diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 9a8bfe07b8e..a472f61f88f 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -13,4 +13,5 @@ obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o obj-$(CONFIG_POWER_TPS65090) += pmic_tps65090.o obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o +obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o diff --git a/drivers/power/pmic/pmic_tps65218.c b/drivers/power/pmic/pmic_tps65218.c new file mode 100644 index 00000000000..09524563799 --- /dev/null +++ b/drivers/power/pmic/pmic_tps65218.c @@ -0,0 +1,97 @@ +/* + * (C) Copyright 2011-2013 + * Texas Instruments, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/** + * tps65218_reg_write() - Generic function that can write a TPS65218 PMIC + * register or bit field regardless of protection + * level. + * + * @prot_level: Register password protection. Use + * TPS65218_PROT_LEVEL_NONE, + * TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2 + * @dest_reg: Register address to write. + * @dest_val: Value to write. + * @mask: Bit mask (8 bits) to be applied. Function will only + * change bits that are set in the bit mask. + * + * @return: 0 for success, not 0 on failure, as per the i2c API + */ +int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, + uchar mask) +{ + uchar read_val; + uchar xor_reg; + int ret; + + /* + * If we are affecting only a bit field, read dest_reg and apply the + * mask + */ + if (mask != TPS65218_MASK_ALL_BITS) { + ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &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 = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, + &xor_reg, 1); + if (ret) + return ret; + } + + ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); + if (ret) + return ret; + + if (prot_level == TPS65218_PROT_LEVEL_2) { + ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, + &xor_reg, 1); + if (ret) + return ret; + + ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); + if (ret) + return ret; + } + + return 0; +} + +/** + * tps65218_voltage_update() - Function to change a voltage level, as this + * is a multi-step process. + * @dc_cntrl_reg: DC voltage control register to change. + * @volt_sel: New value for the voltage register + * @return: 0 for success, not 0 on failure. + */ +int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel) +{ + if ((dc_cntrl_reg != TPS65218_DCDC1) && + (dc_cntrl_reg != TPS65218_DCDC2)) + return 1; + + /* set voltage level */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel, + TPS65218_MASK_ALL_BITS)) + return 1; + + /* set GO bit to initiate voltage transition */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW, + TPS65218_DCDC_GO, TPS65218_DCDC_GO)) + return 1; + + return 0; +} diff --git a/include/power/tps65218.h b/include/power/tps65218.h new file mode 100644 index 00000000000..67aa2f8c8d4 --- /dev/null +++ b/include/power/tps65218.h @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2014 + * Texas Instruments, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __POWER_TPS65218_H__ +#define __POWER_TPS65218_H__ + +/* I2C chip address */ +#define TPS65218_CHIP_PM 0x24 + +/* Registers */ +enum { + TPS65218_CHIPID = 0x00, + TPS65218_INT1, + TPS65218_INT2, + TPS65218_INT_MASK1, + TPS65218_INT_MASK2, + TPS65218_STATUS, + TPS65218_CONTROL, + TPS65218_FLAG, + TPS65218_PASSWORD = 0x10, + TPS65218_ENABLE1, + TPS65218_ENABLE2, + TPS65218_CONFIG1, + TPS65218_CONFIG2, + TPS65218_CONFIG3, + TPS65218_DCDC1, + TPS65218_DCDC2, + TPS65218_DCDC3, + TPS65218_DCDC4, + TPS65218_SLEW, + TPS65218_LDO1, + TPS65218_SEQ1 = 0x20, + TPS65218_SEQ2, + TPS65218_SEQ3, + TPS65218_SEQ4, + TPS65218_SEQ5, + TPS65218_SEQ6, + TPS65218_SEQ7, + TPS65218_PMIC_NUM_OF_REGS, +}; + +#define TPS65218_PROT_LEVEL_NONE 0x00 +#define TPS65218_PROT_LEVEL_1 0x01 +#define TPS65218_PROT_LEVEL_2 0x02 + +#define TPS65218_PASSWORD_LOCK_FOR_WRITE 0x00 +#define TPS65218_PASSWORD_UNLOCK 0x7D + +#define TPS65218_DCDC_GO 0x80 + +#define TPS65218_MASK_ALL_BITS 0xFF + +#define TPS65218_DCDC_VOLT_SEL_1100MV 0x19 +#define TPS65218_DCDC_VOLT_SEL_1330MV 0x30 + +int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, + uchar mask); +int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel); +#endif /* __POWER_TPS65218_H__ */