[U-Boot] [PATCH 0/6] dm: i2c: Set a timeline for conversion of i2c drivers

Driver-model I2C support was added about 2 years ago. So far a little over half of the driveres have been converted. This series sets a timeline for conversion of the rest by June next year.
The Samsung I2C driver was one of the first converted, but some boards still remain using the old subsystem. This series converts these over in an experimental way: disabling code that uses the old framework. This should provide more time for the maintainers to take action while allowing the conversion to be completed.
Simon Glass (6): arm: exynos: i2c: Convert exynos boards to use DM_I2C arm: samsung: Convert s5p_goni and smdkc100 to DM_I2C samsung: i2c: Drop old code from I2C driver samsung: i2c: Split the high-speed I2C code into a new driver dm: i2c: Add a note to I2C drivers which need conversion dm: Add timeline and guide for porting I2C drivers
arch/arm/Kconfig | 2 + board/samsung/common/misc.c | 4 + board/samsung/goni/goni.c | 7 +- board/samsung/trats/trats.c | 20 +- board/samsung/trats2/trats2.c | 18 +- board/samsung/universal_c210/universal.c | 22 +- configs/origen_defconfig | 1 + doc/driver-model/i2c-howto.txt | 56 ++ drivers/i2c/Makefile | 2 +- drivers/i2c/adi_i2c.c | 3 + drivers/i2c/davinci_i2c.c | 3 + drivers/i2c/exynos_hs_i2c.c | 561 +++++++++++++++ drivers/i2c/fti2c010.c | 3 + drivers/i2c/ihs_i2c.c | 3 + drivers/i2c/kona_i2c.c | 3 + drivers/i2c/lpc32xx_i2c.c | 3 + drivers/i2c/pca9564_i2c.c | 3 + drivers/i2c/ppc4xx_i2c.c | 3 + drivers/i2c/rcar_i2c.c | 3 + drivers/i2c/s3c24x0_i2c.c | 1136 +----------------------------- drivers/i2c/s3c24x0_i2c.h | 22 + drivers/i2c/sh_i2c.c | 3 + drivers/i2c/sh_sh7734_i2c.c | 3 + drivers/i2c/soft_i2c.c | 3 + drivers/i2c/tsi108_i2c.c | 3 + drivers/i2c/zynq_i2c.c | 3 + include/configs/s5p_goni.h | 19 - include/configs/s5pc210_universal.h | 19 - include/configs/trats.h | 30 - include/configs/trats2.h | 33 - 30 files changed, 752 insertions(+), 1242 deletions(-) create mode 100644 doc/driver-model/i2c-howto.txt create mode 100644 drivers/i2c/exynos_hs_i2c.c

