Merge branch 'master' of git://git.denx.de/u-boot-i2c
authorTom Rini <trini@konsulko.com>
Mon, 10 Dec 2018 12:16:33 +0000 (07:16 -0500)
committerTom Rini <trini@konsulko.com>
Mon, 10 Dec 2018 12:16:33 +0000 (07:16 -0500)
- DM_I2C_COMPAT removal for all ti platforms from Jean-Jacques Hiblot
- Fix in i2c command help output from Chirstoph Muellner.

53 files changed:
arch/arm/dts/am437x-gp-evm-u-boot.dtsi
arch/arm/dts/omap5-u-boot.dtsi
arch/arm/include/asm/arch-am33xx/i2c.h
arch/arm/include/asm/arch-omap3/i2c.h
arch/arm/include/asm/arch-omap4/i2c.h
arch/arm/include/asm/arch-omap5/i2c.h
arch/arm/include/asm/omap_i2c.h [new file with mode: 0644]
arch/arm/mach-keystone/ddr3_spd.c
arch/arm/mach-omap2/am33xx/board.c
arch/arm/mach-omap2/am33xx/clk_synthesizer.c
arch/arm/mach-omap2/clocks-common.c
arch/arm/mach-omap2/hwinit-common.c
board/eets/pdu001/board.c
board/ti/am335x/board.c
board/ti/am335x/mux.c
board/ti/am43xx/board.c
board/ti/am57xx/board.c
board/ti/common/board_detect.c
board/ti/ks2_evm/board_k2g.c
cmd/Kconfig
cmd/i2c.c
configs/am335x_pdu001_defconfig
configs/am57xx_evm_defconfig
configs/am57xx_hs_evm_defconfig
configs/dra7xx_evm_defconfig
configs/dra7xx_hs_evm_defconfig
configs/omap3_logic_defconfig
doc/README.fdt-control
drivers/core/Kconfig
drivers/core/device.c
drivers/core/root.c
drivers/core/uclass.c
drivers/i2c/i2c-uclass.c
drivers/i2c/omap24xx_i2c.c
drivers/power/palmas.c
drivers/power/pmic/pmic_tps62362.c
drivers/power/pmic/pmic_tps65217.c
drivers/power/pmic/pmic_tps65218.c
drivers/power/pmic/pmic_tps65910.c
drivers/power/twl4030.c
drivers/power/twl6030.c
include/asm-generic/global_data.h
include/configs/am43xx_evm.h
include/configs/pdu001.h
include/configs/ti_armv7_common.h
include/dm/uclass-internal.h
include/fdtdec.h
include/palmas.h
include/power/tps65217.h
include/power/tps65910.h
include/twl4030.h
include/twl6030.h
lib/fdtdec.c

index 530f549..03a1c1d 100644 (file)
@@ -36,3 +36,7 @@
 &phy_sel {
        u-boot,dm-spl;
 };
+
+&i2c0 {
+       u-boot,dm-spl;
+};
index a6a7801..1eb50cd 100644 (file)
@@ -95,3 +95,7 @@
 &gpio7 {
        u-boot,dm-spl;
 };
+
+&i2c1 {
+       u-boot,dm-spl;
+};
index 491fca9..c2a9850 100644 (file)
@@ -6,57 +6,14 @@
 #ifndef _I2C_AM33XX_H_
 #define _I2C_AM33XX_H_
 
+#include <asm/omap_i2c.h>
+
 #define  I2C_BASE1             0x44E0B000
 #define  I2C_BASE2             0x4802A000
 #define  I2C_BASE3             0x4819C000
 
 #define I2C_DEFAULT_BASE               I2C_BASE1
 
-struct i2c {
-       unsigned short revnb_lo;        /* 0x00 */
-       unsigned short res1;
-       unsigned short revnb_hi;        /* 0x04 */
-       unsigned short res2[5];
-       unsigned short sysc;            /* 0x10 */
-       unsigned short res3[9];
-       unsigned short irqstatus_raw;   /* 0x24 */
-       unsigned short res4;
-       unsigned short stat;            /* 0x28 */
-       unsigned short res5;
-       unsigned short ie;              /* 0x2C */
-       unsigned short res6;
-       unsigned short irqenable_clr;   /* 0x30 */
-       unsigned short res7;
-       unsigned short iv;              /* 0x34 */
-       unsigned short res8[45];
-       unsigned short syss;            /* 0x90 */
-       unsigned short res9;
-       unsigned short buf;             /* 0x94 */
-       unsigned short res10;
-       unsigned short cnt;             /* 0x98 */
-       unsigned short res11;
-       unsigned short data;            /* 0x9C */
-       unsigned short res13;
-       unsigned short res14;           /* 0xA0 */
-       unsigned short res15;
-       unsigned short con;             /* 0xA4 */
-       unsigned short res16;
-       unsigned short oa;              /* 0xA8 */
-       unsigned short res17;
-       unsigned short sa;              /* 0xAC */
-       unsigned short res18;
-       unsigned short psc;             /* 0xB0 */
-       unsigned short res19;
-       unsigned short scll;            /* 0xB4 */
-       unsigned short res20;
-       unsigned short sclh;            /* 0xB8 */
-       unsigned short res21;
-       unsigned short systest;         /* 0xBC */
-       unsigned short res22;
-       unsigned short bufstat;         /* 0xC0 */
-       unsigned short res23;
-};
-
 #define I2C_IP_CLK                     48000000
 #define I2C_INTERNAL_SAMPLING_CLK      12000000
 
index 5ddaa0d..b04c012 100644 (file)
@@ -8,51 +8,4 @@
 
 #define I2C_DEFAULT_BASE       I2C_BASE1
 
-struct i2c {
-       unsigned short rev;     /* 0x00 */
-       unsigned short res1;
-       unsigned short ie;      /* 0x04 */
-       unsigned short res2;
-       unsigned short stat;    /* 0x08 */
-       unsigned short res3;
-       unsigned short we;      /* 0x0C */
-       unsigned short res4;
-       unsigned short syss;    /* 0x10 */
-       unsigned short res4a;
-       unsigned short buf;     /* 0x14 */
-       unsigned short res5;
-       unsigned short cnt;     /* 0x18 */
-       unsigned short res6;
-       unsigned short data;    /* 0x1C */
-       unsigned short res7;
-       unsigned short sysc;    /* 0x20 */
-       unsigned short res8;
-       unsigned short con;     /* 0x24 */
-       unsigned short res9;
-       unsigned short oa;      /* 0x28 */
-       unsigned short res10;
-       unsigned short sa;      /* 0x2C */
-       unsigned short res11;
-       unsigned short psc;     /* 0x30 */
-       unsigned short res12;
-       unsigned short scll;    /* 0x34 */
-       unsigned short res13;
-       unsigned short sclh;    /* 0x38 */
-       unsigned short res14;
-       unsigned short systest; /* 0x3c */
-       unsigned short res15;
-       unsigned short bufstat; /* 0x40 */
-       unsigned short res16;
-       unsigned short oa1;     /* 0x44 */
-       unsigned short res17;
-       unsigned short oa2;     /* 0x48 */
-       unsigned short res18;
-       unsigned short oa3;     /* 0x4c */
-       unsigned short res19;
-       unsigned short actoa;   /* 0x50 */
-       unsigned short res20;
-       unsigned short sblock;  /* 0x54 */
-       unsigned short res21;
-};
-
 #endif /* _OMAP3_I2C_H_ */
index c60aac7..c8f2f97 100644 (file)
@@ -8,49 +8,4 @@
 
 #define I2C_DEFAULT_BASE       I2C_BASE1
 
-struct i2c {
-       unsigned short revnb_lo;        /* 0x00 */
-       unsigned short res1;
-       unsigned short revnb_hi;        /* 0x04 */
-       unsigned short res2[5];
-       unsigned short sysc;            /* 0x10 */
-       unsigned short res3[9];
-       unsigned short irqstatus_raw;   /* 0x24 */
-       unsigned short res4;
-       unsigned short stat;            /* 0x28 */
-       unsigned short res5;
-       unsigned short ie;              /* 0x2C */
-       unsigned short res6;
-       unsigned short irqenable_clr;   /* 0x30 */
-       unsigned short res7;
-       unsigned short iv;              /* 0x34 */
-       unsigned short res8[45];
-       unsigned short syss;            /* 0x90 */
-       unsigned short res9;
-       unsigned short buf;             /* 0x94 */
-       unsigned short res10;
-       unsigned short cnt;             /* 0x98 */
-       unsigned short res11;
-       unsigned short data;            /* 0x9C */
-       unsigned short res13;
-       unsigned short res14;           /* 0xA0 */
-       unsigned short res15;
-       unsigned short con;             /* 0xA4 */
-       unsigned short res16;
-       unsigned short oa;              /* 0xA8 */
-       unsigned short res17;
-       unsigned short sa;              /* 0xAC */
-       unsigned short res18;
-       unsigned short psc;             /* 0xB0 */
-       unsigned short res19;
-       unsigned short scll;            /* 0xB4 */
-       unsigned short res20;
-       unsigned short sclh;            /* 0xB8 */
-       unsigned short res21;
-       unsigned short systest;         /* 0xBC */
-       unsigned short res22;
-       unsigned short bufstat;         /* 0xC0 */
-       unsigned short res23;
-};
-
 #endif /* _OMAP4_I2C_H_ */
index 60e2b4b..9e1edcf 100644 (file)
@@ -8,49 +8,4 @@
 
 #define I2C_DEFAULT_BASE       I2C_BASE1
 
-struct i2c {
-       unsigned short revnb_lo;        /* 0x00 */
-       unsigned short res1;
-       unsigned short revnb_hi;        /* 0x04 */
-       unsigned short res2[5];
-       unsigned short sysc;            /* 0x10 */
-       unsigned short res3[9];
-       unsigned short irqstatus_raw;   /* 0x24 */
-       unsigned short res4;
-       unsigned short stat;            /* 0x28 */
-       unsigned short res5;
-       unsigned short ie;              /* 0x2C */
-       unsigned short res6;
-       unsigned short irqenable_clr;   /* 0x30 */
-       unsigned short res7;
-       unsigned short iv;              /* 0x34 */
-       unsigned short res8[45];
-       unsigned short syss;            /* 0x90 */
-       unsigned short res9;
-       unsigned short buf;             /* 0x94 */
-       unsigned short res10;
-       unsigned short cnt;             /* 0x98 */
-       unsigned short res11;
-       unsigned short data;            /* 0x9C */
-       unsigned short res13;
-       unsigned short res14;           /* 0xA0 */
-       unsigned short res15;
-       unsigned short con;             /* 0xA4 */
-       unsigned short res16;
-       unsigned short oa;              /* 0xA8 */
-       unsigned short res17;
-       unsigned short sa;              /* 0xAC */
-       unsigned short res18;
-       unsigned short psc;             /* 0xB0 */
-       unsigned short res19;
-       unsigned short scll;            /* 0xB4 */
-       unsigned short res20;
-       unsigned short sclh;            /* 0xB8 */
-       unsigned short res21;
-       unsigned short systest;         /* 0xBC */
-       unsigned short res22;
-       unsigned short bufstat;         /* 0xC0 */
-       unsigned short res23;
-};
-
 #endif /* _OMAP5_I2C_H_ */
diff --git a/arch/arm/include/asm/omap_i2c.h b/arch/arm/include/asm/omap_i2c.h
new file mode 100644 (file)
index 0000000..c1695cb
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _OMAP_I2C_H
+#define _OMAP_I2C_H
+
+#include <asm/arch/cpu.h>
+
+#ifdef CONFIG_DM_I2C
+
+/* Information about a GPIO bank */
+struct omap_i2c_platdata {
+       ulong base;     /* address of registers in physical memory */
+       int speed;
+       int ip_rev;
+};
+
+#endif
+
+enum {
+       OMAP_I2C_REV_V1 = 0,
+       OMAP_I2C_REV_V2 = 1,
+};
+
+#endif /* _OMAP_I2C_H */
index 2613092..6eee9ad 100644 (file)
@@ -403,6 +403,7 @@ static void init_ddr3param(struct ddr3_spd_cb *spd_cb,
 static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params)
 {
        int ret;
+#ifndef CONFIG_DM_I2C
        int old_bus;
 
        i2c_init(CONFIG_SYS_DAVINCI_I2C_SPEED, CONFIG_SYS_DAVINCI_I2C_SLAVE);
@@ -413,7 +414,13 @@ static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params)
        ret = i2c_read(0x53, 0, 1, (unsigned char *)spd_params, 256);
 
        i2c_set_bus_num(old_bus);
