diff options
-rw-r--r-- | drivers/mfd/wm5102-tables.c | 3 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 7 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 1 | ||||
-rw-r--r-- | drivers/regulator/arizona-ldo1.c | 130 | ||||
-rw-r--r-- | drivers/regulator/arizona-micsupp.c | 2 | ||||
-rw-r--r-- | drivers/regulator/as3711-regulator.c | 369 | ||||
-rw-r--r-- | drivers/regulator/core.c | 22 | ||||
-rw-r--r-- | drivers/regulator/wm831x-dcdc.c | 2 | ||||
-rw-r--r-- | include/linux/mfd/arizona/registers.h | 16 | ||||
-rw-r--r-- | include/linux/regulator/consumer.h | 1 |
10 files changed, 549 insertions, 4 deletions
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 01b9255ed631..b829a5710ddc 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
@@ -775,6 +775,7 @@ static const struct reg_default wm5102_reg_default[] = { | |||
775 | { 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */ | 775 | { 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */ |
776 | { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ | 776 | { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ |
777 | { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ | 777 | { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ |
778 | { 0x00000161, 0x0000 }, /* R353 - Dynamic Frequency Scaling 1 */ | ||
778 | { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */ | 779 | { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */ |
779 | { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ | 780 | { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ |
780 | { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ | 781 | { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ |
@@ -1564,6 +1565,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
1564 | case ARIZONA_RATE_ESTIMATOR_3: | 1565 | case ARIZONA_RATE_ESTIMATOR_3: |
1565 | case ARIZONA_RATE_ESTIMATOR_4: | 1566 | case ARIZONA_RATE_ESTIMATOR_4: |
1566 | case ARIZONA_RATE_ESTIMATOR_5: | 1567 | case ARIZONA_RATE_ESTIMATOR_5: |
1568 | case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1: | ||
1567 | case ARIZONA_FLL1_CONTROL_1: | 1569 | case ARIZONA_FLL1_CONTROL_1: |
1568 | case ARIZONA_FLL1_CONTROL_2: | 1570 | case ARIZONA_FLL1_CONTROL_2: |
1569 | case ARIZONA_FLL1_CONTROL_3: | 1571 | case ARIZONA_FLL1_CONTROL_3: |
@@ -1596,6 +1598,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
1596 | case ARIZONA_FLL2_GPIO_CLOCK: | 1598 | case ARIZONA_FLL2_GPIO_CLOCK: |
1597 | case ARIZONA_MIC_CHARGE_PUMP_1: | 1599 | case ARIZONA_MIC_CHARGE_PUMP_1: |
1598 | case ARIZONA_LDO1_CONTROL_1: | 1600 | case ARIZONA_LDO1_CONTROL_1: |
1601 | case ARIZONA_LDO1_CONTROL_2: | ||
1599 | case ARIZONA_LDO2_CONTROL_1: | 1602 | case ARIZONA_LDO2_CONTROL_1: |
1600 | case ARIZONA_MIC_BIAS_CTRL_1: | 1603 | case ARIZONA_MIC_BIAS_CTRL_1: |
1601 | case ARIZONA_MIC_BIAS_CTRL_2: | 1604 | case ARIZONA_MIC_BIAS_CTRL_2: |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59a66d..f73d6f5ce6dd 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -450,5 +450,12 @@ config REGULATOR_WM8994 | |||
450 | This driver provides support for the voltage regulators on the | 450 | This driver provides support for the voltage regulators on the |
451 | WM8994 CODEC. | 451 | WM8994 CODEC. |
452 | 452 | ||
453 | config REGULATOR_AS3711 | ||
454 | tristate "AS3711 PMIC" | ||
455 | depends on MFD_AS3711 | ||
456 | help | ||
457 | This driver provides support for the voltage regulators on the | ||
458 | AS3711 PMIC | ||
459 | |||
453 | endif | 460 | endif |
454 | 461 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed8a878..c1557ace9095 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -16,6 +16,7 @@ obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o | |||
16 | obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o | 16 | obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o |
17 | obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o | 17 | obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o |
18 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o | 18 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o |
19 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o | ||
19 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | 20 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o |
20 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | 21 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o |
21 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o | 22 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o |
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index d184aa35abcb..739faf99b9e2 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
@@ -34,6 +34,108 @@ struct arizona_ldo1 { | |||
34 | struct regulator_init_data init_data; | 34 | struct regulator_init_data init_data; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev, | ||
38 | unsigned int selector) | ||
39 | { | ||
40 | if (selector >= rdev->desc->n_voltages) | ||
41 | return -EINVAL; | ||
42 | |||
43 | if (selector == rdev->desc->n_voltages - 1) | ||
44 | return 1800000; | ||
45 | else | ||
46 | return rdev->desc->min_uV + (rdev->desc->uV_step * selector); | ||
47 | } | ||
48 | |||
49 | static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev, | ||
50 | int min_uV, int max_uV) | ||
51 | { | ||
52 | int sel; | ||
53 | |||
54 | sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); | ||
55 | if (sel >= rdev->desc->n_voltages) | ||
56 | sel = rdev->desc->n_voltages - 1; | ||
57 | |||
58 | return sel; | ||
59 | } | ||
60 | |||
61 | static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, | ||
62 | unsigned sel) | ||
63 | { | ||
64 | struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); | ||
65 | struct regmap *regmap = ldo->arizona->regmap; | ||
66 | unsigned int val; | ||
67 | int ret; | ||
68 | |||
69 | if (sel == rdev->desc->n_voltages - 1) | ||
70 | val = ARIZONA_LDO1_HI_PWR; | ||
71 | else | ||
72 | val = 0; | ||
73 | |||
74 | ret = regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_2, | ||
75 | ARIZONA_LDO1_HI_PWR, val); | ||
76 | if (ret != 0) | ||
77 | return ret; | ||
78 | |||
79 | ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1, | ||
80 | ARIZONA_SUBSYS_MAX_FREQ, val); | ||
81 | if (ret != 0) | ||
82 | return ret; | ||
83 | |||
84 | if (val) | ||
85 | return 0; | ||
86 | |||
87 | val = sel << ARIZONA_LDO1_VSEL_SHIFT; | ||
88 | |||
89 | return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1, | ||
90 | ARIZONA_LDO1_VSEL_MASK, val); | ||
91 | } | ||
92 | |||
93 | static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) | ||
94 | { | ||
95 | struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); | ||
96 | struct regmap *regmap = ldo->arizona->regmap; | ||
97 | unsigned int val; | ||
98 | int ret; | ||
99 | |||
100 | ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_2, &val); | ||
101 | if (ret != 0) | ||
102 | return ret; | ||
103 | |||
104 | if (val & ARIZONA_LDO1_HI_PWR) | ||
105 | return rdev->desc->n_voltages - 1; | ||
106 | |||
107 | ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val); | ||
108 | if (ret != 0) | ||
109 | return ret; | ||
110 | |||
111 | return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT; | ||
112 | } | ||
113 | |||
114 | static struct regulator_ops arizona_ldo1_hc_ops = { | ||
115 | .list_voltage = arizona_ldo1_hc_list_voltage, | ||
116 | .map_voltage = arizona_ldo1_hc_map_voltage, | ||
117 | .get_voltage_sel = arizona_ldo1_hc_get_voltage_sel, | ||
118 | .set_voltage_sel = arizona_ldo1_hc_set_voltage_sel, | ||
119 | .get_bypass = regulator_get_bypass_regmap, | ||
120 | .set_bypass = regulator_set_bypass_regmap, | ||
121 | }; | ||
122 | |||
123 | static const struct regulator_desc arizona_ldo1_hc = { | ||
124 | .name = "LDO1", | ||
125 | .supply_name = "LDOVDD", | ||
126 | .type = REGULATOR_VOLTAGE, | ||
127 | .ops = &arizona_ldo1_hc_ops, | ||
128 | |||
129 | .bypass_reg = ARIZONA_LDO1_CONTROL_1, | ||
130 | .bypass_mask = ARIZONA_LDO1_BYPASS, | ||
131 | .min_uV = 900000, | ||
132 | .uV_step = 50000, | ||
133 | .n_voltages = 8, | ||
134 | .enable_time = 500, | ||
135 | |||
136 | .owner = THIS_MODULE, | ||
137 | }; | ||
138 | |||
37 | static struct regulator_ops arizona_ldo1_ops = { | 139 | static struct regulator_ops arizona_ldo1_ops = { |
38 | .list_voltage = regulator_list_voltage_linear, | 140 | .list_voltage = regulator_list_voltage_linear, |
39 | .map_voltage = regulator_map_voltage_linear, | 141 | .map_voltage = regulator_map_voltage_linear, |
@@ -55,11 +157,22 @@ static const struct regulator_desc arizona_ldo1 = { | |||
55 | .bypass_mask = ARIZONA_LDO1_BYPASS, | 157 | .bypass_mask = ARIZONA_LDO1_BYPASS, |
56 | .min_uV = 900000, | 158 | .min_uV = 900000, |
57 | .uV_step = 50000, | 159 | .uV_step = 50000, |
58 | .n_voltages = 6, | 160 | .n_voltages = 7, |
161 | .enable_time = 500, | ||
59 | 162 | ||
60 | .owner = THIS_MODULE, | 163 | .owner = THIS_MODULE, |
61 | }; | 164 | }; |
62 | 165 | ||
166 | static const struct regulator_init_data arizona_ldo1_dvfs = { | ||
167 | .constraints = { | ||
168 | .min_uV = 1200000, | ||
169 | .max_uV = 1800000, | ||
170 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | | ||
171 | REGULATOR_CHANGE_VOLTAGE, | ||
172 | }, | ||
173 | .num_consumer_supplies = 1, | ||
174 | }; | ||
175 | |||
63 | static const struct regulator_init_data arizona_ldo1_default = { | 176 | static const struct regulator_init_data arizona_ldo1_default = { |
64 | .constraints = { | 177 | .constraints = { |
65 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 178 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
@@ -70,6 +183,7 @@ static const struct regulator_init_data arizona_ldo1_default = { | |||
70 | static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | 183 | static __devinit int arizona_ldo1_probe(struct platform_device *pdev) |
71 | { | 184 | { |
72 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | 185 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); |
186 | const struct regulator_desc *desc; | ||
73 | struct regulator_config config = { }; | 187 | struct regulator_config config = { }; |
74 | struct arizona_ldo1 *ldo1; | 188 | struct arizona_ldo1 *ldo1; |
75 | int ret; | 189 | int ret; |
@@ -87,7 +201,17 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | |||
87 | * default init_data for it. This will be overridden with | 201 | * default init_data for it. This will be overridden with |
88 | * platform data if provided. | 202 | * platform data if provided. |
89 | */ | 203 | */ |
90 | ldo1->init_data = arizona_ldo1_default; | 204 | switch (arizona->type) { |
205 | case WM5102: | ||
206 | desc = &arizona_ldo1_hc; | ||
207 | ldo1->init_data = arizona_ldo1_dvfs; | ||
208 | break; | ||
209 | default: | ||
210 | desc = &arizona_ldo1; | ||
211 | ldo1->init_data = arizona_ldo1_default; | ||
212 | break; | ||
213 | } | ||
214 | |||
91 | ldo1->init_data.consumer_supplies = &ldo1->supply; | 215 | ldo1->init_data.consumer_supplies = &ldo1->supply; |
92 | ldo1->supply.supply = "DCVDD"; | 216 | ldo1->supply.supply = "DCVDD"; |
93 | ldo1->supply.dev_name = dev_name(arizona->dev); | 217 | ldo1->supply.dev_name = dev_name(arizona->dev); |
@@ -102,7 +226,7 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | |||
102 | else | 226 | else |
103 | config.init_data = &ldo1->init_data; | 227 | config.init_data = &ldo1->init_data; |
104 | 228 | ||
105 | ldo1->regulator = regulator_register(&arizona_ldo1, &config); | 229 | ldo1->regulator = regulator_register(desc, &config); |
106 | if (IS_ERR(ldo1->regulator)) { | 230 | if (IS_ERR(ldo1->regulator)) { |
107 | ret = PTR_ERR(ldo1->regulator); | 231 | ret = PTR_ERR(ldo1->regulator); |
108 | dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", | 232 | dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", |
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index d9b1f82cc5bd..93d0604e64b4 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c | |||
@@ -101,6 +101,8 @@ static const struct regulator_desc arizona_micsupp = { | |||
101 | .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, | 101 | .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, |
102 | .bypass_mask = ARIZONA_CPMIC_BYPASS, | 102 | .bypass_mask = ARIZONA_CPMIC_BYPASS, |
103 | 103 | ||
104 | .enable_time = 3000, | ||
105 | |||
104 | .owner = THIS_MODULE, | 106 | .owner = THIS_MODULE, |
105 | }; | 107 | }; |
106 | 108 | ||
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c new file mode 100644 index 000000000000..2f1341db38a0 --- /dev/null +++ b/drivers/regulator/as3711-regulator.c | |||
@@ -0,0 +1,369 @@ | |||
1 | /* | ||
2 | * AS3711 PMIC regulator driver, using DCDC Step Down and LDO supplies | ||
3 | * | ||
4 | * Copyright (C) 2012 Renesas Electronics Corporation | ||
5 | * Author: Guennadi Liakhovetski, <g.liakhovetski@gmx.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation | ||
10 | */ | ||
11 | |||
12 | #include <linux/err.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/mfd/as3711.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/regulator/driver.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | struct as3711_regulator_info { | ||
22 | struct regulator_desc desc; | ||
23 | unsigned int max_uV; | ||
24 | }; | ||
25 | |||
26 | struct as3711_regulator { | ||
27 | struct as3711_regulator_info *reg_info; | ||
28 | struct regulator_dev *rdev; | ||
29 | }; | ||
30 | |||
31 | static int as3711_list_voltage_sd(struct regulator_dev *rdev, | ||
32 | unsigned int selector) | ||
33 | { | ||
34 | if (selector >= rdev->desc->n_voltages) | ||
35 | return -EINVAL; | ||
36 | |||
37 | if (!selector) | ||
38 | return 0; | ||
39 | if (selector < 0x41) | ||
40 | return 600000 + selector * 12500; | ||
41 | if (selector < 0x71) | ||
42 | return 1400000 + (selector - 0x40) * 25000; | ||
43 | return 2600000 + (selector - 0x70) * 50000; | ||
44 | } | ||
45 | |||
46 | static int as3711_list_voltage_aldo(struct regulator_dev *rdev, | ||
47 | unsigned int selector) | ||
48 | { | ||
49 | if (selector >= rdev->desc->n_voltages) | ||
50 | return -EINVAL; | ||
51 | |||
52 | if (selector < 0x10) | ||
53 | return 1200000 + selector * 50000; | ||
54 | return 1800000 + (selector - 0x10) * 100000; | ||
55 | } | ||
56 | |||
57 | static int as3711_list_voltage_dldo(struct regulator_dev *rdev, | ||
58 | unsigned int selector) | ||
59 | { | ||
60 | if (selector >= rdev->desc->n_voltages || | ||
61 | (selector > 0x10 && selector < 0x20)) | ||
62 | return -EINVAL; | ||
63 | |||
64 | if (selector < 0x11) | ||
65 | return 900000 + selector * 50000; | ||
66 | return 1750000 + (selector - 0x20) * 50000; | ||
67 | } | ||
68 | |||
69 | static int as3711_bound_check(struct regulator_dev *rdev, | ||
70 | int *min_uV, int *max_uV) | ||
71 | { | ||
72 | struct as3711_regulator *reg = rdev_get_drvdata(rdev); | ||
73 | struct as3711_regulator_info *info = reg->reg_info; | ||
74 | |||
75 | dev_dbg(&rdev->dev, "%s(), %d, %d, %d\n", __func__, | ||
76 | *min_uV, rdev->desc->min_uV, info->max_uV); | ||
77 | |||
78 | if (*max_uV < *min_uV || | ||
79 | *min_uV > info->max_uV || rdev->desc->min_uV > *max_uV) | ||
80 | return -EINVAL; | ||
81 | |||
82 | if (rdev->desc->n_voltages == 1) | ||
83 | return 0; | ||
84 | |||
85 | if (*max_uV > info->max_uV) | ||
86 | *max_uV = info->max_uV; | ||
87 | |||
88 | if (*min_uV < rdev->desc->min_uV) | ||
89 | *min_uV = rdev->desc->min_uV; | ||
90 | |||
91 | return *min_uV; | ||
92 | } | ||
93 | |||
94 | static int as3711_sel_check(int min, int max, int bottom, int step) | ||
95 | { | ||
96 | int sel, voltage; | ||
97 | |||
98 | /* Round up min, when dividing: keeps us within the range */ | ||
99 | sel = DIV_ROUND_UP(min - bottom, step); | ||
100 | voltage = sel * step + bottom; | ||
101 | pr_debug("%s(): select %d..%d in %d+N*%d: %d\n", __func__, | ||
102 | min, max, bottom, step, sel); | ||
103 | if (voltage > max) | ||
104 | return -EINVAL; | ||
105 | |||
106 | return sel; | ||
107 | } | ||
108 | |||
109 | static int as3711_map_voltage_sd(struct regulator_dev *rdev, | ||
110 | int min_uV, int max_uV) | ||
111 | { | ||
112 | int ret; | ||
113 | |||
114 | ret = as3711_bound_check(rdev, &min_uV, &max_uV); | ||
115 | if (ret <= 0) | ||
116 | return ret; | ||
117 | |||
118 | if (min_uV <= 1400000) | ||
119 | return as3711_sel_check(min_uV, max_uV, 600000, 12500); | ||
120 | |||
121 | if (min_uV <= 2600000) | ||
122 | return as3711_sel_check(min_uV, max_uV, 1400000, 25000) + 0x40; | ||
123 | |||
124 | return as3711_sel_check(min_uV, max_uV, 2600000, 50000) + 0x70; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * The regulator API supports 4 modes of operataion: FAST, NORMAL, IDLE and | ||
129 | * STANDBY. We map them in the following way to AS3711 SD1-4 DCDC modes: | ||
130 | * FAST: sdX_fast=1 | ||
131 | * NORMAL: low_noise=1 | ||
132 | * IDLE: low_noise=0 | ||
133 | */ | ||
134 | |||
135 | static int as3711_set_mode_sd(struct regulator_dev *rdev, unsigned int mode) | ||
136 | { | ||
137 | unsigned int fast_bit = rdev->desc->enable_mask, | ||
138 | low_noise_bit = fast_bit << 4; | ||
139 | u8 val; | ||
140 | |||
141 | switch (mode) { | ||
142 | case REGULATOR_MODE_FAST: | ||
143 | val = fast_bit | low_noise_bit; | ||
144 | break; | ||
145 | case REGULATOR_MODE_NORMAL: | ||
146 | val = low_noise_bit; | ||
147 | break; | ||
148 | case REGULATOR_MODE_IDLE: | ||
149 | val = 0; | ||
150 | break; | ||
151 | default: | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | return regmap_update_bits(rdev->regmap, AS3711_SD_CONTROL_1, | ||
156 | low_noise_bit | fast_bit, val); | ||
157 | } | ||
158 | |||
159 | static unsigned int as3711_get_mode_sd(struct regulator_dev *rdev) | ||
160 | { | ||
161 | unsigned int fast_bit = rdev->desc->enable_mask, | ||
162 | low_noise_bit = fast_bit << 4, mask = fast_bit | low_noise_bit; | ||
163 | unsigned int val; | ||
164 | int ret = regmap_read(rdev->regmap, AS3711_SD_CONTROL_1, &val); | ||
165 | |||
166 | if (ret < 0) | ||
167 | return ret; | ||
168 | |||
169 | if ((val & mask) == mask) | ||
170 | return REGULATOR_MODE_FAST; | ||
171 | |||
172 | if ((val & mask) == low_noise_bit) | ||
173 | return REGULATOR_MODE_NORMAL; | ||
174 | |||
175 | if (!(val & mask)) | ||
176 | return REGULATOR_MODE_IDLE; | ||
177 | |||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | static int as3711_map_voltage_aldo(struct regulator_dev *rdev, | ||
182 | int min_uV, int max_uV) | ||
183 | { | ||
184 | int ret; | ||
185 | |||
186 | ret = as3711_bound_check(rdev, &min_uV, &max_uV); | ||
187 | if (ret <= 0) | ||
188 | return ret; | ||
189 | |||
190 | if (min_uV <= 1800000) | ||
191 | return as3711_sel_check(min_uV, max_uV, 1200000, 50000); | ||
192 | |||
193 | return as3711_sel_check(min_uV, max_uV, 1800000, 100000) + 0x10; | ||
194 | } | ||
195 | |||
196 | static int as3711_map_voltage_dldo(struct regulator_dev *rdev, | ||
197 | int min_uV, int max_uV) | ||
198 | { | ||
199 | int ret; | ||
200 | |||
201 | ret = as3711_bound_check(rdev, &min_uV, &max_uV); | ||
202 | if (ret <= 0) | ||
203 | return ret; | ||
204 | |||
205 | if (min_uV <= 1700000) | ||
206 | return as3711_sel_check(min_uV, max_uV, 900000, 50000); | ||
207 | |||
208 | return as3711_sel_check(min_uV, max_uV, 1750000, 50000) + 0x20; | ||
209 | } | ||
210 | |||
211 | static struct regulator_ops as3711_sd_ops = { | ||
212 | .is_enabled = regulator_is_enabled_regmap, | ||
213 | .enable = regulator_enable_regmap, | ||
214 | .disable = regulator_disable_regmap, | ||
215 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
216 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
217 | .list_voltage = as3711_list_voltage_sd, | ||
218 | .map_voltage = as3711_map_voltage_sd, | ||
219 | .get_mode = as3711_get_mode_sd, | ||
220 | .set_mode = as3711_set_mode_sd, | ||
221 | }; | ||
222 | |||
223 | static struct regulator_ops as3711_aldo_ops = { | ||
224 | .is_enabled = regulator_is_enabled_regmap, | ||
225 | .enable = regulator_enable_regmap, | ||
226 | .disable = regulator_disable_regmap, | ||
227 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
228 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
229 | .list_voltage = as3711_list_voltage_aldo, | ||
230 | .map_voltage = as3711_map_voltage_aldo, | ||
231 | }; | ||
232 | |||
233 | static struct regulator_ops as3711_dldo_ops = { | ||
234 | .is_enabled = regulator_is_enabled_regmap, | ||
235 | .enable = regulator_enable_regmap, | ||
236 | .disable = regulator_disable_regmap, | ||
237 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
238 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
239 | .list_voltage = as3711_list_voltage_dldo, | ||
240 | .map_voltage = as3711_map_voltage_dldo, | ||
241 | }; | ||
242 | |||
243 | #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _vshift, _min_uV, _max_uV, _sfx) \ | ||
244 | [AS3711_REGULATOR_ ## _id] = { \ | ||
245 | .desc = { \ | ||
246 | .name = "as3711-regulator-" # _id, \ | ||
247 | .id = AS3711_REGULATOR_ ## _id, \ | ||
248 | .n_voltages = (_vmask + 1), \ | ||
249 | .ops = &as3711_ ## _sfx ## _ops, \ | ||
250 | .type = REGULATOR_VOLTAGE, \ | ||
251 | .owner = THIS_MODULE, \ | ||
252 | .vsel_reg = AS3711_ ## _id ## _VOLTAGE, \ | ||
253 | .vsel_mask = _vmask << _vshift, \ | ||
254 | .enable_reg = AS3711_ ## _en_reg, \ | ||
255 | .enable_mask = BIT(_en_bit), \ | ||
256 | .min_uV = _min_uV, \ | ||
257 | }, \ | ||
258 | .max_uV = _max_uV, \ | ||
259 | } | ||
260 | |||
261 | static struct as3711_regulator_info as3711_reg_info[] = { | ||
262 | AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, 0, 612500, 3350000, sd), | ||
263 | AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, 0, 612500, 3350000, sd), | ||
264 | AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, 0, 612500, 3350000, sd), | ||
265 | AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, 0, 612500, 3350000, sd), | ||
266 | AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), | ||
267 | AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), | ||
268 | AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | ||
269 | AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | ||
270 | AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | ||
271 | AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | ||
272 | AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | ||
273 | AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | ||
274 | /* StepUp output voltage depends on supplying regulator */ | ||
275 | }; | ||
276 | |||
277 | #define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info) | ||
278 | |||
279 | static int as3711_regulator_probe(struct platform_device *pdev) | ||
280 | { | ||
281 | struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
282 | struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); | ||
283 | struct regulator_init_data *reg_data; | ||
284 | struct regulator_config config = {.dev = &pdev->dev,}; | ||
285 | struct as3711_regulator *reg = NULL; | ||
286 | struct as3711_regulator *regs; | ||
287 | struct regulator_dev *rdev; | ||
288 | struct as3711_regulator_info *ri; | ||
289 | int ret; | ||
290 | int id; | ||
291 | |||
292 | if (!pdata) | ||
293 | dev_dbg(&pdev->dev, "No platform data...\n"); | ||
294 | |||
295 | regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * | ||
296 | sizeof(struct as3711_regulator), GFP_KERNEL); | ||
297 | if (!regs) { | ||
298 | dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); | ||
299 | return -ENOMEM; | ||
300 | } | ||
301 | |||
302 | for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { | ||
303 | reg_data = pdata ? pdata->init_data[id] : NULL; | ||
304 | |||
305 | /* No need to register if there is no regulator data */ | ||
306 | if (!ri->desc.name) | ||
307 | continue; | ||
308 | |||
309 | reg = ®s[id]; | ||
310 | reg->reg_info = ri; | ||
311 | |||
312 | config.init_data = reg_data; | ||
313 | config.driver_data = reg; | ||
314 | config.regmap = as3711->regmap; | ||
315 | |||
316 | rdev = regulator_register(&ri->desc, &config); | ||
317 | if (IS_ERR(rdev)) { | ||
318 | dev_err(&pdev->dev, "Failed to register regulator %s\n", | ||
319 | ri->desc.name); | ||
320 | ret = PTR_ERR(rdev); | ||
321 | goto eregreg; | ||
322 | } | ||
323 | reg->rdev = rdev; | ||
324 | } | ||
325 | platform_set_drvdata(pdev, regs); | ||
326 | return 0; | ||
327 | |||
328 | eregreg: | ||
329 | while (--id >= 0) | ||
330 | regulator_unregister(regs[id].rdev); | ||
331 | |||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static int as3711_regulator_remove(struct platform_device *pdev) | ||
336 | { | ||
337 | struct as3711_regulator *regs = platform_get_drvdata(pdev); | ||
338 | int id; | ||
339 | |||
340 | for (id = 0; id < AS3711_REGULATOR_NUM; ++id) | ||
341 | regulator_unregister(regs[id].rdev); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static struct platform_driver as3711_regulator_driver = { | ||
346 | .driver = { | ||
347 | .name = "as3711-regulator", | ||
348 | .owner = THIS_MODULE, | ||
349 | }, | ||
350 | .probe = as3711_regulator_probe, | ||
351 | .remove = as3711_regulator_remove, | ||
352 | }; | ||
353 | |||
354 | static int __init as3711_regulator_init(void) | ||
355 | { | ||
356 | return platform_driver_register(&as3711_regulator_driver); | ||
357 | } | ||
358 | subsys_initcall(as3711_regulator_init); | ||
359 | |||
360 | static void __exit as3711_regulator_exit(void) | ||
361 | { | ||
362 | platform_driver_unregister(&as3711_regulator_driver); | ||
363 | } | ||
364 | module_exit(as3711_regulator_exit); | ||
365 | |||
366 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
367 | MODULE_DESCRIPTION("AS3711 regulator driver"); | ||
368 | MODULE_ALIAS("platform:as3711-regulator"); | ||
369 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8be080e..59e08633372a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -1867,6 +1867,28 @@ int regulator_is_enabled(struct regulator *regulator) | |||
1867 | EXPORT_SYMBOL_GPL(regulator_is_enabled); | 1867 | EXPORT_SYMBOL_GPL(regulator_is_enabled); |
1868 | 1868 | ||
1869 | /** | 1869 | /** |
1870 | * regulator_can_change_voltage - check if regulator can change voltage | ||
1871 | * @regulator: regulator source | ||
1872 | * | ||
1873 | * Returns positive if the regulator driver backing the source/client | ||
1874 | * can change its voltage, false otherwise. Usefull for detecting fixed | ||
1875 | * or dummy regulators and disabling voltage change logic in the client | ||
1876 | * driver. | ||
1877 | */ | ||
1878 | int regulator_can_change_voltage(struct regulator *regulator) | ||
1879 | { | ||
1880 | struct regulator_dev *rdev = regulator->rdev; | ||
1881 | |||
1882 | if (rdev->constraints && | ||
1883 | rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE && | ||
1884 | rdev->desc->n_voltages > 1) | ||
1885 | return 1; | ||
1886 | |||
1887 | return 0; | ||
1888 | } | ||
1889 | EXPORT_SYMBOL_GPL(regulator_can_change_voltage); | ||
1890 | |||
1891 | /** | ||
1870 | * regulator_count_voltages - count regulator_list_voltage() selectors | 1892 | * regulator_count_voltages - count regulator_list_voltage() selectors |
1871 | * @regulator: regulator source | 1893 | * @regulator: regulator source |
1872 | * | 1894 | * |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 782c228a19bd..416fe0a37f56 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
@@ -290,7 +290,7 @@ static int wm831x_buckv_set_voltage_sel(struct regulator_dev *rdev, | |||
290 | if (vsel > dcdc->dvs_vsel) { | 290 | if (vsel > dcdc->dvs_vsel) { |
291 | ret = wm831x_set_bits(wm831x, dvs_reg, | 291 | ret = wm831x_set_bits(wm831x, dvs_reg, |
292 | WM831X_DC1_DVS_VSEL_MASK, | 292 | WM831X_DC1_DVS_VSEL_MASK, |
293 | dcdc->dvs_vsel); | 293 | vsel); |
294 | if (ret == 0) | 294 | if (ret == 0) |
295 | dcdc->dvs_vsel = vsel; | 295 | dcdc->dvs_vsel = vsel; |
296 | else | 296 | else |
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index 7671a287dfee..ba26e99c388d 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h | |||
@@ -76,6 +76,7 @@ | |||
76 | #define ARIZONA_RATE_ESTIMATOR_3 0x154 | 76 | #define ARIZONA_RATE_ESTIMATOR_3 0x154 |
77 | #define ARIZONA_RATE_ESTIMATOR_4 0x155 | 77 | #define ARIZONA_RATE_ESTIMATOR_4 0x155 |
78 | #define ARIZONA_RATE_ESTIMATOR_5 0x156 | 78 | #define ARIZONA_RATE_ESTIMATOR_5 0x156 |
79 | #define ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 0x161 | ||
79 | #define ARIZONA_FLL1_CONTROL_1 0x171 | 80 | #define ARIZONA_FLL1_CONTROL_1 0x171 |
80 | #define ARIZONA_FLL1_CONTROL_2 0x172 | 81 | #define ARIZONA_FLL1_CONTROL_2 0x172 |
81 | #define ARIZONA_FLL1_CONTROL_3 0x173 | 82 | #define ARIZONA_FLL1_CONTROL_3 0x173 |
@@ -110,6 +111,7 @@ | |||
110 | #define ARIZONA_FLL2_GPIO_CLOCK 0x1AA | 111 | #define ARIZONA_FLL2_GPIO_CLOCK 0x1AA |
111 | #define ARIZONA_MIC_CHARGE_PUMP_1 0x200 | 112 | #define ARIZONA_MIC_CHARGE_PUMP_1 0x200 |
112 | #define ARIZONA_LDO1_CONTROL_1 0x210 | 113 | #define ARIZONA_LDO1_CONTROL_1 0x210 |
114 | #define ARIZONA_LDO1_CONTROL_2 0x212 | ||
113 | #define ARIZONA_LDO2_CONTROL_1 0x213 | 115 | #define ARIZONA_LDO2_CONTROL_1 0x213 |
114 | #define ARIZONA_MIC_BIAS_CTRL_1 0x218 | 116 | #define ARIZONA_MIC_BIAS_CTRL_1 0x218 |
115 | #define ARIZONA_MIC_BIAS_CTRL_2 0x219 | 117 | #define ARIZONA_MIC_BIAS_CTRL_2 0x219 |
@@ -1574,6 +1576,13 @@ | |||
1574 | #define ARIZONA_SAMPLE_RATE_DETECT_D_WIDTH 5 /* SAMPLE_RATE_DETECT_D - [4:0] */ | 1576 | #define ARIZONA_SAMPLE_RATE_DETECT_D_WIDTH 5 /* SAMPLE_RATE_DETECT_D - [4:0] */ |
1575 | 1577 | ||
1576 | /* | 1578 | /* |
1579 | * R353 (0x161) - Dynamic Frequency Scaling 1 | ||
1580 | */ | ||
1581 | #define ARIZONA_SUBSYS_MAX_FREQ 0x0001 /* SUBSYS_MAX_FREQ */ | ||
1582 | #define ARIZONA_SUBSYS_MAX_FREQ_SHIFT 0 /* SUBSYS_MAX_FREQ */ | ||
1583 | #define ARIZONA_SUBSYS_MAX_FREQ_WIDTH 1 /* SUBSYS_MAX_FREQ */ | ||
1584 | |||
1585 | /* | ||
1577 | * R369 (0x171) - FLL1 Control 1 | 1586 | * R369 (0x171) - FLL1 Control 1 |
1578 | */ | 1587 | */ |
1579 | #define ARIZONA_FLL1_FREERUN 0x0002 /* FLL1_FREERUN */ | 1588 | #define ARIZONA_FLL1_FREERUN 0x0002 /* FLL1_FREERUN */ |
@@ -1889,6 +1898,13 @@ | |||
1889 | #define ARIZONA_LDO1_ENA_WIDTH 1 /* LDO1_ENA */ | 1898 | #define ARIZONA_LDO1_ENA_WIDTH 1 /* LDO1_ENA */ |
1890 | 1899 | ||
1891 | /* | 1900 | /* |
1901 | * R530 (0x212) - LDO1 Control 2 | ||
1902 | */ | ||
1903 | #define ARIZONA_LDO1_HI_PWR 0x0001 /* LDO1_HI_PWR */ | ||
1904 | #define ARIZONA_LDO1_HI_PWR_SHIFT 0 /* LDO1_HI_PWR */ | ||
1905 | #define ARIZONA_LDO1_HI_PWR_WIDTH 1 /* LDO1_HI_PWR */ | ||
1906 | |||
1907 | /* | ||
1892 | * R531 (0x213) - LDO2 Control 1 | 1908 | * R531 (0x213) - LDO2 Control 1 |
1893 | */ | 1909 | */ |
1894 | #define ARIZONA_LDO2_VSEL_MASK 0x07E0 /* LDO2_VSEL - [10:5] */ | 1910 | #define ARIZONA_LDO2_VSEL_MASK 0x07E0 /* LDO2_VSEL - [10:5] */ |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index c43cd3556b1f..5d0f7c10bef1 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
@@ -160,6 +160,7 @@ int regulator_bulk_force_disable(int num_consumers, | |||
160 | void regulator_bulk_free(int num_consumers, | 160 | void regulator_bulk_free(int num_consumers, |
161 | struct regulator_bulk_data *consumers); | 161 | struct regulator_bulk_data *consumers); |
162 | 162 | ||
163 | int regulator_can_change_voltage(struct regulator *regulator); | ||
163 | int regulator_count_voltages(struct regulator *regulator); | 164 | int regulator_count_voltages(struct regulator *regulator); |
164 | int regulator_list_voltage(struct regulator *regulator, unsigned selector); | 165 | int regulator_list_voltage(struct regulator *regulator, unsigned selector); |
165 | int regulator_is_supported_voltage(struct regulator *regulator, | 166 | int regulator_is_supported_voltage(struct regulator *regulator, |