Three boards are still not converting to use DM_I2C. They are also using the old PMIC framework. Rather than removing them, add #ifdefs to allow them to continue to build. This will give the maintainers a little more time to decide whether to convert them or not.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 1 + board/samsung/common/misc.c | 4 ++++ board/samsung/trats/trats.c | 20 +++++++++++++++++-- board/samsung/trats2/trats2.c | 18 +++++++++++++---- board/samsung/universal_c210/universal.c | 22 +++++++++++++++------ configs/origen_defconfig | 1 + include/configs/s5pc210_universal.h | 19 ------------------ include/configs/trats.h | 30 ----------------------------- include/configs/trats2.h | 33 -------------------------------- 9 files changed, 54 insertions(+), 94 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 993485a..2427285 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -399,6 +399,7 @@ config TARGET_BCMNSP config ARCH_EXYNOS bool "Samsung EXYNOS" select DM + select DM_I2C select DM_SPI_FLASH select DM_SERIAL select DM_SPI diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 77d0a4e..203136f 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -101,6 +101,7 @@ void set_board_info(void) #ifdef CONFIG_LCD_MENU static int power_key_pressed(u32 reg) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *pmic; u32 status; u32 mask; @@ -123,6 +124,9 @@ static int power_key_pressed(u32 reg) return 0;
return !!(status & mask); +#else + return 0; +#endif }
static int key_pressed(int key) diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index 66a54d4..7200c2e 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -53,6 +53,7 @@ int exynos_init(void)
void i2c_init_board(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int err;
/* I2C_5 -> PMIC */ @@ -67,8 +68,10 @@ void i2c_init_board(void) gpio_request(EXYNOS4_GPIO_Y41, "i2c_data"); gpio_direction_output(EXYNOS4_GPIO_Y40, 1); gpio_direction_output(EXYNOS4_GPIO_Y41, 1); +#endif }
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ static void trats_low_power_mode(void) { struct exynos4_clock *clk = @@ -273,11 +276,14 @@ static int pmic_init_max8997(void) puts("MAX8997 PMIC setting error!\n"); return -1; } + return 0; } +#endif
int exynos_power_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int chrg, ret; struct power_battery *pb; struct pmic *p_fg, *p_chrg, *p_muic, *p_bat; @@ -341,6 +347,7 @@ int exynos_power_init(void)
if (pb->bat->state == CHARGE && chrg == CHARGER_USB) puts("CHARGE Battery !\n"); +#endif
return 0; } @@ -384,6 +391,7 @@ static void check_hw_revision(void) #ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; u32 val = 0; struct pmic *p = pmic_get("MAX8997_PMIC"); @@ -415,6 +423,7 @@ static int s5pc210_phy_control(int on) puts("MAX8997 LDO setting error!\n"); return -1; } +#endif
return 0; } @@ -435,11 +444,16 @@ int board_usb_init(int index, enum usb_init_type init)
int g_dnl_board_usb_cable_connected(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *muic = pmic_get("MAX8997_MUIC"); if (!muic) return 0;
return !!muic->chrg->chrg_type(muic); +#else + return false; +#endif + } #endif
@@ -552,6 +566,7 @@ void exynos_reset_lcd(void)
int lcd_power(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; struct pmic *p = pmic_get("MAX8997_PMIC"); if (!p) @@ -569,12 +584,13 @@ int lcd_power(void) puts("MAX8997 LDO setting error!\n"); return -1; } - +#endif return 0; }
int mipi_power(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; struct pmic *p = pmic_get("MAX8997_PMIC"); if (!p) @@ -592,7 +608,7 @@ int mipi_power(void) puts("MAX8997 LDO setting error!\n"); return -1; } - +#endif return 0; }
diff --git a/board/samsung/trats2/trats2.c b/board/samsung/trats2/trats2.c index 7b28ae8..150503e 100644 --- a/board/samsung/trats2/trats2.c +++ b/board/samsung/trats2/trats2.c @@ -151,8 +151,6 @@ int exynos_early_init_f(void) return 0; }
-static int pmic_init_max77686(void); - int exynos_init(void) { struct exynos4_power *pwr = @@ -176,6 +174,7 @@ int exynos_init(void)
int exynos_power_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int chrg; struct power_battery *pb; struct pmic *p_chrg, *p_muic, *p_fg, *p_bat; @@ -236,13 +235,14 @@ int exynos_power_init(void)
if (pb->bat->state == CHARGE && chrg == CHARGER_USB) puts("CHARGE Battery !\n"); - +#endif return 0; }
#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; unsigned int val; struct pmic *p, *p_pmic, *p_muic; @@ -299,7 +299,7 @@ static int s5pc210_phy_control(int on)
if (ret) return -1; - +#endif return 0; }
@@ -319,14 +319,19 @@ int board_usb_init(int index, enum usb_init_type init)
int g_dnl_board_usb_cable_connected(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *muic = pmic_get("MAX77693_MUIC"); if (!muic) return 0;
return !!muic->chrg->chrg_type(muic); +#else + return false; +#endif } #endif
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ static int pmic_init_max77686(void) { struct pmic *p = pmic_get("MAX77686_PMIC"); @@ -379,6 +384,7 @@ static int pmic_init_max77686(void)
return 0; } +#endif
/* * LCD @@ -387,18 +393,21 @@ static int pmic_init_max77686(void) #ifdef CONFIG_LCD int mipi_power(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *p = pmic_get("MAX77686_PMIC");
/* LDO8 VMIPI_1.0V_AP */ max77686_set_ldo_mode(p, 8, OPMODE_ON); /* LDO10 VMIPI_1.8V_AP */ max77686_set_ldo_mode(p, 10, OPMODE_ON); +#endif
return 0; }
void exynos_lcd_power_on(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *p = pmic_get("MAX77686_PMIC");
/* LCD_2.2V_EN: GPC0[1] */ @@ -410,6 +419,7 @@ void exynos_lcd_power_on(void) pmic_probe(p); max77686_set_ldo_voltage(p, 25, 3100000); max77686_set_ldo_mode(p, 25, OPMODE_LPM); +#endif }
void exynos_reset_lcd(void) diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c index 81e35b6..c3946ee 100644 --- a/board/samsung/universal_c210/universal.c +++ b/board/samsung/universal_c210/universal.c @@ -38,10 +38,9 @@ static int get_hwrev(void) return board_rev & 0xFF; }
-static void init_pmic_lcd(void); - int exynos_power_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret;
/* @@ -53,7 +52,7 @@ int exynos_power_init(void) return ret;
init_pmic_lcd(); - +#endif return 0; }
@@ -84,6 +83,7 @@ static unsigned short get_adc_value(int channel)
static int adc_power_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret; struct pmic *p = pmic_get("MAX8998_PMIC"); if (!p) @@ -97,6 +97,9 @@ static int adc_power_control(int on) MAX8998_LDO4, !!on);
return ret; +#else + return 0; +#endif }
static unsigned int get_hw_revision(void) @@ -144,6 +147,7 @@ static void check_hw_revision(void) #ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; struct pmic *p = pmic_get("MAX8998_PMIC"); if (!p) @@ -175,7 +179,7 @@ static int s5pc210_phy_control(int on) puts("MAX8998 LDO setting error!\n"); return -1; } - +#endif return 0; }
@@ -201,6 +205,7 @@ int exynos_early_init_f(void) return 0; }
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ static void init_pmic_lcd(void) { unsigned char val; @@ -248,6 +253,7 @@ static void init_pmic_lcd(void) if (ret) puts("LCD pmic initialisation error!\n"); } +#endif
void exynos_cfg_lcd_gpio(void) { @@ -304,6 +310,7 @@ void exynos_reset_lcd(void)
void exynos_lcd_power_on(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *p = pmic_get("MAX8998_PMIC");
if (!p) @@ -314,6 +321,7 @@ void exynos_lcd_power_on(void)
pmic_set_output(p, MAX8998_REG_ONOFF3, MAX8998_LDO17, LDO_ON); pmic_set_output(p, MAX8998_REG_ONOFF2, MAX8998_LDO7, LDO_ON); +#endif }
void exynos_cfg_ldo(void) @@ -328,8 +336,9 @@ void exynos_enable_ldo(unsigned int onoff)
int exynos_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ char buf[16]; - +#endif gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;
switch (get_hwrev()) { @@ -354,13 +363,14 @@ int exynos_init(void) break; }
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ /* Request soft I2C gpios */ strcpy(buf, "soft_i2c_scl"); gpio_request(CONFIG_SOFT_I2C_GPIO_SCL, buf);
strcpy(buf, "soft_i2c_sda"); gpio_request(CONFIG_SOFT_I2C_GPIO_SDA, buf); - +#endif check_hw_revision(); printf("HW Revision:\t0x%x\n", board_rev);
diff --git a/configs/origen_defconfig b/configs/origen_defconfig index 0d91ec1..7b9826a 100644 --- a/configs/origen_defconfig +++ b/configs/origen_defconfig @@ -37,3 +37,4 @@ CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_G_DNL_MANUFACTURER="Samsung" CONFIG_G_DNL_VENDOR_NUM=0x04e8 CONFIG_G_DNL_PRODUCT_NUM=0x6601 +CONFIG_DM_I2C=y diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h index 0210c5b..1bfefe9 100644 --- a/include/configs/s5pc210_universal.h +++ b/include/configs/s5pc210_universal.h @@ -153,25 +153,6 @@ #define CONFIG_SAMSUNG_ONENAND #define CONFIG_SYS_ONENAND_BASE 0x0C000000
-#include <asm/arch/gpio.h> -/* - * I2C Settings - */ -#define CONFIG_SOFT_I2C_GPIO_SCL EXYNOS4_GPIO_B7 -#define CONFIG_SOFT_I2C_GPIO_SDA EXYNOS4_GPIO_B6 - -#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 0 -#define CONFIG_SOFT_I2C_READ_REPEATED_START -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS 7 - -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX8998 - #define CONFIG_USB_GADGET_DWC2_OTG_PHY
/* diff --git a/include/configs/trats.h b/include/configs/trats.h index a26d663..a771ddb 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -178,36 +178,6 @@ /* GPT */ #define CONFIG_RANDOM_UUID
-/* I2C */ -#include <asm/arch/gpio.h> - -#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 0x7F -#define CONFIG_SOFT_I2C_READ_REPEATED_START -#define CONFIG_SYS_I2C_INIT_BOARD - -/* I2C FG */ -#define CONFIG_SOFT_I2C_GPIO_SCL EXYNOS4_GPIO_Y41 -#define CONFIG_SOFT_I2C_GPIO_SDA EXYNOS4_GPIO_Y40 - -/* POWER */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX8997 - -#define CONFIG_POWER_FG -#define CONFIG_POWER_FG_MAX17042 -#define CONFIG_POWER_MUIC -#define CONFIG_POWER_MUIC_MAX8997 -#define CONFIG_POWER_BATTERY -#define CONFIG_POWER_BATTERY_TRATS - /* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA #define CONFIG_LIB_HW_RAND diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 1633c67..1cd3e14 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -155,39 +155,6 @@ /* GPT */ #define CONFIG_RANDOM_UUID
-/* I2C */ -#include <asm/arch/gpio.h> - -#define CONFIG_SYS_I2C -#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 CONFIG_SOFT_I2C_READ_REPEATED_START -#define CONFIG_SYS_I2C_INIT_BOARD - -#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 -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -#define CONFIG_POWER_PMIC_MAX77693 -#define CONFIG_POWER_MUIC_MAX77693 -#define CONFIG_POWER_FG_MAX77693 -#define CONFIG_POWER_BATTERY_TRATS2 - /* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA #define CONFIG_LIB_HW_RAND

Hello Simon,
Am 23.11.2016 um 14:34 schrieb Simon Glass:
Three boards are still not converting to use DM_I2C. They are also using the old PMIC framework. Rather than removing them, add #ifdefs to allow them to continue to build. This will give the maintainers a little more time to decide whether to convert them or not.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 1 + board/samsung/common/misc.c | 4 ++++ board/samsung/trats/trats.c | 20 +++++++++++++++++-- board/samsung/trats2/trats2.c | 18 +++++++++++++---- board/samsung/universal_c210/universal.c | 22 +++++++++++++++------ configs/origen_defconfig | 1 + include/configs/s5pc210_universal.h | 19 ------------------ include/configs/trats.h | 30 ----------------------------- include/configs/trats2.h | 33 -------------------------------- 9 files changed, 54 insertions(+), 94 deletions(-)
Thanks!
Acked-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 993485a..2427285 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -399,6 +399,7 @@ config TARGET_BCMNSP config ARCH_EXYNOS bool "Samsung EXYNOS" select DM
- select DM_I2C select DM_SPI_FLASH select DM_SERIAL select DM_SPI
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 77d0a4e..203136f 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -101,6 +101,7 @@ void set_board_info(void) #ifdef CONFIG_LCD_MENU static int power_key_pressed(u32 reg) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *pmic; u32 status; u32 mask; @@ -123,6 +124,9 @@ static int power_key_pressed(u32 reg) return 0;
return !!(status & mask); +#else
- return 0;
+#endif }
static int key_pressed(int key) diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index 66a54d4..7200c2e 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -53,6 +53,7 @@ int exynos_init(void)
void i2c_init_board(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int err;
/* I2C_5 -> PMIC */ @@ -67,8 +68,10 @@ void i2c_init_board(void) gpio_request(EXYNOS4_GPIO_Y41, "i2c_data"); gpio_direction_output(EXYNOS4_GPIO_Y40, 1); gpio_direction_output(EXYNOS4_GPIO_Y41, 1); +#endif }
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ static void trats_low_power_mode(void) { struct exynos4_clock *clk = @@ -273,11 +276,14 @@ static int pmic_init_max8997(void) puts("MAX8997 PMIC setting error!\n"); return -1; }
- return 0; }
+#endif
int exynos_power_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int chrg, ret; struct power_battery *pb; struct pmic *p_fg, *p_chrg, *p_muic, *p_bat; @@ -341,6 +347,7 @@ int exynos_power_init(void)
if (pb->bat->state == CHARGE && chrg == CHARGER_USB) puts("CHARGE Battery !\n"); +#endif
return 0; } @@ -384,6 +391,7 @@ static void check_hw_revision(void) #ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; u32 val = 0; struct pmic *p = pmic_get("MAX8997_PMIC"); @@ -415,6 +423,7 @@ static int s5pc210_phy_control(int on) puts("MAX8997 LDO setting error!\n"); return -1; } +#endif
return 0; } @@ -435,11 +444,16 @@ int board_usb_init(int index, enum usb_init_type init)
int g_dnl_board_usb_cable_connected(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *muic = pmic_get("MAX8997_MUIC"); if (!muic) return 0;
return !!muic->chrg->chrg_type(muic); +#else
- return false;
+#endif
- } #endif
@@ -552,6 +566,7 @@ void exynos_reset_lcd(void)
int lcd_power(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; struct pmic *p = pmic_get("MAX8997_PMIC"); if (!p) @@ -569,12 +584,13 @@ int lcd_power(void) puts("MAX8997 LDO setting error!\n"); return -1; }
+#endif return 0; }
int mipi_power(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; struct pmic *p = pmic_get("MAX8997_PMIC"); if (!p) @@ -592,7 +608,7 @@ int mipi_power(void) puts("MAX8997 LDO setting error!\n"); return -1; }
+#endif return 0; }
diff --git a/board/samsung/trats2/trats2.c b/board/samsung/trats2/trats2.c index 7b28ae8..150503e 100644 --- a/board/samsung/trats2/trats2.c +++ b/board/samsung/trats2/trats2.c @@ -151,8 +151,6 @@ int exynos_early_init_f(void) return 0; }
-static int pmic_init_max77686(void);
- int exynos_init(void) { struct exynos4_power *pwr =
@@ -176,6 +174,7 @@ int exynos_init(void)
int exynos_power_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int chrg; struct power_battery *pb; struct pmic *p_chrg, *p_muic, *p_fg, *p_bat; @@ -236,13 +235,14 @@ int exynos_power_init(void)
if (pb->bat->state == CHARGE && chrg == CHARGER_USB) puts("CHARGE Battery !\n");
+#endif return 0; }
#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; unsigned int val; struct pmic *p, *p_pmic, *p_muic; @@ -299,7 +299,7 @@ static int s5pc210_phy_control(int on)
if (ret) return -1;
+#endif return 0; }
@@ -319,14 +319,19 @@ int board_usb_init(int index, enum usb_init_type init)
int g_dnl_board_usb_cable_connected(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *muic = pmic_get("MAX77693_MUIC"); if (!muic) return 0;
return !!muic->chrg->chrg_type(muic); +#else
- return false;
+#endif } #endif
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ static int pmic_init_max77686(void) { struct pmic *p = pmic_get("MAX77686_PMIC"); @@ -379,6 +384,7 @@ static int pmic_init_max77686(void)
return 0; } +#endif
/*
- LCD
@@ -387,18 +393,21 @@ static int pmic_init_max77686(void) #ifdef CONFIG_LCD int mipi_power(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *p = pmic_get("MAX77686_PMIC");
/* LDO8 VMIPI_1.0V_AP */ max77686_set_ldo_mode(p, 8, OPMODE_ON); /* LDO10 VMIPI_1.8V_AP */ max77686_set_ldo_mode(p, 10, OPMODE_ON); +#endif
return 0; }
void exynos_lcd_power_on(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *p = pmic_get("MAX77686_PMIC");
/* LCD_2.2V_EN: GPC0[1] */ @@ -410,6 +419,7 @@ void exynos_lcd_power_on(void) pmic_probe(p); max77686_set_ldo_voltage(p, 25, 3100000); max77686_set_ldo_mode(p, 25, OPMODE_LPM); +#endif }
void exynos_reset_lcd(void) diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c index 81e35b6..c3946ee 100644 --- a/board/samsung/universal_c210/universal.c +++ b/board/samsung/universal_c210/universal.c @@ -38,10 +38,9 @@ static int get_hwrev(void) return board_rev & 0xFF; }
-static void init_pmic_lcd(void);
- int exynos_power_init(void) {
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret;
/* @@ -53,7 +52,7 @@ int exynos_power_init(void) return ret;
init_pmic_lcd();
+#endif return 0; }
@@ -84,6 +83,7 @@ static unsigned short get_adc_value(int channel)
static int adc_power_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret; struct pmic *p = pmic_get("MAX8998_PMIC"); if (!p) @@ -97,6 +97,9 @@ static int adc_power_control(int on) MAX8998_LDO4, !!on);
return ret; +#else
- return 0;
+#endif }
static unsigned int get_hw_revision(void) @@ -144,6 +147,7 @@ static void check_hw_revision(void) #ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret = 0; struct pmic *p = pmic_get("MAX8998_PMIC"); if (!p) @@ -175,7 +179,7 @@ static int s5pc210_phy_control(int on) puts("MAX8998 LDO setting error!\n"); return -1; }
+#endif return 0; }
@@ -201,6 +205,7 @@ int exynos_early_init_f(void) return 0; }
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ static void init_pmic_lcd(void) { unsigned char val; @@ -248,6 +253,7 @@ static void init_pmic_lcd(void) if (ret) puts("LCD pmic initialisation error!\n"); } +#endif
void exynos_cfg_lcd_gpio(void) { @@ -304,6 +310,7 @@ void exynos_reset_lcd(void)
void exynos_lcd_power_on(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ struct pmic *p = pmic_get("MAX8998_PMIC");
if (!p) @@ -314,6 +321,7 @@ void exynos_lcd_power_on(void)
pmic_set_output(p, MAX8998_REG_ONOFF3, MAX8998_LDO17, LDO_ON); pmic_set_output(p, MAX8998_REG_ONOFF2, MAX8998_LDO7, LDO_ON); +#endif }
void exynos_cfg_ldo(void) @@ -328,8 +336,9 @@ void exynos_enable_ldo(unsigned int onoff)
int exynos_init(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ char buf[16];
+#endif gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;
switch (get_hwrev()) { @@ -354,13 +363,14 @@ int exynos_init(void) break; }
+#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ /* Request soft I2C gpios */ strcpy(buf, "soft_i2c_scl"); gpio_request(CONFIG_SOFT_I2C_GPIO_SCL, buf);
strcpy(buf, "soft_i2c_sda"); gpio_request(CONFIG_SOFT_I2C_GPIO_SDA, buf);
+#endif check_hw_revision(); printf("HW Revision:\t0x%x\n", board_rev);
diff --git a/configs/origen_defconfig b/configs/origen_defconfig index 0d91ec1..7b9826a 100644 --- a/configs/origen_defconfig +++ b/configs/origen_defconfig @@ -37,3 +37,4 @@ CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_G_DNL_MANUFACTURER="Samsung" CONFIG_G_DNL_VENDOR_NUM=0x04e8 CONFIG_G_DNL_PRODUCT_NUM=0x6601 +CONFIG_DM_I2C=y diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h index 0210c5b..1bfefe9 100644 --- a/include/configs/s5pc210_universal.h +++ b/include/configs/s5pc210_universal.h @@ -153,25 +153,6 @@ #define CONFIG_SAMSUNG_ONENAND #define CONFIG_SYS_ONENAND_BASE 0x0C000000
-#include <asm/arch/gpio.h> -/*
- I2C Settings
- */
-#define CONFIG_SOFT_I2C_GPIO_SCL EXYNOS4_GPIO_B7 -#define CONFIG_SOFT_I2C_GPIO_SDA EXYNOS4_GPIO_B6
-#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 0 -#define CONFIG_SOFT_I2C_READ_REPEATED_START -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS 7
-#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX8998
#define CONFIG_USB_GADGET_DWC2_OTG_PHY
/*
diff --git a/include/configs/trats.h b/include/configs/trats.h index a26d663..a771ddb 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -178,36 +178,6 @@ /* GPT */ #define CONFIG_RANDOM_UUID
-/* I2C */ -#include <asm/arch/gpio.h>
-#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 0x7F -#define CONFIG_SOFT_I2C_READ_REPEATED_START -#define CONFIG_SYS_I2C_INIT_BOARD
-/* I2C FG */ -#define CONFIG_SOFT_I2C_GPIO_SCL EXYNOS4_GPIO_Y41 -#define CONFIG_SOFT_I2C_GPIO_SDA EXYNOS4_GPIO_Y40
-/* POWER */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX8997
-#define CONFIG_POWER_FG -#define CONFIG_POWER_FG_MAX17042 -#define CONFIG_POWER_MUIC -#define CONFIG_POWER_MUIC_MAX8997 -#define CONFIG_POWER_BATTERY -#define CONFIG_POWER_BATTERY_TRATS
- /* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA #define CONFIG_LIB_HW_RAND
diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 1633c67..1cd3e14 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -155,39 +155,6 @@ /* GPT */ #define CONFIG_RANDOM_UUID
-/* I2C */ -#include <asm/arch/gpio.h>
-#define CONFIG_SYS_I2C -#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 CONFIG_SOFT_I2C_READ_REPEATED_START -#define CONFIG_SYS_I2C_INIT_BOARD
-#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 -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -#define CONFIG_POWER_PMIC_MAX77693 -#define CONFIG_POWER_MUIC_MAX77693 -#define CONFIG_POWER_FG_MAX77693 -#define CONFIG_POWER_BATTERY_TRATS2
- /* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA #define CONFIG_LIB_HW_RAND

These are the last two samsung boards that don't use DM_I2C. Move them over, leaving #ifdefs to allow the maintainer to complete this work.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 1 + board/samsung/goni/goni.c | 7 ++++++- include/configs/s5p_goni.h | 19 ------------------- 3 files changed, 7 insertions(+), 20 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2427285..a87f692 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -412,6 +412,7 @@ config ARCH_S5PC1XX select DM select DM_SERIAL select DM_GPIO + select DM_I2C
config ARCH_HIGHBANK bool "Calxeda Highbank" diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c index e8329bb..b066832 100644 --- a/board/samsung/goni/goni.c +++ b/board/samsung/goni/goni.c @@ -45,11 +45,15 @@ void i2c_init_board(void)
int power_init_board(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ /* * For PMIC the I2C bus is named as I2C5, but it is connected * to logical I2C adapter 0 */ return pmic_init(I2C_0); +#else + return 0; +#endif }
int dram_init(void) @@ -142,6 +146,7 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_USB_GADGET static int s5pc1xx_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret; static int status; struct pmic *p = pmic_get("MAX8998_PMIC"); @@ -173,7 +178,7 @@ static int s5pc1xx_phy_control(int on) status = 0; } udelay(10000); - +#endif return 0; }
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index 124cca3..6a5425a 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -229,25 +229,6 @@
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
-#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX8998 - -#include <asm/arch/gpio.h> -/* - * I2C Settings - */ -#define CONFIG_SOFT_I2C_GPIO_SCL S5PC110_GPIO_J43 -#define CONFIG_SOFT_I2C_GPIO_SDA S5PC110_GPIO_J40 - -#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 0x7F -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_I2C_INIT_BOARD - -#define CONFIG_SYS_MAX_I2C_BUS 7 #define CONFIG_USB_GADGET_DWC2_OTG_PHY #define CONFIG_USB_FUNCTION_MASS_STORAGE

Hello Simon,
Am 23.11.2016 um 14:34 schrieb Simon Glass:
These are the last two samsung boards that don't use DM_I2C. Move them over, leaving #ifdefs to allow the maintainer to complete this work.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 1 + board/samsung/goni/goni.c | 7 ++++++- include/configs/s5p_goni.h | 19 ------------------- 3 files changed, 7 insertions(+), 20 deletions(-)
Thanks!
Acked-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2427285..a87f692 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -412,6 +412,7 @@ config ARCH_S5PC1XX select DM select DM_SERIAL select DM_GPIO
select DM_I2C
config ARCH_HIGHBANK bool "Calxeda Highbank"
diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c index e8329bb..b066832 100644 --- a/board/samsung/goni/goni.c +++ b/board/samsung/goni/goni.c @@ -45,11 +45,15 @@ void i2c_init_board(void)
int power_init_board(void) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ /* * For PMIC the I2C bus is named as I2C5, but it is connected * to logical I2C adapter 0 */ return pmic_init(I2C_0); +#else
- return 0;
+#endif }
int dram_init(void) @@ -142,6 +146,7 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_USB_GADGET static int s5pc1xx_phy_control(int on) { +#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ int ret; static int status; struct pmic *p = pmic_get("MAX8998_PMIC"); @@ -173,7 +178,7 @@ static int s5pc1xx_phy_control(int on) status = 0; } udelay(10000);
+#endif return 0; }
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index 124cca3..6a5425a 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -229,25 +229,6 @@
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
-#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX8998
-#include <asm/arch/gpio.h> -/*
- I2C Settings
- */
-#define CONFIG_SOFT_I2C_GPIO_SCL S5PC110_GPIO_J43 -#define CONFIG_SOFT_I2C_GPIO_SDA S5PC110_GPIO_J40
-#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 0x7F -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_SYS_MAX_I2C_BUS 7 #define CONFIG_USB_GADGET_DWC2_OTG_PHY #define CONFIG_USB_FUNCTION_MASS_STORAGE

Now that all boards use DM_I2C we can drop the old code.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/i2c/s3c24x0_i2c.c | 585 +--------------------------------------------- 1 file changed, 2 insertions(+), 583 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index eab49d0..24fc984 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -116,77 +116,13 @@
#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
- -/* To support VCMA9 boards and other who dont define max_i2c_num */ -#ifndef CONFIG_MAX_I2C_NUM -#define CONFIG_MAX_I2C_NUM 1 -#endif - DECLARE_GLOBAL_DATA_PTR;
-/* - * For SPL boot some boards need i2c before SDRAM is initialised so force - * variables to live in SRAM - */ -#ifdef CONFIG_SYS_I2C -static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] - __attribute__((section(".data"))); -#endif - enum exynos_i2c_type { EXYNOS_I2C_STD, EXYNOS_I2C_HS, };
-#ifdef CONFIG_SYS_I2C -/** - * Get a pointer to the given bus index - * - * @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) -{ - if (bus_idx < ARRAY_SIZE(i2c_bus)) { - struct s3c24x0_i2c_bus *bus; - - bus = &i2c_bus[bus_idx]; - if (bus->active) - return bus; - } - - debug("Undefined bus: %d\n", bus_idx); - return NULL; -} -#endif - -#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) -static int GetI2CSDA(void) -{ - struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); - -#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) - return (readl(&gpio->gpedat) & 0x8000) >> 15; -#endif -#ifdef CONFIG_S3C2400 - return (readl(&gpio->pgdat) & 0x0020) >> 5; -#endif -} - -static void SetI2CSCL(int x) -{ - struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); - -#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) - writel((readl(&gpio->gpedat) & ~0x4000) | - (x & 1) << 14, &gpio->gpedat); -#endif -#ifdef CONFIG_S3C2400 - writel((readl(&gpio->pgdat) & ~0x0040) | (x & 1) << 6, &gpio->pgdat); -#endif -} -#endif - /* * Wait til the byte transfer is completed. * @@ -263,25 +199,6 @@ static void read_write_byte(struct s3c24x0_i2c *i2c) clrbits_le32(&i2c->iiccon, I2CCON_IRPND); }
-#ifdef CONFIG_SYS_I2C -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 - * bus)); - return i2c; -#elif defined CONFIG_EXYNOS5 - struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() - + (EXYNOS5_I2C_SPACING - * bus)); - return i2c; -#else - return s3c24x0_get_base_i2c(); -#endif -} -#endif - static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { ulong freq, pres = 16, div; @@ -412,88 +329,6 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) hsi2c_ch_init(i2c_bus); }
-#ifdef CONFIG_SYS_I2C -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); - - i2c = get_base_i2c(adap->hwadapnr); - bus = &i2c_bus[adap->hwadapnr]; - if (!bus) - return; - - /* - * In case the previous transfer is still going, wait to give it a - * chance to finish. - */ - while (readl(&i2c->iicstat) & I2CSTAT_BSY) { - if (get_timer(start_time) > I2C_TIMEOUT_MS) { - printf("%s: I2C bus busy for %p\n", __func__, - &i2c->iicstat); - return; - } - } - -#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) - int i; - - if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) { -#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) - ulong old_gpecon = readl(&gpio->gpecon); -#endif -#ifdef CONFIG_S3C2400 - ulong old_gpecon = readl(&gpio->pgcon); -#endif - /* bus still busy probably by (most) previously interrupted - transfer */ - -#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) - /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */ - writel((readl(&gpio->gpecon) & ~0xF0000000) | 0x10000000, - &gpio->gpecon); -#endif -#ifdef CONFIG_S3C2400 - /* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */ - writel((readl(&gpio->pgcon) & ~0x00003c00) | 0x00001000, - &gpio->pgcon); -#endif - - /* toggle I2CSCL until bus idle */ - SetI2CSCL(0); - udelay(1000); - i = 10; - while ((i > 0) && (GetI2CSDA() != 1)) { - SetI2CSCL(1); - udelay(1000); - SetI2CSCL(0); - udelay(1000); - i--; - } - SetI2CSCL(1); - udelay(1000); - - /* restore pin functions */ -#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) - writel(old_gpecon, &gpio->gpecon); -#endif -#ifdef CONFIG_S3C2400 - writel(old_gpecon, &gpio->pgcon); -#endif - } -#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ - - i2c_ch_init(i2c, speed, slaveadd); - - bus->active = true; - bus->regs = i2c; -} -#endif /* CONFIG_SYS_I2C */ - /* * Poll the appropriate bit of the fifo status register until the interface is * ready to process the next byte or timeout expires. @@ -715,22 +550,10 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c, return rv; }
-#ifdef CONFIG_SYS_I2C -static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, - unsigned int speed) -#else static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) -#endif { - struct s3c24x0_i2c_bus *i2c_bus; + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
-#ifdef CONFIG_SYS_I2C - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -EFAULT; -#else - i2c_bus = dev_get_priv(dev); -#endif i2c_bus->clock_frequency = speed;
if (i2c_bus->is_highspeed) { @@ -857,23 +680,12 @@ bailout: return result; }
-#ifdef CONFIG_SYS_I2C -static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) -#else static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) -#endif { - struct s3c24x0_i2c_bus *i2c_bus; + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); uchar buf[1]; int ret;
-#ifdef CONFIG_SYS_I2C - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -EFAULT; -#else - i2c_bus = dev_get_priv(dev); -#endif buf[0] = 0;
/* @@ -892,398 +704,6 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) return ret != I2C_OK; }
-#ifdef CONFIG_SYS_I2C -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]; - int ret; - - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -EFAULT; - - if (alen > 4) { - debug("I2C read: addr len %d not supported\n", alen); - return -EADDRNOTAVAIL; - } - - if (alen > 0) { - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - } - -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of - * address and the extra bits end up in the "chip address" - * bit slots. This makes a 24WC08 (1Kbyte) chip look like - * four 256 byte chips. - * - * Note that we consider the length of the address field to - * still be one byte because the extra address bits are - * hidden in the chip address. - */ - if (alen > 0) - chip |= ((addr >> (alen * 8)) & - CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); -#endif - if (i2c_bus->is_highspeed) - ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], - alen, buffer, len); - else - ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1, - &xaddr[4 - alen], alen, buffer, len); - - if (ret) { - if (i2c_bus->is_highspeed) - exynos5_i2c_reset(i2c_bus); - debug("I2c read failed %d\n", ret); - return -EIO; - } - return 0; -} - -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]; - int ret; - - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -EFAULT; - - if (alen > 4) { - debug("I2C write: addr len %d not supported\n", alen); - return -EINVAL; - } - - if (alen > 0) { - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - } -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of - * address and the extra bits end up in the "chip address" - * bit slots. This makes a 24WC08 (1Kbyte) chip look like - * four 256 byte chips. - * - * Note that we consider the length of the address field to - * still be one byte because the extra address bits are - * hidden in the chip address. - */ - if (alen > 0) - chip |= ((addr >> (alen * 8)) & - CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); -#endif - if (i2c_bus->is_highspeed) - ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], - alen, buffer, len, true); - else - ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, chip << 1, - &xaddr[4 - alen], alen, buffer, len); - - if (ret != 0) { - if (i2c_bus->is_highspeed) - exynos5_i2c_reset(i2c_bus); - return 1; - } else { - return 0; - } -} - -#if CONFIG_IS_ENABLED(OF_CONTROL) -static void process_nodes(const void *blob, int node_list[], int count, - int is_highspeed) -{ - struct s3c24x0_i2c_bus *bus; - int i, flags; - - for (i = 0; i < count; i++) { - int node = node_list[i]; - - if (node <= 0) - continue; - - bus = &i2c_bus[i]; - bus->active = true; - bus->is_highspeed = is_highspeed; - - if (is_highspeed) { - flags = PINMUX_FLAG_HS_MODE; - bus->hsregs = (struct exynos5_hsi2c *) - fdtdec_get_addr(blob, node, "reg"); - } else { - flags = 0; - bus->regs = (struct s3c24x0_i2c *) - fdtdec_get_addr(blob, node, "reg"); - } - - bus->id = pinmux_decode_periph_id(blob, node); - bus->clock_frequency = fdtdec_get_int(blob, node, - "clock-frequency", - CONFIG_SYS_I2C_S3C24X0_SPEED); - bus->node = node; - bus->bus_num = i; - exynos_pinmux_config(bus->id, flags); - - /* Mark position as used */ - node_list[i] = -1; - } -} - -void board_i2c_init(const void *blob) -{ - int node_list[CONFIG_MAX_I2C_NUM]; - 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); -} - -int i2c_get_bus_num_fdt(int node) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(i2c_bus); i++) { - if (node == i2c_bus[i].node) - return i; - } - - debug("%s: Can't find any matched I2C bus\n", __func__); - return -EINVAL; -} - -int i2c_reset_port_fdt(const void *blob, int node) -{ - struct s3c24x0_i2c_bus *i2c_bus; - int bus; - - bus = i2c_get_bus_num_fdt(node); - if (bus < 0) { - debug("could not get bus for node %d\n", node); - return bus; - } - - i2c_bus = get_bus(bus); - if (!i2c_bus) { - debug("get_bus() failed for node %d\n", node); - return -EFAULT; - } - - if (i2c_bus->is_highspeed) { - if (hsi2c_get_clk_details(i2c_bus)) - return -EINVAL; - hsi2c_ch_init(i2c_bus); - } else { - i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, - CONFIG_SYS_I2C_S3C24X0_SLAVE); - } - - return 0; -} -#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ - -#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)) - error("i2c_init: failed to init bus for speed = %d", speed); -} -#endif /* CONFIG_EXYNOS5 */ - -/* - * Register s3c24x0 i2c adapters - */ -#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 -#endif /* CONFIG_SYS_I2C */ - -#ifdef CONFIG_DM_I2C static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) { @@ -1460,4 +880,3 @@ U_BOOT_DRIVER(hs_i2c) = { .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), .ops = &exynos_hs_i2c_ops, }; -#endif /* CONFIG_DM_I2C */

Hello Simon,
Am 23.11.2016 um 14:34 schrieb Simon Glass:
Now that all boards use DM_I2C we can drop the old code.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/i2c/s3c24x0_i2c.c | 585 +--------------------------------------------- 1 file changed, 2 insertions(+), 583 deletions(-)
Thanks!
Acked-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index eab49d0..24fc984 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -116,77 +116,13 @@
#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
-/* To support VCMA9 boards and other who dont define max_i2c_num */ -#ifndef CONFIG_MAX_I2C_NUM -#define CONFIG_MAX_I2C_NUM 1 -#endif
- DECLARE_GLOBAL_DATA_PTR;
-/*
- For SPL boot some boards need i2c before SDRAM is initialised so force
- variables to live in SRAM
- */
-#ifdef CONFIG_SYS_I2C -static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
__attribute__((section(".data")));
-#endif
- enum exynos_i2c_type { EXYNOS_I2C_STD, EXYNOS_I2C_HS, };
-#ifdef CONFIG_SYS_I2C -/**
- Get a pointer to the given bus index
- @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) -{
- if (bus_idx < ARRAY_SIZE(i2c_bus)) {
struct s3c24x0_i2c_bus *bus;
bus = &i2c_bus[bus_idx];
if (bus->active)
return bus;
- }
- debug("Undefined bus: %d\n", bus_idx);
- return NULL;
-} -#endif
-#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) -static int GetI2CSDA(void) -{
- struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
-#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
- return (readl(&gpio->gpedat) & 0x8000) >> 15;
-#endif -#ifdef CONFIG_S3C2400
- return (readl(&gpio->pgdat) & 0x0020) >> 5;
-#endif -}
-static void SetI2CSCL(int x) -{
- struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
-#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
- writel((readl(&gpio->gpedat) & ~0x4000) |
(x & 1) << 14, &gpio->gpedat);
-#endif -#ifdef CONFIG_S3C2400
- writel((readl(&gpio->pgdat) & ~0x0040) | (x & 1) << 6, &gpio->pgdat);
-#endif -} -#endif
- /*
- Wait til the byte transfer is completed.
@@ -263,25 +199,6 @@ static void read_write_byte(struct s3c24x0_i2c *i2c) clrbits_le32(&i2c->iiccon, I2CCON_IRPND); }
-#ifdef CONFIG_SYS_I2C -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
* bus));
- return i2c;
-#elif defined CONFIG_EXYNOS5
- struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
+ (EXYNOS5_I2C_SPACING
* bus));
- return i2c;
-#else
- return s3c24x0_get_base_i2c();
-#endif -} -#endif
- static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { ulong freq, pres = 16, div;
@@ -412,88 +329,6 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) hsi2c_ch_init(i2c_bus); }
-#ifdef CONFIG_SYS_I2C -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);
- i2c = get_base_i2c(adap->hwadapnr);
- bus = &i2c_bus[adap->hwadapnr];
- if (!bus)
return;
- /*
* In case the previous transfer is still going, wait to give it a
* chance to finish.
*/
- while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
if (get_timer(start_time) > I2C_TIMEOUT_MS) {
printf("%s: I2C bus busy for %p\n", __func__,
&i2c->iicstat);
return;
}
- }
-#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
- int i;
- if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) {
-#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
ulong old_gpecon = readl(&gpio->gpecon);
-#endif -#ifdef CONFIG_S3C2400
ulong old_gpecon = readl(&gpio->pgcon);
-#endif
/* bus still busy probably by (most) previously interrupted
transfer */
-#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
/* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
writel((readl(&gpio->gpecon) & ~0xF0000000) | 0x10000000,
&gpio->gpecon);
-#endif -#ifdef CONFIG_S3C2400
/* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */
writel((readl(&gpio->pgcon) & ~0x00003c00) | 0x00001000,
&gpio->pgcon);
-#endif
/* toggle I2CSCL until bus idle */
SetI2CSCL(0);
udelay(1000);
i = 10;
while ((i > 0) && (GetI2CSDA() != 1)) {
SetI2CSCL(1);
udelay(1000);
SetI2CSCL(0);
udelay(1000);
i--;
}
SetI2CSCL(1);
udelay(1000);
/* restore pin functions */
-#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
writel(old_gpecon, &gpio->gpecon);
-#endif -#ifdef CONFIG_S3C2400
writel(old_gpecon, &gpio->pgcon);
-#endif
- }
-#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
- i2c_ch_init(i2c, speed, slaveadd);
- bus->active = true;
- bus->regs = i2c;
-} -#endif /* CONFIG_SYS_I2C */
- /*
- Poll the appropriate bit of the fifo status register until the interface is
- ready to process the next byte or timeout expires.
@@ -715,22 +550,10 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c, return rv; }
-#ifdef CONFIG_SYS_I2C -static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap,
unsigned int speed)
-#else static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) -#endif {
- struct s3c24x0_i2c_bus *i2c_bus;
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
-#ifdef CONFIG_SYS_I2C
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -EFAULT;
-#else
- i2c_bus = dev_get_priv(dev);
-#endif i2c_bus->clock_frequency = speed;
if (i2c_bus->is_highspeed) { @@ -857,23 +680,12 @@ bailout: return result; }
-#ifdef CONFIG_SYS_I2C -static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) -#else static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) -#endif {
- struct s3c24x0_i2c_bus *i2c_bus;
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); uchar buf[1]; int ret;
-#ifdef CONFIG_SYS_I2C
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -EFAULT;
-#else
- i2c_bus = dev_get_priv(dev);
-#endif buf[0] = 0;
/* @@ -892,398 +704,6 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) return ret != I2C_OK; }
-#ifdef CONFIG_SYS_I2C -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];
- int ret;
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -EFAULT;
- if (alen > 4) {
debug("I2C read: addr len %d not supported\n", alen);
return -EADDRNOTAVAIL;
- }
- if (alen > 0) {
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
- }
-#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
- /*
* EEPROM chips that implement "address overflow" are ones
* like Catalyst 24WC04/08/16 which has 9/10/11 bits of
* address and the extra bits end up in the "chip address"
* bit slots. This makes a 24WC08 (1Kbyte) chip look like
* four 256 byte chips.
*
* Note that we consider the length of the address field to
* still be one byte because the extra address bits are
* hidden in the chip address.
*/
- if (alen > 0)
chip |= ((addr >> (alen * 8)) &
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
-#endif
- if (i2c_bus->is_highspeed)
ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen],
alen, buffer, len);
- else
ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1,
&xaddr[4 - alen], alen, buffer, len);
- if (ret) {
if (i2c_bus->is_highspeed)
exynos5_i2c_reset(i2c_bus);
debug("I2c read failed %d\n", ret);
return -EIO;
- }
- return 0;
-}
-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];
- int ret;
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -EFAULT;
- if (alen > 4) {
debug("I2C write: addr len %d not supported\n", alen);
return -EINVAL;
- }
- if (alen > 0) {
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
- }
-#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
- /*
* EEPROM chips that implement "address overflow" are ones
* like Catalyst 24WC04/08/16 which has 9/10/11 bits of
* address and the extra bits end up in the "chip address"
* bit slots. This makes a 24WC08 (1Kbyte) chip look like
* four 256 byte chips.
*
* Note that we consider the length of the address field to
* still be one byte because the extra address bits are
* hidden in the chip address.
*/
- if (alen > 0)
chip |= ((addr >> (alen * 8)) &
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
-#endif
- if (i2c_bus->is_highspeed)
ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen],
alen, buffer, len, true);
- else
ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, chip << 1,
&xaddr[4 - alen], alen, buffer, len);
- if (ret != 0) {
if (i2c_bus->is_highspeed)
exynos5_i2c_reset(i2c_bus);
return 1;
- } else {
return 0;
- }
-}
-#if CONFIG_IS_ENABLED(OF_CONTROL) -static void process_nodes(const void *blob, int node_list[], int count,
int is_highspeed)
-{
- struct s3c24x0_i2c_bus *bus;
- int i, flags;
- for (i = 0; i < count; i++) {
int node = node_list[i];
if (node <= 0)
continue;
bus = &i2c_bus[i];
bus->active = true;
bus->is_highspeed = is_highspeed;
if (is_highspeed) {
flags = PINMUX_FLAG_HS_MODE;
bus->hsregs = (struct exynos5_hsi2c *)
fdtdec_get_addr(blob, node, "reg");
} else {
flags = 0;
bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
}
bus->id = pinmux_decode_periph_id(blob, node);
bus->clock_frequency = fdtdec_get_int(blob, node,
"clock-frequency",
CONFIG_SYS_I2C_S3C24X0_SPEED);
bus->node = node;
bus->bus_num = i;
exynos_pinmux_config(bus->id, flags);
/* Mark position as used */
node_list[i] = -1;
- }
-}
-void board_i2c_init(const void *blob) -{
- int node_list[CONFIG_MAX_I2C_NUM];
- 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);
-}
-int i2c_get_bus_num_fdt(int node) -{
- int i;
- for (i = 0; i < ARRAY_SIZE(i2c_bus); i++) {
if (node == i2c_bus[i].node)
return i;
- }
- debug("%s: Can't find any matched I2C bus\n", __func__);
- return -EINVAL;
-}
-int i2c_reset_port_fdt(const void *blob, int node) -{
- struct s3c24x0_i2c_bus *i2c_bus;
- int bus;
- bus = i2c_get_bus_num_fdt(node);
- if (bus < 0) {
debug("could not get bus for node %d\n", node);
return bus;
- }
- i2c_bus = get_bus(bus);
- if (!i2c_bus) {
debug("get_bus() failed for node %d\n", node);
return -EFAULT;
- }
- if (i2c_bus->is_highspeed) {
if (hsi2c_get_clk_details(i2c_bus))
return -EINVAL;
hsi2c_ch_init(i2c_bus);
- } else {
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_S3C24X0_SLAVE);
- }
- return 0;
-} -#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
-#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))
error("i2c_init: failed to init bus for speed = %d", speed);
-} -#endif /* CONFIG_EXYNOS5 */
-/*
- Register s3c24x0 i2c adapters
- */
-#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 -#endif /* CONFIG_SYS_I2C */
-#ifdef CONFIG_DM_I2C static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) { @@ -1460,4 +880,3 @@ U_BOOT_DRIVER(hs_i2c) = { .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), .ops = &exynos_hs_i2c_ops, }; -#endif /* CONFIG_DM_I2C */

