aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/arizona-ldo1.c4
-rw-r--r--drivers/regulator/arizona-micsupp.c5
-rw-r--r--drivers/regulator/core.c126
-rw-r--r--drivers/regulator/wm831x-ldo.c8
4 files changed, 143 insertions, 0 deletions
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index c8f95c07adb6..80e012f14160 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -39,6 +39,8 @@ static struct regulator_ops arizona_ldo1_ops = {
39 .map_voltage = regulator_map_voltage_linear, 39 .map_voltage = regulator_map_voltage_linear,
40 .get_voltage_sel = regulator_get_voltage_sel_regmap, 40 .get_voltage_sel = regulator_get_voltage_sel_regmap,
41 .set_voltage_sel = regulator_set_voltage_sel_regmap, 41 .set_voltage_sel = regulator_set_voltage_sel_regmap,
42 .get_bypass = regulator_get_bypass_regmap,
43 .set_bypass = regulator_set_bypass_regmap,
42}; 44};
43 45
44static const struct regulator_desc arizona_ldo1 = { 46static const struct regulator_desc arizona_ldo1 = {
@@ -49,6 +51,8 @@ static const struct regulator_desc arizona_ldo1 = {
49 51
50 .vsel_reg = ARIZONA_LDO1_CONTROL_1, 52 .vsel_reg = ARIZONA_LDO1_CONTROL_1,
51 .vsel_mask = ARIZONA_LDO1_VSEL_MASK, 53 .vsel_mask = ARIZONA_LDO1_VSEL_MASK,
54 .bypass_reg = ARIZONA_LDO1_CONTROL_1,
55 .bypass_mask = ARIZONA_LDO1_BYPASS,
52 .min_uV = 900000, 56 .min_uV = 900000,
53 .uV_step = 50000, 57 .uV_step = 50000,
54 .n_voltages = 7, 58 .n_voltages = 7,
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index 450a069aa9b6..d9b1f82cc5bd 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = {
82 82
83 .get_voltage_sel = regulator_get_voltage_sel_regmap, 83 .get_voltage_sel = regulator_get_voltage_sel_regmap,
84 .set_voltage_sel = regulator_set_voltage_sel_regmap, 84 .set_voltage_sel = regulator_set_voltage_sel_regmap,
85
86 .get_bypass = regulator_get_bypass_regmap,
87 .set_bypass = regulator_set_bypass_regmap,
85}; 88};
86 89
87static const struct regulator_desc arizona_micsupp = { 90static const struct regulator_desc arizona_micsupp = {
@@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = {
95 .vsel_mask = ARIZONA_LDO2_VSEL_MASK, 98 .vsel_mask = ARIZONA_LDO2_VSEL_MASK,
96 .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, 99 .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
97 .enable_mask = ARIZONA_CPMIC_ENA, 100 .enable_mask = ARIZONA_CPMIC_ENA,
101 .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
102 .bypass_mask = ARIZONA_CPMIC_BYPASS,
98 103
99 .owner = THIS_MODULE, 104 .owner = THIS_MODULE,
100}; 105};
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 48385318175a..419805cdd9d7 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -77,6 +77,7 @@ struct regulator {
77 struct device *dev; 77 struct device *dev;
78 struct list_head list; 78 struct list_head list;
79 unsigned int always_on:1; 79 unsigned int always_on:1;
80 unsigned int bypass:1;
80 int uA_load; 81 int uA_load;
81 int min_uV; 82 int min_uV;
82 int max_uV; 83 int max_uV;
@@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev,
394 case REGULATOR_STATUS_STANDBY: 395 case REGULATOR_STATUS_STANDBY:
395 label = "standby"; 396 label = "standby";
396 break; 397 break;
398 case REGULATOR_STATUS_BYPASS:
399 label = "bypass";
400 break;
397 case REGULATOR_STATUS_UNDEFINED: 401 case REGULATOR_STATUS_UNDEFINED:
398 label = "undefined"; 402 label = "undefined";
399 break; 403 break;
@@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev,
585static DEVICE_ATTR(suspend_standby_state, 0444, 589static DEVICE_ATTR(suspend_standby_state, 0444,
586 regulator_suspend_standby_state_show, NULL); 590 regulator_suspend_standby_state_show, NULL);
587 591
592static ssize_t regulator_bypass_show(struct device *dev,
593 struct device_attribute *attr, char *buf)
594{
595 struct regulator_dev *rdev = dev_get_drvdata(dev);
596 const char *report;
597 bool bypass;
598 int ret;
599
600 ret = rdev->desc->ops->get_bypass(rdev, &bypass);
601
602 if (ret != 0)
603 report = "unknown";
604 else if (bypass)
605 report = "enabled";
606 else
607 report = "disabled";
608
609 return sprintf(buf, "%s\n", report);
610}
611static DEVICE_ATTR(bypass, 0444,
612 regulator_bypass_show, NULL);
588 613
589/* 614/*
590 * These are the only attributes are present for all regulators. 615 * These are the only attributes are present for all regulators.
@@ -2674,6 +2699,100 @@ out:
2674EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); 2699EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
2675 2700
2676/** 2701/**
2702 * regulator_set_bypass_regmap - Default set_bypass() using regmap
2703 *
2704 * @rdev: device to operate on.
2705 * @enable: state to set.
2706 */
2707int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
2708{
2709 unsigned int val;
2710
2711 if (enable)
2712 val = rdev->desc->bypass_mask;
2713 else
2714 val = 0;
2715
2716 return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
2717 rdev->desc->bypass_mask, val);
2718}
2719EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
2720
2721/**
2722 * regulator_get_bypass_regmap - Default get_bypass() using regmap
2723 *
2724 * @rdev: device to operate on.
2725 * @enable: current state.
2726 */
2727int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
2728{
2729 unsigned int val;
2730 int ret;
2731
2732 ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
2733 if (ret != 0)
2734 return ret;
2735
2736 *enable = val & rdev->desc->bypass_mask;
2737
2738 return 0;
2739}
2740EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
2741
2742/**
2743 * regulator_allow_bypass - allow the regulator to go into bypass mode
2744 *
2745 * @regulator: Regulator to configure
2746 * @allow: enable or disable bypass mode
2747 *
2748 * Allow the regulator to go into bypass mode if all other consumers
2749 * for the regulator also enable bypass mode and the machine
2750 * constraints allow this. Bypass mode means that the regulator is
2751 * simply passing the input directly to the output with no regulation.
2752 */
2753int regulator_allow_bypass(struct regulator *regulator, bool enable)
2754{
2755 struct regulator_dev *rdev = regulator->rdev;
2756 int ret = 0;
2757
2758 if (!rdev->desc->ops->set_bypass)
2759 return 0;
2760
2761 if (rdev->constraints &&
2762 !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
2763 return 0;
2764
2765 mutex_lock(&rdev->mutex);
2766
2767 if (enable && !regulator->bypass) {
2768 rdev->bypass_count++;
2769
2770 if (rdev->bypass_count == rdev->open_count) {
2771 ret = rdev->desc->ops->set_bypass(rdev, enable);
2772 if (ret != 0)
2773 rdev->bypass_count--;
2774 }
2775
2776 } else if (!enable && regulator->bypass) {
2777 rdev->bypass_count--;
2778
2779 if (rdev->bypass_count != rdev->open_count) {
2780 ret = rdev->desc->ops->set_bypass(rdev, enable);
2781 if (ret != 0)
2782 rdev->bypass_count++;
2783 }
2784 }
2785
2786 if (ret == 0)
2787 regulator->bypass = enable;
2788
2789 mutex_unlock(&rdev->mutex);
2790
2791 return ret;
2792}
2793EXPORT_SYMBOL_GPL(regulator_allow_bypass);
2794
2795/**
2677 * regulator_register_notifier - register regulator event notifier 2796 * regulator_register_notifier - register regulator event notifier
2678 * @regulator: regulator source 2797 * @regulator: regulator source
2679 * @nb: notifier block 2798 * @nb: notifier block
@@ -3036,6 +3155,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
3036 if (status < 0) 3155 if (status < 0)
3037 return status; 3156 return status;
3038 } 3157 }
3158 if (ops->get_bypass) {
3159 status = device_create_file(dev, &dev_attr_bypass);
3160 if (status < 0)
3161 return status;
3162 }
3039 3163
3040 /* some attributes are type-specific */ 3164 /* some attributes are type-specific */
3041 if (rdev->desc->type == REGULATOR_CURRENT) { 3165 if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -3124,6 +3248,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
3124 &rdev->use_count); 3248 &rdev->use_count);
3125 debugfs_create_u32("open_count", 0444, rdev->debugfs, 3249 debugfs_create_u32("open_count", 0444, rdev->debugfs,
3126 &rdev->open_count); 3250 &rdev->open_count);
3251 debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
3252 &rdev->bypass_count);
3127} 3253}
3128 3254
3129/** 3255/**
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 5cb70ca1e98d..f203a972dedf 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -237,6 +237,8 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
237 .set_mode = wm831x_gp_ldo_set_mode, 237 .set_mode = wm831x_gp_ldo_set_mode,
238 .get_status = wm831x_gp_ldo_get_status, 238 .get_status = wm831x_gp_ldo_get_status,
239 .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode, 239 .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
240 .get_bypass = regulator_get_bypass_regmap,
241 .set_bypass = regulator_set_bypass_regmap,
240 242
241 .is_enabled = regulator_is_enabled_regmap, 243 .is_enabled = regulator_is_enabled_regmap,
242 .enable = regulator_enable_regmap, 244 .enable = regulator_enable_regmap,
@@ -293,6 +295,8 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
293 ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK; 295 ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK;
294 ldo->desc.enable_reg = WM831X_LDO_ENABLE; 296 ldo->desc.enable_reg = WM831X_LDO_ENABLE;
295 ldo->desc.enable_mask = 1 << id; 297 ldo->desc.enable_mask = 1 << id;
298 ldo->desc.bypass_reg = ldo->base;
299 ldo->desc.bypass_mask = WM831X_LDO1_SWI;
296 300
297 config.dev = pdev->dev.parent; 301 config.dev = pdev->dev.parent;
298 if (pdata) 302 if (pdata)
@@ -488,6 +492,8 @@ static struct regulator_ops wm831x_aldo_ops = {
488 .get_mode = wm831x_aldo_get_mode, 492 .get_mode = wm831x_aldo_get_mode,
489 .set_mode = wm831x_aldo_set_mode, 493 .set_mode = wm831x_aldo_set_mode,
490 .get_status = wm831x_aldo_get_status, 494 .get_status = wm831x_aldo_get_status,
495 .set_bypass = regulator_set_bypass_regmap,
496 .get_bypass = regulator_get_bypass_regmap,
491 497
492 .is_enabled = regulator_is_enabled_regmap, 498 .is_enabled = regulator_is_enabled_regmap,
493 .enable = regulator_enable_regmap, 499 .enable = regulator_enable_regmap,
@@ -544,6 +550,8 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
544 ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK; 550 ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK;
545 ldo->desc.enable_reg = WM831X_LDO_ENABLE; 551 ldo->desc.enable_reg = WM831X_LDO_ENABLE;
546 ldo->desc.enable_mask = 1 << id; 552 ldo->desc.enable_mask = 1 << id;
553 ldo->desc.bypass_reg = ldo->base;
554 ldo->desc.bypass_mask = WM831X_LDO7_SWI;
547 555
548 config.dev = pdev->dev.parent; 556 config.dev = pdev->dev.parent;
549 if (pdata) 557 if (pdata)