From fb1b7712ad3f375f83e74629f03236c300b0b896 Mon Sep 17 00:00:00 2001 From: Jean-Jacques Hiblot Date: Fri, 7 Dec 2018 14:50:46 +0100 Subject: [PATCH] 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 Reviewed-by: Tom Rini Reviewed-by: Heiko Schocher --- drivers/power/palmas.c | 39 ++++++++++++++ drivers/power/pmic/pmic_tps62362.c | 24 +++++++++ drivers/power/pmic/pmic_tps65217.c | 44 +++++++++++++++- drivers/power/pmic/pmic_tps65218.c | 85 ++++++++++++++++++++++++++++++ drivers/power/pmic/pmic_tps65910.c | 57 ++++++++++++++++---- drivers/power/twl4030.c | 39 ++++++++++++++ drivers/power/twl6030.c | 39 ++++++++++++++ include/palmas.h | 5 ++ include/power/tps65217.h | 2 + include/power/tps65910.h | 1 + include/twl4030.h | 6 ++- include/twl6030.h | 5 ++ 12 files changed, 335 insertions(+), 11 deletions(-) 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 #include +#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 #include +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 #include +#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 #include +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