diff options
| author | Rajeshwari Shinde <rajeshwari.s@samsung.com> | 2012-12-26 20:03:12 +0000 | 
|---|---|---|
| committer | Minkyu Kang <mk7.kang@samsung.com> | 2013-01-08 10:54:33 +0900 | 
| commit | a9d2ae7014d9e66dde6dd4a344308449508e4a22 (patch) | |
| tree | e8f2248447d9831045a1de483444a39081bbce27 | |
| parent | d055911887583e36e550900506c80fbd73c89a58 (diff) | |
| download | olio-uboot-2014.01-a9d2ae7014d9e66dde6dd4a344308449508e4a22.tar.xz olio-uboot-2014.01-a9d2ae7014d9e66dde6dd4a344308449508e4a22.zip | |
I2C: Driver changes for FDT support
Functions added to get the I2C bus number and reset I2C bus using
FDT node.
Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com>
Acked-by: Simon Glass <sjg@chromium.org>
Acked-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
| -rw-r--r-- | drivers/i2c/s3c24x0_i2c.c | 83 | ||||
| -rw-r--r-- | drivers/i2c/s3c24x0_i2c.h | 8 | ||||
| -rw-r--r-- | include/i2c.h | 26 | 
3 files changed, 116 insertions, 1 deletions
| diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a28..7ec01ec62 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@   */  #include <common.h> +#include <fdtdec.h>  #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)  #include <asm/arch/clk.h>  #include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h>  #else  #include <asm/arch/s3c24x0_cpu.h>  #endif @@ -60,7 +62,14 @@  #define I2C_TIMEOUT 1		/* 1 second */ -static unsigned int g_current_bus;	/* Stores Current I2C Bus */ +/* + * For SPL boot some boards need i2c before SDRAM is initialised so force + * variables to live in SRAM + */ +static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] +			__attribute__((section(".data"))); +static int i2c_busses __attribute__((section(".data")));  #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)  static int GetI2CSDA(void) @@ -512,4 +521,76 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)  		(i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer,  		 len) != 0);  } + +#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{ +	int node_list[CONFIG_MAX_I2C_NUM]; +	int count, i; + +	count = fdtdec_find_aliases_for_id(blob, "i2c", +		COMPAT_SAMSUNG_S3C2440_I2C, node_list, +		CONFIG_MAX_I2C_NUM); + +	for (i = 0; i < count; i++) { +		struct s3c24x0_i2c_bus *bus; +		int node = node_list[i]; + +		if (node <= 0) +			continue; +		bus = &i2c_bus[i]; +		bus->regs = (struct s3c24x0_i2c *) +			fdtdec_get_addr(blob, node, "reg"); +		bus->id = pinmux_decode_periph_id(blob, node); +		bus->node = node; +		bus->bus_num = i2c_busses++; +		exynos_pinmux_config(bus->id, 0); +	} +} + +static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{ +	if (bus_idx < i2c_busses) +		return &i2c_bus[bus_idx]; + +	debug("Undefined bus: %d\n", bus_idx); +	return NULL; +} + +int i2c_get_bus_num_fdt(int node) +{ +	int i; + +	for (i = 0; i < i2c_busses; i++) { +		if (node == i2c_bus[i].node) +			return i; +	} + +	debug("%s: Can't find any matched I2C bus\n", __func__); +	return -1; +} + +int i2c_reset_port_fdt(const void *blob, int node) +{ +	struct s3c24x0_i2c_bus *i2c; +	int bus; + +	bus = i2c_get_bus_num_fdt(node); +	if (bus < 0) { +		debug("could not get bus for node %d\n", node); +		return -1; +	} + +	i2c = get_bus(bus); +	if (!i2c) { +		debug("get_bus() failed for node node %d\n", node); +		return -1; +	} + +	i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + +	return 0; +} +#endif +  #endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06a2..1243bf1b1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c {  	u32	iicds;  	u32	iiclc;  }; + +struct s3c24x0_i2c_bus { +	int node;	/* device tree node */ +	int bus_num;	/* i2c bus number */ +	struct s3c24x0_i2c *regs; +	enum periph_id id; +}; +  #endif /* _S3C24X0_I2C_H */ diff --git a/include/i2c.h b/include/i2c.h index 16f099d2e..c60d07583 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -262,4 +262,30 @@ extern int get_multi_scl_pin(void);  extern int get_multi_sda_pin(void);  extern int multi_i2c_init(void);  #endif + +/** + * Get FDT values for i2c bus. + * + * @param blob  Device tree blbo + * @return the number of I2C bus + */ +void board_i2c_init(const void *blob); + +/** + * Find the I2C bus number by given a FDT I2C node. + * + * @param blob  Device tree blbo + * @param node  FDT I2C node to find + * @return the number of I2C bus (zero based), or -1 on error + */ +int i2c_get_bus_num_fdt(int node); + +/** + * Reset the I2C bus represented by the given a FDT I2C node. + * + * @param blob  Device tree blbo + * @param node  FDT I2C node to find + * @return 0 if port was reset, -1 if not found + */ +int i2c_reset_port_fdt(const void *blob, int node);  #endif	/* _I2C_H_ */ |