[U-Boot] [PATCH 00/18] Exynos: move i2c driver to dm api

This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So this can't be enabled with the full board functionality.
In this case each Exynos5 based boards have fixed config dependencies for testing the dm i2c api with the new i2c driver. This will facilitate the peripheral porting.
For test, just enable CONFIG_DM_I2C in exynos5-common.h. The i2c command should work with this as previous.
This patchset also provides some changes related to Exynos4 boards. Most Exynos4 boards requires only pmic support, and this will be done with the new pmic framework soon.
Przemyslaw Marczak (18): arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config dm: i2c: s3c24x0: adjust to dm-i2c api exynos5: config: prepare for dm i2c support exynos5250: config: temporary disable sound for dm i2c arndale: config: temporary disable pmic for dm i2c exynos5-dt: config: temporary disable pmic for dm i2c snow: config: temporary disable cros ec i2c for dm i2c smdk5250: config: temporary disable pmic for dm i2c smdk5420: board: fix build warning for testing dm i2c peach-pi: config: temporary disable video parade for dm i2c peach-pit: config: temporary disable video parade for dm i2c trats2: board: cleanup power init code trats2: config: disable i2c peripherals if testing dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 ++-- arch/arm/dts/exynos4.dtsi | 24 ++-- arch/arm/dts/exynos5250-arndale.dts | 8 ++ board/samsung/smdk5420/smdk5420.c | 2 +- board/samsung/trats2/trats2.c | 144 +++++++++++--------- drivers/i2c/s3c24x0_i2c.c | 254 +++++++++++++++++++++++++++++++----- include/configs/arndale.h | 5 +- include/configs/exynos5-common.h | 29 ++-- include/configs/exynos5-dt-common.h | 2 + include/configs/exynos5250-common.h | 5 +- include/configs/peach-pi.h | 2 + include/configs/peach-pit.h | 2 + include/configs/smdk5250.h | 4 + include/configs/snow.h | 4 +- include/configs/trats2.h | 17 ++- 15 files changed, 395 insertions(+), 134 deletions(-)

There is no MAX77686 pmic on this board, so the driver support should be removed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/arndale.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index d68993b..3ad4a9b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -51,8 +51,6 @@ /* PMIC */ #define CONFIG_PMIC #define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -
#define CONFIG_PREBOOT

This PMIC is not common for all Exynos5250 based boards, so should be romoved from common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/exynos5250-common.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index 6714313..ae0e5ff 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -28,9 +28,6 @@
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
-/* PMIC */ -#define CONFIG_POWER_MAX77686 - /* Sound */ #define CONFIG_CMD_SOUND #ifdef CONFIG_CMD_SOUND

On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
This PMIC is not common for all Exynos5250 based boards, so should be romoved from common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/exynos5250-common.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index 6714313..ae0e5ff 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -28,9 +28,6 @@
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
-/* PMIC */ -#define CONFIG_POWER_MAX77686
/* Sound */ #define CONFIG_CMD_SOUND
#ifdef CONFIG_CMD_SOUND
1.9.1
Acked-by: Simon Glass sjg@chromium.org

This commit enable support for the above driver, which was disabled in common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 8395372..3b06d30 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -18,6 +18,8 @@
#include <configs/exynos5250-common.h>
+/* PMIC */ +#define CONFIG_POWER_MAX77686
#define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R

On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
This commit enable support for the above driver, which was disabled in common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+)
Acked-by: Simon Glass sjg@chromium.org

This patch modify i2c nodes in exynos4.dtsi with: - adding proper interrupts arrays for each i2c node, which allows to decode periph id - add reg address for each i2c node for i2c driver internal use
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com --- arch/arm/dts/exynos4.dtsi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi index 77fad48..0e46622 100644 --- a/arch/arm/dts/exynos4.dtsi +++ b/arch/arm/dts/exynos4.dtsi @@ -51,56 +51,64 @@ #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <0 0 0>; + reg = <0x13860000 0x100>; + interrupts = <0 56 0>; };
i2c@13870000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <1 1 0>; + reg = <0x13870000 0x100>; + interrupts = <1 57 0>; };
i2c@13880000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <2 2 0>; + reg = <0x13880000 0x100>; + interrupts = <2 58 0>; };
i2c@13890000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <3 3 0>; + reg = <0x13890000 0x100>; + interrupts = <3 59 0>; };
i2c@138a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <4 4 0>; + reg = <0x138a0000 0x100>; + interrupts = <4 60 0>; };
i2c@138b0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <5 5 0>; + reg = <0x138b0000 0x100>; + interrupts = <5 61 0>; };
i2c@138c0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <6 6 0>; + reg = <0x138c0000 0x100>; + interrupts = <6 62 0>; };
i2c@138d0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <7 7 0>; + reg = <0x138d0000 0x100>; + interrupts = <7 63 0>; };
sdhci@12510000 {

On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch modify i2c nodes in exynos4.dtsi with:
- adding proper interrupts arrays for each i2c node, which allows to decode periph id
- add reg address for each i2c node for i2c driver internal use
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com
arch/arm/dts/exynos4.dtsi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
Acked-by: Simon Glass sjg@chromium.org

Without this alias setting, the seq numbers of the i2c devices are wrong.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- arch/arm/dts/exynos5250-arndale.dts | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/dts/exynos5250-arndale.dts b/arch/arm/dts/exynos5250-arndale.dts index 202f2ea..21c0a21 100644 --- a/arch/arm/dts/exynos5250-arndale.dts +++ b/arch/arm/dts/exynos5250-arndale.dts @@ -15,6 +15,14 @@ compatible = "samsung,arndale", "samsung,exynos5250";
aliases { + i2c0 = "/i2c@12c60000"; + i2c1 = "/i2c@12c70000"; + i2c2 = "/i2c@12c80000"; + i2c3 = "/i2c@12c90000"; + i2c4 = "/i2c@12ca0000"; + i2c5 = "/i2c@12cb0000"; + i2c6 = "/i2c@12cc0000"; + i2c7 = "/i2c@12cd0000"; serial0 = "/serial@12C20000"; console = "/serial@12C20000"; };

On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
Without this alias setting, the seq numbers of the i2c devices are wrong.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
arch/arm/dts/exynos5250-arndale.dts | 8 ++++++++ 1 file changed, 8 insertions(+)
This might be fixed now, but still I think aliases are a good idea.
Acked-by: Simon Glass sjg@chromium.org

Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 94d0297..b2c5494 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -266,22 +266,33 @@ static void exynos5_sromc_config(int flags)
static void exynos5_i2c_config(int peripheral, int flags) { + int func01, func23; + + /* flags only for High-Speed I2C */ + if (flags) { + func01 = 4; + func23 = 4; + } else { + func01 = 2; + func23 = 3; + } + switch (peripheral) { case PERIPH_ID_I2C0: - gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C1: - gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C2: - gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C3: - gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C4: gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3));

Hi Przemyslaw,
On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
As mentioned in the other flag you should add a flag for high speed so that it is explicit. See pinmux.h for what other devices do.
Regards, Simon

This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2 and Arndale (also with HS).
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com --- drivers/i2c/s3c24x0_i2c.c | 254 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 222 insertions(+), 32 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..c21d479 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@ * as they seem to have the same I2C controller inside. * The different address mapping is handled by the s3c24xx.h files below. */ - #include <common.h> +#include <errno.h> +#include <dm.h> #include <fdtdec.h> #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> @@ -121,13 +122,23 @@ #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 * @@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
+#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -398,18 +412,20 @@ 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);
- /* By default i2c channel 0 is the current bus */ 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 @@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ + i2c_ch_init(i2c, speed, slaveadd);
- bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c; } +#endif /* CONFIG_SYS_I2C */
/* * Poll the appropriate bit of the fifo status register until the interface is @@ -545,7 +562,6 @@ static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c, bool issue_stop) { u32 conf; - conf = len | HSI2C_MASTER_RUN;
if (issue_stop) @@ -698,14 +714,24 @@ 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) + unsigned int speed) +#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus; - +#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else + if (!dev) + return -ENODEV; + + i2c_bus = dev_get_priv(dev); +#endif if (!i2c_bus) - return -1; + return -ENODEV;
i2c_bus->clock_frequency = speed;
@@ -715,23 +741,12 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, - CONFIG_SYS_I2C_S3C24X0_SLAVE); + CONFIG_SYS_I2C_S3C24X0_SLAVE); }
return 0; }
-#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{ - /* This will override the speed selected in the fdt for that port */ - debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); - if (i2c_set_bus_speed(speed)) - printf("i2c_init: failed to init bus %d for speed = %d\n", - adap->hwadapnr, speed); -} -#endif - /* * cmd_type is 0 for write, 1 for read. * @@ -844,15 +859,24 @@ 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; uchar buf[1]; int ret;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else + i2c_bus = dev_get_priv(dev); +#endif if (!i2c_bus) - return -1; + return -ENODEV; + buf[0] = 0;
/* @@ -871,6 +895,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) 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) { @@ -878,6 +903,10 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret;
+ i2c_bus = get_bus(adap->hwadapnr); + if (!i2c_bus) + return -1; + if (alen > 4) { debug("I2C read: addr len %d not supported\n", alen); return 1; @@ -906,10 +935,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len); @@ -933,6 +958,10 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret;
+ i2c_bus = get_bus(adap->hwadapnr); + if (!i2c_bus) + return -1; + if (alen > 4) { debug("I2C write: addr len %d not supported\n", alen); return 1; @@ -960,10 +989,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true); @@ -1010,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i; - exynos_pinmux_config(bus->id, 0); + exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, 0);
/* Mark position as used */ node_list[i] = -1; @@ -1033,7 +1058,6 @@ void board_i2c_init(const void *blob) 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) @@ -1077,7 +1101,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
return 0; } -#endif +#endif /* CONFIG_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 @@ -1247,3 +1281,159 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */ + +#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len, bool end_with_repeated_start) +{ + int ret; + + if (!i2c_bus) + return -1; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0, + buffer, len, true); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len) +{ + int ret; + + if (!i2c_bus) + return -1; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_READ, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct s3c24x0_i2c_bus *i2c_bus; + int ret; + + if (!dev) + return -ENODEV; + + i2c_bus = dev_get_priv(dev); + + if (!i2c_bus) + return -1; + + for (; nmsgs > 0; nmsgs--, msg++) { + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); + + if (msg->flags & I2C_M_RD) { + ret = i2c_read_data(i2c_bus, msg->addr, msg->buf, + msg->len); + } else { + ret = i2c_write_data(i2c_bus, msg->addr, msg->buf, + msg->len, next_is_read); + } + if (ret) + return -EREMOTEIO; + } + + return 0; +} + +static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + struct s3c24x0_i2c_bus *i2c_bus; + int node; + + if (!dev) { + error("%s: no such device!", dev->name); + return -ENODEV; + } + + i2c_bus = dev_get_priv(dev); + if (!i2c_bus) { + error("%s: i2c bus not allocated!", dev->name); + return -EINVAL; + } + + if (!dev->of_id) { + error("%s: no compat ids!", dev->name); + return -EINVAL; + } + i2c_bus->is_highspeed = dev->of_id->data; + + node = dev->of_offset; + + if (i2c_bus->is_highspeed) { + i2c_bus->hsregs = (struct exynos5_hsi2c *) + fdtdec_get_addr(blob, node, "reg"); + } else { + i2c_bus->regs = (struct s3c24x0_i2c *) + fdtdec_get_addr(blob, node, "reg"); + } + + i2c_bus->id = pinmux_decode_periph_id(blob, node); + + i2c_bus->clock_frequency = fdtdec_get_int(blob, node, + "clock-frequency", + CONFIG_SYS_I2C_S3C24X0_SPEED); + i2c_bus->node = node; + i2c_bus->bus_num = dev->seq; + + exynos_pinmux_config(i2c_bus->id, i2c_bus->is_highspeed); + + i2c_bus->active = true; + + return 0; +} + +static int s3c_i2c_child_pre_probe(struct udevice *dev) +{ + struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); + + if (dev->of_offset == -1) + return 0; + return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, + i2c_chip); +} + +static const struct dm_i2c_ops s3c_i2c_ops = { + .xfer = s3c24x0_i2c_xfer, + .probe_chip = s3c24x0_i2c_probe, + .set_bus_speed = s3c24x0_i2c_set_bus_speed, +}; + +static const struct udevice_id s3c_i2c_ids[] = { + { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD }, + { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS }, + { } +}; + +U_BOOT_DRIVER(i2c_s3c) = { + .name = "i2c_s3c", + .id = UCLASS_I2C, + .of_match = s3c_i2c_ids, + .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .child_pre_probe = s3c_i2c_child_pre_probe, + .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), + .ops = &s3c_i2c_ops, +}; +#endif /* CONFIG_DM_I2C */

