[U-Boot] [PATCH 0/6] Bring new I2C framwork to Samsung Trats board

This patchset brings new I2C framework to Samsung Trats board. It is intended to test the framework, please don't merge.
I2C clock, spacing and pinmux are added for Exynos4. The s3c24x0 i2c driver is modified to support both Exynos4.
The s3c24x0 i2c driver is modiefied for the new I2C framework. Configs for VCMA9.h and smdk5250.h boards are modified. Boards compile successfully but were not tested.
New i2c framework is enabled and tested on Samsung Trats board.
Piotr Wilczek (6): exynos:clock: Add i2c clock exynos:cpu: Add Exynos4 I2C spacing exynos:pinmux: Add pinmux support for i2c drivers:i2c: Modify I2C driver for Exynos4 WIP: i2c: s3c24x0: modify driver for new I2C framework WIP: arm: trats: add support for new I2C framework
arch/arm/cpu/armv7/exynos/clock.c | 17 ++++ arch/arm/cpu/armv7/exynos/pinmux.c | 64 ++++++++++++++ arch/arm/include/asm/arch-exynos/cpu.h | 2 + board/samsung/trats/trats.c | 26 +++++- drivers/i2c/i2c_core.c | 5 + drivers/i2c/s3c24x0_i2c.c | 148 ++++++++++++++++++++++++++++---- include/configs/VCMA9.h | 4 + include/configs/smdk5250.h | 4 + include/configs/trats.h | 16 +++- 9 files changed, 263 insertions(+), 23 deletions(-)

This patch adds i2c clock for Exynos4
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- arch/arm/cpu/armv7/exynos/clock.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 4f3b451..21e45d2 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -732,6 +732,21 @@ static unsigned long exynos5_get_i2c_clk(void) return aclk_66; }
+static unsigned long exynos4_get_i2c_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long sclk, aclk_100; + unsigned int ratio; + + sclk = get_pll_clk(APLL); + + ratio = (readl(&clk->div_top)) >> 4; + ratio &= 0xf; + aclk_100 = sclk / (ratio + 1); + return aclk_100; +} + unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) @@ -752,6 +767,8 @@ unsigned long get_i2c_clk(void) { if (cpu_is_exynos5()) { return exynos5_get_i2c_clk(); + } else if (cpu_is_exynos4()) { + return exynos4_get_i2c_clk(); } else { debug("I2C clock is not set for this CPU\n"); return 0;

This patch add the spacing for i2c for Exynos4
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- arch/arm/include/asm/arch-exynos/cpu.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 2cd4ae1..3073ca1 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -28,6 +28,8 @@ #define EXYNOS4_ADDR_BASE 0x10000000
/* EXYNOS4 */ +#define EXYNOS4_I2C_SPACING 0x10000 + #define EXYNOS4_GPIO_PART3_BASE 0x03860000 #define EXYNOS4_PRO_ID 0x10000000 #define EXYNOS4_SYSREG_BASE 0x10010000

This patch add pinmux for I2C for Exynos4
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 64 ++++++++++++++++++++++++++++++++++++ 1 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 7776add..44ce072 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -265,10 +265,74 @@ static int exynos5_pinmux_config(int peripheral, int flags) return 0; }
+static void exynos4_i2c_config(int peripheral, int flags) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1(); + + switch (peripheral) { + case PERIPH_ID_I2C0: + s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2)); + s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C1: + s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2)); + s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C2: + s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C3: + s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C4: + s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4)); + s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3)); + break; + } +} + +static int exynos4_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + exynos4_i2c_config(peripheral, flags); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + int exynos_pinmux_config(int peripheral, int flags) { if (cpu_is_exynos5()) return exynos5_pinmux_config(peripheral, flags); + else if (cpu_is_exynos4()) + return exynos4_pinmux_config(peripheral, flags); else { debug("pinmux functionality not supported\n"); return -1;

This patch modifies the S3C i2c driver to support both Exynos4 and Exynos5
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- drivers/i2c/s3c24x0_i2c.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..90d297a 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,7 +27,7 @@ */
#include <common.h> -#ifdef CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> #include <asm/arch/cpu.h> #else @@ -62,7 +62,7 @@
static unsigned int g_current_bus; /* Stores Current I2C Bus */
-#ifndef CONFIG_EXYNOS5 +#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) { struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); @@ -121,7 +121,12 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)
static struct s3c24x0_i2c *get_base_i2c(void) { -#ifdef CONFIG_EXYNOS5 +#ifdef CONFIG_EXYNOS4 + struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() + + (EXYNOS4_I2C_SPACING + * g_current_bus)); + return i2c; +#elif defined CONFIG_EXYNOS5 struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() + (EXYNOS5_I2C_SPACING * g_current_bus)); @@ -134,7 +139,7 @@ static struct s3c24x0_i2c *get_base_i2c(void) static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { ulong freq, pres = 16, div; -#ifdef CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) freq = get_i2c_clk(); #else freq = get_PCLK(); @@ -188,7 +193,7 @@ unsigned int i2c_get_bus_num(void) void i2c_init(int speed, int slaveadd) { struct s3c24x0_i2c *i2c; -#ifndef CONFIG_EXYNOS5 +#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); #endif int i; @@ -204,7 +209,7 @@ void i2c_init(int speed, int slaveadd) i--; }
-#ifndef CONFIG_EXYNOS5 +#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) { #ifdef CONFIG_S3C2410 ulong old_gpecon = readl(&gpio->gpecon); @@ -248,7 +253,7 @@ void i2c_init(int speed, int slaveadd) writel(old_gpecon, &gpio->pgcon); #endif } -#endif /* #ifndef CONFIG_EXYNOS5 */ +#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ i2c_ch_init(i2c, speed, slaveadd); }

This patch modifies s3c24x0 driver for the new I2C framework. Configs for VCMA9.h and smdk5250.h boards are modified. Boards compile successfully but were not tested.
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- drivers/i2c/i2c_core.c | 5 ++ drivers/i2c/s3c24x0_i2c.c | 129 ++++++++++++++++++++++++++++++++++++++++--- include/configs/VCMA9.h | 4 ++ include/configs/smdk5250.h | 4 ++ 4 files changed, 133 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c index d3b5a8d..f0816f7 100644 --- a/drivers/i2c/i2c_core.c +++ b/drivers/i2c/i2c_core.c @@ -10,6 +10,10 @@ extern struct i2c_adapter fsl_i2c_adap[]; #endif
+#ifdef CONFIG_DRIVER_S3C24X0_I2C +extern struct i2c_adapter s3c24x0_i2c_adap[]; +#endif + #ifdef CONFIG_SYS_I2C_SOFT extern struct i2c_adapter soft_i2c_adap[]; #endif @@ -214,6 +218,7 @@ unsigned int i2c_get_bus_num(void) */ int i2c_set_bus_num(unsigned int bus) { + #ifndef CONFIG_SYS_I2C_DIRECT_BUS int i; uint8_t buf; diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a..d473eaa 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -155,7 +155,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
/* set prescaler, divisor according to freq, also set ACKGEN, IRQ */ writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon); - /* init to SLAVE REVEIVE and set slaveaddr */ writel(0, &i2c->iicstat); writel(slaveadd, &i2c->iicadd); @@ -168,7 +167,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) */
#ifdef CONFIG_I2C_MULTI_BUS -int i2c_set_bus_num(unsigned int bus) +int s3c24x0_i2c_set_bus_num(unsigned int bus) { struct s3c24x0_i2c *i2c;
@@ -184,13 +183,13 @@ int i2c_set_bus_num(unsigned int bus) return 0; }
-unsigned int i2c_get_bus_num(void) +unsigned int s3c24x0_i2c_get_bus_num(void) { return g_current_bus; } #endif
-void i2c_init(int speed, int slaveadd) +void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { struct s3c24x0_i2c *i2c; #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) @@ -198,8 +197,7 @@ void i2c_init(int speed, int slaveadd) #endif int i;
- /* By default i2c channel 0 is the current bus */ - g_current_bus = 0; + g_current_bus = adap->hwadapnr; i2c = get_base_i2c();
/* wait for some time to give previous transfer a chance to finish */ @@ -415,11 +413,13 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, return result; }
-int i2c_probe(uchar chip) +int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) { struct s3c24x0_i2c *i2c; uchar buf[1];
+ g_current_bus = adap->hwadapnr; + i2c = get_base_i2c(); buf[0] = 0;
@@ -431,12 +431,15 @@ int i2c_probe(uchar chip) return i2c_transfer(i2c, I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK; }
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) { struct s3c24x0_i2c *i2c; uchar xaddr[4]; int ret;
+ g_current_bus = adap->hwadapnr; + if (alen > 4) { debug("I2C read: addr len %d not supported\n", alen); return 1; @@ -475,11 +478,14 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) return 0; }
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) { struct s3c24x0_i2c *i2c; uchar xaddr[4];
+ g_current_bus = adap->hwadapnr; + if (alen > 4) { debug("I2C write: addr len %d not supported\n", alen); return 1; @@ -512,4 +518,109 @@ 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); } + +struct i2c_adapter s3c24x0_i2c_adap[] = { + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 0, + .name = "s3c24x0-i2c#0" + }, +#if CONFIG_MAX_I2C_NUM > 1 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 1, + .name = "s3c24x0-i2c#1" + }, +#endif +#if CONFIG_MAX_I2C_NUM > 2 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 2, + .name = "s3c24x0-i2c#2" + }, +#endif +#if CONFIG_MAX_I2C_NUM > 3 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 3, + .name = "s3c24x0-i2c#3" + }, +#endif +#if CONFIG_MAX_I2C_NUM > 4 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 4, + .name = "s3c24x0-i2c#4" + }, +#endif +#if CONFIG_MAX_I2C_NUM > 5 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 5, + .name = "s3c24x0-i2c#5" + }, +#endif +#if CONFIG_MAX_I2C_NUM > 6 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 6, + .name = "s3c24x0-i2c#6" + }, +#endif +#if CONFIG_MAX_I2C_NUM > 7 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_SPEED, + .slaveaddr = CONFIG_SYS_I2C_SLAVE, + .init_done = 0, + .hwadapnr = 7, + .name = "s3c24x0-i2c#7" + }, +#endif +}; #endif /* CONFIG_HARD_I2C */ diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index fb7d922..f1de21d 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -95,6 +95,10 @@ /* we use the built-in I2C controller */ #define CONFIG_DRIVER_S3C24X0_I2C
+#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1 + #define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 /* use EEPROM for environment vars */ diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index c0f8622..cb0f449 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -204,6 +204,10 @@ #define CONFIG_MAX_I2C_NUM 8 #define CONFIG_SYS_I2C_SLAVE 0x0
+#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1 + /* Ethernet Controllor Driver */ #ifdef CONFIG_CMD_NET #define CONFIG_SMC911X

