
Hello Naveen,
Am 30.09.2013 08:58, schrieb Naveen Krishna Chatradhi:
This enables CONFIG_SYS_I2C on Samsung, updating existing s3c24x0 i2c driver to support this.
Note: Not for merge, Just for review and suggestions.
Signed-off-by: Naveen Krishna Chatradhich.naveen@samsung.com
drivers/i2c/Makefile | 2 +- drivers/i2c/s3c24x0_i2c.c | 156 +++++++++++++++++++++++++++++++-------------- 2 files changed, 108 insertions(+), 50 deletions(-)
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 37ccbd1..96448a6 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -20,7 +20,7 @@ COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o 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_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o +COBJS-$(CONFIG_SYS_I2C_S3C24X0_I2C) += s3c24x0_i2c.o
Please keep lists sorted.
COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 604d43d..89cb2d2 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -117,6 +117,8 @@
#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */
+DECLARE_GLOBAL_DATA_PTR;
- /*
- For SPL boot some boards need i2c before SDRAM is initialised so force
- variables to live in SRAM
@@ -126,6 +128,9 @@ static unsigned int g_current_bus __attribute__((section(".data"))); static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] __attribute__((section(".data"))); #endif +static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd); +static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *); +static void hsi2c_ch_init(struct s3c24x0_i2c_bus *);
/**
- Get a pointer to the given bus index
@@ -133,20 +138,40 @@ static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
- @bus_idx: Bus index to look up
- @return pointer to bus, or NULL if invalid or not available
*/ -static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +static struct s3c24x0_i2c_bus *s3c_i2c_get_bus(struct i2c_adapter *adap) {
- if (bus_idx< ARRAY_SIZE(i2c_bus)) {
struct s3c24x0_i2c_bus *bus;
- struct s3c24x0_i2c_bus *bus;
bus =&i2c_bus[bus_idx];
if (bus->active)
return bus;
- }
- bus =&i2c_bus[adap->hwadapnr];
- if (bus->active)
return bus;
- debug("Undefined bus: %d\n", bus_idx);
- debug("Undefined bus: %d\n", adap->hwadapnr); return NULL; }
+static unsigned int s3c_i2c_set_bus_speed(struct i2c_adapter *adap,
unsigned int speed)
+{
- struct s3c24x0_i2c_bus *i2c_bus;
- i2c_bus = s3c_i2c_get_bus(adap);
- if (!i2c_bus)
return -1;
- i2c_bus->clock_frequency = speed;
- if (i2c_bus->is_highspeed) {
if (hsi2c_get_clk_details(i2c_bus))
return -1;
hsi2c_ch_init(i2c_bus);
- } else {
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_SLAVE);
- }
- return 0;
+}
- #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) {
@@ -392,39 +417,7 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) hsi2c_ch_init(i2c_bus); }
-/*
- MULTI BUS I2C support
- */
-#ifdef CONFIG_I2C_MULTI_BUS -int i2c_set_bus_num(unsigned int bus) -{
- struct s3c24x0_i2c_bus *i2c_bus;
- i2c_bus = get_bus(bus);
- if (!i2c_bus)
return -1;
- g_current_bus = bus;
- if (i2c_bus->is_highspeed) {
if (hsi2c_get_clk_details(i2c_bus))
return -1;
hsi2c_ch_init(i2c_bus);
- } else {
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
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 s3c_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) { struct s3c24x0_i2c *i2c; #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) @@ -493,9 +486,15 @@ void i2c_init(int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
- i2c_ch_init(i2c, speed, slaveadd);
- /* This will override the speed selected in the fdt for that port */
- debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
- i2c_ch_init(i2c_bus->regs, speed, slaveaddr); }
+static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) +{
- i2c_set_bus_speed(speed);
+} /*
- Poll the appropriate bit of the fifo status register until the interface is
- ready to process the next byte or timeout expires.
@@ -829,13 +828,13 @@ bailout: return result; }
-int i2c_probe(uchar chip) +int s3c_i2c_probe(struct i2c_adapter *adap, uchar chip) { struct s3c24x0_i2c_bus *i2c_bus; uchar buf[1]; int ret;
- i2c_bus = get_bus(g_current_bus);
- i2c_bus = s3c_i2c_get_bus(adap); if (!i2c_bus) return -1; buf[0] = 0;
@@ -857,7 +856,8 @@ int i2c_probe(uchar chip) return ret != I2C_OK; }
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +int s3c_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, int alen,
{ struct s3c24x0_i2c_bus *i2c_bus; uchar xaddr[4];uchar *buffer, int len)
@@ -891,7 +891,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_bus = get_bus(g_current_bus);
- i2c_bus = s3c_i2c_get_bus(adap); if (!i2c_bus) return -1;
@@ -911,7 +911,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) +int s3c_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, int alen,
{ struct s3c24x0_i2c_bus *i2c_bus; uchar xaddr[4];uchar *buffer, int len)
@@ -944,7 +945,7 @@ 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_bus = get_bus(g_current_bus);
- i2c_bus = s3c_i2c_get_bus(adap); if (!i2c_bus) return -1;
@@ -1000,6 +1001,25 @@ static void process_nodes(const void *blob, int node_list[], int count, node_list[i] = -1; } } +void i2c_init_board() +{
- int node_list[CONFIG_MAX_I2C_NUM];
- const void *blob = gd->fdt_blob;
- int count;
- /* First get the normal i2c ports */
- count = fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_SAMSUNG_S3C2440_I2C, node_list,
CONFIG_MAX_I2C_NUM);
- process_nodes(blob, node_list, count, 0);
- /* Now look for high speed i2c ports */
- count = fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_SAMSUNG_EXYNOS5_I2C, node_list,
CONFIG_MAX_I2C_NUM);
- process_nodes(blob, node_list, count, 1);
+}
void board_i2c_init(const void *blob) { @@ -1017,9 +1037,10 @@ void board_i2c_init(const void *blob) COMPAT_SAMSUNG_EXYNOS5_I2C, node_list, CONFIG_MAX_I2C_NUM); process_nodes(blob, node_list, count, 1);
- }
+#ifndef CONFIG_SYS_I2C +/* TODO: fix this as per comments from upstream */
Why this? If we switch to the new i2c framework, please convert all boards, which using this driver ...
int i2c_get_bus_num_fdt(int node) { int i; @@ -1062,5 +1083,42 @@ int i2c_reset_port_fdt(const void *blob, int node) return 0; } #endif +#endif
+/*
- Register soft i2c adapters
- */
+U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 0)
+U_BOOT_I2C_ADAP_COMPLETE(s3c1, s3c_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 1)
+U_BOOT_I2C_ADAP_COMPLETE(s3c2, s3c_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 2)
+U_BOOT_I2C_ADAP_COMPLETE(s3c3, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 3)
+U_BOOT_I2C_ADAP_COMPLETE(s3c4, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 4)
+U_BOOT_I2C_ADAP_COMPLETE(s3c5, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 5)
+U_BOOT_I2C_ADAP_COMPLETE(s3c6, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 6)
+U_BOOT_I2C_ADAP_COMPLETE(s3c7, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 7)
+U_BOOT_I2C_ADAP_COMPLETE(s3c8, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 8)
+U_BOOT_I2C_ADAP_COMPLETE(s3c9, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
s3c_i2c_set_bus_speed, 100000, 0, 9)
+U_BOOT_I2C_ADAP_COMPLETE(s3c10, exynos_i2c_init, s3c_i2c_probe,
s3c_i2c_read, s3c_i2c_write,
#endif /* CONFIG_HARD_I2C */s3c_i2c_set_bus_speed, 100000, 0, 10)
Beside of that, it looks good to me.
Thanks for your work!
bye, Heiko