Hello Przemyslaw Marczak,
just some nitpick ...
Am 08.01.2015 12:33, schrieb Przemyslaw Marczak:
This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2 and Arndale (also with HS).
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
drivers/i2c/s3c24x0_i2c.c | 254 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 222 insertions(+), 32 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..c21d479 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@
- as they seem to have the same I2C controller inside.
- The different address mapping is handled by the s3c24xx.h files below.
*/
- #include <common.h>
+#include <errno.h> +#include <dm.h> #include <fdtdec.h> #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> @@ -121,13 +122,23 @@ #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
@@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
+#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -398,18 +412,20 @@ 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);
/* By default i2c channel 0 is the current bus */ 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
@@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
- i2c_ch_init(i2c, speed, slaveadd);
- bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c; }
+#endif /* CONFIG_SYS_I2C */
/*
- Poll the appropriate bit of the fifo status register until the interface is
@@ -545,7 +562,6 @@ static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c, bool issue_stop) { u32 conf;
why do you delete this empty line?
conf = len | HSI2C_MASTER_RUN;
if (issue_stop) @@ -698,14 +714,24 @@ 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)
unsigned int speed)
+#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus;
here too ...
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else
- if (!dev)
return -ENODEV;
- i2c_bus = dev_get_priv(dev);
+#endif if (!i2c_bus)
return -1;
return -ENODEV;
i2c_bus->clock_frequency = speed;
@@ -715,23 +741,12 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_S3C24X0_SLAVE);
CONFIG_SYS_I2C_S3C24X0_SLAVE);
}
return 0; }
-#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{
- /* This will override the speed selected in the fdt for that port */
- debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
- if (i2c_set_bus_speed(speed))
printf("i2c_init: failed to init bus %d for speed = %d\n",
adap->hwadapnr, speed);
-} -#endif
- /*
- cmd_type is 0 for write, 1 for read.
@@ -844,15 +859,24 @@ 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; uchar buf[1]; int ret;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else
- i2c_bus = dev_get_priv(dev);
+#endif if (!i2c_bus)
return -1;
return -ENODEV;
buf[0] = 0;
/*
@@ -871,6 +895,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) 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) { @@ -878,6 +903,10 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret;
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
above you change "return -1" to "return -ENODEV" ... Shouldn;t we use here also an errno? Suggestion -EFAULT?
- if (alen > 4) { debug("I2C read: addr len %d not supported\n", alen); return 1;
@@ -906,10 +935,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
- if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len);
@@ -933,6 +958,10 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret;
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
here too ...
- if (alen > 4) { debug("I2C write: addr len %d not supported\n", alen); return 1;
@@ -960,10 +989,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
- if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true);
@@ -1010,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i;
exynos_pinmux_config(bus->id, 0);
exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, 0);
/* Mark position as used */ node_list[i] = -1;
@@ -1033,7 +1058,6 @@ void board_i2c_init(const void *blob) 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)
@@ -1077,7 +1101,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
return 0; } -#endif +#endif /* CONFIG_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
@@ -1247,3 +1281,159 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */
+#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
uchar *buffer, int len, bool end_with_repeated_start)
+{
- int ret;
- if (!i2c_bus)
return -1;
and here
- if (i2c_bus->is_highspeed) {
ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0,
buffer, len, true);
if (ret)
exynos5_i2c_reset(i2c_bus);
- } else {
ret = i2c_transfer(i2c_bus->regs, I2C_WRITE,
chip << 1, 0, 0, buffer, len);
- }
- return ret != I2C_OK;
+}
+static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
uchar *buffer, int len)
+{
- int ret;
- if (!i2c_bus)
return -1;
and here
- if (i2c_bus->is_highspeed) {
ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len);
if (ret)
exynos5_i2c_reset(i2c_bus);
- } else {
ret = i2c_transfer(i2c_bus->regs, I2C_READ,
chip << 1, 0, 0, buffer, len);
- }
- return ret != I2C_OK;
+}
+static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
int nmsgs)
+{
- struct s3c24x0_i2c_bus *i2c_bus;
- int ret;
- if (!dev)
return -ENODEV;
- i2c_bus = dev_get_priv(dev);
- if (!i2c_bus)
return -1;
and here...
- for (; nmsgs > 0; nmsgs--, msg++) {
bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
if (msg->flags & I2C_M_RD) {
ret = i2c_read_data(i2c_bus, msg->addr, msg->buf,
msg->len);
} else {
ret = i2c_write_data(i2c_bus, msg->addr, msg->buf,
msg->len, next_is_read);
}
if (ret)
return -EREMOTEIO;
- }
- return 0;
+}
+static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{
- const void *blob = gd->fdt_blob;
- struct s3c24x0_i2c_bus *i2c_bus;
- int node;
- if (!dev) {
error("%s: no such device!", dev->name);
return -ENODEV;
- }
- i2c_bus = dev_get_priv(dev);
- if (!i2c_bus) {
error("%s: i2c bus not allocated!", dev->name);
return -EINVAL;
ah, here if no bus is found you return -EINVAL ... as EINVAL is used below again, I prefer to use another errno here ... as suggested EFAULT or maybe ENOENT? ... but please for all occurrences of "if (!i2c_bus) {" the same value, thanks!
- }
- if (!dev->of_id) {
error("%s: no compat ids!", dev->name);
return -EINVAL;
- }
- i2c_bus->is_highspeed = dev->of_id->data;
- node = dev->of_offset;
- if (i2c_bus->is_highspeed) {
i2c_bus->hsregs = (struct exynos5_hsi2c *)
fdtdec_get_addr(blob, node, "reg");
- } else {
i2c_bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
- }
- i2c_bus->id = pinmux_decode_periph_id(blob, node);
- i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
"clock-frequency",
CONFIG_SYS_I2C_S3C24X0_SPEED);
- i2c_bus->node = node;
- i2c_bus->bus_num = dev->seq;
- exynos_pinmux_config(i2c_bus->id, i2c_bus->is_highspeed);
- i2c_bus->active = true;
- return 0;
+}
+static int s3c_i2c_child_pre_probe(struct udevice *dev) +{
- struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
- if (dev->of_offset == -1)
return 0;
- return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
i2c_chip);
+}
+static const struct dm_i2c_ops s3c_i2c_ops = {
- .xfer = s3c24x0_i2c_xfer,
- .probe_chip = s3c24x0_i2c_probe,
- .set_bus_speed = s3c24x0_i2c_set_bus_speed,
+};
+static const struct udevice_id s3c_i2c_ids[] = {
- { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD },
- { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS },
- { }
+};
+U_BOOT_DRIVER(i2c_s3c) = {
- .name = "i2c_s3c",
- .id = UCLASS_I2C,
- .of_match = s3c_i2c_ids,
- .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
- .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
- .child_pre_probe = s3c_i2c_child_pre_probe,
- .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
- .ops = &s3c_i2c_ops,
+}; +#endif /* CONFIG_DM_I2C */
Thanks for your work!
bye, Heiko

Hello Heiko Schocher,
On 01/09/2015 07:31 AM, Heiko Schocher wrote:
Hello Przemyslaw Marczak,
just some nitpick ...
Am 08.01.2015 12:33, schrieb Przemyslaw Marczak:
This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2 and Arndale (also with HS).
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
drivers/i2c/s3c24x0_i2c.c | 254 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 222 insertions(+), 32 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..c21d479 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@
- as they seem to have the same I2C controller inside.
- The different address mapping is handled by the s3c24xx.h files
below. */
- #include <common.h>
+#include <errno.h> +#include <dm.h> #include <fdtdec.h> #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> @@ -121,13 +122,23 @@ #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
@@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
+#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -398,18 +412,20 @@ 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);
/* By default i2c channel 0 is the current bus */ 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
@@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
i2c_ch_init(i2c, speed, slaveadd);
- bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c; }
+#endif /* CONFIG_SYS_I2C */
/*
- Poll the appropriate bit of the fifo status register until the
interface is @@ -545,7 +562,6 @@ static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c, bool issue_stop) { u32 conf;
why do you delete this empty line?
conf = len | HSI2C_MASTER_RUN; if (issue_stop)
@@ -698,14 +714,24 @@ 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)
unsigned int speed)
+#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus;
here too ...
Oh, I missed this after removing the debug code. Will fix in both cases.
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else
- if (!dev)
return -ENODEV;
- i2c_bus = dev_get_priv(dev);
+#endif if (!i2c_bus)
return -1;
return -ENODEV; i2c_bus->clock_frequency = speed;
@@ -715,23 +741,12 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_S3C24X0_SLAVE);
CONFIG_SYS_I2C_S3C24X0_SLAVE); } return 0;
}
-#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{
- /* This will override the speed selected in the fdt for that port */
- debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
- if (i2c_set_bus_speed(speed))
printf("i2c_init: failed to init bus %d for speed = %d\n",
adap->hwadapnr, speed);
-} -#endif
- /*
- cmd_type is 0 for write, 1 for read.
@@ -844,15 +859,24 @@ 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; uchar buf[1]; int ret;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else
- i2c_bus = dev_get_priv(dev);
+#endif if (!i2c_bus)
return -1;
return -ENODEV;
buf[0] = 0; /*
@@ -871,6 +895,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) 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) { @@ -878,6 +903,10 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret;
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
above you change "return -1" to "return -ENODEV" ... Shouldn;t we use here also an errno? Suggestion -EFAULT?
Yes, you are right, I will fix this issue globally.
if (alen > 4) { debug("I2C read: addr len %d not supported\n", alen); return 1;
@@ -906,10 +935,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len);
@@ -933,6 +958,10 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret;
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
here too ...
if (alen > 4) { debug("I2C write: addr len %d not supported\n", alen); return 1;
@@ -960,10 +989,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif
- i2c_bus = get_bus(adap->hwadapnr);
- if (!i2c_bus)
return -1;
if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true);
@@ -1010,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i;
exynos_pinmux_config(bus->id, 0);
exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, 0); /* Mark position as used */ node_list[i] = -1;
@@ -1033,7 +1058,6 @@ void board_i2c_init(const void *blob) 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)
@@ -1077,7 +1101,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
return 0;
} -#endif +#endif /* CONFIG_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
@@ -1247,3 +1281,159 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */
+#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
uchar *buffer, int len, bool end_with_repeated_start)
+{
- int ret;
- if (!i2c_bus)
return -1;
and here
- if (i2c_bus->is_highspeed) {
ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0,
buffer, len, true);
if (ret)
exynos5_i2c_reset(i2c_bus);
- } else {
ret = i2c_transfer(i2c_bus->regs, I2C_WRITE,
chip << 1, 0, 0, buffer, len);
- }
- return ret != I2C_OK;
+}
+static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
uchar *buffer, int len)
+{
- int ret;
- if (!i2c_bus)
return -1;
and here
- if (i2c_bus->is_highspeed) {
ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len);
if (ret)
exynos5_i2c_reset(i2c_bus);
- } else {
ret = i2c_transfer(i2c_bus->regs, I2C_READ,
chip << 1, 0, 0, buffer, len);
- }
- return ret != I2C_OK;
+}
+static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
int nmsgs)
+{
- struct s3c24x0_i2c_bus *i2c_bus;
- int ret;
- if (!dev)
return -ENODEV;
- i2c_bus = dev_get_priv(dev);
- if (!i2c_bus)
return -1;
and here...
- for (; nmsgs > 0; nmsgs--, msg++) {
bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
if (msg->flags & I2C_M_RD) {
ret = i2c_read_data(i2c_bus, msg->addr, msg->buf,
msg->len);
} else {
ret = i2c_write_data(i2c_bus, msg->addr, msg->buf,
msg->len, next_is_read);
}
if (ret)
return -EREMOTEIO;
- }
- return 0;
+}
+static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{
- const void *blob = gd->fdt_blob;
- struct s3c24x0_i2c_bus *i2c_bus;
- int node;
- if (!dev) {
error("%s: no such device!", dev->name);
return -ENODEV;
- }
- i2c_bus = dev_get_priv(dev);
- if (!i2c_bus) {
error("%s: i2c bus not allocated!", dev->name);
return -EINVAL;
ah, here if no bus is found you return -EINVAL ... as EINVAL is used below again, I prefer to use another errno here ... as suggested EFAULT or maybe ENOENT? ... but please for all occurrences of "if (!i2c_bus) {" the same value, thanks!
Right, this was not good.
- }
- if (!dev->of_id) {
error("%s: no compat ids!", dev->name);
return -EINVAL;
- }
- i2c_bus->is_highspeed = dev->of_id->data;
- node = dev->of_offset;
- if (i2c_bus->is_highspeed) {
i2c_bus->hsregs = (struct exynos5_hsi2c *)
fdtdec_get_addr(blob, node, "reg");
- } else {
i2c_bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
- }
- i2c_bus->id = pinmux_decode_periph_id(blob, node);
- i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
"clock-frequency",
CONFIG_SYS_I2C_S3C24X0_SPEED);
- i2c_bus->node = node;
- i2c_bus->bus_num = dev->seq;
- exynos_pinmux_config(i2c_bus->id, i2c_bus->is_highspeed);
- i2c_bus->active = true;
- return 0;
+}
+static int s3c_i2c_child_pre_probe(struct udevice *dev) +{
- struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
- if (dev->of_offset == -1)
return 0;
- return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
i2c_chip);
+}
+static const struct dm_i2c_ops s3c_i2c_ops = {
- .xfer = s3c24x0_i2c_xfer,
- .probe_chip = s3c24x0_i2c_probe,
- .set_bus_speed = s3c24x0_i2c_set_bus_speed,
+};
+static const struct udevice_id s3c_i2c_ids[] = {
- { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD },
- { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS },
- { }
+};
+U_BOOT_DRIVER(i2c_s3c) = {
- .name = "i2c_s3c",
- .id = UCLASS_I2C,
- .of_match = s3c_i2c_ids,
- .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
- .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
- .child_pre_probe = s3c_i2c_child_pre_probe,
- .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
- .ops = &s3c_i2c_ops,
+}; +#endif /* CONFIG_DM_I2C */
Thanks for your work!
bye, Heiko
Thank you for the review, I will fix this in the next patchset version. Best regards,

Hi Przemyslaw,
On 9 January 2015 at 01:57, Przemyslaw Marczak p.marczak@samsung.com wrote:
Hello Heiko Schocher,
On 01/09/2015 07:31 AM, Heiko Schocher wrote:
Hello Przemyslaw Marczak,
just some nitpick ...
[snip]
Thank you for the review, I will fix this in the next patchset version.
I'd like to apply this to u-boot-dm soon - can you please resend this patch with the nits fixed? I don't have any comments beyond what Heiko says.
Also, you probably saw the compatibility layer for I2C which should make it possible for you to run the old PMIC framework with I2C using driver model. It should make it easier to get everything done. It is in u-boot-dm/testing.
Regards, Simon

Hello Simon,
On 01/20/2015 04:18 AM, Simon Glass wrote:
Hi Przemyslaw,
On 9 January 2015 at 01:57, Przemyslaw Marczak p.marczak@samsung.com wrote:
Hello Heiko Schocher,
On 01/09/2015 07:31 AM, Heiko Schocher wrote:
Hello Przemyslaw Marczak,
just some nitpick ...
[snip]
Thank you for the review, I will fix this in the next patchset version.
I'd like to apply this to u-boot-dm soon - can you please resend this patch with the nits fixed? I don't have any comments beyond what Heiko says.
Also, you probably saw the compatibility layer for I2C which should make it possible for you to run the old PMIC framework with I2C using driver model. It should make it easier to get everything done. It is in u-boot-dm/testing.
Regards, Simon
I will check this and send the second patch version probably on Monday.
Best regards,