+#else
+       struct udevice *dev;
 
+       ret = i2c_get_chip_for_busnum(1, 0x53, 1, &dev);
+       if (!ret)
+               ret = dm_i2c_read(dev, 0, (unsigned char *)spd_params, 256);
+#endif
        if (ret) {
                printf("Cannot read DIMM params\n");
                return 1;
index f5f2bd5..2fc364d 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/arch/ddr_defs.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/i2c.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
@@ -93,6 +94,20 @@ U_BOOT_DEVICES(am33xx_uarts) = {
 #  endif
 };
 
+#ifdef CONFIG_DM_I2C
+static const struct omap_i2c_platdata am33xx_i2c[] = {
+       { I2C_BASE1, 100000, OMAP_I2C_REV_V2},
+       { I2C_BASE2, 100000, OMAP_I2C_REV_V2},
+       { I2C_BASE3, 100000, OMAP_I2C_REV_V2},
+};
+
+U_BOOT_DEVICES(am33xx_i2c) = {
+       { "i2c_omap", &am33xx_i2c[0] },
+       { "i2c_omap", &am33xx_i2c[1] },
+       { "i2c_omap", &am33xx_i2c[2] },
+};
+#endif
+
 #ifdef CONFIG_DM_GPIO
 static const struct omap_gpio_platdata am33xx_gpio[] = {
        { 0, AM33XX_GPIO0_BASE },
@@ -457,12 +472,15 @@ void early_system_init(void)
 #ifdef CONFIG_DEBUG_UART_OMAP
        debug_uart_init();
 #endif
-#ifdef CONFIG_TI_I2C_BOARD_DETECT
-       do_board_detect();
-#endif
+
 #ifdef CONFIG_SPL_BUILD
        spl_early_init();
 #endif
+
+#ifdef CONFIG_TI_I2C_BOARD_DETECT
+       do_board_detect();
+#endif
+
 #if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
        /* Enable RTC32K clock */
        rtc32k_enable();
index 0e7ad1d..ff1bfaf 100644 (file)
@@ -14,6 +14,7 @@
 
 /**
  * clk_synthesizer_reg_read - Read register from synthesizer.
+ * dev:                i2c bus device (not used if CONFIG_DM_I2C is not set)
  * @addr:      addr within the i2c device
  * buf:                Buffer to which value is to be read.
  *
  * be send along with enabling byte read more, and then read can happen.
  * Returns 0 on success
  */
-static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
+static int clk_synthesizer_reg_read(struct udevice *dev, int addr, u8 *buf)
 {
        int rc;
 
        /* Enable Bye read */
        addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
 
+#ifndef CONFIG_DM_I2C
        /* Send the command byte */
        rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
        if (rc)
@@ -35,26 +37,46 @@ static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
 
        /* Read the Data */
        return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
+#else
+       /* Send the command byte */
+       rc = dm_i2c_reg_write(dev, addr, *buf);
+       if (rc)
+               printf("Failed to send command to clock synthesizer\n");
+
+       /* Read the Data */
+       rc = dm_i2c_reg_read(dev, addr);
+       if (rc < 0)
+               return rc;
+
+       *buf = (u8)rc;
+       return 0;
+#endif
+
 }
 
 /**
  * clk_synthesizer_reg_write - Write a value to register in synthesizer.
+ * dev:                i2c bus device (not used if CONFIG_DM_I2C is not set)
  * @addr:      addr within the i2c device
  * val:                Value to be written in the addr.
  *
  * Enable the byte read mode in the address and start the i2c transfer.
  * Returns 0 on success
  */
-static int clk_synthesizer_reg_write(int addr, uint8_t val)
+static int clk_synthesizer_reg_write(struct udevice *dev, int addr, u8 val)
 {
-       uint8_t cmd[2];
+       u8 cmd[2];
        int rc = 0;
 
        /* Enable byte write */
        cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
        cmd[1] = val;
 
+#ifndef CONFIG_DM_I2C
        rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
+#else
+       rc = dm_i2c_write(dev, addr, cmd, 2);
+#endif
        if (rc)
                printf("Clock synthesizer reg write failed at addr = 0x%x\n",
                       addr);
@@ -72,30 +94,42 @@ static int clk_synthesizer_reg_write(int addr, uint8_t val)
 int setup_clock_synthesizer(struct clk_synth *data)
 {
        int rc;
-       uint8_t val;
-
+       u8 val = 0;
+       struct udevice *dev = NULL;
+#ifndef CONFIG_DM_I2C
        rc =  i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
        if (rc) {
                printf("i2c probe failed at address 0x%x\n",
                       CLK_SYNTHESIZER_I2C_ADDR);
                return rc;
        }
-
-       rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
+#else
+       rc = i2c_get_chip_for_busnum(0, CLK_SYNTHESIZER_I2C_ADDR, 1, &dev);
+       if (rc) {
+               printf("failed to get device for synthesizer at address 0x%x\n",
+                      CLK_SYNTHESIZER_I2C_ADDR);
+               return rc;
+       }
+#endif
+       rc = clk_synthesizer_reg_read(dev, CLK_SYNTHESIZER_ID_REG, &val);
        if (val != data->id)
                return rc;
 
        /* Crystal Load capacitor selection */
-       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
+       rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_XCSEL,
+                                      data->capacitor);
        if (rc)
                return rc;
-       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
+       rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_MUX_REG,
+                                      data->mux);
        if (rc)
                return rc;
-       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
+       rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV2_REG,
+                                      data->pdiv2);
        if (rc)
                return rc;
-       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
+       rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV3_REG,
+                                      data->pdiv3);
        if (rc)
                return rc;
 
index 790548e..5932d69 100644 (file)
@@ -909,6 +909,7 @@ void prcm_init(void)
                enable_basic_uboot_clocks();
 }
 
+#if !defined(CONFIG_DM_I2C)
 void gpi2c_init(void)
 {
        static int gpi2c = 1;
@@ -919,3 +920,4 @@ void gpi2c_init(void)
                gpi2c = 0;
        }
 }
+#endif
index 1a24acb..772b4c4 100644 (file)
@@ -12,6 +12,7 @@
  */
 #include <common.h>
 #include <debug_uart.h>
+#include <fdtdec.h>
 #include <spl.h>
 #include <asm/arch/sys_proto.h>
 #include <linux/sizes.h>
@@ -19,6 +20,7 @@
 #include <asm/omap_common.h>
 #include <linux/compiler.h>
 #include <asm/system.h>
+#include <dm/root.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -171,6 +173,10 @@ void __weak init_package_revision(void)
  */
 void early_system_init(void)
 {
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_MULTI_DTB_FIT)
+       int ret;
+       int rescan;
+#endif
        init_omap_revision();
        hw_data_init();
        init_package_revision();
@@ -186,6 +192,7 @@ void early_system_init(void)
        do_io_settings();
 #endif
        setup_early_clocks();
+
 #ifdef CONFIG_SPL_BUILD
        /*
         * Save the boot parameters passed from romcode.
@@ -193,11 +200,23 @@ void early_system_init(void)
         * to prevent overwrites.
         */
        save_omap_boot_params();
+       spl_early_init();
 #endif
        do_board_detect();
-#ifdef CONFIG_SPL_BUILD
-       spl_early_init();
+
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_MULTI_DTB_FIT)
+       /*
+        * Board detection has been done.
+        * Let us see if another dtb wouldn't be a better match
+        * for our board
+        */
+       ret = fdtdec_resetup(&rescan);
+       if (!ret && rescan) {
+               dm_uninit();
+               dm_init_and_scan(true);
+       }
 #endif
+
        vcores_init();
 #ifdef CONFIG_DEBUG_UART_OMAP
        debug_uart_init();
index b4b8081..b857a5a 100644 (file)
@@ -209,7 +209,6 @@ void am33xx_spl_board_init(void)
 const struct dpll_params *get_dpll_ddr_params(void)
 {
        enable_i2c0_pin_mux();
-       i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
 
        return &dpll_ddr;
 }
index 1384525..d67f94a 100644 (file)
@@ -70,8 +70,9 @@ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 void do_board_detect(void)
 {
        enable_i2c0_pin_mux();
+#ifndef CONFIG_DM_I2C
        i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
-
+#endif
        if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
                                 CONFIG_EEPROM_CHIP_ADDRESS))
                printf("ti_i2c_eeprom_init failed\n");
@@ -328,8 +329,14 @@ static void scale_vcores_bone(int freq)
        if (board_is_bone() && !strncmp(board_ti_get_rev(), "00A1", 4))
                return;
 
+#ifndef CONFIG_DM_I2C
        if (i2c_probe(TPS65217_CHIP_PM))
                return;
+#else
+       if (power_tps65217_init(0))
+               return;
+#endif
+
 
        /*
         * On Beaglebone White we need to ensure we have AC power
@@ -421,9 +428,13 @@ void scale_vcores_generic(int freq)
         * 1.10V.  For MPU voltage we need to switch based on
         * the frequency we are running at.
         */
+#ifndef CONFIG_DM_I2C
        if (i2c_probe(TPS65910_CTRL_I2C_ADDR))
                return;
-
+#else
+       if (power_tps65910_init(0))
+               return;
+#endif
        /*
         * Depending on MPU clock and PG we will need a different
         * VDD to drive at that speed.
@@ -451,8 +462,10 @@ void gpi2c_init(void)
 
        if (first_time) {
                enable_i2c0_pin_mux();
+#ifndef CONFIG_DM_I2C
                i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
                         CONFIG_SYS_OMAP24_I2C_SLAVE);
+#endif
                first_time = false;
        }
 }
index 41333f9..04f4b8e 100644 (file)
@@ -329,12 +329,23 @@ static unsigned short detect_daughter_board_profile(void)
 {
        unsigned short val;
 
+#ifndef CONFIG_DM_I2C
        if (i2c_probe(I2C_CPLD_ADDR))
                return PROFILE_NONE;
 
        if (i2c_read(I2C_CPLD_ADDR, CFG_REG, 1, (unsigned char *)(&val), 2))
                return PROFILE_NONE;
+#else
+       struct udevice *dev = NULL;
+       int rc;
 
+       rc = i2c_get_chip_for_busnum(0, I2C_CPLD_ADDR, 1, &dev);
+       if (rc)
+               return PROFILE_NONE;
+       rc = dm_i2c_read(dev, CFG_REG, (unsigned char *)(&val), 2);
+       if (rc)
+               return PROFILE_NONE;
+#endif
        return (1 << (val & PROFILE_MASK));
 }
 
index 2a59b06..31bc0f4 100644 (file)
@@ -43,6 +43,8 @@ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 #ifdef CONFIG_TI_I2C_BOARD_DETECT
 void do_board_detect(void)
 {
+       /* Ensure I2C is initialized for EEPROM access*/
+       gpi2c_init();
        if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
                                 CONFIG_EEPROM_CHIP_ADDRESS))
                printf("ti_i2c_eeprom_init failed\n");
