diff options
Diffstat (limited to 'drivers/regulator/max8660.c')
-rw-r--r-- | drivers/regulator/max8660.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 8d94d3d7f97f..2fc411188794 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
@@ -81,16 +81,17 @@ enum { | |||
81 | struct max8660 { | 81 | struct max8660 { |
82 | struct i2c_client *client; | 82 | struct i2c_client *client; |
83 | u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ | 83 | u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ |
84 | struct regulator_dev *rdev[]; | ||
85 | }; | 84 | }; |
86 | 85 | ||
87 | static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) | 86 | static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) |
88 | { | 87 | { |
89 | static const u8 max8660_addresses[MAX8660_N_REGS] = | 88 | static const u8 max8660_addresses[MAX8660_N_REGS] = { |
90 | { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 }; | 89 | 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 |
90 | }; | ||
91 | 91 | ||
92 | int ret; | 92 | int ret; |
93 | u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; | 93 | u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; |
94 | |||
94 | dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", | 95 | dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", |
95 | max8660_addresses[reg], reg_val); | 96 | max8660_addresses[reg], reg_val); |
96 | 97 | ||
@@ -112,6 +113,7 @@ static int max8660_dcdc_is_enabled(struct regulator_dev *rdev) | |||
112 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 113 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
113 | u8 val = max8660->shadow_regs[MAX8660_OVER1]; | 114 | u8 val = max8660->shadow_regs[MAX8660_OVER1]; |
114 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; | 115 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; |
116 | |||
115 | return !!(val & mask); | 117 | return !!(val & mask); |
116 | } | 118 | } |
117 | 119 | ||
@@ -119,6 +121,7 @@ static int max8660_dcdc_enable(struct regulator_dev *rdev) | |||
119 | { | 121 | { |
120 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 122 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
121 | u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; | 123 | u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; |
124 | |||
122 | return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); | 125 | return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); |
123 | } | 126 | } |
124 | 127 | ||
@@ -126,15 +129,16 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev) | |||
126 | { | 129 | { |
127 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 130 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
128 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; | 131 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; |
132 | |||
129 | return max8660_write(max8660, MAX8660_OVER1, mask, 0); | 133 | return max8660_write(max8660, MAX8660_OVER1, mask, 0); |
130 | } | 134 | } |
131 | 135 | ||
132 | static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) | 136 | static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) |
133 | { | 137 | { |
134 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 138 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
135 | |||
136 | u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; | 139 | u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; |
137 | u8 selector = max8660->shadow_regs[reg]; | 140 | u8 selector = max8660->shadow_regs[reg]; |
141 | |||
138 | return selector; | 142 | return selector; |
139 | } | 143 | } |
140 | 144 | ||
@@ -207,6 +211,7 @@ static int max8660_ldo67_is_enabled(struct regulator_dev *rdev) | |||
207 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 211 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
208 | u8 val = max8660->shadow_regs[MAX8660_OVER2]; | 212 | u8 val = max8660->shadow_regs[MAX8660_OVER2]; |
209 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; | 213 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; |
214 | |||
210 | return !!(val & mask); | 215 | return !!(val & mask); |
211 | } | 216 | } |
212 | 217 | ||
@@ -214,6 +219,7 @@ static int max8660_ldo67_enable(struct regulator_dev *rdev) | |||
214 | { | 219 | { |
215 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 220 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
216 | u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; | 221 | u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; |
222 | |||
217 | return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); | 223 | return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); |
218 | } | 224 | } |
219 | 225 | ||
@@ -221,15 +227,16 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev) | |||
221 | { | 227 | { |
222 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 228 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
223 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; | 229 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; |
230 | |||
224 | return max8660_write(max8660, MAX8660_OVER2, mask, 0); | 231 | return max8660_write(max8660, MAX8660_OVER2, mask, 0); |
225 | } | 232 | } |
226 | 233 | ||
227 | static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) | 234 | static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) |
228 | { | 235 | { |
229 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 236 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
230 | |||
231 | u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; | 237 | u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; |
232 | u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; | 238 | u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; |
239 | |||
233 | return selector; | 240 | return selector; |
234 | } | 241 | } |
235 | 242 | ||
@@ -330,7 +337,7 @@ static int max8660_pdata_from_dt(struct device *dev, | |||
330 | struct max8660_subdev_data *sub; | 337 | struct max8660_subdev_data *sub; |
331 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; | 338 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; |
332 | 339 | ||
333 | np = of_find_node_by_name(dev->of_node, "regulators"); | 340 | np = of_get_child_by_name(dev->of_node, "regulators"); |
334 | if (!np) { | 341 | if (!np) { |
335 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | 342 | dev_err(dev, "missing 'regulators' subnode in DT\n"); |
336 | return -EINVAL; | 343 | return -EINVAL; |
@@ -340,6 +347,7 @@ static int max8660_pdata_from_dt(struct device *dev, | |||
340 | rmatch[i].name = max8660_reg[i].name; | 347 | rmatch[i].name = max8660_reg[i].name; |
341 | 348 | ||
342 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); | 349 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); |
350 | of_node_put(np); | ||
343 | if (matched <= 0) | 351 | if (matched <= 0) |
344 | return matched; | 352 | return matched; |
345 | 353 | ||
@@ -373,7 +381,6 @@ static inline int max8660_pdata_from_dt(struct device *dev, | |||
373 | static int max8660_probe(struct i2c_client *client, | 381 | static int max8660_probe(struct i2c_client *client, |
374 | const struct i2c_device_id *i2c_id) | 382 | const struct i2c_device_id *i2c_id) |
375 | { | 383 | { |
376 | struct regulator_dev **rdev; | ||
377 | struct device *dev = &client->dev; | 384 | struct device *dev = &client->dev; |
378 | struct max8660_platform_data *pdata = dev_get_platdata(dev); | 385 | struct max8660_platform_data *pdata = dev_get_platdata(dev); |
379 | struct regulator_config config = { }; | 386 | struct regulator_config config = { }; |
@@ -406,14 +413,11 @@ static int max8660_probe(struct i2c_client *client, | |||
406 | return -EINVAL; | 413 | return -EINVAL; |
407 | } | 414 | } |
408 | 415 | ||
409 | max8660 = devm_kzalloc(dev, sizeof(struct max8660) + | 416 | max8660 = devm_kzalloc(dev, sizeof(struct max8660), GFP_KERNEL); |
410 | sizeof(struct regulator_dev *) * MAX8660_V_END, | ||
411 | GFP_KERNEL); | ||
412 | if (!max8660) | 417 | if (!max8660) |
413 | return -ENOMEM; | 418 | return -ENOMEM; |
414 | 419 | ||
415 | max8660->client = client; | 420 | max8660->client = client; |
416 | rdev = max8660->rdev; | ||
417 | 421 | ||
418 | if (pdata->en34_is_high) { | 422 | if (pdata->en34_is_high) { |
419 | /* Simulate always on */ | 423 | /* Simulate always on */ |
@@ -481,6 +485,7 @@ static int max8660_probe(struct i2c_client *client, | |||
481 | 485 | ||
482 | /* Finally register devices */ | 486 | /* Finally register devices */ |
483 | for (i = 0; i < pdata->num_subdevs; i++) { | 487 | for (i = 0; i < pdata->num_subdevs; i++) { |
488 | struct regulator_dev *rdev; | ||
484 | 489 | ||
485 | id = pdata->subdevs[i].id; | 490 | id = pdata->subdevs[i].id; |
486 | 491 | ||
@@ -489,13 +494,13 @@ static int max8660_probe(struct i2c_client *client, | |||
489 | config.of_node = of_node[i]; | 494 | config.of_node = of_node[i]; |
490 | config.driver_data = max8660; | 495 | config.driver_data = max8660; |
491 | 496 | ||
492 | rdev[i] = devm_regulator_register(&client->dev, | 497 | rdev = devm_regulator_register(&client->dev, |
493 | &max8660_reg[id], &config); | 498 | &max8660_reg[id], &config); |
494 | if (IS_ERR(rdev[i])) { | 499 | if (IS_ERR(rdev)) { |
495 | ret = PTR_ERR(rdev[i]); | 500 | ret = PTR_ERR(rdev); |
496 | dev_err(&client->dev, "failed to register %s\n", | 501 | dev_err(&client->dev, "failed to register %s\n", |
497 | max8660_reg[id].name); | 502 | max8660_reg[id].name); |
498 | return PTR_ERR(rdev[i]); | 503 | return PTR_ERR(rdev); |
499 | } | 504 | } |
500 | } | 505 | } |
501 | 506 | ||