From a9d2ae7014d9e66dde6dd4a344308449508e4a22 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Wed, 26 Dec 2012 20:03:12 +0000 Subject: 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 Acked-by: Simon Glass Acked-by: Heiko Schocher Signed-off-by: Minkyu Kang --- drivers/i2c/s3c24x0_i2c.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/i2c/s3c24x0_i2c.h | 8 +++++ 2 files changed, 90 insertions(+), 1 deletion(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a..7ec01ec 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */ #include +#include #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include #include +#include #else #include #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 2dd4b06..1243bf1 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 */ -- cgit v1.1 From d04df3c6adf7b025d4f68d4f558975d3beb32544 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Sun, 13 Jan 2013 19:49:36 +0000 Subject: I2C: S3C24X0: Resolve build error for VCMA9 This patch resolves the following build errors for I2C driver in VCMA9: In file included from s3c24x0_i2c.c:40:0: s3c24x0_i2c.h:38:17: error: field 'id' has incomplete type s3c24x0_i2c.c:70:39: error: 'CONFIG_MAX_I2C_NUM' undeclared here (not in a function) s3c24x0_i2c.c:70:31: warning: 'i2c_bus' defined but not used [-Wunused-variable] s3c24x0_i2c.c:72:12: warning: 'i2c_busses' defined but not used [-Wunused-variable] Signed-off-by: Rajeshwari Shinde Signed-off-by: Minkyu Kang --- drivers/i2c/s3c24x0_i2c.c | 4 +++- drivers/i2c/s3c24x0_i2c.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 7ec01ec..769a2ba 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -67,9 +67,11 @@ * variables to live in SRAM */ static unsigned int g_current_bus __attribute__((section(".data"))); +#ifdef CONFIG_OF_CONTROL +static int i2c_busses __attribute__((section(".data"))); static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] __attribute__((section(".data"))); -static int i2c_busses __attribute__((section(".data"))); +#endif #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 1243bf1..a56d749 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -35,7 +35,6 @@ struct s3c24x0_i2c_bus { int node; /* device tree node */ int bus_num; /* i2c bus number */ struct s3c24x0_i2c *regs; - enum periph_id id; + int id; }; - #endif /* _S3C24X0_I2C_H */ -- cgit v1.1