This commit allows for test i2c drivers with new i2c api on Exynos5xxx based boards.
The S3C24X0 I2C driver supports driver model I2C api, but i2c peripherials drivers on exynos5 boards doesn't. So this commit allows for test ported driver before switch the Exynos5 boards to DM I2C at all.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/exynos5-common.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c..b7af8a5 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -54,13 +54,6 @@ #define CONFIG_CMD_DTT #define CONFIG_TMU_CMD_DTT
-/* TPM */ -#define CONFIG_TPM -#define CONFIG_CMD_TPM -#define CONFIG_TPM_TIS_I2C -#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 -#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20 - /* MMC SPL */ #define COPY_BL2_FNPTR_ADDR 0x02020030 #define CONFIG_SUPPORT_EMMC_BOOT @@ -126,15 +119,29 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C_INIT_BOARD +#define CONFIG_SYS_I2C +#define CONFIG_I2C_MULTI_BUS +#endif /* ifndef CONFIG_DM_I2C */ #define CONFIG_I2C_EDID
+/* TPM */ +#ifndef CONFIG_DM_I2C +#define CONFIG_TPM +#define CONFIG_CMD_TPM +#define CONFIG_TPM_TIS_I2C +#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 +#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20 +#endif + /* SPI */ #ifdef CONFIG_SPI_FLASH #define CONFIG_EXYNOS_SPI

Hi,
On 08/01/15 20:33, Przemyslaw Marczak wrote:
This commit allows for test i2c drivers with new i2c api on Exynos5xxx based boards.
The S3C24X0 I2C driver supports driver model I2C api, but i2c peripherials drivers on exynos5 boards doesn't. So this commit allows for test ported driver before switch the Exynos5 boards to DM I2C at all.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/exynos5-common.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c..b7af8a5 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -54,13 +54,6 @@ #define CONFIG_CMD_DTT #define CONFIG_TMU_CMD_DTT
-/* TPM */ -#define CONFIG_TPM -#define CONFIG_CMD_TPM -#define CONFIG_TPM_TIS_I2C -#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 -#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20
/* MMC SPL */ #define COPY_BL2_FNPTR_ADDR 0x02020030 #define CONFIG_SUPPORT_EMMC_BOOT @@ -126,15 +119,29 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif
please remove test code
#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C_INIT_BOARD +#define CONFIG_SYS_I2C +#define CONFIG_I2C_MULTI_BUS +#endif /* ifndef CONFIG_DM_I2C */ #define CONFIG_I2C_EDID
+/* TPM */ +#ifndef CONFIG_DM_I2C +#define CONFIG_TPM +#define CONFIG_CMD_TPM +#define CONFIG_TPM_TIS_I2C +#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 +#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20 +#endif
/* SPI */ #ifdef CONFIG_SPI_FLASH #define CONFIG_EXYNOS_SPI
Thanks, Minkyu Kang.

Hello Przemyslaw Marczak,
Am 08.01.2015 12:33, schrieb Przemyslaw Marczak:
This commit allows for test i2c drivers with new i2c api on Exynos5xxx based boards.
The S3C24X0 I2C driver supports driver model I2C api, but i2c peripherials drivers on exynos5 boards doesn't. So this commit allows for test ported driver before switch the Exynos5 boards to DM I2C at all.
Hmm... so this is just a patch for test purposes not for mainline?
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/exynos5-common.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c..b7af8a5 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -54,13 +54,6 @@ #define CONFIG_CMD_DTT #define CONFIG_TMU_CMD_DTT
-/* TPM */ -#define CONFIG_TPM -#define CONFIG_CMD_TPM -#define CONFIG_TPM_TIS_I2C -#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 -#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20
- /* MMC SPL */ #define COPY_BL2_FNPTR_ADDR 0x02020030 #define CONFIG_SUPPORT_EMMC_BOOT
@@ -126,15 +119,29 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif
Hmm.. no, please no dead code in mainline ... maybe you enable "CONFIG_DM_I2C" if "CONFIG_DM" is set?
bye, Heiko
#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C_INIT_BOARD +#define CONFIG_SYS_I2C +#define CONFIG_I2C_MULTI_BUS +#endif /* ifndef CONFIG_DM_I2C */ #define CONFIG_I2C_EDID
+/* TPM */ +#ifndef CONFIG_DM_I2C +#define CONFIG_TPM +#define CONFIG_CMD_TPM +#define CONFIG_TPM_TIS_I2C +#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 +#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20 +#endif
- /* SPI */ #ifdef CONFIG_SPI_FLASH #define CONFIG_EXYNOS_SPI

Hello Heiko Schocher,
Sorry, I missed this message this morning.
On 01/09/2015 07:37 AM, Heiko Schocher wrote:
Hello Przemyslaw Marczak,
Am 08.01.2015 12:33, schrieb Przemyslaw Marczak:
This commit allows for test i2c drivers with new i2c api on Exynos5xxx based boards.
The S3C24X0 I2C driver supports driver model I2C api, but i2c peripherials drivers on exynos5 boards doesn't. So this commit allows for test ported driver before switch the Exynos5 boards to DM I2C at all.
Hmm... so this is just a patch for test purposes not for mainline?
This patch is for the mainline, but I left the "if 0" just for the developers, who want to port the required i2c drivers. I will remove the "if 0". There are some i2c drivers for Exynos based boards, which should be ported to the new i2c api.
At present I'm not able to do this at once and as I know someone needs the i2c driver for the present work. I required the i2c bus driver for the pmic framework, on which now I'm working.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/exynos5-common.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c..b7af8a5 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -54,13 +54,6 @@ #define CONFIG_CMD_DTT #define CONFIG_TMU_CMD_DTT
-/* TPM */ -#define CONFIG_TPM -#define CONFIG_CMD_TPM -#define CONFIG_TPM_TIS_I2C -#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 -#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20
- /* MMC SPL */ #define COPY_BL2_FNPTR_ADDR 0x02020030 #define CONFIG_SUPPORT_EMMC_BOOT
@@ -126,15 +119,29 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif
Hmm.. no, please no dead code in mainline ... maybe you enable "CONFIG_DM_I2C" if "CONFIG_DM" is set?
bye, Heiko
Yes, will be removed. I can't use the CONFIG_DM because of the rest of the i2c drivers, which are waiting for the adjust to new i2c api.
#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C_INIT_BOARD +#define CONFIG_SYS_I2C +#define CONFIG_I2C_MULTI_BUS +#endif /* ifndef CONFIG_DM_I2C */ #define CONFIG_I2C_EDID
+/* TPM */ +#ifndef CONFIG_DM_I2C +#define CONFIG_TPM +#define CONFIG_CMD_TPM +#define CONFIG_TPM_TIS_I2C +#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3 +#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20 +#endif
- /* SPI */ #ifdef CONFIG_SPI_FLASH #define CONFIG_EXYNOS_SPI
Also I'm not going to move the current pmic framework/drivers to the new i2c api, since I hope to send the new framework soon.
Thank you and best regards,

This commit disables sound support for testing new i2c api for Exynos5250 boards. After move i2c part of sound drivers to the new i2c api, then this ifdef will be removed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/exynos5250-common.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index ae0e5ff..a6a766a 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -29,7 +29,9 @@ #define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
/* Sound */ +#ifndef CONFIG_DM_I2C #define CONFIG_CMD_SOUND +#endif #ifdef CONFIG_CMD_SOUND #define CONFIG_SOUND #define CONFIG_I2S_SAMSUNG

This commit disables pmic support for testing dm i2c api on arndale. There is no sense for move the current pmic framework to new i2c api, since the new power framework will be ready soon.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/arndale.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 3ad4a9b..b3d3868 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -49,9 +49,10 @@ #define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
/* PMIC */ +#ifndef CONFIG_DM_I2C #define CONFIG_PMIC #define CONFIG_POWER_I2C - +#endif #define CONFIG_PREBOOT
#define CONFIG_S5P_PA_SYSRAM 0x02020000

Disable pmic if CONFIG_DM_I2C in exynos5-common.h is enabled.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/exynos5-dt-common.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index 9cef0b0..a774a41 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -19,9 +19,11 @@ #include "exynos5-common.h"
/* PMIC */ +#ifndef CONFIG_DM_I2C #define CONFIG_POWER #define CONFIG_POWER_I2C #define CONFIG_POWER_TPS65090 +#endif
/* Enable keyboard */ #define CONFIG_CROS_EC /* CROS_EC protocol */

Disable cros ec i2c driver if CONFIG_DM_I2C in exynos5-common.h is enabled.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/snow.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/configs/snow.h b/include/configs/snow.h index 7eaa586..b42766d 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -19,10 +19,10 @@ #include <configs/exynos5250-common.h> #include <configs/exynos5-dt-common.h>
- +#ifndef CONFIG_DM_I2C #define CONFIG_CROS_EC_I2C /* Support CROS_EC over I2C */ #define CONFIG_POWER_TPS65090_I2C - +#endif #define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R

Disable pmic if CONFIG_DM_I2C in exynos5-common.h is enabled.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 3b06d30..f57e94a 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -19,7 +19,9 @@ #include <configs/exynos5250-common.h>
/* PMIC */ +#ifndef CONFIG_DM_I2C #define CONFIG_POWER_MAX77686 +#endif
#define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R