Now that driver model is used for I2C on all boards, we can split the high-speed code into its own driver. There is virtually no common code, and this significantly reduces confusion.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/i2c/Makefile | 2 +- drivers/i2c/exynos_hs_i2c.c | 561 ++++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/s3c24x0_i2c.c | 551 +------------------------------------------ drivers/i2c/s3c24x0_i2c.h | 22 ++ 4 files changed, 591 insertions(+), 545 deletions(-) create mode 100644 drivers/i2c/exynos_hs_i2c.c
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 2987081..7c86198 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -34,7 +34,7 @@ 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_ROCKCHIP) += rk_i2c.o -obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o +obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o exynos_hs_i2c.o obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c new file mode 100644 index 0000000..9521aeb --- /dev/null +++ b/drivers/i2c/exynos_hs_i2c.c @@ -0,0 +1,561 @@ +/* + * Copyright (c) 2016, Google Inc + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <i2c.h> +#include <asm/arch/clk.h> +#include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> +#include "s3c24x0_i2c.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* HSI2C-specific register description */ + +/* I2C_CTL Register bits */ +#define HSI2C_FUNC_MODE_I2C (1u << 0) +#define HSI2C_MASTER (1u << 3) +#define HSI2C_RXCHON (1u << 6) /* Write/Send */ +#define HSI2C_TXCHON (1u << 7) /* Read/Receive */ +#define HSI2C_SW_RST (1u << 31) + +/* I2C_FIFO_CTL Register bits */ +#define HSI2C_RXFIFO_EN (1u << 0) +#define HSI2C_TXFIFO_EN (1u << 1) +#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x20 << 16) +#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x20 << 4) + +/* I2C_TRAILING_CTL Register bits */ +#define HSI2C_TRAILING_COUNT (0xff) + +/* I2C_INT_EN Register bits */ +#define HSI2C_TX_UNDERRUN_EN (1u << 2) +#define HSI2C_TX_OVERRUN_EN (1u << 3) +#define HSI2C_RX_UNDERRUN_EN (1u << 4) +#define HSI2C_RX_OVERRUN_EN (1u << 5) +#define HSI2C_INT_TRAILING_EN (1u << 6) +#define HSI2C_INT_I2C_EN (1u << 9) + +#define HSI2C_INT_ERROR_MASK (HSI2C_TX_UNDERRUN_EN |\ + HSI2C_TX_OVERRUN_EN |\ + HSI2C_RX_UNDERRUN_EN |\ + HSI2C_RX_OVERRUN_EN |\ + HSI2C_INT_TRAILING_EN) + +/* I2C_CONF Register bits */ +#define HSI2C_AUTO_MODE (1u << 31) +#define HSI2C_10BIT_ADDR_MODE (1u << 30) +#define HSI2C_HS_MODE (1u << 29) + +/* I2C_AUTO_CONF Register bits */ +#define HSI2C_READ_WRITE (1u << 16) +#define HSI2C_STOP_AFTER_TRANS (1u << 17) +#define HSI2C_MASTER_RUN (1u << 31) + +/* I2C_TIMEOUT Register bits */ +#define HSI2C_TIMEOUT_EN (1u << 31) + +/* I2C_TRANS_STATUS register bits */ +#define HSI2C_MASTER_BUSY (1u << 17) +#define HSI2C_SLAVE_BUSY (1u << 16) +#define HSI2C_TIMEOUT_AUTO (1u << 4) +#define HSI2C_NO_DEV (1u << 3) +#define HSI2C_NO_DEV_ACK (1u << 2) +#define HSI2C_TRANS_ABORT (1u << 1) +#define HSI2C_TRANS_SUCCESS (1u << 0) +#define HSI2C_TRANS_ERROR_MASK (HSI2C_TIMEOUT_AUTO |\ + HSI2C_NO_DEV | HSI2C_NO_DEV_ACK |\ + HSI2C_TRANS_ABORT) +#define HSI2C_TRANS_FINISHED_MASK (HSI2C_TRANS_ERROR_MASK | HSI2C_TRANS_SUCCESS) + + +/* I2C_FIFO_STAT Register bits */ +#define HSI2C_RX_FIFO_EMPTY (1u << 24) +#define HSI2C_RX_FIFO_FULL (1u << 23) +#define HSI2C_TX_FIFO_EMPTY (1u << 8) +#define HSI2C_TX_FIFO_FULL (1u << 7) +#define HSI2C_RX_FIFO_LEVEL(x) (((x) >> 16) & 0x7f) +#define HSI2C_TX_FIFO_LEVEL(x) ((x) & 0x7f) + +#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10) + +#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */ + +/* + * Wait for transfer completion. + * + * This function reads the interrupt status register waiting for the INT_I2C + * bit to be set, which indicates copletion of a transaction. + * + * @param i2c: pointer to the appropriate register bank + * + * @return: I2C_OK in case of successful completion, I2C_NOK_TIMEOUT in case + * the status bits do not get set in time, or an approrpiate error + * value in case of transfer errors. + */ +static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c) +{ + int i = HSI2C_TIMEOUT_US; + + while (i-- > 0) { + u32 int_status = readl(&i2c->usi_int_stat); + + if (int_status & HSI2C_INT_I2C_EN) { + u32 trans_status = readl(&i2c->usi_trans_status); + + /* Deassert pending interrupt. */ + writel(int_status, &i2c->usi_int_stat); + + if (trans_status & HSI2C_NO_DEV_ACK) { + debug("%s: no ACK from device\n", __func__); + return I2C_NACK; + } + if (trans_status & HSI2C_NO_DEV) { + debug("%s: no device\n", __func__); + return I2C_NOK; + } + if (trans_status & HSI2C_TRANS_ABORT) { + debug("%s: arbitration lost\n", __func__); + return I2C_NOK_LA; + } + if (trans_status & HSI2C_TIMEOUT_AUTO) { + debug("%s: device timed out\n", __func__); + return I2C_NOK_TOUT; + } + return I2C_OK; + } + udelay(1); + } + debug("%s: transaction timeout!\n", __func__); + return I2C_NOK_TOUT; +} + +static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) +{ + struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; + ulong clkin; + unsigned int op_clk = i2c_bus->clock_frequency; + unsigned int i = 0, utemp0 = 0, utemp1 = 0; + unsigned int t_ftl_cycle; + +#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 + * uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + * uTemp1 = (TSCLK_L + TSCLK_H + 2) + * uTemp2 = TSCLK_L + TSCLK_H + */ + t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7; + utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle; + + /* CLK_DIV max is 256 */ + for (i = 0; i < 256; i++) { + utemp1 = utemp0 / (i + 1); + if ((utemp1 < 512) && (utemp1 > 4)) { + i2c_bus->clk_cycle = utemp1 - 2; + i2c_bus->clk_div = i; + return 0; + } + } + return -EINVAL; +} + +static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) +{ + struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; + unsigned int t_sr_release; + unsigned int n_clkdiv; + unsigned int t_start_su, t_start_hd; + unsigned int t_stop_su; + unsigned int t_data_su, t_data_hd; + unsigned int t_scl_l, t_scl_h; + u32 i2c_timing_s1; + u32 i2c_timing_s2; + u32 i2c_timing_s3; + u32 i2c_timing_sla; + + n_clkdiv = i2c_bus->clk_div; + t_scl_l = i2c_bus->clk_cycle / 2; + t_scl_h = i2c_bus->clk_cycle / 2; + t_start_su = t_scl_l; + t_start_hd = t_scl_l; + t_stop_su = t_scl_l; + t_data_su = t_scl_l / 2; + t_data_hd = t_scl_l / 2; + t_sr_release = i2c_bus->clk_cycle; + + i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8; + i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0; + i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0; + i2c_timing_sla = t_data_hd << 0; + + writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl); + + /* Clear to enable Timeout */ + clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0); + + /* set AUTO mode */ + writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf); + + /* Enable completion conditions' reporting. */ + writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en); + + /* Enable FIFOs */ + writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl); + + /* Currently operating in Fast speed mode. */ + writel(i2c_timing_s1, &hsregs->usi_timing_fs1); + writel(i2c_timing_s2, &hsregs->usi_timing_fs2); + writel(i2c_timing_s3, &hsregs->usi_timing_fs3); + writel(i2c_timing_sla, &hsregs->usi_timing_sla); +} + +/* SW reset for the high speed bus */ +static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) +{ + struct exynos5_hsi2c *i2c = i2c_bus->hsregs; + u32 i2c_ctl; + + /* Set and clear the bit for reset */ + i2c_ctl = readl(&i2c->usi_ctl); + i2c_ctl |= HSI2C_SW_RST; + writel(i2c_ctl, &i2c->usi_ctl); + + i2c_ctl = readl(&i2c->usi_ctl); + i2c_ctl &= ~HSI2C_SW_RST; + writel(i2c_ctl, &i2c->usi_ctl); + + /* Initialize the configure registers */ + hsi2c_ch_init(i2c_bus); +} + +/* + * Poll the appropriate bit of the fifo status register until the interface is + * ready to process the next byte or timeout expires. + * + * In addition to the FIFO status register this function also polls the + * interrupt status register to be able to detect unexpected transaction + * completion. + * + * When FIFO is ready to process the next byte, this function returns I2C_OK. + * If in course of polling the INT_I2C assertion is detected, the function + * returns I2C_NOK. If timeout happens before any of the above conditions is + * met - the function returns I2C_NOK_TOUT; + + * @param i2c: pointer to the appropriate i2c register bank. + * @param rx_transfer: set to True if the receive transaction is in progress. + * @return: as described above. + */ +static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer) +{ + u32 fifo_bit = rx_transfer ? HSI2C_RX_FIFO_EMPTY : HSI2C_TX_FIFO_FULL; + int i = HSI2C_TIMEOUT_US; + + while (readl(&i2c->usi_fifo_stat) & fifo_bit) { + if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) { + /* + * There is a chance that assertion of + * HSI2C_INT_I2C_EN and deassertion of + * HSI2C_RX_FIFO_EMPTY happen simultaneously. Let's + * give FIFO status priority and check it one more + * time before reporting interrupt. The interrupt will + * be reported next time this function is called. + */ + if (rx_transfer && + !(readl(&i2c->usi_fifo_stat) & fifo_bit)) + break; + return I2C_NOK; + } + if (!i--) { + debug("%s: FIFO polling timeout!\n", __func__); + return I2C_NOK_TOUT; + } + udelay(1); + } + return I2C_OK; +} + +/* + * Preapre hsi2c transaction, either read or write. + * + * Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of + * the 5420 UM. + * + * @param i2c: pointer to the appropriate i2c register bank. + * @param chip: slave address on the i2c bus (with read/write bit exlcuded) + * @param len: number of bytes expected to be sent or received + * @param rx_transfer: set to true for receive transactions + * @param: issue_stop: set to true if i2c stop condition should be generated + * after this transaction. + * @return: I2C_NOK_TOUT in case the bus remained busy for HSI2C_TIMEOUT_US, + * I2C_OK otherwise. + */ +static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c, + u8 chip, + u16 len, + bool rx_transfer, + bool issue_stop) +{ + u32 conf; + + conf = len | HSI2C_MASTER_RUN; + + if (issue_stop) + conf |= HSI2C_STOP_AFTER_TRANS; + + /* Clear to enable Timeout */ + writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout); + + /* Set slave address */ + writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr); + + if (rx_transfer) { + /* i2c master, read transaction */ + writel((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), + &i2c->usi_ctl); + + /* read up to len bytes, stop after transaction is finished */ + writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf); + } else { + /* i2c master, write transaction */ + writel((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), + &i2c->usi_ctl); + + /* write up to len bytes, stop after transaction is finished */ + writel(conf, &i2c->usi_auto_conf); + } + + /* Reset all pending interrupt status bits we care about, if any */ + writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat); + + return I2C_OK; +} + +/* + * Wait while i2c bus is settling down (mostly stop gets completed). + */ +static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c) +{ + int i = HSI2C_TIMEOUT_US; + + while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) { + if (!i--) { + debug("%s: bus busy\n", __func__); + return I2C_NOK_TOUT; + } + udelay(1); + } + return I2C_OK; +} + +static int hsi2c_write(struct exynos5_hsi2c *i2c, + unsigned char chip, + unsigned char addr[], + unsigned char alen, + unsigned char data[], + unsigned short len, + bool issue_stop) +{ + int i, rv = 0; + + if (!(len + alen)) { + /* Writes of zero length not supported in auto mode. */ + debug("%s: zero length writes not supported\n", __func__); + return I2C_NOK; + } + + rv = hsi2c_prepare_transaction + (i2c, chip, len + alen, false, issue_stop); + if (rv != I2C_OK) + return rv; + + /* Move address, if any, and the data, if any, into the FIFO. */ + for (i = 0; i < alen; i++) { + rv = hsi2c_poll_fifo(i2c, false); + if (rv != I2C_OK) { + debug("%s: address write failed\n", __func__); + goto write_error; + } + writel(addr[i], &i2c->usi_txdata); + } + + for (i = 0; i < len; i++) { + rv = hsi2c_poll_fifo(i2c, false); + if (rv != I2C_OK) { + debug("%s: data write failed\n", __func__); + goto write_error; + } + writel(data[i], &i2c->usi_txdata); + } + + rv = hsi2c_wait_for_trx(i2c); + + write_error: + if (issue_stop) { + int tmp_ret = hsi2c_wait_while_busy(i2c); + if (rv == I2C_OK) + rv = tmp_ret; + } + + writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */ + return rv; +} + +static int hsi2c_read(struct exynos5_hsi2c *i2c, + unsigned char chip, + unsigned char addr[], + unsigned char alen, + unsigned char data[], + unsigned short len) +{ + int i, rv, tmp_ret; + bool drop_data = false; + + if (!len) { + /* Reads of zero length not supported in auto mode. */ + debug("%s: zero length read adjusted\n", __func__); + drop_data = true; + len = 1; + } + + if (alen) { + /* Internal register adress needs to be written first. */ + rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false); + if (rv != I2C_OK) + return rv; + } + + rv = hsi2c_prepare_transaction(i2c, chip, len, true, true); + + if (rv != I2C_OK) + return rv; + + for (i = 0; i < len; i++) { + rv = hsi2c_poll_fifo(i2c, true); + if (rv != I2C_OK) + goto read_err; + if (drop_data) + continue; + data[i] = readl(&i2c->usi_rxdata); + } + + rv = hsi2c_wait_for_trx(i2c); + + read_err: + tmp_ret = hsi2c_wait_while_busy(i2c); + if (rv == I2C_OK) + rv = tmp_ret; + + writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */ + return rv; +} + +static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; + int ret; + + for (; nmsgs > 0; nmsgs--, msg++) { + if (msg->flags & I2C_M_RD) { + ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf, + msg->len); + } else { + ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf, + msg->len, true); + } + if (ret) { + exynos5_i2c_reset(i2c_bus); + return -EREMOTEIO; + } + } + + return 0; +} + +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +{ + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + + i2c_bus->clock_frequency = speed; + + if (hsi2c_get_clk_details(i2c_bus)) + return -EFAULT; + hsi2c_ch_init(i2c_bus); + + return 0; +} + +static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) +{ + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + uchar buf[1]; + int ret; + + buf[0] = 0; + + /* + * What is needed is to send the chip address and verify that the + * address was <ACK>ed (i.e. there was a chip at that address which + * drove the data line low). + */ + ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buf, 1); + + return ret != I2C_OK; +} + +static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + int node; + + node = dev->of_offset; + + i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev); + + i2c_bus->id = pinmux_decode_periph_id(blob, node); + + i2c_bus->clock_frequency = fdtdec_get_int(blob, node, + "clock-frequency", 100000); + i2c_bus->node = node; + i2c_bus->bus_num = dev->seq; + + exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE); + + i2c_bus->active = true; + + return 0; +} + +static const struct dm_i2c_ops exynos_hs_i2c_ops = { + .xfer = exynos_hs_i2c_xfer, + .probe_chip = s3c24x0_i2c_probe, + .set_bus_speed = s3c24x0_i2c_set_bus_speed, +}; + +static const struct udevice_id exynos_hs_i2c_ids[] = { + { .compatible = "samsung,exynos5-hsi2c" }, + { } +}; + +U_BOOT_DRIVER(hs_i2c) = { + .name = "i2c_s3c_hs", + .id = UCLASS_I2C, + .of_match = exynos_hs_i2c_ids, + .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), + .ops = &exynos_hs_i2c_ops, +}; diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 24fc984..2ece9f4 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -24,105 +24,8 @@ #include <i2c.h> #include "s3c24x0_i2c.h"
-#define I2C_WRITE 0 -#define I2C_READ 1 - -#define I2C_OK 0 -#define I2C_NOK 1 -#define I2C_NACK 2 -#define I2C_NOK_LA 3 /* Lost arbitration */ -#define I2C_NOK_TOUT 4 /* time out */ - -/* HSI2C specific register description */ - -/* I2C_CTL Register bits */ -#define HSI2C_FUNC_MODE_I2C (1u << 0) -#define HSI2C_MASTER (1u << 3) -#define HSI2C_RXCHON (1u << 6) /* Write/Send */ -#define HSI2C_TXCHON (1u << 7) /* Read/Receive */ -#define HSI2C_SW_RST (1u << 31) - -/* I2C_FIFO_CTL Register bits */ -#define HSI2C_RXFIFO_EN (1u << 0) -#define HSI2C_TXFIFO_EN (1u << 1) -#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x20 << 16) -#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x20 << 4) - -/* I2C_TRAILING_CTL Register bits */ -#define HSI2C_TRAILING_COUNT (0xff) - -/* I2C_INT_EN Register bits */ -#define HSI2C_TX_UNDERRUN_EN (1u << 2) -#define HSI2C_TX_OVERRUN_EN (1u << 3) -#define HSI2C_RX_UNDERRUN_EN (1u << 4) -#define HSI2C_RX_OVERRUN_EN (1u << 5) -#define HSI2C_INT_TRAILING_EN (1u << 6) -#define HSI2C_INT_I2C_EN (1u << 9) - -#define HSI2C_INT_ERROR_MASK (HSI2C_TX_UNDERRUN_EN |\ - HSI2C_TX_OVERRUN_EN |\ - HSI2C_RX_UNDERRUN_EN |\ - HSI2C_RX_OVERRUN_EN |\ - HSI2C_INT_TRAILING_EN) - -/* I2C_CONF Register bits */ -#define HSI2C_AUTO_MODE (1u << 31) -#define HSI2C_10BIT_ADDR_MODE (1u << 30) -#define HSI2C_HS_MODE (1u << 29) - -/* I2C_AUTO_CONF Register bits */ -#define HSI2C_READ_WRITE (1u << 16) -#define HSI2C_STOP_AFTER_TRANS (1u << 17) -#define HSI2C_MASTER_RUN (1u << 31) - -/* I2C_TIMEOUT Register bits */ -#define HSI2C_TIMEOUT_EN (1u << 31) - -/* I2C_TRANS_STATUS register bits */ -#define HSI2C_MASTER_BUSY (1u << 17) -#define HSI2C_SLAVE_BUSY (1u << 16) -#define HSI2C_TIMEOUT_AUTO (1u << 4) -#define HSI2C_NO_DEV (1u << 3) -#define HSI2C_NO_DEV_ACK (1u << 2) -#define HSI2C_TRANS_ABORT (1u << 1) -#define HSI2C_TRANS_SUCCESS (1u << 0) -#define HSI2C_TRANS_ERROR_MASK (HSI2C_TIMEOUT_AUTO |\ - HSI2C_NO_DEV | HSI2C_NO_DEV_ACK |\ - HSI2C_TRANS_ABORT) -#define HSI2C_TRANS_FINISHED_MASK (HSI2C_TRANS_ERROR_MASK | HSI2C_TRANS_SUCCESS) - - -/* I2C_FIFO_STAT Register bits */ -#define HSI2C_RX_FIFO_EMPTY (1u << 24) -#define HSI2C_RX_FIFO_FULL (1u << 23) -#define HSI2C_TX_FIFO_EMPTY (1u << 8) -#define HSI2C_TX_FIFO_FULL (1u << 7) -#define HSI2C_RX_FIFO_LEVEL(x) (((x) >> 16) & 0x7f) -#define HSI2C_TX_FIFO_LEVEL(x) ((x) & 0x7f) - -#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10) - -/* S3C I2C Controller bits */ -#define I2CSTAT_BSY 0x20 /* Busy bit */ -#define I2CSTAT_NACK 0x01 /* Nack bit */ -#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */ -#define I2CCON_IRPND 0x10 /* Interrupt pending bit */ -#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */ -#define I2C_MODE_MR 0x80 /* Master Receive Mode */ -#define I2C_START_STOP 0x20 /* START / STOP */ -#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */ - -#define I2C_TIMEOUT_MS 10 /* 10 ms */ - -#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */ - DECLARE_GLOBAL_DATA_PTR;
-enum exynos_i2c_type { - EXYNOS_I2C_STD, - EXYNOS_I2C_HS, -}; - /* * Wait til the byte transfer is completed. * @@ -145,55 +48,6 @@ static int WaitForXfer(struct s3c24x0_i2c *i2c) return I2C_NOK_TOUT; }
-/* - * Wait for transfer completion. - * - * This function reads the interrupt status register waiting for the INT_I2C - * bit to be set, which indicates copletion of a transaction. - * - * @param i2c: pointer to the appropriate register bank - * - * @return: I2C_OK in case of successful completion, I2C_NOK_TIMEOUT in case - * the status bits do not get set in time, or an approrpiate error - * value in case of transfer errors. - */ -static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c) -{ - int i = HSI2C_TIMEOUT_US; - - while (i-- > 0) { - u32 int_status = readl(&i2c->usi_int_stat); - - if (int_status & HSI2C_INT_I2C_EN) { - u32 trans_status = readl(&i2c->usi_trans_status); - - /* Deassert pending interrupt. */ - writel(int_status, &i2c->usi_int_stat); - - if (trans_status & HSI2C_NO_DEV_ACK) { - debug("%s: no ACK from device\n", __func__); - return I2C_NACK; - } - if (trans_status & HSI2C_NO_DEV) { - debug("%s: no device\n", __func__); - return I2C_NOK; - } - if (trans_status & HSI2C_TRANS_ABORT) { - debug("%s: arbitration lost\n", __func__); - return I2C_NOK_LA; - } - if (trans_status & HSI2C_TIMEOUT_AUTO) { - debug("%s: device timed out\n", __func__); - return I2C_NOK_TOUT; - } - return I2C_OK; - } - udelay(1); - } - debug("%s: transaction timeout!\n", __func__); - return I2C_NOK_TOUT; -} - static void read_write_byte(struct s3c24x0_i2c *i2c) { clrbits_le32(&i2c->iiccon, I2CCON_IRPND); @@ -226,344 +80,14 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); }
-static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) -{ - struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; - ulong clkin; - unsigned int op_clk = i2c_bus->clock_frequency; - unsigned int i = 0, utemp0 = 0, utemp1 = 0; - unsigned int t_ftl_cycle; - -#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 - * uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) - * uTemp1 = (TSCLK_L + TSCLK_H + 2) - * uTemp2 = TSCLK_L + TSCLK_H - */ - t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7; - utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle; - - /* CLK_DIV max is 256 */ - for (i = 0; i < 256; i++) { - utemp1 = utemp0 / (i + 1); - if ((utemp1 < 512) && (utemp1 > 4)) { - i2c_bus->clk_cycle = utemp1 - 2; - i2c_bus->clk_div = i; - return 0; - } - } - return -EINVAL; -} - -static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) -{ - struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; - unsigned int t_sr_release; - unsigned int n_clkdiv; - unsigned int t_start_su, t_start_hd; - unsigned int t_stop_su; - unsigned int t_data_su, t_data_hd; - unsigned int t_scl_l, t_scl_h; - u32 i2c_timing_s1; - u32 i2c_timing_s2; - u32 i2c_timing_s3; - u32 i2c_timing_sla; - - n_clkdiv = i2c_bus->clk_div; - t_scl_l = i2c_bus->clk_cycle / 2; - t_scl_h = i2c_bus->clk_cycle / 2; - t_start_su = t_scl_l; - t_start_hd = t_scl_l; - t_stop_su = t_scl_l; - t_data_su = t_scl_l / 2; - t_data_hd = t_scl_l / 2; - t_sr_release = i2c_bus->clk_cycle; - - i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8; - i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0; - i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0; - i2c_timing_sla = t_data_hd << 0; - - writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl); - - /* Clear to enable Timeout */ - clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0); - - /* set AUTO mode */ - writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf); - - /* Enable completion conditions' reporting. */ - writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en); - - /* Enable FIFOs */ - writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl); - - /* Currently operating in Fast speed mode. */ - writel(i2c_timing_s1, &hsregs->usi_timing_fs1); - writel(i2c_timing_s2, &hsregs->usi_timing_fs2); - writel(i2c_timing_s3, &hsregs->usi_timing_fs3); - writel(i2c_timing_sla, &hsregs->usi_timing_sla); -} - -/* SW reset for the high speed bus */ -static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) -{ - struct exynos5_hsi2c *i2c = i2c_bus->hsregs; - u32 i2c_ctl; - - /* Set and clear the bit for reset */ - i2c_ctl = readl(&i2c->usi_ctl); - i2c_ctl |= HSI2C_SW_RST; - writel(i2c_ctl, &i2c->usi_ctl); - - i2c_ctl = readl(&i2c->usi_ctl); - i2c_ctl &= ~HSI2C_SW_RST; - writel(i2c_ctl, &i2c->usi_ctl); - - /* Initialize the configure registers */ - hsi2c_ch_init(i2c_bus); -} - -/* - * Poll the appropriate bit of the fifo status register until the interface is - * ready to process the next byte or timeout expires. - * - * In addition to the FIFO status register this function also polls the - * interrupt status register to be able to detect unexpected transaction - * completion. - * - * When FIFO is ready to process the next byte, this function returns I2C_OK. - * If in course of polling the INT_I2C assertion is detected, the function - * returns I2C_NOK. If timeout happens before any of the above conditions is - * met - the function returns I2C_NOK_TOUT; - - * @param i2c: pointer to the appropriate i2c register bank. - * @param rx_transfer: set to True if the receive transaction is in progress. - * @return: as described above. - */ -static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer) -{ - u32 fifo_bit = rx_transfer ? HSI2C_RX_FIFO_EMPTY : HSI2C_TX_FIFO_FULL; - int i = HSI2C_TIMEOUT_US; - - while (readl(&i2c->usi_fifo_stat) & fifo_bit) { - if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) { - /* - * There is a chance that assertion of - * HSI2C_INT_I2C_EN and deassertion of - * HSI2C_RX_FIFO_EMPTY happen simultaneously. Let's - * give FIFO status priority and check it one more - * time before reporting interrupt. The interrupt will - * be reported next time this function is called. - */ - if (rx_transfer && - !(readl(&i2c->usi_fifo_stat) & fifo_bit)) - break; - return I2C_NOK; - } - if (!i--) { - debug("%s: FIFO polling timeout!\n", __func__); - return I2C_NOK_TOUT; - } - udelay(1); - } - return I2C_OK; -} - -/* - * Preapre hsi2c transaction, either read or write. - * - * Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of - * the 5420 UM. - * - * @param i2c: pointer to the appropriate i2c register bank. - * @param chip: slave address on the i2c bus (with read/write bit exlcuded) - * @param len: number of bytes expected to be sent or received - * @param rx_transfer: set to true for receive transactions - * @param: issue_stop: set to true if i2c stop condition should be generated - * after this transaction. - * @return: I2C_NOK_TOUT in case the bus remained busy for HSI2C_TIMEOUT_US, - * I2C_OK otherwise. - */ -static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c, - u8 chip, - u16 len, - bool rx_transfer, - bool issue_stop) -{ - u32 conf; - - conf = len | HSI2C_MASTER_RUN; - - if (issue_stop) - conf |= HSI2C_STOP_AFTER_TRANS; - - /* Clear to enable Timeout */ - writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout); - - /* Set slave address */ - writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr); - - if (rx_transfer) { - /* i2c master, read transaction */ - writel((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), - &i2c->usi_ctl); - - /* read up to len bytes, stop after transaction is finished */ - writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf); - } else { - /* i2c master, write transaction */ - writel((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), - &i2c->usi_ctl); - - /* write up to len bytes, stop after transaction is finished */ - writel(conf, &i2c->usi_auto_conf); - } - - /* Reset all pending interrupt status bits we care about, if any */ - writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat); - - return I2C_OK; -} - -/* - * Wait while i2c bus is settling down (mostly stop gets completed). - */ -static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c) -{ - int i = HSI2C_TIMEOUT_US; - - while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) { - if (!i--) { - debug("%s: bus busy\n", __func__); - return I2C_NOK_TOUT; - } - udelay(1); - } - return I2C_OK; -} - -static int hsi2c_write(struct exynos5_hsi2c *i2c, - unsigned char chip, - unsigned char addr[], - unsigned char alen, - unsigned char data[], - unsigned short len, - bool issue_stop) -{ - int i, rv = 0; - - if (!(len + alen)) { - /* Writes of zero length not supported in auto mode. */ - debug("%s: zero length writes not supported\n", __func__); - return I2C_NOK; - } - - rv = hsi2c_prepare_transaction - (i2c, chip, len + alen, false, issue_stop); - if (rv != I2C_OK) - return rv; - - /* Move address, if any, and the data, if any, into the FIFO. */ - for (i = 0; i < alen; i++) { - rv = hsi2c_poll_fifo(i2c, false); - if (rv != I2C_OK) { - debug("%s: address write failed\n", __func__); - goto write_error; - } - writel(addr[i], &i2c->usi_txdata); - } - - for (i = 0; i < len; i++) { - rv = hsi2c_poll_fifo(i2c, false); - if (rv != I2C_OK) { - debug("%s: data write failed\n", __func__); - goto write_error; - } - writel(data[i], &i2c->usi_txdata); - } - - rv = hsi2c_wait_for_trx(i2c); - - write_error: - if (issue_stop) { - int tmp_ret = hsi2c_wait_while_busy(i2c); - if (rv == I2C_OK) - rv = tmp_ret; - } - - writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */ - return rv; -} - -static int hsi2c_read(struct exynos5_hsi2c *i2c, - unsigned char chip, - unsigned char addr[], - unsigned char alen, - unsigned char data[], - unsigned short len) -{ - int i, rv, tmp_ret; - bool drop_data = false; - - if (!len) { - /* Reads of zero length not supported in auto mode. */ - debug("%s: zero length read adjusted\n", __func__); - drop_data = true; - len = 1; - } - - if (alen) { - /* Internal register adress needs to be written first. */ - rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false); - if (rv != I2C_OK) - return rv; - } - - rv = hsi2c_prepare_transaction(i2c, chip, len, true, true); - - if (rv != I2C_OK) - return rv; - - for (i = 0; i < len; i++) { - rv = hsi2c_poll_fifo(i2c, true); - if (rv != I2C_OK) - goto read_err; - if (drop_data) - continue; - data[i] = readl(&i2c->usi_rxdata); - } - - rv = hsi2c_wait_for_trx(i2c); - - read_err: - tmp_ret = hsi2c_wait_while_busy(i2c); - if (rv == I2C_OK) - rv = tmp_ret; - - writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */ - return rv; -} - static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) { struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
i2c_bus->clock_frequency = speed;
- if (i2c_bus->is_highspeed) { - if (hsi2c_get_clk_details(i2c_bus)) - return -EFAULT; - hsi2c_ch_init(i2c_bus); - } else { - i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, - CONFIG_SYS_I2C_S3C24X0_SLAVE); - } + i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, + CONFIG_SYS_I2C_S3C24X0_SLAVE);
return 0; } @@ -693,41 +217,11 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) * address was <ACK>ed (i.e. there was a chip at that address which * drove the data line low). */ - if (i2c_bus->is_highspeed) { - ret = hsi2c_read(i2c_bus->hsregs, - chip, 0, 0, buf, 1); - } else { - ret = i2c_transfer(i2c_bus->regs, - I2C_READ, chip << 1, 0, 0, buf, 1); - } + ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1, 0, 0, buf, 1);
return ret != I2C_OK; }
-static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, - int nmsgs) -{ - struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); - struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; - int ret; - - for (; nmsgs > 0; nmsgs--, msg++) { - if (msg->flags & I2C_M_RD) { - ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf, - msg->len); - } else { - ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf, - msg->len, true); - } - if (ret) { - exynos5_i2c_reset(i2c_bus); - return -EREMOTEIO; - } - } - - return 0; -} - static int s3c24x0_do_msg(struct s3c24x0_i2c_bus *i2c_bus, struct i2c_msg *msg, int seq) { @@ -810,18 +304,11 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) { const void *blob = gd->fdt_blob; struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); - int node, flags; + int node;
- i2c_bus->is_highspeed = dev_get_driver_data(dev); node = dev->of_offset;
- if (i2c_bus->is_highspeed) { - flags = PINMUX_FLAG_HS_MODE; - i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev); - } else { - flags = 0; - i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev); - } + i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
i2c_bus->id = pinmux_decode_periph_id(blob, node);
@@ -830,7 +317,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) i2c_bus->node = node; i2c_bus->bus_num = dev->seq;
- exynos_pinmux_config(i2c_bus->id, flags); + exynos_pinmux_config(i2c_bus->id, 0);
i2c_bus->active = true;
@@ -844,7 +331,7 @@ static const struct dm_i2c_ops s3c_i2c_ops = { };
static const struct udevice_id s3c_i2c_ids[] = { - { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD }, + { .compatible = "samsung,s3c2440-i2c" }, { } };
@@ -856,27 +343,3 @@ U_BOOT_DRIVER(i2c_s3c) = { .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), .ops = &s3c_i2c_ops, }; - -/* - * TODO(sjg@chromium.org): Move this to a separate file when everything uses - * driver model - */ -static const struct dm_i2c_ops exynos_hs_i2c_ops = { - .xfer = exynos_hs_i2c_xfer, - .probe_chip = s3c24x0_i2c_probe, - .set_bus_speed = s3c24x0_i2c_set_bus_speed, -}; - -static const struct udevice_id exynos_hs_i2c_ids[] = { - { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS }, - { } -}; - -U_BOOT_DRIVER(hs_i2c) = { - .name = "i2c_s3c_hs", - .id = UCLASS_I2C, - .of_match = exynos_hs_i2c_ids, - .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata, - .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), - .ops = &exynos_hs_i2c_ops, -}; diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 1ae73d2..aa10fc7 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -59,4 +59,26 @@ struct s3c24x0_i2c_bus { unsigned clk_cycle; unsigned clk_div; }; + +#define I2C_WRITE 0 +#define I2C_READ 1 + +#define I2C_OK 0 +#define I2C_NOK 1 +#define I2C_NACK 2 +#define I2C_NOK_LA 3 /* Lost arbitration */ +#define I2C_NOK_TOUT 4 /* time out */ + +/* S3C I2C Controller bits */ +#define I2CSTAT_BSY 0x20 /* Busy bit */ +#define I2CSTAT_NACK 0x01 /* Nack bit */ +#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */ +#define I2CCON_IRPND 0x10 /* Interrupt pending bit */ +#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */ +#define I2C_MODE_MR 0x80 /* Master Receive Mode */ +#define I2C_START_STOP 0x20 /* START / STOP */ +#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */ + +#define I2C_TIMEOUT_MS 10 /* 10 ms */ + #endif /* _S3C24X0_I2C_H */

