forked from Mirrors/opensbi
		
	lib: utils/i2c: Add simple FDT based I2C framework
FDT based I2C framework on the top of I2C library. The drivers are probed on demand by fdt_i2c_adapter_get function. Tested-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Reviewed-by: Alexandre Ghiti <alexandre.ghiti@canonical.com> Tested-by: Alexandre Ghiti <alexandre.ghiti@canonical.com> Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
This commit is contained in:
		
				
					committed by
					
						
						Anup Patel
					
				
			
			
				
	
			
			
			
						parent
						
							2c964a2e15
						
					
				
				
					commit
					6ca6bcafb7
				
			
							
								
								
									
										87
									
								
								lib/utils/i2c/fdt_i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								lib/utils/i2c/fdt_i2c.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2021 YADRO
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Nikita Shubin <n.shubin@yadro.com>
 | 
			
		||||
 *
 | 
			
		||||
 * derivate: lib/utils/gpio/fdt_gpio.c
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Anup Patel <anup.patel@wdc.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <libfdt.h>
 | 
			
		||||
#include <sbi/sbi_error.h>
 | 
			
		||||
#include <sbi_utils/fdt/fdt_helper.h>
 | 
			
		||||
#include <sbi_utils/i2c/fdt_i2c.h>
 | 
			
		||||
 | 
			
		||||
#include <sbi/sbi_console.h>
 | 
			
		||||
 | 
			
		||||
static struct fdt_i2c_adapter *i2c_adapter_drivers[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int fdt_i2c_adapter_init(void *fdt, int nodeoff)
 | 
			
		||||
{
 | 
			
		||||
	int pos, rc;
 | 
			
		||||
	struct fdt_i2c_adapter *drv;
 | 
			
		||||
	const struct fdt_match *match;
 | 
			
		||||
 | 
			
		||||
	/* Try all I2C drivers one-by-one */
 | 
			
		||||
	for (pos = 0; pos < array_size(i2c_adapter_drivers); pos++) {
 | 
			
		||||
		drv = i2c_adapter_drivers[pos];
 | 
			
		||||
		match = fdt_match_node(fdt, nodeoff, drv->match_table);
 | 
			
		||||
		if (match && drv->init) {
 | 
			
		||||
			rc = drv->init(fdt, nodeoff, match);
 | 
			
		||||
			if (rc == SBI_ENODEV)
 | 
			
		||||
				continue;
 | 
			
		||||
			if (rc)
 | 
			
		||||
				return rc;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return SBI_ENOSYS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int fdt_i2c_adapter_find(void *fdt, int nodeoff,
 | 
			
		||||
				struct i2c_adapter **out_adapter)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	struct i2c_adapter *adapter = i2c_adapter_find(nodeoff);
 | 
			
		||||
 | 
			
		||||
	if (!adapter) {
 | 
			
		||||
		/* I2C adapter not found so initialize matching driver */
 | 
			
		||||
		rc = fdt_i2c_adapter_init(fdt, nodeoff);
 | 
			
		||||
		if (rc)
 | 
			
		||||
			return rc;
 | 
			
		||||
 | 
			
		||||
		/* Try to find I2C adapter again */
 | 
			
		||||
		adapter = i2c_adapter_find(nodeoff);
 | 
			
		||||
		if (!adapter)
 | 
			
		||||
			return SBI_ENOSYS;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (out_adapter)
 | 
			
		||||
		*out_adapter = adapter;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_i2c_adapter_get(void *fdt, int nodeoff,
 | 
			
		||||
			struct i2c_adapter **out_adapter)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	struct i2c_adapter *adapter;
 | 
			
		||||
 | 
			
		||||
	if (!fdt || (nodeoff < 0) || !out_adapter)
 | 
			
		||||
		return SBI_EINVAL;
 | 
			
		||||
 | 
			
		||||
	rc = fdt_i2c_adapter_find(fdt, nodeoff, &adapter);
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	*out_adapter = adapter;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -8,3 +8,4 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
libsbiutils-objs-y += i2c/i2c.o
 | 
			
		||||
libsbiutils-objs-y += i2c/fdt_i2c.o
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user