If pmic is disabled for testing dm i2c then some unused variable should be moved around proper ifdef in smdk5420.c
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- board/samsung/smdk5420/smdk5420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/samsung/smdk5420/smdk5420.c b/board/samsung/smdk5420/smdk5420.c index 1aca9fa..5738fd3 100644 --- a/board/samsung/smdk5420/smdk5420.c +++ b/board/samsung/smdk5420/smdk5420.c @@ -44,9 +44,9 @@ static int has_edp_bridge(void)
void exynos_lcd_power_on(void) { +#ifdef CONFIG_POWER_TPS65090 int ret;
-#ifdef CONFIG_POWER_TPS65090 ret = tps65090_init(); if (ret < 0) { printf("%s: tps65090_init() failed\n", __func__);

Disable video parade driver if CONFIG_DM_I2C in exynos5-common.h is enabled.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/peach-pi.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h index a1c980d..7515e96 100644 --- a/include/configs/peach-pi.h +++ b/include/configs/peach-pi.h @@ -32,7 +32,9 @@ #define CONFIG_SYS_PROMPT "Peach-Pi # " #define CONFIG_IDENT_STRING " for Peach-Pi"
+#ifndef CONFIG_DM_I2C #define CONFIG_VIDEO_PARADE +#endif
/* Display */ #define CONFIG_LCD

Disable video parade driver if CONFIG_DM_I2C in exynos5-common.h is enabled.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/peach-pit.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index 6516a72..d0c40d3 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -32,7 +32,9 @@ #define CONFIG_SYS_PROMPT "Peach-Pit # " #define CONFIG_IDENT_STRING " for Peach-Pit"
+#ifndef CONFIG_DM_I2C #define CONFIG_VIDEO_PARADE +#endif
/* Display */ #define CONFIG_LCD

This patch makes cleanup in: - proper ifdefs to the power related functions - check for pmic null pointers before use
And is a preparation for enabling dm i2c support.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- board/samsung/trats2/trats2.c | 144 ++++++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 62 deletions(-)
diff --git a/board/samsung/trats2/trats2.c b/board/samsung/trats2/trats2.c index a737749..caa885d 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 = @@ -174,6 +172,63 @@ int exynos_init(void) return 0; }
+#ifdef CONFIG_POWER +static int pmic_init_max77686(void) +{ + struct pmic *p; + + p = pmic_get("MAX77686_PMIC"); + if (!p) + return -ENODEV; + + if (pmic_probe(p)) + return -1; + + /* BUCK/LDO Output Voltage */ + max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 VTF_2.8V */ + max77686_set_ldo_voltage(p, 23, 3300000); /* LDO23 TSP_AVDD_3.3V*/ + max77686_set_ldo_voltage(p, 24, 1800000); /* LDO24 TSP_VDD_1.8V */ + + /* BUCK/LDO Output Mode */ + max77686_set_buck_mode(p, 1, OPMODE_STANDBY); /* BUCK1 VMIF_1.1V_AP */ + max77686_set_buck_mode(p, 2, OPMODE_ON); /* BUCK2 VARM_1.0V_AP */ + max77686_set_buck_mode(p, 3, OPMODE_ON); /* BUCK3 VINT_1.0V_AP */ + max77686_set_buck_mode(p, 4, OPMODE_ON); /* BUCK4 VG3D_1.0V_AP */ + max77686_set_buck_mode(p, 5, OPMODE_ON); /* BUCK5 VMEM_1.2V_AP */ + max77686_set_buck_mode(p, 6, OPMODE_ON); /* BUCK6 VCC_SUB_1.35V*/ + max77686_set_buck_mode(p, 7, OPMODE_ON); /* BUCK7 VCC_SUB_2.0V */ + max77686_set_buck_mode(p, 8, OPMODE_OFF); /* VMEM_VDDF_2.85V */ + max77686_set_buck_mode(p, 9, OPMODE_OFF); /* CAM_ISP_CORE_1.2V*/ + + max77686_set_ldo_mode(p, 1, OPMODE_LPM); /* LDO1 VALIVE_1.0V_AP*/ + max77686_set_ldo_mode(p, 2, OPMODE_STANDBY); /* LDO2 VM1M2_1.2V_AP */ + max77686_set_ldo_mode(p, 3, OPMODE_LPM); /* LDO3 VCC_1.8V_AP */ + max77686_set_ldo_mode(p, 4, OPMODE_LPM); /* LDO4 VCC_2.8V_AP */ + max77686_set_ldo_mode(p, 5, OPMODE_OFF); /* LDO5_VCC_1.8V_IO */ + max77686_set_ldo_mode(p, 6, OPMODE_STANDBY); /* LDO6 VMPLL_1.0V_AP */ + max77686_set_ldo_mode(p, 7, OPMODE_STANDBY); /* LDO7 VPLL_1.0V_AP */ + max77686_set_ldo_mode(p, 8, OPMODE_LPM); /* LDO8 VMIPI_1.0V_AP */ + max77686_set_ldo_mode(p, 9, OPMODE_OFF); /* CAM_ISP_MIPI_1.2*/ + max77686_set_ldo_mode(p, 10, OPMODE_LPM); /* LDO10 VMIPI_1.8V_AP*/ + max77686_set_ldo_mode(p, 11, OPMODE_STANDBY); /* LDO11 VABB1_1.8V_AP*/ + max77686_set_ldo_mode(p, 12, OPMODE_LPM); /* LDO12 VUOTG_3.0V_AP*/ + max77686_set_ldo_mode(p, 13, OPMODE_OFF); /* LDO13 VC2C_1.8V_AP */ + max77686_set_ldo_mode(p, 14, OPMODE_STANDBY); /* VABB02_1.8V_AP */ + max77686_set_ldo_mode(p, 15, OPMODE_STANDBY); /* LDO15 VHSIC_1.0V_AP*/ + max77686_set_ldo_mode(p, 16, OPMODE_STANDBY); /* LDO16 VHSIC_1.8V_AP*/ + max77686_set_ldo_mode(p, 17, OPMODE_OFF); /* CAM_SENSOR_CORE_1.2*/ + max77686_set_ldo_mode(p, 18, OPMODE_OFF); /* CAM_ISP_SEN_IO_1.8V*/ + max77686_set_ldo_mode(p, 19, OPMODE_OFF); /* LDO19 VT_CAM_1.8V */ + max77686_set_ldo_mode(p, 20, OPMODE_ON); /* LDO20 VDDQ_PRE_1.8V*/ + max77686_set_ldo_mode(p, 21, OPMODE_OFF); /* LDO21 VTF_2.8V */ + max77686_set_ldo_mode(p, 22, OPMODE_OFF); /* LDO22 VMEM_VDD_2.8V*/ + max77686_set_ldo_mode(p, 23, OPMODE_OFF); /* LDO23 TSP_AVDD_3.3V*/ + max77686_set_ldo_mode(p, 24, OPMODE_OFF); /* LDO24 TSP_VDD_1.8V */ + max77686_set_ldo_mode(p, 25, OPMODE_OFF); /* LDO25 VCC_3.3V_LCD */ + max77686_set_ldo_mode(p, 26, OPMODE_OFF); /*LDO26 VCC_3.0V_MOTOR*/ + return 0; +} + int exynos_power_init(void) { int chrg; @@ -239,10 +294,12 @@ int exynos_power_init(void)
return 0; } +#endif /* CONFIG_POWER */
#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control(int on) { +#ifdef CONFIG_POWER int ret = 0; unsigned int val; struct pmic *p, *p_pmic, *p_muic; @@ -299,7 +356,7 @@ static int s5pc210_phy_control(int on)
if (ret) return -1; - +#endif return 0; }
@@ -319,97 +376,60 @@ int board_usb_init(int index, enum usb_init_type init)
int g_dnl_board_usb_cable_connected(void) { - struct pmic *muic = pmic_get("MAX77693_MUIC"); +#ifdef CONFIG_POWER + struct pmic *muic; + + muic = pmic_get("MAX77693_MUIC"); if (!muic) return 0;
return !!muic->chrg->chrg_type(muic); -} -#endif - -static int pmic_init_max77686(void) -{ - struct pmic *p = pmic_get("MAX77686_PMIC"); - - if (pmic_probe(p)) - return -1; - - /* BUCK/LDO Output Voltage */ - max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 VTF_2.8V */ - max77686_set_ldo_voltage(p, 23, 3300000); /* LDO23 TSP_AVDD_3.3V*/ - max77686_set_ldo_voltage(p, 24, 1800000); /* LDO24 TSP_VDD_1.8V */ - - /* BUCK/LDO Output Mode */ - max77686_set_buck_mode(p, 1, OPMODE_STANDBY); /* BUCK1 VMIF_1.1V_AP */ - max77686_set_buck_mode(p, 2, OPMODE_ON); /* BUCK2 VARM_1.0V_AP */ - max77686_set_buck_mode(p, 3, OPMODE_ON); /* BUCK3 VINT_1.0V_AP */ - max77686_set_buck_mode(p, 4, OPMODE_ON); /* BUCK4 VG3D_1.0V_AP */ - max77686_set_buck_mode(p, 5, OPMODE_ON); /* BUCK5 VMEM_1.2V_AP */ - max77686_set_buck_mode(p, 6, OPMODE_ON); /* BUCK6 VCC_SUB_1.35V*/ - max77686_set_buck_mode(p, 7, OPMODE_ON); /* BUCK7 VCC_SUB_2.0V */ - max77686_set_buck_mode(p, 8, OPMODE_OFF); /* VMEM_VDDF_2.85V */ - max77686_set_buck_mode(p, 9, OPMODE_OFF); /* CAM_ISP_CORE_1.2V*/ - - max77686_set_ldo_mode(p, 1, OPMODE_LPM); /* LDO1 VALIVE_1.0V_AP*/ - max77686_set_ldo_mode(p, 2, OPMODE_STANDBY); /* LDO2 VM1M2_1.2V_AP */ - max77686_set_ldo_mode(p, 3, OPMODE_LPM); /* LDO3 VCC_1.8V_AP */ - max77686_set_ldo_mode(p, 4, OPMODE_LPM); /* LDO4 VCC_2.8V_AP */ - max77686_set_ldo_mode(p, 5, OPMODE_OFF); /* LDO5_VCC_1.8V_IO */ - max77686_set_ldo_mode(p, 6, OPMODE_STANDBY); /* LDO6 VMPLL_1.0V_AP */ - max77686_set_ldo_mode(p, 7, OPMODE_STANDBY); /* LDO7 VPLL_1.0V_AP */ - max77686_set_ldo_mode(p, 8, OPMODE_LPM); /* LDO8 VMIPI_1.0V_AP */ - max77686_set_ldo_mode(p, 9, OPMODE_OFF); /* CAM_ISP_MIPI_1.2*/ - max77686_set_ldo_mode(p, 10, OPMODE_LPM); /* LDO10 VMIPI_1.8V_AP*/ - max77686_set_ldo_mode(p, 11, OPMODE_STANDBY); /* LDO11 VABB1_1.8V_AP*/ - max77686_set_ldo_mode(p, 12, OPMODE_LPM); /* LDO12 VUOTG_3.0V_AP*/ - max77686_set_ldo_mode(p, 13, OPMODE_OFF); /* LDO13 VC2C_1.8V_AP */ - max77686_set_ldo_mode(p, 14, OPMODE_STANDBY); /* VABB02_1.8V_AP */ - max77686_set_ldo_mode(p, 15, OPMODE_STANDBY); /* LDO15 VHSIC_1.0V_AP*/ - max77686_set_ldo_mode(p, 16, OPMODE_STANDBY); /* LDO16 VHSIC_1.8V_AP*/ - max77686_set_ldo_mode(p, 17, OPMODE_OFF); /* CAM_SENSOR_CORE_1.2*/ - max77686_set_ldo_mode(p, 18, OPMODE_OFF); /* CAM_ISP_SEN_IO_1.8V*/ - max77686_set_ldo_mode(p, 19, OPMODE_OFF); /* LDO19 VT_CAM_1.8V */ - max77686_set_ldo_mode(p, 20, OPMODE_ON); /* LDO20 VDDQ_PRE_1.8V*/ - max77686_set_ldo_mode(p, 21, OPMODE_OFF); /* LDO21 VTF_2.8V */ - max77686_set_ldo_mode(p, 22, OPMODE_OFF); /* LDO22 VMEM_VDD_2.8V*/ - max77686_set_ldo_mode(p, 23, OPMODE_OFF); /* LDO23 TSP_AVDD_3.3V*/ - max77686_set_ldo_mode(p, 24, OPMODE_OFF); /* LDO24 TSP_VDD_1.8V */ - max77686_set_ldo_mode(p, 25, OPMODE_OFF); /* LDO25 VCC_3.3V_LCD */ - max77686_set_ldo_mode(p, 26, OPMODE_OFF); /*LDO26 VCC_3.0V_MOTOR*/ - +#else return 0; +#endif } +#endif
/* * LCD */ - #ifdef CONFIG_LCD int mipi_power(void) { - struct pmic *p = pmic_get("MAX77686_PMIC"); +#ifdef CONFIG_POWER + struct pmic *p; + + p = pmic_get("MAX77686_PMIC"); + if (!p) + return -ENODEV;
/* 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) { - struct pmic *p = pmic_get("MAX77686_PMIC"); - /* LCD_2.2V_EN: GPC0[1] */ gpio_request(EXYNOS4X12_GPIO_C01, "lcd_2v2_en"); gpio_set_pull(EXYNOS4X12_GPIO_C01, S5P_GPIO_PULL_UP); gpio_direction_output(EXYNOS4X12_GPIO_C01, 1);
+#ifdef CONFIG_POWER + struct pmic *p; + + p = pmic_get("MAX77686_PMIC"); + if (!p) + return; + /* LDO25 VCC_3.1V_LCD */ pmic_probe(p); max77686_set_ldo_voltage(p, 25, 3100000); max77686_set_ldo_mode(p, 25, OPMODE_LPM); +#endif }
void exynos_reset_lcd(void)

Most i2c peripherals for this board doesn't support new i2c api. So CONFIG_DM_I2C on this board can be enabled for test only. The i2c command works fine with it. This is the first step before adding support to the new power framework soon.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/trats2.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 42481ab..8b099dd 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -159,15 +159,18 @@ #define CONFIG_RANDOM_UUID
/* I2C */ -#include <asm/arch/gpio.h> - +#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif #define CONFIG_CMD_I2C - -#define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 + +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C #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 @@ -177,6 +180,8 @@ #define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD
+#include <asm/arch/gpio.h> + #ifndef __ASSEMBLY__ int get_soft_i2c_scl_pin(void); int get_soft_i2c_sda_pin(void); @@ -192,6 +197,7 @@ int get_soft_i2c_sda_pin(void); #define CONFIG_POWER_MUIC_MAX77693 #define CONFIG_POWER_FG_MAX77693 #define CONFIG_POWER_BATTERY_TRATS2 +#endif /* ifndef CONFIG_DM_I2C */
/* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA @@ -203,11 +209,13 @@ int get_soft_i2c_sda_pin(void); #define CONFIG_MISC_INIT_R
/* Download menu - Samsung common */ +#ifndef CONFIG_DM_I2C #define CONFIG_LCD_MENU #define CONFIG_LCD_MENU_BOARD
/* Download menu - definitions for check keys */ #ifndef __ASSEMBLY__ +#include <power/pmic.h> #include <power/max77686_pmic.h>
#define KEY_PWR_PMIC_NAME "MAX77686_PMIC" @@ -219,6 +227,7 @@ int get_soft_i2c_sda_pin(void); #define KEY_VOL_UP_GPIO EXYNOS4X12_GPIO_X22 #define KEY_VOL_DOWN_GPIO EXYNOS4X12_GPIO_X33 #endif /* __ASSEMBLY__ */ +#endif
/* LCD console */ #define LCD_BPP LCD_COLOR16

On 08/01/15 20:33, Przemyslaw Marczak wrote:
Most i2c peripherals for this board doesn't support new i2c api. So CONFIG_DM_I2C on this board can be enabled for test only. The i2c command works fine with it. This is the first step before adding support to the new power framework soon.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/trats2.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 42481ab..8b099dd 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -159,15 +159,18 @@ #define CONFIG_RANDOM_UUID
/* I2C */ -#include <asm/arch/gpio.h>
+#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif
please remove test code.
#define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0
+#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C #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 @@ -177,6 +180,8 @@ #define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD
+#include <asm/arch/gpio.h>
#ifndef __ASSEMBLY__ int get_soft_i2c_scl_pin(void); int get_soft_i2c_sda_pin(void); @@ -192,6 +197,7 @@ int get_soft_i2c_sda_pin(void); #define CONFIG_POWER_MUIC_MAX77693 #define CONFIG_POWER_FG_MAX77693 #define CONFIG_POWER_BATTERY_TRATS2 +#endif /* ifndef CONFIG_DM_I2C */
/* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA @@ -203,11 +209,13 @@ int get_soft_i2c_sda_pin(void); #define CONFIG_MISC_INIT_R
/* Download menu - Samsung common */ +#ifndef CONFIG_DM_I2C #define CONFIG_LCD_MENU #define CONFIG_LCD_MENU_BOARD
/* Download menu - definitions for check keys */ #ifndef __ASSEMBLY__ +#include <power/pmic.h> #include <power/max77686_pmic.h>
#define KEY_PWR_PMIC_NAME "MAX77686_PMIC" @@ -219,6 +227,7 @@ int get_soft_i2c_sda_pin(void); #define KEY_VOL_UP_GPIO EXYNOS4X12_GPIO_X22 #define KEY_VOL_DOWN_GPIO EXYNOS4X12_GPIO_X33 #endif /* __ASSEMBLY__ */ +#endif
/* LCD console */ #define LCD_BPP LCD_COLOR16
Thanks, Minkyu Kang

Hello Minkyu,
On 01/08/2015 03:11 PM, Minkyu Kang wrote:
On 08/01/15 20:33, Przemyslaw Marczak wrote:
Most i2c peripherals for this board doesn't support new i2c api. So CONFIG_DM_I2C on this board can be enabled for test only. The i2c command works fine with it. This is the first step before adding support to the new power framework soon.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/trats2.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 42481ab..8b099dd 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -159,15 +159,18 @@ #define CONFIG_RANDOM_UUID
/* I2C */ -#include <asm/arch/gpio.h>
+#if 0 /* For test */ +#define CONFIG_DM_I2C +#endif
please remove test code.
#define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0
+#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C #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
@@ -177,6 +180,8 @@ #define CONFIG_SOFT_I2C_READ_REPEATED_START #define CONFIG_SYS_I2C_INIT_BOARD
+#include <asm/arch/gpio.h>
- #ifndef __ASSEMBLY__ int get_soft_i2c_scl_pin(void); int get_soft_i2c_sda_pin(void);
@@ -192,6 +197,7 @@ int get_soft_i2c_sda_pin(void); #define CONFIG_POWER_MUIC_MAX77693 #define CONFIG_POWER_FG_MAX77693 #define CONFIG_POWER_BATTERY_TRATS2 +#endif /* ifndef CONFIG_DM_I2C */
/* Security subsystem - enable hw_rand() */ #define CONFIG_EXYNOS_ACE_SHA @@ -203,11 +209,13 @@ int get_soft_i2c_sda_pin(void); #define CONFIG_MISC_INIT_R
/* Download menu - Samsung common */ +#ifndef CONFIG_DM_I2C #define CONFIG_LCD_MENU #define CONFIG_LCD_MENU_BOARD
/* Download menu - definitions for check keys */ #ifndef __ASSEMBLY__ +#include <power/pmic.h> #include <power/max77686_pmic.h>
#define KEY_PWR_PMIC_NAME "MAX77686_PMIC" @@ -219,6 +227,7 @@ int get_soft_i2c_sda_pin(void); #define KEY_VOL_UP_GPIO EXYNOS4X12_GPIO_X22 #define KEY_VOL_DOWN_GPIO EXYNOS4X12_GPIO_X33 #endif /* __ASSEMBLY__ */ +#endif
/* LCD console */ #define LCD_BPP LCD_COLOR16
Thanks, Minkyu Kang
Ok, I will remove it in the both cases.
Best regards,

