From: Jean-Jacques Hiblot <jjhiblot@ti.com>
Date: Fri, 7 Dec 2018 13:50:46 +0000 (+0100)
Subject: power: make most tps drivers and the twl4030 driver compatible with DM_I2C
X-Git-Tag: v2025.01-rc5-pxa1908~3224^2~10
X-Git-Url: http://git.dujemihanovic.xyz/%22/img/sics.gif/%22/static/git-favicon.png?a=commitdiff_plain;h=fb1b7712ad3f;p=u-boot.git

power: make most tps drivers and the twl4030 driver compatible with DM_I2C

Those driver are not DM drivers per se (not using the PMIC/regulator
framework) and are using the legacy I2C API. Make them compatible with
the DM_I2C API.

This impacts the following drivers:
- palmas (used by am57xx/dra7xx evms)
- tps65218 (used by am43xx evms)
- tps65217 and tps65910 (used by am335x evms and am335x boneblack vboot)
- twl4030 (used by omap3_logicpd)
- tps65217 (used by brppt1)
- twl6030

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Heiko Schocher <hs@denx.de>
---

diff --git a/drivers/power/palmas.c b/drivers/power/palmas.c
index 6d5abba5a7..2584bea38d 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 f2987de48e..c3977fccc3 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 01c0ad1a8c..c839e31890 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 b50953bdc1..7c95e5e758 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 f4d2aa1b7a..4772de11be 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 52460014bf..42c9001518 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 e0cbda1f8c..103960d48d 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
diff --git a/include/palmas.h b/include/palmas.h
index 229de53715..20c7e489c1 100644
--- a/include/palmas.h
+++ b/include/palmas.h
@@ -117,6 +117,7 @@
 #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);
diff --git a/include/power/tps65217.h b/include/power/tps65217.h
index 00fbab80cb..669a94a6c8 100644
--- a/include/power/tps65217.h
+++ b/include/power/tps65217.h
@@ -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);
diff --git a/include/power/tps65910.h b/include/power/tps65910.h
index 48e0b2c5ab..21b2a21ee0 100644
--- a/include/power/tps65910.h
+++ b/include/power/tps65910.h
@@ -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__ */
diff --git a/include/twl4030.h b/include/twl4030.h
index 46a9306246..c27ad615ee 100644
--- a/include/twl4030.h
+++ b/include/twl4030.h
@@ -648,6 +648,7 @@
  *   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
  */
diff --git a/include/twl6030.h b/include/twl6030.h
index 66853439ed..41f17de3ab 100644
--- a/include/twl6030.h
+++ b/include/twl6030.h
@@ -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