Commit 50f19a45961ffa0445db02777ad9342119ceb2aa
Committed by
Samuel Ortiz
1 parent
58aa6334fb
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 193 additions and 21 deletions Side-by-side Diff
drivers/regulator/max8998.c
... | ... | @@ -340,24 +340,37 @@ |
340 | 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 | 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 | 357 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); |
358 | + struct max8998_platform_data *pdata = | |
359 | + dev_get_platdata(max8998->iodev->dev); | |
347 | 360 | struct i2c_client *i2c = max8998->iodev->i2c; |
348 | 361 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; |
349 | - int previous_vol = 0; | |
350 | 362 | const struct voltage_map_desc *desc; |
351 | - int ldo = max8998_get_ldo(rdev); | |
363 | + int buck = max8998_get_ldo(rdev); | |
352 | 364 | int reg, shift = 0, mask, ret; |
353 | - int i = 0; | |
354 | - u8 val; | |
355 | - bool en_ramp = false; | |
365 | + int difference = 0, i = 0, j = 0, previous_vol = 0; | |
366 | + u8 val = 0; | |
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 | 370 | return -EINVAL; |
359 | 371 | |
360 | - desc = ldo_voltage_map[ldo]; | |
372 | + desc = ldo_voltage_map[buck]; | |
373 | + | |
361 | 374 | if (desc == NULL) |
362 | 375 | return -EINVAL; |
363 | 376 | |
364 | 377 | |
365 | 378 | |
366 | 379 | |
... | ... | @@ -375,24 +388,102 @@ |
375 | 388 | if (ret) |
376 | 389 | return ret; |
377 | 390 | |
378 | - /* wait for RAMP_UP_DELAY if rdev is BUCK1/2 and | |
379 | - * ENRAMP is ON */ | |
380 | - if (ldo == MAX8998_BUCK1 || ldo == MAX8998_BUCK2) { | |
381 | - max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); | |
382 | - if (val & (1 << 4)) { | |
383 | - en_ramp = true; | |
384 | - previous_vol = max8998_get_voltage(rdev); | |
385 | - } | |
391 | + previous_vol = max8998_get_voltage(rdev); | |
392 | + | |
393 | + /* Check if voltage needs to be changed */ | |
394 | + /* if previous_voltage equal new voltage, return */ | |
395 | + if (previous_vol == max8998_list_voltage(rdev, i)) { | |
396 | + dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n", | |
397 | + previous_vol, max8998_list_voltage(rdev, i)); | |
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]); | |
389 | 408 | |
390 | - if (en_ramp == true) { | |
391 | - int difference = desc->min + desc->step*i - previous_vol/1000; | |
392 | - if (difference > 0) | |
393 | - udelay(difference / ((val & 0x0f) + 1)); | |
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; | |
444 | + | |
445 | + case MAX8998_BUCK2: | |
446 | + dev_dbg(max8998->dev, | |
447 | + "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" | |
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 | 487 | return ret; |
397 | 488 | } |
398 | 489 | |
... | ... | @@ -586,6 +677,7 @@ |
586 | 677 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); |
587 | 678 | struct regulator_dev **rdev; |
588 | 679 | struct max8998_data *max8998; |
680 | + struct i2c_client *i2c; | |
589 | 681 | int i, ret, size; |
590 | 682 | |
591 | 683 | if (!pdata) { |
... | ... | @@ -609,6 +701,86 @@ |
609 | 701 | max8998->iodev = iodev; |
610 | 702 | max8998->num_regulators = pdata->num_regulators; |
611 | 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 | 785 | for (i = 0; i < pdata->num_regulators; i++) { |
614 | 786 | const struct voltage_map_desc *desc; |