On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
There is no MAX77686 pmic on this board, so the driver support should be removed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/arndale.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index d68993b..3ad4a9b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -51,8 +51,6 @@ /* PMIC */ #define CONFIG_PMIC #define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686
#define CONFIG_PREBOOT
-- 1.9.1
Acked-by: Simon Glass sjg@chromium.org

On 26 January 2015 at 20:13, Simon Glass sjg@chromium.org wrote:
On 8 January 2015 at 04:33, Przemyslaw Marczak p.marczak@samsung.com wrote:
There is no MAX77686 pmic on this board, so the driver support should be removed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/arndale.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index d68993b..3ad4a9b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -51,8 +51,6 @@ /* PMIC */ #define CONFIG_PMIC #define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686
#define CONFIG_PREBOOT
-- 1.9.1
Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

Hello all,
On 01/08/2015 12:28 PM, Przemyslaw Marczak wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So this can't be enabled with the full board functionality.
In this case each Exynos5 based boards have fixed config dependencies Helloafor testing the dm i2c api with the new i2c driver. This will facilitate the peripheral porting.
For test, just enable CONFIG_DM_I2C in exynos5-common.h. The i2c command should work with this as previous.
This patchset also provides some changes related to Exynos4 boards. Most Exynos4 boards requires only pmic support, and this will be done with the new pmic framework soon.
Przemyslaw Marczak (18): arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config dm: i2c: s3c24x0: adjust to dm-i2c api exynos5: config: prepare for dm i2c support exynos5250: config: temporary disable sound for dm i2c arndale: config: temporary disable pmic for dm i2c exynos5-dt: config: temporary disable pmic for dm i2c snow: config: temporary disable cros ec i2c for dm i2c smdk5250: config: temporary disable pmic for dm i2c smdk5420: board: fix build warning for testing dm i2c peach-pi: config: temporary disable video parade for dm i2c peach-pit: config: temporary disable video parade for dm i2c trats2: board: cleanup power init code trats2: config: disable i2c peripherals if testing dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 ++-- arch/arm/dts/exynos4.dtsi | 24 ++-- arch/arm/dts/exynos5250-arndale.dts | 8 ++ board/samsung/smdk5420/smdk5420.c | 2 +- board/samsung/trats2/trats2.c | 144 +++++++++++--------- drivers/i2c/s3c24x0_i2c.c | 254 +++++++++++++++++++++++++++++++----- include/configs/arndale.h | 5 +- include/configs/exynos5-common.h | 29 ++-- include/configs/exynos5-dt-common.h | 2 + include/configs/exynos5250-common.h | 5 +- include/configs/peach-pi.h | 2 + include/configs/peach-pit.h | 2 + include/configs/smdk5250.h | 4 + include/configs/snow.h | 4 +- include/configs/trats2.h | 17 ++- 15 files changed, 395 insertions(+), 134 deletions(-)
The related patchset is also available here:
https://github.com/bobenstein/u-boot/tree/dm-i2c-exynos
Best regards,

This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
Commits with the test code, from the previous patch set, are removed.
Przemyslaw Marczak (10): arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config dm: i2c: s3c24x0: adjust to dm-i2c api odroid u3: dts: add missing i2c aliases odroid u3: enable dm i2c support exynos5: enable dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 ++-- arch/arm/dts/exynos4.dtsi | 24 ++-- arch/arm/dts/exynos4412-odroid.dts | 7 + arch/arm/dts/exynos5250-arndale.dts | 8 ++ board/samsung/odroid/odroid.c | 14 +- drivers/i2c/s3c24x0_i2c.c | 275 ++++++++++++++++++++++++++++++------ include/configs/arndale.h | 2 - include/configs/exynos5-common.h | 7 +- include/configs/exynos5250-common.h | 3 - include/configs/odroid.h | 5 +- include/configs/smdk5250.h | 2 + 11 files changed, 291 insertions(+), 83 deletions(-)

There is no MAX77686 pmic on this board, so the driver support should be removed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/arndale.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index d68993b..3ad4a9b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -51,8 +51,6 @@ /* PMIC */ #define CONFIG_PMIC #define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -
#define CONFIG_PREBOOT

This PMIC is not common for all Exynos5250 based boards, so should be romoved from common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/exynos5250-common.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index 6714313..ae0e5ff 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -28,9 +28,6 @@
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
-/* PMIC */ -#define CONFIG_POWER_MAX77686 - /* Sound */ #define CONFIG_CMD_SOUND #ifdef CONFIG_CMD_SOUND

This commit enable support for the above driver, which was disabled in common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 8395372..3b06d30 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -18,6 +18,8 @@
#include <configs/exynos5250-common.h>
+/* PMIC */ +#define CONFIG_POWER_MAX77686
#define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R

This patch modify i2c nodes in exynos4.dtsi with: - adding proper interrupts arrays for each i2c node, which allows to decode periph id - add reg address for each i2c node for i2c driver internal use
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com --- arch/arm/dts/exynos4.dtsi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi index 3c983ed..7de227c 100644 --- a/arch/arm/dts/exynos4.dtsi +++ b/arch/arm/dts/exynos4.dtsi @@ -51,56 +51,64 @@ #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <0 0 0>; + reg = <0x13860000 0x100>; + interrupts = <0 56 0>; };
i2c@13870000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <1 1 0>; + reg = <0x13870000 0x100>; + interrupts = <1 57 0>; };
i2c@13880000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <2 2 0>; + reg = <0x13880000 0x100>; + interrupts = <2 58 0>; };
i2c@13890000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <3 3 0>; + reg = <0x13890000 0x100>; + interrupts = <3 59 0>; };
i2c@138a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <4 4 0>; + reg = <0x138a0000 0x100>; + interrupts = <4 60 0>; };
i2c@138b0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <5 5 0>; + reg = <0x138b0000 0x100>; + interrupts = <5 61 0>; };
i2c@138c0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <6 6 0>; + reg = <0x138c0000 0x100>; + interrupts = <6 62 0>; };
i2c@138d0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <7 7 0>; + reg = <0x138d0000 0x100>; + interrupts = <7 63 0>; };
sdhci@12510000 {

Without this alias setting, the seq numbers of the i2c devices are wrong.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- arch/arm/dts/exynos5250-arndale.dts | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/dts/exynos5250-arndale.dts b/arch/arm/dts/exynos5250-arndale.dts index 202f2ea..21c0a21 100644 --- a/arch/arm/dts/exynos5250-arndale.dts +++ b/arch/arm/dts/exynos5250-arndale.dts @@ -15,6 +15,14 @@ compatible = "samsung,arndale", "samsung,exynos5250";
aliases { + i2c0 = "/i2c@12c60000"; + i2c1 = "/i2c@12c70000"; + i2c2 = "/i2c@12c80000"; + i2c3 = "/i2c@12c90000"; + i2c4 = "/i2c@12ca0000"; + i2c5 = "/i2c@12cb0000"; + i2c6 = "/i2c@12cc0000"; + i2c7 = "/i2c@12cd0000"; serial0 = "/serial@12C20000"; console = "/serial@12C20000"; };

Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 94d0297..b2c5494 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -266,22 +266,33 @@ static void exynos5_sromc_config(int flags)
static void exynos5_i2c_config(int peripheral, int flags) { + int func01, func23; + + /* flags only for High-Speed I2C */ + if (flags) { + func01 = 4; + func23 = 4; + } else { + func01 = 2; + func23 = 3; + } + switch (peripheral) { case PERIPH_ID_I2C0: - gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C1: - gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C2: - gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C3: - gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C4: gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3));

This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2, Odroid U3, Arndale, Odroid XU3
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - use consistent return values on errors - decrease transaction status timeout, because the previous one was too big --- drivers/i2c/s3c24x0_i2c.c | 275 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 233 insertions(+), 42 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..c82640d 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@ * as they seem to have the same I2C controller inside. * The different address mapping is handled by the s3c24xx.h files below. */ - #include <common.h> +#include <errno.h> +#include <dm.h> #include <fdtdec.h> #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> @@ -111,9 +112,9 @@ #define I2C_START_STOP 0x20 /* START / STOP */ #define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
-#define I2C_TIMEOUT_MS 1000 /* 1 second */ +#define I2C_TIMEOUT_MS 10 /* 10 ms */
-#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */ +#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
/* To support VCMA9 boards and other who dont define max_i2c_num */ @@ -121,13 +122,23 @@ #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 * @@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
+#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -326,7 +340,7 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) return 0; } } - return -1; + return -EINVAL; }
static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) @@ -398,18 +412,20 @@ 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);
- /* By default i2c channel 0 is the current bus */ 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 @@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ + i2c_ch_init(i2c, speed, slaveadd);
- bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c; } +#endif /* CONFIG_SYS_I2C */
/* * Poll the appropriate bit of the fifo status register until the interface is @@ -698,40 +715,40 @@ 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) + unsigned int speed) +#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else + if (!dev) + return -ENODEV; + + i2c_bus = dev_get_priv(dev); +#endif if (!i2c_bus) - return -1; + return -EFAULT;
i2c_bus->clock_frequency = speed;
if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus)) - return -1; + return -EFAULT; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, - CONFIG_SYS_I2C_S3C24X0_SLAVE); + CONFIG_SYS_I2C_S3C24X0_SLAVE); }
return 0; }
-#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{ - /* This will override the speed selected in the fdt for that port */ - debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); - if (i2c_set_bus_speed(speed)) - printf("i2c_init: failed to init bus %d for speed = %d\n", - adap->hwadapnr, speed); -} -#endif - /* * cmd_type is 0 for write, 1 for read. * @@ -844,15 +861,24 @@ 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; uchar buf[1]; int ret;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else + i2c_bus = dev_get_priv(dev); +#endif if (!i2c_bus) - return -1; + return -EFAULT; + buf[0] = 0;
/* @@ -871,6 +897,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) 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) { @@ -878,9 +905,13 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, 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 1; + return -EFBIG; }
if (alen > 0) { @@ -906,10 +937,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len); @@ -921,7 +948,7 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (i2c_bus->is_highspeed) exynos5_i2c_reset(i2c_bus); debug("I2c read failed %d\n", ret); - return 1; + return -EIO; } return 0; } @@ -933,9 +960,13 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, 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 1; + return -EINVAL; }
if (alen > 0) { @@ -960,10 +991,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true); @@ -1010,7 +1037,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i; - exynos_pinmux_config(bus->id, 0); + exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, 0);
/* Mark position as used */ node_list[i] = -1; @@ -1033,7 +1060,6 @@ void board_i2c_init(const void *blob) 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) @@ -1046,7 +1072,7 @@ int i2c_get_bus_num_fdt(int node) }
debug("%s: Can't find any matched I2C bus\n", __func__); - return -1; + return -EINVAL; }
int i2c_reset_port_fdt(const void *blob, int node) @@ -1057,18 +1083,18 @@ int i2c_reset_port_fdt(const void *blob, int node) bus = i2c_get_bus_num_fdt(node); if (bus < 0) { debug("could not get bus for node %d\n", node); - return -1; + return bus; }
i2c_bus = get_bus(bus); if (!i2c_bus) { - debug("get_bus() failed for node node %d\n", node); - return -1; + debug("get_bus() failed for node %d\n", node); + return -EFAULT; }
if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus)) - return -1; + return -EINVAL; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, @@ -1077,7 +1103,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
return 0; } -#endif +#endif /* CONFIG_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 @@ -1247,3 +1283,158 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */ + +#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len, bool end_with_repeated_start) +{ + int ret; + + if (!i2c_bus) + return -EFAULT; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0, + buffer, len, true); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len) +{ + int ret; + + if (!i2c_bus) + return -EFAULT; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_READ, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct s3c24x0_i2c_bus *i2c_bus; + int ret; + + if (!dev) + return -ENODEV; + + i2c_bus = dev_get_priv(dev); + if (!i2c_bus) + return -EFAULT; + + for (; nmsgs > 0; nmsgs--, msg++) { + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); + + if (msg->flags & I2C_M_RD) { + ret = i2c_read_data(i2c_bus, msg->addr, msg->buf, + msg->len); + } else { + ret = i2c_write_data(i2c_bus, msg->addr, msg->buf, + msg->len, next_is_read); + } + if (ret) + return -EREMOTEIO; + } + + return 0; +} + +static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + struct s3c24x0_i2c_bus *i2c_bus; + int node; + + if (!dev) { + error("%s: no such device!", dev->name); + return -ENODEV; + } + + i2c_bus = dev_get_priv(dev); + if (!i2c_bus) { + error("%s: i2c bus not allocated!", dev->name); + return -EFAULT; + } + + if (!dev->of_id) { + error("%s: no compat ids!", dev->name); + return -EINVAL; + } + i2c_bus->is_highspeed = dev->of_id->data; + + node = dev->of_offset; + + if (i2c_bus->is_highspeed) { + i2c_bus->hsregs = (struct exynos5_hsi2c *) + fdtdec_get_addr(blob, node, "reg"); + } else { + i2c_bus->regs = (struct s3c24x0_i2c *) + fdtdec_get_addr(blob, node, "reg"); + } + + i2c_bus->id = pinmux_decode_periph_id(blob, node); + + i2c_bus->clock_frequency = fdtdec_get_int(blob, node, + "clock-frequency", + CONFIG_SYS_I2C_S3C24X0_SPEED); + i2c_bus->node = node; + i2c_bus->bus_num = dev->seq; + + exynos_pinmux_config(i2c_bus->id, i2c_bus->is_highspeed); + + i2c_bus->active = true; + + return 0; +} + +static int s3c_i2c_child_pre_probe(struct udevice *dev) +{ + struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); + + if (dev->of_offset == -1) + return 0; + return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, + i2c_chip); +} + +static const struct dm_i2c_ops s3c_i2c_ops = { + .xfer = s3c24x0_i2c_xfer, + .probe_chip = s3c24x0_i2c_probe, + .set_bus_speed = s3c24x0_i2c_set_bus_speed, +}; + +static const struct udevice_id s3c_i2c_ids[] = { + { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD }, + { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS }, + { } +}; + +U_BOOT_DRIVER(i2c_s3c) = { + .name = "i2c_s3c", + .id = UCLASS_I2C, + .of_match = s3c_i2c_ids, + .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .child_pre_probe = s3c_i2c_child_pre_probe, + .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), + .ops = &s3c_i2c_ops, +}; +#endif /* CONFIG_DM_I2C */

