diff options
Diffstat (limited to 'drivers/regulator/tps65090-regulator.c')
| -rw-r--r-- | drivers/regulator/tps65090-regulator.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 2e92ef68574d..ca04e9f010e1 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c | |||
| @@ -28,15 +28,58 @@ | |||
| 28 | #include <linux/regulator/of_regulator.h> | 28 | #include <linux/regulator/of_regulator.h> |
| 29 | #include <linux/mfd/tps65090.h> | 29 | #include <linux/mfd/tps65090.h> |
| 30 | 30 | ||
| 31 | #define CTRL_WT_BIT 2 /* Regulator wait time 0 bit */ | ||
| 32 | |||
| 33 | #define MAX_OVERCURRENT_WAIT 3 /* Overcurrent wait must be <= this */ | ||
| 34 | |||
| 35 | /** | ||
| 36 | * struct tps65090_regulator - Per-regulator data for a tps65090 regulator | ||
| 37 | * | ||
| 38 | * @dev: Pointer to our device. | ||
| 39 | * @desc: The struct regulator_desc for the regulator. | ||
| 40 | * @rdev: The struct regulator_dev for the regulator. | ||
| 41 | * @overcurrent_wait_valid: True if overcurrent_wait is valid. | ||
| 42 | * @overcurrent_wait: For FETs, the value to put in the WTFET bitfield. | ||
| 43 | */ | ||
| 44 | |||
| 31 | struct tps65090_regulator { | 45 | struct tps65090_regulator { |
| 32 | struct device *dev; | 46 | struct device *dev; |
| 33 | struct regulator_desc *desc; | 47 | struct regulator_desc *desc; |
| 34 | struct regulator_dev *rdev; | 48 | struct regulator_dev *rdev; |
| 49 | bool overcurrent_wait_valid; | ||
| 50 | int overcurrent_wait; | ||
| 35 | }; | 51 | }; |
| 36 | 52 | ||
| 37 | static struct regulator_ops tps65090_ext_control_ops = { | 53 | static struct regulator_ops tps65090_ext_control_ops = { |
| 38 | }; | 54 | }; |
| 39 | 55 | ||
| 56 | /** | ||
| 57 | * tps65090_reg_set_overcurrent_wait - Setup overcurrent wait | ||
| 58 | * | ||
| 59 | * This will set the overcurrent wait time based on what's in the regulator | ||
| 60 | * info. | ||
| 61 | * | ||
| 62 | * @ri: Overall regulator data | ||
| 63 | * @rdev: Regulator device | ||
| 64 | * | ||
| 65 | * Return: 0 if no error, non-zero if there was an error writing the register. | ||
| 66 | */ | ||
| 67 | static int tps65090_reg_set_overcurrent_wait(struct tps65090_regulator *ri, | ||
| 68 | struct regulator_dev *rdev) | ||
| 69 | { | ||
| 70 | int ret; | ||
| 71 | |||
| 72 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 73 | MAX_OVERCURRENT_WAIT << CTRL_WT_BIT, | ||
| 74 | ri->overcurrent_wait << CTRL_WT_BIT); | ||
| 75 | if (ret) { | ||
| 76 | dev_err(&rdev->dev, "Error updating overcurrent wait %#x\n", | ||
| 77 | rdev->desc->enable_reg); | ||
| 78 | } | ||
| 79 | |||
| 80 | return ret; | ||
| 81 | } | ||
| 82 | |||
| 40 | static struct regulator_ops tps65090_reg_contol_ops = { | 83 | static struct regulator_ops tps65090_reg_contol_ops = { |
| 41 | .enable = regulator_enable_regmap, | 84 | .enable = regulator_enable_regmap, |
| 42 | .disable = regulator_disable_regmap, | 85 | .disable = regulator_disable_regmap, |
| @@ -209,6 +252,11 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( | |||
| 209 | rpdata->gpio = of_get_named_gpio(np, | 252 | rpdata->gpio = of_get_named_gpio(np, |
| 210 | "dcdc-ext-control-gpios", 0); | 253 | "dcdc-ext-control-gpios", 0); |
| 211 | 254 | ||
| 255 | if (of_property_read_u32(tps65090_matches[idx].of_node, | ||
| 256 | "ti,overcurrent-wait", | ||
| 257 | &rpdata->overcurrent_wait) == 0) | ||
| 258 | rpdata->overcurrent_wait_valid = true; | ||
| 259 | |||
| 212 | tps65090_pdata->reg_pdata[idx] = rpdata; | 260 | tps65090_pdata->reg_pdata[idx] = rpdata; |
| 213 | } | 261 | } |
| 214 | return tps65090_pdata; | 262 | return tps65090_pdata; |
| @@ -258,6 +306,8 @@ static int tps65090_regulator_probe(struct platform_device *pdev) | |||
| 258 | ri = &pmic[num]; | 306 | ri = &pmic[num]; |
| 259 | ri->dev = &pdev->dev; | 307 | ri->dev = &pdev->dev; |
| 260 | ri->desc = &tps65090_regulator_desc[num]; | 308 | ri->desc = &tps65090_regulator_desc[num]; |
| 309 | ri->overcurrent_wait_valid = tps_pdata->overcurrent_wait_valid; | ||
| 310 | ri->overcurrent_wait = tps_pdata->overcurrent_wait; | ||
| 261 | 311 | ||
| 262 | /* | 312 | /* |
| 263 | * TPS5090 DCDC support the control from external digital input. | 313 | * TPS5090 DCDC support the control from external digital input. |
| @@ -299,6 +349,12 @@ static int tps65090_regulator_probe(struct platform_device *pdev) | |||
| 299 | } | 349 | } |
| 300 | ri->rdev = rdev; | 350 | ri->rdev = rdev; |
| 301 | 351 | ||
| 352 | if (ri->overcurrent_wait_valid) { | ||
| 353 | ret = tps65090_reg_set_overcurrent_wait(ri, rdev); | ||
| 354 | if (ret < 0) | ||
| 355 | return ret; | ||
| 356 | } | ||
| 357 | |||
| 302 | /* Enable external control if it is require */ | 358 | /* Enable external control if it is require */ |
| 303 | if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && | 359 | if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && |
| 304 | tps_pdata->enable_ext_control) { | 360 | tps_pdata->enable_ext_control) { |