@@ -386,8 +388,13 @@ void scale_vcores_generic(u32 m)
 {
        int mpu_vdd, ddr_volt;
 
+#ifndef CONFIG_DM_I2C
        if (i2c_probe(TPS65218_CHIP_PM))
                return;
+#else
+       if (power_tps65218_init(0))
+               return;
+#endif
 
        switch (m) {
        case 1000:
@@ -439,8 +446,13 @@ void scale_vcores_idk(u32 m)
 {
        int mpu_vdd;
 
+#ifndef CONFIG_DM_I2C
        if (i2c_probe(TPS62362_I2C_ADDR))
                return;
+#else
+       if (power_tps62362_init(0))
+               return;
+#endif
 
        switch (m) {
        case 1000:
@@ -462,14 +474,12 @@ void scale_vcores_idk(u32 m)
                puts("Unknown MPU clock, not scaling\n");
                return;
        }
-
        /* Set VDD_MPU voltage */
        if (tps62362_voltage_update(TPS62362_SET3, mpu_vdd)) {
                printf("%s failure\n", __func__);
                return;
        }
 }
-
 void gpi2c_init(void)
 {
        /* When needed to be invoked prior to BSS initialization */
@@ -477,8 +487,10 @@ void gpi2c_init(void)
 
        if (first_time) {
                enable_i2c0_pin_mux();
+#ifndef CONFIG_DM_I2C
                i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
                         CONFIG_SYS_OMAP24_I2C_SLAVE);
+#endif
                first_time = false;
        }
 }
@@ -614,20 +626,32 @@ void sdram_init(void)
 /* setup board specific PMIC */
 int power_init_board(void)
 {
-       struct pmic *p;
-
+       int rc;
+#ifndef CONFIG_DM_I2C
+       struct pmic *p = NULL;
+#endif
        if (board_is_idk()) {
-               power_tps62362_init(I2C_PMIC);
+               rc = power_tps62362_init(0);
+               if (rc)
+                       goto done;
+#ifndef CONFIG_DM_I2C
                p = pmic_get("TPS62362");
-               if (p && !pmic_probe(p))
-                       puts("PMIC:  TPS62362\n");
+               if (!p || pmic_probe(p))
+                       goto done;
+#endif
+               puts("PMIC:  TPS62362\n");
        } else {
-               power_tps65218_init(I2C_PMIC);
+               rc = power_tps65218_init(0);
+               if (rc)
+                       goto done;
+#ifndef CONFIG_DM_I2C
                p = pmic_get("TPS65218_PMIC");
-               if (p && !pmic_probe(p))
-                       puts("PMIC:  TPS65218\n");
+               if (!p || pmic_probe(p))
+                       goto done;
+#endif
+               puts("PMIC:  TPS65218\n");
        }
-
+done:
        return 0;
 }
 
index 8dfb2ee..7063345 100644 (file)
@@ -623,7 +623,7 @@ void am57x_idk_lcd_detect(void)
 {
        int r = -ENODEV;
        char *idk_lcd = "no";
-       uint8_t buf = 0;
+       struct udevice *dev;
 
        /* Only valid for IDKs */
        if (board_is_x15() || board_is_am572x_evm())
@@ -633,32 +633,29 @@ void am57x_idk_lcd_detect(void)
        if (board_is_am571x_idk() && !am571x_idk_needs_lcd())
                goto out;
 
-       r = i2c_set_bus_num(OSD_TS_FT_BUS_ADDRESS);
-       if (r) {
-               printf("%s: Failed to set bus address to %d: %d\n",
-                      __func__, OSD_TS_FT_BUS_ADDRESS, r);
-               goto out;
-       }
-       r = i2c_probe(OSD_TS_FT_CHIP_ADDRESS);
+       r = i2c_get_chip_for_busnum(OSD_TS_FT_BUS_ADDRESS,
+                                   OSD_TS_FT_CHIP_ADDRESS, 1, &dev);
        if (r) {
+               printf("%s: Failed to get I2C device %d/%d (ret %d)\n",
+                      __func__, OSD_TS_FT_BUS_ADDRESS, OSD_TS_FT_CHIP_ADDRESS,
+                      r);
                /* AM572x IDK has no explicit settings for optional LCD kit */
-               if (board_is_am571x_idk()) {
+               if (board_is_am571x_idk())
                        printf("%s: Touch screen detect failed: %d!\n",
                               __func__, r);
-               }
                goto out;
        }
 
        /* Read FT ID */
-       r = i2c_read(OSD_TS_FT_CHIP_ADDRESS, OSD_TS_FT_REG_ID, 1, &buf, 1);
-       if (r) {
+       r = dm_i2c_reg_read(dev, OSD_TS_FT_REG_ID);
+       if (r < 0) {
                printf("%s: Touch screen ID read %d:0x%02x[0x%02x] failed:%d\n",
                       __func__, OSD_TS_FT_BUS_ADDRESS, OSD_TS_FT_CHIP_ADDRESS,
                       OSD_TS_FT_REG_ID, r);
                goto out;
        }
 
-       switch (buf) {
+       switch (r) {
        case OSD_TS_FT_ID_5606:
                idk_lcd = "osd101t2045";
                break;
@@ -667,7 +664,7 @@ void am57x_idk_lcd_detect(void)
                break;
        default:
                printf("%s: Unidentifed Touch screen ID 0x%02x\n",
-                      __func__, buf);
+                      __func__, r);
                /* we will let default be "no lcd" */
        }
 out:
index c475f10..e258e22 100644 (file)
 
 #include "board_detect.h"
 
-#if defined(CONFIG_DM_I2C_COMPAT)
-/**
- * ti_i2c_set_alen - Set chip's i2c address length
- * @bus_addr - I2C bus number
- * @dev_addr - I2C eeprom id
- * @alen     - I2C address length in bytes
- *
- * DM_I2C by default sets the address length to be used to 1. This
- * function allows this address length to be changed to match the
- * eeprom used for board detection.
- */
-int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
-{
-       struct udevice *dev;
-       struct udevice *bus;
-       int rc;
-
-       rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
-       if (rc)
-               return rc;
-       rc = i2c_get_chip(bus, dev_addr, 1, &dev);
-       if (rc)
-               return rc;
-       rc = i2c_set_chip_offset_len(dev, alen);
-       if (rc)
-               return rc;
-
-       return 0;
-}
-#else
-int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
-{
-       return 0;
-}
-#endif
-
+#if !defined(CONFIG_DM_I2C)
 /**
  * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
  * @i2c_bus: i2c bus number to initialize
@@ -82,18 +47,9 @@ static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
 static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
                                             uchar *ep, int epsize)
 {
-       int bus_num, rc, alen;
-
-       bus_num = i2c_get_bus_num();
-
-       alen = 2;
-
-       rc = ti_i2c_set_alen(bus_num, dev_addr, alen);
-       if (rc)
-               return rc;
-
-       return i2c_read(dev_addr, offset, alen, ep, epsize);
+       return i2c_read(dev_addr, offset, 2, ep, epsize);
 }
+#endif
 
 /**
  * ti_eeprom_string_cleanup() - Handle eeprom programming errors
@@ -122,23 +78,67 @@ __weak void gpi2c_init(void)
 static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
                                            u32 header, u32 size, uint8_t *ep)
 {
-       u32 byte, hdr_read;
+       u32 hdr_read;
        int rc;
 
-       gpi2c_init();
-       rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
+#if defined(CONFIG_DM_I2C)
+       struct udevice *dev;
+       struct udevice *bus;
+
+       rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
+       if (rc)
+               return rc;
+       rc = i2c_get_chip(bus, dev_addr, 1, &dev);
        if (rc)
                return rc;
 
        /*
         * Read the header first then only read the other contents.
         */
-       byte = 2;
+       rc = i2c_set_chip_offset_len(dev, 2);
+       if (rc)
+               return rc;
+
+       rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
+       if (rc)
+               return rc;
+
+       /* Corrupted data??? */
+       if (hdr_read != header) {
+               rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
+               /*
+                * read the eeprom header using i2c again, but use only a
+                * 1 byte address (some legacy boards need this..)
+                */
+               if (rc) {
+                       rc =  i2c_set_chip_offset_len(dev, 1);
+                       if (rc)
+                               return rc;
+
+                       rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
+               }
+               if (rc)
+                       return rc;
+       }
+       if (hdr_read != header)
+               return -1;
+
+       rc = dm_i2c_read(dev, 0, ep, size);
+       if (rc)
+               return rc;
+#else
+       u32 byte;
 
-       rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
+       gpi2c_init();
+       rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
        if (rc)
                return rc;
 
+       /*
+        * Read the header first then only read the other contents.
+        */
+       byte = 2;
+
        rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
        if (rc)
                return rc;
@@ -152,10 +152,6 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
                 */
                byte = 1;
                if (rc) {
-                       rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
-                       if (rc)
-                               return rc;
-
                        rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
                                      4);
                }
@@ -168,7 +164,7 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
        rc = i2c_read(dev_addr, 0x0, byte, ep, size);
        if (rc)
                return rc;
-
+#endif
        return 0;
 }
 
index 87dc4d0..39a782e 100644 (file)
@@ -251,6 +251,7 @@ int board_fit_config_name_match(const char *name)
 #if defined(CONFIG_DTB_RESELECT)
 static int k2g_alt_board_detect(void)
 {
+#ifndef CONFIG_DM_I2C
        int rc;
 
        rc = i2c_set_bus_num(1);
@@ -260,7 +261,17 @@ static int k2g_alt_board_detect(void)
        rc = i2c_probe(K2G_GP_AUDIO_CODEC_ADDRESS);
        if (rc)
                return rc;
+#else
+       struct udevice *bus, *dev;
+       int rc;
 
+       rc = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus);
+       if (rc)
+               return rc;
+       rc = dm_i2c_probe(bus, K2G_GP_AUDIO_CODEC_ADDRESS, 0, &dev);
+       if (rc)
+               return rc;
+#endif
        ti_i2c_eeprom_am_set("66AK2GGP", "1.0X");
 
        return 0;
index b1cd1c9..ea1a325 100644 (file)
@@ -445,6 +445,7 @@ config CRC32_VERIFY
 
 config CMD_EEPROM
        bool "eeprom - EEPROM subsystem"
+       depends on !DM_I2C || DM_I2C_COMPAT
        help
          (deprecated, needs conversion to driver model)
          Provides commands to read and write EEPROM (Electrically Erasable
index 56df8eb..09c4ba9 100644 (file)
--- a/cmd/i2c.c
+++ b/cmd/i2c.c
@@ -2023,6 +2023,7 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 static char i2c_help_text[] =
 #if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
        "bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
+       "i2c " /* That's the prefix for the crc32 command below. */
 #endif
        "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
 #if defined(CONFIG_SYS_I2C) || \
index 3cb38af..dc8094e 100644 (file)
@@ -36,6 +36,7 @@ CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-pdu001"
 # CONFIG_NET is not set
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_BLK=y
index 32a95ea..aa82830 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SCSI_AHCI=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
index 6a05738..09f3774 100644 (file)
@@ -40,6 +40,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SCSI_AHCI=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
index 1d9509c..2b6606f 100644 (file)
@@ -1,7 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_TI_COMMON_CMD_OPTIONS=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x18000
 CONFIG_OMAP54XX=y
 CONFIG_TARGET_DRA7XX_EVM=y
 CONFIG_SPL=y
@@ -34,11 +34,13 @@ CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="dra7-evm"
 CONFIG_OF_LIST="dra7-evm dra72-evm dra72-evm-revc dra71-evm dra76-evm"
 CONFIG_SPL_MULTI_DTB_FIT=y
+CONFIG_SPL_MULTI_DTB_FIT_UNCOMPRESS_SZ=0x9000
 CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_DEVICE_REMOVE=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SPL_SYSCON=y
index f3be339..725acb5 100644 (file)
@@ -41,6 +41,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SPL_SYSCON=y
 CONFIG_DWC_AHCI=y
index 969387a..3197259 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-37xx-devkit"
 # CONFIG_ENV_IS_IN_FAT is not set
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_DM_I2C=y
index d6ab7bf..446401c 100644 (file)
@@ -184,6 +184,24 @@ The full device tree is available to U-Boot proper, but normally only a subset
 'SPL Support' in doc/driver-model/README.txt for more details.
 
 
+Using several DTBs in the SPL (CONFIG_SPL_MULTI_DTB)
+----------------------------------------------------
+In some rare cases it is desirable to let SPL be able to select one DTB among
+many. This usually not very useful as the DTB for the SPL is small and usually
+fits several platforms. However the DTB sometimes include information that do
+work on several platforms (like IO tuning parameters).
+In this case it is possible to use CONFIG_SPL_MULTI_DTB. This option appends to
+the SPL a FIT image containing several DTBs listed in SPL_OF_LIST.
+board_fit_config_name_match() is called to select the right DTB.
+
+If board_fit_config_name_match() relies on DM (DM driver to access an EEPROM
+containing the board ID for example), it possible to start with a generic DTB
+and then switch over to the right DTB after the detection. For this purpose,
+the platform code must call fdtdec_resetup(). Based on the returned flag, the
+platform may have to re-initiliaze the DM subusystem using dm_uninit() and
+dm_init_and_scan().
+
+
 Limitations
 -----------
 
index e8ba20c..046b87a 100644 (file)
@@ -57,13 +57,21 @@ config DM_DEVICE_REMOVE
        default y
        help
          We can save some code space by dropping support for removing a
-         device. This is not normally required in SPL, so by default this
-         option is disabled for SPL.
+         device.
 
          Note that this may have undesirable results in the USB subsystem as
          it causes unplugged devices to linger around in the dm-tree, and it
          causes USB host controllers to not be stopped when booting the OS.
 
+config SPL_DM_DEVICE_REMOVE
+       bool "Support device removal in SPL"
+       depends on SPL_DM
+       default n
+       help
+         We can save some code space by dropping support for removing a
+         device. This is not normally required in SPL, so by default this
+         option is disabled for SPL.
+
 config DM_STDIO
        bool "Support stdio registration"
        depends on DM
index 836bcad..0d15e50 100644 (file)
@@ -70,7 +70,8 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 
        dev->seq = -1;
        dev->req_seq = -1;
-       if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS)) {
+       if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
+           (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
                /*
                 * Some devices, such as a SPI bus, I2C bus and serial ports
                 * are numbered using aliases.
@@ -78,10 +79,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
                 * This is just a 'requested' sequence, and will be
                 * resolved (and ->seq updated) when the device is probed.
                 */
-               if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
-                       if (uc->uc_drv->name && ofnode_valid(node)) {
+               if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
+                       if (uc->uc_drv->name && ofnode_valid(node))
                                dev_read_alias_seq(dev, &dev->req_seq);
-                       }
+               } else {
+                       dev->req_seq = uclass_find_next_free_req_seq(drv->id);
                }
        }
 