Hello Piotr,
On 15.11.2012 09:15, Piotr Wilczek wrote:
This patch modifies s3c24x0 driver for the new I2C framework. Configs for VCMA9.h and smdk5250.h boards are modified. Boards compile successfully but were not tested.
Signed-off-by: Piotr Wilczekp.wilczek@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Minkyu Kangmk7.kang@samsung.com
drivers/i2c/i2c_core.c | 5 ++ drivers/i2c/s3c24x0_i2c.c | 129 ++++++++++++++++++++++++++++++++++++++++--- include/configs/VCMA9.h | 4 ++ include/configs/smdk5250.h | 4 ++ 4 files changed, 133 insertions(+), 9 deletions(-)
[...]
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a..d473eaa 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -155,7 +155,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
/* set prescaler, divisor according to freq, also set ACKGEN, IRQ */ writel((div& 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0),&i2c->iiccon);
Why this delete?
/* init to SLAVE REVEIVE and set slaveaddr */ writel(0,&i2c->iicstat); writel(slaveadd,&i2c->iicadd); @@ -168,7 +167,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) */
#ifdef CONFIG_I2C_MULTI_BUS
This define can go completely away.
-int i2c_set_bus_num(unsigned int bus) +int s3c24x0_i2c_set_bus_num(unsigned int bus)
all functions are static now, please change.
{ struct s3c24x0_i2c *i2c;
@@ -184,13 +183,13 @@ int i2c_set_bus_num(unsigned int bus) return 0; }
-unsigned int i2c_get_bus_num(void) +unsigned int s3c24x0_i2c_get_bus_num(void)
No longer needed.
{ return g_current_bus; } #endif
-void i2c_init(int speed, int slaveadd) +void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
static.
{ struct s3c24x0_i2c *i2c; #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) @@ -198,8 +197,7 @@ void i2c_init(int speed, int slaveadd) #endif int i;
- /* By default i2c channel 0 is the current bus */
- g_current_bus = 0;
- g_current_bus = adap->hwadapnr;
Can we please delete g_current_bus and use adap->hwadapnr only. g_current_bus should go away completely.
i2c = get_base_i2c();
/* wait for some time to give previous transfer a chance to finish */ @@ -415,11 +413,13 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, return result; }
-int i2c_probe(uchar chip) +int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)
static.
{ struct s3c24x0_i2c *i2c; uchar buf[1];
- g_current_bus = adap->hwadapnr;
Please get rid of g_current_bus, and use adap->hwadapnr only!
- i2c = get_base_i2c(); buf[0] = 0;
@@ -431,12 +431,15 @@ int i2c_probe(uchar chip) return i2c_transfer(i2c, I2C_READ, chip<< 1, 0, 0, buf, 1) != I2C_OK; }
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
static.
{ struct s3c24x0_i2c *i2c; uchar xaddr[4]; int ret;
- g_current_bus = adap->hwadapnr;
- if (alen> 4) { debug("I2C read: addr len %d not supported\n", alen); return 1;
@@ -475,11 +478,14 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) return 0; }
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
static
{ struct s3c24x0_i2c *i2c; uchar xaddr[4];
- g_current_bus = adap->hwadapnr;
- if (alen> 4) { debug("I2C write: addr len %d not supported\n", alen); return 1;
@@ -512,4 +518,109 @@ 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); }
+struct i2c_adapter s3c24x0_i2c_adap[] = {
- {
.init = s3c24x0_i2c_init,
.probe = s3c24x0_i2c_probe,
.read = s3c24x0_i2c_read,
.write = s3c24x0_i2c_write,
.speed = CONFIG_SYS_I2C_SPEED,
.slaveaddr = CONFIG_SYS_I2C_SLAVE,
Please use a more driver specific name here, for example: CONFIG_SYS_I2C_S3C24X0_{SPEED/SLAVE} ...
.init_done = 0,
.hwadapnr = 0,
.name = "s3c24x0-i2c#0"
- },
+#if CONFIG_MAX_I2C_NUM> 1
Please use a more driver specific name here, for example: CONFIG_I2C_S3C24X0_MAX_NUM, thanks!
- {
[...]
+#endif +}; #endif /* CONFIG_HARD_I2C */ diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index fb7d922..f1de21d 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -95,6 +95,10 @@ /* we use the built-in I2C controller */ #define CONFIG_DRIVER_S3C24X0_I2C
^ Can we rename this define to CONFIG_SYS_I2C_S3C24X0
+#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
- #define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 /* use EEPROM for environment vars */
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index c0f8622..cb0f449 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -204,6 +204,10 @@ #define CONFIG_MAX_I2C_NUM 8
^ Please rename
#define CONFIG_SYS_I2C_SLAVE 0x0
^ Please rename
+#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
- /* Ethernet Controllor Driver */ #ifdef CONFIG_CMD_NET #define CONFIG_SMC911X
Thanks!
bye, Heiko

Hello Heiko,
-----Original Message----- From: Heiko Schocher [mailto:hs@denx.de] Sent: Friday, November 16, 2012 11:34 AM To: Piotr Wilczek Cc: u-boot@lists.denx.de; Minkyu Kang; Kyungmin Park; Lukasz Majewski; Simon Glass; Stephen Warren; Tom Rini Subject: Re: [PATCH 5/6] WIP: i2c: s3c24x0: modify driver for new I2C framework
Hello Piotr,
On 15.11.2012 09:15, Piotr Wilczek wrote:
This patch modifies s3c24x0 driver for the new I2C framework. Configs for VCMA9.h and smdk5250.h boards are modified. Boards compile successfully but were not tested.
Signed-off-by: Piotr Wilczekp.wilczek@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Minkyu Kangmk7.kang@samsung.com
drivers/i2c/i2c_core.c | 5 ++ drivers/i2c/s3c24x0_i2c.c | 129
++++++++++++++++++++++++++++++++++++++++---
include/configs/VCMA9.h | 4 ++ include/configs/smdk5250.h | 4 ++ 4 files changed, 133 insertions(+), 9 deletions(-)
[...]
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a..d473eaa 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -155,7 +155,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
/* set prescaler, divisor according to freq, also set ACKGEN, IRQ
*/
writel((div& 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0),&i2c->iiccon);
Why this delete?
Unintentional, I fix it.
/* init to SLAVE REVEIVE and set slaveaddr */ writel(0,&i2c->iicstat); writel(slaveadd,&i2c->iicadd); @@ -168,7 +167,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c,
int speed, int slaveadd)
*/
#ifdef CONFIG_I2C_MULTI_BUS
This define can go completely away.
Right.
-int i2c_set_bus_num(unsigned int bus) +int s3c24x0_i2c_set_bus_num(unsigned int bus)
all functions are static now, please change.
Yes, I overlooked it.
{ struct s3c24x0_i2c *i2c;
@@ -184,13 +183,13 @@ int i2c_set_bus_num(unsigned int bus) return 0; }
-unsigned int i2c_get_bus_num(void) +unsigned int s3c24x0_i2c_get_bus_num(void)
No longer needed.
{ return g_current_bus; } #endif
-void i2c_init(int speed, int slaveadd) +void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int +slaveadd)
static.
{ struct s3c24x0_i2c *i2c; #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) @@ -198,8 +197,7 @@ void i2c_init(int speed, int slaveadd) #endif int i;
- /* By default i2c channel 0 is the current bus */
- g_current_bus = 0;
- g_current_bus = adap->hwadapnr;
Can we please delete g_current_bus and use adap->hwadapnr only. g_current_bus should go away completely.
Ok
i2c = get_base_i2c();
/* wait for some time to give previous transfer a chance to
finish
*/ @@ -415,11 +413,13 @@ static int i2c_transfer(struct s3c24x0_i2c
*i2c,
return result; }
-int i2c_probe(uchar chip) +int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)
static.
{ struct s3c24x0_i2c *i2c; uchar buf[1];
- g_current_bus = adap->hwadapnr;
Please get rid of g_current_bus, and use adap->hwadapnr only!
- i2c = get_base_i2c(); buf[0] = 0;
@@ -431,12 +431,15 @@ int i2c_probe(uchar chip) return i2c_transfer(i2c, I2C_READ, chip<< 1, 0, 0, buf, 1) !=
I2C_OK;
}
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int
len)
+int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint
addr,
int alen, uchar *buffer, int len)
static.
{ struct s3c24x0_i2c *i2c; uchar xaddr[4]; int ret;
- g_current_bus = adap->hwadapnr;
- if (alen> 4) { debug("I2C read: addr len %d not supported\n", alen); return 1;
@@ -475,11 +478,14 @@ int i2c_read(uchar chip, uint addr, int alen,
uchar *buffer, int len)
return 0; }
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint
addr,
int alen, uchar *buffer, int len)
static
{ struct s3c24x0_i2c *i2c; uchar xaddr[4];
- g_current_bus = adap->hwadapnr;
- if (alen> 4) { debug("I2C write: addr len %d not supported\n", alen); return 1;
@@ -512,4 +518,109 @@ 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);
}
+struct i2c_adapter s3c24x0_i2c_adap[] = {
- {
.init = s3c24x0_i2c_init,
.probe = s3c24x0_i2c_probe,
.read = s3c24x0_i2c_read,
.write = s3c24x0_i2c_write,
.speed = CONFIG_SYS_I2C_SPEED,
.slaveaddr = CONFIG_SYS_I2C_SLAVE,
Please use a more driver specific name here, for example: CONFIG_SYS_I2C_S3C24X0_{SPEED/SLAVE} ...
Ok
.init_done = 0,
.hwadapnr = 0,
.name = "s3c24x0-i2c#0"
- },
+#if CONFIG_MAX_I2C_NUM> 1
Please use a more driver specific name here, for example: CONFIG_I2C_S3C24X0_MAX_NUM, thanks!
Ok
- {
[...]
+#endif +}; #endif /* CONFIG_HARD_I2C */ diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index fb7d922..f1de21d 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -95,6 +95,10 @@ /* we use the built-in I2C controller */ #define CONFIG_DRIVER_S3C24X0_I2C
^ Can we rename this define to CONFIG_SYS_I2C_S3C24X0
+#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
- #define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 /* use EEPROM for environment vars */ diff --git
a/include/configs/smdk5250.h b/include/configs/smdk5250.h index c0f8622..cb0f449 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -204,6 +204,10 @@ #define CONFIG_MAX_I2C_NUM 8
^ Please rename
#define CONFIG_SYS_I2C_SLAVE 0x0
^ Please rename
Ok
+#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
- /* Ethernet Controllor Driver */ #ifdef CONFIG_CMD_NET #define CONFIG_SMC911X
Thanks!
bye, Heiko -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Best regards, Piotr Wilczek -- Samsung Poland R&D Center | Linux Platform Group

This enables new i2c framework on Trats board. Hardware s3c24x0 i2c driver is used instead of software i2c.
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- board/samsung/trats/trats.c | 26 +++++++++++++++++++++----- include/configs/trats.h | 16 ++++++++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index e11a892..71e1975 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -24,8 +24,10 @@ */
#include <common.h> +#include <i2c.h> #include <lcd.h> #include <asm/io.h> +#include <asm/arch/pinmux.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> #include <asm/arch/mmc.h> @@ -61,6 +63,19 @@ static int hwrevision(int rev)
struct s3c_plat_otg_data s5pc210_otg_data;
+void i2c_init_pinmux(void) +{ + int i, err; + for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) { + err = exynos_pinmux_config((PERIPH_ID_I2C0 + i), + PINMUX_FLAG_NONE); + if (err) { + debug("I2C%d not configured\n", (PERIPH_ID_I2C0 + i)); + return; + } + } +} + int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -68,6 +83,8 @@ int board_init(void) check_hw_revision(); printf("HW Revision:\t0x%x\n", board_rev);
+ i2c_init_pinmux(); + #if defined(CONFIG_PMIC) pmic_init(); #endif @@ -77,14 +94,9 @@ int board_init(void)
void i2c_init_board(void) { - struct exynos4_gpio_part1 *gpio1 = - (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); struct exynos4_gpio_part2 *gpio2 = (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
- /* I2C_5 -> PMIC */ - s5p_gpio_direction_output(&gpio1->b, 7, 1); - s5p_gpio_direction_output(&gpio1->b, 6, 1); /* I2C_9 -> FG */ s5p_gpio_direction_output(&gpio2->y4, 0, 1); s5p_gpio_direction_output(&gpio2->y4, 1, 1); @@ -415,6 +427,8 @@ static int lcd_power(void) int ret = 0; struct pmic *p = get_pmic();
+ i2c_set_bus_num(0); + if (pmic_probe(p)) return 0;
@@ -475,6 +489,8 @@ static int mipi_power(void) int ret = 0; struct pmic *p = get_pmic();
+ i2c_set_bus_num(0); + if (pmic_probe(p)) return 0;
diff --git a/include/configs/trats.h b/include/configs/trats.h index 106fd37..54423f4 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -33,6 +33,7 @@ #define CONFIG_SAMSUNG /* in a SAMSUNG core */ #define CONFIG_S5P /* which is in a S5P Family */ #define CONFIG_EXYNOS4210 /* which is in a EXYNOS4210 */ +#define CONFIG_EXYNOS4 #define CONFIG_TRATS /* working with TRATS */ #define CONFIG_TIZEN /* TIZEN lib */
@@ -211,18 +212,29 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_CACHELINE_SIZE 32
- #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ #define CONFIG_SYS_I2C_SOFT_SPEED 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE 0xFE -#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]} #define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD #define CONFIG_I2C_MULTI_BUS #define CONFIG_SOFT_I2C_MULTI_BUS #define CONFIG_SYS_MAX_I2C_BUS 15
+#define CONFIG_HARD_I2C +#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_CMD_I2C + +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[5]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1 +#define CONFIG_SYS_I2C_BUSSES {{0, {{{0, "S3C24X0"}, 0x00, 5}}}, \ + } +#define CONFIG_SYS_NUM_I2C_BUSSES 1 + #include <asm/arch/gpio.h>
/* I2C PMIC */

Hello Piotr,
On 15.11.2012 09:15, Piotr Wilczek wrote:
This enables new i2c framework on Trats board. Hardware s3c24x0 i2c driver is used instead of software i2c.
Signed-off-by: Piotr Wilczekp.wilczek@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Minkyu Kangmk7.kang@samsung.com
board/samsung/trats/trats.c | 26 +++++++++++++++++++++----- include/configs/trats.h | 16 ++++++++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index e11a892..71e1975 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -24,8 +24,10 @@ */
#include<common.h> +#include<i2c.h> #include<lcd.h> #include<asm/io.h> +#include<asm/arch/pinmux.h> #include<asm/arch/cpu.h> #include<asm/arch/gpio.h> #include<asm/arch/mmc.h> @@ -61,6 +63,19 @@ static int hwrevision(int rev)
struct s3c_plat_otg_data s5pc210_otg_data;
+void i2c_init_pinmux(void) +{
- int i, err;
- for (i = 0; i< CONFIG_MAX_I2C_NUM; i++) {
err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
PINMUX_FLAG_NONE);
if (err) {
debug("I2C%d not configured\n", (PERIPH_ID_I2C0 + i));
return;
}
- }
+}
Is this change multibus specific? Why?
int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -68,6 +83,8 @@ int board_init(void) check_hw_revision(); printf("HW Revision:\t0x%x\n", board_rev);
- i2c_init_pinmux();
Why this call not in i2c_init_board(void)?
#if defined(CONFIG_PMIC) pmic_init(); #endif @@ -77,14 +94,9 @@ int board_init(void)
void i2c_init_board(void) {
struct exynos4_gpio_part1 *gpio1 =
(struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
struct exynos4_gpio_part2 *gpio2 = (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
/* I2C_5 -> PMIC */
s5p_gpio_direction_output(&gpio1->b, 7, 1);
s5p_gpio_direction_output(&gpio1->b, 6, 1);
Here again, what has this to do with the new multibus framework?
/* I2C_9 -> FG */ s5p_gpio_direction_output(&gpio2->y4, 0, 1); s5p_gpio_direction_output(&gpio2->y4, 1, 1); @@ -415,6 +427,8 @@ static int lcd_power(void) int ret = 0; struct pmic *p = get_pmic();
- i2c_set_bus_num(0);
^ Fix number? Please use here a define.
- if (pmic_probe(p)) return 0;
@@ -475,6 +489,8 @@ static int mipi_power(void) int ret = 0; struct pmic *p = get_pmic();
- i2c_set_bus_num(0);
- if (pmic_probe(p)) return 0;
diff --git a/include/configs/trats.h b/include/configs/trats.h index 106fd37..54423f4 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -33,6 +33,7 @@ #define CONFIG_SAMSUNG /* in a SAMSUNG core */ #define CONFIG_S5P /* which is in a S5P Family */ #define CONFIG_EXYNOS4210 /* which is in a EXYNOS4210 */ +#define CONFIG_EXYNOS4 #define CONFIG_TRATS /* working with TRATS */ #define CONFIG_TIZEN /* TIZEN lib */
@@ -211,18 +212,29 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_CACHELINE_SIZE 32
- #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ #define CONFIG_SYS_I2C_SOFT_SPEED 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE 0xFE
-#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
Why you delete here this adapter? You can use now in the new Framework Hard and soft i2c adapter ...
#define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD #define CONFIG_I2C_MULTI_BUS #define CONFIG_SOFT_I2C_MULTI_BUS #define CONFIG_SYS_MAX_I2C_BUS 15
+#define CONFIG_HARD_I2C
No longer needed
+#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x0
This defines please rename, as posted in previous EMail ...
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[5]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1 +#define CONFIG_SYS_I2C_BUSSES {{0, {{{0, "S3C24X0"}, 0x00, 5}}}, \
You use here only one bus, so you do not need to define this here.
}
+#define CONFIG_SYS_NUM_I2C_BUSSES 1
#include<asm/arch/gpio.h>
/* I2C PMIC */
bye, Heiko

Hello Heiko,
-----Original Message----- From: Heiko Schocher [mailto:hs@denx.de] Sent: Friday, November 16, 2012 11:46 AM To: Piotr Wilczek Cc: u-boot@lists.denx.de; Minkyu Kang; Kyungmin Park; Lukasz Majewski; Simon Glass; Stephen Warren; Tom Rini Subject: Re: [PATCH 6/6] WIP: arm: trats: add support for new I2C framework
Hello Piotr,
On 15.11.2012 09:15, Piotr Wilczek wrote:
This enables new i2c framework on Trats board. Hardware s3c24x0 i2c driver is used instead of software i2c.
Signed-off-by: Piotr Wilczekp.wilczek@samsung.com Signed-off-by: Kyungmin Parkkyungmin.park@samsung.com CC: Minkyu Kangmk7.kang@samsung.com
board/samsung/trats/trats.c | 26 +++++++++++++++++++++----- include/configs/trats.h | 16 ++++++++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/board/samsung/trats/trats.c
b/board/samsung/trats/trats.c
index e11a892..71e1975 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -24,8 +24,10 @@ */
#include<common.h> +#include<i2c.h> #include<lcd.h> #include<asm/io.h> +#include<asm/arch/pinmux.h> #include<asm/arch/cpu.h> #include<asm/arch/gpio.h> #include<asm/arch/mmc.h> @@ -61,6 +63,19 @@ static int hwrevision(int rev)
struct s3c_plat_otg_data s5pc210_otg_data;
+void i2c_init_pinmux(void) +{
- int i, err;
- for (i = 0; i< CONFIG_MAX_I2C_NUM; i++) {
err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
PINMUX_FLAG_NONE);
if (err) {
debug("I2C%d not configured\n", (PERIPH_ID_I2C0 +
i));
return;
}
- }
+}
Is this change multibus specific? Why?
GPIO must be set to I2C function when hardware I2C driver is used. Also, because only one hardware I2C bus is used I should change pins function for I2C_5 only.
int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -68,6 +83,8 @@ int board_init(void) check_hw_revision(); printf("HW Revision:\t0x%x\n", board_rev);
- i2c_init_pinmux();
Why this call not in i2c_init_board(void)?
Ok
#if defined(CONFIG_PMIC) pmic_init(); #endif @@ -77,14 +94,9 @@ int board_init(void)
void i2c_init_board(void) {
struct exynos4_gpio_part1 *gpio1 =
(struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
struct exynos4_gpio_part2 *gpio2 = (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
/* I2C_5 -> PMIC */
s5p_gpio_direction_output(&gpio1->b, 7, 1);
s5p_gpio_direction_output(&gpio1->b, 6, 1);
Here again, what has this to do with the new multibus framework?
Currently only software I2c is used and pins must be set as outputs. With this patchset I switch from software to hardware I2C for PMIC and I must change pins function from output to I2C.
/* I2C_9 -> FG */ s5p_gpio_direction_output(&gpio2->y4, 0, 1); s5p_gpio_direction_output(&gpio2->y4, 1, 1); @@ -415,6 +427,8 @@ static int lcd_power(void) int ret = 0; struct pmic *p = get_pmic();
- i2c_set_bus_num(0);
^ Fix number? Please use here a define.
Ok
- if (pmic_probe(p)) return 0;
@@ -475,6 +489,8 @@ static int mipi_power(void) int ret = 0; struct pmic *p = get_pmic();
- i2c_set_bus_num(0);
- if (pmic_probe(p)) return 0;
diff --git a/include/configs/trats.h b/include/configs/trats.h index 106fd37..54423f4 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -33,6 +33,7 @@ #define CONFIG_SAMSUNG /* in a SAMSUNG core */ #define CONFIG_S5P /* which is in a S5P Family */ #define CONFIG_EXYNOS4210 /* which is in a EXYNOS4210 */ +#define CONFIG_EXYNOS4 #define CONFIG_TRATS /* working with TRATS */ #define CONFIG_TIZEN /* TIZEN lib */
@@ -211,18 +212,29 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR -
GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_CACHELINE_SIZE 32
- #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ #define CONFIG_SYS_I2C_SOFT_SPEED 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE 0xFE
-#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
Why you delete here this adapter? You can use now in the new Framework Hard and soft i2c adapter ...
Yes, soft adapter should be kept.
#define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD #define CONFIG_I2C_MULTI_BUS #define CONFIG_SOFT_I2C_MULTI_BUS #define CONFIG_SYS_MAX_I2C_BUS 15
+#define CONFIG_HARD_I2C
No longer needed
Ok
+#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x0
This defines please rename, as posted in previous EMail ...
Ok
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[5]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1 +#define CONFIG_SYS_I2C_BUSSES {{0, {{{0, "S3C24X0"}, 0x00, 5}}}, \
You use here only one bus, so you do not need to define this here.
Just testing, I will remove it.
}
+#define CONFIG_SYS_NUM_I2C_BUSSES 1
#include<asm/arch/gpio.h>
/* I2C PMIC */
bye, Heiko -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Best regards, Piotr Wilczek

This patchset brings new I2C framework to Samsung Trats board.
I2C clock, spacing and pinmux are added for Exynos4. The s3c24x0 i2c driver is modified to support both Exynos4.
The s3c24x0 i2c driver is modiefied for the new I2C framework. Configs for VCMA9.h and smdk5250.h boards are modified. Boards compile successfully but were not tested.
New i2c framework is enabled and tested on Samsung Trats board.
Piotr Wilczek (6): exynos:clock: Add i2c clock exynos:cpu: Add Exynos4 I2C spacing exynos:pinmux: Add pinmux support for i2c drivers:i2c: Modify I2C driver for Exynos4 drivers:i2c:s3c24x0: modify driver for new I2C framework arm:trats: add support for new I2C framework
arch/arm/cpu/armv7/exynos/clock.c | 17 +++ arch/arm/cpu/armv7/exynos/pinmux.c | 64 +++++++++++ arch/arm/include/asm/arch-exynos/cpu.h | 2 + board/samsung/smdk5250/smdk5250.c | 4 +- board/samsung/trats/trats.c | 17 +++- drivers/i2c/Makefile | 2 +- drivers/i2c/i2c_core.c | 5 + drivers/i2c/s3c24x0_i2c.c | 181 +++++++++++++++++++++++--------- include/configs/VCMA9.h | 11 ++- include/configs/smdk5250.h | 13 ++- include/configs/trats.h | 35 ++++--- 11 files changed, 266 insertions(+), 85 deletions(-)

This patch adds i2c clock for Exynos4
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- Changes for v2: - none --- arch/arm/cpu/armv7/exynos/clock.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 4f3b451..21e45d2 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -732,6 +732,21 @@ static unsigned long exynos5_get_i2c_clk(void) return aclk_66; }
+static unsigned long exynos4_get_i2c_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long sclk, aclk_100; + unsigned int ratio; + + sclk = get_pll_clk(APLL); + + ratio = (readl(&clk->div_top)) >> 4; + ratio &= 0xf; + aclk_100 = sclk / (ratio + 1); + return aclk_100; +} + unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) @@ -752,6 +767,8 @@ unsigned long get_i2c_clk(void) { if (cpu_is_exynos5()) { return exynos5_get_i2c_clk(); + } else if (cpu_is_exynos4()) { + return exynos4_get_i2c_clk(); } else { debug("I2C clock is not set for this CPU\n"); return 0;

This patch add the spacing for i2c for Exynos4
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- Changes for v2: - none --- arch/arm/include/asm/arch-exynos/cpu.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 2cd4ae1..3073ca1 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -28,6 +28,8 @@ #define EXYNOS4_ADDR_BASE 0x10000000
/* EXYNOS4 */ +#define EXYNOS4_I2C_SPACING 0x10000 + #define EXYNOS4_GPIO_PART3_BASE 0x03860000 #define EXYNOS4_PRO_ID 0x10000000 #define EXYNOS4_SYSREG_BASE 0x10010000

This patch add pinmux for I2C for Exynos4
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- Changes for v2: - none --- arch/arm/cpu/armv7/exynos/pinmux.c | 64 ++++++++++++++++++++++++++++++++++++ 1 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 7776add..44ce072 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -265,10 +265,74 @@ static int exynos5_pinmux_config(int peripheral, int flags) return 0; }
+static void exynos4_i2c_config(int peripheral, int flags) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1(); + + switch (peripheral) { + case PERIPH_ID_I2C0: + s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2)); + s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C1: + s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2)); + s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C2: + s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C3: + s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C4: + s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4)); + s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3)); + s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3)); + break; + } +} + +static int exynos4_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + exynos4_i2c_config(peripheral, flags); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + int exynos_pinmux_config(int peripheral, int flags) { if (cpu_is_exynos5()) return exynos5_pinmux_config(peripheral, flags); + else if (cpu_is_exynos4()) + return exynos4_pinmux_config(peripheral, flags); else { debug("pinmux functionality not supported\n"); return -1;

This patch modifies the S3C i2c driver to support both Exynos4 and Exynos5
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- Changes for v2: - none --- drivers/i2c/s3c24x0_i2c.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..90d297a 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,7 +27,7 @@ */
#include <common.h> -#ifdef CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> #include <asm/arch/cpu.h> #else @@ -62,7 +62,7 @@
static unsigned int g_current_bus; /* Stores Current I2C Bus */
-#ifndef CONFIG_EXYNOS5 +#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) { struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); @@ -121,7 +121,12 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)
static struct s3c24x0_i2c *get_base_i2c(void) { -#ifdef CONFIG_EXYNOS5 +#ifdef CONFIG_EXYNOS4 + struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() + + (EXYNOS4_I2C_SPACING + * g_current_bus)); + return i2c; +#elif defined CONFIG_EXYNOS5 struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() + (EXYNOS5_I2C_SPACING * g_current_bus)); @@ -134,7 +139,7 @@ static struct s3c24x0_i2c *get_base_i2c(void) static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { ulong freq, pres = 16, div; -#ifdef CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) freq = get_i2c_clk(); #else freq = get_PCLK(); @@ -188,7 +193,7 @@ unsigned int i2c_get_bus_num(void) void i2c_init(int speed, int slaveadd) { struct s3c24x0_i2c *i2c; -#ifndef CONFIG_EXYNOS5 +#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); #endif int i; @@ -204,7 +209,7 @@ void i2c_init(int speed, int slaveadd) i--; }
-#ifndef CONFIG_EXYNOS5 +#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) { #ifdef CONFIG_S3C2410 ulong old_gpecon = readl(&gpio->gpecon); @@ -248,7 +253,7 @@ void i2c_init(int speed, int slaveadd) writel(old_gpecon, &gpio->pgcon); #endif } -#endif /* #ifndef CONFIG_EXYNOS5 */ +#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ i2c_ch_init(i2c, speed, slaveadd); }

This patch modifies s3c24x0 driver for the new I2C framework. Configs of VCMA9.h and smdk5250.h boards are modified but not tested.
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- Changes for v2: - changed i2c related names to s3c24x0 driver specfic: CONFIG_MAX_I2C_NUM -> CONFIG_SYS_I2C_S3C24X0_MAX_NUM CONFIG_DRIVER_S3C24X0_I2C -> CONFIG_SYS_I2C_S3C24X0 CONFIG_SYS_I2C_SPEED/SLAVE -> CONFIG_SYS_I2C_S3C24X0_SPEED/SLAVE - removed CONFIG_HARD_I2C - removed g_current_bus and i2c_{get/set}_bus_num() functions - changed function get_base_i2c(void) to get_base_i2c(int bus) - made all functions static --- board/samsung/smdk5250/smdk5250.c | 4 +- drivers/i2c/Makefile | 2 +- drivers/i2c/i2c_core.c | 5 + drivers/i2c/s3c24x0_i2c.c | 164 ++++++++++++++++++++++++++---------- include/configs/VCMA9.h | 11 ++- include/configs/smdk5250.h | 13 ++-- 6 files changed, 140 insertions(+), 59 deletions(-)
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index a5816e4..0bc161a 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -178,7 +178,7 @@ static int board_i2c_init(void) { int i, err;
- for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) { + for (i = 0; i < CONFIG_SYS_I2C_S3C24X0_MAX_NUM; i++) { err = exynos_pinmux_config((PERIPH_ID_I2C0 + i), PINMUX_FLAG_NONE); if (err) { @@ -186,7 +186,7 @@ static int board_i2c_init(void) return err; } } - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + i2c_init(CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE); return 0; } #endif diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 2162173..09279d0 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -37,7 +37,7 @@ COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += omap24xx_i2c.o COBJS-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o COBJS-$(CONFIG_PPC4XX_I2C) += ppc4xx_i2c.o -COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o +COBJS-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o COBJS-$(CONFIG_TEGRA_I2C) += tegra_i2c.o COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c index d3b5a8d..143a062 100644 --- a/drivers/i2c/i2c_core.c +++ b/drivers/i2c/i2c_core.c @@ -10,6 +10,10 @@ extern struct i2c_adapter fsl_i2c_adap[]; #endif
+#ifdef CONFIG_SYS_I2C_S3C24X0 +extern struct i2c_adapter s3c24x0_i2c_adap[]; +#endif + #ifdef CONFIG_SYS_I2C_SOFT extern struct i2c_adapter soft_i2c_adap[]; #endif @@ -214,6 +218,7 @@ unsigned int i2c_get_bus_num(void) */ int i2c_set_bus_num(unsigned int bus) { + #ifndef CONFIG_SYS_I2C_DIRECT_BUS int i; uint8_t buf; diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a..101fd08 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -37,8 +37,6 @@ #include <i2c.h> #include "s3c24x0_i2c.h"
-#ifdef CONFIG_HARD_I2C - #define I2C_WRITE 0 #define I2C_READ 1
@@ -59,9 +57,6 @@
#define I2C_TIMEOUT 1 /* 1 second */
- -static unsigned int g_current_bus; /* Stores Current I2C Bus */ - #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) { @@ -119,17 +114,17 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
-static struct s3c24x0_i2c *get_base_i2c(void) +static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() + (EXYNOS4_I2C_SPACING - * g_current_bus)); + * bus)); return i2c; #elif defined CONFIG_EXYNOS5 struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() + (EXYNOS5_I2C_SPACING - * g_current_bus)); + * bus)); return i2c; #else return s3c24x0_get_base_i2c(); @@ -163,34 +158,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); }
-/* - * MULTI BUS I2C support - */ - -#ifdef CONFIG_I2C_MULTI_BUS -int i2c_set_bus_num(unsigned int bus) -{ - struct s3c24x0_i2c *i2c; - - if ((bus < 0) || (bus >= CONFIG_MAX_I2C_NUM)) { - debug("Bad bus: %d\n", bus); - return -1; - } - - g_current_bus = bus; - i2c = get_base_i2c(); - i2c_ch_init(i2c, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - - return 0; -} - -unsigned int i2c_get_bus_num(void) -{ - return g_current_bus; -} -#endif - -void i2c_init(int speed, int slaveadd) +static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { struct s3c24x0_i2c *i2c; #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) @@ -198,9 +166,7 @@ void i2c_init(int speed, int slaveadd) #endif int i;
- /* By default i2c channel 0 is the current bus */ - g_current_bus = 0; - i2c = get_base_i2c(); + i2c = get_base_i2c(adap->hwadapnr);
/* wait for some time to give previous transfer a chance to finish */ i = I2C_TIMEOUT * 1000; @@ -415,12 +381,12 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, return result; }
-int i2c_probe(uchar chip) +static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) { struct s3c24x0_i2c *i2c; uchar buf[1];
- i2c = get_base_i2c(); + i2c = get_base_i2c(adap->hwadapnr); buf[0] = 0;
/* @@ -431,7 +397,8 @@ int i2c_probe(uchar chip) return i2c_transfer(i2c, I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK; }
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) { struct s3c24x0_i2c *i2c; uchar xaddr[4]; @@ -465,7 +432,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c = get_base_i2c(); + i2c = get_base_i2c(adap->hwadapnr); ret = i2c_transfer(i2c, I2C_READ, chip << 1, &xaddr[4 - alen], alen, buffer, len); if (ret != 0) { @@ -475,7 +442,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) return 0; }
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) { struct s3c24x0_i2c *i2c; uchar xaddr[4]; @@ -507,9 +475,113 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c = get_base_i2c(); + i2c = get_base_i2c(adap->hwadapnr); return (i2c_transfer (i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, len) != 0); } -#endif /* CONFIG_HARD_I2C */ + +struct i2c_adapter s3c24x0_i2c_adap[] = { + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 0, + .name = "s3c24x0-i2c" + }, +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 1 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 1, + .name = "s3c24x0-i2c#1" + }, +#endif +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 2 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 2, + .name = "s3c24x0-i2c#2" + }, +#endif +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 3 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 3, + .name = "s3c24x0-i2c#3" + }, +#endif +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 4 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 4, + .name = "s3c24x0-i2c#4" + }, +#endif +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 5 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 5, + .name = "s3c24x0-i2c#5" + }, +#endif +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 6 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 6, + .name = "s3c24x0-i2c#6" + }, +#endif +#if CONFIG_SYS_I2C_S3C24X0_MAX_NUM > 7 + { + .init = s3c24x0_i2c_init, + .probe = s3c24x0_i2c_probe, + .read = s3c24x0_i2c_read, + .write = s3c24x0_i2c_write, + .speed = CONFIG_SYS_I2C_S3C24X0_SPEED, + .slaveaddr = CONFIG_SYS_I2C_S3C24X0_SLAVE, + .init_done = 0, + .hwadapnr = 7, + .name = "s3c24x0-i2c#7" + }, +#endif +}; diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index fb7d922..23c9285 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -88,12 +88,15 @@ * the MPL VCMA9 is equipped with an ATMEL 24C256 EEPROM at * address 0x50 with 16bit addressing */ -#define CONFIG_HARD_I2C /* I2C with hardware support */ -#define CONFIG_SYS_I2C_SPEED 100000 /* I2C speed */ -#define CONFIG_SYS_I2C_SLAVE 0x7F /* I2C slave addr */ +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* I2C speed */ +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x7F /* I2C slave addr */
/* we use the built-in I2C controller */ -#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_SYS_I2C_S3C24X0 + +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index c0f8622..2de5d5c 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -196,13 +196,14 @@
/* I2C */ #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_HARD_I2C #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_SPEED 100000 /* 100 Kbps */ -#define CONFIG_DRIVER_S3C24X0_I2C -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_MAX_I2C_NUM 8 -#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_MAX_NUM 8 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 +#define CONFIG_SYS_I2C_ADAPTERS {&s3c24x0_i2c_adap[0]} +#define CONFIG_SYS_NUM_I2C_ADAPTERS 1
/* Ethernet Controllor Driver */ #ifdef CONFIG_CMD_NET

