summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/Kconfig12
-rw-r--r--drivers/core/device.c10
-rw-r--r--drivers/core/root.c1
-rw-r--r--drivers/core/uclass.c24
-rw-r--r--drivers/i2c/i2c-uclass.c11
-rw-r--r--drivers/i2c/omap24xx_i2c.c467
-rw-r--r--drivers/power/palmas.c39
-rw-r--r--drivers/power/pmic/pmic_tps62362.c24
-rw-r--r--drivers/power/pmic/pmic_tps65217.c44
-rw-r--r--drivers/power/pmic/pmic_tps65218.c85
-rw-r--r--drivers/power/pmic/pmic_tps65910.c57
-rw-r--r--drivers/power/twl4030.c39
-rw-r--r--drivers/power/twl6030.c39
13 files changed, 688 insertions, 164 deletions
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index e8ba20ca82d..046b87a3337 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -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
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 836bcadced5..0d15e5062b6 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -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);
}
}
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 4ce55f9cc89..e6ec7faf379 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -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;
}
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 9766aeabd19..a622f079410 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -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)
{
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index c5a3c4e2016..975318e5f25 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -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,
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 51f923752c3..4b93e02bbe8 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -42,8 +42,18 @@
#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"
@@ -52,14 +62,107 @@
/* 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),
diff --git a/drivers/power/palmas.c b/drivers/power/palmas.c
index 6d5abba5a73..2584bea38d0 100644
--- a/drivers/power/palmas.c
+++ b/drivers/power/palmas.c
@@ -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
diff --git a/drivers/power/pmic/pmic_tps62362.c b/drivers/power/pmic/pmic_tps62362.c
index f2987de48e0..c3977fccc3b 100644
--- a/drivers/power/pmic/pmic_tps62362.c
+++ b/drivers/power/pmic/pmic_tps62362.c
@@ -10,6 +10,10 @@
#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
diff --git a/drivers/power/pmic/pmic_tps65217.c b/drivers/power/pmic/pmic_tps65217.c
index 01c0ad1a8c8..c839e318905 100644
--- a/drivers/power/pmic/pmic_tps65217.c
+++ b/drivers/power/pmic/pmic_tps65217.c
@@ -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
@@ -16,7 +18,11 @@
*/
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;
+}
diff --git a/drivers/power/pmic/pmic_tps65218.c b/drivers/power/pmic/pmic_tps65218.c
index b50953bdc12..7c95e5e7580 100644
--- a/drivers/power/pmic/pmic_tps65218.c
+++ b/drivers/power/pmic/pmic_tps65218.c
@@ -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
diff --git a/drivers/power/pmic/pmic_tps65910.c b/drivers/power/pmic/pmic_tps65910.c
index f4d2aa1b7a4..4772de11be2 100644
--- a/drivers/power/pmic/pmic_tps65910.c
+++ b/drivers/power/pmic/pmic_tps65910.c
@@ -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;
diff --git a/drivers/power/twl4030.c b/drivers/power/twl4030.c
index 52460014bff..42c9001518b 100644
--- a/drivers/power/twl4030.c
+++ b/drivers/power/twl4030.c
@@ -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
diff --git a/drivers/power/twl6030.c b/drivers/power/twl6030.c
index e0cbda1f8c4..103960d48d2 100644
--- a/drivers/power/twl6030.c
+++ b/drivers/power/twl6030.c
@@ -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