index 4ce55f9..e6ec7fa 100644 (file)
@@ -187,6 +187,7 @@ int dm_uninit(void)
 {
        device_remove(dm_root(), DM_REMOVE_NORMAL);
        device_unbind(dm_root());
+       gd->dm_root = NULL;
 
        return 0;
 }
index 9766aea..a622f07 100644 (file)
@@ -269,6 +269,30 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
        return -ENODEV;
 }
 
+#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA)
+int uclass_find_next_free_req_seq(enum uclass_id id)
+{
+       struct uclass *uc;
+       struct udevice *dev;
+       int ret;
+       int max = -1;
+
+       ret = uclass_get(id, &uc);
+       if (ret)
+               return ret;
+
+       list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+               if ((dev->req_seq != -1) && (dev->req_seq > max))
+                       max = dev->req_seq;
+       }
+
+       if (max == -1)
+               return 0;
+
+       return max + 1;
+}
+#endif
+
 int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
                              bool find_req_seq, struct udevice **devp)
 {
index c5a3c4e..975318e 100644 (file)
@@ -347,6 +347,17 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
                debug("Cannot find I2C bus %d\n", busnum);
                return ret;
        }
+
+       /* detect the presence of the chip on the bus */
+       ret = i2c_probe_chip(bus, chip_addr, 0);
+       debug("%s: bus='%s', address %02x, ret=%d\n", __func__, bus->name,
+             chip_addr, ret);
+       if (ret) {
+               debug("Cannot detect I2C chip %02x on bus %d\n", chip_addr,
+                     busnum);
+               return ret;
+       }
+
        ret = i2c_get_chip(bus, chip_addr, offset_len, devp);
        if (ret) {
                debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
index 51f9237..4b93e02 100644 (file)
 #include <dm.h>
 #include <i2c.h>
 
-#include <asm/arch/i2c.h>
 #include <asm/io.h>
+#include <asm/omap_i2c.h>
+
+/*
+ * Provide access to architecture-specific I2C header files for platforms
+ * that are NOT yet solely relying on CONFIG_DM_I2C, CONFIG_OF_CONTROL, and
+ * the defaults provided in 'omap24xx_i2c.h' for all U-Boot stages where I2C
+ * access is desired.
+ */
+#ifndef CONFIG_ARCH_K3
+#include <asm/arch/i2c.h>
+#endif
 
 #include "omap24xx_i2c.h"
 
 /* Absolutely safe for status update at 100 kHz I2C: */
 #define I2C_WAIT       200
 
+enum {
+       OMAP_I2C_REV_REG = 0,           /* Only on IP V1 (OMAP34XX) */
+       OMAP_I2C_IE_REG,                /* Only on IP V1 (OMAP34XX) */
+       OMAP_I2C_STAT_REG,
+       OMAP_I2C_WE_REG,
+       OMAP_I2C_SYSS_REG,
+       OMAP_I2C_BUF_REG,
+       OMAP_I2C_CNT_REG,
+       OMAP_I2C_DATA_REG,
+       OMAP_I2C_SYSC_REG,
+       OMAP_I2C_CON_REG,
+       OMAP_I2C_OA_REG,
+       OMAP_I2C_SA_REG,
+       OMAP_I2C_PSC_REG,
+       OMAP_I2C_SCLL_REG,
+       OMAP_I2C_SCLH_REG,
+       OMAP_I2C_SYSTEST_REG,
+       OMAP_I2C_BUFSTAT_REG,
+       /* Only on IP V2 (OMAP4430, etc.) */
+       OMAP_I2C_IP_V2_REVNB_LO,
+       OMAP_I2C_IP_V2_REVNB_HI,
+       OMAP_I2C_IP_V2_IRQSTATUS_RAW,
+       OMAP_I2C_IP_V2_IRQENABLE_SET,
+       OMAP_I2C_IP_V2_IRQENABLE_CLR,
+};
+
+static const u8 __maybe_unused reg_map_ip_v1[] = {
+       [OMAP_I2C_REV_REG] = 0x00,
+       [OMAP_I2C_IE_REG] = 0x04,
+       [OMAP_I2C_STAT_REG] = 0x08,
+       [OMAP_I2C_WE_REG] = 0x0c,
+       [OMAP_I2C_SYSS_REG] = 0x10,
+       [OMAP_I2C_BUF_REG] = 0x14,
+       [OMAP_I2C_CNT_REG] = 0x18,
+       [OMAP_I2C_DATA_REG] = 0x1c,
+       [OMAP_I2C_SYSC_REG] = 0x20,
+       [OMAP_I2C_CON_REG] = 0x24,
+       [OMAP_I2C_OA_REG] = 0x28,
+       [OMAP_I2C_SA_REG] = 0x2c,
+       [OMAP_I2C_PSC_REG] = 0x30,
+       [OMAP_I2C_SCLL_REG] = 0x34,
+       [OMAP_I2C_SCLH_REG] = 0x38,
+       [OMAP_I2C_SYSTEST_REG] = 0x3c,
+       [OMAP_I2C_BUFSTAT_REG] = 0x40,
+};
+
+static const u8 __maybe_unused reg_map_ip_v2[] = {
+       [OMAP_I2C_STAT_REG] = 0x28,
+       [OMAP_I2C_WE_REG] = 0x34,
+       [OMAP_I2C_SYSS_REG] = 0x90,
+       [OMAP_I2C_BUF_REG] = 0x94,
+       [OMAP_I2C_CNT_REG] = 0x98,
+       [OMAP_I2C_DATA_REG] = 0x9c,
+       [OMAP_I2C_SYSC_REG] = 0x10,
+       [OMAP_I2C_CON_REG] = 0xa4,
+       [OMAP_I2C_OA_REG] = 0xa8,
+       [OMAP_I2C_SA_REG] = 0xac,
+       [OMAP_I2C_PSC_REG] = 0xb0,
+       [OMAP_I2C_SCLL_REG] = 0xb4,
+       [OMAP_I2C_SCLH_REG] = 0xb8,
+       [OMAP_I2C_SYSTEST_REG] = 0xbc,
+       [OMAP_I2C_BUFSTAT_REG] = 0xc0,
+       [OMAP_I2C_IP_V2_REVNB_LO] = 0x00,
+       [OMAP_I2C_IP_V2_REVNB_HI] = 0x04,
+       [OMAP_I2C_IP_V2_IRQSTATUS_RAW] = 0x24,
+       [OMAP_I2C_IP_V2_IRQENABLE_SET] = 0x2c,
+       [OMAP_I2C_IP_V2_IRQENABLE_CLR] = 0x30,
+};
+
 struct omap_i2c {
        struct udevice *clk;
+       int ip_rev;
        struct i2c *regs;
        unsigned int speed;
        int waitdelay;
        int clk_id;
 };
 
+static inline const u8 *omap_i2c_get_ip_reg_map(int ip_rev)
+{
+       switch (ip_rev) {
+       case OMAP_I2C_REV_V1:
+               return reg_map_ip_v1;
+       case OMAP_I2C_REV_V2:
+               /* Fall through... */
+       default:
+               return reg_map_ip_v2;
+       }
+}
+
+static inline void omap_i2c_write_reg(void __iomem *base, int ip_rev,
+                                     u16 val, int reg)
+{
+       writew(val, base + omap_i2c_get_ip_reg_map(ip_rev)[reg]);
+}
+
+static inline u16 omap_i2c_read_reg(void __iomem *base, int ip_rev, int reg)
+{
+       return readw(base + omap_i2c_get_ip_reg_map(ip_rev)[reg]);
+}
+
 static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
 {
        unsigned long internal_clk = 0, fclk;
@@ -114,29 +217,31 @@ static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
  * Wait for the bus to be free by checking the Bus Busy (BB)
  * bit to become clear
  */
-static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
+static int wait_for_bb(void __iomem *i2c_base, int ip_rev, int waitdelay)
 {
        int timeout = I2C_TIMEOUT;
+       int irq_stat_reg;
        u16 stat;
 
-       writew(0xFFFF, &i2c_base->stat);        /* clear current interrupts...*/
-#if defined(CONFIG_OMAP34XX)
-       while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
-#else
-       /* Read RAW status */
-       while ((stat = readw(&i2c_base->irqstatus_raw) &
+       irq_stat_reg = (ip_rev == OMAP_I2C_REV_V1) ?
+                      OMAP_I2C_STAT_REG : OMAP_I2C_IP_V2_IRQSTATUS_RAW;
+
+       /* clear current interrupts */
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
+
+       while ((stat = omap_i2c_read_reg(i2c_base, ip_rev, irq_stat_reg) &
                I2C_STAT_BB) && timeout--) {
-#endif
-               writew(stat, &i2c_base->stat);
+               omap_i2c_write_reg(i2c_base, ip_rev, stat, OMAP_I2C_STAT_REG);
                udelay(waitdelay);
        }
 
        if (timeout <= 0) {
-               printf("Timed out in wait_for_bb: status=%04x\n",
-                      stat);
+               printf("Timed out in %s: status=%04x\n", __func__, stat);
                return 1;
        }
-       writew(0xFFFF, &i2c_base->stat);         /* clear delayed stuff*/
+
+       /* clear delayed stuff */
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
        return 0;
 }
 
@@ -144,40 +249,37 @@ static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
  * Wait for the I2C controller to complete current action
  * and update status
  */
-static u16 wait_for_event(struct i2c *i2c_base, int waitdelay)
+static u16 wait_for_event(void __iomem *i2c_base, int ip_rev, int waitdelay)
 {
        u16 status;
        int timeout = I2C_TIMEOUT;
+       int irq_stat_reg;
 
+       irq_stat_reg = (ip_rev == OMAP_I2C_REV_V1) ?
+                      OMAP_I2C_STAT_REG : OMAP_I2C_IP_V2_IRQSTATUS_RAW;
        do {
                udelay(waitdelay);
-#if defined(CONFIG_OMAP34XX)
-               status = readw(&i2c_base->stat);
-#else
-               /* Read RAW status */
-               status = readw(&i2c_base->irqstatus_raw);
-#endif
+               status = omap_i2c_read_reg(i2c_base, ip_rev, irq_stat_reg);
        } while (!(status &
                   (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
                    I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
                    I2C_STAT_AL)) && timeout--);
 
        if (timeout <= 0) {
-               printf("Timed out in wait_for_event: status=%04x\n",
-                      status);
+               printf("Timed out in %s: status=%04x\n", __func__, status);
                /*
                 * If status is still 0 here, probably the bus pads have
                 * not been configured for I2C, and/or pull-ups are missing.
                 */
                printf("Check if pads/pull-ups of bus are properly configured\n");
-               writew(0xFFFF, &i2c_base->stat);
+               omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
                status = 0;
        }
 
        return status;
 }
 
-static void flush_fifo(struct i2c *i2c_base)
+static void flush_fifo(void __iomem *i2c_base, int ip_rev)
 {
        u16 stat;
 
@@ -186,17 +288,18 @@ static void flush_fifo(struct i2c *i2c_base)
         * you get a bus error
         */
        while (1) {
-               stat = readw(&i2c_base->stat);
+               stat = omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_STAT_REG);
                if (stat == I2C_STAT_RRDY) {
-                       readb(&i2c_base->data);
-                       writew(I2C_STAT_RRDY, &i2c_base->stat);
+                       omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_DATA_REG);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          I2C_STAT_RRDY, OMAP_I2C_STAT_REG);
                        udelay(1000);
                } else
                        break;
        }
 }
 
-static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
+static int __omap24_i2c_setspeed(void __iomem *i2c_base, int ip_rev, uint speed,
                                 int *waitdelay)
 {
        int psc, fsscll = 0, fssclh = 0;
@@ -248,79 +351,89 @@ static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
                }
        }
 