Hello Simon,
Am 23.11.2016 um 14:34 schrieb Simon Glass:
Now that driver model is used for I2C on all boards, we can split the high-speed code into its own driver. There is virtually no common code, and this significantly reduces confusion.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/i2c/Makefile | 2 +- drivers/i2c/exynos_hs_i2c.c | 561 ++++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/s3c24x0_i2c.c | 551 +------------------------------------------ drivers/i2c/s3c24x0_i2c.h | 22 ++ 4 files changed, 591 insertions(+), 545 deletions(-) create mode 100644 drivers/i2c/exynos_hs_i2c.c
Thanks!
Acked-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 2987081..7c86198 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -34,7 +34,7 @@ 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_ROCKCHIP) += rk_i2c.o -obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o +obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o exynos_hs_i2c.o obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c new file mode 100644 index 0000000..9521aeb --- /dev/null +++ b/drivers/i2c/exynos_hs_i2c.c @@ -0,0 +1,561 @@ +/*
- Copyright (c) 2016, Google Inc
- (C) Copyright 2002
- David Mueller, ELSOFT AG, d.mueller@elsoft.ch
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <dm.h> +#include <i2c.h> +#include <asm/arch/clk.h> +#include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> +#include "s3c24x0_i2c.h"
+DECLARE_GLOBAL_DATA_PTR;
+/* HSI2C-specific register description */
+/* I2C_CTL Register bits */ +#define HSI2C_FUNC_MODE_I2C (1u << 0) +#define HSI2C_MASTER (1u << 3) +#define HSI2C_RXCHON (1u << 6) /* Write/Send */ +#define HSI2C_TXCHON (1u << 7) /* Read/Receive */ +#define HSI2C_SW_RST (1u << 31)
+/* I2C_FIFO_CTL Register bits */ +#define HSI2C_RXFIFO_EN (1u << 0) +#define HSI2C_TXFIFO_EN (1u << 1) +#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x20 << 16) +#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x20 << 4)
+/* I2C_TRAILING_CTL Register bits */ +#define HSI2C_TRAILING_COUNT (0xff)
+/* I2C_INT_EN Register bits */ +#define HSI2C_TX_UNDERRUN_EN (1u << 2) +#define HSI2C_TX_OVERRUN_EN (1u << 3) +#define HSI2C_RX_UNDERRUN_EN (1u << 4) +#define HSI2C_RX_OVERRUN_EN (1u << 5) +#define HSI2C_INT_TRAILING_EN (1u << 6) +#define HSI2C_INT_I2C_EN (1u << 9)
+#define HSI2C_INT_ERROR_MASK (HSI2C_TX_UNDERRUN_EN |\
HSI2C_TX_OVERRUN_EN |\
HSI2C_RX_UNDERRUN_EN |\
HSI2C_RX_OVERRUN_EN |\
HSI2C_INT_TRAILING_EN)
+/* I2C_CONF Register bits */ +#define HSI2C_AUTO_MODE (1u << 31) +#define HSI2C_10BIT_ADDR_MODE (1u << 30) +#define HSI2C_HS_MODE (1u << 29)
+/* I2C_AUTO_CONF Register bits */ +#define HSI2C_READ_WRITE (1u << 16) +#define HSI2C_STOP_AFTER_TRANS (1u << 17) +#define HSI2C_MASTER_RUN (1u << 31)
+/* I2C_TIMEOUT Register bits */ +#define HSI2C_TIMEOUT_EN (1u << 31)
+/* I2C_TRANS_STATUS register bits */ +#define HSI2C_MASTER_BUSY (1u << 17) +#define HSI2C_SLAVE_BUSY (1u << 16) +#define HSI2C_TIMEOUT_AUTO (1u << 4) +#define HSI2C_NO_DEV (1u << 3) +#define HSI2C_NO_DEV_ACK (1u << 2) +#define HSI2C_TRANS_ABORT (1u << 1) +#define HSI2C_TRANS_SUCCESS (1u << 0) +#define HSI2C_TRANS_ERROR_MASK (HSI2C_TIMEOUT_AUTO |\
HSI2C_NO_DEV | HSI2C_NO_DEV_ACK |\
HSI2C_TRANS_ABORT)
+#define HSI2C_TRANS_FINISHED_MASK (HSI2C_TRANS_ERROR_MASK | HSI2C_TRANS_SUCCESS)
+/* I2C_FIFO_STAT Register bits */ +#define HSI2C_RX_FIFO_EMPTY (1u << 24) +#define HSI2C_RX_FIFO_FULL (1u << 23) +#define HSI2C_TX_FIFO_EMPTY (1u << 8) +#define HSI2C_TX_FIFO_FULL (1u << 7) +#define HSI2C_RX_FIFO_LEVEL(x) (((x) >> 16) & 0x7f) +#define HSI2C_TX_FIFO_LEVEL(x) ((x) & 0x7f)
+#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10)
+#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
+/*
- Wait for transfer completion.
- This function reads the interrupt status register waiting for the INT_I2C
- bit to be set, which indicates copletion of a transaction.
- @param i2c: pointer to the appropriate register bank
- @return: I2C_OK in case of successful completion, I2C_NOK_TIMEOUT in case
the status bits do not get set in time, or an approrpiate error
value in case of transfer errors.
- */
+static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c) +{
- int i = HSI2C_TIMEOUT_US;
- while (i-- > 0) {
u32 int_status = readl(&i2c->usi_int_stat);
if (int_status & HSI2C_INT_I2C_EN) {
u32 trans_status = readl(&i2c->usi_trans_status);
/* Deassert pending interrupt. */
writel(int_status, &i2c->usi_int_stat);
if (trans_status & HSI2C_NO_DEV_ACK) {
debug("%s: no ACK from device\n", __func__);
return I2C_NACK;
}
if (trans_status & HSI2C_NO_DEV) {
debug("%s: no device\n", __func__);
return I2C_NOK;
}
if (trans_status & HSI2C_TRANS_ABORT) {
debug("%s: arbitration lost\n", __func__);
return I2C_NOK_LA;
}
if (trans_status & HSI2C_TIMEOUT_AUTO) {
debug("%s: device timed out\n", __func__);
return I2C_NOK_TOUT;
}
return I2C_OK;
}
udelay(1);
- }
- debug("%s: transaction timeout!\n", __func__);
- return I2C_NOK_TOUT;
+}
+static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) +{
- struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
- ulong clkin;
- unsigned int op_clk = i2c_bus->clock_frequency;
- unsigned int i = 0, utemp0 = 0, utemp1 = 0;
- unsigned int t_ftl_cycle;
+#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
* uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
* uTemp1 = (TSCLK_L + TSCLK_H + 2)
* uTemp2 = TSCLK_L + TSCLK_H
*/
- t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7;
- utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle;
- /* CLK_DIV max is 256 */
- for (i = 0; i < 256; i++) {
utemp1 = utemp0 / (i + 1);
if ((utemp1 < 512) && (utemp1 > 4)) {
i2c_bus->clk_cycle = utemp1 - 2;
i2c_bus->clk_div = i;
return 0;
}
- }
- return -EINVAL;
+}
+static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) +{
- struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
- unsigned int t_sr_release;
- unsigned int n_clkdiv;
- unsigned int t_start_su, t_start_hd;
- unsigned int t_stop_su;
- unsigned int t_data_su, t_data_hd;
- unsigned int t_scl_l, t_scl_h;
- u32 i2c_timing_s1;
- u32 i2c_timing_s2;
- u32 i2c_timing_s3;
- u32 i2c_timing_sla;
- n_clkdiv = i2c_bus->clk_div;
- t_scl_l = i2c_bus->clk_cycle / 2;
- t_scl_h = i2c_bus->clk_cycle / 2;
- t_start_su = t_scl_l;
- t_start_hd = t_scl_l;
- t_stop_su = t_scl_l;
- t_data_su = t_scl_l / 2;
- t_data_hd = t_scl_l / 2;
- t_sr_release = i2c_bus->clk_cycle;
- i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
- i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0;
- i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0;
- i2c_timing_sla = t_data_hd << 0;
- writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl);
- /* Clear to enable Timeout */
- clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0);
- /* set AUTO mode */
- writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf);
- /* Enable completion conditions' reporting. */
- writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en);
- /* Enable FIFOs */
- writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl);
- /* Currently operating in Fast speed mode. */
- writel(i2c_timing_s1, &hsregs->usi_timing_fs1);
- writel(i2c_timing_s2, &hsregs->usi_timing_fs2);
- writel(i2c_timing_s3, &hsregs->usi_timing_fs3);
- writel(i2c_timing_sla, &hsregs->usi_timing_sla);
+}
+/* SW reset for the high speed bus */ +static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) +{
- struct exynos5_hsi2c *i2c = i2c_bus->hsregs;
- u32 i2c_ctl;
- /* Set and clear the bit for reset */
- i2c_ctl = readl(&i2c->usi_ctl);
- i2c_ctl |= HSI2C_SW_RST;
- writel(i2c_ctl, &i2c->usi_ctl);
- i2c_ctl = readl(&i2c->usi_ctl);
- i2c_ctl &= ~HSI2C_SW_RST;
- writel(i2c_ctl, &i2c->usi_ctl);
- /* Initialize the configure registers */
- hsi2c_ch_init(i2c_bus);
+}
+/*
- Poll the appropriate bit of the fifo status register until the interface is
- ready to process the next byte or timeout expires.
- In addition to the FIFO status register this function also polls the
- interrupt status register to be able to detect unexpected transaction
- completion.
- When FIFO is ready to process the next byte, this function returns I2C_OK.
- If in course of polling the INT_I2C assertion is detected, the function
- returns I2C_NOK. If timeout happens before any of the above conditions is
- met - the function returns I2C_NOK_TOUT;
- @param i2c: pointer to the appropriate i2c register bank.
- @param rx_transfer: set to True if the receive transaction is in progress.
- @return: as described above.
- */
+static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer) +{
- u32 fifo_bit = rx_transfer ? HSI2C_RX_FIFO_EMPTY : HSI2C_TX_FIFO_FULL;
- int i = HSI2C_TIMEOUT_US;
- while (readl(&i2c->usi_fifo_stat) & fifo_bit) {
if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) {
/*
* There is a chance that assertion of
* HSI2C_INT_I2C_EN and deassertion of
* HSI2C_RX_FIFO_EMPTY happen simultaneously. Let's
* give FIFO status priority and check it one more
* time before reporting interrupt. The interrupt will
* be reported next time this function is called.
*/
if (rx_transfer &&
!(readl(&i2c->usi_fifo_stat) & fifo_bit))
break;
return I2C_NOK;
}
if (!i--) {
debug("%s: FIFO polling timeout!\n", __func__);
return I2C_NOK_TOUT;
}
udelay(1);
- }
- return I2C_OK;
+}
+/*
- Preapre hsi2c transaction, either read or write.
- Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of
- the 5420 UM.
- @param i2c: pointer to the appropriate i2c register bank.
- @param chip: slave address on the i2c bus (with read/write bit exlcuded)
- @param len: number of bytes expected to be sent or received
- @param rx_transfer: set to true for receive transactions
- @param: issue_stop: set to true if i2c stop condition should be generated
after this transaction.
- @return: I2C_NOK_TOUT in case the bus remained busy for HSI2C_TIMEOUT_US,
I2C_OK otherwise.
- */
+static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c,
u8 chip,
u16 len,
bool rx_transfer,
bool issue_stop)
+{
- u32 conf;
- conf = len | HSI2C_MASTER_RUN;
- if (issue_stop)
conf |= HSI2C_STOP_AFTER_TRANS;
- /* Clear to enable Timeout */
- writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout);
- /* Set slave address */
- writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr);
- if (rx_transfer) {
/* i2c master, read transaction */
writel((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
&i2c->usi_ctl);
/* read up to len bytes, stop after transaction is finished */
writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf);
- } else {
/* i2c master, write transaction */
writel((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
&i2c->usi_ctl);
/* write up to len bytes, stop after transaction is finished */
writel(conf, &i2c->usi_auto_conf);
- }
- /* Reset all pending interrupt status bits we care about, if any */
- writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat);
- return I2C_OK;
+}
+/*
- Wait while i2c bus is settling down (mostly stop gets completed).
- */
+static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c) +{
- int i = HSI2C_TIMEOUT_US;
- while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) {
if (!i--) {
debug("%s: bus busy\n", __func__);
return I2C_NOK_TOUT;
}
udelay(1);
- }
- return I2C_OK;
+}
+static int hsi2c_write(struct exynos5_hsi2c *i2c,
unsigned char chip,
unsigned char addr[],
unsigned char alen,
unsigned char data[],
unsigned short len,
bool issue_stop)
+{
- int i, rv = 0;
- if (!(len + alen)) {
/* Writes of zero length not supported in auto mode. */
debug("%s: zero length writes not supported\n", __func__);
return I2C_NOK;
- }
- rv = hsi2c_prepare_transaction
(i2c, chip, len + alen, false, issue_stop);
- if (rv != I2C_OK)
return rv;
- /* Move address, if any, and the data, if any, into the FIFO. */
- for (i = 0; i < alen; i++) {
rv = hsi2c_poll_fifo(i2c, false);
if (rv != I2C_OK) {
debug("%s: address write failed\n", __func__);
goto write_error;
}
writel(addr[i], &i2c->usi_txdata);
- }
- for (i = 0; i < len; i++) {
rv = hsi2c_poll_fifo(i2c, false);
if (rv != I2C_OK) {
debug("%s: data write failed\n", __func__);
goto write_error;
}
writel(data[i], &i2c->usi_txdata);
- }
- rv = hsi2c_wait_for_trx(i2c);
- write_error:
- if (issue_stop) {
int tmp_ret = hsi2c_wait_while_busy(i2c);
if (rv == I2C_OK)
rv = tmp_ret;
- }
- writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
- return rv;
+}
+static int hsi2c_read(struct exynos5_hsi2c *i2c,
unsigned char chip,
unsigned char addr[],
unsigned char alen,
unsigned char data[],
unsigned short len)
+{
- int i, rv, tmp_ret;
- bool drop_data = false;
- if (!len) {
/* Reads of zero length not supported in auto mode. */
debug("%s: zero length read adjusted\n", __func__);
drop_data = true;
len = 1;
- }
- if (alen) {
/* Internal register adress needs to be written first. */
rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false);
if (rv != I2C_OK)
return rv;
- }
- rv = hsi2c_prepare_transaction(i2c, chip, len, true, true);
- if (rv != I2C_OK)
return rv;
- for (i = 0; i < len; i++) {
rv = hsi2c_poll_fifo(i2c, true);
if (rv != I2C_OK)
goto read_err;
if (drop_data)
continue;
data[i] = readl(&i2c->usi_rxdata);
- }
- rv = hsi2c_wait_for_trx(i2c);
- read_err:
- tmp_ret = hsi2c_wait_while_busy(i2c);
- if (rv == I2C_OK)
rv = tmp_ret;
- writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
- return rv;
+}
+static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
int nmsgs)
+{
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
- struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
- int ret;
- for (; nmsgs > 0; nmsgs--, msg++) {
if (msg->flags & I2C_M_RD) {
ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf,
msg->len);
} else {
ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf,
msg->len, true);
}
if (ret) {
exynos5_i2c_reset(i2c_bus);
return -EREMOTEIO;
}
- }
- return 0;
+}
+static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +{
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
- i2c_bus->clock_frequency = speed;
- if (hsi2c_get_clk_details(i2c_bus))
return -EFAULT;
- hsi2c_ch_init(i2c_bus);
- return 0;
+}
+static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) +{
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
- uchar buf[1];
- int ret;
- buf[0] = 0;
- /*
* What is needed is to send the chip address and verify that the
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
- ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buf, 1);
- return ret != I2C_OK;
+}
+static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{
- const void *blob = gd->fdt_blob;
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
- int node;
- node = dev->of_offset;
- i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev);
- i2c_bus->id = pinmux_decode_periph_id(blob, node);
- i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
"clock-frequency", 100000);
- i2c_bus->node = node;
- i2c_bus->bus_num = dev->seq;
- exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE);
- i2c_bus->active = true;
- return 0;
+}
+static const struct dm_i2c_ops exynos_hs_i2c_ops = {
- .xfer = exynos_hs_i2c_xfer,
- .probe_chip = s3c24x0_i2c_probe,
- .set_bus_speed = s3c24x0_i2c_set_bus_speed,
+};
+static const struct udevice_id exynos_hs_i2c_ids[] = {
- { .compatible = "samsung,exynos5-hsi2c" },
- { }
+};
+U_BOOT_DRIVER(hs_i2c) = {
- .name = "i2c_s3c_hs",
- .id = UCLASS_I2C,
- .of_match = exynos_hs_i2c_ids,
- .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
- .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
- .ops = &exynos_hs_i2c_ops,
+}; diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 24fc984..2ece9f4 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -24,105 +24,8 @@ #include <i2c.h> #include "s3c24x0_i2c.h"
-#define I2C_WRITE 0 -#define I2C_READ 1
-#define I2C_OK 0 -#define I2C_NOK 1 -#define I2C_NACK 2 -#define I2C_NOK_LA 3 /* Lost arbitration */ -#define I2C_NOK_TOUT 4 /* time out */
-/* HSI2C specific register description */
-/* I2C_CTL Register bits */ -#define HSI2C_FUNC_MODE_I2C (1u << 0) -#define HSI2C_MASTER (1u << 3) -#define HSI2C_RXCHON (1u << 6) /* Write/Send */ -#define HSI2C_TXCHON (1u << 7) /* Read/Receive */ -#define HSI2C_SW_RST (1u << 31)
-/* I2C_FIFO_CTL Register bits */ -#define HSI2C_RXFIFO_EN (1u << 0) -#define HSI2C_TXFIFO_EN (1u << 1) -#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x20 << 16) -#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x20 << 4)
-/* I2C_TRAILING_CTL Register bits */ -#define HSI2C_TRAILING_COUNT (0xff)
-/* I2C_INT_EN Register bits */ -#define HSI2C_TX_UNDERRUN_EN (1u << 2) -#define HSI2C_TX_OVERRUN_EN (1u << 3) -#define HSI2C_RX_UNDERRUN_EN (1u << 4) -#define HSI2C_RX_OVERRUN_EN (1u << 5) -#define HSI2C_INT_TRAILING_EN (1u << 6) -#define HSI2C_INT_I2C_EN (1u << 9)
-#define HSI2C_INT_ERROR_MASK (HSI2C_TX_UNDERRUN_EN |\
HSI2C_TX_OVERRUN_EN |\
HSI2C_RX_UNDERRUN_EN |\
HSI2C_RX_OVERRUN_EN |\
HSI2C_INT_TRAILING_EN)
-/* I2C_CONF Register bits */ -#define HSI2C_AUTO_MODE (1u << 31) -#define HSI2C_10BIT_ADDR_MODE (1u << 30) -#define HSI2C_HS_MODE (1u << 29)
-/* I2C_AUTO_CONF Register bits */ -#define HSI2C_READ_WRITE (1u << 16) -#define HSI2C_STOP_AFTER_TRANS (1u << 17) -#define HSI2C_MASTER_RUN (1u << 31)
-/* I2C_TIMEOUT Register bits */ -#define HSI2C_TIMEOUT_EN (1u << 31)
-/* I2C_TRANS_STATUS register bits */ -#define HSI2C_MASTER_BUSY (1u << 17) -#define HSI2C_SLAVE_BUSY (1u << 16) -#define HSI2C_TIMEOUT_AUTO (1u << 4) -#define HSI2C_NO_DEV (1u << 3) -#define HSI2C_NO_DEV_ACK (1u << 2) -#define HSI2C_TRANS_ABORT (1u << 1) -#define HSI2C_TRANS_SUCCESS (1u << 0) -#define HSI2C_TRANS_ERROR_MASK (HSI2C_TIMEOUT_AUTO |\
HSI2C_NO_DEV | HSI2C_NO_DEV_ACK |\
HSI2C_TRANS_ABORT)
-#define HSI2C_TRANS_FINISHED_MASK (HSI2C_TRANS_ERROR_MASK | HSI2C_TRANS_SUCCESS)
-/* I2C_FIFO_STAT Register bits */ -#define HSI2C_RX_FIFO_EMPTY (1u << 24) -#define HSI2C_RX_FIFO_FULL (1u << 23) -#define HSI2C_TX_FIFO_EMPTY (1u << 8) -#define HSI2C_TX_FIFO_FULL (1u << 7) -#define HSI2C_RX_FIFO_LEVEL(x) (((x) >> 16) & 0x7f) -#define HSI2C_TX_FIFO_LEVEL(x) ((x) & 0x7f)
-#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10)
-/* S3C I2C Controller bits */ -#define I2CSTAT_BSY 0x20 /* Busy bit */ -#define I2CSTAT_NACK 0x01 /* Nack bit */ -#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */ -#define I2CCON_IRPND 0x10 /* Interrupt pending bit */ -#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */ -#define I2C_MODE_MR 0x80 /* Master Receive Mode */ -#define I2C_START_STOP 0x20 /* START / STOP */ -#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
-#define I2C_TIMEOUT_MS 10 /* 10 ms */
-#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
- DECLARE_GLOBAL_DATA_PTR;
-enum exynos_i2c_type {
- EXYNOS_I2C_STD,
- EXYNOS_I2C_HS,
-};
- /*
- Wait til the byte transfer is completed.
@@ -145,55 +48,6 @@ static int WaitForXfer(struct s3c24x0_i2c *i2c) return I2C_NOK_TOUT; }
-/*
- Wait for transfer completion.
- This function reads the interrupt status register waiting for the INT_I2C
- bit to be set, which indicates copletion of a transaction.
- @param i2c: pointer to the appropriate register bank
- @return: I2C_OK in case of successful completion, I2C_NOK_TIMEOUT in case
the status bits do not get set in time, or an approrpiate error
value in case of transfer errors.
- */
-static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c) -{
- int i = HSI2C_TIMEOUT_US;
- while (i-- > 0) {
u32 int_status = readl(&i2c->usi_int_stat);
if (int_status & HSI2C_INT_I2C_EN) {
u32 trans_status = readl(&i2c->usi_trans_status);
/* Deassert pending interrupt. */
writel(int_status, &i2c->usi_int_stat);
if (trans_status & HSI2C_NO_DEV_ACK) {
debug("%s: no ACK from device\n", __func__);
return I2C_NACK;
}
if (trans_status & HSI2C_NO_DEV) {
debug("%s: no device\n", __func__);
return I2C_NOK;
}
if (trans_status & HSI2C_TRANS_ABORT) {
debug("%s: arbitration lost\n", __func__);
return I2C_NOK_LA;
}
if (trans_status & HSI2C_TIMEOUT_AUTO) {
debug("%s: device timed out\n", __func__);
return I2C_NOK_TOUT;
}
return I2C_OK;
}
udelay(1);
- }
- debug("%s: transaction timeout!\n", __func__);
- return I2C_NOK_TOUT;
-}
- static void read_write_byte(struct s3c24x0_i2c *i2c) { clrbits_le32(&i2c->iiccon, I2CCON_IRPND);
@@ -226,344 +80,14 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); }
-static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) -{
- struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
- ulong clkin;
- unsigned int op_clk = i2c_bus->clock_frequency;
- unsigned int i = 0, utemp0 = 0, utemp1 = 0;
- unsigned int t_ftl_cycle;
-#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
* uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
* uTemp1 = (TSCLK_L + TSCLK_H + 2)
* uTemp2 = TSCLK_L + TSCLK_H
*/
- t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7;
- utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle;
- /* CLK_DIV max is 256 */
- for (i = 0; i < 256; i++) {
utemp1 = utemp0 / (i + 1);
if ((utemp1 < 512) && (utemp1 > 4)) {
i2c_bus->clk_cycle = utemp1 - 2;
i2c_bus->clk_div = i;
return 0;
}
- }
- return -EINVAL;
-}
-static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) -{
- struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
- unsigned int t_sr_release;
- unsigned int n_clkdiv;
- unsigned int t_start_su, t_start_hd;
- unsigned int t_stop_su;
- unsigned int t_data_su, t_data_hd;
- unsigned int t_scl_l, t_scl_h;
- u32 i2c_timing_s1;
- u32 i2c_timing_s2;
- u32 i2c_timing_s3;
- u32 i2c_timing_sla;
- n_clkdiv = i2c_bus->clk_div;
- t_scl_l = i2c_bus->clk_cycle / 2;
- t_scl_h = i2c_bus->clk_cycle / 2;
- t_start_su = t_scl_l;
- t_start_hd = t_scl_l;
- t_stop_su = t_scl_l;
- t_data_su = t_scl_l / 2;
- t_data_hd = t_scl_l / 2;
- t_sr_release = i2c_bus->clk_cycle;
- i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
- i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0;
- i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0;
- i2c_timing_sla = t_data_hd << 0;
- writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl);
- /* Clear to enable Timeout */
- clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0);
- /* set AUTO mode */
- writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf);
- /* Enable completion conditions' reporting. */
- writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en);
- /* Enable FIFOs */
- writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl);
- /* Currently operating in Fast speed mode. */
- writel(i2c_timing_s1, &hsregs->usi_timing_fs1);
- writel(i2c_timing_s2, &hsregs->usi_timing_fs2);
- writel(i2c_timing_s3, &hsregs->usi_timing_fs3);
- writel(i2c_timing_sla, &hsregs->usi_timing_sla);
-}
-/* SW reset for the high speed bus */ -static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) -{
- struct exynos5_hsi2c *i2c = i2c_bus->hsregs;
- u32 i2c_ctl;
- /* Set and clear the bit for reset */
- i2c_ctl = readl(&i2c->usi_ctl);
- i2c_ctl |= HSI2C_SW_RST;
- writel(i2c_ctl, &i2c->usi_ctl);
- i2c_ctl = readl(&i2c->usi_ctl);
- i2c_ctl &= ~HSI2C_SW_RST;
- writel(i2c_ctl, &i2c->usi_ctl);
- /* Initialize the configure registers */
- hsi2c_ch_init(i2c_bus);
-}
-/*
- Poll the appropriate bit of the fifo status register until the interface is
- ready to process the next byte or timeout expires.
- In addition to the FIFO status register this function also polls the
- interrupt status register to be able to detect unexpected transaction
- completion.
- When FIFO is ready to process the next byte, this function returns I2C_OK.
- If in course of polling the INT_I2C assertion is detected, the function
- returns I2C_NOK. If timeout happens before any of the above conditions is
- met - the function returns I2C_NOK_TOUT;
- @param i2c: pointer to the appropriate i2c register bank.
- @param rx_transfer: set to True if the receive transaction is in progress.
- @return: as described above.
- */
-static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer) -{
- u32 fifo_bit = rx_transfer ? HSI2C_RX_FIFO_EMPTY : HSI2C_TX_FIFO_FULL;
- int i = HSI2C_TIMEOUT_US;
- while (readl(&i2c->usi_fifo_stat) & fifo_bit) {
if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) {
/*
* There is a chance that assertion of
* HSI2C_INT_I2C_EN and deassertion of
* HSI2C_RX_FIFO_EMPTY happen simultaneously. Let's
* give FIFO status priority and check it one more
* time before reporting interrupt. The interrupt will
* be reported next time this function is called.
*/
if (rx_transfer &&
!(readl(&i2c->usi_fifo_stat) & fifo_bit))
break;
return I2C_NOK;
}
if (!i--) {
debug("%s: FIFO polling timeout!\n", __func__);
return I2C_NOK_TOUT;
}
udelay(1);
- }
- return I2C_OK;
-}
-/*
- Preapre hsi2c transaction, either read or write.
- Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of
- the 5420 UM.
- @param i2c: pointer to the appropriate i2c register bank.
- @param chip: slave address on the i2c bus (with read/write bit exlcuded)
- @param len: number of bytes expected to be sent or received
- @param rx_transfer: set to true for receive transactions
- @param: issue_stop: set to true if i2c stop condition should be generated
after this transaction.
- @return: I2C_NOK_TOUT in case the bus remained busy for HSI2C_TIMEOUT_US,
I2C_OK otherwise.
- */
-static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c,
u8 chip,
u16 len,
bool rx_transfer,
bool issue_stop)
-{
- u32 conf;
- conf = len | HSI2C_MASTER_RUN;
- if (issue_stop)
conf |= HSI2C_STOP_AFTER_TRANS;
- /* Clear to enable Timeout */
- writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout);
- /* Set slave address */
- writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr);
- if (rx_transfer) {
/* i2c master, read transaction */
writel((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
&i2c->usi_ctl);
/* read up to len bytes, stop after transaction is finished */
writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf);
- } else {
/* i2c master, write transaction */
writel((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
&i2c->usi_ctl);
/* write up to len bytes, stop after transaction is finished */
writel(conf, &i2c->usi_auto_conf);
- }
- /* Reset all pending interrupt status bits we care about, if any */
- writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat);
- return I2C_OK;
-}
-/*
- Wait while i2c bus is settling down (mostly stop gets completed).
- */
-static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c) -{
- int i = HSI2C_TIMEOUT_US;
- while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) {
if (!i--) {
debug("%s: bus busy\n", __func__);
return I2C_NOK_TOUT;
}
udelay(1);
- }
- return I2C_OK;
-}
-static int hsi2c_write(struct exynos5_hsi2c *i2c,
unsigned char chip,
unsigned char addr[],
unsigned char alen,
unsigned char data[],
unsigned short len,
bool issue_stop)
-{
- int i, rv = 0;
- if (!(len + alen)) {
/* Writes of zero length not supported in auto mode. */
debug("%s: zero length writes not supported\n", __func__);
return I2C_NOK;
- }
- rv = hsi2c_prepare_transaction
(i2c, chip, len + alen, false, issue_stop);
- if (rv != I2C_OK)
return rv;
- /* Move address, if any, and the data, if any, into the FIFO. */
- for (i = 0; i < alen; i++) {
rv = hsi2c_poll_fifo(i2c, false);
if (rv != I2C_OK) {
debug("%s: address write failed\n", __func__);
goto write_error;
}
writel(addr[i], &i2c->usi_txdata);
- }
- for (i = 0; i < len; i++) {
rv = hsi2c_poll_fifo(i2c, false);
if (rv != I2C_OK) {
debug("%s: data write failed\n", __func__);
goto write_error;
}
writel(data[i], &i2c->usi_txdata);
- }
- rv = hsi2c_wait_for_trx(i2c);
- write_error:
- if (issue_stop) {
int tmp_ret = hsi2c_wait_while_busy(i2c);
if (rv == I2C_OK)
rv = tmp_ret;
- }
- writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
- return rv;
-}
-static int hsi2c_read(struct exynos5_hsi2c *i2c,
unsigned char chip,
unsigned char addr[],
unsigned char alen,
unsigned char data[],
unsigned short len)
-{
- int i, rv, tmp_ret;
- bool drop_data = false;
- if (!len) {
/* Reads of zero length not supported in auto mode. */
debug("%s: zero length read adjusted\n", __func__);
drop_data = true;
len = 1;
- }
- if (alen) {
/* Internal register adress needs to be written first. */
rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false);
if (rv != I2C_OK)
return rv;
- }
- rv = hsi2c_prepare_transaction(i2c, chip, len, true, true);
- if (rv != I2C_OK)
return rv;
- for (i = 0; i < len; i++) {
rv = hsi2c_poll_fifo(i2c, true);
if (rv != I2C_OK)
goto read_err;
if (drop_data)
continue;
data[i] = readl(&i2c->usi_rxdata);
- }
- rv = hsi2c_wait_for_trx(i2c);
- read_err:
- tmp_ret = hsi2c_wait_while_busy(i2c);
- if (rv == I2C_OK)
rv = tmp_ret;
- writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
- return rv;
-}
static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) { struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
i2c_bus->clock_frequency = speed;
if (i2c_bus->is_highspeed) {
if (hsi2c_get_clk_details(i2c_bus))
return -EFAULT;
hsi2c_ch_init(i2c_bus);
} else {
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_S3C24X0_SLAVE);
}
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_S3C24X0_SLAVE);
return 0; }
@@ -693,41 +217,11 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) * address was <ACK>ed (i.e. there was a chip at that address which * drove the data line low). */
- if (i2c_bus->is_highspeed) {
ret = hsi2c_read(i2c_bus->hsregs,
chip, 0, 0, buf, 1);
- } else {
ret = i2c_transfer(i2c_bus->regs,
I2C_READ, chip << 1, 0, 0, buf, 1);
- }
ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1, 0, 0, buf, 1);
return ret != I2C_OK; }
-static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
int nmsgs)
-{
- struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
- struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
- int ret;
- for (; nmsgs > 0; nmsgs--, msg++) {
if (msg->flags & I2C_M_RD) {
ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf,
msg->len);
} else {
ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf,
msg->len, true);
}
if (ret) {
exynos5_i2c_reset(i2c_bus);
return -EREMOTEIO;
}
- }
- return 0;
-}
- static int s3c24x0_do_msg(struct s3c24x0_i2c_bus *i2c_bus, struct i2c_msg *msg, int seq) {
@@ -810,18 +304,11 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) { const void *blob = gd->fdt_blob; struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
- int node, flags;
- int node;
i2c_bus->is_highspeed = dev_get_driver_data(dev); node = dev->of_offset;
if (i2c_bus->is_highspeed) {
flags = PINMUX_FLAG_HS_MODE;
i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev);
} else {
flags = 0;
i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
}
i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
i2c_bus->id = pinmux_decode_periph_id(blob, node);
@@ -830,7 +317,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) i2c_bus->node = node; i2c_bus->bus_num = dev->seq;
- exynos_pinmux_config(i2c_bus->id, flags);
exynos_pinmux_config(i2c_bus->id, 0);
i2c_bus->active = true;
@@ -844,7 +331,7 @@ static const struct dm_i2c_ops s3c_i2c_ops = { };
static const struct udevice_id s3c_i2c_ids[] = {
- { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD },
- { .compatible = "samsung,s3c2440-i2c" }, { } };
@@ -856,27 +343,3 @@ U_BOOT_DRIVER(i2c_s3c) = { .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), .ops = &s3c_i2c_ops, };
-/*
- TODO(sjg@chromium.org): Move this to a separate file when everything uses
- driver model
- */
-static const struct dm_i2c_ops exynos_hs_i2c_ops = {
- .xfer = exynos_hs_i2c_xfer,
- .probe_chip = s3c24x0_i2c_probe,
- .set_bus_speed = s3c24x0_i2c_set_bus_speed,
-};
-static const struct udevice_id exynos_hs_i2c_ids[] = {
- { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS },
- { }
-};
-U_BOOT_DRIVER(hs_i2c) = {
- .name = "i2c_s3c_hs",
- .id = UCLASS_I2C,
- .of_match = exynos_hs_i2c_ids,
- .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
- .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
- .ops = &exynos_hs_i2c_ops,
-}; diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 1ae73d2..aa10fc7 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -59,4 +59,26 @@ struct s3c24x0_i2c_bus { unsigned clk_cycle; unsigned clk_div; };
+#define I2C_WRITE 0 +#define I2C_READ 1
+#define I2C_OK 0 +#define I2C_NOK 1 +#define I2C_NACK 2 +#define I2C_NOK_LA 3 /* Lost arbitration */ +#define I2C_NOK_TOUT 4 /* time out */
+/* S3C I2C Controller bits */ +#define I2CSTAT_BSY 0x20 /* Busy bit */ +#define I2CSTAT_NACK 0x01 /* Nack bit */ +#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */ +#define I2CCON_IRPND 0x10 /* Interrupt pending bit */ +#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */ +#define I2C_MODE_MR 0x80 /* Master Receive Mode */ +#define I2C_START_STOP 0x20 /* START / STOP */ +#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
+#define I2C_TIMEOUT_MS 10 /* 10 ms */
- #endif /* _S3C24X0_I2C_H */