Hi Przemyslaw,
On 26 January 2015 at 08:21, Przemyslaw Marczak p.marczak@samsung.com wrote:
This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2, Odroid U3, Arndale, Odroid XU3
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
Tested on snow:
Tested-by: Simon Glass sjg@chromium.org
This looks right to me, but I have a number of nits, mostly code that can be deleted, Please see below.
If you can respin this I will pick it up.
Changes v2:
- use consistent return values on errors
- decrease transaction status timeout, because the previous one was too big
drivers/i2c/s3c24x0_i2c.c | 275 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 233 insertions(+), 42 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..c82640d 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@
- as they seem to have the same I2C controller inside.
- The different address mapping is handled by the s3c24xx.h files below.
*/
#include <common.h> +#include <errno.h> +#include <dm.h> #include <fdtdec.h> #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> @@ -111,9 +112,9 @@ #define I2C_START_STOP 0x20 /* START / STOP */ #define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
-#define I2C_TIMEOUT_MS 1000 /* 1 second */ +#define I2C_TIMEOUT_MS 10 /* 10 ms */
-#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */ +#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
Why change the timeouts? In any case that should be a separate patch.
/* To support VCMA9 boards and other who dont define max_i2c_num */ @@ -121,13 +122,23 @@ #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
@@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
+#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -326,7 +340,7 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) return 0; } }
return -1;
return -EINVAL;
}
static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) @@ -398,18 +412,20 @@ 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);
/* By default i2c channel 0 is the current bus */ 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
@@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
i2c_ch_init(i2c, speed, slaveadd);
bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c;
} +#endif /* CONFIG_SYS_I2C */
/*
- Poll the appropriate bit of the fifo status register until the interface is
@@ -698,40 +715,40 @@ 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)
unsigned int speed)
+#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else
if (!dev)
return -ENODEV;
This can't happen, you can drop this check.
i2c_bus = dev_get_priv(dev);
+#endif if (!i2c_bus)
return -1;
return -EFAULT;
This can't happen for driver model, so move this check up into the #ifdef CONFIG_SYS_I2C
i2c_bus->clock_frequency = speed; if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus))
return -1;
return -EFAULT; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
CONFIG_SYS_I2C_S3C24X0_SLAVE);
CONFIG_SYS_I2C_S3C24X0_SLAVE);
Should leave this line alone.
} return 0;
}
-#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{
/* This will override the speed selected in the fdt for that port */
debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
if (i2c_set_bus_speed(speed))
printf("i2c_init: failed to init bus %d for speed = %d\n",
adap->hwadapnr, speed);
-} -#endif
/*
- cmd_type is 0 for write, 1 for read.
@@ -844,15 +861,24 @@ 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; uchar buf[1]; int ret;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); +#else
i2c_bus = dev_get_priv(dev);
+#endif if (!i2c_bus)
return -1;
return -EFAULT;
Same comments as above.
buf[0] = 0; /*
@@ -871,6 +897,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) 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) { @@ -878,9 +905,13 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, 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 1;
return -EFBIG;
I've been using -EADDRNOTAVAIL
} if (alen > 0) {
@@ -906,10 +937,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif
i2c_bus = get_bus(adap->hwadapnr);
if (!i2c_bus)
return -1;
if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len);
@@ -921,7 +948,7 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (i2c_bus->is_highspeed) exynos5_i2c_reset(i2c_bus); debug("I2c read failed %d\n", ret);
return 1;
return -EIO; } return 0;
} @@ -933,9 +960,13 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, 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 1;
return -EINVAL; } if (alen > 0) {
@@ -960,10 +991,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif
i2c_bus = get_bus(adap->hwadapnr);
if (!i2c_bus)
return -1;
if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true);
@@ -1010,7 +1037,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i;
exynos_pinmux_config(bus->id, 0);
exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, 0); /* Mark position as used */ node_list[i] = -1;
@@ -1033,7 +1060,6 @@ void board_i2c_init(const void *blob) 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) @@ -1046,7 +1072,7 @@ int i2c_get_bus_num_fdt(int node) }
debug("%s: Can't find any matched I2C bus\n", __func__);
return -1;
return -EINVAL;
}
int i2c_reset_port_fdt(const void *blob, int node) @@ -1057,18 +1083,18 @@ int i2c_reset_port_fdt(const void *blob, int node) bus = i2c_get_bus_num_fdt(node); if (bus < 0) { debug("could not get bus for node %d\n", node);
return -1;
return bus; } i2c_bus = get_bus(bus); if (!i2c_bus) {
debug("get_bus() failed for node node %d\n", node);
return -1;
debug("get_bus() failed for node %d\n", node);
return -EFAULT; } if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus))
return -1;
return -EINVAL; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
@@ -1077,7 +1103,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
return 0;
} -#endif +#endif /* CONFIG_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
@@ -1247,3 +1283,158 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */
+#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
uchar *buffer, int len, bool end_with_repeated_start)
+{
int ret;
if (!i2c_bus)
return -EFAULT;
Can't happen, drop this check.
if (i2c_bus->is_highspeed) {
ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0,
buffer, len, true);
if (ret)
exynos5_i2c_reset(i2c_bus);
} else {
ret = i2c_transfer(i2c_bus->regs, I2C_WRITE,
chip << 1, 0, 0, buffer, len);
}
return ret != I2C_OK;
+}
+static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
uchar *buffer, int len)
+{
int ret;
if (!i2c_bus)
return -EFAULT;
Can't happen, drop this check.
if (i2c_bus->is_highspeed) {
ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len);
if (ret)
exynos5_i2c_reset(i2c_bus);
} else {
ret = i2c_transfer(i2c_bus->regs, I2C_READ,
chip << 1, 0, 0, buffer, len);
}
return ret != I2C_OK;
+}
+static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
int nmsgs)
+{
struct s3c24x0_i2c_bus *i2c_bus;
int ret;
if (!dev)
return -ENODEV;
i2c_bus = dev_get_priv(dev);
if (!i2c_bus)
return -EFAULT;
Can't happen, drop this check.
for (; nmsgs > 0; nmsgs--, msg++) {
bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
if (msg->flags & I2C_M_RD) {
ret = i2c_read_data(i2c_bus, msg->addr, msg->buf,
msg->len);
} else {
ret = i2c_write_data(i2c_bus, msg->addr, msg->buf,
msg->len, next_is_read);
}
if (ret)
return -EREMOTEIO;
}
return 0;
+}
+static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{
const void *blob = gd->fdt_blob;
struct s3c24x0_i2c_bus *i2c_bus;
int node;
if (!dev) {
error("%s: no such device!", dev->name);
return -ENODEV;
}
Can't happen, drop this check.
i2c_bus = dev_get_priv(dev);
if (!i2c_bus) {
error("%s: i2c bus not allocated!", dev->name);
return -EFAULT;
}
Can't happen, drop this check.
if (!dev->of_id) {
error("%s: no compat ids!", dev->name);
return -EINVAL;
}
Can't happen, drop this check.
i2c_bus->is_highspeed = dev->of_id->data;
Remove blank line
node = dev->of_offset;
if (i2c_bus->is_highspeed) {
i2c_bus->hsregs = (struct exynos5_hsi2c *)
fdtdec_get_addr(blob, node, "reg");
} else {
i2c_bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
}
i2c_bus->id = pinmux_decode_periph_id(blob, node);
i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
"clock-frequency",
CONFIG_SYS_I2C_S3C24X0_SPEED);
i2c_bus->node = node;
i2c_bus->bus_num = dev->seq;
exynos_pinmux_config(i2c_bus->id, i2c_bus->is_highspeed);
You should add a flag to pinmux.h and then do something like:
exynos_pinmux_config(i2c_bus->id, i2c_bus->is_highspeed ? PINMUX_FLAG_I2C_HIGH_SPEED : 0);
i2c_bus->active = true;
return 0;
+}
+static int s3c_i2c_child_pre_probe(struct udevice *dev) +{
struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
if (dev->of_offset == -1)
return 0;
return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
i2c_chip);
+}
Not needed, drop this functoin.
+static const struct dm_i2c_ops s3c_i2c_ops = {
.xfer = s3c24x0_i2c_xfer,
.probe_chip = s3c24x0_i2c_probe,
.set_bus_speed = s3c24x0_i2c_set_bus_speed,
+};
+static const struct udevice_id s3c_i2c_ids[] = {
{ .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD },
{ .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS },
{ }
+};
+U_BOOT_DRIVER(i2c_s3c) = {
.name = "i2c_s3c",
.id = UCLASS_I2C,
.of_match = s3c_i2c_ids,
.ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
Not needed, drop this member.
.child_pre_probe = s3c_i2c_child_pre_probe,
Not needed, drop this functoin.
.priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
.ops = &s3c_i2c_ops,
+};
+#endif /* CONFIG_DM_I2C */
1.9.1
Regards, Simon

Hello Simon,
On 01/27/2015 04:13 AM, Simon Glass wrote:
Hi Przemyslaw,
On 26 January 2015 at 08:21, Przemyslaw Marczak p.marczak@samsung.com wrote:
This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2, Odroid U3, Arndale, Odroid XU3
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
Tested on snow:
Tested-by: Simon Glass sjg@chromium.org
This looks right to me, but I have a number of nits, mostly code that can be deleted, Please see below.
If you can respin this I will pick it up.
Thank you for the review, I will fix the issues and resend this today.
Best regards,

This change fixes i2c bus numbering for Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - new patch --- arch/arm/dts/exynos4412-odroid.dts | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index 29ad6ab..00a2917 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -16,6 +16,13 @@
aliases { i2c0 = "/i2c@13860000"; + i2c1 = "/i2c@13870000"; + i2c2 = "/i2c@13880000"; + i2c3 = "/i2c@13890000"; + i2c4 = "/i2c@138a0000"; + i2c5 = "/i2c@138b0000"; + i2c6 = "/i2c@138c0000"; + i2c7 = "/i2c@138d0000"; serial0 = "/serial@13800000"; console = "/serial@13810000"; mmc2 = "sdhci@12530000";

On 26 January 2015 at 08:21, Przemyslaw Marczak p.marczak@samsung.com wrote:
This change fixes i2c bus numbering for Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
Changes v2:
- new patch
arch/arm/dts/exynos4412-odroid.dts | 7 +++++++ 1 file changed, 7 insertions(+)
Acked-by: Simon Glass sjg@chromium.org

This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when the dm pmic framework will be finished.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - new patch --- board/samsung/odroid/odroid.c | 14 +------------- include/configs/odroid.h | 5 ++--- 2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c index b7d2381..e3517f2 100644 --- a/board/samsung/odroid/odroid.c +++ b/board/samsung/odroid/odroid.c @@ -415,15 +415,6 @@ static int pmic_init_max77686(void) return 0; }
-#ifdef CONFIG_SYS_I2C_INIT_BOARD -static void board_init_i2c(void) -{ - /* I2C_0 */ - if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) - debug("I2C%d not configured\n", (I2C_0)); -} -#endif - int exynos_early_init_f(void) { board_clock_init(); @@ -444,10 +435,7 @@ int exynos_init(void)
int exynos_power_init(void) { -#ifdef CONFIG_SYS_I2C_INIT_BOARD - board_init_i2c(); -#endif - pmic_init(I2C_0); + pmic_init(0); pmic_init_max77686();
return 0; diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 807e96b..9d5dbdc 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -177,12 +177,11 @@
/* I2C */ #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C +#define CONFIG_DM_I2C +#define CONFIG_DM_I2C_COMPAT #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_INIT_BOARD
/* POWER */ #define CONFIG_POWER

On 26 January 2015 at 08:21, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when the dm pmic framework will be finished.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
Changes v2:
- new patch
board/samsung/odroid/odroid.c | 14 +------------- include/configs/odroid.h | 5 ++--- 2 files changed, 3 insertions(+), 16 deletions(-)
Acked-by: Simon Glass sjg@chromium.org

This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when all the i2c peripheral drivers will use dm i2c framework.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Simon Glass sjg@chromium.org
--- Changes v2: - new patch --- include/configs/exynos5-common.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c..0ba39a2 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -126,12 +126,11 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#define CONFIG_DM_I2C +#define CONFIG_DM_I2C_COMPAT #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 #define CONFIG_I2C_EDID

On 26 January 2015 at 08:21, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when all the i2c peripheral drivers will use dm i2c framework.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Simon Glass sjg@chromium.org
Changes v2:
- new patch
Acked-by: Simon Glass sjg@chromium.org

Hello Simon,
On 01/26/2015 04:21 PM, Przemyslaw Marczak wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
Commits with the test code, from the previous patch set, are removed.
Przemyslaw Marczak (10): arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config dm: i2c: s3c24x0: adjust to dm-i2c api odroid u3: dts: add missing i2c aliases odroid u3: enable dm i2c support exynos5: enable dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 ++-- arch/arm/dts/exynos4.dtsi | 24 ++-- arch/arm/dts/exynos4412-odroid.dts | 7 + arch/arm/dts/exynos5250-arndale.dts | 8 ++ board/samsung/odroid/odroid.c | 14 +- drivers/i2c/s3c24x0_i2c.c | 275 ++++++++++++++++++++++++++++++------ include/configs/arndale.h | 2 - include/configs/exynos5-common.h | 7 +- include/configs/exynos5250-common.h | 3 - include/configs/odroid.h | 5 +- include/configs/smdk5250.h | 2 + 11 files changed, 291 insertions(+), 83 deletions(-)
The patchset is rebased on the top of the u-boot-dm/master, and is available also on github: https://github.com/bobenstein/u-boot/tree/dm-i2c-exynos_v2
Best regards,

This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
The main change from the previous version is: - non-required code cleanup after Simon Glass comments - add new pinmux flag for Exynos - split commit with s3c i2c status timeout change - fix build error for u-boot-dm/master
Przemyslaw Marczak (12): dm: i2c-uclass-compat: fix missed argument arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config i2c: s3c24x0: reduce transmission status timeout dm: i2c: s3c24x0: adjust to dm-i2c api odroid u3: dts: add missing i2c aliases odroid u3: enable dm i2c support exynos5: enable dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++- arch/arm/dts/exynos4.dtsi | 24 ++- arch/arm/dts/exynos4412-odroid.dts | 7 + arch/arm/dts/exynos5250-arndale.dts | 8 + arch/arm/include/asm/arch-exynos/pinmux.h | 3 + board/samsung/odroid/odroid.c | 14 +- drivers/i2c/i2c-uclass-compat.c | 2 +- drivers/i2c/s3c24x0_i2c.c | 241 ++++++++++++++++++++++++------ include/configs/arndale.h | 2 - include/configs/exynos5-common.h | 7 +- include/configs/exynos5250-common.h | 3 - include/configs/odroid.h | 5 +- include/configs/smdk5250.h | 2 + 13 files changed, 258 insertions(+), 87 deletions(-)

This patch fixes build error for CONFIG_DM_I2C_COMPAT. In i2c_get_chip_for_busnum() call, one of argument was missed, which was offset_len. Now it is set to 'alen' as previous.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- drivers/i2c/i2c-uclass-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 11239da..841ce05 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -17,7 +17,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, struct dm_i2c_chip *chip; int ret;
- ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); + ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp); if (ret) return ret; chip = dev_get_parent_platdata(*devp);

