diff options
author | Lukasz Majewski <l.majewski@samsung.com> | 2010-09-27 08:32:27 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-10-28 18:30:15 -0400 |
commit | 50f19a45961ffa0445db02777ad9342119ceb2aa (patch) | |
tree | c4e1b67e4e843e53f6c3c8db70883ca8708eaf0f /drivers/regulator/max8998.c | |
parent | 58aa6334fbf5cf420a47cfd2718a0b299f40a379 (diff) |
regulator: max8998 BUCK1/2 voltage change with use of GPIOs
max8998_pmic_probe:
- modified to check if valid pins are defined at platform
data
- maximal voltage values (predefined at platform data) are uploaded to
max8998 device
max8998_set_voltage_buck:
- BUCK1/2 voltages change between values already defined
- Checks if valid GPIO pins are passed from platform data
- If requested voltage cannot be satisfied from already defined values,
then one of free slots is used
- Predefined maximum voltages (as defined at platform data) are always
available
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/regulator/max8998.c')
-rw-r--r-- | drivers/regulator/max8998.c | 214 |
1 files changed, 193 insertions, 21 deletions
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 7ae0639c1394..5c20756db607 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -340,24 +340,37 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, | |||
340 | return ret; | 340 | return ret; |
341 | } | 341 | } |
342 | 342 | ||
343 | static inline void buck1_gpio_set(int gpio1, int gpio2, int v) | ||
344 | { | ||
345 | gpio_set_value(gpio1, v & 0x1); | ||
346 | gpio_set_value(gpio2, (v >> 1) & 0x1); | ||
347 | } | ||
348 | |||
349 | static inline void buck2_gpio_set(int gpio, int v) | ||
350 | { | ||
351 | gpio_set_value(gpio, v & 0x1); | ||
352 | } | ||
353 | |||
343 | static int max8998_set_voltage_buck(struct regulator_dev *rdev, | 354 | static int max8998_set_voltage_buck(struct regulator_dev *rdev, |
344 | int min_uV, int max_uV) | 355 | int min_uV, int max_uV) |
345 | { | 356 | { |
346 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | 357 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); |
358 | struct max8998_platform_data *pdata = | ||
359 | dev_get_platdata(max8998->iodev->dev); | ||
347 | struct i2c_client *i2c = max8998->iodev->i2c; | 360 | struct i2c_client *i2c = max8998->iodev->i2c; |
348 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; | 361 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; |
349 | int previous_vol = 0; | ||
350 | const struct voltage_map_desc *desc; | 362 | const struct voltage_map_desc *desc; |
351 | int ldo = max8998_get_ldo(rdev); | 363 | int buck = max8998_get_ldo(rdev); |
352 | int reg, shift = 0, mask, ret; | 364 | int reg, shift = 0, mask, ret; |
353 | int i = 0; | 365 | int difference = 0, i = 0, j = 0, previous_vol = 0; |
354 | u8 val; | 366 | u8 val = 0; |
355 | bool en_ramp = false; | 367 | static u8 buck1_last_val; |
356 | 368 | ||
357 | if (ldo >= ARRAY_SIZE(ldo_voltage_map)) | 369 | if (buck >= ARRAY_SIZE(ldo_voltage_map)) |
358 | return -EINVAL; | 370 | return -EINVAL; |
359 | 371 | ||
360 | desc = ldo_voltage_map[ldo]; | 372 | desc = ldo_voltage_map[buck]; |
373 | |||
361 | if (desc == NULL) | 374 | if (desc == NULL) |
362 | return -EINVAL; | 375 | return -EINVAL; |
363 | 376 | ||
@@ -375,24 +388,102 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, | |||
375 | if (ret) | 388 | if (ret) |
376 | return ret; | 389 | return ret; |
377 | 390 | ||
378 | /* wait for RAMP_UP_DELAY if rdev is BUCK1/2 and | 391 | previous_vol = max8998_get_voltage(rdev); |
379 | * ENRAMP is ON */ | 392 | |
380 | if (ldo == MAX8998_BUCK1 || ldo == MAX8998_BUCK2) { | 393 | /* Check if voltage needs to be changed */ |
381 | max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); | 394 | /* if previous_voltage equal new voltage, return */ |
382 | if (val & (1 << 4)) { | 395 | if (previous_vol == max8998_list_voltage(rdev, i)) { |
383 | en_ramp = true; | 396 | dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n", |
384 | previous_vol = max8998_get_voltage(rdev); | 397 | previous_vol, max8998_list_voltage(rdev, i)); |
385 | } | 398 | return ret; |
386 | } | 399 | } |
387 | 400 | ||
388 | ret = max8998_update_reg(i2c, reg, i<<shift, mask<<shift); | 401 | switch (buck) { |
402 | case MAX8998_BUCK1: | ||
403 | dev_dbg(max8998->dev, | ||
404 | "BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n\ | ||
405 | buck1_vol3:%d, buck1_vol4:%d\n", | ||
406 | i, max8998->buck1_vol[0], max8998->buck1_vol[1], | ||
407 | max8998->buck1_vol[2], max8998->buck1_vol[3]); | ||
408 | |||
409 | if (gpio_is_valid(pdata->buck1_set1) && | ||
410 | gpio_is_valid(pdata->buck1_set2)) { | ||
411 | |||
412 | /* check if requested voltage */ | ||
413 | /* value is already defined */ | ||
414 | for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) { | ||
415 | if (max8998->buck1_vol[j] == i) { | ||
416 | max8998->buck1_idx = j; | ||
417 | buck1_gpio_set(pdata->buck1_set1, | ||
418 | pdata->buck1_set2, j); | ||
419 | goto buck1_exit; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | /* no predefine regulator found */ | ||
424 | max8998->buck1_idx = (buck1_last_val % 2) + 2; | ||
425 | dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", | ||
426 | max8998->buck1_idx); | ||
427 | max8998->buck1_vol[max8998->buck1_idx] = i; | ||
428 | ret = max8998_get_voltage_register(rdev, ®, | ||
429 | &shift, | ||
430 | &mask); | ||
431 | ret = max8998_write_reg(i2c, reg, i); | ||
432 | buck1_gpio_set(pdata->buck1_set1, | ||
433 | pdata->buck1_set2, max8998->buck1_idx); | ||
434 | buck1_last_val++; | ||
435 | buck1_exit: | ||
436 | dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n", | ||
437 | i2c->name, gpio_get_value(pdata->buck1_set1), | ||
438 | gpio_get_value(pdata->buck1_set2)); | ||
439 | break; | ||
440 | } else { | ||
441 | ret = max8998_write_reg(i2c, reg, i); | ||
442 | } | ||
443 | break; | ||
389 | 444 | ||
390 | if (en_ramp == true) { | 445 | case MAX8998_BUCK2: |
391 | int difference = desc->min + desc->step*i - previous_vol/1000; | 446 | dev_dbg(max8998->dev, |
392 | if (difference > 0) | 447 | "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" |
393 | udelay(difference / ((val & 0x0f) + 1)); | 448 | , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); |
449 | if (gpio_is_valid(pdata->buck2_set3)) { | ||
450 | if (max8998->buck2_vol[0] == i) { | ||
451 | max8998->buck1_idx = 0; | ||
452 | buck2_gpio_set(pdata->buck2_set3, 0); | ||
453 | } else { | ||
454 | max8998->buck1_idx = 1; | ||
455 | ret = max8998_get_voltage_register(rdev, ®, | ||
456 | &shift, | ||
457 | &mask); | ||
458 | ret = max8998_write_reg(i2c, reg, i); | ||
459 | max8998->buck2_vol[1] = i; | ||
460 | buck2_gpio_set(pdata->buck2_set3, 1); | ||
461 | } | ||
462 | dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, | ||
463 | gpio_get_value(pdata->buck2_set3)); | ||
464 | } else { | ||
465 | ret = max8998_write_reg(i2c, reg, i); | ||
466 | } | ||
467 | break; | ||
468 | |||
469 | case MAX8998_BUCK3: | ||
470 | case MAX8998_BUCK4: | ||
471 | ret = max8998_update_reg(i2c, reg, i<<shift, mask<<shift); | ||
472 | break; | ||
394 | } | 473 | } |
395 | 474 | ||
475 | /* Voltage stabilization */ | ||
476 | max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); | ||
477 | |||
478 | /* lp3974 hasn't got ENRAMP bit - ramp is assumed as true */ | ||
479 | /* MAX8998 has ENRAMP bit implemented, so test it*/ | ||
480 | if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP)) | ||
481 | return ret; | ||
482 | |||
483 | difference = desc->min + desc->step*i - previous_vol/1000; | ||
484 | if (difference > 0) | ||
485 | udelay(difference / ((val & 0x0f) + 1)); | ||
486 | |||
396 | return ret; | 487 | return ret; |
397 | } | 488 | } |
398 | 489 | ||
@@ -586,6 +677,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
586 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); | 677 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); |
587 | struct regulator_dev **rdev; | 678 | struct regulator_dev **rdev; |
588 | struct max8998_data *max8998; | 679 | struct max8998_data *max8998; |
680 | struct i2c_client *i2c; | ||
589 | int i, ret, size; | 681 | int i, ret, size; |
590 | 682 | ||
591 | if (!pdata) { | 683 | if (!pdata) { |
@@ -609,6 +701,86 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
609 | max8998->iodev = iodev; | 701 | max8998->iodev = iodev; |
610 | max8998->num_regulators = pdata->num_regulators; | 702 | max8998->num_regulators = pdata->num_regulators; |
611 | platform_set_drvdata(pdev, max8998); | 703 | platform_set_drvdata(pdev, max8998); |
704 | i2c = max8998->iodev->i2c; | ||
705 | |||
706 | /* NOTE: */ | ||
707 | /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ | ||
708 | /* will be displayed */ | ||
709 | |||
710 | /* Check if MAX8998 voltage selection GPIOs are defined */ | ||
711 | if (gpio_is_valid(pdata->buck1_set1) && | ||
712 | gpio_is_valid(pdata->buck1_set2)) { | ||
713 | /* Check if SET1 is not equal to 0 */ | ||
714 | if (!pdata->buck1_set1) { | ||
715 | printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); | ||
716 | WARN_ON(!pdata->buck1_set1); | ||
717 | return -EIO; | ||
718 | } | ||
719 | /* Check if SET2 is not equal to 0 */ | ||
720 | if (!pdata->buck1_set2) { | ||
721 | printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); | ||
722 | WARN_ON(!pdata->buck1_set2); | ||
723 | return -EIO; | ||
724 | } | ||
725 | |||
726 | gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); | ||
727 | gpio_direction_output(pdata->buck1_set1, | ||
728 | max8998->buck1_idx & 0x1); | ||
729 | |||
730 | |||
731 | gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2"); | ||
732 | gpio_direction_output(pdata->buck1_set2, | ||
733 | (max8998->buck1_idx >> 1) & 0x1); | ||
734 | /* Set predefined value for BUCK1 register 1 */ | ||
735 | i = 0; | ||
736 | while (buck12_voltage_map_desc.min + | ||
737 | buck12_voltage_map_desc.step*i | ||
738 | != (pdata->buck1_max_voltage1 / 1000)) | ||
739 | i++; | ||
740 | printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); | ||
741 | max8998->buck1_vol[0] = i; | ||
742 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); | ||
743 | |||
744 | /* Set predefined value for BUCK1 register 2 */ | ||
745 | i = 0; | ||
746 | while (buck12_voltage_map_desc.min + | ||
747 | buck12_voltage_map_desc.step*i | ||
748 | != (pdata->buck1_max_voltage2 / 1000)) | ||
749 | i++; | ||
750 | |||
751 | max8998->buck1_vol[1] = i; | ||
752 | printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); | ||
753 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i) | ||
754 | + ret; | ||
755 | if (ret) | ||
756 | return ret; | ||
757 | |||
758 | } | ||
759 | |||
760 | if (gpio_is_valid(pdata->buck2_set3)) { | ||
761 | /* Check if SET3 is not equal to 0 */ | ||
762 | if (!pdata->buck2_set3) { | ||
763 | printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); | ||
764 | WARN_ON(!pdata->buck2_set3); | ||
765 | return -EIO; | ||
766 | } | ||
767 | gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); | ||
768 | gpio_direction_output(pdata->buck2_set3, | ||
769 | max8998->buck2_idx & 0x1); | ||
770 | |||
771 | /* BUCK2 - set preset default voltage value to buck2_vol[0] */ | ||
772 | i = 0; | ||
773 | while (buck12_voltage_map_desc.min + | ||
774 | buck12_voltage_map_desc.step*i | ||
775 | != (pdata->buck2_max_voltage / 1000)) | ||
776 | i++; | ||
777 | printk(KERN_ERR "i:%d, buck2_idx:%d\n", i, max8998->buck2_idx); | ||
778 | max8998->buck2_vol[0] = i; | ||
779 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); | ||
780 | if (ret) | ||
781 | return ret; | ||
782 | |||
783 | } | ||
612 | 784 | ||
613 | for (i = 0; i < pdata->num_regulators; i++) { | 785 | for (i = 0; i < pdata->num_regulators; i++) { |
614 | const struct voltage_map_desc *desc; | 786 | const struct voltage_map_desc *desc; |