Maintainers need to be notified more directly of the need to convert these drivers. Add a note to the top each affected file.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/i2c/adi_i2c.c | 3 +++ drivers/i2c/davinci_i2c.c | 3 +++ drivers/i2c/fti2c010.c | 3 +++ drivers/i2c/ihs_i2c.c | 3 +++ drivers/i2c/kona_i2c.c | 3 +++ drivers/i2c/lpc32xx_i2c.c | 3 +++ drivers/i2c/pca9564_i2c.c | 3 +++ drivers/i2c/ppc4xx_i2c.c | 3 +++ drivers/i2c/rcar_i2c.c | 3 +++ drivers/i2c/sh_i2c.c | 3 +++ drivers/i2c/sh_sh7734_i2c.c | 3 +++ drivers/i2c/soft_i2c.c | 3 +++ drivers/i2c/tsi108_i2c.c | 3 +++ drivers/i2c/zynq_i2c.c | 3 +++ 14 files changed, 42 insertions(+)
diff --git a/drivers/i2c/adi_i2c.c b/drivers/i2c/adi_i2c.c index f0c0841..d340639 100644 --- a/drivers/i2c/adi_i2c.c +++ b/drivers/i2c/adi_i2c.c @@ -4,6 +4,9 @@ * Copyright (c) 2006-2014 Analog Devices Inc. * * Licensed under the GPL-2 or later. + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index 9ca99c4..c5bd38c 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -7,6 +7,9 @@ * -------------------------------------------------------- * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index 68d9a42..b35d0d2 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -5,6 +5,9 @@ * Dante Su dantesu@faraday-tech.com * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c index b05c15f..29612e6 100644 --- a/drivers/i2c/ihs_i2c.c +++ b/drivers/i2c/ihs_i2c.c @@ -3,6 +3,9 @@ * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c index 1228ef3..26ee202 100644 --- a/drivers/i2c/kona_i2c.c +++ b/drivers/i2c/kona_i2c.c @@ -2,6 +2,9 @@ * Copyright 2013 Broadcom Corporation. * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/lpc32xx_i2c.c b/drivers/i2c/lpc32xx_i2c.c index 3e842e7..b0167ab 100644 --- a/drivers/i2c/lpc32xx_i2c.c +++ b/drivers/i2c/lpc32xx_i2c.c @@ -5,6 +5,9 @@ * Written-by: Albert ARIBAUD - 3ADEV albert.aribaud@3adev.fr * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/pca9564_i2c.c b/drivers/i2c/pca9564_i2c.c index 313288d..4ed0923 100644 --- a/drivers/i2c/pca9564_i2c.c +++ b/drivers/i2c/pca9564_i2c.c @@ -12,6 +12,9 @@ * Bugs: * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/ppc4xx_i2c.c b/drivers/i2c/ppc4xx_i2c.c index df88885..8a38d11 100644 --- a/drivers/i2c/ppc4xx_i2c.c +++ b/drivers/i2c/ppc4xx_i2c.c @@ -8,6 +8,9 @@ * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/rcar_i2c.c b/drivers/i2c/rcar_i2c.c index 90ad116..bfba443 100644 --- a/drivers/i2c/rcar_i2c.c +++ b/drivers/i2c/rcar_i2c.c @@ -5,6 +5,9 @@ * Copyright (C) 2013 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com * * SPDX-License-Identifier: GPL-2.0 + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index e7e9692..ef79725 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -3,6 +3,9 @@ * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/sh_sh7734_i2c.c b/drivers/i2c/sh_sh7734_i2c.c index 6c2f221..1c12fb8 100644 --- a/drivers/i2c/sh_sh7734_i2c.c +++ b/drivers/i2c/sh_sh7734_i2c.c @@ -3,6 +3,9 @@ * Copyright (C) 2012 Renesas Solutions Corp. * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index 05bf4d4..c102a1a 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -11,6 +11,9 @@ * This has been changed substantially by Gerald Van Baren, Custom IDEAS, * vanbaren@cideas.com. It was heavily influenced by LiMon, written by * Neil Russell. + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h> diff --git a/drivers/i2c/tsi108_i2c.c b/drivers/i2c/tsi108_i2c.c index c077907..90292d2 100644 --- a/drivers/i2c/tsi108_i2c.c +++ b/drivers/i2c/tsi108_i2c.c @@ -3,6 +3,9 @@ * Author: Alex Bounine * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <config.h> diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c index 2f6b364..85be58f 100644 --- a/drivers/i2c/zynq_i2c.c +++ b/drivers/i2c/zynq_i2c.c @@ -8,6 +8,9 @@ * Copyright (c) 2012-2013 Xilinx, Michal Simek * * SPDX-License-Identifier: GPL-2.0+ + * + * NOTE: This driver should be converted to driver model before June 2017. + * Please see doc/driver-model/i2c-howto.txt for instructions. */
#include <common.h>

