From 2d8f1e27695a8a9a3ed863a510be58284b6b411c Mon Sep 17 00:00:00 2001 From: Piotr Wilczek Date: Wed, 20 Nov 2013 10:43:49 +0100 Subject: driver:i2c:s3c24x0: adapt driver to new i2c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adapts the s3c24x0 driver to the new i2c framework. Config file is modified for all the boards that use the driver. Signed-off-by: Piotr Wilczek Signed-off-by: Kyungmin Park CC: Minkyu Kang CC: Heiko Schocher CC: Inderpal Singh CC: David Müller CC: Chander Kashyap CC: Lukasz Majewski Tested-by: Naveen Krishna Chatradhi Reviewed-by: Naveen Krishna Chatradhi diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c index 6bcc883..6aa0509 100644 --- a/board/samsung/smdk5250/exynos5-dt.c +++ b/board/samsung/smdk5250/exynos5-dt.c @@ -150,8 +150,6 @@ int power_init_board(void) set_ps_hold_ctrl(); - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - if (pmic_init(I2C_PMIC)) return -1; diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index 7012c13..44be5fc 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -57,15 +57,18 @@ 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 -> Adapter 0 */ - s5p_gpio_direction_output(&gpio1->b, 7, 1); - s5p_gpio_direction_output(&gpio1->b, 6, 1); - /* I2C_9 -> FG -> Adapter 1 */ + /* I2C_5 -> PMIC */ + err = exynos_pinmux_config(PERIPH_ID_I2C5, PINMUX_FLAG_NONE); + if (err) { + debug("I2C%d not configured\n", (I2C_5)); + return; + } + + /* I2C_8 -> FG */ s5p_gpio_direction_output(&gpio2->y4, 0, 1); s5p_gpio_direction_output(&gpio2->y4, 1, 1); } @@ -290,10 +293,10 @@ int power_init_board(void) * The FUEL_GAUGE is marked as I2C9 on the schematic, but connected * to logical I2C adapter 1 */ - ret = pmic_init(I2C_0); + ret = pmic_init(I2C_5); ret |= pmic_init_max8997(); - ret |= power_fg_init(I2C_1); - ret |= power_muic_init(I2C_0); + ret |= power_fg_init(I2C_8); + ret |= power_muic_init(I2C_5); ret |= power_bat_init(0); if (ret) return ret; diff --git a/board/samsung/trats2/trats2.c b/board/samsung/trats2/trats2.c index d44d825..8df85ee 100644 --- a/board/samsung/trats2/trats2.c +++ b/board/samsung/trats2/trats2.c @@ -115,12 +115,17 @@ static void board_external_gpio_init(void) #ifdef CONFIG_SYS_I2C_INIT_BOARD static void board_init_i2c(void) { + int err; + gpio1 = (struct exynos4x12_gpio_part1 *)EXYNOS4X12_GPIO_PART1_BASE; gpio2 = (struct exynos4x12_gpio_part2 *)EXYNOS4X12_GPIO_PART2_BASE; /* I2C_7 */ - s5p_gpio_direction_output(&gpio1->d0, 2, 1); - s5p_gpio_direction_output(&gpio1->d0, 3, 1); + err = exynos_pinmux_config(PERIPH_ID_I2C7, PINMUX_FLAG_NONE); + if (err) { + debug("I2C%d not configured\n", (I2C_7)); + return; + } /* I2C_8 */ s5p_gpio_direction_output(&gpio1->f1, 4, 1); @@ -132,6 +137,24 @@ static void board_init_i2c(void) } #endif +#ifdef CONFIG_SYS_I2C_SOFT +int get_soft_i2c_scl_pin(void) +{ + if (I2C_ADAP_HWNR) + return exynos4x12_gpio_part2_get_nr(m2, 1); /* I2C9 */ + else + return exynos4x12_gpio_part1_get_nr(f1, 4); /* I2C8 */ +} + +int get_soft_i2c_sda_pin(void) +{ + if (I2C_ADAP_HWNR) + return exynos4x12_gpio_part2_get_nr(m2, 0); /* I2C9 */ + else + return exynos4x12_gpio_part1_get_nr(f1, 5); /* I2C8 */ +} +#endif + int board_early_init_f(void) { check_hw_revision(); @@ -167,11 +190,11 @@ int power_init_board(void) #ifdef CONFIG_SYS_I2C_INIT_BOARD board_init_i2c(); #endif - pmic_init(I2C_0); /* I2C adapter 0 - bus name I2C_5 */ + pmic_init(I2C_7); /* I2C adapter 7 - bus name s3c24x0_7 */ pmic_init_max77686(); - pmic_init_max77693(I2C_2); /* I2C adapter 2 - bus name I2C_10 */ - power_muic_init(I2C_2); /* I2C adapter 2 - bus name I2C_10 */ - power_fg_init(I2C_1); /* I2C adapter 1 - bus name I2C_9 */ + pmic_init_max77693(I2C_9); /* I2C adapter 9 - bus name soft1 */ + power_muic_init(I2C_9); /* I2C adapter 9 - bus name soft1 */ + power_fg_init(I2C_8); /* I2C adapter 8 - bus name soft0 */ power_bat_init(0); p_chrg = pmic_get("MAX77693_PMIC"); diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 553b519..fa3a875 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_I2C_MV) += mv_i2c.o obj-$(CONFIG_I2C_MXS) += mxs_i2c.o obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o -obj-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o obj-$(CONFIG_U8500_I2C) += u8500_i2c.o obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o @@ -24,6 +23,7 @@ obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o +obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index f77a9d1..5dc35e7 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -23,8 +23,6 @@ #include #include "s3c24x0_i2c.h" -#ifdef CONFIG_HARD_I2C - #define I2C_WRITE 0 #define I2C_READ 1 @@ -127,7 +125,6 @@ * 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"))); @@ -254,17 +251,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(); @@ -298,7 +295,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); } -#ifdef CONFIG_I2C_MULTI_BUS static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) { struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; @@ -330,7 +326,6 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) } return -1; } -#endif static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) { @@ -401,49 +396,18 @@ 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 s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { struct s3c24x0_i2c *i2c; + struct s3c24x0_i2c_bus *bus; + #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); #endif ulong start_time = get_timer(0); /* By default i2c channel 0 is the current bus */ - g_current_bus = 0; - i2c = get_base_i2c(); + i2c = get_base_i2c(adap->hwadapnr); /* * In case the previous transfer is still going, wait to give it a @@ -505,6 +469,10 @@ void i2c_init(int speed, int slaveadd) } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ i2c_ch_init(i2c, speed, slaveadd); + + bus = &i2c_bus[adap->hwadapnr]; + bus->active = true; + bus->regs = i2c; } /* @@ -728,6 +696,29 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c, return rv; } +static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, + unsigned int speed) +{ + struct s3c24x0_i2c_bus *i2c_bus; + + i2c_bus = get_bus(adap->hwadapnr); + 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_S3C24X0_SLAVE); + } + + return 0; +} + /* * cmd_type is 0 for write, 1 for read. * @@ -840,13 +831,13 @@ bailout: return result; } -int i2c_probe(uchar chip) +static int s3c24x0_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 = get_bus(adap->hwadapnr); if (!i2c_bus) return -1; buf[0] = 0; @@ -864,11 +855,11 @@ int i2c_probe(uchar chip) I2C_READ, chip << 1, 0, 0, buf, 1); } - return ret != 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_bus *i2c_bus; uchar xaddr[4]; @@ -902,7 +893,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 = get_bus(adap->hwadapnr); if (!i2c_bus) return -1; @@ -922,7 +913,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_bus *i2c_bus; uchar xaddr[4]; @@ -955,7 +947,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 = get_bus(adap->hwadapnr); if (!i2c_bus) return -1; @@ -1001,8 +993,8 @@ static void process_nodes(const void *blob, int node_list[], int count, bus->id = pinmux_decode_periph_id(blob, node); bus->clock_frequency = fdtdec_get_int(blob, node, - "clock-frequency", - CONFIG_SYS_I2C_SPEED); + "clock-frequency", + CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i; exynos_pinmux_config(bus->id, 0); @@ -1044,7 +1036,6 @@ int i2c_get_bus_num_fdt(int node) return -1; } -#ifdef CONFIG_I2C_MULTI_BUS int i2c_reset_port_fdt(const void *blob, int node) { struct s3c24x0_i2c_bus *i2c_bus; @@ -1068,12 +1059,61 @@ int i2c_reset_port_fdt(const void *blob, int node) hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, - CONFIG_SYS_I2C_SLAVE); + CONFIG_SYS_I2C_S3C24X0_SLAVE); } return 0; } #endif -#endif -#endif /* CONFIG_HARD_I2C */ +/* + * Register s3c24x0 i2c adapters + */ +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_0, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 0) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_1, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 1) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_2, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 2) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_3, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 3) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_4, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 4) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_5, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 5) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_6, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 6) +U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_7, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, + 7) diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index 79a6079..57b620d 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -73,12 +73,12 @@ * 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 /* we use the built-in I2C controller */ -#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* I2C speed */ +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x7F /* I2C slave addr */ #define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 45fa047..ea8753b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -214,13 +214,12 @@ /* I2C */ #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_HARD_I2C +#define CONFIG_SYS_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_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ +#define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_MAX_I2C_NUM 8 -#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 #define CONFIG_I2C_EDID /* PMIC */ diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index bdefee1..0155322 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -249,13 +249,13 @@ /* I2C */ #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_HARD_I2C +#define CONFIG_SYS_I2C #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_SPEED 100000 /* 100 Kbps */ -#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ +#define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_I2C_MULTI_BUS #define CONFIG_MAX_I2C_NUM 8 -#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 #define CONFIG_I2C_EDID /* PMIC */ diff --git a/include/configs/trats.h b/include/configs/trats.h index 3d080c4..f163303 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -16,6 +16,7 @@ */ #define CONFIG_SAMSUNG /* in a SAMSUNG core */ #define CONFIG_S5P /* which is in a S5P Family */ +#define CONFIG_EXYNOS4 /* which is in a EXYNOS4XXX */ #define CONFIG_EXYNOS4210 /* which is in a EXYNOS4210 */ #define CONFIG_TRATS /* working with TRATS */ #define CONFIG_TIZEN /* TIZEN lib */ @@ -268,31 +269,21 @@ #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0xFE +#define CONFIG_MAX_I2C_NUM 8 #define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ #define CONFIG_SYS_I2C_SOFT_SPEED 50000 -#define CONFIG_SYS_I2C_SOFT_SLAVE 0xFE -#define I2C_SOFT_DECLARATIONS2 -#define CONFIG_SYS_I2C_SOFT_SPEED_2 50000 -#define CONFIG_SYS_I2C_SOFT_SLAVE_2 0x7F +#define CONFIG_SYS_I2C_SOFT_SLAVE 0x7F #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 -/* 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) - /* 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) - -#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_POWER #define CONFIG_POWER_I2C diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 0e93836..3bcdfb1 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -260,30 +260,25 @@ #include #define CONFIG_SYS_I2C -#define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_SOFT #define CONFIG_SYS_I2C_SOFT_SPEED 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE 0x00 #define I2C_SOFT_DECLARATIONS2 #define CONFIG_SYS_I2C_SOFT_SPEED_2 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE_2 0x00 -#define I2C_SOFT_DECLARATIONS3 -#define CONFIG_SYS_I2C_SOFT_SPEED_3 50000 -#define CONFIG_SYS_I2C_SOFT_SLAVE_3 0x00 #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_SOFT_I2C_I2C5_SCL exynos4x12_gpio_part1_get_nr(d0, 3) -#define CONFIG_SOFT_I2C_I2C5_SDA exynos4x12_gpio_part1_get_nr(d0, 2) -#define CONFIG_SOFT_I2C_I2C9_SCL exynos4x12_gpio_part1_get_nr(f1, 4) -#define CONFIG_SOFT_I2C_I2C9_SDA exynos4x12_gpio_part1_get_nr(f1, 5) -#define CONFIG_SOFT_I2C_I2C10_SCL exynos4x12_gpio_part2_get_nr(m2, 1) -#define CONFIG_SOFT_I2C_I2C10_SDA exynos4x12_gpio_part2_get_nr(m2, 0) -#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() + +#ifndef __ASSEMBLY__ +int get_soft_i2c_scl_pin(void); +int get_soft_i2c_sda_pin(void); +#endif +#define CONFIG_SOFT_I2C_GPIO_SCL get_soft_i2c_scl_pin() +#define CONFIG_SOFT_I2C_GPIO_SDA get_soft_i2c_sda_pin() /* POWER */ #define CONFIG_POWER -- cgit v0.10.2 From a6756bbdac43474193472b43309626e2c28d8100 Mon Sep 17 00:00:00 2001 From: Piotr Wilczek Date: Wed, 20 Nov 2013 10:43:50 +0100 Subject: driver:i2c:s3c24x0: fix clock init for hsi2c Fix clock value initialisation for Exynos other than Exynos5 for hsi2c. Signed-off-by: Piotr Wilczek Signed-off-by: Kyungmin Park Cc: Minkyu Kang Cc: Heiko Schocher diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 5dc35e7..1e9dba0 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -303,8 +303,10 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) unsigned int i = 0, utemp0 = 0, utemp1 = 0; unsigned int t_ftl_cycle; -#if defined CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) clkin = get_i2c_clk(); +#else + clkin = get_PCLK(); #endif /* FPCLK / FI2C = * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE -- cgit v0.10.2 From e6d3ab890950c284091ba11042056dff4d464a27 Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Mon, 2 Dec 2013 16:02:56 +0800 Subject: i2c: fti2c010: cosmetic: coding style cleanup Coding style cleanup Signed-off-by: Kuo-Jung Su Cc: Heiko Schocher diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index ddeb941..ec6afc9 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -18,22 +18,23 @@ #endif #ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED 50000 +#define CONFIG_SYS_I2C_SPEED 5000 #endif -#ifndef CONFIG_FTI2C010_FREQ -#define CONFIG_FTI2C010_FREQ clk_get_rate("I2C") +#ifndef CONFIG_FTI2C010_CLOCK +#define CONFIG_FTI2C010_CLOCK clk_get_rate("I2C") #endif -/* command timeout */ -#define CFG_CMD_TIMEOUT 10 /* ms */ +#ifndef CONFIG_FTI2C010_TIMEOUT +#define CONFIG_FTI2C010_TIMEOUT 10 /* ms */ +#endif -/* 7-bit chip address + 1-bit read/write */ -#define I2C_RD(chip) ((((chip) << 1) & 0xff) | 1) -#define I2C_WR(chip) (((chip) << 1) & 0xff) +/* 7-bit dev address + 1-bit read/write */ +#define I2C_RD(dev) ((((dev) << 1) & 0xfe) | 1) +#define I2C_WR(dev) (((dev) << 1) & 0xfe) struct fti2c010_chip { - void __iomem *regs; + struct fti2c010_regs *regs; uint bus; uint speed; }; @@ -41,25 +42,25 @@ struct fti2c010_chip { static struct fti2c010_chip chip_list[] = { { .bus = 0, - .regs = (void __iomem *)CONFIG_FTI2C010_BASE, + .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE, }, #ifdef CONFIG_I2C_MULTI_BUS # ifdef CONFIG_FTI2C010_BASE1 { .bus = 1, - .regs = (void __iomem *)CONFIG_FTI2C010_BASE1, + .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE1, }, # endif # ifdef CONFIG_FTI2C010_BASE2 { .bus = 2, - .regs = (void __iomem *)CONFIG_FTI2C010_BASE2, + .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE2, }, # endif # ifdef CONFIG_FTI2C010_BASE3 { .bus = 3, - .regs = (void __iomem *)CONFIG_FTI2C010_BASE3, + .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE3, }, # endif #endif /* #ifdef CONFIG_I2C_MULTI_BUS */ @@ -73,7 +74,7 @@ static int fti2c010_wait(uint32_t mask) uint32_t stat, ts; struct fti2c010_regs *regs = curr->regs; - for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { + for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { stat = readl(®s->sr); if ((stat & mask) == mask) { ret = 0; @@ -324,7 +325,7 @@ uint i2c_get_bus_num(void) int i2c_set_bus_speed(uint speed) { struct fti2c010_regs *regs = curr->regs; - uint clk = CONFIG_FTI2C010_FREQ; + uint clk = CONFIG_FTI2C010_CLOCK; uint gsr = 0, tsr = 32; uint spd, div; -- cgit v0.10.2 From 49f4c762e4a14cb4b8088bcc0726d7b1ce80e014 Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Mon, 2 Dec 2013 16:02:57 +0800 Subject: i2c: fti2c010: migrate to new i2c model Replace the legacy i2c model with the new one. Signed-off-by: Kuo-Jung Su Cc: Heiko Schocher diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index ec6afc9..eccc1da 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -13,14 +13,14 @@ #include "fti2c010.h" -#ifndef CONFIG_HARD_I2C -#error "fti2c010: CONFIG_HARD_I2C is not defined" -#endif - #ifndef CONFIG_SYS_I2C_SPEED #define CONFIG_SYS_I2C_SPEED 5000 #endif +#ifndef CONFIG_SYS_I2C_SLAVE +#define CONFIG_SYS_I2C_SLAVE 0 +#endif + #ifndef CONFIG_FTI2C010_CLOCK #define CONFIG_FTI2C010_CLOCK clk_get_rate("I2C") #endif @@ -35,44 +35,54 @@ struct fti2c010_chip { struct fti2c010_regs *regs; - uint bus; - uint speed; }; static struct fti2c010_chip chip_list[] = { { - .bus = 0, .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE, }, -#ifdef CONFIG_I2C_MULTI_BUS -# ifdef CONFIG_FTI2C010_BASE1 +#ifdef CONFIG_FTI2C010_BASE1 { - .bus = 1, .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE1, }, -# endif -# ifdef CONFIG_FTI2C010_BASE2 +#endif +#ifdef CONFIG_FTI2C010_BASE2 { - .bus = 2, .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE2, }, -# endif -# ifdef CONFIG_FTI2C010_BASE3 +#endif +#ifdef CONFIG_FTI2C010_BASE3 { - .bus = 3, .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE3, }, -# endif -#endif /* #ifdef CONFIG_I2C_MULTI_BUS */ +#endif }; -static struct fti2c010_chip *curr = chip_list; +static int fti2c010_reset(struct fti2c010_chip *chip) +{ + ulong ts; + int ret = -1; + struct fti2c010_regs *regs = chip->regs; -static int fti2c010_wait(uint32_t mask) + writel(CR_I2CRST, ®s->cr); + for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { + if (!(readl(®s->cr) & CR_I2CRST)) { + ret = 0; + break; + } + } + + if (ret) + printf("fti2c010: reset timeout\n"); + + return ret; +} + +static int fti2c010_wait(struct fti2c010_chip *chip, uint32_t mask) { int ret = -1; uint32_t stat, ts; - struct fti2c010_regs *regs = curr->regs; + struct fti2c010_regs *regs = chip->regs; for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { stat = readl(®s->sr); @@ -85,74 +95,97 @@ static int fti2c010_wait(uint32_t mask) return ret; } -/* - * u-boot I2C API - */ +static unsigned int set_i2c_bus_speed(struct fti2c010_chip *chip, + unsigned int speed) +{ + struct fti2c010_regs *regs = chip->regs; + unsigned int clk = CONFIG_FTI2C010_CLOCK; + unsigned int gsr = 0; + unsigned int tsr = 32; + unsigned int div, rate; + + for (div = 0; div < 0x3ffff; ++div) { + /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ + rate = clk / (2 * (div + 2) + gsr); + if (rate <= speed) + break; + } + + writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); + writel(CDR_DIV(div), ®s->cdr); + + return rate; +} /* * Initialization, must be called once on start up, may be called * repeatedly to change the speed and slave addresses. */ -void i2c_init(int speed, int slaveaddr) +static void fti2c010_init(struct i2c_adapter *adap, int speed, int slaveaddr) { - if (speed || !curr->speed) - i2c_set_bus_speed(speed); + struct fti2c010_chip *chip = chip_list + adap->hwadapnr; - /* if slave mode disabled */ - if (!slaveaddr) + if (adap->init_done) return; - /* - * TODO: - * Implement slave mode, but is it really necessary? - */ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + /* Call board specific i2c bus reset routine before accessing the + * environment, which might be in a chip on that bus. For details + * about this problem see doc/I2C_Edge_Conditions. + */ + i2c_init_board(); +#endif + + /* master init */ + + fti2c010_reset(chip); + + set_i2c_bus_speed(chip, speed); + + /* slave init, don't care */ + +#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT + /* Call board specific i2c bus reset routine AFTER the bus has been + * initialized. Use either this callpoint or i2c_init_board; + * which is called before fti2c010_init operations. + * For details about this problem see doc/I2C_Edge_Conditions. + */ + i2c_board_late_init(); +#endif } /* * Probe the given I2C chip address. Returns 0 if a chip responded, * not 0 on failure. */ -int i2c_probe(uchar chip) +static int fti2c010_probe(struct i2c_adapter *adap, u8 dev) { + struct fti2c010_chip *chip = chip_list + adap->hwadapnr; + struct fti2c010_regs *regs = chip->regs; int ret; - struct fti2c010_regs *regs = curr->regs; - - i2c_init(0, 0); /* 1. Select slave device (7bits Address + 1bit R/W) */ - writel(I2C_WR(chip), ®s->dr); + writel(I2C_WR(dev), ®s->dr); writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) return ret; /* 2. Select device register */ writel(0, ®s->dr); writel(CR_ENABLE | CR_TBEN, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); return ret; } -/* - * Read/Write interface: - * chip: I2C chip address, range 0..127 - * addr: Memory (register) address within the chip - * alen: Number of bytes to use for addr (typically 1, 2 for larger - * memories, 0 for register type devices with only one - * register) - * buffer: Where to read/write the data - * len: How many bytes to read/write - * - * Returns: 0 on success, not 0 on failure - */ -int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +static int fti2c010_read(struct i2c_adapter *adap, + u8 dev, uint addr, int alen, uchar *buf, int len) { + struct fti2c010_chip *chip = chip_list + adap->hwadapnr; + struct fti2c010_regs *regs = chip->regs; int ret, pos; uchar paddr[4]; - struct fti2c010_regs *regs = curr->regs; - - i2c_init(0, 0); paddr[0] = (addr >> 0) & 0xFF; paddr[1] = (addr >> 8) & 0xFF; @@ -164,9 +197,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) */ /* A.1 Select slave device (7bits Address + 1bit R/W) */ - writel(I2C_WR(chip), ®s->dr); + writel(I2C_WR(dev), ®s->dr); writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) return ret; @@ -176,7 +209,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) writel(paddr[pos], ®s->dr); writel(ctrl, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) return ret; } @@ -186,9 +219,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) */ /* B.1 Select slave device (7bits Address + 1bit R/W) */ - writel(I2C_RD(chip), ®s->dr); + writel(I2C_RD(dev), ®s->dr); writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) return ret; @@ -202,7 +235,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) stat |= SR_ACK; } writel(ctrl, ®s->cr); - ret = fti2c010_wait(stat); + ret = fti2c010_wait(chip, stat); if (ret) break; buf[pos] = (uchar)(readl(®s->dr) & 0xFF); @@ -211,25 +244,13 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) return ret; } -/* - * Read/Write interface: - * chip: I2C chip address, range 0..127 - * addr: Memory (register) address within the chip - * alen: Number of bytes to use for addr (typically 1, 2 for larger - * memories, 0 for register type devices with only one - * register) - * buffer: Where to read/write the data - * len: How many bytes to read/write - * - * Returns: 0 on success, not 0 on failure - */ -int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) +static int fti2c010_write(struct i2c_adapter *adap, + u8 dev, uint addr, int alen, u8 *buf, int len) { + struct fti2c010_chip *chip = chip_list + adap->hwadapnr; + struct fti2c010_regs *regs = chip->regs; int ret, pos; uchar paddr[4]; - struct fti2c010_regs *regs = curr->regs; - - i2c_init(0, 0); paddr[0] = (addr >> 0) & 0xFF; paddr[1] = (addr >> 8) & 0xFF; @@ -241,9 +262,9 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) * * A.1 Select slave device (7bits Address + 1bit R/W) */ - writel(I2C_WR(chip), ®s->dr); + writel(I2C_WR(dev), ®s->dr); writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) return ret; @@ -253,7 +274,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) writel(paddr[pos], ®s->dr); writel(ctrl, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) return ret; } @@ -268,7 +289,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) ctrl |= CR_STOP; writel(buf[pos], ®s->dr); writel(ctrl, ®s->cr); - ret = fti2c010_wait(SR_DT); + ret = fti2c010_wait(chip, SR_DT); if (ret) break; } @@ -276,94 +297,40 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) return ret; } -/* - * Functions for setting the current I2C bus and its speed - */ -#ifdef CONFIG_I2C_MULTI_BUS - -/* - * i2c_set_bus_num: - * - * Change the active I2C bus. Subsequent read/write calls will - * go to this one. - * - * bus - bus index, zero based - * - * Returns: 0 on success, not 0 on failure - */ -int i2c_set_bus_num(uint bus) -{ - if (bus >= ARRAY_SIZE(chip_list)) - return -1; - curr = chip_list + bus; - i2c_init(0, 0); - return 0; -} - -/* - * i2c_get_bus_num: - * - * Returns index of currently active I2C bus. Zero-based. - */ - -uint i2c_get_bus_num(void) -{ - return curr->bus; -} - -#endif /* #ifdef CONFIG_I2C_MULTI_BUS */ - -/* - * i2c_set_bus_speed: - * - * Change the speed of the active I2C bus - * - * speed - bus speed in Hz - * - * Returns: 0 on success, not 0 on failure - */ -int i2c_set_bus_speed(uint speed) +static unsigned int fti2c010_set_bus_speed(struct i2c_adapter *adap, + unsigned int speed) { - struct fti2c010_regs *regs = curr->regs; - uint clk = CONFIG_FTI2C010_CLOCK; - uint gsr = 0, tsr = 32; - uint spd, div; - - if (!speed) - speed = CONFIG_SYS_I2C_SPEED; - - for (div = 0; div < 0x3ffff; ++div) { - /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ - spd = clk / (2 * (div + 2) + gsr); - if (spd <= speed) - break; - } - - if (curr->speed == spd) - return 0; - - writel(CR_I2CRST, ®s->cr); - mdelay(100); - if (readl(®s->cr) & CR_I2CRST) { - printf("fti2c010: reset timeout\n"); - return -1; - } - - curr->speed = spd; + struct fti2c010_chip *chip = chip_list + adap->hwadapnr; + int ret; - writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); - writel(CDR_DIV(div), ®s->cdr); + fti2c010_reset(chip); + ret = set_i2c_bus_speed(chip, speed); - return 0; + return ret; } /* - * i2c_get_bus_speed: - * - * Returns speed of currently active I2C bus in Hz + * Register i2c adapters */ - -uint i2c_get_bus_speed(void) -{ - return curr->speed; -} +U_BOOT_I2C_ADAP_COMPLETE(i2c_0, fti2c010_init, fti2c010_probe, fti2c010_read, + fti2c010_write, fti2c010_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, + 0) +#ifdef CONFIG_FTI2C010_BASE1 +U_BOOT_I2C_ADAP_COMPLETE(i2c_1, fti2c010_init, fti2c010_probe, fti2c010_read, + fti2c010_write, fti2c010_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, + 1) +#endif +#ifdef CONFIG_FTI2C010_BASE2 +U_BOOT_I2C_ADAP_COMPLETE(i2c_2, fti2c010_init, fti2c010_probe, fti2c010_read, + fti2c010_write, fti2c010_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, + 2) +#endif +#ifdef CONFIG_FTI2C010_BASE3 +U_BOOT_I2C_ADAP_COMPLETE(i2c_3, fti2c010_init, fti2c010_probe, fti2c010_read, + fti2c010_write, fti2c010_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, + 3) +#endif -- cgit v0.10.2 From c727618d2cee0b848e5349ec923a5ef0bc3f0447 Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Mon, 2 Dec 2013 16:02:58 +0800 Subject: i2c: fti2c010: serial out r/w address in MSB order For a eeprom with a 2-bytes address (e.g., Ateml AT24C1024B), the r/w address should be serial out in MSB order. Signed-off-by: Kuo-Jung Su Cc: Heiko Schocher diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index eccc1da..fb9fa35 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -179,6 +179,22 @@ static int fti2c010_probe(struct i2c_adapter *adap, u8 dev) return ret; } +static void to_i2c_addr(u8 *buf, uint32_t addr, int alen) +{ + int i, shift; + + if (!buf || alen <= 0) + return; + + /* MSB first */ + i = 0; + shift = (alen - 1) * 8; + while (alen-- > 0) { + buf[i] = (u8)(addr >> shift); + shift -= 8; + } +} + static int fti2c010_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, uchar *buf, int len) { @@ -187,10 +203,7 @@ static int fti2c010_read(struct i2c_adapter *adap, int ret, pos; uchar paddr[4]; - paddr[0] = (addr >> 0) & 0xFF; - paddr[1] = (addr >> 8) & 0xFF; - paddr[2] = (addr >> 16) & 0xFF; - paddr[3] = (addr >> 24) & 0xFF; + to_i2c_addr(paddr, addr, alen); /* * Phase A. Set register address @@ -252,10 +265,7 @@ static int fti2c010_write(struct i2c_adapter *adap, int ret, pos; uchar paddr[4]; - paddr[0] = (addr >> 0) & 0xFF; - paddr[1] = (addr >> 8) & 0xFF; - paddr[2] = (addr >> 16) & 0xFF; - paddr[3] = (addr >> 24) & 0xFF; + to_i2c_addr(paddr, addr, alen); /* * Phase A. Set register address -- cgit v0.10.2 From 6ca6d080d6c75a88709e8ba8d1e6d776bc01b68d Mon Sep 17 00:00:00 2001 From: Kuo-Jung Su Date: Mon, 2 Dec 2013 16:02:59 +0800 Subject: cmd_eeprom: bug fix for i2c read/write The local pointer of address (i.e., addr) only gets referenced under SPI mode, and it won't be appropriate to pass only 1-byte addr[1] to i2c_read/i2c_write while CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 1. 1. In U-boot's I2C model, the address would be re-assembled to a byte string in MSB order inside I2C controller drivers. 2. The 'CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW' option which could be found at soft_i2c.c is always turned on in cmd_eeprom.c, the addr[0] always contains the device address with overflowed MSB address bits. Signed-off-by: Kuo-Jung Su Cc: Alexey Brodkin Cc: Jean-Christophe PLAGNIOL-VILLARD cc: Peter Tyser Cc: Heiko Schocher Cc: Wolfgang Denk Cc: Stefan Roese Cc: Mischa Jonker diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index 02539c4..3924805 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -161,7 +161,7 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt #if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) spi_read (addr, alen, buffer, len); #else - if (i2c_read (addr[0], addr[1], alen-1, buffer, len) != 0) + if (i2c_read(addr[0], offset, alen - 1, buffer, len)) rcode = 1; #endif buffer += len; @@ -339,7 +339,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn /* Write is enabled ... now write eeprom value. */ #endif - if (i2c_write (addr[0], addr[1], alen-1, buffer, len) != 0) + if (i2c_write(addr[0], offset, alen - 1, buffer, len)) rcode = 1; #endif -- cgit v0.10.2 From 92c23c9226a23548c875e4ba0e493a0aac172e25 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Thu, 28 Nov 2013 18:04:42 +0200 Subject: arm: omap: i2c: don't zero cnt in i2c_write Writing zero into I2Ci.I2C_CNT register causes random I2C failures in OMAP3 based devices. This seems to be related to the following advisory which apears in multiple erratas for OMAP3 SoCs (OMAP35xx, DM37xx), as well as OMAP4430 TRM: Advisory: I2C Module Does Not Allow 0-Byte Data Requests Details: When configured as the master, the I2C module does not allow 0-byte data transfers. Note: Programming I2Ci.I2C_CNT[15:0]: DCOUNT = 0 will cause undefined behavior. Workaround(s): No workaround. Do not use 0-byte data requests. The writes in question are unnecessary from a functional point of view. Most of them are done after I/O has finished, and the only one that preceds I/O (in i2c_probe()) is also unnecessary because a stop bit is sent before actual data transmission takes place. Therefore, remove all writes that zero the cnt register. Cc: Heiko Schocher Cc: Thomas Petazzoni Cc: Tom Rini Cc: Lubomir Popov Cc: Enric Balletbo Serra Signed-off-by: Nikita Kiryanov Tested-by: Thomas Petazzoni Tested-by: Lubomir Popov diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 3d38c03..c784004 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -158,7 +158,6 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) udelay(1000); flush_fifo(adap); writew(0xFFFF, &i2c_base->stat); - writew(0, &i2c_base->cnt); } static void flush_fifo(struct i2c_adapter *adap) @@ -198,8 +197,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip) return res; /* No data transfer, slave addr only */ - writew(0, &i2c_base->cnt); - /* Set slave address */ writew(chip, &i2c_base->sa); /* Stop bit needed here */ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | @@ -234,7 +231,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip) pr_exit: flush_fifo(adap); writew(0xFFFF, &i2c_base->stat); - writew(0, &i2c_base->cnt); return res; } @@ -372,7 +368,6 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, rd_exit: flush_fifo(adap); writew(0xFFFF, &i2c_base->stat); - writew(0, &i2c_base->cnt); return i2c_error; } @@ -473,7 +468,6 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, wr_exit: flush_fifo(adap); writew(0xFFFF, &i2c_base->stat); - writew(0, &i2c_base->cnt); return i2c_error; } -- cgit v0.10.2 From e717fc6d1a2b459ae8352f7af5945cc0c216ab1e Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Fri, 6 Dec 2013 12:12:38 +0530 Subject: i2c: samsung: register i2c busses for Exynso5420 and Exynos5250 This patch adds the U_BOOT_I2C_ADAP_COMPLETE defines for channels on Exynos5420 and Exynos5250 and also adds support for init function for hsi2c channels Signed-off-by: Naveen Krishna Chatradhi diff --git a/README b/README index 265e81e..3c233db 100644 --- a/README +++ b/README @@ -2125,6 +2125,12 @@ CBFS (Coreboot Filesystem) support - set CONFIG_SYS_I2C_ZYNQ_SPEED for speed setting - set CONFIG_SYS_I2C_ZYNQ_SLAVE for slave addr + - drivers/i2c/s3c24x0_i2c.c: + - activate this driver with CONFIG_SYS_I2C_S3C24X0 + - This driver adds i2c buses (11 for Exynos5250, Exynos5420 + 9 i2c buses for Exynos4 and 1 for S3C24X0 SoCs from Samsung) + with a fix speed from 100000 and the slave addr 0! + additional defines: CONFIG_SYS_NUM_I2C_BUSES diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 1e9dba0..fd328f0 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -721,6 +721,17 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, return 0; } +#ifdef CONFIG_EXYNOS5 +static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) +{ + /* This will override the speed selected in the fdt for that port */ + debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); + if (i2c_set_bus_speed(speed)) + printf("i2c_init: failed to init bus %d for speed = %d\n", + adap->hwadapnr, speed); +} +#endif + /* * cmd_type is 0 for write, 1 for read. * @@ -1071,51 +1082,168 @@ int i2c_reset_port_fdt(const void *blob, int node) /* * Register s3c24x0 i2c adapters */ -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_0, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 0) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_1, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 1) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_2, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 2) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_3, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 3) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_4, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 4) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_5, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 5) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_6, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 6) -U_BOOT_I2C_ADAP_COMPLETE(s3c24x0_7, s3c24x0_i2c_init, s3c24x0_i2c_probe, - s3c24x0_i2c_read, s3c24x0_i2c_write, - s3c24x0_i2c_set_bus_speed, - CONFIG_SYS_I2C_S3C24X0_SPEED, - CONFIG_SYS_I2C_S3C24X0_SLAVE, - 7) +#if defined(CONFIG_EXYNOS5420) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +U_BOOT_I2C_ADAP_COMPLETE(i2c09, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) +U_BOOT_I2C_ADAP_COMPLETE(i2c10, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) +#elif defined(CONFIG_EXYNOS5250) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +U_BOOT_I2C_ADAP_COMPLETE(i2c09, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) +U_BOOT_I2C_ADAP_COMPLETE(s3c10, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) +#elif defined(CONFIG_EXYNOS4) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +#else +U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, + s3c24x0_i2c_read, s3c24x0_i2c_write, + s3c24x0_i2c_set_bus_speed, + CONFIG_SYS_I2C_S3C24X0_SPEED, + CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +#endif -- cgit v0.10.2