Hi Przemyslaw,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch fixes build error for CONFIG_DM_I2C_COMPAT. In i2c_get_chip_for_busnum() call, one of argument was missed, which was offset_len. Now it is set to 'alen' as previous.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
drivers/i2c/i2c-uclass-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 11239da..841ce05 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -17,7 +17,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, struct dm_i2c_chip *chip; int ret;
ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp);
ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp); if (ret) return ret; chip = dev_get_parent_platdata(*devp);
--
Thanks. I sent a patch which fixes this too but have not yet applied it.
Acked-by: Simon Glass sjg@chromium.org
Regards, Simon

On 27 January 2015 at 08:38, Simon Glass sjg@chromium.org wrote:
Hi Przemyslaw,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch fixes build error for CONFIG_DM_I2C_COMPAT. In i2c_get_chip_for_busnum() call, one of argument was missed, which was offset_len. Now it is set to 'alen' as previous.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
drivers/i2c/i2c-uclass-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 11239da..841ce05 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -17,7 +17,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, struct dm_i2c_chip *chip; int ret;
ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp);
ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp); if (ret) return ret; chip = dev_get_parent_platdata(*devp);
--
Thanks. I sent a patch which fixes this too but have not yet applied it.
Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

There is no MAX77686 pmic on this board, so the driver support should be removed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/arndale.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index d68993b..3ad4a9b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -51,8 +51,6 @@ /* PMIC */ #define CONFIG_PMIC #define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -
#define CONFIG_PREBOOT

This PMIC is not common for all Exynos5250 based boards, so should be romoved from common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/exynos5250-common.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index 6714313..ae0e5ff 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -28,9 +28,6 @@
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
-/* PMIC */ -#define CONFIG_POWER_MAX77686 - /* Sound */ #define CONFIG_CMD_SOUND #ifdef CONFIG_CMD_SOUND

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This PMIC is not common for all Exynos5250 based boards, so should be romoved from common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/exynos5250-common.h | 3 --- 1 file changed, 3 deletions(-)
Applied to u-boot-dm, thanks!

This commit enable support for the above driver, which was disabled in common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 8395372..3b06d30 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -18,6 +18,8 @@
#include <configs/exynos5250-common.h>
+/* PMIC */ +#define CONFIG_POWER_MAX77686
#define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This commit enable support for the above driver, which was disabled in common config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-dm, thanks!

This patch modify i2c nodes in exynos4.dtsi with: - adding proper interrupts arrays for each i2c node, which allows to decode periph id - add reg address for each i2c node for i2c driver internal use
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com --- arch/arm/dts/exynos4.dtsi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi index 3c983ed..7de227c 100644 --- a/arch/arm/dts/exynos4.dtsi +++ b/arch/arm/dts/exynos4.dtsi @@ -51,56 +51,64 @@ #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <0 0 0>; + reg = <0x13860000 0x100>; + interrupts = <0 56 0>; };
i2c@13870000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <1 1 0>; + reg = <0x13870000 0x100>; + interrupts = <1 57 0>; };
i2c@13880000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <2 2 0>; + reg = <0x13880000 0x100>; + interrupts = <2 58 0>; };
i2c@13890000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <3 3 0>; + reg = <0x13890000 0x100>; + interrupts = <3 59 0>; };
i2c@138a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <4 4 0>; + reg = <0x138a0000 0x100>; + interrupts = <4 60 0>; };
i2c@138b0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <5 5 0>; + reg = <0x138b0000 0x100>; + interrupts = <5 61 0>; };
i2c@138c0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <6 6 0>; + reg = <0x138c0000 0x100>; + interrupts = <6 62 0>; };
i2c@138d0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <7 7 0>; + reg = <0x138d0000 0x100>; + interrupts = <7 63 0>; };
sdhci@12510000 {

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch modify i2c nodes in exynos4.dtsi with:
- adding proper interrupts arrays for each i2c node, which allows to decode periph id
- add reg address for each i2c node for i2c driver internal use
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com Cc: Lukasz Majewski l.majewski@samsung.com
arch/arm/dts/exynos4.dtsi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
Applied to u-boot-dm, thanks!

Without this alias setting, the seq numbers of the i2c devices are wrong.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com --- arch/arm/dts/exynos5250-arndale.dts | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/dts/exynos5250-arndale.dts b/arch/arm/dts/exynos5250-arndale.dts index 202f2ea..21c0a21 100644 --- a/arch/arm/dts/exynos5250-arndale.dts +++ b/arch/arm/dts/exynos5250-arndale.dts @@ -15,6 +15,14 @@ compatible = "samsung,arndale", "samsung,exynos5250";
aliases { + i2c0 = "/i2c@12c60000"; + i2c1 = "/i2c@12c70000"; + i2c2 = "/i2c@12c80000"; + i2c3 = "/i2c@12c90000"; + i2c4 = "/i2c@12ca0000"; + i2c5 = "/i2c@12cb0000"; + i2c6 = "/i2c@12cc0000"; + i2c7 = "/i2c@12cd0000"; serial0 = "/serial@12C20000"; console = "/serial@12C20000"; };

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
Without this alias setting, the seq numbers of the i2c devices are wrong.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
arch/arm/dts/exynos5250-arndale.dts | 8 ++++++++ 1 file changed, 8 insertions(+)
Applied to u-boot-dm, thanks!

Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this. The new flag is: PINMUX_FLAG_HS_MODE
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v3: - add new flag: PINMUX_FLAG_HS_MODE --- arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- arch/arm/include/asm/arch-exynos/pinmux.h | 3 +++ 2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 94d0297..be43e22 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -266,22 +266,33 @@ static void exynos5_sromc_config(int flags)
static void exynos5_i2c_config(int peripheral, int flags) { + int func01, func23; + + /* High-Speed I2C */ + if (flags & PINMUX_FLAG_HS_MODE) { + func01 = 4; + func23 = 4; + } else { + func01 = 2; + func23 = 3; + } + switch (peripheral) { case PERIPH_ID_I2C0: - gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C1: - gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C2: - gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C3: - gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C4: gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3)); diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h index 0b91ef6..d0ae757 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -23,6 +23,9 @@ enum { /* Flags for SROM controller */ PINMUX_FLAG_BANK = 3 << 0, /* bank number (0-3) */ PINMUX_FLAG_16BIT = 1 << 2, /* 16-bit width */ + + /* Flags for I2C */ + PINMUX_FLAG_HS_MODE = 1 << 1, /* I2C High Speed Mode */ };
/**

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this. The new flag is: PINMUX_FLAG_HS_MODE
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
Changes v3:
- add new flag: PINMUX_FLAG_HS_MODE
arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- arch/arm/include/asm/arch-exynos/pinmux.h | 3 +++ 2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 94d0297..be43e22 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -266,22 +266,33 @@ static void exynos5_sromc_config(int flags)
static void exynos5_i2c_config(int peripheral, int flags) {
int func01, func23;
/* High-Speed I2C */
if (flags & PINMUX_FLAG_HS_MODE) {
func01 = 4;
func23 = 4;
} else {
func01 = 2;
func23 = 3;
}
switch (peripheral) { case PERIPH_ID_I2C0:
gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(0x2));
gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(0x2));
gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01));
gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C1:
gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(0x2));
gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(0x2));
gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01));
gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C2:
gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(0x3));
gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(0x3));
gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23));
gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C3:
gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(0x3));
gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(0x3));
gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23));
gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C4: gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3));
diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h index 0b91ef6..d0ae757 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -23,6 +23,9 @@ enum { /* Flags for SROM controller */ PINMUX_FLAG_BANK = 3 << 0, /* bank number (0-3) */ PINMUX_FLAG_16BIT = 1 << 2, /* 16-bit width */
/* Flags for I2C */
PINMUX_FLAG_HS_MODE = 1 << 1, /* I2C High Speed Mode */
};
/**
Acked-by: Simon Glass sjg@chromium.org

On 27 January 2015 at 08:38, Simon Glass sjg@chromium.org wrote:
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this. The new flag is: PINMUX_FLAG_HS_MODE
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
Changes v3:
- add new flag: PINMUX_FLAG_HS_MODE
arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- arch/arm/include/asm/arch-exynos/pinmux.h | 3 +++ 2 files changed, 22 insertions(+), 8 deletions(-)
Applied to u-boot-dm, thanks!

If no device is connected to I2C bus, the i2c probe command can take a lot of time for probe each address. This commit reduces the busy timeout to 10ms for standard and high speed modes. This doesn't break the transmission an also allow for properly probe the devices.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v3: - new commit, after split the next one --- drivers/i2c/s3c24x0_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..3129c7f 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -111,9 +111,9 @@ #define I2C_START_STOP 0x20 /* START / STOP */ #define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
-#define I2C_TIMEOUT_MS 1000 /* 1 second */ +#define I2C_TIMEOUT_MS 10 /* 10 ms */
-#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */ +#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
/* To support VCMA9 boards and other who dont define max_i2c_num */

Hi,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
If no device is connected to I2C bus, the i2c probe command can take a lot of time for probe each address. This commit reduces the busy timeout to 10ms for standard and high speed modes. This doesn't break the transmission an also allow for properly probe the devices.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Tested-by: Simon Glass sjg@chromium.org
This patch looks OK but I'd like to get other comments if possible.
Changes v3:
- new commit, after split the next one
drivers/i2c/s3c24x0_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0..3129c7f 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -111,9 +111,9 @@ #define I2C_START_STOP 0x20 /* START / STOP */ #define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
-#define I2C_TIMEOUT_MS 1000 /* 1 second */ +#define I2C_TIMEOUT_MS 10 /* 10 ms */
-#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */ +#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
/* To support VCMA9 boards and other who dont define max_i2c_num */
1.9.1
Regards, Simon

Hello,
On 01/27/2015 04:38 PM, Simon Glass wrote:
Hi,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
If no device is connected to I2C bus, the i2c probe command can take a lot of time for probe each address. This commit reduces the busy timeout to 10ms for standard and high speed modes. This doesn't break the transmission an also allow for properly probe the devices.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Tested-by: Simon Glass sjg@chromium.org
This patch looks OK but I'd like to get other comments if possible.
[cut]
Ok, that's fine. I tested this on Trats2 and Odroid XU3 and it works fine.
Best regards,

Hi,
On 27 January 2015 at 08:44, Przemyslaw Marczak p.marczak@samsung.com wrote:
Hello,
On 01/27/2015 04:38 PM, Simon Glass wrote:
Hi,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
If no device is connected to I2C bus, the i2c probe command can take a lot of time for probe each address. This commit reduces the busy timeout to 10ms for standard and high speed modes. This doesn't break the transmission an also allow for properly probe the devices.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Tested-by: Simon Glass sjg@chromium.org
This patch looks OK but I'd like to get other comments if possible.
[cut]
Ok, that's fine. I tested this on Trats2 and Odroid XU3 and it works fine.
Well, as this patch has not attracted any comments, and seems to work for me, I'll pick it up.
Regards, Simon

On 6 February 2015 at 13:48, Simon Glass sjg@chromium.org wrote:
Hi,
On 27 January 2015 at 08:44, Przemyslaw Marczak p.marczak@samsung.com wrote:
Hello,
On 01/27/2015 04:38 PM, Simon Glass wrote:
Hi,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
If no device is connected to I2C bus, the i2c probe command can take a lot of time for probe each address. This commit reduces the busy timeout to 10ms for standard and high speed modes. This doesn't break the transmission an also allow for properly probe the devices.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Tested-by: Simon Glass sjg@chromium.org
This patch looks OK but I'd like to get other comments if possible.
[cut]
Ok, that's fine. I tested this on Trats2 and Odroid XU3 and it works fine.
Well, as this patch has not attracted any comments, and seems to work for me, I'll pick it up.
Regards, Simon
Applied to u-boot-dm, thanks!