Hello Simon,
Am 23.11.2016 um 14:34 schrieb Simon Glass:
Maintainers need to be notified more directly of the need to convert these drivers. Add a note to the top each affected file.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/i2c/adi_i2c.c | 3 +++ drivers/i2c/davinci_i2c.c | 3 +++ drivers/i2c/fti2c010.c | 3 +++ drivers/i2c/ihs_i2c.c | 3 +++ drivers/i2c/kona_i2c.c | 3 +++ drivers/i2c/lpc32xx_i2c.c | 3 +++ drivers/i2c/pca9564_i2c.c | 3 +++ drivers/i2c/ppc4xx_i2c.c | 3 +++ drivers/i2c/rcar_i2c.c | 3 +++ drivers/i2c/sh_i2c.c | 3 +++ drivers/i2c/sh_sh7734_i2c.c | 3 +++ drivers/i2c/soft_i2c.c | 3 +++ drivers/i2c/tsi108_i2c.c | 3 +++ drivers/i2c/zynq_i2c.c | 3 +++ 14 files changed, 42 insertions(+)
Thanks!
Acked-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/drivers/i2c/adi_i2c.c b/drivers/i2c/adi_i2c.c index f0c0841..d340639 100644 --- a/drivers/i2c/adi_i2c.c +++ b/drivers/i2c/adi_i2c.c @@ -4,6 +4,9 @@
- Copyright (c) 2006-2014 Analog Devices Inc.
- Licensed under the GPL-2 or later.
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index 9ca99c4..c5bd38c 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -7,6 +7,9 @@
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index 68d9a42..b35d0d2 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -5,6 +5,9 @@
- Dante Su dantesu@faraday-tech.com
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c index b05c15f..29612e6 100644 --- a/drivers/i2c/ihs_i2c.c +++ b/drivers/i2c/ihs_i2c.c @@ -3,6 +3,9 @@
- Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c index 1228ef3..26ee202 100644 --- a/drivers/i2c/kona_i2c.c +++ b/drivers/i2c/kona_i2c.c @@ -2,6 +2,9 @@
- Copyright 2013 Broadcom Corporation.
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/lpc32xx_i2c.c b/drivers/i2c/lpc32xx_i2c.c index 3e842e7..b0167ab 100644 --- a/drivers/i2c/lpc32xx_i2c.c +++ b/drivers/i2c/lpc32xx_i2c.c @@ -5,6 +5,9 @@
- Written-by: Albert ARIBAUD - 3ADEV albert.aribaud@3adev.fr
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/pca9564_i2c.c b/drivers/i2c/pca9564_i2c.c index 313288d..4ed0923 100644 --- a/drivers/i2c/pca9564_i2c.c +++ b/drivers/i2c/pca9564_i2c.c @@ -12,6 +12,9 @@
- Bugs:
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/ppc4xx_i2c.c b/drivers/i2c/ppc4xx_i2c.c index df88885..8a38d11 100644 --- a/drivers/i2c/ppc4xx_i2c.c +++ b/drivers/i2c/ppc4xx_i2c.c @@ -8,6 +8,9 @@
- Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/rcar_i2c.c b/drivers/i2c/rcar_i2c.c index 90ad116..bfba443 100644 --- a/drivers/i2c/rcar_i2c.c +++ b/drivers/i2c/rcar_i2c.c @@ -5,6 +5,9 @@
- Copyright (C) 2013 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
- SPDX-License-Identifier: GPL-2.0
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index e7e9692..ef79725 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -3,6 +3,9 @@
- Copyright (C) 2011, 2013 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/sh_sh7734_i2c.c b/drivers/i2c/sh_sh7734_i2c.c index 6c2f221..1c12fb8 100644 --- a/drivers/i2c/sh_sh7734_i2c.c +++ b/drivers/i2c/sh_sh7734_i2c.c @@ -3,6 +3,9 @@
- Copyright (C) 2012 Renesas Solutions Corp.
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index 05bf4d4..c102a1a 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -11,6 +11,9 @@
- This has been changed substantially by Gerald Van Baren, Custom IDEAS,
- vanbaren@cideas.com. It was heavily influenced by LiMon, written by
- Neil Russell.
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/tsi108_i2c.c b/drivers/i2c/tsi108_i2c.c index c077907..90292d2 100644 --- a/drivers/i2c/tsi108_i2c.c +++ b/drivers/i2c/tsi108_i2c.c @@ -3,6 +3,9 @@
- Author: Alex Bounine
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <config.h>
diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c index 2f6b364..85be58f 100644 --- a/drivers/i2c/zynq_i2c.c +++ b/drivers/i2c/zynq_i2c.c @@ -8,6 +8,9 @@
- Copyright (c) 2012-2013 Xilinx, Michal Simek
- SPDX-License-Identifier: GPL-2.0+
- NOTE: This driver should be converted to driver model before June 2017.
- Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>

