/* * driver/regulator/tps80031-regulator.c * * Regulator driver for TI TPS80031 * * Copyright (C) 2011 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include #include #include #include #include #include #include #include #include /* Flags for DCDC Voltage reading */ #define DCDC_OFFSET_EN BIT(0) #define DCDC_EXTENDED_EN BIT(1) #define TRACK_MODE_ENABLE BIT(2) #define SMPS_MULTOFFSET_VIO BIT(1) #define SMPS_MULTOFFSET_SMPS1 BIT(3) #define SMPS_MULTOFFSET_SMPS2 BIT(4) #define SMPS_MULTOFFSET_SMPS3 BIT(6) #define SMPS_MULTOFFSET_SMPS4 BIT(0) #define PMC_SMPS_OFFSET_ADD 0xE0 #define PMC_SMPS_MULT_ADD 0xE3 #define STATE_OFF 0x00 #define STATE_ON 0x01 #define STATE_MASK 0x03 #define TRANS_SLEEP_OFF 0x00 #define TRANS_SLEEP_ON 0x04 #define TRANS_SLEEP_MASK 0x0C #define SMPS_CMD_MASK 0xC0 #define SMPS_VSEL_MASK 0x3F #define LDO_VSEL_MASK 0x1F #define TPS80031_MISC2_ADD 0xE5 #define MISC2_LDOUSB_IN_VSYS 0x10 #define MISC2_LDOUSB_IN_PMID 0x08 #define MISC2_LDOUSB_IN_MASK 0x18 #define MISC2_LDO3_SEL_VIB_VAL BIT(0) #define MISC2_LDO3_SEL_VIB_MASK 0x1 #define CHARGERUSB_CTRL3_ADD 0xEA #define BOOST_HW_PWR_EN BIT(5) #define BOOST_HW_PWR_EN_MASK BIT(5) #define CHARGERUSB_CTRL1_ADD 0xE8 #define OPA_MODE_EN BIT(6) #define OPA_MODE_EN_MASK BIT(6) #define USB_VBUS_CTRL_SET 0x04 #define USB_VBUS_CTRL_CLR 0x05 #define VBUS_DISCHRG 0x20 #define EXT_PWR_REQ (PWR_REQ_INPUT_PREQ1 | PWR_REQ_INPUT_PREQ2 | \ PWR_REQ_INPUT_PREQ3) struct tps80031_regulator { /* Regulator register address.*/ u8 trans_reg; u8 state_reg; u8 force_reg; u8 volt_reg; u8 volt_id; uint8_t trans_reg_cache; uint8_t state_reg_cache; uint8_t force_reg_cache; uint8_t volt_reg_cache; /* twl resource ID, for resource control state machine */ u8 id; /* chip constraints on regulator behavior */ u16 min_mV; u16 max_mV; /* regulator specific turn-on delay */ int delay; u8 flags; unsigned int platform_flags; unsigned int ext_ctrl_flag; /* used by regulator core */ struct regulator_desc desc; /* Device */ struct device *dev; /*Power request bits */ int preq_bit; }; static inline struct device *to_tps80031_dev(struct regulator_dev *rdev) { return rdev_get_dev(rdev)->parent->parent; } static int tps80031_regulator_enable_time(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); return ri->delay; } static u8 tps80031_get_smps_offset(struct device *parent) { u8 value; int ret; ret = tps80031_read(parent, SLAVE_ID1, PMC_SMPS_OFFSET_ADD, &value); if (ret < 0) { dev_err(parent, "Error in reading smps offset register\n"); return 0; } return value; } static u8 tps80031_get_smps_mult(struct device *parent) { u8 value; int ret; ret = tps80031_read(parent, SLAVE_ID1, PMC_SMPS_MULT_ADD, &value); if (ret < 0) { dev_err(parent, "Error in reading smps mult register\n"); return 0; } return value; } static int tps80031_reg_is_enabled(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); if (ri->ext_ctrl_flag & EXT_PWR_REQ) return true; return ((ri->state_reg_cache & STATE_MASK) == STATE_ON); } static int tps80031_reg_enable(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); int ret; uint8_t reg_val; if (ri->ext_ctrl_flag & EXT_PWR_REQ) return 0; reg_val = (ri->state_reg_cache & ~STATE_MASK) | (STATE_ON & STATE_MASK); ret = tps80031_write(parent, SLAVE_ID1, ri->state_reg, reg_val); if (ret < 0) { dev_err(&rdev->dev, "Error in writing the STATE register\n"); return ret; } ri->state_reg_cache = reg_val; udelay(ri->delay); return ret; } static int tps80031_reg_disable(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); int ret; uint8_t reg_val; if (ri->ext_ctrl_flag & EXT_PWR_REQ) return 0; reg_val = (ri->state_reg_cache & ~STATE_MASK) | (STATE_OFF & STATE_MASK); ret = tps80031_write(parent, SLAVE_ID1, ri->state_reg, reg_val); if (ret < 0) dev_err(&rdev->dev, "Error in writing the STATE register\n"); else ri->state_reg_cache = reg_val; return ret; } /* * DCDC status and control */ static int tps80031dcdc_list_voltage(struct regulator_dev *rdev, unsigned index) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); int voltage = 0; switch (ri->flags) { case 0: if (index == 0) voltage = 0; else if (index < 58) voltage = (607700 + (12660 * (index - 1))); else if (index == 58) voltage = 1350 * 1000; else if (index == 59) voltage = 1500 * 1000; else if (index == 60) voltage = 1800 * 1000; else if (index == 61) voltage = 1900 * 1000; else if (index == 62) voltage = 2100 * 1000; break; case DCDC_OFFSET_EN: if (index == 0) voltage = 0; else if (index < 58) voltage = (700000 + (12500 * (index - 1))); else if (index == 58) voltage = 1350 * 1000; else if (index == 59) voltage = 1500 * 1000; else if (index == 60) voltage = 1800 * 1000; else if (index == 61) voltage = 1900 * 1000; else if (index == 62) voltage = 2100 * 1000; break; case DCDC_EXTENDED_EN: if (index == 0) voltage = 0; else if (index < 58) voltage = (1852000 + (38600 * (index - 1))); else if (index == 58) voltage = 2084 * 1000; else if (index == 59) voltage = 2315 * 1000; else if (index == 60) voltage = 2778 * 1000; else if (index == 61) voltage = 2932 * 1000; else if (index == 62) voltage = 3241 * 1000; break; case DCDC_OFFSET_EN|DCDC_EXTENDED_EN: if (index == 0) voltage = 0; else if (index < 58) voltage = (2161000 + (38600 * (index - 1))); else if (index == 58) voltage = 4167 * 1000; else if (index == 59) voltage = 2315 * 1000; else if (index == 60) voltage = 2778 * 1000; else if (index == 61) voltage = 2932 * 1000; else if (index == 62) voltage = 3241 * 1000; break; } return voltage; } static int __tps80031_dcdc_set_voltage(struct device *parent, struct tps80031_regulator *ri, int min_uV, int max_uV, unsigned *selector) { int vsel = 0; int ret; switch (ri->flags) { case 0: if (min_uV == 0) vsel = 0; else if ((min_uV >= 607700) && (min_uV <= 1300000)) { int cal_volt; vsel = (10 * (min_uV - 607700)) / 1266; if (vsel % 100) vsel += 100; vsel /= 100; vsel++; cal_volt = (607700 + (12660 * (vsel - 1))); if (cal_volt > max_uV) return -EINVAL; } else if ((min_uV > 1900000) && (max_uV >= 2100000)) vsel = 62; else if ((min_uV > 1800000) && (max_uV >= 1900000)) vsel = 61; else if ((min_uV > 1500000) && (max_uV >= 1800000)) vsel = 60; else if ((min_uV > 1350000) && (max_uV >= 1500000)) vsel = 59; else if ((min_uV > 1300000) && (max_uV >= 1350000)) vsel = 58; else return -EINVAL; break; case DCDC_OFFSET_EN: if (min_uV == 0) vsel = 0; else if ((min_uV >= 700000) && (min_uV <= 1420000)) { int cal_volt; vsel = (min_uV - 700000) / 125; if (vsel % 100) vsel += 100; vsel /= 100; vsel++; cal_volt = (700000 + (12500 * (vsel - 1))); if (cal_volt > max_uV) return -EINVAL; } else if ((min_uV > 1900000) && (max_uV >= 2100000)) vsel = 62; else if ((min_uV > 1800000) && (max_uV >= 1900000)) vsel = 61; else if ((min_uV > 1500000) && (max_uV >= 1800000)) vsel = 60; else if ((min_uV > 1350000) && (max_uV >= 1500000)) vsel = 59; else if ((min_uV > 1300000) && (max_uV >= 1350000)) vsel = 58; else return -EINVAL; break; case DCDC_EXTENDED_EN: if (min_uV == 0) vsel = 0; else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { vsel = (min_uV - 1852000) / 386; if (vsel % 100) vsel += 100; vsel++; } break; case DCDC_OFFSET_EN|DCDC_EXTENDED_EN: if (min_uV == 0) vsel = 0; else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { vsel = (min_uV - 2161000) / 386; if (vsel % 100) vsel += 100; vsel /= 100; vsel++; } break; } if (selector) *selector = vsel; if (ri->force_reg) { if (((ri->force_reg_cache >> 6) & 0x3) == 0) { ret = tps80031_write(parent, ri->volt_id, ri->force_reg, vsel); if (ret < 0) dev_err(ri->dev, "Error in writing the " "force register\n"); else ri->force_reg_cache = vsel; return ret; } } ret = tps80031_write(parent, ri->volt_id, ri->volt_reg, vsel); if (ret < 0) dev_err(ri->dev, "Error in writing the Voltage register\n"); else ri->volt_reg_cache = vsel; return ret; } static int tps80031dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); return __tps80031_dcdc_set_voltage(parent, ri, min_uV, max_uV, selector); } static int tps80031dcdc_get_voltage(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); uint8_t vsel = 0; int voltage = 0; if (ri->force_reg) { vsel = ri->force_reg_cache; if ((vsel & SMPS_CMD_MASK) == 0) goto decode; } vsel = ri->volt_reg_cache; decode: vsel &= SMPS_VSEL_MASK; switch (ri->flags) { case 0: if (vsel == 0) voltage = 0; else if (vsel < 58) voltage = (607700 + (12660 * (vsel - 1))); else if (vsel == 58) voltage = 1350 * 1000; else if (vsel == 59) voltage = 1500 * 1000; else if (vsel == 60) voltage = 1800 * 1000; else if (vsel == 61) voltage = 1900 * 1000; else if (vsel == 62) voltage = 2100 * 1000; break; case DCDC_OFFSET_EN: if (vsel == 0) voltage = 0; else if (vsel < 58) voltage = (700000 + (12500 * (vsel - 1))); else if (vsel == 58) voltage = 1350 * 1000; else if (vsel == 59) voltage = 1500 * 1000; else if (vsel == 60) voltage = 1800 * 1000; else if (vsel == 61) voltage = 1900 * 1000; else if (vsel == 62) voltage = 2100 * 1000; break; case DCDC_EXTENDED_EN: if (vsel == 0) voltage = 0; else if (vsel < 58) voltage = (1852000 + (38600 * (vsel - 1))); else if (vsel == 58) voltage = 2084 * 1000; else if (vsel == 59) voltage = 2315 * 1000; else if (vsel == 60) voltage = 2778 * 1000; else if (vsel == 61) voltage = 2932 * 1000; else if (vsel == 62) voltage = 3241 * 1000; break; case DCDC_EXTENDED_EN|DCDC_OFFSET_EN: if (vsel == 0) voltage = 0; else if (vsel < 58) voltage = (2161000 + (38600 * (vsel - 1))); else if (vsel == 58) voltage = 4167 * 1000; else if (vsel == 59) voltage = 2315 * 1000; else if (vsel == 60) voltage = 2778 * 1000; else if (vsel == 61) voltage = 2932 * 1000; else if (vsel == 62) voltage = 3241 * 1000; break; } return voltage; } static int tps80031ldo_list_voltage(struct regulator_dev *rdev, unsigned index) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); if (index == 0) return 0; if ((ri->desc.id == TPS80031_ID_LDO2) && (ri->flags & TRACK_MODE_ENABLE)) return (ri->min_mV + (((index - 1) * 125))/10) * 1000; return (ri->min_mV + ((index - 1) * 100)) * 1000; } static int __tps80031_ldo2_set_voltage_track_mode(struct device *parent, struct tps80031_regulator *ri, int min_uV, int max_uV) { int vsel = 0; int ret; int nvsel; if (min_uV < 600000) { vsel = 0; } else if ((min_uV >= 600000) && (max_uV <= 1300000)) { vsel = (min_uV - 600000) / 125; if (vsel % 100) vsel += 100; vsel /= 100; vsel++; } else { return -EINVAL; } /* Check for valid setting for TPS80031 or TPS80032-ES1.0 */ if ((tps80031_get_chip_info(parent) == TPS80031) || ((tps80031_get_chip_info(parent) == TPS80032) && (tps80031_get_pmu_version(parent) == 0x0))) { nvsel = vsel & 0x1F; if ((nvsel == 0x0) || (nvsel >= 0x19 && nvsel <= 0x1F)) { dev_err(ri->dev, "Invalid value for track mode LDO2 " "configuration for TPS8003x PMU\n"); return -EINVAL; } } ret = tps80031_write(parent, ri->volt_id, ri->volt_reg, vsel); if (ret < 0) dev_err(ri->dev, "Error in writing the Voltage register\n"); else ri->volt_reg_cache = vsel; return ret; } static int __tps80031_ldo_set_voltage(struct device *parent, struct tps80031_regulator *ri, int min_uV, int max_uV, unsigned *selector) { int vsel; int ret; if ((min_uV/1000 < ri->min_mV) || (max_uV/1000 > ri->max_mV)) return -EDOM; if ((ri->desc.id == TPS80031_ID_LDO2) && (ri->flags & TRACK_MODE_ENABLE)) return __tps80031_ldo2_set_voltage_track_mode(parent, ri, min_uV, max_uV); /* * Use the below formula to calculate vsel * mV = 1000mv + 100mv * (vsel - 1) */ vsel = (min_uV/1000 - 1000)/100 + 1; if (selector) *selector = vsel; ret = tps80031_write(parent, ri->volt_id, ri->volt_reg, vsel); if (ret < 0) dev_err(ri->dev, "Error in writing the Voltage register\n"); else ri->volt_reg_cache = vsel; return ret; } static int tps80031ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); return __tps80031_ldo_set_voltage(parent, ri, min_uV, max_uV, selector); } static int tps80031ldo_get_voltage(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); uint8_t vsel; if ((ri->desc.id == TPS80031_ID_LDO2) && (ri->flags & TRACK_MODE_ENABLE)) { vsel = ri->volt_reg_cache & 0x3F; return (ri->min_mV + (((vsel - 1) * 125))/10) * 1000; } vsel = ri->volt_reg_cache & LDO_VSEL_MASK; /* * Use the below formula to calculate vsel * mV = 1000mv + 100mv * (vsel - 1) */ return (1000 + (100 * (vsel - 1))) * 1000; } /* VBUS */ static int tps80031_vbus_enable_time(struct regulator_dev *rdev) { /* Enable and settling time for vbus is 3ms */ return 3000; } static int tps80031_vbus_is_enabled(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); uint8_t ctrl1, ctrl3; int ret; if (ri->platform_flags & VBUS_SW_ONLY) { ret = tps80031_read(parent, SLAVE_ID2, CHARGERUSB_CTRL1_ADD, &ctrl1); if (!ret) ret = tps80031_read(parent, SLAVE_ID2, CHARGERUSB_CTRL3_ADD, &ctrl3); if (ret < 0) { dev_err(&rdev->dev, "Error in reading control reg\n"); return ret; } if ((ctrl1 & OPA_MODE_EN) && (ctrl3 & BOOST_HW_PWR_EN)) return 1; return 0; } else { return -EIO; } } static int tps80031_vbus_enable(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); int ret; if (ri->platform_flags & VBUS_SW_ONLY) { ret = tps80031_set_bits(parent, SLAVE_ID2, CHARGERUSB_CTRL1_ADD, OPA_MODE_EN); if (!ret) ret = tps80031_set_bits(parent, SLAVE_ID2, CHARGERUSB_CTRL3_ADD, BOOST_HW_PWR_EN); if (ret < 0) { dev_err(&rdev->dev, "Error in reading control reg\n"); return ret; } udelay(ri->delay); return ret; } dev_err(&rdev->dev, "%s() is not supported with flag 0x%08x\n", __func__, ri->platform_flags); return -EIO; } static int tps80031_vbus_disable(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps80031_dev(rdev); int ret = 0; if (ri->platform_flags & VBUS_SW_ONLY) { if (ri->platform_flags & VBUS_DISCHRG_EN_PDN) ret = tps80031_write(parent, SLAVE_ID2, USB_VBUS_CTRL_SET, VBUS_DISCHRG); if (!ret) ret = tps80031_clr_bits(parent, SLAVE_ID2, CHARGERUSB_CTRL1_ADD, OPA_MODE_EN); if (!ret) ret = tps80031_clr_bits(parent, SLAVE_ID2, CHARGERUSB_CTRL3_ADD, BOOST_HW_PWR_EN); if (!ret) mdelay((ri->delay + 999)/1000); if (ri->platform_flags & VBUS_DISCHRG_EN_PDN) tps80031_write(parent, SLAVE_ID2, USB_VBUS_CTRL_CLR, VBUS_DISCHRG); if (ret < 0) dev_err(&rdev->dev, "Error in reading control reg\n"); return ret; } dev_err(&rdev->dev, "%s() is not supported with flag 0x%08x\n", __func__, ri->platform_flags); return -EIO; } static int tps80031vbus_get_voltage(struct regulator_dev *rdev) { int ret; ret = tps80031_vbus_is_enabled(rdev); if (ret > 0) return 5000000; return ret; } static struct regulator_ops tps80031dcdc_ops = { .list_voltage = tps80031dcdc_list_voltage, .set_voltage = tps80031dcdc_set_voltage, .get_voltage = tps80031dcdc_get_voltage, .enable = tps80031_reg_enable, .disable = tps80031_reg_disable, .is_enabled = tps80031_reg_is_enabled, .enable_time = tps80031_regulator_enable_time, }; static struct regulator_ops tps80031ldo_ops = { .list_voltage = tps80031ldo_list_voltage, .set_voltage = tps80031ldo_set_voltage, .get_voltage = tps80031ldo_get_voltage, .enable = tps80031_reg_enable, .disable = tps80031_reg_disable, .is_enabled = tps80031_reg_is_enabled, .enable_time = tps80031_regulator_enable_time, }; static struct regulator_ops tps80031vbus_ops = { .get_voltage = tps80031vbus_get_voltage, .enable = tps80031_vbus_enable, .disable = tps80031_vbus_disable, .is_enabled = tps80031_vbus_is_enabled, .enable_time = tps80031_vbus_enable_time, }; #define TPS80031_REG(_id, _trans_reg, _state_reg, _force_reg, _volt_reg, \ _volt_id, min_mVolts, max_mVolts, _ops, _n_volt, _delay, \ _preq_bit) \ { \ .trans_reg = _trans_reg, \ .state_reg = _state_reg, \ .force_reg = _force_reg, \ .volt_reg = _volt_reg, \ .volt_id = _volt_id, \ .id = TPS80031_ID_##_id, \ .min_mV = min_mVolts, \ .max_mV = max_mVolts, \ .desc = { \ .name = tps80031_rails(_id), \ .id = TPS80031_ID_##_id, \ .n_voltages = _n_volt, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ .delay = _delay, \ .preq_bit = _preq_bit, \ } static struct tps80031_regulator tps80031_regulator[] = { TPS80031_REG(VIO, 0x47, 0x48, 0x49, 0x4A, SLAVE_ID0, 600, 2100, tps80031dcdc_ops, 63, 500, 4), TPS80031_REG(SMPS1, 0x53, 0x54, 0x55, 0x56, SLAVE_ID0, 600, 2100, tps80031dcdc_ops, 63, 500, 0), TPS80031_REG(SMPS2, 0x59, 0x5A, 0x5B, 0x5C, SLAVE_ID0, 600, 2100, tps80031dcdc_ops, 63, 500, 1), TPS80031_REG(SMPS3, 0x65, 0x66, 0x00, 0x68, SLAVE_ID1, 600, 2100, tps80031dcdc_ops, 63, 500, 2), TPS80031_REG(SMPS4, 0x41, 0x42, 0x00, 0x44, SLAVE_ID1, 600, 2100, tps80031dcdc_ops, 63, 500, 3), TPS80031_REG(LDO1, 0x9D, 0x9E, 0x00, 0x9F, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 8), TPS80031_REG(LDO2, 0x85, 0x86, 0x00, 0x87, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 9), TPS80031_REG(LDO3, 0x8D, 0x8E, 0x00, 0x8F, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 10), TPS80031_REG(LDO4, 0x89, 0x8A, 0x00, 0x8B, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 11), TPS80031_REG(LDO5, 0x99, 0x9A, 0x00, 0x9B, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 12), TPS80031_REG(LDO6, 0x91, 0x92, 0x00, 0x93, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 13), TPS80031_REG(LDO7, 0xA5, 0xA6, 0x00, 0xA7, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 14), TPS80031_REG(LDOUSB, 0xA1, 0xA2, 0x00, 0xA3, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 5), TPS80031_REG(LDOLN, 0x95, 0x96, 0x00, 0x97, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, 15), TPS80031_REG(VANA, 0x81, 0x82, 0x00, 0x83, SLAVE_ID1, 1000, 3300, tps80031ldo_ops, 25, 500, -1), TPS80031_REG(VBUS, 0x0, 0x0, 0x00, 0x0, SLAVE_ID1, 0, 5000, tps80031vbus_ops, 2, 200000, -1), }; static int tps80031_power_req_config(struct device *parent, struct tps80031_regulator *ri, struct tps80031_regulator_platform_data *tps80031_pdata) { int ret; uint8_t reg_val; if (ri->preq_bit < 0) return 0; ret = tps80031_ext_power_req_config(parent, ri->ext_ctrl_flag, ri->preq_bit, ri->state_reg, ri->trans_reg); if (!ret) ret = tps80031_read(parent, SLAVE_ID1, ri->trans_reg, &ri->trans_reg_cache); if (!ret && ri->state_reg) ret = tps80031_read(parent, SLAVE_ID1, ri->state_reg, &ri->state_reg_cache); if (ret < 0) { dev_err(ri->dev, "%s() fails\n", __func__); return ret; } if (tps80031_pdata->ext_ctrl_flag & (PWR_OFF_ON_SLEEP | PWR_ON_ON_SLEEP)) { reg_val = (ri->trans_reg_cache & ~0xC); if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP) reg_val |= 0x4; ret = tps80031_write(parent, SLAVE_ID1, ri->trans_reg, reg_val); if (ret < 0) dev_err(ri->dev, "Not able to write reg 0x%02x\n", ri->trans_reg); else ri->trans_reg_cache = reg_val; } return ret; } static int tps80031_regulator_preinit(struct device *parent, struct tps80031_regulator *ri, struct tps80031_regulator_platform_data *tps80031_pdata) { int ret = 0; uint8_t reg_val; if (ri->desc.id == TPS80031_ID_LDOUSB) { if (ri->platform_flags & USBLDO_INPUT_VSYS) ret = tps80031_update(parent, SLAVE_ID1, TPS80031_MISC2_ADD, MISC2_LDOUSB_IN_VSYS, MISC2_LDOUSB_IN_MASK); if (ri->platform_flags & USBLDO_INPUT_PMID) ret = tps80031_update(parent, SLAVE_ID1, TPS80031_MISC2_ADD, MISC2_LDOUSB_IN_PMID, MISC2_LDOUSB_IN_MASK); if (ret < 0) { dev_err(ri->dev, "Not able to configure the rail " "LDOUSB as per platform data error %d\n", ret); return ret; } } if (ri->desc.id == TPS80031_ID_LDO3) { if (ri->platform_flags & LDO3_OUTPUT_VIB) ret = tps80031_update(parent, SLAVE_ID1, TPS80031_MISC2_ADD, MISC2_LDO3_SEL_VIB_VAL, MISC2_LDO3_SEL_VIB_MASK); if (ret < 0) { dev_err(ri->dev, "Not able to configure the rail " "LDO3 as per platform data error %d\n", ret); return ret; } } if (!tps80031_pdata->init_apply) return 0; if (tps80031_pdata->init_uV >= 0) { switch (ri->desc.id) { case TPS80031_ID_VIO: case TPS80031_ID_SMPS1: case TPS80031_ID_SMPS2: case TPS80031_ID_SMPS3: case TPS80031_ID_SMPS4: ret = __tps80031_dcdc_set_voltage(parent, ri, tps80031_pdata->init_uV, tps80031_pdata->init_uV, 0); break; case TPS80031_ID_LDO1: case TPS80031_ID_LDO2: case TPS80031_ID_LDO3: case TPS80031_ID_LDO4: case TPS80031_ID_LDO5: case TPS80031_ID_LDO6: case TPS80031_ID_LDO7: case TPS80031_ID_LDOUSB: case TPS80031_ID_LDOLN: case TPS80031_ID_VANA: ret = __tps80031_ldo_set_voltage(parent, ri, tps80031_pdata->init_uV, tps80031_pdata->init_uV, 0); break; default: ret = -EINVAL; break; } if (ret < 0) { dev_err(ri->dev, "Not able to initialize voltage %d " "for rail %d err %d\n", tps80031_pdata->init_uV, ri->desc.id, ret); return ret; } } if (tps80031_pdata->init_enable) reg_val = (ri->state_reg_cache & ~STATE_MASK) | (STATE_ON & STATE_MASK); else reg_val = (ri->state_reg_cache & ~STATE_MASK) | (STATE_OFF & STATE_MASK); ret = tps80031_write(parent, SLAVE_ID1, ri->state_reg, reg_val); if (ret < 0) dev_err(ri->dev, "Not able to %s rail %d err %d\n", (tps80031_pdata->init_enable) ? "enable" : "disable", ri->desc.id, ret); else ri->state_reg_cache = reg_val; return ret; } static inline struct tps80031_regulator *find_regulator_info(int id) { struct tps80031_regulator *ri; int i; for (i = 0; i < ARRAY_SIZE(tps80031_regulator); i++) { ri = &tps80031_regulator[i]; if (ri->desc.id == id) return ri; } return NULL; } static void check_smps_mode_mult(struct device *parent, struct tps80031_regulator *ri) { int mult_offset; switch (ri->desc.id) { case TPS80031_ID_VIO: mult_offset = SMPS_MULTOFFSET_VIO; break; case TPS80031_ID_SMPS1: mult_offset = SMPS_MULTOFFSET_SMPS1; break; case TPS80031_ID_SMPS2: mult_offset = SMPS_MULTOFFSET_SMPS2; break; case TPS80031_ID_SMPS3: mult_offset = SMPS_MULTOFFSET_SMPS3; break; case TPS80031_ID_SMPS4: mult_offset = SMPS_MULTOFFSET_SMPS4; break; case TPS80031_ID_LDO2: ri->flags = (tps80031_get_smps_mult(parent) & (1 << 5)) ? TRACK_MODE_ENABLE : 0; /* TRACK mode the ldo2 varies from 600mV to 1300mV */ if (ri->flags & TRACK_MODE_ENABLE) { ri->min_mV = 600; ri->max_mV = 1300; ri->desc.n_voltages = 57; } return; default: return; } ri->flags = (tps80031_get_smps_offset(parent) & mult_offset) ? DCDC_OFFSET_EN : 0; ri->flags |= (tps80031_get_smps_mult(parent) & mult_offset) ? DCDC_EXTENDED_EN : 0; return; } static inline int tps80031_cache_regulator_register(struct device *parent, struct tps80031_regulator *ri) { int ret; ret = tps80031_read(parent, SLAVE_ID1, ri->trans_reg, &ri->trans_reg_cache); if (!ret && ri->state_reg) ret = tps80031_read(parent, SLAVE_ID1, ri->state_reg, &ri->state_reg_cache); if (!ret && ri->force_reg) ret = tps80031_read(parent, ri->volt_id, ri->force_reg, &ri->force_reg_cache); if (!ret && ri->volt_reg) ret = tps80031_read(parent, ri->volt_id, ri->volt_reg, &ri->volt_reg_cache); return ret; } static int __devinit tps80031_regulator_probe(struct platform_device *pdev) { struct tps80031_regulator *ri = NULL; struct regulator_dev *rdev; struct tps80031_regulator_platform_data *tps_pdata; int id = pdev->id; int err; dev_dbg(&pdev->dev, "Probing reulator %d\n", id); ri = find_regulator_info(id); if (ri == NULL) { dev_err(&pdev->dev, "invalid regulator ID specified\n"); return -EINVAL; } tps_pdata = pdev->dev.platform_data; ri->dev = &pdev->dev; if (tps_pdata->delay_us > 0) ri->delay = tps_pdata->delay_us; check_smps_mode_mult(pdev->dev.parent, ri); ri->platform_flags = tps_pdata->flags; ri->ext_ctrl_flag = tps_pdata->ext_ctrl_flag; err = tps80031_cache_regulator_register(pdev->dev.parent, ri); if (err) { dev_err(&pdev->dev, "Register access for caching is failed\n"); return err; } err = tps80031_regulator_preinit(pdev->dev.parent, ri, tps_pdata); if (err) return err; err = tps80031_power_req_config(pdev->dev.parent, ri, tps_pdata); if (err) return err; rdev = regulator_register(&ri->desc, &pdev->dev, &tps_pdata->regulator, ri); if (IS_ERR_OR_NULL(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); return 0; } static int __devexit tps80031_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); regulator_unregister(rdev); return 0; } static struct platform_driver tps80031_regulator_driver = { .driver = { .name = "tps80031-regulator", .owner = THIS_MODULE, }, .probe = tps80031_regulator_probe, .remove = __devexit_p(tps80031_regulator_remove), }; static int __init tps80031_regulator_init(void) { return platform_driver_register(&tps80031_regulator_driver); } subsys_initcall(tps80031_regulator_init); static void __exit tps80031_regulator_exit(void) { platform_driver_unregister(&tps80031_regulator_driver); } module_exit(tps80031_regulator_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Regulator Driver for TI TPS80031 PMIC"); MODULE_ALIAS("platform:tps80031-regulator");