-       *waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
-       writew(0, &i2c_base->con);
-       writew(psc, &i2c_base->psc);
-       writew(scll, &i2c_base->scll);
-       writew(sclh, &i2c_base->sclh);
-       writew(I2C_CON_EN, &i2c_base->con);
-       writew(0xFFFF, &i2c_base->stat);        /* clear all pending status */
+       /* wait for 20 clkperiods */
+       *waitdelay = (10000000 / speed) * 2;
+
+       omap_i2c_write_reg(i2c_base, ip_rev, 0,  OMAP_I2C_CON_REG);
+       omap_i2c_write_reg(i2c_base, ip_rev, psc, OMAP_I2C_PSC_REG);
+       omap_i2c_write_reg(i2c_base, ip_rev, scll, OMAP_I2C_SCLL_REG);
+       omap_i2c_write_reg(i2c_base, ip_rev, sclh, OMAP_I2C_SCLH_REG);
+       omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN, OMAP_I2C_CON_REG);
+
+       /* clear all pending status */
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
 
        return 0;
 }
 
-static void omap24_i2c_deblock(struct i2c *i2c_base)
+static void omap24_i2c_deblock(void __iomem *i2c_base, int ip_rev)
 {
        int i;
        u16 systest;
        u16 orgsystest;
 
        /* set test mode ST_EN = 1 */
-       orgsystest = readw(&i2c_base->systest);
+       orgsystest = omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_SYSTEST_REG);
        systest = orgsystest;
+
        /* enable testmode */
        systest |= I2C_SYSTEST_ST_EN;
-       writew(systest, &i2c_base->systest);
+       omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
        systest &= ~I2C_SYSTEST_TMODE_MASK;
        systest |= 3 << I2C_SYSTEST_TMODE_SHIFT;
-       writew(systest, &i2c_base->systest);
+       omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
 
        /* set SCL, SDA  = 1 */
        systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O;
-       writew(systest, &i2c_base->systest);
+       omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
        udelay(10);
 
        /* toggle scl 9 clocks */
        for (i = 0; i < 9; i++) {
                /* SCL = 0 */
                systest &= ~I2C_SYSTEST_SCL_O;
-               writew(systest, &i2c_base->systest);
+               omap_i2c_write_reg(i2c_base, ip_rev,
+                                  systest, OMAP_I2C_SYSTEST_REG);
                udelay(10);
                /* SCL = 1 */
                systest |= I2C_SYSTEST_SCL_O;
-               writew(systest, &i2c_base->systest);
+               omap_i2c_write_reg(i2c_base, ip_rev,
+                                  systest, OMAP_I2C_SYSTEST_REG);
                udelay(10);
        }
 
        /* send stop */
        systest &= ~I2C_SYSTEST_SDA_O;
-       writew(systest, &i2c_base->systest);
+       omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
        udelay(10);
        systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O;
-       writew(systest, &i2c_base->systest);
+       omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
        udelay(10);
 
        /* restore original mode */
-       writew(orgsystest, &i2c_base->systest);
+       omap_i2c_write_reg(i2c_base, ip_rev, orgsystest, OMAP_I2C_SYSTEST_REG);
 }
 
-static void __omap24_i2c_init(struct i2c *i2c_base, int speed, int slaveadd,
-                             int *waitdelay)
+static void __omap24_i2c_init(void __iomem *i2c_base, int ip_rev, int speed,
+                             int slaveadd, int *waitdelay)
 {
        int timeout = I2C_TIMEOUT;
        int deblock = 1;
 
 retry:
-       if (readw(&i2c_base->con) & I2C_CON_EN) {
-               writew(0, &i2c_base->con);
+       if (omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_CON_REG) &
+           I2C_CON_EN) {
+               omap_i2c_write_reg(i2c_base, ip_rev, 0, OMAP_I2C_CON_REG);
                udelay(50000);
        }
 
-       writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
+       /* for ES2 after soft reset */
+       omap_i2c_write_reg(i2c_base, ip_rev, 0x2, OMAP_I2C_SYSC_REG);
        udelay(1000);
 
-       writew(I2C_CON_EN, &i2c_base->con);
-       while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) {
+       omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN, OMAP_I2C_CON_REG);
+       while (!(omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_SYSS_REG) &
+                I2C_SYSS_RDONE) && timeout--) {
                if (timeout <= 0) {
                        puts("ERROR: Timeout in soft-reset\n");
                        return;
@@ -328,30 +441,33 @@ retry:
                udelay(1000);
        }
 
-       if (0 != __omap24_i2c_setspeed(i2c_base, speed, waitdelay)) {
+       if (__omap24_i2c_setspeed(i2c_base, ip_rev, speed, waitdelay)) {
                printf("ERROR: failed to setup I2C bus-speed!\n");
                return;
        }
 
        /* own address */
-       writew(slaveadd, &i2c_base->oa);
+       omap_i2c_write_reg(i2c_base, ip_rev, slaveadd, OMAP_I2C_OA_REG);
+
+       if (ip_rev == OMAP_I2C_REV_V1) {
+               /*
+                * Have to enable interrupts for OMAP2/3, these IPs don't have
+                * an 'irqstatus_raw' register and we shall have to poll 'stat'
+                */
+               omap_i2c_write_reg(i2c_base, ip_rev, I2C_IE_XRDY_IE |
+                                  I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
+                                  I2C_IE_NACK_IE | I2C_IE_AL_IE,
+                                  OMAP_I2C_IE_REG);
+       }
 
-#if defined(CONFIG_OMAP34XX)
-       /*
-        * Have to enable interrupts for OMAP2/3, these IPs don't have
-        * an 'irqstatus_raw' register and we shall have to poll 'stat'
-        */
-       writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
-              I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
-#endif
        udelay(1000);
-       flush_fifo(i2c_base);
-       writew(0xFFFF, &i2c_base->stat);
+       flush_fifo(i2c_base, ip_rev);
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
 
        /* Handle possible failed I2C state */
-       if (wait_for_bb(i2c_base, *waitdelay))
+       if (wait_for_bb(i2c_base, ip_rev, *waitdelay))
                if (deblock == 1) {
-                       omap24_i2c_deblock(i2c_base);
+                       omap24_i2c_deblock(i2c_base, ip_rev);
                        deblock = 0;
                        goto retry;
                }
@@ -361,25 +477,28 @@ retry:
  * i2c_probe: Use write access. Allows to identify addresses that are
  *            write-only (like the config register of dual-port EEPROMs)
  */
-static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
+static int __omap24_i2c_probe(void __iomem *i2c_base, int ip_rev, int waitdelay,
+                             uchar chip)
 {
        u16 status;
        int res = 1; /* default = fail */
 
-       if (chip == readw(&i2c_base->oa))
+       if (chip == omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_OA_REG))
                return res;
 
        /* Wait until bus is free */
-       if (wait_for_bb(i2c_base, waitdelay))
+       if (wait_for_bb(i2c_base, ip_rev, waitdelay))
                return res;
 
        /* No data transfer, slave addr only */
-       writew(chip, &i2c_base->sa);
+       omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
+
        /* Stop bit needed here */
-       writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
-              I2C_CON_STP, &i2c_base->con);
+       omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
+                          I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP,
+                          OMAP_I2C_CON_REG);
 
-       status = wait_for_event(i2c_base, waitdelay);
+       status = wait_for_event(i2c_base, ip_rev, waitdelay);
 
        if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) {
                /*
@@ -400,14 +519,17 @@ static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
                res = 0;                                /* Device found */
                udelay(waitdelay);/* Required by AM335X in SPL */
                /* Abort transfer (force idle state) */
-               writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */
+               omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_MST | I2C_CON_TRX,
+                                  OMAP_I2C_CON_REG);   /* Reset */
                udelay(1000);
-               writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX |
-                      I2C_CON_STP, &i2c_base->con);            /* STP */
+               omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
+                                  I2C_CON_TRX | I2C_CON_STP,
+                                  OMAP_I2C_CON_REG);   /* STP */
        }
+
 pr_exit:
-       flush_fifo(i2c_base);
-       writew(0xFFFF, &i2c_base->stat);
+       flush_fifo(i2c_base, ip_rev);
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
        return res;
 }
 
@@ -424,8 +546,9 @@ pr_exit:
  *           or that do not need a register address at all (such as some clock
  *           distributors).
  */
-static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
-                            uint addr, int alen, uchar *buffer, int len)
+static int __omap24_i2c_read(void __iomem *i2c_base, int ip_rev, int waitdelay,
+                            uchar chip, uint addr, int alen, uchar *buffer,
+                            int len)
 {
        int i2c_error = 0;
        u16 status;
@@ -434,10 +557,12 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
                puts("I2C read: addr len < 0\n");
                return 1;
        }
+
        if (len < 0) {
                puts("I2C read: data len < 0\n");
                return 1;
        }
+
        if (buffer == NULL) {
                puts("I2C read: NULL pointer passed\n");
                return 1;
@@ -471,28 +596,29 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
 #endif
 
        /* Wait until bus not busy */
-       if (wait_for_bb(i2c_base, waitdelay))
+       if (wait_for_bb(i2c_base, ip_rev, waitdelay))
                return 1;
 
        /* Zero, one or two bytes reg address (offset) */
-       writew(alen, &i2c_base->cnt);
+       omap_i2c_write_reg(i2c_base, ip_rev, alen, OMAP_I2C_CNT_REG);
        /* Set slave address */
-       writew(chip, &i2c_base->sa);
+       omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
 
        if (alen) {
                /* Must write reg offset first */
 #ifdef CONFIG_I2C_REPEATED_START
                /* No stop bit, use Repeated Start (Sr) */
-               writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
-                      I2C_CON_TRX, &i2c_base->con);
+               omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
+                                  I2C_CON_STT | I2C_CON_TRX, OMAP_I2C_CON_REG);
 #else
                /* Stop - Start (P-S) */