Add a README with a brief guide to porting i2c drivers over to use driver model.
Add a timeline also. All I2C drivers should be converted by the end of June 2017.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/driver-model/i2c-howto.txt | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/driver-model/i2c-howto.txt
diff --git a/doc/driver-model/i2c-howto.txt b/doc/driver-model/i2c-howto.txt new file mode 100644 index 0000000..605d3ef --- /dev/null +++ b/doc/driver-model/i2c-howto.txt @@ -0,0 +1,56 @@ +How to port a serial driver to driver model +=========================================== + +Over half of the I2C drivers have been converted as at November 2016. These +ones remain: + + adi_i2c + davinci_i2c + fti2c010 + ihs_i2c + kona_i2c + lpc32xx_i2c + pca9564_i2c + ppc4xx_i2c + rcar_i2c + sh_i2c + sh_sh7734_i2c + soft_i2c + tsi108_i2c + zynq_i2c + +The deadline for this work is the end of June 2017. If no one steps +forward to convert these, at some point there may come a patch to remove them! + +Here is a suggested approach for converting your I2C driver over to driver +model. Please feel free to update this file with your ideas and suggestions. + +- #ifdef out all your own I2C driver code (#ifndef CONFIG_DM_I2C) +- Define CONFIG_DM_I2C for your board, vendor or architecture +- If the board does not already use driver model, you need CONFIG_DM also +- Your board should then build, but will not work fully since there will be + no I2C driver +- Add the U_BOOT_DRIVER piece at the end (e.g. copy tegra_i2c.c for example) +- Add a private struct for the driver data - avoid using static variables +- Implement each of the driver methods, perhaps by calling your old methods +- You may need to adjust the function parameters so that the old and new + implementations can share most of the existing code +- If you convert all existing users of the driver, remove the pre-driver-model + code + +In terms of patches a conversion series typically has these patches: +- clean up / prepare the driver for conversion +- add driver model code +- convert at least one existing board to use driver model serial +- (if no boards remain that don't use driver model) remove the old code + +This may be a good time to move your board to use device tree also. Mostly +this involves these steps: + +- define CONFIG_OF_CONTROL and CONFIG_OF_SEPARATE +- add your device tree files to arch/<arch>/dts +- update the Makefile there +- Add stdout-path to your /chosen device tree node if it is not already there +- build and get u-boot-dtb.bin so you can test it +- Your drivers can now use device tree +- For device tree in SPL, define CONFIG_SPL_OF_CONTROL