This enables new i2c framework on Trats board. Hardware s3c24x0 i2c driver is used instead of software i2c.
Signed-off-by: Piotr Wilczek p.wilczek@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com CC: Minkyu Kang mk7.kang@samsung.com --- Changes for v2: - hardware i2c outputs configuration moved to i2c_init_board(void) function - used define instead of fix number on i2c_set_bus_num(); - keep soft_i2c_adap[0] - changed i2c related names to s3c24x0 driver specfic: CONFIG_MAX_I2C_NUM -> CONFIG_SYS_I2C_S3C24X0_MAX_NUM CONFIG_DRIVER_S3C24X0_I2C -> CONFIG_SYS_I2C_S3C24X0 CONFIG_SYS_I2C_SPEED/SLAVE -> CONFIG_SYS_I2C_S3C24X0_SPEED/SLAVE - removed CONFIG_SYS_I2C_BUSSES --- board/samsung/trats/trats.c | 17 +++++++++++++---- include/configs/trats.h | 35 +++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index e11a892..393a910 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -24,8 +24,10 @@ */
#include <common.h> +#include <i2c.h> #include <lcd.h> #include <asm/io.h> +#include <asm/arch/pinmux.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> #include <asm/arch/mmc.h> @@ -77,14 +79,17 @@ int board_init(void)
void i2c_init_board(void) { - struct exynos4_gpio_part1 *gpio1 = - (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + int err; struct exynos4_gpio_part2 *gpio2 = (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
/* I2C_5 -> PMIC */ - s5p_gpio_direction_output(&gpio1->b, 7, 1); - s5p_gpio_direction_output(&gpio1->b, 6, 1); + err = exynos_pinmux_config(I2C_5, PINMUX_FLAG_NONE); + if (err) { + debug("I2C%d not configured\n", (I2C_5)); + return; + } + /* I2C_9 -> FG */ s5p_gpio_direction_output(&gpio2->y4, 0, 1); s5p_gpio_direction_output(&gpio2->y4, 1, 1); @@ -415,6 +420,8 @@ static int lcd_power(void) int ret = 0; struct pmic *p = get_pmic();
+ i2c_set_bus_num(CONFIG_SYS_I2C_PMIC_BUS_NUM); + if (pmic_probe(p)) return 0;
@@ -475,6 +482,8 @@ static int mipi_power(void) int ret = 0; struct pmic *p = get_pmic();
+ i2c_set_bus_num(CONFIG_SYS_I2C_PMIC_BUS_NUM); + if (pmic_probe(p)) return 0;
diff --git a/include/configs/trats.h b/include/configs/trats.h index 106fd37..1083e9b 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -33,6 +33,7 @@ #define CONFIG_SAMSUNG /* in a SAMSUNG core */ #define CONFIG_S5P /* which is in a S5P Family */ #define CONFIG_EXYNOS4210 /* which is in a EXYNOS4210 */ +#define CONFIG_EXYNOS4 #define CONFIG_TRATS /* working with TRATS */ #define CONFIG_TIZEN /* TIZEN lib */
@@ -211,31 +212,33 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_CACHELINE_SIZE 32
- #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ #define CONFIG_SYS_I2C_SOFT_SPEED 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE 0xFE -#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]} #define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SOFT_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS 15 - -#include <asm/arch/gpio.h>
-/* I2C PMIC */ -#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_part1_get_nr(b, 7) -#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_part1_get_nr(b, 6) +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_MAX_NUM 8 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 +#define CONFIG_CMD_I2C + +#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0], \ + &s3c24x0_i2c_adap[5], \ + } +#define CONFIG_SYS_NUM_I2C_ADAPTERS 2 +#define CONFIG_SYS_I2C_BUSSES {{0, {{{0, "SOFT"}, 0x00, 0} } }, \ + {1, {{{0, "S3C24X0"}, 0x00, 5} } }, \ + } +#define CONFIG_SYS_NUM_I2C_BUSSES 2 +#define CONFIG_SYS_I2C_PMIC_BUS_NUM 1
-/* I2C FG */ -#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_part2_get_nr(y4, 1) -#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_part2_get_nr(y4, 0) +#include <asm/arch/gpio.h>
-#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin() -#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin() -#define I2C_INIT multi_i2c_init() +#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part2_get_nr(y4, 1) +#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part2_get_nr(y4, 0)
#define CONFIG_PMIC #define CONFIG_PMIC_I2C
participants (2)
-
Heiko Schocher
-
Piotr Wilczek