-               writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP |
-                      I2C_CON_TRX, &i2c_base->con);
+               omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
+                                  I2C_CON_STT | I2C_CON_STP | I2C_CON_TRX,
+                                  OMAP_I2C_CON_REG);
 #endif
                /* Send register offset */
                while (1) {
-                       status = wait_for_event(i2c_base, waitdelay);
+                       status = wait_for_event(i2c_base, ip_rev, waitdelay);
                        /* Try to identify bus that is not padconf'd for I2C */
                        if (status == I2C_STAT_XRDY) {
                                i2c_error = 2;
@@ -508,31 +634,37 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
                        }
                        if (alen) {
                                if (status & I2C_STAT_XRDY) {
+                                       u8 addr_byte;
                                        alen--;
-                                       /* Do we have to use byte access? */
-                                       writeb((addr >> (8 * alen)) & 0xff,
-                                              &i2c_base->data);
-                                       writew(I2C_STAT_XRDY, &i2c_base->stat);
+                                       addr_byte = (addr >> (8 * alen)) & 0xff;
+                                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                                          addr_byte,
+                                                          OMAP_I2C_DATA_REG);
+                                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                                          I2C_STAT_XRDY,
+                                                          OMAP_I2C_STAT_REG);
                                }
                        }
                        if (status & I2C_STAT_ARDY) {
-                               writew(I2C_STAT_ARDY, &i2c_base->stat);
+                               omap_i2c_write_reg(i2c_base, ip_rev,
+                                                  I2C_STAT_ARDY,
+                                                  OMAP_I2C_STAT_REG);
                                break;
                        }
                }
        }
+
        /* Set slave address */
-       writew(chip, &i2c_base->sa);
+       omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
        /* Read len bytes from slave */
-       writew(len, &i2c_base->cnt);
+       omap_i2c_write_reg(i2c_base, ip_rev, len, OMAP_I2C_CNT_REG);
        /* Need stop bit here */
-       writew(I2C_CON_EN | I2C_CON_MST |
-              I2C_CON_STT | I2C_CON_STP,
-              &i2c_base->con);
+       omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
+                          I2C_CON_STT | I2C_CON_STP, OMAP_I2C_CON_REG);
 
        /* Receive data */
        while (1) {
-               status = wait_for_event(i2c_base, waitdelay);
+               status = wait_for_event(i2c_base, ip_rev, waitdelay);
                /*
                 * Try to identify bus that is not padconf'd for I2C. This
                 * state could be left over from previous transactions if
@@ -549,24 +681,28 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
                        goto rd_exit;
                }
                if (status & I2C_STAT_RRDY) {
-                       *buffer++ = readb(&i2c_base->data);
-                       writew(I2C_STAT_RRDY, &i2c_base->stat);
+                       *buffer++ = omap_i2c_read_reg(i2c_base, ip_rev,
+                                                     OMAP_I2C_DATA_REG);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          I2C_STAT_RRDY, OMAP_I2C_STAT_REG);
                }
                if (status & I2C_STAT_ARDY) {
-                       writew(I2C_STAT_ARDY, &i2c_base->stat);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          I2C_STAT_ARDY, OMAP_I2C_STAT_REG);
                        break;
                }
        }
 
 rd_exit:
-       flush_fifo(i2c_base);
-       writew(0xFFFF, &i2c_base->stat);
+       flush_fifo(i2c_base, ip_rev);
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
        return i2c_error;
 }
 
 /* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */
-static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
-                             uint addr, int alen, uchar *buffer, int len)
+static int __omap24_i2c_write(void __iomem *i2c_base, int ip_rev, int waitdelay,
+                             uchar chip, uint addr, int alen, uchar *buffer,
+                             int len)
 {
        int i;
        u16 status;
@@ -617,20 +753,21 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
 #endif
 
        /* Wait until bus not busy */
-       if (wait_for_bb(i2c_base, waitdelay))
+       if (wait_for_bb(i2c_base, ip_rev, waitdelay))
                return 1;
 
        /* Start address phase - will write regoffset + len bytes data */
-       writew(alen + len, &i2c_base->cnt);
+       omap_i2c_write_reg(i2c_base, ip_rev, alen + len, OMAP_I2C_CNT_REG);
        /* Set slave address */
-       writew(chip, &i2c_base->sa);
+       omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
        /* Stop bit needed here */
-       writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
-              I2C_CON_STP, &i2c_base->con);
+       omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
+                          I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP,
+                          OMAP_I2C_CON_REG);
 
        while (alen) {
                /* Must write reg offset (one or two bytes) */
-               status = wait_for_event(i2c_base, waitdelay);
+               status = wait_for_event(i2c_base, ip_rev, waitdelay);
                /* Try to identify bus that is not padconf'd for I2C */
                if (status == I2C_STAT_XRDY) {
                        i2c_error = 2;
@@ -646,8 +783,11 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
                }
                if (status & I2C_STAT_XRDY) {
                        alen--;
-                       writeb((addr >> (8 * alen)) & 0xff, &i2c_base->data);
-                       writew(I2C_STAT_XRDY, &i2c_base->stat);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          (addr >> (8 * alen)) & 0xff,
+                                          OMAP_I2C_DATA_REG);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          I2C_STAT_XRDY, OMAP_I2C_STAT_REG);
                } else {
                        i2c_error = 1;
                        printf("i2c_write: bus not ready for addr Tx (status=0x%x)\n",
@@ -655,9 +795,10 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
                        goto wr_exit;
                }
        }
+
        /* Address phase is over, now write data */
        for (i = 0; i < len; i++) {
-               status = wait_for_event(i2c_base, waitdelay);
+               status = wait_for_event(i2c_base, ip_rev, waitdelay);
                if (status == 0 || (status & I2C_STAT_NACK)) {
                        i2c_error = 1;
                        printf("i2c_write: error waiting for data ACK (status=0x%x)\n",
@@ -665,8 +806,10 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
                        goto wr_exit;
                }
                if (status & I2C_STAT_XRDY) {
-                       writeb(buffer[i], &i2c_base->data);
-                       writew(I2C_STAT_XRDY, &i2c_base->stat);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          buffer[i], OMAP_I2C_DATA_REG);
+                       omap_i2c_write_reg(i2c_base, ip_rev,
+                                          I2C_STAT_XRDY, OMAP_I2C_STAT_REG);
                } else {
                        i2c_error = 1;
                        printf("i2c_write: bus not ready for data Tx (i=%d)\n",
@@ -674,19 +817,20 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
                        goto wr_exit;
                }
        }
+
        /*
         * poll ARDY bit for making sure that last byte really has been
         * transferred on the bus.
         */
        do {
-               status = wait_for_event(i2c_base, waitdelay);
+               status = wait_for_event(i2c_base, ip_rev, waitdelay);
        } while (!(status & I2C_STAT_ARDY) && timeout--);
        if (timeout <= 0)
                printf("i2c_write: timed out writig last byte!\n");
 
 wr_exit:
-       flush_fifo(i2c_base);
-       writew(0xFFFF, &i2c_base->stat);
+       flush_fifo(i2c_base, ip_rev);
+       omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
        return i2c_error;
 }
 
@@ -695,26 +839,26 @@ wr_exit:
  * The legacy I2C functions. These need to get removed once
  * all users of this driver are converted to DM.
  */
-static struct i2c *omap24_get_base(struct i2c_adapter *adap)
+static void __iomem *omap24_get_base(struct i2c_adapter *adap)
 {
        switch (adap->hwadapnr) {
        case 0:
-               return (struct i2c *)I2C_BASE1;
+               return (void __iomem *)I2C_BASE1;
                break;
        case 1:
-               return (struct i2c *)I2C_BASE2;
+               return (void __iomem *)I2C_BASE2;
                break;
 #if (CONFIG_SYS_I2C_BUS_MAX > 2)
        case 2:
-               return (struct i2c *)I2C_BASE3;
+               return (void __iomem *)I2C_BASE3;
                break;
 #if (CONFIG_SYS_I2C_BUS_MAX > 3)
        case 3:
-               return (struct i2c *)I2C_BASE4;
+               return (void __iomem *)I2C_BASE4;
                break;
 #if (CONFIG_SYS_I2C_BUS_MAX > 4)
        case 4:
-               return (struct i2c *)I2C_BASE5;
+               return (void __iomem *)I2C_BASE5;
                break;
 #endif
 #endif
@@ -723,35 +867,46 @@ static struct i2c *omap24_get_base(struct i2c_adapter *adap)
                printf("wrong hwadapnr: %d\n", adap->hwadapnr);
                break;
        }
+
        return NULL;
 }
 
+static int omap24_get_ip_rev(void)
+{
+#ifdef CONFIG_OMAP34XX
+       return OMAP_I2C_REV_V1;
+#else
+       return OMAP_I2C_REV_V2;
+#endif
+}
 
 static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                           int alen, uchar *buffer, int len)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
+       void __iomem *i2c_base = omap24_get_base(adap);
+       int ip_rev = omap24_get_ip_rev();
 
-       return __omap24_i2c_read(i2c_base, adap->waitdelay, chip, addr,
+       return __omap24_i2c_read(i2c_base, ip_rev, adap->waitdelay, chip, addr,
                                 alen, buffer, len);
 }
 
-
 static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
                            int alen, uchar *buffer, int len)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
+       void __iomem *i2c_base = omap24_get_base(adap);
+       int ip_rev = omap24_get_ip_rev();
 
-       return __omap24_i2c_write(i2c_base, adap->waitdelay, chip, addr,
+       return __omap24_i2c_write(i2c_base, ip_rev, adap->waitdelay, chip, addr,
                                  alen, buffer, len);
 }
 
 static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
+       void __iomem *i2c_base = omap24_get_base(adap);
+       int ip_rev = omap24_get_ip_rev();
        int ret;
 
-       ret = __omap24_i2c_setspeed(i2c_base, speed, &adap->waitdelay);
+       ret = __omap24_i2c_setspeed(i2c_base, ip_rev, speed, &adap->waitdelay);
        if (ret) {
                pr_err("%s: set i2c speed failed\n", __func__);
                return ret;
@@ -764,16 +919,19 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
 
 static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
+       void __iomem *i2c_base = omap24_get_base(adap);
+       int ip_rev = omap24_get_ip_rev();
 
-       return __omap24_i2c_init(i2c_base, speed, slaveadd, &adap->waitdelay);
+       return __omap24_i2c_init(i2c_base, ip_rev, speed, slaveadd,
+                                &adap->waitdelay);
 }
 
 static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
+       void __iomem *i2c_base = omap24_get_base(adap);
+       int ip_rev = omap24_get_ip_rev();
 
-       return __omap24_i2c_probe(i2c_base, adap->waitdelay, chip);
+       return __omap24_i2c_probe(i2c_base, ip_rev, adap->waitdelay, chip);
 }
 
 #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1)
@@ -793,6 +951,7 @@ U_BOOT_I2C_ADAP_COMPLETE(omap24_1, omap24_i2c_init, omap24_i2c_probe,
                         CONFIG_SYS_OMAP24_I2C_SPEED1,
                         CONFIG_SYS_OMAP24_I2C_SLAVE1,
                         1)
+
 #if (CONFIG_SYS_I2C_BUS_MAX > 2)
 #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED2)
 #define CONFIG_SYS_OMAP24_I2C_SPEED2 CONFIG_SYS_OMAP24_I2C_SPEED