On 23.11.2016 14:34, Simon Glass wrote:
Add a README with a brief guide to porting i2c drivers over to use driver model.
Add a timeline also. All I2C drivers should be converted by the end of June 2017.
Signed-off-by: Simon Glass sjg@chromium.org
doc/driver-model/i2c-howto.txt | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/driver-model/i2c-howto.txt
diff --git a/doc/driver-model/i2c-howto.txt b/doc/driver-model/i2c-howto.txt new file mode 100644 index 0000000..605d3ef --- /dev/null +++ b/doc/driver-model/i2c-howto.txt @@ -0,0 +1,56 @@ +How to port a serial driver to driver model +===========================================
+Over half of the I2C drivers have been converted as at November 2016. These +ones remain:
- adi_i2c
- davinci_i2c
- fti2c010
- ihs_i2c
- kona_i2c
- lpc32xx_i2c
- pca9564_i2c
- ppc4xx_i2c
- rcar_i2c
- sh_i2c
- sh_sh7734_i2c
- soft_i2c
- tsi108_i2c
- zynq_i2c
FYI: we are not going to move this driver to DM. There is i2c-cdns.c which replace this one. But because eeprom framework hasn't been merged yet we need to have this driver for old configurations.
Thanks, Michal

Hi Michal,
On 23 November 2016 at 07:52, Michal Simek michal.simek@xilinx.com wrote:
On 23.11.2016 14:34, Simon Glass wrote:
Add a README with a brief guide to porting i2c drivers over to use driver model.
Add a timeline also. All I2C drivers should be converted by the end of June 2017.
Signed-off-by: Simon Glass sjg@chromium.org
doc/driver-model/i2c-howto.txt | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/driver-model/i2c-howto.txt
diff --git a/doc/driver-model/i2c-howto.txt b/doc/driver-model/i2c-howto.txt new file mode 100644 index 0000000..605d3ef --- /dev/null +++ b/doc/driver-model/i2c-howto.txt @@ -0,0 +1,56 @@ +How to port a serial driver to driver model +===========================================
+Over half of the I2C drivers have been converted as at November 2016. These +ones remain:
- adi_i2c
- davinci_i2c
- fti2c010
- ihs_i2c
- kona_i2c
- lpc32xx_i2c
- pca9564_i2c
- ppc4xx_i2c
- rcar_i2c
- sh_i2c
- sh_sh7734_i2c
- soft_i2c
- tsi108_i2c
- zynq_i2c
FYI: we are not going to move this driver to DM. There is i2c-cdns.c which replace this one. But because eeprom framework hasn't been merged yet we need to have this driver for old configurations.
OK, thanks, one less to worry about!
- Simon

Hello Simon,
Am 23.11.2016 um 14:34 schrieb Simon Glass:
Add a README with a brief guide to porting i2c drivers over to use driver model.
Add a timeline also. All I2C drivers should be converted by the end of June 2017.
Signed-off-by: Simon Glass sjg@chromium.org
doc/driver-model/i2c-howto.txt | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/driver-model/i2c-howto.txt
Thanks!
Acked-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/doc/driver-model/i2c-howto.txt b/doc/driver-model/i2c-howto.txt new file mode 100644 index 0000000..605d3ef --- /dev/null +++ b/doc/driver-model/i2c-howto.txt @@ -0,0 +1,56 @@ +How to port a serial driver to driver model +===========================================
+Over half of the I2C drivers have been converted as at November 2016. These +ones remain:
- adi_i2c
- davinci_i2c
- fti2c010
- ihs_i2c
- kona_i2c
- lpc32xx_i2c
- pca9564_i2c
- ppc4xx_i2c
- rcar_i2c
- sh_i2c
- sh_sh7734_i2c
- soft_i2c
- tsi108_i2c
- zynq_i2c
+The deadline for this work is the end of June 2017. If no one steps +forward to convert these, at some point there may come a patch to remove them!
+Here is a suggested approach for converting your I2C driver over to driver +model. Please feel free to update this file with your ideas and suggestions.
+- #ifdef out all your own I2C driver code (#ifndef CONFIG_DM_I2C) +- Define CONFIG_DM_I2C for your board, vendor or architecture +- If the board does not already use driver model, you need CONFIG_DM also +- Your board should then build, but will not work fully since there will be
- no I2C driver
+- Add the U_BOOT_DRIVER piece at the end (e.g. copy tegra_i2c.c for example) +- Add a private struct for the driver data - avoid using static variables +- Implement each of the driver methods, perhaps by calling your old methods +- You may need to adjust the function parameters so that the old and new
- implementations can share most of the existing code
+- If you convert all existing users of the driver, remove the pre-driver-model
- code
+In terms of patches a conversion series typically has these patches: +- clean up / prepare the driver for conversion +- add driver model code +- convert at least one existing board to use driver model serial +- (if no boards remain that don't use driver model) remove the old code
+This may be a good time to move your board to use device tree also. Mostly +this involves these steps:
+- define CONFIG_OF_CONTROL and CONFIG_OF_SEPARATE +- add your device tree files to arch/<arch>/dts +- update the Makefile there +- Add stdout-path to your /chosen device tree node if it is not already there +- build and get u-boot-dtb.bin so you can test it +- Your drivers can now use device tree +- For device tree in SPL, define CONFIG_SPL_OF_CONTROL

Hi Simon,
On 11/23/2016 10:34 PM, Simon Glass wrote:
Driver-model I2C support was added about 2 years ago. So far a little over half of the driveres have been converted. This series sets a timeline for conversion of the rest by June next year.
The Samsung I2C driver was one of the first converted, but some boards still remain using the old subsystem. This series converts these over in an experimental way: disabling code that uses the old framework. This should provide more time for the maintainers to take action while allowing the conversion to be completed.
About using the old framework, i will discuss with Minkyu. After that, if it needs, i or my colleague will change to DM.
Best Regards, Jaehoon Chung
Simon Glass (6): arm: exynos: i2c: Convert exynos boards to use DM_I2C arm: samsung: Convert s5p_goni and smdkc100 to DM_I2C samsung: i2c: Drop old code from I2C driver samsung: i2c: Split the high-speed I2C code into a new driver dm: i2c: Add a note to I2C drivers which need conversion dm: Add timeline and guide for porting I2C drivers
arch/arm/Kconfig | 2 + board/samsung/common/misc.c | 4 + board/samsung/goni/goni.c | 7 +- board/samsung/trats/trats.c | 20 +- board/samsung/trats2/trats2.c | 18 +- board/samsung/universal_c210/universal.c | 22 +- configs/origen_defconfig | 1 + doc/driver-model/i2c-howto.txt | 56 ++ drivers/i2c/Makefile | 2 +- drivers/i2c/adi_i2c.c | 3 + drivers/i2c/davinci_i2c.c | 3 + drivers/i2c/exynos_hs_i2c.c | 561 +++++++++++++++ drivers/i2c/fti2c010.c | 3 + drivers/i2c/ihs_i2c.c | 3 + drivers/i2c/kona_i2c.c | 3 + drivers/i2c/lpc32xx_i2c.c | 3 + drivers/i2c/pca9564_i2c.c | 3 + drivers/i2c/ppc4xx_i2c.c | 3 + drivers/i2c/rcar_i2c.c | 3 + drivers/i2c/s3c24x0_i2c.c | 1136 +----------------------------- drivers/i2c/s3c24x0_i2c.h | 22 + drivers/i2c/sh_i2c.c | 3 + drivers/i2c/sh_sh7734_i2c.c | 3 + drivers/i2c/soft_i2c.c | 3 + drivers/i2c/tsi108_i2c.c | 3 + drivers/i2c/zynq_i2c.c | 3 + include/configs/s5p_goni.h | 19 - include/configs/s5pc210_universal.h | 19 - include/configs/trats.h | 30 - include/configs/trats2.h | 33 - 30 files changed, 752 insertions(+), 1242 deletions(-) create mode 100644 doc/driver-model/i2c-howto.txt create mode 100644 drivers/i2c/exynos_hs_i2c.c

On Tuesday, 6 December 2016, Jaehoon Chung wrote:
Hi Simon,
On 11/23/2016 10:34 PM, Simon Glass wrote:
Driver-model I2C support was added about 2 years ago. So far a little
over
half of the driveres have been converted. This series sets a timeline for conversion of the rest by June next year.
The Samsung I2C driver was one of the first converted, but some boards still remain using the old subsystem. This series converts these over in an experimental way: disabling code that uses the old framework. This should provide more time for the maintainers to take action while
allowing
the conversion to be completed.
About using the old framework, i will discuss with Minkyu. After that, if it needs, i or my colleague will change to DM.
Yes! please : ) I will contact you.
Thanks, Minkyu Kang
Best Regards, Jaehoon Chung
Simon Glass (6): arm: exynos: i2c: Convert exynos boards to use DM_I2C arm: samsung: Convert s5p_goni and smdkc100 to DM_I2C samsung: i2c: Drop old code from I2C driver samsung: i2c: Split the high-speed I2C code into a new driver dm: i2c: Add a note to I2C drivers which need conversion dm: Add timeline and guide for porting I2C drivers
arch/arm/Kconfig | 2 + board/samsung/common/misc.c | 4 + board/samsung/goni/goni.c | 7 +- board/samsung/trats/trats.c | 20 +- board/samsung/trats2/trats2.c | 18 +- board/samsung/universal_c210/universal.c | 22 +- configs/origen_defconfig | 1 + doc/driver-model/i2c-howto.txt | 56 ++ drivers/i2c/Makefile | 2 +- drivers/i2c/adi_i2c.c | 3 + drivers/i2c/davinci_i2c.c | 3 + drivers/i2c/exynos_hs_i2c.c | 561 +++++++++++++++ drivers/i2c/fti2c010.c | 3 + drivers/i2c/ihs_i2c.c | 3 + drivers/i2c/kona_i2c.c | 3 + drivers/i2c/lpc32xx_i2c.c | 3 + drivers/i2c/pca9564_i2c.c | 3 + drivers/i2c/ppc4xx_i2c.c | 3 + drivers/i2c/rcar_i2c.c | 3 + drivers/i2c/s3c24x0_i2c.c | 1136
+-----------------------------
drivers/i2c/s3c24x0_i2c.h | 22 + drivers/i2c/sh_i2c.c | 3 + drivers/i2c/sh_sh7734_i2c.c | 3 + drivers/i2c/soft_i2c.c | 3 + drivers/i2c/tsi108_i2c.c | 3 + drivers/i2c/zynq_i2c.c | 3 + include/configs/s5p_goni.h | 19 - include/configs/s5pc210_universal.h | 19 - include/configs/trats.h | 30 - include/configs/trats2.h | 33 - 30 files changed, 752 insertions(+), 1242 deletions(-) create mode 100644 doc/driver-model/i2c-howto.txt create mode 100644 drivers/i2c/exynos_hs_i2c.c
U-Boot mailing list U-Boot@lists.denx.de javascript:; http://lists.denx.de/mailman/listinfo/u-boot
participants (5)
-
Heiko Schocher
-
Jaehoon Chung
-
Michal Simek
-
Minkyu Kang
-
Simon Glass