diff options
author | Jett.Zhou <jtzhou@marvell.com> | 2012-09-17 00:19:06 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-09-19 06:39:13 -0400 |
commit | e7a7810ae08bfca5cb2cad8a8d55c16f299cc3fe (patch) | |
tree | 9e37c95144c1f811623df1014aae5ae76cb96fd4 /drivers/regulator | |
parent | 51acdb61185e9c7579366712a415fc929929d3bb (diff) |
regulator: 88pm860x: Add pre-regulator support for 88pm860x regulator
Pre-regulator of 88pm8606 is mainly for support charging based on vbus,
it needs to be enabled for charging battery, and will be disabled in
some exception condition like over-temp.
Add the pre-regulator support for 88pm860x regulator driver.
Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/88pm8607.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 843c89a15472..d34bd8c5ad08 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -23,6 +23,7 @@ struct pm8607_regulator_info { | |||
23 | struct pm860x_chip *chip; | 23 | struct pm860x_chip *chip; |
24 | struct regulator_dev *regulator; | 24 | struct regulator_dev *regulator; |
25 | struct i2c_client *i2c; | 25 | struct i2c_client *i2c; |
26 | struct i2c_client *i2c_8606; | ||
26 | 27 | ||
27 | unsigned int *vol_table; | 28 | unsigned int *vol_table; |
28 | unsigned int *vol_suspend; | 29 | unsigned int *vol_suspend; |
@@ -242,6 +243,35 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) | |||
242 | return ret; | 243 | return ret; |
243 | } | 244 | } |
244 | 245 | ||
246 | static int pm8606_preg_enable(struct regulator_dev *rdev) | ||
247 | { | ||
248 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | ||
249 | |||
250 | return pm860x_set_bits(info->i2c, rdev->desc->enable_reg, | ||
251 | 1 << rdev->desc->enable_mask, 0); | ||
252 | } | ||
253 | |||
254 | static int pm8606_preg_disable(struct regulator_dev *rdev) | ||
255 | { | ||
256 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | ||
257 | |||
258 | return pm860x_set_bits(info->i2c, rdev->desc->enable_reg, | ||
259 | 1 << rdev->desc->enable_mask, | ||
260 | 1 << rdev->desc->enable_mask); | ||
261 | } | ||
262 | |||
263 | static int pm8606_preg_is_enabled(struct regulator_dev *rdev) | ||
264 | { | ||
265 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | ||
266 | int ret; | ||
267 | |||
268 | ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg); | ||
269 | if (ret < 0) | ||
270 | return ret; | ||
271 | |||
272 | return !((unsigned char)ret & (1 << rdev->desc->enable_mask)); | ||
273 | } | ||
274 | |||
245 | static struct regulator_ops pm8607_regulator_ops = { | 275 | static struct regulator_ops pm8607_regulator_ops = { |
246 | .list_voltage = pm8607_list_voltage, | 276 | .list_voltage = pm8607_list_voltage, |
247 | .set_voltage_sel = pm8607_set_voltage_sel, | 277 | .set_voltage_sel = pm8607_set_voltage_sel, |
@@ -251,6 +281,25 @@ static struct regulator_ops pm8607_regulator_ops = { | |||
251 | .is_enabled = regulator_is_enabled_regmap, | 281 | .is_enabled = regulator_is_enabled_regmap, |
252 | }; | 282 | }; |
253 | 283 | ||
284 | static struct regulator_ops pm8606_preg_ops = { | ||
285 | .enable = pm8606_preg_enable, | ||
286 | .disable = pm8606_preg_disable, | ||
287 | .is_enabled = pm8606_preg_is_enabled, | ||
288 | }; | ||
289 | |||
290 | #define PM8606_PREG(ereg, ebit) \ | ||
291 | { \ | ||
292 | .desc = { \ | ||
293 | .name = "PREG", \ | ||
294 | .ops = &pm8606_preg_ops, \ | ||
295 | .type = REGULATOR_CURRENT, \ | ||
296 | .id = PM8606_ID_PREG, \ | ||
297 | .owner = THIS_MODULE, \ | ||
298 | .enable_reg = PM8606_##ereg, \ | ||
299 | .enable_mask = (ebit), \ | ||
300 | }, \ | ||
301 | } | ||
302 | |||
254 | #define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \ | 303 | #define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \ |
255 | { \ | 304 | { \ |
256 | .desc = { \ | 305 | .desc = { \ |
@@ -309,6 +358,8 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = { | |||
309 | PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5), | 358 | PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5), |
310 | PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0), | 359 | PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0), |
311 | PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6), | 360 | PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6), |
361 | |||
362 | PM8606_PREG(PREREGULATORB, 5), | ||
312 | }; | 363 | }; |
313 | 364 | ||
314 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | 365 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) |
@@ -336,6 +387,8 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | |||
336 | return -EINVAL; | 387 | return -EINVAL; |
337 | } | 388 | } |
338 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | 389 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; |
390 | info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : | ||
391 | chip->client; | ||
339 | info->chip = chip; | 392 | info->chip = chip; |
340 | 393 | ||
341 | /* check DVC ramp slope double */ | 394 | /* check DVC ramp slope double */ |
@@ -371,6 +424,18 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev) | |||
371 | return 0; | 424 | return 0; |
372 | } | 425 | } |
373 | 426 | ||
427 | static struct platform_device_id pm8607_regulator_driver_ids[] = { | ||
428 | { | ||
429 | .name = "88pm860x-regulator", | ||
430 | .driver_data = 0, | ||
431 | }, { | ||
432 | .name = "88pm860x-preg", | ||
433 | .driver_data = 0, | ||
434 | }, | ||
435 | { }, | ||
436 | }; | ||
437 | MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids); | ||
438 | |||
374 | static struct platform_driver pm8607_regulator_driver = { | 439 | static struct platform_driver pm8607_regulator_driver = { |
375 | .driver = { | 440 | .driver = { |
376 | .name = "88pm860x-regulator", | 441 | .name = "88pm860x-regulator", |
@@ -378,6 +443,7 @@ static struct platform_driver pm8607_regulator_driver = { | |||
378 | }, | 443 | }, |
379 | .probe = pm8607_regulator_probe, | 444 | .probe = pm8607_regulator_probe, |
380 | .remove = __devexit_p(pm8607_regulator_remove), | 445 | .remove = __devexit_p(pm8607_regulator_remove), |
446 | .id_table = pm8607_regulator_driver_ids, | ||
381 | }; | 447 | }; |
382 | 448 | ||
383 | static int __init pm8607_regulator_init(void) | 449 | static int __init pm8607_regulator_init(void) |