Loading Documentation/devicetree/bindings/regulator/tps65090.txt +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,10 @@ Optional properties: number should be provided. If it is externally controlled and no GPIO entry then driver will just configure this rails as external control and will not provide any enable/disable APIs. - ti,overcurrent-wait: This is applicable to FET registers, which have a poorly defined "overcurrent wait" field. If this property is present it should be between 0 - 3. If this property isn't present we won't touch the "overcurrent wait" field and we'll leave it to the BIOS/EC to deal with. Each regulator is defined using the standard binding for regulators. Loading drivers/regulator/s5m8767.c +12 −25 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ struct s5m8767_info { struct device *dev; struct sec_pmic_dev *iodev; int num_regulators; struct regulator_dev **rdev; struct sec_opmode_data *opmode; int ramp_delay; Loading Loading @@ -529,16 +528,6 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev, return 0; } static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev, struct sec_regulator_data *rdata, struct device_node *reg_np) { rdata->ext_control_gpio = of_get_named_gpio(reg_np, "s5m8767,pmic-ext-control-gpios", 0); if (!gpio_is_valid(rdata->ext_control_gpio)) rdata->ext_control_gpio = 0; } static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, struct sec_platform_data *pdata) { Loading Loading @@ -587,7 +576,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, continue; } s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np); rdata->ext_control_gpio = of_get_named_gpio(reg_np, "s5m8767,pmic-ext-control-gpios", 0); rdata->id = i; rdata->initdata = of_get_regulator_init_data( Loading Loading @@ -695,7 +685,6 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = iodev->pdata; struct regulator_config config = { }; struct regulator_dev **rdev; struct s5m8767_info *s5m8767; int i, ret, size, buck_init; Loading Loading @@ -737,11 +726,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) return -ENOMEM; size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!s5m8767->rdev) return -ENOMEM; rdev = s5m8767->rdev; s5m8767->dev = &pdev->dev; s5m8767->iodev = iodev; s5m8767->num_regulators = pdata->num_regulators; Loading Loading @@ -938,6 +923,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) const struct sec_voltage_desc *desc; int id = pdata->regulators[i].id; int enable_reg, enable_val; struct regulator_dev *rdev; desc = reg_voltage_map[id]; if (desc) { Loading @@ -964,26 +950,27 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) config.driver_data = s5m8767; config.regmap = iodev->regmap_pmic; config.of_node = pdata->regulators[i].reg_node; config.ena_gpio = config.ena_gpio_flags = 0; if (pdata->regulators[i].ext_control_gpio) config.ena_gpio = -EINVAL; config.ena_gpio_flags = 0; if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) s5m8767_regulator_config_ext_control(s5m8767, &pdata->regulators[i], &config); rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(s5m8767->dev, "regulator init failed for %d\n", id); return ret; } if (pdata->regulators[i].ext_control_gpio) { ret = s5m8767_enable_ext_control(s5m8767, rdev[i]); if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) { ret = s5m8767_enable_ext_control(s5m8767, rdev); if (ret < 0) { dev_err(s5m8767->dev, "failed to enable gpio control over %s: %d\n", rdev[i]->desc->name, ret); rdev->desc->name, ret); return ret; } } Loading drivers/regulator/tps65090-regulator.c +199 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ */ #include <linux/module.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/gpio.h> #include <linux/of_gpio.h> Loading @@ -28,49 +29,216 @@ #include <linux/regulator/of_regulator.h> #include <linux/mfd/tps65090.h> #define MAX_CTRL_READ_TRIES 5 #define MAX_FET_ENABLE_TRIES 1000 #define CTRL_EN_BIT 0 /* Regulator enable bit, active high */ #define CTRL_WT_BIT 2 /* Regulator wait time 0 bit */ #define CTRL_PG_BIT 4 /* Regulator power good bit, 1=good */ #define CTRL_TO_BIT 7 /* Regulator timeout bit, 1=wait */ #define MAX_OVERCURRENT_WAIT 3 /* Overcurrent wait must be <= this */ /** * struct tps65090_regulator - Per-regulator data for a tps65090 regulator * * @dev: Pointer to our device. * @desc: The struct regulator_desc for the regulator. * @rdev: The struct regulator_dev for the regulator. * @overcurrent_wait_valid: True if overcurrent_wait is valid. * @overcurrent_wait: For FETs, the value to put in the WTFET bitfield. */ struct tps65090_regulator { struct device *dev; struct regulator_desc *desc; struct regulator_dev *rdev; bool overcurrent_wait_valid; int overcurrent_wait; }; static struct regulator_ops tps65090_ext_control_ops = { }; static struct regulator_ops tps65090_reg_contol_ops = { /** * tps65090_reg_set_overcurrent_wait - Setup overcurrent wait * * This will set the overcurrent wait time based on what's in the regulator * info. * * @ri: Overall regulator data * @rdev: Regulator device * * Return: 0 if no error, non-zero if there was an error writing the register. */ static int tps65090_reg_set_overcurrent_wait(struct tps65090_regulator *ri, struct regulator_dev *rdev) { int ret; ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, MAX_OVERCURRENT_WAIT << CTRL_WT_BIT, ri->overcurrent_wait << CTRL_WT_BIT); if (ret) { dev_err(&rdev->dev, "Error updating overcurrent wait %#x\n", rdev->desc->enable_reg); } return ret; } /** * tps65090_try_enable_fet - Try to enable a FET * * @rdev: Regulator device * * Return: 0 if ok, -ENOTRECOVERABLE if the FET power good bit did not get * set, or some other -ve value if another error occurred (e.g. i2c error) */ static int tps65090_try_enable_fet(struct regulator_dev *rdev) { unsigned int control; int ret, i; ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, rdev->desc->enable_mask); if (ret < 0) { dev_err(&rdev->dev, "Error in updating reg %#x\n", rdev->desc->enable_reg); return ret; } for (i = 0; i < MAX_CTRL_READ_TRIES; i++) { ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &control); if (ret < 0) return ret; if (!(control & BIT(CTRL_TO_BIT))) break; usleep_range(1000, 1500); } if (!(control & BIT(CTRL_PG_BIT))) return -ENOTRECOVERABLE; return 0; } /** * tps65090_fet_enable - Enable a FET, trying a few times if it fails * * Some versions of the tps65090 have issues when turning on the FETs. * This function goes through several steps to ensure the best chance of the * FET going on. Specifically: * - We'll make sure that we bump the "overcurrent wait" to the maximum, which * increases the chances that we'll turn on properly. * - We'll retry turning the FET on multiple times (turning off in between). * * @rdev: Regulator device * * Return: 0 if ok, non-zero if it fails. */ static int tps65090_fet_enable(struct regulator_dev *rdev) { int ret, tries; /* * Try enabling multiple times until we succeed since sometimes the * first try times out. */ tries = 0; while (true) { ret = tps65090_try_enable_fet(rdev); if (!ret) break; if (ret != -ENOTRECOVERABLE || tries == MAX_FET_ENABLE_TRIES) goto err; /* Try turning the FET off (and then on again) */ ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, 0); if (ret) goto err; tries++; } if (tries) dev_warn(&rdev->dev, "reg %#x enable ok after %d tries\n", rdev->desc->enable_reg, tries); return 0; err: dev_warn(&rdev->dev, "reg %#x enable failed\n", rdev->desc->enable_reg); WARN_ON(1); return ret; } static struct regulator_ops tps65090_reg_control_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; static struct regulator_ops tps65090_fet_control_ops = { .enable = tps65090_fet_enable, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; static struct regulator_ops tps65090_ldo_ops = { }; #define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \ #define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _ops) \ { \ .name = "TPS65090_RAILS"#_id, \ .supply_name = _sname, \ .id = TPS65090_REGULATOR_##_id, \ .ops = &_ops, \ .enable_reg = _en_reg, \ .enable_mask = BIT(0), \ .enable_val = _en_bits, \ .enable_mask = _en_bits, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ } static struct regulator_desc tps65090_regulator_desc[] = { tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_reg_contol_ops), tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_reg_contol_ops), tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_reg_contol_ops), tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_reg_contol_ops), tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_reg_contol_ops), tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_reg_contol_ops), tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_reg_contol_ops), tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), tps65090_REG_DESC(LDO1, "vsys-l1", 0, tps65090_ldo_ops), tps65090_REG_DESC(LDO2, "vsys-l2", 0, tps65090_ldo_ops), tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT), tps65090_reg_control_ops), tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT), tps65090_reg_control_ops), tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT), tps65090_reg_control_ops), tps65090_REG_DESC(FET1, "infet1", 0x0F, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET2, "infet2", 0x10, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET3, "infet3", 0x11, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET4, "infet4", 0x12, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET5, "infet5", 0x13, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET6, "infet6", 0x14, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET7, "infet7", 0x15, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(LDO1, "vsys-l1", 0, 0, tps65090_ldo_ops), tps65090_REG_DESC(LDO2, "vsys-l2", 0, 0, tps65090_ldo_ops), }; static inline bool is_dcdc(int id) Loading Loading @@ -209,6 +377,11 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( rpdata->gpio = of_get_named_gpio(np, "dcdc-ext-control-gpios", 0); if (of_property_read_u32(tps65090_matches[idx].of_node, "ti,overcurrent-wait", &rpdata->overcurrent_wait) == 0) rpdata->overcurrent_wait_valid = true; tps65090_pdata->reg_pdata[idx] = rpdata; } return tps65090_pdata; Loading Loading @@ -258,6 +431,11 @@ static int tps65090_regulator_probe(struct platform_device *pdev) ri = &pmic[num]; ri->dev = &pdev->dev; ri->desc = &tps65090_regulator_desc[num]; if (tps_pdata) { ri->overcurrent_wait_valid = tps_pdata->overcurrent_wait_valid; ri->overcurrent_wait = tps_pdata->overcurrent_wait; } /* * TPS5090 DCDC support the control from external digital input. Loading Loading @@ -299,6 +477,12 @@ static int tps65090_regulator_probe(struct platform_device *pdev) } ri->rdev = rdev; if (ri->overcurrent_wait_valid) { ret = tps65090_reg_set_overcurrent_wait(ri, rdev); if (ret < 0) return ret; } /* Enable external control if it is require */ if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && tps_pdata->enable_ext_control) { Loading drivers/regulator/tps65217-regulator.c +1 −3 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, }; static const struct regulator_desc regulators[] = { Loading Loading @@ -257,9 +258,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) pdev->name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ tps->rdev[i] = rdev; } return 0; } Loading drivers/regulator/tps65218-regulator.c +10 −27 Original line number Diff line number Diff line Loading @@ -27,12 +27,10 @@ #include <linux/regulator/machine.h> #include <linux/mfd/tps65218.h> static unsigned int tps65218_ramp_delay = 4000; enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \ _lr, _nlr) \ _lr, _nlr, _delay) \ { \ .name = _name, \ .id = _id, \ Loading @@ -47,6 +45,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; .volt_table = _t, \ .linear_ranges = _lr, \ .n_linear_ranges = _nlr, \ .ramp_delay = _delay, \ } \ #define TPS65218_INFO(_id, _nm, _min, _max) \ Loading Loading @@ -152,22 +151,6 @@ static int tps65218_pmic_disable(struct regulator_dev *dev) dev->desc->enable_mask, TPS65218_PROTECT_L1); } static int tps65218_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { int old_uv, new_uv; old_uv = regulator_list_voltage_linear_range(rdev, old_selector); if (old_uv < 0) return old_uv; new_uv = regulator_list_voltage_linear_range(rdev, new_selector); if (new_uv < 0) return new_uv; return DIV_ROUND_UP(abs(old_uv - new_uv), tps65218_ramp_delay); } /* Operations permitted on DCDC1, DCDC2 */ static struct regulator_ops tps65218_dcdc12_ops = { .is_enabled = regulator_is_enabled_regmap, Loading @@ -177,7 +160,7 @@ static struct regulator_ops tps65218_dcdc12_ops = { .set_voltage_sel = tps65218_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .set_voltage_time_sel = tps65218_set_voltage_time_sel, .set_voltage_time_sel = regulator_set_voltage_time_sel, }; /* Operations permitted on DCDC3, DCDC4 and LDO1 */ Loading @@ -203,33 +186,33 @@ static const struct regulator_desc regulators[] = { TPS65218_REG_CONTROL_DCDC1, TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL, dcdc1_dcdc2_ranges, 2), dcdc1_dcdc2_ranges, 2, 4000), TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL, dcdc1_dcdc2_ranges, 2), dcdc1_dcdc2_ranges, 2, 4000), TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC3_EN, NULL, ldo1_dcdc3_ranges, 2), ldo1_dcdc3_ranges, 2, 0), TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL, dcdc4_ranges, 2), dcdc4_ranges, 2, 0), TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0), TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0, 0), TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0), TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, 2), 2, 0), }; static int tps65218_regulator_probe(struct platform_device *pdev) Loading Loading
Documentation/devicetree/bindings/regulator/tps65090.txt +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,10 @@ Optional properties: number should be provided. If it is externally controlled and no GPIO entry then driver will just configure this rails as external control and will not provide any enable/disable APIs. - ti,overcurrent-wait: This is applicable to FET registers, which have a poorly defined "overcurrent wait" field. If this property is present it should be between 0 - 3. If this property isn't present we won't touch the "overcurrent wait" field and we'll leave it to the BIOS/EC to deal with. Each regulator is defined using the standard binding for regulators. Loading
drivers/regulator/s5m8767.c +12 −25 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ struct s5m8767_info { struct device *dev; struct sec_pmic_dev *iodev; int num_regulators; struct regulator_dev **rdev; struct sec_opmode_data *opmode; int ramp_delay; Loading Loading @@ -529,16 +528,6 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev, return 0; } static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev, struct sec_regulator_data *rdata, struct device_node *reg_np) { rdata->ext_control_gpio = of_get_named_gpio(reg_np, "s5m8767,pmic-ext-control-gpios", 0); if (!gpio_is_valid(rdata->ext_control_gpio)) rdata->ext_control_gpio = 0; } static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, struct sec_platform_data *pdata) { Loading Loading @@ -587,7 +576,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, continue; } s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np); rdata->ext_control_gpio = of_get_named_gpio(reg_np, "s5m8767,pmic-ext-control-gpios", 0); rdata->id = i; rdata->initdata = of_get_regulator_init_data( Loading Loading @@ -695,7 +685,6 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = iodev->pdata; struct regulator_config config = { }; struct regulator_dev **rdev; struct s5m8767_info *s5m8767; int i, ret, size, buck_init; Loading Loading @@ -737,11 +726,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) return -ENOMEM; size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!s5m8767->rdev) return -ENOMEM; rdev = s5m8767->rdev; s5m8767->dev = &pdev->dev; s5m8767->iodev = iodev; s5m8767->num_regulators = pdata->num_regulators; Loading Loading @@ -938,6 +923,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) const struct sec_voltage_desc *desc; int id = pdata->regulators[i].id; int enable_reg, enable_val; struct regulator_dev *rdev; desc = reg_voltage_map[id]; if (desc) { Loading @@ -964,26 +950,27 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) config.driver_data = s5m8767; config.regmap = iodev->regmap_pmic; config.of_node = pdata->regulators[i].reg_node; config.ena_gpio = config.ena_gpio_flags = 0; if (pdata->regulators[i].ext_control_gpio) config.ena_gpio = -EINVAL; config.ena_gpio_flags = 0; if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) s5m8767_regulator_config_ext_control(s5m8767, &pdata->regulators[i], &config); rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(s5m8767->dev, "regulator init failed for %d\n", id); return ret; } if (pdata->regulators[i].ext_control_gpio) { ret = s5m8767_enable_ext_control(s5m8767, rdev[i]); if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) { ret = s5m8767_enable_ext_control(s5m8767, rdev); if (ret < 0) { dev_err(s5m8767->dev, "failed to enable gpio control over %s: %d\n", rdev[i]->desc->name, ret); rdev->desc->name, ret); return ret; } } Loading
drivers/regulator/tps65090-regulator.c +199 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ */ #include <linux/module.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/gpio.h> #include <linux/of_gpio.h> Loading @@ -28,49 +29,216 @@ #include <linux/regulator/of_regulator.h> #include <linux/mfd/tps65090.h> #define MAX_CTRL_READ_TRIES 5 #define MAX_FET_ENABLE_TRIES 1000 #define CTRL_EN_BIT 0 /* Regulator enable bit, active high */ #define CTRL_WT_BIT 2 /* Regulator wait time 0 bit */ #define CTRL_PG_BIT 4 /* Regulator power good bit, 1=good */ #define CTRL_TO_BIT 7 /* Regulator timeout bit, 1=wait */ #define MAX_OVERCURRENT_WAIT 3 /* Overcurrent wait must be <= this */ /** * struct tps65090_regulator - Per-regulator data for a tps65090 regulator * * @dev: Pointer to our device. * @desc: The struct regulator_desc for the regulator. * @rdev: The struct regulator_dev for the regulator. * @overcurrent_wait_valid: True if overcurrent_wait is valid. * @overcurrent_wait: For FETs, the value to put in the WTFET bitfield. */ struct tps65090_regulator { struct device *dev; struct regulator_desc *desc; struct regulator_dev *rdev; bool overcurrent_wait_valid; int overcurrent_wait; }; static struct regulator_ops tps65090_ext_control_ops = { }; static struct regulator_ops tps65090_reg_contol_ops = { /** * tps65090_reg_set_overcurrent_wait - Setup overcurrent wait * * This will set the overcurrent wait time based on what's in the regulator * info. * * @ri: Overall regulator data * @rdev: Regulator device * * Return: 0 if no error, non-zero if there was an error writing the register. */ static int tps65090_reg_set_overcurrent_wait(struct tps65090_regulator *ri, struct regulator_dev *rdev) { int ret; ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, MAX_OVERCURRENT_WAIT << CTRL_WT_BIT, ri->overcurrent_wait << CTRL_WT_BIT); if (ret) { dev_err(&rdev->dev, "Error updating overcurrent wait %#x\n", rdev->desc->enable_reg); } return ret; } /** * tps65090_try_enable_fet - Try to enable a FET * * @rdev: Regulator device * * Return: 0 if ok, -ENOTRECOVERABLE if the FET power good bit did not get * set, or some other -ve value if another error occurred (e.g. i2c error) */ static int tps65090_try_enable_fet(struct regulator_dev *rdev) { unsigned int control; int ret, i; ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, rdev->desc->enable_mask); if (ret < 0) { dev_err(&rdev->dev, "Error in updating reg %#x\n", rdev->desc->enable_reg); return ret; } for (i = 0; i < MAX_CTRL_READ_TRIES; i++) { ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &control); if (ret < 0) return ret; if (!(control & BIT(CTRL_TO_BIT))) break; usleep_range(1000, 1500); } if (!(control & BIT(CTRL_PG_BIT))) return -ENOTRECOVERABLE; return 0; } /** * tps65090_fet_enable - Enable a FET, trying a few times if it fails * * Some versions of the tps65090 have issues when turning on the FETs. * This function goes through several steps to ensure the best chance of the * FET going on. Specifically: * - We'll make sure that we bump the "overcurrent wait" to the maximum, which * increases the chances that we'll turn on properly. * - We'll retry turning the FET on multiple times (turning off in between). * * @rdev: Regulator device * * Return: 0 if ok, non-zero if it fails. */ static int tps65090_fet_enable(struct regulator_dev *rdev) { int ret, tries; /* * Try enabling multiple times until we succeed since sometimes the * first try times out. */ tries = 0; while (true) { ret = tps65090_try_enable_fet(rdev); if (!ret) break; if (ret != -ENOTRECOVERABLE || tries == MAX_FET_ENABLE_TRIES) goto err; /* Try turning the FET off (and then on again) */ ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, 0); if (ret) goto err; tries++; } if (tries) dev_warn(&rdev->dev, "reg %#x enable ok after %d tries\n", rdev->desc->enable_reg, tries); return 0; err: dev_warn(&rdev->dev, "reg %#x enable failed\n", rdev->desc->enable_reg); WARN_ON(1); return ret; } static struct regulator_ops tps65090_reg_control_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; static struct regulator_ops tps65090_fet_control_ops = { .enable = tps65090_fet_enable, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; static struct regulator_ops tps65090_ldo_ops = { }; #define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \ #define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _ops) \ { \ .name = "TPS65090_RAILS"#_id, \ .supply_name = _sname, \ .id = TPS65090_REGULATOR_##_id, \ .ops = &_ops, \ .enable_reg = _en_reg, \ .enable_mask = BIT(0), \ .enable_val = _en_bits, \ .enable_mask = _en_bits, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ } static struct regulator_desc tps65090_regulator_desc[] = { tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_reg_contol_ops), tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_reg_contol_ops), tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_reg_contol_ops), tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_reg_contol_ops), tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_reg_contol_ops), tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_reg_contol_ops), tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_reg_contol_ops), tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), tps65090_REG_DESC(LDO1, "vsys-l1", 0, tps65090_ldo_ops), tps65090_REG_DESC(LDO2, "vsys-l2", 0, tps65090_ldo_ops), tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT), tps65090_reg_control_ops), tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT), tps65090_reg_control_ops), tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT), tps65090_reg_control_ops), tps65090_REG_DESC(FET1, "infet1", 0x0F, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET2, "infet2", 0x10, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET3, "infet3", 0x11, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET4, "infet4", 0x12, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET5, "infet5", 0x13, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET6, "infet6", 0x14, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(FET7, "infet7", 0x15, BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), tps65090_fet_control_ops), tps65090_REG_DESC(LDO1, "vsys-l1", 0, 0, tps65090_ldo_ops), tps65090_REG_DESC(LDO2, "vsys-l2", 0, 0, tps65090_ldo_ops), }; static inline bool is_dcdc(int id) Loading Loading @@ -209,6 +377,11 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( rpdata->gpio = of_get_named_gpio(np, "dcdc-ext-control-gpios", 0); if (of_property_read_u32(tps65090_matches[idx].of_node, "ti,overcurrent-wait", &rpdata->overcurrent_wait) == 0) rpdata->overcurrent_wait_valid = true; tps65090_pdata->reg_pdata[idx] = rpdata; } return tps65090_pdata; Loading Loading @@ -258,6 +431,11 @@ static int tps65090_regulator_probe(struct platform_device *pdev) ri = &pmic[num]; ri->dev = &pdev->dev; ri->desc = &tps65090_regulator_desc[num]; if (tps_pdata) { ri->overcurrent_wait_valid = tps_pdata->overcurrent_wait_valid; ri->overcurrent_wait = tps_pdata->overcurrent_wait; } /* * TPS5090 DCDC support the control from external digital input. Loading Loading @@ -299,6 +477,12 @@ static int tps65090_regulator_probe(struct platform_device *pdev) } ri->rdev = rdev; if (ri->overcurrent_wait_valid) { ret = tps65090_reg_set_overcurrent_wait(ri, rdev); if (ret < 0) return ret; } /* Enable external control if it is require */ if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && tps_pdata->enable_ext_control) { Loading
drivers/regulator/tps65217-regulator.c +1 −3 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, }; static const struct regulator_desc regulators[] = { Loading Loading @@ -257,9 +258,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) pdev->name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ tps->rdev[i] = rdev; } return 0; } Loading
drivers/regulator/tps65218-regulator.c +10 −27 Original line number Diff line number Diff line Loading @@ -27,12 +27,10 @@ #include <linux/regulator/machine.h> #include <linux/mfd/tps65218.h> static unsigned int tps65218_ramp_delay = 4000; enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \ _lr, _nlr) \ _lr, _nlr, _delay) \ { \ .name = _name, \ .id = _id, \ Loading @@ -47,6 +45,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; .volt_table = _t, \ .linear_ranges = _lr, \ .n_linear_ranges = _nlr, \ .ramp_delay = _delay, \ } \ #define TPS65218_INFO(_id, _nm, _min, _max) \ Loading Loading @@ -152,22 +151,6 @@ static int tps65218_pmic_disable(struct regulator_dev *dev) dev->desc->enable_mask, TPS65218_PROTECT_L1); } static int tps65218_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { int old_uv, new_uv; old_uv = regulator_list_voltage_linear_range(rdev, old_selector); if (old_uv < 0) return old_uv; new_uv = regulator_list_voltage_linear_range(rdev, new_selector); if (new_uv < 0) return new_uv; return DIV_ROUND_UP(abs(old_uv - new_uv), tps65218_ramp_delay); } /* Operations permitted on DCDC1, DCDC2 */ static struct regulator_ops tps65218_dcdc12_ops = { .is_enabled = regulator_is_enabled_regmap, Loading @@ -177,7 +160,7 @@ static struct regulator_ops tps65218_dcdc12_ops = { .set_voltage_sel = tps65218_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .set_voltage_time_sel = tps65218_set_voltage_time_sel, .set_voltage_time_sel = regulator_set_voltage_time_sel, }; /* Operations permitted on DCDC3, DCDC4 and LDO1 */ Loading @@ -203,33 +186,33 @@ static const struct regulator_desc regulators[] = { TPS65218_REG_CONTROL_DCDC1, TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL, dcdc1_dcdc2_ranges, 2), dcdc1_dcdc2_ranges, 2, 4000), TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL, dcdc1_dcdc2_ranges, 2), dcdc1_dcdc2_ranges, 2, 4000), TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC3_EN, NULL, ldo1_dcdc3_ranges, 2), ldo1_dcdc3_ranges, 2, 0), TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL, dcdc4_ranges, 2), dcdc4_ranges, 2, 0), TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0), TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0, 0), TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0), TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, 2), 2, 0), }; static int tps65218_regulator_probe(struct platform_device *pdev) Loading