@@ -847,11 +1006,13 @@ static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
        for (; nmsgs > 0; nmsgs--, msg++) {
                debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
                if (msg->flags & I2C_M_RD) {
-                       ret = __omap24_i2c_read(priv->regs, priv->waitdelay,
+                       ret = __omap24_i2c_read(priv->regs, priv->ip_rev,
+                                               priv->waitdelay,
                                                msg->addr, 0, 0, msg->buf,
                                                msg->len);
                } else {
-                       ret = __omap24_i2c_write(priv->regs, priv->waitdelay,
+                       ret = __omap24_i2c_write(priv->regs, priv->ip_rev,
+                                                priv->waitdelay,
                                                 msg->addr, 0, 0, msg->buf,
                                                 msg->len);
                }
@@ -870,7 +1031,8 @@ static int omap_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 
        priv->speed = speed;
 
-       return __omap24_i2c_setspeed(priv->regs, speed, &priv->waitdelay);
+       return __omap24_i2c_setspeed(priv->regs, priv->ip_rev, speed,
+                                    &priv->waitdelay);
 }
 
 static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr,
@@ -878,14 +1040,22 @@ static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr,
 {
        struct omap_i2c *priv = dev_get_priv(bus);
 
-       return __omap24_i2c_probe(priv->regs, priv->waitdelay, chip_addr);
+       return __omap24_i2c_probe(priv->regs, priv->ip_rev, priv->waitdelay,
+                                 chip_addr);
 }
 
 static int omap_i2c_probe(struct udevice *bus)
 {
        struct omap_i2c *priv = dev_get_priv(bus);
+       struct omap_i2c_platdata *plat = dev_get_platdata(bus);
 
-       __omap24_i2c_init(priv->regs, priv->speed, 0, &priv->waitdelay);
+       priv->speed = plat->speed;
+       priv->regs = map_physmem(plat->base, sizeof(void *),
+                                MAP_NOCACHE);
+       priv->ip_rev = plat->ip_rev;
+
+       __omap24_i2c_init(priv->regs, priv->ip_rev, priv->speed, 0,
+                         &priv->waitdelay);
 
        return 0;
 }
@@ -893,18 +1063,18 @@ static int omap_i2c_probe(struct udevice *bus)
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
 {
-       struct omap_i2c *priv = dev_get_priv(bus);
+       struct omap_i2c_platdata *plat = dev_get_platdata(bus);
 
-       priv->regs = map_physmem(devfdt_get_addr(bus), sizeof(void *),
-                                MAP_NOCACHE);
-       priv->speed = CONFIG_SYS_OMAP24_I2C_SPEED;
+       plat->base = devfdt_get_addr(bus);
+       plat->speed = dev_read_u32_default(bus, "clock-frequency", 100000);
+       plat->ip_rev = dev_get_driver_data(bus);
 
        return 0;
 }
 
 static const struct udevice_id omap_i2c_ids[] = {
-       { .compatible = "ti,omap3-i2c" },
-       { .compatible = "ti,omap4-i2c" },
+       { .compatible = "ti,omap3-i2c", .data = OMAP_I2C_REV_V1 },
+       { .compatible = "ti,omap4-i2c", .data = OMAP_I2C_REV_V2 },
        { }
 };
 #endif
@@ -921,6 +1091,7 @@ U_BOOT_DRIVER(i2c_omap) = {
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
        .of_match = omap_i2c_ids,
        .ofdata_to_platdata = omap_i2c_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct omap_i2c_platdata),
 #endif
        .probe  = omap_i2c_probe,
        .priv_auto_alloc_size = sizeof(struct omap_i2c),
index 6d5abba..2584bea 100644 (file)
@@ -175,3 +175,42 @@ int twl603x_enable_bb_charge(u8 bb_fields)
                       val, err);
        return err;
 }
+
+#ifdef CONFIG_DM_I2C
+int palmas_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
+       if (ret) {
+               pr_err("unable to get I2C bus. ret %d\n", ret);
+               return ret;
+       }
+       ret = dm_i2c_reg_write(dev, reg, val);
+       if (ret) {
+               pr_err("writing to palmas failed. ret %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int palmas_i2c_read_u8(u8 chip_no, u8 reg, u8 *valp)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
+       if (ret) {
+               pr_err("unable to get I2C bus. ret %d\n", ret);
+               return ret;
+       }
+       ret = dm_i2c_reg_read(dev, reg);
+       if (ret < 0) {
+               pr_err("reading from palmas failed. ret %d\n", ret);
+               return ret;
+       }
+       *valp = (u8)ret;
+       return 0;
+}
+#endif
index f2987de..c3977fc 100644 (file)
 #include <power/pmic.h>
 #include <power/tps62362.h>
 
+#ifdef CONFIG_DM_I2C
+struct udevice *tps62362_dev __attribute__((section(".data"))) = NULL;
+#endif
+
 /**
  * tps62362_voltage_update() - Function to change a voltage level, as this
  *                            is a multi-step process.
@@ -22,9 +26,16 @@ int tps62362_voltage_update(unsigned char reg, unsigned char volt_sel)
        if (reg > TPS62362_NUM_REGS)
                return 1;
 
+#ifndef CONFIG_DM_I2C
        return i2c_write(TPS62362_I2C_ADDR, reg, 1, &volt_sel, 1);
+#else
+       if (!tps62362_dev)
+               return -ENODEV;
+       return dm_i2c_reg_write(tps62362_dev, reg, volt_sel);
+#endif
 }
 
+#ifndef CONFIG_DM_I2C
 int power_tps62362_init(unsigned char bus)
 {
        static const char name[] = "TPS62362";
@@ -44,3 +55,16 @@ int power_tps62362_init(unsigned char bus)
 
        return 0;
 }
+#else
+int power_tps62362_init(unsigned char bus)
+{
+       struct udevice *dev = NULL;
+       int rc;
+
+       rc = i2c_get_chip_for_busnum(bus, TPS62362_I2C_ADDR, 1, &dev);
+       if (rc)
+               return rc;
+       tps62362_dev = dev;
+       return 0;
+}
+#endif
index 01c0ad1..c839e31 100644 (file)
@@ -8,6 +8,8 @@
 #include <i2c.h>
 #include <power/tps65217.h>
 
+struct udevice *tps65217_dev __attribute__((section(".data"))) = NULL;
+
 /**
  * tps65217_reg_read() - Generic function that can read a TPS65217 register
  * @src_reg:            Source register address
  */
 int tps65217_reg_read(uchar src_reg, uchar *src_val)
 {
+#ifndef CONFIG_DM_I2C
        return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
+#else
+       return dm_i2c_read(tps65217_dev, src_reg,  src_val, 1);
+#endif
 }
 
 /**
@@ -46,9 +52,14 @@ int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
         * mask
         */
        if (mask != TPS65217_MASK_ALL_BITS) {
+#ifndef CONFIG_DM_I2C
                ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
+#else
+               ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
+#endif
                if (ret)
                        return ret;
+
                read_val &= (~mask);
                read_val |= (dest_val & mask);
                dest_val = read_val;
@@ -56,23 +67,40 @@ int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
 
        if (prot_level > 0) {
                xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
+#ifndef CONFIG_DM_I2C
                ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
                                &xor_reg, 1);
+#else
+               ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
+                                  &xor_reg, 1);
+#endif
                if (ret)
                        return ret;
        }
-
+#ifndef CONFIG_DM_I2C
        ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
+#else
+       ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
+#endif
        if (ret)
                return ret;
 
        if (prot_level == TPS65217_PROT_LEVEL_2) {
+#ifndef CONFIG_DM_I2C
                ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
                                &xor_reg, 1);
+#else
+               ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
+                                  &xor_reg, 1);
+#endif
                if (ret)
                        return ret;
 
+#ifndef CONFIG_DM_I2C
                ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
+#else
+               ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
+#endif
                if (ret)
                        return ret;
        }
@@ -106,3 +134,17 @@ int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
 
        return 0;
 }
+
+int power_tps65217_init(unsigned char bus)
+{
+#ifdef CONFIG_DM_I2C
+       struct udevice *dev = NULL;
+       int rc;
+
+       rc = i2c_get_chip_for_busnum(bus, TPS65217_CHIP_PM, 1, &dev);
+       if (rc)
+               return rc;
+       tps65217_dev = dev;
+#endif
+       return 0;
+}
index b50953b..7c95e5e 100644 (file)
@@ -10,6 +10,7 @@
 #include <power/pmic.h>
 #include <power/tps65218.h>
 
+#ifndef CONFIG_DM_I2C
 int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
 {
        uchar read_val;
@@ -84,6 +85,76 @@ int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
 
        return 0;
 }
