aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 14:49:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 14:49:41 -0400
commit99765cc7e393c8637abaaf0c73f28ec63370d35c (patch)
treec386ff98390afe9a5f2626dbd3c49b7371a020eb
parent51e618c357b39597b474165c5d17067afe8f16a6 (diff)
parent500b4ac90d1103a7c302d5bb16c53f4ffc45d057 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: regulator: return set_mode is same mode is requested Regulators: ab3100/bq24022: add a missing .owner field in regulator_desc twl6030: regulator: Remove vsel tables and use formula for calculation mc13783-regulator: fix vaild voltage range checking for mc13783_fixed_regulator_set_voltage regulator: use voltage number array in 88pm860x regulator: make 88pm860x sharing one driver structure regulator: simplify regulator_register() error handling regulator: fix unset_regulator_supplies() to remove all matches regulator: prevent registration of matching regulator consumer supplies regulator: Allow regulator-regulator supplies to be specified by name
-rw-r--r--drivers/mfd/88pm860x-core.c36
-rw-r--r--drivers/regulator/88pm8607.c533
-rw-r--r--drivers/regulator/ab3100.c10
-rw-r--r--drivers/regulator/bq24022.c1
-rw-r--r--drivers/regulator/core.c83
-rw-r--r--drivers/regulator/mc13783-regulator.c6
-rw-r--r--drivers/regulator/twl-regulator.c138
-rw-r--r--include/linux/mfd/88pm860x.h3
-rw-r--r--include/linux/regulator/machine.h9
9 files changed, 414 insertions, 405 deletions
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 6a14d2b1ccf0..405d2d5183cf 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -173,33 +173,35 @@ static struct resource regulator_resources[] = {
173 PM8607_REG_RESOURCE(LDO9, LDO9), 173 PM8607_REG_RESOURCE(LDO9, LDO9),
174 PM8607_REG_RESOURCE(LDO10, LDO10), 174 PM8607_REG_RESOURCE(LDO10, LDO10),
175 PM8607_REG_RESOURCE(LDO12, LDO12), 175 PM8607_REG_RESOURCE(LDO12, LDO12),
176 PM8607_REG_RESOURCE(VIBRATOR_SET, VIBRATOR_SET),
176 PM8607_REG_RESOURCE(LDO14, LDO14), 177 PM8607_REG_RESOURCE(LDO14, LDO14),
177}; 178};
178 179
179#define PM8607_REG_DEVS(_name, _id) \ 180#define PM8607_REG_DEVS(_id) \
180{ \ 181{ \
181 .name = "88pm8607-" #_name, \ 182 .name = "88pm860x-regulator", \
182 .num_resources = 1, \ 183 .num_resources = 1, \
183 .resources = &regulator_resources[PM8607_ID_##_id], \ 184 .resources = &regulator_resources[PM8607_ID_##_id], \
184 .id = PM8607_ID_##_id, \ 185 .id = PM8607_ID_##_id, \
185} 186}
186 187
187static struct mfd_cell regulator_devs[] = { 188static struct mfd_cell regulator_devs[] = {
188 PM8607_REG_DEVS(buck1, BUCK1), 189 PM8607_REG_DEVS(BUCK1),
189 PM8607_REG_DEVS(buck2, BUCK2), 190 PM8607_REG_DEVS(BUCK2),
190 PM8607_REG_DEVS(buck3, BUCK3), 191 PM8607_REG_DEVS(BUCK3),
191 PM8607_REG_DEVS(ldo1, LDO1), 192 PM8607_REG_DEVS(LDO1),
192 PM8607_REG_DEVS(ldo2, LDO2), 193 PM8607_REG_DEVS(LDO2),
193 PM8607_REG_DEVS(ldo3, LDO3), 194 PM8607_REG_DEVS(LDO3),
194 PM8607_REG_DEVS(ldo4, LDO4), 195 PM8607_REG_DEVS(LDO4),
195 PM8607_REG_DEVS(ldo5, LDO5), 196 PM8607_REG_DEVS(LDO5),
196 PM8607_REG_DEVS(ldo6, LDO6), 197 PM8607_REG_DEVS(LDO6),
197 PM8607_REG_DEVS(ldo7, LDO7), 198 PM8607_REG_DEVS(LDO7),
198 PM8607_REG_DEVS(ldo8, LDO8), 199 PM8607_REG_DEVS(LDO8),
199 PM8607_REG_DEVS(ldo9, LDO9), 200 PM8607_REG_DEVS(LDO9),
200 PM8607_REG_DEVS(ldo10, LDO10), 201 PM8607_REG_DEVS(LDO10),
201 PM8607_REG_DEVS(ldo12, LDO12), 202 PM8607_REG_DEVS(LDO12),
202 PM8607_REG_DEVS(ldo14, LDO14), 203 PM8607_REG_DEVS(LDO13),
204 PM8607_REG_DEVS(LDO14),
203}; 205};
204 206
205struct pm860x_irq_data { 207struct pm860x_irq_data {
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 5fb83e2ced25..7d149a8d8d9b 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -23,9 +23,9 @@ struct pm8607_regulator_info {
23 struct regulator_dev *regulator; 23 struct regulator_dev *regulator;
24 struct i2c_client *i2c; 24 struct i2c_client *i2c;
25 25
26 int min_uV; 26 unsigned int *vol_table;
27 int max_uV; 27 unsigned int *vol_suspend;
28 int step_uV; 28
29 int vol_reg; 29 int vol_reg;
30 int vol_shift; 30 int vol_shift;
31 int vol_nbits; 31 int vol_nbits;
@@ -36,83 +36,189 @@ struct pm8607_regulator_info {
36 int slope_double; 36 int slope_double;
37}; 37};
38 38
39static inline int check_range(struct pm8607_regulator_info *info, 39static const unsigned int BUCK1_table[] = {
40 int min_uV, int max_uV) 40 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000,
41{ 41 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000,
42 if (max_uV < info->min_uV || min_uV > info->max_uV || min_uV > max_uV) 42 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
43 return -EINVAL; 43 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
44 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
45 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
46 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
47 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
48};
44 49
45 return 0; 50static const unsigned int BUCK1_suspend_table[] = {
46} 51 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
52 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
53 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
54 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
55 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
56 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
57 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
58 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
59};
60
61static const unsigned int BUCK2_table[] = {
62 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000,
63 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000,
64 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
65 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
66 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
67 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
68 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
69 2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000,
70};
71
72static const unsigned int BUCK2_suspend_table[] = {
73 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000,
74 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000,
75 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
76 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
77 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
78 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
79 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
80 2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000,
81};
82
83static const unsigned int BUCK3_table[] = {
84 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
85 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
86 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
87 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
88 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
89 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
90 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
91 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
92};
93
94static const unsigned int BUCK3_suspend_table[] = {
95 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
96 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
97 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
98 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
99 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
100 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
101 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
102 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
103};
104
105static const unsigned int LDO1_table[] = {
106 1800000, 1200000, 2800000, 0,
107};
108
109static const unsigned int LDO1_suspend_table[] = {
110 1800000, 1200000, 0, 0,
111};
112
113static const unsigned int LDO2_table[] = {
114 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
115};
116
117static const unsigned int LDO2_suspend_table[] = {
118 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
119};
120
121static const unsigned int LDO3_table[] = {
122 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
123};
124
125static const unsigned int LDO3_suspend_table[] = {
126 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
127};
128
129static const unsigned int LDO4_table[] = {
130 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 3300000,
131};
132
133static const unsigned int LDO4_suspend_table[] = {
134 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 2900000,
135};
136
137static const unsigned int LDO5_table[] = {
138 2900000, 3000000, 3100000, 3300000,
139};
140
141static const unsigned int LDO5_suspend_table[] = {
142 2900000, 0, 0, 0,
143};
144
145static const unsigned int LDO6_table[] = {
146 1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 3300000,
147};
148
149static const unsigned int LDO6_suspend_table[] = {
150 1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 2900000,
151};
152
153static const unsigned int LDO7_table[] = {
154 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
155};
156
157static const unsigned int LDO7_suspend_table[] = {
158 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
159};
160
161static const unsigned int LDO8_table[] = {
162 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
163};
164
165static const unsigned int LDO8_suspend_table[] = {
166 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
167};
168
169static const unsigned int LDO9_table[] = {
170 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
171};
172
173static const unsigned int LDO9_suspend_table[] = {
174 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
175};
176
177static const unsigned int LDO10_table[] = {
178 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
179 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
180};
181
182static const unsigned int LDO10_suspend_table[] = {
183 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
184 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
185};
186
187static const unsigned int LDO12_table[] = {
188 1800000, 1900000, 2700000, 2800000, 2900000, 3000000, 3100000, 3300000,
189 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
190};
191
192static const unsigned int LDO12_suspend_table[] = {
193 1800000, 1900000, 2700000, 2800000, 2900000, 2900000, 2900000, 2900000,
194 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
195};
196
197static const unsigned int LDO13_table[] = {
198 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, 0,
199};
200
201static const unsigned int LDO13_suspend_table[] = {
202 0,
203};
204
205static const unsigned int LDO14_table[] = {
206 1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 3300000,
207};
208
209static const unsigned int LDO14_suspend_table[] = {
210 1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 2900000,
211};
47 212
48static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) 213static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
49{ 214{
50 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 215 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
51 int ret = -EINVAL; 216 int ret = -EINVAL;
52 217
53 switch (info->desc.id) { 218 if (info->vol_table && (index < (2 << info->vol_nbits))) {
54 case PM8607_ID_BUCK1: 219 ret = info->vol_table[index];
55 ret = (index < 0x1d) ? (index * 25000 + 800000) :
56 ((index < 0x20) ? 1500000 :
57 ((index < 0x40) ? ((index - 0x20) * 25000) :
58 -EINVAL));
59 break;
60 case PM8607_ID_BUCK3:
61 ret = (index < 0x3d) ? (index * 25000) :
62 ((index < 0x40) ? 1500000 : -EINVAL);
63 if (ret < 0)
64 break;
65 if (info->slope_double) 220 if (info->slope_double)
66 ret <<= 1; 221 ret <<= 1;
67 break;
68 case PM8607_ID_LDO1:
69 ret = (index == 0) ? 1800000 :
70 ((index == 1) ? 1200000 :
71 ((index == 2) ? 2800000 : -EINVAL));
72 break;
73 case PM8607_ID_LDO5:
74 ret = (index == 0) ? 2900000 :
75 ((index == 1) ? 3000000 :
76 ((index == 2) ? 3100000 : 3300000));
77 break;
78 case PM8607_ID_LDO7:
79 case PM8607_ID_LDO8:
80 ret = (index < 3) ? (index * 50000 + 1800000) :
81 ((index < 8) ? (index * 50000 + 2550000) :
82 -EINVAL);
83 break;
84 case PM8607_ID_LDO12:
85 ret = (index < 2) ? (index * 100000 + 1800000) :
86 ((index < 7) ? (index * 100000 + 2500000) :
87 ((index == 7) ? 3300000 : 1200000));
88 break;
89 case PM8607_ID_LDO2:
90 case PM8607_ID_LDO3:
91 case PM8607_ID_LDO9:
92 ret = (index < 3) ? (index * 50000 + 1800000) :
93 ((index < 7) ? (index * 50000 + 2550000) :
94 3300000);
95 break;
96 case PM8607_ID_LDO4:
97 ret = (index < 3) ? (index * 50000 + 1800000) :
98 ((index < 6) ? (index * 50000 + 2550000) :
99 ((index == 6) ? 2900000 : 3300000));
100 break;
101 case PM8607_ID_LDO6:
102 ret = (index < 2) ? (index * 50000 + 1800000) :
103 ((index < 7) ? (index * 50000 + 2500000) :
104 3300000);
105 break;
106 case PM8607_ID_LDO10:
107 ret = (index < 3) ? (index * 50000 + 1800000) :
108 ((index < 7) ? (index * 50000 + 2550000) :
109 ((index == 7) ? 3300000 : 1200000));
110 break;
111 case PM8607_ID_LDO14:
112 ret = (index < 2) ? (index * 50000 + 1800000) :
113 ((index < 7) ? (index * 50000 + 2600000) :
114 3300000);
115 break;
116 } 222 }
117 return ret; 223 return ret;
118} 224}
@@ -120,174 +226,26 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
120static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 226static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
121{ 227{
122 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 228 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
123 int val = -ENOENT; 229 int i, ret = -ENOENT;
124 int ret;
125 230
126 switch (info->desc.id) { 231 if (info->slope_double) {
127 case PM8607_ID_BUCK1: 232 min_uV = min_uV >> 1;
128 if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */ 233 max_uV = max_uV >> 1;
129 val = (min_uV - 775001) / 25000;
130 else { /* 25mV ~ 775mV / 25mV */
131 val = (min_uV + 249999) / 25000;
132 val += 32;
133 }
134 break;
135 case PM8607_ID_BUCK3:
136 if (info->slope_double)
137 min_uV = min_uV >> 1;
138 val = (min_uV + 249999) / 25000; /* 0mV ~ 1500mV / 25mV */
139
140 break;
141 case PM8607_ID_LDO1:
142 if (min_uV > 1800000)
143 val = 2;
144 else if (min_uV > 1200000)
145 val = 0;
146 else
147 val = 1;
148 break;
149 case PM8607_ID_LDO5:
150 if (min_uV > 3100000)
151 val = 3;
152 else /* 2900mV ~ 3100mV / 100mV */
153 val = (min_uV - 2800001) / 100000;
154 break;
155 case PM8607_ID_LDO7:
156 case PM8607_ID_LDO8:
157 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
158 if (min_uV <= 1800000)
159 val = 0; /* 1800mv */
160 else if (min_uV <= 1900000)
161 val = (min_uV - 1750001) / 50000;
162 else
163 val = 3; /* 2700mV */
164 } else { /* 2700mV ~ 2900mV / 50mV */
165 if (min_uV <= 2900000) {
166 val = (min_uV - 2650001) / 50000;
167 val += 3;
168 } else
169 val = -EINVAL;
170 }
171 break;
172 case PM8607_ID_LDO10:
173 if (min_uV > 2850000)
174 val = 7;
175 else if (min_uV <= 1200000)
176 val = 8;
177 else if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */
178 val = (min_uV - 1750001) / 50000;
179 else { /* 2700mV ~ 2850mV / 50mV */
180 val = (min_uV - 2650001) / 50000;
181 val += 3;
182 }
183 break;
184 case PM8607_ID_LDO12:
185 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 100mV */
186 if (min_uV <= 1200000)
187 val = 8; /* 1200mV */
188 else if (min_uV <= 1800000)
189 val = 0; /* 1800mV */
190 else if (min_uV <= 1900000)
191 val = (min_uV - 1700001) / 100000;
192 else
193 val = 2; /* 2700mV */
194 } else { /* 2700mV ~ 3100mV / 100mV */
195 if (min_uV <= 3100000) {
196 val = (min_uV - 2600001) / 100000;
197 val += 2;
198 } else if (min_uV <= 3300000)
199 val = 7;
200 else
201 val = -EINVAL;
202 }
203 break;
204 case PM8607_ID_LDO2:
205 case PM8607_ID_LDO3:
206 case PM8607_ID_LDO9:
207 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
208 if (min_uV <= 1800000)
209 val = 0;
210 else if (min_uV <= 1900000)
211 val = (min_uV - 1750001) / 50000;
212 else
213 val = 3; /* 2700mV */
214 } else { /* 2700mV ~ 2850mV / 50mV */
215 if (min_uV <= 2850000) {
216 val = (min_uV - 2650001) / 50000;
217 val += 3;
218 } else if (min_uV <= 3300000)
219 val = 7;
220 else
221 val = -EINVAL;
222 }
223 break;
224 case PM8607_ID_LDO4:
225 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
226 if (min_uV <= 1800000)
227 val = 0;
228 else if (min_uV <= 1900000)
229 val = (min_uV - 1750001) / 50000;
230 else
231 val = 3; /* 2700mV */
232 } else { /* 2700mV ~ 2800mV / 50mV */
233 if (min_uV <= 2850000) {
234 val = (min_uV - 2650001) / 50000;
235 val += 3;
236 } else if (min_uV <= 2900000)
237 val = 6;
238 else if (min_uV <= 3300000)
239 val = 7;
240 else
241 val = -EINVAL;
242 }
243 break;
244 case PM8607_ID_LDO6:
245 if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
246 if (min_uV <= 1800000)
247 val = 0;
248 else if (min_uV <= 1850000)
249 val = (min_uV - 1750001) / 50000;
250 else
251 val = 2; /* 2600mV */
252 } else { /* 2600mV ~ 2800mV / 50mV */
253 if (min_uV <= 2800000) {
254 val = (min_uV - 2550001) / 50000;
255 val += 2;
256 } else if (min_uV <= 3300000)
257 val = 7;
258 else
259 val = -EINVAL;
260 }
261 break;
262 case PM8607_ID_LDO14:
263 if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
264 if (min_uV <= 1800000)
265 val = 0;
266 else if (min_uV <= 1850000)
267 val = (min_uV - 1750001) / 50000;
268 else
269 val = 2; /* 2700mV */
270 } else { /* 2700mV ~ 2900mV / 50mV */
271 if (min_uV <= 2900000) {
272 val = (min_uV - 2650001) / 50000;
273 val += 2;
274 } else if (min_uV <= 3300000)
275 val = 7;
276 else
277 val = -EINVAL;
278 }
279 break;
280 } 234 }
281 if (val >= 0) { 235 if (info->vol_table) {
282 ret = pm8607_list_voltage(rdev, val); 236 for (i = 0; i < (2 << info->vol_nbits); i++) {
283 if (ret > max_uV) { 237 if (!info->vol_table[i])
284 pr_err("exceed voltage range (%d %d) uV", 238 break;
285 min_uV, max_uV); 239 if ((min_uV <= info->vol_table[i])
286 return -EINVAL; 240 && (max_uV >= info->vol_table[i])) {
241 ret = i;
242 break;
243 }
287 } 244 }
288 } else 245 }
289 pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV); 246 if (ret < 0)
290 return val; 247 pr_err("invalid voltage range (%d %d) uV\n", min_uV, max_uV);
248 return ret;
291} 249}
292 250
293static int pm8607_set_voltage(struct regulator_dev *rdev, 251static int pm8607_set_voltage(struct regulator_dev *rdev,
@@ -297,7 +255,7 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
297 uint8_t val, mask; 255 uint8_t val, mask;
298 int ret; 256 int ret;
299 257
300 if (check_range(info, min_uV, max_uV)) { 258 if (min_uV > max_uV) {
301 pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); 259 pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
302 return -EINVAL; 260 return -EINVAL;
303 } 261 }
@@ -375,18 +333,15 @@ static struct regulator_ops pm8607_regulator_ops = {
375 .is_enabled = pm8607_is_enabled, 333 .is_enabled = pm8607_is_enabled,
376}; 334};
377 335
378#define PM8607_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ 336#define PM8607_DVC(vreg, nbits, ureg, ubit, ereg, ebit) \
379{ \ 337{ \
380 .desc = { \ 338 .desc = { \
381 .name = "BUCK" #_id, \ 339 .name = #vreg, \
382 .ops = &pm8607_regulator_ops, \ 340 .ops = &pm8607_regulator_ops, \
383 .type = REGULATOR_VOLTAGE, \ 341 .type = REGULATOR_VOLTAGE, \
384 .id = PM8607_ID_BUCK##_id, \ 342 .id = PM8607_ID_##vreg, \
385 .owner = THIS_MODULE, \ 343 .owner = THIS_MODULE, \
386 }, \ 344 }, \
387 .min_uV = (min) * 1000, \
388 .max_uV = (max) * 1000, \
389 .step_uV = (step) * 1000, \
390 .vol_reg = PM8607_##vreg, \ 345 .vol_reg = PM8607_##vreg, \
391 .vol_shift = (0), \ 346 .vol_shift = (0), \
392 .vol_nbits = (nbits), \ 347 .vol_nbits = (nbits), \
@@ -395,9 +350,11 @@ static struct regulator_ops pm8607_regulator_ops = {
395 .enable_reg = PM8607_##ereg, \ 350 .enable_reg = PM8607_##ereg, \
396 .enable_bit = (ebit), \ 351 .enable_bit = (ebit), \
397 .slope_double = (0), \ 352 .slope_double = (0), \
353 .vol_table = (unsigned int *)&vreg##_table, \
354 .vol_suspend = (unsigned int *)&vreg##_suspend_table, \
398} 355}
399 356
400#define PM8607_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ 357#define PM8607_LDO(_id, vreg, shift, nbits, ereg, ebit) \
401{ \ 358{ \
402 .desc = { \ 359 .desc = { \
403 .name = "LDO" #_id, \ 360 .name = "LDO" #_id, \
@@ -406,33 +363,34 @@ static struct regulator_ops pm8607_regulator_ops = {
406 .id = PM8607_ID_LDO##_id, \ 363 .id = PM8607_ID_LDO##_id, \
407 .owner = THIS_MODULE, \ 364 .owner = THIS_MODULE, \
408 }, \ 365 }, \
409 .min_uV = (min) * 1000, \
410 .max_uV = (max) * 1000, \
411 .step_uV = (step) * 1000, \
412 .vol_reg = PM8607_##vreg, \ 366 .vol_reg = PM8607_##vreg, \
413 .vol_shift = (shift), \ 367 .vol_shift = (shift), \
414 .vol_nbits = (nbits), \ 368 .vol_nbits = (nbits), \
415 .enable_reg = PM8607_##ereg, \ 369 .enable_reg = PM8607_##ereg, \
416 .enable_bit = (ebit), \ 370 .enable_bit = (ebit), \
417 .slope_double = (0), \ 371 .slope_double = (0), \
372 .vol_table = (unsigned int *)&LDO##_id##_table, \
373 .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \
418} 374}
419 375
420static struct pm8607_regulator_info pm8607_regulator_info[] = { 376static struct pm8607_regulator_info pm8607_regulator_info[] = {
421 PM8607_DVC(1, 0, 1500, 25, BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), 377 PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0),
422 PM8607_DVC(3, 0, 1500, 25, BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), 378 PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1),
423 379 PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2),
424 PM8607_LDO(1 , 1200, 2800, 0, LDO1 , 0, 2, SUPPLIES_EN11, 3), 380
425 PM8607_LDO(2 , 1800, 3300, 0, LDO2 , 0, 3, SUPPLIES_EN11, 4), 381 PM8607_LDO( 1, LDO1, 0, 2, SUPPLIES_EN11, 3),
426 PM8607_LDO(3 , 1800, 3300, 0, LDO3 , 0, 3, SUPPLIES_EN11, 5), 382 PM8607_LDO( 2, LDO2, 0, 3, SUPPLIES_EN11, 4),
427 PM8607_LDO(4 , 1800, 3300, 0, LDO4 , 0, 3, SUPPLIES_EN11, 6), 383 PM8607_LDO( 3, LDO3, 0, 3, SUPPLIES_EN11, 5),
428 PM8607_LDO(5 , 2900, 3300, 0, LDO5 , 0, 2, SUPPLIES_EN11, 7), 384 PM8607_LDO( 4, LDO4, 0, 3, SUPPLIES_EN11, 6),
429 PM8607_LDO(6 , 1800, 3300, 0, LDO6 , 0, 3, SUPPLIES_EN12, 0), 385 PM8607_LDO( 5, LDO5, 0, 2, SUPPLIES_EN11, 7),
430 PM8607_LDO(7 , 1800, 2900, 0, LDO7 , 0, 3, SUPPLIES_EN12, 1), 386 PM8607_LDO( 6, LDO6, 0, 3, SUPPLIES_EN12, 0),
431 PM8607_LDO(8 , 1800, 2900, 0, LDO8 , 0, 3, SUPPLIES_EN12, 2), 387 PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1),
432 PM8607_LDO(9 , 1800, 3300, 0, LDO9 , 0, 3, SUPPLIES_EN12, 3), 388 PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2),
433 PM8607_LDO(10, 1200, 3300, 0, LDO10, 0, 4, SUPPLIES_EN11, 4), 389 PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3),
434 PM8607_LDO(12, 1200, 3300, 0, LDO12, 0, 4, SUPPLIES_EN11, 5), 390 PM8607_LDO(10, LDO10, 0, 3, SUPPLIES_EN12, 4),
435 PM8607_LDO(14, 1800, 3300, 0, LDO14, 0, 3, SUPPLIES_EN11, 6), 391 PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5),
392 PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0),
393 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6),
436}; 394};
437 395
438static inline struct pm8607_regulator_info *find_regulator_info(int id) 396static inline struct pm8607_regulator_info *find_regulator_info(int id)
@@ -484,60 +442,29 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
484{ 442{
485 struct pm8607_regulator_info *info = platform_get_drvdata(pdev); 443 struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
486 444
445 platform_set_drvdata(pdev, NULL);
487 regulator_unregister(info->regulator); 446 regulator_unregister(info->regulator);
488 return 0; 447 return 0;
489} 448}
490 449
491#define PM8607_REGULATOR_DRIVER(_name) \ 450static struct platform_driver pm8607_regulator_driver = {
492{ \ 451 .driver = {
493 .driver = { \ 452 .name = "88pm860x-regulator",
494 .name = "88pm8607-" #_name, \ 453 .owner = THIS_MODULE,
495 .owner = THIS_MODULE, \ 454 },
496 }, \ 455 .probe = pm8607_regulator_probe,
497 .probe = pm8607_regulator_probe, \ 456 .remove = __devexit_p(pm8607_regulator_remove),
498 .remove = __devexit_p(pm8607_regulator_remove), \
499}
500
501static struct platform_driver pm8607_regulator_driver[] = {
502 PM8607_REGULATOR_DRIVER(buck1),
503 PM8607_REGULATOR_DRIVER(buck2),
504 PM8607_REGULATOR_DRIVER(buck3),
505 PM8607_REGULATOR_DRIVER(ldo1),
506 PM8607_REGULATOR_DRIVER(ldo2),
507 PM8607_REGULATOR_DRIVER(ldo3),
508 PM8607_REGULATOR_DRIVER(ldo4),
509 PM8607_REGULATOR_DRIVER(ldo5),
510 PM8607_REGULATOR_DRIVER(ldo6),
511 PM8607_REGULATOR_DRIVER(ldo7),
512 PM8607_REGULATOR_DRIVER(ldo8),
513 PM8607_REGULATOR_DRIVER(ldo9),
514 PM8607_REGULATOR_DRIVER(ldo10),
515 PM8607_REGULATOR_DRIVER(ldo12),
516 PM8607_REGULATOR_DRIVER(ldo14),
517}; 457};
518 458
519static int __init pm8607_regulator_init(void) 459static int __init pm8607_regulator_init(void)
520{ 460{
521 int i, count, ret; 461 return platform_driver_register(&pm8607_regulator_driver);
522
523 count = ARRAY_SIZE(pm8607_regulator_driver);
524 for (i = 0; i < count; i++) {
525 ret = platform_driver_register(&pm8607_regulator_driver[i]);
526 if (ret != 0)
527 pr_err("Failed to register regulator driver: %d\n",
528 ret);
529 }
530 return 0;
531} 462}
532subsys_initcall(pm8607_regulator_init); 463subsys_initcall(pm8607_regulator_init);
533 464
534static void __exit pm8607_regulator_exit(void) 465static void __exit pm8607_regulator_exit(void)
535{ 466{
536 int i, count; 467 platform_driver_unregister(&pm8607_regulator_driver);
537
538 count = ARRAY_SIZE(pm8607_regulator_driver);
539 for (i = 0; i < count; i++)
540 platform_driver_unregister(&pm8607_regulator_driver[i]);
541} 468}
542module_exit(pm8607_regulator_exit); 469module_exit(pm8607_regulator_exit);
543 470
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 7de950959ed2..1afd008ca957 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -492,18 +492,21 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
492 .id = AB3100_LDO_A, 492 .id = AB3100_LDO_A,
493 .ops = &regulator_ops_fixed, 493 .ops = &regulator_ops_fixed,
494 .type = REGULATOR_VOLTAGE, 494 .type = REGULATOR_VOLTAGE,
495 .owner = THIS_MODULE,
495 }, 496 },
496 { 497 {
497 .name = "LDO_C", 498 .name = "LDO_C",
498 .id = AB3100_LDO_C, 499 .id = AB3100_LDO_C,
499 .ops = &regulator_ops_fixed, 500 .ops = &regulator_ops_fixed,
500 .type = REGULATOR_VOLTAGE, 501 .type = REGULATOR_VOLTAGE,
502 .owner = THIS_MODULE,
501 }, 503 },
502 { 504 {
503 .name = "LDO_D", 505 .name = "LDO_D",
504 .id = AB3100_LDO_D, 506 .id = AB3100_LDO_D,
505 .ops = &regulator_ops_fixed, 507 .ops = &regulator_ops_fixed,
506 .type = REGULATOR_VOLTAGE, 508 .type = REGULATOR_VOLTAGE,
509 .owner = THIS_MODULE,
507 }, 510 },
508 { 511 {
509 .name = "LDO_E", 512 .name = "LDO_E",
@@ -511,6 +514,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
511 .ops = &regulator_ops_variable_sleepable, 514 .ops = &regulator_ops_variable_sleepable,
512 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), 515 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
513 .type = REGULATOR_VOLTAGE, 516 .type = REGULATOR_VOLTAGE,
517 .owner = THIS_MODULE,
514 }, 518 },
515 { 519 {
516 .name = "LDO_F", 520 .name = "LDO_F",
@@ -518,6 +522,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
518 .ops = &regulator_ops_variable, 522 .ops = &regulator_ops_variable,
519 .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), 523 .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages),
520 .type = REGULATOR_VOLTAGE, 524 .type = REGULATOR_VOLTAGE,
525 .owner = THIS_MODULE,
521 }, 526 },
522 { 527 {
523 .name = "LDO_G", 528 .name = "LDO_G",
@@ -525,6 +530,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
525 .ops = &regulator_ops_variable, 530 .ops = &regulator_ops_variable,
526 .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), 531 .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages),
527 .type = REGULATOR_VOLTAGE, 532 .type = REGULATOR_VOLTAGE,
533 .owner = THIS_MODULE,
528 }, 534 },
529 { 535 {
530 .name = "LDO_H", 536 .name = "LDO_H",
@@ -532,6 +538,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
532 .ops = &regulator_ops_variable, 538 .ops = &regulator_ops_variable,
533 .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), 539 .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages),
534 .type = REGULATOR_VOLTAGE, 540 .type = REGULATOR_VOLTAGE,
541 .owner = THIS_MODULE,
535 }, 542 },
536 { 543 {
537 .name = "LDO_K", 544 .name = "LDO_K",
@@ -539,12 +546,14 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
539 .ops = &regulator_ops_variable, 546 .ops = &regulator_ops_variable,
540 .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), 547 .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages),
541 .type = REGULATOR_VOLTAGE, 548 .type = REGULATOR_VOLTAGE,
549 .owner = THIS_MODULE,
542 }, 550 },
543 { 551 {
544 .name = "LDO_EXT", 552 .name = "LDO_EXT",
545 .id = AB3100_LDO_EXT, 553 .id = AB3100_LDO_EXT,
546 .ops = &regulator_ops_external, 554 .ops = &regulator_ops_external,
547 .type = REGULATOR_VOLTAGE, 555 .type = REGULATOR_VOLTAGE,
556 .owner = THIS_MODULE,
548 }, 557 },
549 { 558 {
550 .name = "BUCK", 559 .name = "BUCK",
@@ -552,6 +561,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
552 .ops = &regulator_ops_variable_sleepable, 561 .ops = &regulator_ops_variable_sleepable,
553 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), 562 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
554 .type = REGULATOR_VOLTAGE, 563 .type = REGULATOR_VOLTAGE,
564 .owner = THIS_MODULE,
555 }, 565 },
556}; 566};
557 567
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index d08cd9b66c6d..068d488a4f71 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -78,6 +78,7 @@ static struct regulator_desc bq24022_desc = {
78 .name = "bq24022", 78 .name = "bq24022",
79 .ops = &bq24022_ops, 79 .ops = &bq24022_ops,
80 .type = REGULATOR_CURRENT, 80 .type = REGULATOR_CURRENT,
81 .owner = THIS_MODULE,
81}; 82};
82 83
83static int __init bq24022_probe(struct platform_device *pdev) 84static int __init bq24022_probe(struct platform_device *pdev)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 51cf2bb37438..2248087b9be2 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -944,8 +944,13 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
944 has_dev = 0; 944 has_dev = 0;
945 945
946 list_for_each_entry(node, &regulator_map_list, list) { 946 list_for_each_entry(node, &regulator_map_list, list) {
947 if (consumer_dev_name != node->dev_name) 947 if (node->dev_name && consumer_dev_name) {
948 if (strcmp(node->dev_name, consumer_dev_name) != 0)
949 continue;
950 } else if (node->dev_name || consumer_dev_name) {
948 continue; 951 continue;
952 }
953
949 if (strcmp(node->supply, supply) != 0) 954 if (strcmp(node->supply, supply) != 0)
950 continue; 955 continue;
951 956
@@ -976,29 +981,6 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
976 return 0; 981 return 0;
977} 982}
978 983
979static void unset_consumer_device_supply(struct regulator_dev *rdev,
980 const char *consumer_dev_name, struct device *consumer_dev)
981{
982 struct regulator_map *node, *n;
983
984 if (consumer_dev && !consumer_dev_name)
985 consumer_dev_name = dev_name(consumer_dev);
986
987 list_for_each_entry_safe(node, n, &regulator_map_list, list) {
988 if (rdev != node->regulator)
989 continue;
990
991 if (consumer_dev_name && node->dev_name &&
992 strcmp(consumer_dev_name, node->dev_name))
993 continue;
994
995 list_del(&node->list);
996 kfree(node->dev_name);
997 kfree(node);
998 return;
999 }
1000}
1001
1002static void unset_regulator_supplies(struct regulator_dev *rdev) 984static void unset_regulator_supplies(struct regulator_dev *rdev)
1003{ 985{
1004 struct regulator_map *node, *n; 986 struct regulator_map *node, *n;
@@ -1008,7 +990,6 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
1008 list_del(&node->list); 990 list_del(&node->list);
1009 kfree(node->dev_name); 991 kfree(node->dev_name);
1010 kfree(node); 992 kfree(node);
1011 return;
1012 } 993 }
1013 } 994 }
1014} 995}
@@ -1764,6 +1745,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
1764{ 1745{
1765 struct regulator_dev *rdev = regulator->rdev; 1746 struct regulator_dev *rdev = regulator->rdev;
1766 int ret; 1747 int ret;
1748 int regulator_curr_mode;
1767 1749
1768 mutex_lock(&rdev->mutex); 1750 mutex_lock(&rdev->mutex);
1769 1751
@@ -1773,6 +1755,15 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
1773 goto out; 1755 goto out;
1774 } 1756 }
1775 1757
1758 /* return if the same mode is requested */
1759 if (rdev->desc->ops->get_mode) {
1760 regulator_curr_mode = rdev->desc->ops->get_mode(rdev);
1761 if (regulator_curr_mode == mode) {
1762 ret = 0;
1763 goto out;
1764 }
1765 }
1766
1776 /* constraints check */ 1767 /* constraints check */
1777 ret = regulator_check_mode(rdev, mode); 1768 ret = regulator_check_mode(rdev, mode);
1778 if (ret < 0) 1769 if (ret < 0)
@@ -2328,7 +2319,37 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2328 goto scrub; 2319 goto scrub;
2329 2320
2330 /* set supply regulator if it exists */ 2321 /* set supply regulator if it exists */
2322 if (init_data->supply_regulator && init_data->supply_regulator_dev) {
2323 dev_err(dev,
2324 "Supply regulator specified by both name and dev\n");
2325 goto scrub;
2326 }
2327
2328 if (init_data->supply_regulator) {
2329 struct regulator_dev *r;
2330 int found = 0;
2331
2332 list_for_each_entry(r, &regulator_list, list) {
2333 if (strcmp(rdev_get_name(r),
2334 init_data->supply_regulator) == 0) {
2335 found = 1;
2336 break;
2337 }
2338 }
2339
2340 if (!found) {
2341 dev_err(dev, "Failed to find supply %s\n",
2342 init_data->supply_regulator);
2343 goto scrub;
2344 }
2345
2346 ret = set_supply(rdev, r);
2347 if (ret < 0)
2348 goto scrub;
2349 }
2350
2331 if (init_data->supply_regulator_dev) { 2351 if (init_data->supply_regulator_dev) {
2352 dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n");
2332 ret = set_supply(rdev, 2353 ret = set_supply(rdev,
2333 dev_get_drvdata(init_data->supply_regulator_dev)); 2354 dev_get_drvdata(init_data->supply_regulator_dev));
2334 if (ret < 0) 2355 if (ret < 0)
@@ -2341,13 +2362,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2341 init_data->consumer_supplies[i].dev, 2362 init_data->consumer_supplies[i].dev,
2342 init_data->consumer_supplies[i].dev_name, 2363 init_data->consumer_supplies[i].dev_name,
2343 init_data->consumer_supplies[i].supply); 2364 init_data->consumer_supplies[i].supply);
2344 if (ret < 0) { 2365 if (ret < 0)
2345 for (--i; i >= 0; i--) 2366 goto unset_supplies;
2346 unset_consumer_device_supply(rdev,
2347 init_data->consumer_supplies[i].dev_name,
2348 init_data->consumer_supplies[i].dev);
2349 goto scrub;
2350 }
2351 } 2367 }
2352 2368
2353 list_add(&rdev->list, &regulator_list); 2369 list_add(&rdev->list, &regulator_list);
@@ -2355,6 +2371,9 @@ out:
2355 mutex_unlock(&regulator_list_mutex); 2371 mutex_unlock(&regulator_list_mutex);
2356 return rdev; 2372 return rdev;
2357 2373
2374unset_supplies:
2375 unset_regulator_supplies(rdev);
2376
2358scrub: 2377scrub:
2359 device_unregister(&rdev->dev); 2378 device_unregister(&rdev->dev);
2360 /* device core frees rdev */ 2379 /* device core frees rdev */
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index ad036dd8da13..4597d508a229 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -440,8 +440,8 @@ static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev,
440 dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", 440 dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
441 __func__, id, min_uV, max_uV); 441 __func__, id, min_uV, max_uV);
442 442
443 if (min_uV > mc13783_regulators[id].voltages[0] && 443 if (min_uV >= mc13783_regulators[id].voltages[0] &&
444 max_uV < mc13783_regulators[id].voltages[0]) 444 max_uV <= mc13783_regulators[id].voltages[0])
445 return 0; 445 return 0;
446 else 446 else
447 return -EINVAL; 447 return -EINVAL;
@@ -649,6 +649,6 @@ static void __exit mc13783_regulator_exit(void)
649module_exit(mc13783_regulator_exit); 649module_exit(mc13783_regulator_exit);
650 650
651MODULE_LICENSE("GPL v2"); 651MODULE_LICENSE("GPL v2");
652MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); 652MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
653MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC"); 653MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
654MODULE_ALIAS("platform:mc13783-regulator"); 654MODULE_ALIAS("platform:mc13783-regulator");
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 9729d760fb4d..7e5892efc437 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -49,6 +49,7 @@ struct twlreg_info {
49 49
50 /* chip constraints on regulator behavior */ 50 /* chip constraints on regulator behavior */
51 u16 min_mV; 51 u16 min_mV;
52 u16 max_mV;
52 53
53 /* used by regulator core */ 54 /* used by regulator core */
54 struct regulator_desc desc; 55 struct regulator_desc desc;
@@ -318,31 +319,8 @@ static const u16 VIO_VSEL_table[] = {
318static const u16 VINTANA2_VSEL_table[] = { 319static const u16 VINTANA2_VSEL_table[] = {
319 2500, 2750, 320 2500, 2750,
320}; 321};
321static const u16 VAUX1_6030_VSEL_table[] = {
322 1000, 1300, 1800, 2500,
323 2800, 2900, 3000, 3000,
324};
325static const u16 VAUX2_6030_VSEL_table[] = {
326 1200, 1800, 2500, 2750,
327 2800, 2800, 2800, 2800,
328};
329static const u16 VAUX3_6030_VSEL_table[] = {
330 1000, 1200, 1300, 1800,
331 2500, 2800, 3000, 3000,
332};
333static const u16 VMMC_VSEL_table[] = {
334 1200, 1800, 2800, 2900,
335 3000, 3000, 3000, 3000,
336};
337static const u16 VPP_VSEL_table[] = {
338 1800, 1900, 2000, 2100,
339 2200, 2300, 2400, 2500,
340};
341static const u16 VUSIM_VSEL_table[] = {
342 1200, 1800, 2500, 2900,
343};
344 322
345static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) 323static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
346{ 324{
347 struct twlreg_info *info = rdev_get_drvdata(rdev); 325 struct twlreg_info *info = rdev_get_drvdata(rdev);
348 int mV = info->table[index]; 326 int mV = info->table[index];
@@ -351,7 +329,7 @@ static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index)
351} 329}
352 330
353static int 331static int
354twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 332twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
355{ 333{
356 struct twlreg_info *info = rdev_get_drvdata(rdev); 334 struct twlreg_info *info = rdev_get_drvdata(rdev);
357 int vsel; 335 int vsel;
@@ -375,7 +353,7 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
375 return -EDOM; 353 return -EDOM;
376} 354}
377 355
378static int twlldo_get_voltage(struct regulator_dev *rdev) 356static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
379{ 357{
380 struct twlreg_info *info = rdev_get_drvdata(rdev); 358 struct twlreg_info *info = rdev_get_drvdata(rdev);
381 int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, 359 int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
@@ -388,11 +366,67 @@ static int twlldo_get_voltage(struct regulator_dev *rdev)
388 return LDO_MV(info->table[vsel]) * 1000; 366 return LDO_MV(info->table[vsel]) * 1000;
389} 367}
390 368
391static struct regulator_ops twlldo_ops = { 369static struct regulator_ops twl4030ldo_ops = {
392 .list_voltage = twlldo_list_voltage, 370 .list_voltage = twl4030ldo_list_voltage,
393 371
394 .set_voltage = twlldo_set_voltage, 372 .set_voltage = twl4030ldo_set_voltage,
395 .get_voltage = twlldo_get_voltage, 373 .get_voltage = twl4030ldo_get_voltage,
374
375 .enable = twlreg_enable,
376 .disable = twlreg_disable,
377 .is_enabled = twlreg_is_enabled,
378
379 .set_mode = twlreg_set_mode,
380
381 .get_status = twlreg_get_status,
382};
383
384static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
385{
386 struct twlreg_info *info = rdev_get_drvdata(rdev);
387
388 return ((info->min_mV + (index * 100)) * 1000);
389}
390
391static int
392twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
393{
394 struct twlreg_info *info = rdev_get_drvdata(rdev);
395 int vsel;
396
397 if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV))
398 return -EDOM;
399
400 /*
401 * Use the below formula to calculate vsel
402 * mV = 1000mv + 100mv * (vsel - 1)
403 */
404 vsel = (min_uV/1000 - 1000)/100 + 1;
405 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel);
406
407}
408
409static int twl6030ldo_get_voltage(struct regulator_dev *rdev)
410{
411 struct twlreg_info *info = rdev_get_drvdata(rdev);
412 int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
413 VREG_VOLTAGE);
414
415 if (vsel < 0)
416 return vsel;
417
418 /*
419 * Use the below formula to calculate vsel
420 * mV = 1000mv + 100mv * (vsel - 1)
421 */
422 return (1000 + (100 * (vsel - 1))) * 1000;
423}
424
425static struct regulator_ops twl6030ldo_ops = {
426 .list_voltage = twl6030ldo_list_voltage,
427
428 .set_voltage = twl6030ldo_set_voltage,
429 .get_voltage = twl6030ldo_get_voltage,
396 430
397 .enable = twlreg_enable, 431 .enable = twlreg_enable,
398 .disable = twlreg_disable, 432 .disable = twlreg_disable,
@@ -438,24 +472,16 @@ static struct regulator_ops twlfixed_ops = {
438 472
439/*----------------------------------------------------------------------*/ 473/*----------------------------------------------------------------------*/
440 474
441#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
442 TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
443 remap_conf, TWL4030)
444#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 475#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
445 remap_conf) \ 476 remap_conf) \
446 TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 477 TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
447 remap_conf, TWL4030) 478 remap_conf, TWL4030)
448#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
449 remap_conf) \
450 TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
451 remap_conf, TWL6030)
452#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 479#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
453 remap_conf) \ 480 remap_conf) \
454 TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 481 TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
455 remap_conf, TWL6030) 482 remap_conf, TWL6030)
456 483
457#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ 484#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \
458 family) { \
459 .base = offset, \ 485 .base = offset, \
460 .id = num, \ 486 .id = num, \
461 .table_len = ARRAY_SIZE(label##_VSEL_table), \ 487 .table_len = ARRAY_SIZE(label##_VSEL_table), \
@@ -464,14 +490,32 @@ static struct regulator_ops twlfixed_ops = {
464 .remap = remap_conf, \ 490 .remap = remap_conf, \
465 .desc = { \ 491 .desc = { \
466 .name = #label, \ 492 .name = #label, \
467 .id = family##_REG_##label, \ 493 .id = TWL4030_REG_##label, \
468 .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ 494 .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
469 .ops = &twlldo_ops, \ 495 .ops = &twl4030ldo_ops, \
470 .type = REGULATOR_VOLTAGE, \ 496 .type = REGULATOR_VOLTAGE, \
471 .owner = THIS_MODULE, \ 497 .owner = THIS_MODULE, \
472 }, \ 498 }, \
473 } 499 }
474 500
501#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \
502 remap_conf) { \
503 .base = offset, \
504 .id = num, \
505 .min_mV = min_mVolts, \
506 .max_mV = max_mVolts, \
507 .remap = remap_conf, \
508 .desc = { \
509 .name = #label, \
510 .id = TWL6030_REG_##label, \
511 .n_voltages = (max_mVolts - min_mVolts)/100, \
512 .ops = &twl6030ldo_ops, \
513 .type = REGULATOR_VOLTAGE, \
514 .owner = THIS_MODULE, \
515 }, \
516 }
517
518
475#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ 519#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
476 family) { \ 520 family) { \
477 .base = offset, \ 521 .base = offset, \
@@ -519,12 +563,12 @@ static struct twlreg_info twl_regs[] = {
519 /* 6030 REG with base as PMC Slave Misc : 0x0030 */ 563 /* 6030 REG with base as PMC Slave Misc : 0x0030 */
520 /* Turnon-delay and remap configuration values for 6030 are not 564 /* Turnon-delay and remap configuration values for 6030 are not
521 verified since the specification is not public */ 565 verified since the specification is not public */
522 TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x21), 566 TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21),
523 TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x21), 567 TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21),
524 TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x21), 568 TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21),
525 TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x21), 569 TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21),
526 TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x21), 570 TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21),
527 TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x21), 571 TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21),
528 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), 572 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21),
529 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), 573 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21),
530 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), 574 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21),
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 73f92c5feea2..e3c4ff8c3e38 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -132,6 +132,7 @@ enum {
132 PM8607_ID_LDO9, 132 PM8607_ID_LDO9,
133 PM8607_ID_LDO10, 133 PM8607_ID_LDO10,
134 PM8607_ID_LDO12, 134 PM8607_ID_LDO12,
135 PM8607_ID_LDO13,
135 PM8607_ID_LDO14, 136 PM8607_ID_LDO14,
136 137
137 PM8607_ID_RG_MAX, 138 PM8607_ID_RG_MAX,
@@ -309,7 +310,7 @@ struct pm860x_chip {
309 310
310}; 311};
311 312
312#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */ 313#define PM8607_MAX_REGULATOR PM8607_ID_RG_MAX /* 3 Bucks, 13 LDOs */
313 314
314enum { 315enum {
315 GI2C_PORT = 0, 316 GI2C_PORT = 0,
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 234a8476cba8..e2980287245e 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -157,7 +157,11 @@ struct regulator_consumer_supply {
157 * 157 *
158 * Initialisation constraints, our supply and consumers supplies. 158 * Initialisation constraints, our supply and consumers supplies.
159 * 159 *
160 * @supply_regulator_dev: Parent regulator (if any). 160 * @supply_regulator: Parent regulator. Specified using the regulator name
161 * as it appears in the name field in sysfs, which can
162 * be explicitly set using the constraints field 'name'.
163 * @supply_regulator_dev: Parent regulator (if any) - DEPRECATED in favour
164 * of supply_regulator.
161 * 165 *
162 * @constraints: Constraints. These must be specified for the regulator to 166 * @constraints: Constraints. These must be specified for the regulator to
163 * be usable. 167 * be usable.
@@ -168,7 +172,8 @@ struct regulator_consumer_supply {
168 * @driver_data: Data passed to regulator_init. 172 * @driver_data: Data passed to regulator_init.
169 */ 173 */
170struct regulator_init_data { 174struct regulator_init_data {
171 struct device *supply_regulator_dev; /* or NULL for LINE */ 175 const char *supply_regulator; /* or NULL for system supply */
176 struct device *supply_regulator_dev; /* or NULL for system supply */
172 177
173 struct regulation_constraints constraints; 178 struct regulation_constraints constraints;
174 179