This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2, Odroid U3, Arndale, Odroid XU3
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Tested-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - use consistent return values on errors - decrease transaction status timeout, because the previous one was too big
Changes v3: - change of timeout move to new commit - use pinmux hs mode flag - remove unused code --- drivers/i2c/s3c24x0_i2c.c | 237 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 194 insertions(+), 43 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 3129c7f..b4ee33f 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@ * as they seem to have the same I2C controller inside. * The different address mapping is handled by the s3c24xx.h files below. */ - #include <common.h> +#include <errno.h> +#include <dm.h> #include <fdtdec.h> #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include <asm/arch/clk.h> @@ -121,13 +122,23 @@ #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 * @@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); }
+#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -326,7 +340,7 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) return 0; } } - return -1; + return -EINVAL; }
static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) @@ -398,18 +412,20 @@ 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);
- /* By default i2c channel 0 is the current bus */ 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 @@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ + i2c_ch_init(i2c, speed, slaveadd);
- bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c; } +#endif /* CONFIG_SYS_I2C */
/* * Poll the appropriate bit of the fifo status register until the interface is @@ -698,20 +715,27 @@ 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) + unsigned int speed) +#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); if (!i2c_bus) - return -1; - + return -EFAULT; +#else + i2c_bus = dev_get_priv(dev); +#endif i2c_bus->clock_frequency = speed;
if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus)) - return -1; + return -EFAULT; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, @@ -721,17 +745,6 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, return 0; }
-#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{ - /* This will override the speed selected in the fdt for that port */ - debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); - if (i2c_set_bus_speed(speed)) - printf("i2c_init: failed to init bus %d for speed = %d\n", - adap->hwadapnr, speed); -} -#endif - /* * cmd_type is 0 for write, 1 for read. * @@ -844,15 +857,23 @@ 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; uchar buf[1]; int ret;
+#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); if (!i2c_bus) - return -1; + return -EFAULT; +#else + i2c_bus = dev_get_priv(dev); +#endif buf[0] = 0;
/* @@ -871,6 +892,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) 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) { @@ -878,9 +900,13 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, 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 1; + return -EADDRNOTAVAIL; }
if (alen > 0) { @@ -906,10 +932,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len); @@ -921,7 +943,7 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (i2c_bus->is_highspeed) exynos5_i2c_reset(i2c_bus); debug("I2c read failed %d\n", ret); - return 1; + return -EIO; } return 0; } @@ -933,9 +955,13 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, 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 1; + return -EINVAL; }
if (alen > 0) { @@ -960,10 +986,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true); @@ -985,7 +1007,7 @@ static void process_nodes(const void *blob, int node_list[], int count, int is_highspeed) { struct s3c24x0_i2c_bus *bus; - int i; + int i, flags;
for (i = 0; i < count; i++) { int node = node_list[i]; @@ -997,12 +1019,15 @@ static void process_nodes(const void *blob, int node_list[], int count, bus->active = true; bus->is_highspeed = is_highspeed;
- if (is_highspeed) + if (is_highspeed) { + flags = PINMUX_FLAG_HS_MODE; bus->hsregs = (struct exynos5_hsi2c *) fdtdec_get_addr(blob, node, "reg"); - else + } 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, @@ -1010,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i; - exynos_pinmux_config(bus->id, 0); + exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, flags);
/* Mark position as used */ node_list[i] = -1; @@ -1033,7 +1058,6 @@ void board_i2c_init(const void *blob) 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) @@ -1046,7 +1070,7 @@ int i2c_get_bus_num_fdt(int node) }
debug("%s: Can't find any matched I2C bus\n", __func__); - return -1; + return -EINVAL; }
int i2c_reset_port_fdt(const void *blob, int node) @@ -1057,18 +1081,18 @@ int i2c_reset_port_fdt(const void *blob, int node) bus = i2c_get_bus_num_fdt(node); if (bus < 0) { debug("could not get bus for node %d\n", node); - return -1; + return bus; }
i2c_bus = get_bus(bus); if (!i2c_bus) { - debug("get_bus() failed for node node %d\n", node); - return -1; + debug("get_bus() failed for node %d\n", node); + return -EFAULT; }
if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus)) - return -1; + return -EINVAL; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, @@ -1077,7 +1101,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
return 0; } -#endif +#endif /* CONFIG_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 @@ -1247,3 +1281,120 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */ + +#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len, bool end_with_repeated_start) +{ + int ret; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0, + buffer, len, true); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len) +{ + int ret; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_READ, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + int ret; + + for (; nmsgs > 0; nmsgs--, msg++) { + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); + + if (msg->flags & I2C_M_RD) { + ret = i2c_read_data(i2c_bus, msg->addr, msg->buf, + msg->len); + } else { + ret = i2c_write_data(i2c_bus, msg->addr, msg->buf, + msg->len, next_is_read); + } + if (ret) + return -EREMOTEIO; + } + + return 0; +} + +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; + + i2c_bus->is_highspeed = dev->of_id->data; + node = dev->of_offset; + + if (i2c_bus->is_highspeed) { + flags = PINMUX_FLAG_HS_MODE; + i2c_bus->hsregs = (struct exynos5_hsi2c *) + fdtdec_get_addr(blob, node, "reg"); + } else { + flags = 0; + i2c_bus->regs = (struct s3c24x0_i2c *) + fdtdec_get_addr(blob, node, "reg"); + } + + i2c_bus->id = pinmux_decode_periph_id(blob, node); + + i2c_bus->clock_frequency = fdtdec_get_int(blob, node, + "clock-frequency", + CONFIG_SYS_I2C_S3C24X0_SPEED); + i2c_bus->node = node; + i2c_bus->bus_num = dev->seq; + + exynos_pinmux_config(i2c_bus->id, flags); + + i2c_bus->active = true; + + return 0; +} + +static const struct dm_i2c_ops s3c_i2c_ops = { + .xfer = s3c24x0_i2c_xfer, + .probe_chip = s3c24x0_i2c_probe, + .set_bus_speed = s3c24x0_i2c_set_bus_speed, +}; + +static const struct udevice_id s3c_i2c_ids[] = { + { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD }, + { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS }, + { } +}; + +U_BOOT_DRIVER(i2c_s3c) = { + .name = "i2c_s3c", + .id = UCLASS_I2C, + .of_match = s3c_i2c_ids, + .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), + .ops = &s3c_i2c_ops, +}; +#endif /* CONFIG_DM_I2C */

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2, Odroid U3, Arndale, Odroid XU3
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Tested-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
Retested on snow.
Acked-by: Simon Glass sjg@chromium.org

On 27 January 2015 at 08:38, Simon Glass sjg@chromium.org wrote:
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous.
Tested on Trats2, Odroid U3, Arndale, Odroid XU3
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Tested-by: Simon Glass sjg@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Heiko Schocher hs@denx.de Cc: Minkyu Kang mk7.kang@samsung.com
Retested on snow.
Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

This change fixes i2c bus numbering for Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - new patch --- arch/arm/dts/exynos4412-odroid.dts | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index 29ad6ab..00a2917 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -16,6 +16,13 @@
aliases { i2c0 = "/i2c@13860000"; + i2c1 = "/i2c@13870000"; + i2c2 = "/i2c@13880000"; + i2c3 = "/i2c@13890000"; + i2c4 = "/i2c@138a0000"; + i2c5 = "/i2c@138b0000"; + i2c6 = "/i2c@138c0000"; + i2c7 = "/i2c@138d0000"; serial0 = "/serial@13800000"; console = "/serial@13810000"; mmc2 = "sdhci@12530000";

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This change fixes i2c bus numbering for Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
Changes v2:
- new patch
arch/arm/dts/exynos4412-odroid.dts | 7 +++++++ 1 file changed, 7 insertions(+)
Applied to u-boot-dm, thanks!

This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when the dm pmic framework will be finished.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - new patch --- board/samsung/odroid/odroid.c | 14 +------------- include/configs/odroid.h | 5 ++--- 2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c index b7d2381..e3517f2 100644 --- a/board/samsung/odroid/odroid.c +++ b/board/samsung/odroid/odroid.c @@ -415,15 +415,6 @@ static int pmic_init_max77686(void) return 0; }
-#ifdef CONFIG_SYS_I2C_INIT_BOARD -static void board_init_i2c(void) -{ - /* I2C_0 */ - if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) - debug("I2C%d not configured\n", (I2C_0)); -} -#endif - int exynos_early_init_f(void) { board_clock_init(); @@ -444,10 +435,7 @@ int exynos_init(void)
int exynos_power_init(void) { -#ifdef CONFIG_SYS_I2C_INIT_BOARD - board_init_i2c(); -#endif - pmic_init(I2C_0); + pmic_init(0); pmic_init_max77686();
return 0; diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 807e96b..9d5dbdc 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -177,12 +177,11 @@
/* I2C */ #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C +#define CONFIG_DM_I2C +#define CONFIG_DM_I2C_COMPAT #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_INIT_BOARD
/* POWER */ #define CONFIG_POWER

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when the dm pmic framework will be finished.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Minkyu Kang mk7.kang@samsung.com
Changes v2:
- new patch
board/samsung/odroid/odroid.c | 14 +------------- include/configs/odroid.h | 5 ++--- 2 files changed, 3 insertions(+), 16 deletions(-)
Applied to u-boot-dm, thanks!

This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when all the i2c peripheral drivers will use dm i2c framework.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Simon Glass sjg@chromium.org
--- Changes v2: - new patch --- include/configs/exynos5-common.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c..0ba39a2 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -126,12 +126,11 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#define CONFIG_DM_I2C +#define CONFIG_DM_I2C_COMPAT #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 #define CONFIG_I2C_EDID

On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when all the i2c peripheral drivers will use dm i2c framework.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Acked-by: Simon Glass sjg@chromium.org Cc: Akshay Saraswat akshay.s@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Simon Glass sjg@chromium.org
Changes v2:
- new patch
include/configs/exynos5-common.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
Applied to u-boot-dm, thanks!

Hello Simon,
On 01/27/2015 01:36 PM, Przemyslaw Marczak wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
The main change from the previous version is:
- non-required code cleanup after Simon Glass comments
- add new pinmux flag for Exynos
- split commit with s3c i2c status timeout change
- fix build error for u-boot-dm/master
Przemyslaw Marczak (12): dm: i2c-uclass-compat: fix missed argument arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config i2c: s3c24x0: reduce transmission status timeout dm: i2c: s3c24x0: adjust to dm-i2c api odroid u3: dts: add missing i2c aliases odroid u3: enable dm i2c support exynos5: enable dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++- arch/arm/dts/exynos4.dtsi | 24 ++- arch/arm/dts/exynos4412-odroid.dts | 7 + arch/arm/dts/exynos5250-arndale.dts | 8 + arch/arm/include/asm/arch-exynos/pinmux.h | 3 + board/samsung/odroid/odroid.c | 14 +- drivers/i2c/i2c-uclass-compat.c | 2 +- drivers/i2c/s3c24x0_i2c.c | 241 ++++++++++++++++++++++++------ include/configs/arndale.h | 2 - include/configs/exynos5-common.h | 7 +- include/configs/exynos5250-common.h | 3 - include/configs/odroid.h | 5 +- include/configs/smdk5250.h | 2 + 13 files changed, 258 insertions(+), 87 deletions(-)
This version is available here: https://github.com/bobenstein/u-boot/tree/dm-i2c-exynos_v3
One additional fix to: i2c-uclass-compat.c, the same issue is on u-boot-dm/i2c-working
Best regards,

+Minkyu
Hi Przemyslaw,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
I plan to pick this series up for the driver model tree and hopefully get it in in time for RC1. Minkyu is that OK with you?
The main change from the previous version is:
- non-required code cleanup after Simon Glass comments
- add new pinmux flag for Exynos
- split commit with s3c i2c status timeout change
- fix build error for u-boot-dm/master
If you use patman Series-changes tags it will automate the change logs for you.
Przemyslaw Marczak (12): dm: i2c-uclass-compat: fix missed argument arndale: config: disable max77686 support exynos5250: config: disable max77686 driver smdk5250: config: enable max77686 driver support exynos4: dts: add missing i2c properties arndale: dts: add missing i2c aliases exynos5: pinmux: check flag for i2c config i2c: s3c24x0: reduce transmission status timeout dm: i2c: s3c24x0: adjust to dm-i2c api odroid u3: dts: add missing i2c aliases odroid u3: enable dm i2c support exynos5: enable dm i2c
arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++- arch/arm/dts/exynos4.dtsi | 24 ++- arch/arm/dts/exynos4412-odroid.dts | 7 + arch/arm/dts/exynos5250-arndale.dts | 8 + arch/arm/include/asm/arch-exynos/pinmux.h | 3 + board/samsung/odroid/odroid.c | 14 +- drivers/i2c/i2c-uclass-compat.c | 2 +- drivers/i2c/s3c24x0_i2c.c | 241 ++++++++++++++++++++++++------ include/configs/arndale.h | 2 - include/configs/exynos5-common.h | 7 +- include/configs/exynos5250-common.h | 3 - include/configs/odroid.h | 5 +- include/configs/smdk5250.h | 2 + 13 files changed, 258 insertions(+), 87 deletions(-)
-- 1.9.1
Regards, Simon

Hi,
On 27 January 2015 at 08:38, Simon Glass sjg@chromium.org wrote:
+Minkyu
Hi Przemyslaw,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
I plan to pick this series up for the driver model tree and hopefully get it in in time for RC1. Minkyu is that OK with you?
OK I guess this is OK. I've assigned this series to myself in patchwork and will apply it tomorrow so that we can get the I2C changes in before the merge window ends.
Regards, Simon

On 28/01/15 00:38, Simon Glass wrote:
+Minkyu
Hi Przemyslaw,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
I plan to pick this series up for the driver model tree and hopefully get it in in time for RC1. Minkyu is that OK with you?
Sure. It's OK.
Do you have plan to merge dm with main tree? I will accept few patches to samsung, but I wonder that conflict with your tree. So please let me know about merge plan.
Thanks, Minkyu Kang.

Hi Minkyu,
On 28 January 2015 at 18:58, Minkyu Kang mk7.kang@samsung.com wrote:
On 28/01/15 00:38, Simon Glass wrote:
+Minkyu
Hi Przemyslaw,
On 27 January 2015 at 05:36, Przemyslaw Marczak p.marczak@samsung.com wrote:
This patchset adds support to driver model i2c api for Exynos i2c driver. Few boards are using this driver, but the board peripherals are not ported to the new api yet. So the CONFIG_DM_I2C_COMPAT is enabled.
Switch to dm i2c is currentlly not possible for the few devices like Trats2, Universal C210, S5P Goni, because ir require soft i2c support.
For Odroid U3, the compatiblility layer is enabled, because it uses only one pmic driver, which soon is going to be moved to dm i2c with the dm pmic framework.
The i2c dm compatibility layer is also enabled for Exynos5 boards, which should be removed after moving the i2c drivers to driver model.
I plan to pick this series up for the driver model tree and hopefully get it in in time for RC1. Minkyu is that OK with you?
Sure. It's OK.
OK ta.
Do you have plan to merge dm with main tree? I will accept few patches to samsung, but I wonder that conflict with your tree. So please let me know about merge plan.
I plan to send a pull request as soon as possible, probably Friday. So it should not be too much of a problem. Also hopefully your other outstanding patches don't affect the exynos I2C driver model conversion so there may not be any conflicts.
Regards, Simon
participants (4)
-
Heiko Schocher
-
Minkyu Kang
-
Przemyslaw Marczak
-
Simon Glass