+#else
+struct udevice *tps65218_dev __attribute__((section(".data"))) = NULL;
+
+int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
+{
+       uchar read_val;
+       int ret;
+
+       if (!tps65218_dev)
+               return -ENODEV;
+
+       ret = dm_i2c_read(tps65218_dev, dest_reg,  &read_val, 1);
+       if (ret)
+               return ret;
+
+       *dest_val = read_val;
+
+       return 0;
+}
+
+int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
+                      uchar mask)
+{
+       uchar read_val;
+       uchar xor_reg;
+       int ret;
+
+       if (!tps65218_dev)
+               return -ENODEV;
+
+       /*
+        * If we are affecting only a bit field, read dest_reg and apply the
+        * mask
+        */
+       if (mask != TPS65218_MASK_ALL_BITS) {
+               ret = dm_i2c_read(tps65218_dev, dest_reg, &read_val, 1);
+               if (ret)
+                       return ret;
+
+               read_val &= (~mask);
+               read_val |= (dest_val & mask);
+               dest_val = read_val;
+       }
+
+       if (prot_level > 0) {
+               xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
+               ret = dm_i2c_write(tps65218_dev, TPS65218_PASSWORD, &xor_reg,
+                                  1);
+               if (ret)
+                       return ret;
+       }
+
+       ret = dm_i2c_write(tps65218_dev, dest_reg, &dest_val, 1);
+       if (ret)
+               return ret;
+
+       if (prot_level == TPS65218_PROT_LEVEL_2) {
+               ret = dm_i2c_write(tps65218_dev, TPS65218_PASSWORD, &xor_reg,
+                                  1);
+               if (ret)
+                       return ret;
+
+               ret = dm_i2c_write(tps65218_dev, dest_reg, &dest_val, 1);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+#endif
 
 /**
  * tps65218_voltage_update() - Function to change a voltage level, as this
@@ -154,6 +225,7 @@ int tps65218_lock_fseal(void)
        return 0;
 }
 
+#ifndef CONFIG_DM_I2C
 int power_tps65218_init(unsigned char bus)
 {
        static const char name[] = "TPS65218_PMIC";
@@ -173,3 +245,16 @@ int power_tps65218_init(unsigned char bus)
 
        return 0;
 }
+#else
+int power_tps65218_init(unsigned char bus)
+{
+       struct udevice *dev = NULL;
+       int rc;
+
+       rc = i2c_get_chip_for_busnum(bus, TPS65218_CHIP_PM, 1, &dev);
+       if (rc)
+               return rc;
+       tps65218_dev = dev;
+       return 0;
+}
+#endif
index f4d2aa1..4772de1 100644 (file)
@@ -8,6 +8,47 @@
 #include <i2c.h>
 #include <power/tps65910.h>
 
+struct udevice *tps65910_dev __attribute__((section(".data"))) = NULL;
+
+static inline int tps65910_read_reg(int addr, uchar *buf)
+{
+#ifndef CONFIG_DM_I2C
+       return i2c_read(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
+#else
+       int rc;
+
+       rc = dm_i2c_reg_read(tps65910_dev, addr);
+       if (rc < 0)
+               return rc;
+       *buf = (uchar)rc;
+       return 0;
+#endif
+}
+
+static inline int tps65910_write_reg(int addr, uchar *buf)
+{
+#ifndef CONFIG_DM_I2C
+       return i2c_write(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
+#else
+       return dm_i2c_reg_write(tps65910_dev, addr, *buf);
+#endif
+}
+
+int power_tps65910_init(unsigned char bus)
+{
+#ifdef CONFIG_DM_I2C
+       struct udevice *dev = NULL;
+       int rc;
+
+       rc = i2c_get_chip_for_busnum(bus, TPS65910_CTRL_I2C_ADDR, 1, &dev);
+
+       if (rc)
+               return rc;
+       tps65910_dev = dev;
+#endif
+       return 0;
+}
+
 /*
  * tps65910_set_i2c_control() - Set the TPS65910 to be controlled via the I2C
  *                             interface.
@@ -19,16 +60,14 @@ int tps65910_set_i2c_control(void)
        uchar buf;
 
        /* VDD1/2 voltage selection register access by control i/f */
-       ret = i2c_read(TPS65910_CTRL_I2C_ADDR, TPS65910_DEVCTRL_REG, 1,
-                      &buf, 1);
+       ret = tps65910_read_reg(TPS65910_DEVCTRL_REG, &buf);
 
        if (ret)
                return ret;
 
        buf |= TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
 
-       return i2c_write(TPS65910_CTRL_I2C_ADDR, TPS65910_DEVCTRL_REG, 1,
-                        &buf, 1);
+       return tps65910_write_reg(TPS65910_DEVCTRL_REG, &buf);
 }
 
 /*
@@ -49,29 +88,29 @@ int tps65910_voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
                reg_offset = TPS65910_VDD2_OP_REG;
 
        /* Select VDDx OP   */
-       ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
+       ret = tps65910_read_reg(reg_offset, &buf);
        if (ret)
                return ret;
 
        buf &= ~TPS65910_OP_REG_CMD_MASK;
 
-       ret = i2c_write(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
+       ret = tps65910_write_reg(reg_offset, &buf);
        if (ret)
                return ret;
 
        /* Configure VDDx OP  Voltage */
-       ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
+       ret = tps65910_read_reg(reg_offset, &buf);
        if (ret)
                return ret;
 
        buf &= ~TPS65910_OP_REG_SEL_MASK;
        buf |= vddx_op_vol_sel;
 
-       ret = i2c_write(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
+       ret = tps65910_write_reg(reg_offset, &buf);
        if (ret)
                return ret;
 
-       ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
+       ret = tps65910_read_reg(reg_offset, &buf);
        if (ret)
                return ret;
 
index 5246001..42c9001 100644 (file)
@@ -179,3 +179,42 @@ int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        return 0;
 }
 #endif
+
+#ifdef CONFIG_DM_I2C
+int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
+       if (ret) {
+               pr_err("unable to get I2C bus. ret %d\n", ret);
+               return ret;
+       }
+       ret = dm_i2c_reg_write(dev, reg, val);
+       if (ret) {
+               pr_err("writing to twl4030 failed. ret %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *valp)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
+       if (ret) {
+               pr_err("unable to get I2C bus. ret %d\n", ret);
+               return ret;
+       }
+       ret = dm_i2c_reg_read(dev, reg);
+       if (ret < 0) {
+               pr_err("reading from twl4030 failed. ret %d\n", ret);
+               return ret;
+       }
+       *valp = (u8)ret;
+       return 0;
+}
+#endif
index e0cbda1..103960d 100644 (file)
@@ -268,3 +268,42 @@ void twl6030_usb_device_settings()
        value &= ~TWL6030_MISC2_VUSB_IN_PMID;
        twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_MISC2, value);
 }
+
+#ifdef CONFIG_DM_I2C
+int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
+       if (ret) {
+               pr_err("unable to get I2C bus. ret %d\n", ret);
+               return ret;
+       }
+       ret = dm_i2c_reg_write(dev, reg, val);
+       if (ret) {
+               pr_err("writing to twl6030 failed. ret %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *valp)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
+       if (ret) {
+               pr_err("unable to get I2C bus. ret %d\n", ret);
+               return ret;
+       }
+       ret = dm_i2c_reg_read(dev, reg);
+       if (ret < 0) {
+               pr_err("reading from twl6030 failed. ret %d\n", ret);
+               return ret;
+       }
+       *valp = (u8)ret;
+       return 0;
+}
+#endif
index dffd6b2..78dcf40 100644 (file)
@@ -77,6 +77,10 @@ typedef struct global_data {
 #ifdef CONFIG_OF_LIVE
        struct device_node *of_root;
 #endif
+
+#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
+       const void *multi_dtb_fit;      /* uncompressed multi-dtb FIT image */
+#endif
        struct jt_funcs *jt;            /* jump table */
        char env_buf[32];               /* buffer for env_get() before reloc. */
 #ifdef CONFIG_TRACE
index 9d0d342..ed71f4c 100644 (file)
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
 
 /* Power */
+#ifndef CONFIG_DM_I2C
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
+#endif
 #define CONFIG_POWER_TPS65218
 #define CONFIG_POWER_TPS62362
 
index 7b809e2..e4c2872 100644 (file)
 
 #include <configs/ti_am335x_common.h>
 
-/* No more need for I2C legacy compatibility for this board.
- * CONFIG_DM_I2C_COMPAT is defined in ti_armv7_common.h. See the comment there
- * for the right moment to delete the following line.
- */
-#undef CONFIG_DM_I2C_COMPAT
-
 /* Using 32K of volatile storage for environment */
 #define CONFIG_ENV_SIZE                0x4000
 
index 0f892e5..1e2a62d 100644 (file)
 /* Timer information. */
 #define CONFIG_SYS_PTV                 2       /* Divisor: 2^(PTV+1) => 8 */
 
-/*
- * Disable DM_* for SPL build and can be re-enabled after adding
- * DM support in SPL
- */
-#ifdef CONFIG_SPL_BUILD
-#undef CONFIG_DM_I2C
-#endif
-
-/* I2C IP block */
+/* If DM_I2C, enable non-DM I2C support */
+#if !defined(CONFIG_DM_I2C)
 #define CONFIG_I2C
-#ifndef CONFIG_DM_I2C
 #define CONFIG_SYS_I2C
-#else
-/*
- * Enable CONFIG_DM_I2C_COMPAT temporarily until all the i2c client
- * devices are adopted to DM
- */
-#define CONFIG_DM_I2C_COMPAT
 #endif
 
 /*
index 8a4839e..6977995 100644 (file)
 #include <dm/ofnode.h>
 
 /**
+ * uclass_find_next_free_req_seq() - Get the next free req_seq number
+ *
+ * This returns the next free req_seq number. This is useful only if
+ * OF_CONTROL is not used. The next free req_seq number is simply the
+ * maximum req_seq of the uclass + 1.
+ * This allows assiging req_seq number in the binding order.
+ *
+ * @id:                Id number of the uclass
+ * @return     The next free req_seq number
+ */
+int uclass_find_next_free_req_seq(enum uclass_id id);
+
+/**
  * uclass_get_device_tail() - handle the end of a get_device call
  *
  * This handles returning an error or probing a device as needed.
index b15da00..f1bcbf8 100644 (file)
@@ -951,6 +951,27 @@ int fdtdec_setup_memory_banksize(void);
  */
 int fdtdec_setup(void);
 
+#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
+/**
+ * fdtdec_resetup()  - Set up the device tree again
+ *
+ * The main difference with fdtdec_setup() is that it returns if the fdt has
+ * changed because a better match has been found.
+ * This is typically used for boards that rely on a DM driver to detect the
+ * board type. This function sould be called by the board code after the stuff
+ * needed by board_fit_config_name_match() to operate porperly is available.
+ * If this functions signals that a rescan is necessary, the board code must
+ * unbind all the drivers using dm_uninit() and then rescan the DT with
+ * dm_init_and_scan().
+ *
+ * @param rescan Returns a flag indicating that fdt has changed and rescanning
+ *               the fdt is required
+ *
+ * @return 0 if OK, -ve on error
+ */
+int fdtdec_resetup(int *rescan);
+#endif
+
 /**
  * Board-specific FDT initialization. Returns the address to a device tree blob.
  * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined
index 229de53..20c7e48 100644 (file)
 #define BB_VSEL_VBAT           (3 << 1)
 #define BB_CHRG_EN             (1 << 0)
 
+#ifndef CONFIG_DM_I2C
 /*
  * Functions to read and write from TPS659038/TWL6035/TWL6037
  * or other Palmas family of TI PMICs
@@ -130,6 +131,10 @@ static inline int palmas_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
 {
        return i2c_read(chip_no, reg, 1, val, 1);
 }
+#else
+int palmas_i2c_write_u8(u8 chip_no, u8 reg, u8 val);
+int palmas_i2c_read_u8(u8 chip_no, u8 reg, u8 *val);
+#endif
 
 void palmas_init_settings(void);
 int palmas_mmc1_poweron_ldo(uint ldo_volt, uint ldo_ctrl, uint voltage);
index 00fbab8..669a94a 100644 (file)
@@ -80,6 +80,8 @@ enum {
 #define TPS65217_PWR_SRC_USB_BITMASK           0x4
 #define TPS65217_PWR_SRC_AC_BITMASK            0x8
 
+int power_tps65217_init(unsigned char bus);
+
 int tps65217_reg_read(uchar src_reg, uchar *src_val);
 int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
                       uchar mask);
index 48e0b2c..21b2a21 100644 (file)
@@ -72,6 +72,7 @@ enum {
 #define TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_SR_I2C     (0x0 << 4)
 #define TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C    (0x1 << 4)
 
+int power_tps65910_init(unsigned char bus);
 int tps65910_set_i2c_control(void);
 int tps65910_voltage_update(unsigned int module, unsigned char vddx_op_vol_sel);
 #endif /* __POWER_TPS65910_H__ */
index 46a9306..c27ad61 100644 (file)
  *   examples are TWL4030_PM_RECEIVER_VMMC1_DEV_GRP and
  *   TWL4030_LED_LEDEN.
  */
+#ifndef CONFIG_DM_I2C
 static inline int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
        return i2c_write(chip_no, reg, 1, &val, 1);
@@ -657,7 +658,10 @@ static inline int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
 {
        return i2c_read(chip_no, reg, 1, val, 1);
 }
-
+#else
+int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val);
+int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val);
+#endif
 /*
  * Power
  */
index 6685343..41f17de 100644 (file)
@@ -186,6 +186,7 @@ struct twl6030_data{
 };
 
 /* Functions to read and write from TWL6030 */
+#ifndef CONFIG_DM_I2C
 static inline int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
        return i2c_write(chip_no, reg, 1, &val, 1);
@@ -195,6 +196,10 @@ static inline int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
 {
        return i2c_read(chip_no, reg, 1, val, 1);
 }
+#else
+int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val);
+int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val);
+#endif
 
 /*
  * Power
index cbdc077..7bbc6d4 100644 (file)
@@ -1275,14 +1275,55 @@ int fdtdec_setup(void)
         * If so, pick the most relevant
         */
        fdt_blob = locate_dtb_in_fit(gd->fdt_blob);
-       if (fdt_blob)
+       if (fdt_blob) {
+               gd->multi_dtb_fit = gd->fdt_blob;
                gd->fdt_blob = fdt_blob;
+       }
+
 # endif
 #endif
 
        return fdtdec_prepare_fdt();
 }
 
+#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
+int fdtdec_resetup(int *rescan)
+{
+       void *fdt_blob;
+
+       /*
+        * If the current DTB is part of a compressed FIT image,
+        * try to locate the best match from the uncompressed
+        * FIT image stillpresent there. Save the time and space
+        * required to uncompress it again.
+        */
+       if (gd->multi_dtb_fit) {
+               fdt_blob = locate_dtb_in_fit(gd->multi_dtb_fit);
+
+               if (fdt_blob == gd->fdt_blob) {
+                       /*
+                        * The best match did not change. no need to tear down
+                        * the DM and rescan the fdt.
+                        */
+                       *rescan = 0;
+                       return 0;
+               }
+
+               *rescan = 1;
+               gd->fdt_blob = fdt_blob;
+               return fdtdec_prepare_fdt();
+       }
+
+       /*
+        * If multi_dtb_fit is NULL, it means that blob appended to u-boot is
+        * not a FIT image containings DTB, but a single DTB. There is no need
+        * to teard down DM and rescan the DT in this case.
+        */
+       *rescan = 0;
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_NR_DRAM_BANKS
 int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id,
                           phys_addr_t *basep, phys_size_t *sizep, bd_t *bd)