diff options
Diffstat (limited to 'drivers/regulator/max77686.c')
| -rw-r--r-- | drivers/regulator/max77686.c | 170 |
1 files changed, 158 insertions, 12 deletions
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 2a67d08658ad..b85040caaea3 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
| @@ -67,8 +67,94 @@ enum max77686_ramp_rate { | |||
| 67 | 67 | ||
| 68 | struct max77686_data { | 68 | struct max77686_data { |
| 69 | struct regulator_dev *rdev[MAX77686_REGULATORS]; | 69 | struct regulator_dev *rdev[MAX77686_REGULATORS]; |
| 70 | unsigned int opmode[MAX77686_REGULATORS]; | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 73 | /* Some BUCKS supports Normal[ON/OFF] mode during suspend */ | ||
| 74 | static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev) | ||
| 75 | { | ||
| 76 | unsigned int val; | ||
| 77 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | ||
| 78 | |||
| 79 | if (rdev->desc->id == MAX77686_BUCK1) | ||
| 80 | val = 0x1; | ||
| 81 | else | ||
| 82 | val = 0x1 << MAX77686_OPMODE_BUCK234_SHIFT; | ||
| 83 | |||
| 84 | max77686->opmode[rdev->desc->id] = val; | ||
| 85 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 86 | rdev->desc->enable_mask, | ||
| 87 | val); | ||
| 88 | } | ||
| 89 | |||
| 90 | /* Some LDOs supports [LPM/Normal]ON mode during suspend state */ | ||
| 91 | static int max77686_set_suspend_mode(struct regulator_dev *rdev, | ||
| 92 | unsigned int mode) | ||
| 93 | { | ||
| 94 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | ||
| 95 | unsigned int val; | ||
| 96 | |||
| 97 | /* BUCK[5-9] doesn't support this feature */ | ||
| 98 | if (rdev->desc->id >= MAX77686_BUCK5) | ||
| 99 | return 0; | ||
| 100 | |||
| 101 | switch (mode) { | ||
| 102 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | ||
| 103 | val = 0x2 << MAX77686_OPMODE_SHIFT; | ||
| 104 | break; | ||
| 105 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | ||
| 106 | val = 0x3 << MAX77686_OPMODE_SHIFT; | ||
| 107 | break; | ||
| 108 | default: | ||
| 109 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", | ||
| 110 | rdev->desc->name, mode); | ||
| 111 | return -EINVAL; | ||
| 112 | } | ||
| 113 | |||
| 114 | max77686->opmode[rdev->desc->id] = val; | ||
| 115 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 116 | rdev->desc->enable_mask, | ||
| 117 | val); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state */ | ||
| 121 | static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | ||
| 122 | unsigned int mode) | ||
| 123 | { | ||
| 124 | unsigned int val; | ||
| 125 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | ||
| 126 | |||
| 127 | switch (mode) { | ||
| 128 | case REGULATOR_MODE_STANDBY: /* switch off */ | ||
| 129 | val = 0x1 << MAX77686_OPMODE_SHIFT; | ||
| 130 | break; | ||
| 131 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | ||
| 132 | val = 0x2 << MAX77686_OPMODE_SHIFT; | ||
| 133 | break; | ||
| 134 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | ||
| 135 | val = 0x3 << MAX77686_OPMODE_SHIFT; | ||
| 136 | break; | ||
| 137 | default: | ||
| 138 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", | ||
| 139 | rdev->desc->name, mode); | ||
| 140 | return -EINVAL; | ||
| 141 | } | ||
| 142 | |||
| 143 | max77686->opmode[rdev->desc->id] = val; | ||
| 144 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 145 | rdev->desc->enable_mask, | ||
| 146 | val); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int max77686_enable(struct regulator_dev *rdev) | ||
| 150 | { | ||
| 151 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | ||
| 152 | |||
| 153 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 154 | rdev->desc->enable_mask, | ||
| 155 | max77686->opmode[rdev->desc->id]); | ||
| 156 | } | ||
| 157 | |||
| 72 | static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | 158 | static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) |
| 73 | { | 159 | { |
| 74 | unsigned int ramp_value = RAMP_RATE_NO_CTRL; | 160 | unsigned int ramp_value = RAMP_RATE_NO_CTRL; |
| @@ -98,23 +184,49 @@ static struct regulator_ops max77686_ops = { | |||
| 98 | .list_voltage = regulator_list_voltage_linear, | 184 | .list_voltage = regulator_list_voltage_linear, |
| 99 | .map_voltage = regulator_map_voltage_linear, | 185 | .map_voltage = regulator_map_voltage_linear, |
| 100 | .is_enabled = regulator_is_enabled_regmap, | 186 | .is_enabled = regulator_is_enabled_regmap, |
| 101 | .enable = regulator_enable_regmap, | 187 | .enable = max77686_enable, |
| 188 | .disable = regulator_disable_regmap, | ||
| 189 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 190 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 191 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 192 | .set_suspend_mode = max77686_set_suspend_mode, | ||
| 193 | }; | ||
| 194 | |||
| 195 | static struct regulator_ops max77686_ldo_ops = { | ||
| 196 | .list_voltage = regulator_list_voltage_linear, | ||
| 197 | .map_voltage = regulator_map_voltage_linear, | ||
| 198 | .is_enabled = regulator_is_enabled_regmap, | ||
| 199 | .enable = max77686_enable, | ||
| 102 | .disable = regulator_disable_regmap, | 200 | .disable = regulator_disable_regmap, |
| 103 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 201 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 104 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 202 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 105 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 203 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 204 | .set_suspend_mode = max77686_ldo_set_suspend_mode, | ||
| 205 | }; | ||
| 206 | |||
| 207 | static struct regulator_ops max77686_buck1_ops = { | ||
| 208 | .list_voltage = regulator_list_voltage_linear, | ||
| 209 | .map_voltage = regulator_map_voltage_linear, | ||
| 210 | .is_enabled = regulator_is_enabled_regmap, | ||
| 211 | .enable = max77686_enable, | ||
| 212 | .disable = regulator_disable_regmap, | ||
| 213 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 214 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 215 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 216 | .set_suspend_disable = max77686_buck_set_suspend_disable, | ||
| 106 | }; | 217 | }; |
| 107 | 218 | ||
| 108 | static struct regulator_ops max77686_buck_dvs_ops = { | 219 | static struct regulator_ops max77686_buck_dvs_ops = { |
| 109 | .list_voltage = regulator_list_voltage_linear, | 220 | .list_voltage = regulator_list_voltage_linear, |
| 110 | .map_voltage = regulator_map_voltage_linear, | 221 | .map_voltage = regulator_map_voltage_linear, |
| 111 | .is_enabled = regulator_is_enabled_regmap, | 222 | .is_enabled = regulator_is_enabled_regmap, |
| 112 | .enable = regulator_enable_regmap, | 223 | .enable = max77686_enable, |
| 113 | .disable = regulator_disable_regmap, | 224 | .disable = regulator_disable_regmap, |
| 114 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 225 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 115 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 226 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 116 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 227 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 117 | .set_ramp_delay = max77686_set_ramp_delay, | 228 | .set_ramp_delay = max77686_set_ramp_delay, |
| 229 | .set_suspend_disable = max77686_buck_set_suspend_disable, | ||
| 118 | }; | 230 | }; |
| 119 | 231 | ||
| 120 | #define regulator_desc_ldo(num) { \ | 232 | #define regulator_desc_ldo(num) { \ |
| @@ -133,9 +245,41 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
| 133 | .enable_mask = MAX77686_OPMODE_MASK \ | 245 | .enable_mask = MAX77686_OPMODE_MASK \ |
| 134 | << MAX77686_OPMODE_SHIFT, \ | 246 | << MAX77686_OPMODE_SHIFT, \ |
| 135 | } | 247 | } |
| 248 | #define regulator_desc_lpm_ldo(num) { \ | ||
| 249 | .name = "LDO"#num, \ | ||
| 250 | .id = MAX77686_LDO##num, \ | ||
| 251 | .ops = &max77686_ldo_ops, \ | ||
| 252 | .type = REGULATOR_VOLTAGE, \ | ||
| 253 | .owner = THIS_MODULE, \ | ||
| 254 | .min_uV = MAX77686_LDO_MINUV, \ | ||
| 255 | .uV_step = MAX77686_LDO_UVSTEP, \ | ||
| 256 | .ramp_delay = MAX77686_RAMP_DELAY, \ | ||
| 257 | .n_voltages = MAX77686_VSEL_MASK + 1, \ | ||
| 258 | .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ | ||
| 259 | .vsel_mask = MAX77686_VSEL_MASK, \ | ||
| 260 | .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ | ||
| 261 | .enable_mask = MAX77686_OPMODE_MASK \ | ||
| 262 | << MAX77686_OPMODE_SHIFT, \ | ||
| 263 | } | ||
| 136 | #define regulator_desc_ldo_low(num) { \ | 264 | #define regulator_desc_ldo_low(num) { \ |
| 137 | .name = "LDO"#num, \ | 265 | .name = "LDO"#num, \ |
| 138 | .id = MAX77686_LDO##num, \ | 266 | .id = MAX77686_LDO##num, \ |
| 267 | .ops = &max77686_ldo_ops, \ | ||
| 268 | .type = REGULATOR_VOLTAGE, \ | ||
| 269 | .owner = THIS_MODULE, \ | ||
| 270 | .min_uV = MAX77686_LDO_LOW_MINUV, \ | ||
| 271 | .uV_step = MAX77686_LDO_LOW_UVSTEP, \ | ||
| 272 | .ramp_delay = MAX77686_RAMP_DELAY, \ | ||
| 273 | .n_voltages = MAX77686_VSEL_MASK + 1, \ | ||
| 274 | .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ | ||
| 275 | .vsel_mask = MAX77686_VSEL_MASK, \ | ||
| 276 | .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ | ||
| 277 | .enable_mask = MAX77686_OPMODE_MASK \ | ||
| 278 | << MAX77686_OPMODE_SHIFT, \ | ||
| 279 | } | ||
| 280 | #define regulator_desc_ldo1_low(num) { \ | ||
| 281 | .name = "LDO"#num, \ | ||
| 282 | .id = MAX77686_LDO##num, \ | ||
| 139 | .ops = &max77686_ops, \ | 283 | .ops = &max77686_ops, \ |
| 140 | .type = REGULATOR_VOLTAGE, \ | 284 | .type = REGULATOR_VOLTAGE, \ |
| 141 | .owner = THIS_MODULE, \ | 285 | .owner = THIS_MODULE, \ |
| @@ -167,7 +311,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
| 167 | #define regulator_desc_buck1(num) { \ | 311 | #define regulator_desc_buck1(num) { \ |
| 168 | .name = "BUCK"#num, \ | 312 | .name = "BUCK"#num, \ |
| 169 | .id = MAX77686_BUCK##num, \ | 313 | .id = MAX77686_BUCK##num, \ |
| 170 | .ops = &max77686_ops, \ | 314 | .ops = &max77686_buck1_ops, \ |
| 171 | .type = REGULATOR_VOLTAGE, \ | 315 | .type = REGULATOR_VOLTAGE, \ |
| 172 | .owner = THIS_MODULE, \ | 316 | .owner = THIS_MODULE, \ |
| 173 | .min_uV = MAX77686_BUCK_MINUV, \ | 317 | .min_uV = MAX77686_BUCK_MINUV, \ |
| @@ -197,7 +341,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
| 197 | } | 341 | } |
| 198 | 342 | ||
| 199 | static struct regulator_desc regulators[] = { | 343 | static struct regulator_desc regulators[] = { |
| 200 | regulator_desc_ldo_low(1), | 344 | regulator_desc_ldo1_low(1), |
| 201 | regulator_desc_ldo_low(2), | 345 | regulator_desc_ldo_low(2), |
| 202 | regulator_desc_ldo(3), | 346 | regulator_desc_ldo(3), |
| 203 | regulator_desc_ldo(4), | 347 | regulator_desc_ldo(4), |
| @@ -206,13 +350,13 @@ static struct regulator_desc regulators[] = { | |||
| 206 | regulator_desc_ldo_low(7), | 350 | regulator_desc_ldo_low(7), |
| 207 | regulator_desc_ldo_low(8), | 351 | regulator_desc_ldo_low(8), |
| 208 | regulator_desc_ldo(9), | 352 | regulator_desc_ldo(9), |
| 209 | regulator_desc_ldo(10), | 353 | regulator_desc_lpm_ldo(10), |
| 210 | regulator_desc_ldo(11), | 354 | regulator_desc_lpm_ldo(11), |
| 211 | regulator_desc_ldo(12), | 355 | regulator_desc_lpm_ldo(12), |
| 212 | regulator_desc_ldo(13), | 356 | regulator_desc_ldo(13), |
| 213 | regulator_desc_ldo(14), | 357 | regulator_desc_lpm_ldo(14), |
| 214 | regulator_desc_ldo_low(15), | 358 | regulator_desc_ldo_low(15), |
| 215 | regulator_desc_ldo(16), | 359 | regulator_desc_lpm_ldo(16), |
| 216 | regulator_desc_ldo(17), | 360 | regulator_desc_ldo(17), |
| 217 | regulator_desc_ldo(18), | 361 | regulator_desc_ldo(18), |
| 218 | regulator_desc_ldo(19), | 362 | regulator_desc_ldo(19), |
| @@ -280,7 +424,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | |||
| 280 | } | 424 | } |
| 281 | #endif /* CONFIG_OF */ | 425 | #endif /* CONFIG_OF */ |
| 282 | 426 | ||
| 283 | static __devinit int max77686_pmic_probe(struct platform_device *pdev) | 427 | static int max77686_pmic_probe(struct platform_device *pdev) |
| 284 | { | 428 | { |
| 285 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 429 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 286 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); | 430 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); |
| @@ -314,12 +458,14 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) | |||
| 314 | 458 | ||
| 315 | config.dev = &pdev->dev; | 459 | config.dev = &pdev->dev; |
| 316 | config.regmap = iodev->regmap; | 460 | config.regmap = iodev->regmap; |
| 461 | config.driver_data = max77686; | ||
| 317 | platform_set_drvdata(pdev, max77686); | 462 | platform_set_drvdata(pdev, max77686); |
| 318 | 463 | ||
| 319 | for (i = 0; i < MAX77686_REGULATORS; i++) { | 464 | for (i = 0; i < MAX77686_REGULATORS; i++) { |
| 320 | config.init_data = pdata->regulators[i].initdata; | 465 | config.init_data = pdata->regulators[i].initdata; |
| 321 | config.of_node = pdata->regulators[i].of_node; | 466 | config.of_node = pdata->regulators[i].of_node; |
| 322 | 467 | ||
| 468 | max77686->opmode[i] = regulators[i].enable_mask; | ||
| 323 | max77686->rdev[i] = regulator_register(®ulators[i], &config); | 469 | max77686->rdev[i] = regulator_register(®ulators[i], &config); |
| 324 | if (IS_ERR(max77686->rdev[i])) { | 470 | if (IS_ERR(max77686->rdev[i])) { |
| 325 | ret = PTR_ERR(max77686->rdev[i]); | 471 | ret = PTR_ERR(max77686->rdev[i]); |
| @@ -337,7 +483,7 @@ err: | |||
| 337 | return ret; | 483 | return ret; |
| 338 | } | 484 | } |
| 339 | 485 | ||
| 340 | static int __devexit max77686_pmic_remove(struct platform_device *pdev) | 486 | static int max77686_pmic_remove(struct platform_device *pdev) |
| 341 | { | 487 | { |
| 342 | struct max77686_data *max77686 = platform_get_drvdata(pdev); | 488 | struct max77686_data *max77686 = platform_get_drvdata(pdev); |
| 343 | int i; | 489 | int i; |
| @@ -360,7 +506,7 @@ static struct platform_driver max77686_pmic_driver = { | |||
| 360 | .owner = THIS_MODULE, | 506 | .owner = THIS_MODULE, |
| 361 | }, | 507 | }, |
| 362 | .probe = max77686_pmic_probe, | 508 | .probe = max77686_pmic_probe, |
| 363 | .remove = __devexit_p(max77686_pmic_remove), | 509 | .remove = max77686_pmic_remove, |
| 364 | .id_table = max77686_pmic_id, | 510 | .id_table = max77686_pmic_id, |
| 365 | }; | 511 | }; |
| 366 | 512 | ||
