aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-07-08 18:31:36 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-07-08 18:31:36 -0400
commit59db96913c9d94fe74002df494eb80e4a5ca4087 (patch)
tree0f1bd565730de65907e5924ec848002374a50002
parent14b5bd5cf5605555a746c10404e442c6a95567c1 (diff)
mfd: Move arizona digital core supply management to the regulator API
Rather than open coding the enable GPIO control in the MFD core use the API to push the management on to the regulator driver. The immediate advantage is slight for most systems but this will in future allow device configurations where an external regulator is used for DCVDD. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/arizona-core.c65
-rw-r--r--include/linux/mfd/arizona/core.h1
2 files changed, 36 insertions, 30 deletions
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 42cb28b2b5c8..c8946a889a78 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/err.h>
14#include <linux/gpio.h> 15#include <linux/gpio.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
16#include <linux/mfd/core.h> 17#include <linux/mfd/core.h>
@@ -28,7 +29,6 @@
28static const char *wm5102_core_supplies[] = { 29static const char *wm5102_core_supplies[] = {
29 "AVDD", 30 "AVDD",
30 "DBVDD1", 31 "DBVDD1",
31 "DCVDD",
32}; 32};
33 33
34int arizona_clk32k_enable(struct arizona *arizona) 34int arizona_clk32k_enable(struct arizona *arizona)
@@ -223,8 +223,11 @@ static int arizona_runtime_resume(struct device *dev)
223 struct arizona *arizona = dev_get_drvdata(dev); 223 struct arizona *arizona = dev_get_drvdata(dev);
224 int ret; 224 int ret;
225 225
226 if (arizona->pdata.ldoena) 226 ret = regulator_enable(arizona->dcvdd);
227 gpio_set_value_cansleep(arizona->pdata.ldoena, 1); 227 if (ret != 0) {
228 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
229 return ret;
230 }
228 231
229 regcache_cache_only(arizona->regmap, false); 232 regcache_cache_only(arizona->regmap, false);
230 233
@@ -241,11 +244,9 @@ static int arizona_runtime_suspend(struct device *dev)
241{ 244{
242 struct arizona *arizona = dev_get_drvdata(dev); 245 struct arizona *arizona = dev_get_drvdata(dev);
243 246
244 if (arizona->pdata.ldoena) { 247 regulator_disable(arizona->dcvdd);
245 gpio_set_value_cansleep(arizona->pdata.ldoena, 0); 248 regcache_cache_only(arizona->regmap, true);
246 regcache_cache_only(arizona->regmap, true); 249 regcache_mark_dirty(arizona->regmap);
247 regcache_mark_dirty(arizona->regmap);
248 }
249 250
250 return 0; 251 return 0;
251} 252}
@@ -314,6 +315,13 @@ int __devinit arizona_dev_init(struct arizona *arizona)
314 goto err_early; 315 goto err_early;
315 } 316 }
316 317
318 arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
319 if (IS_ERR(arizona->dcvdd)) {
320 ret = PTR_ERR(arizona->dcvdd);
321 dev_err(dev, "Failed to request DCVDD: %d\n", ret);
322 goto err_early;
323 }
324
317 ret = regulator_bulk_enable(arizona->num_core_supplies, 325 ret = regulator_bulk_enable(arizona->num_core_supplies,
318 arizona->core_supplies); 326 arizona->core_supplies);
319 if (ret != 0) { 327 if (ret != 0) {
@@ -322,6 +330,12 @@ int __devinit arizona_dev_init(struct arizona *arizona)
322 goto err_early; 330 goto err_early;
323 } 331 }
324 332
333 ret = regulator_enable(arizona->dcvdd);
334 if (ret != 0) {
335 dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
336 goto err_enable;
337 }
338
325 if (arizona->pdata.reset) { 339 if (arizona->pdata.reset) {
326 /* Start out with /RESET low to put the chip into reset */ 340 /* Start out with /RESET low to put the chip into reset */
327 ret = gpio_request_one(arizona->pdata.reset, 341 ret = gpio_request_one(arizona->pdata.reset,
@@ -329,35 +343,25 @@ int __devinit arizona_dev_init(struct arizona *arizona)
329 "arizona /RESET"); 343 "arizona /RESET");
330 if (ret != 0) { 344 if (ret != 0) {
331 dev_err(dev, "Failed to request /RESET: %d\n", ret); 345 dev_err(dev, "Failed to request /RESET: %d\n", ret);
332 goto err_enable; 346 goto err_dcvdd;
333 } 347 }
334 348
335 gpio_set_value_cansleep(arizona->pdata.reset, 1); 349 gpio_set_value_cansleep(arizona->pdata.reset, 1);
336 } 350 }
337 351
338 if (arizona->pdata.ldoena) {
339 ret = gpio_request_one(arizona->pdata.ldoena,
340 GPIOF_DIR_OUT | GPIOF_INIT_HIGH,
341 "arizona LDOENA");
342 if (ret != 0) {
343 dev_err(dev, "Failed to request LDOENA: %d\n", ret);
344 goto err_reset;
345 }
346 }
347
348 regcache_cache_only(arizona->regmap, false); 352 regcache_cache_only(arizona->regmap, false);
349 353
350 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg); 354 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
351 if (ret != 0) { 355 if (ret != 0) {
352 dev_err(dev, "Failed to read ID register: %d\n", ret); 356 dev_err(dev, "Failed to read ID register: %d\n", ret);
353 goto err_ldoena; 357 goto err_reset;
354 } 358 }
355 359
356 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION, 360 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
357 &arizona->rev); 361 &arizona->rev);
358 if (ret != 0) { 362 if (ret != 0) {
359 dev_err(dev, "Failed to read revision register: %d\n", ret); 363 dev_err(dev, "Failed to read revision register: %d\n", ret);
360 goto err_ldoena; 364 goto err_reset;
361 } 365 }
362 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; 366 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
363 367
@@ -374,7 +378,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
374 378
375 default: 379 default:
376 dev_err(arizona->dev, "Unknown device ID %x\n", reg); 380 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
377 goto err_ldoena; 381 goto err_reset;
378 } 382 }
379 383
380 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); 384 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
@@ -387,7 +391,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
387 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); 391 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
388 if (ret != 0) { 392 if (ret != 0) {
389 dev_err(dev, "Failed to reset device: %d\n", ret); 393 dev_err(dev, "Failed to reset device: %d\n", ret);
390 goto err_ldoena; 394 goto err_reset;
391 } 395 }
392 } 396 }
393 397
@@ -424,7 +428,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
424 dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n", 428 dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
425 arizona->pdata.clk32k_src); 429 arizona->pdata.clk32k_src);
426 ret = -EINVAL; 430 ret = -EINVAL;
427 goto err_ldoena; 431 goto err_reset;
428 } 432 }
429 433
430 for (i = 0; i < ARIZONA_MAX_INPUT; i++) { 434 for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
@@ -470,7 +474,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
470 /* Set up for interrupts */ 474 /* Set up for interrupts */
471 ret = arizona_irq_init(arizona); 475 ret = arizona_irq_init(arizona);
472 if (ret != 0) 476 if (ret != 0)
473 goto err_ldoena; 477 goto err_reset;
474 478
475 arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error", 479 arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
476 arizona_clkgen_err, arizona); 480 arizona_clkgen_err, arizona);
@@ -491,20 +495,21 @@ int __devinit arizona_dev_init(struct arizona *arizona)
491 goto err_irq; 495 goto err_irq;
492 } 496 }
493 497
498#ifdef CONFIG_PM_RUNTIME
499 regulator_disable(arizona->dcvdd);
500#endif
501
494 return 0; 502 return 0;
495 503
496err_irq: 504err_irq:
497 arizona_irq_exit(arizona); 505 arizona_irq_exit(arizona);
498err_ldoena:
499 if (arizona->pdata.ldoena) {
500 gpio_set_value_cansleep(arizona->pdata.ldoena, 0);
501 gpio_free(arizona->pdata.ldoena);
502 }
503err_reset: 506err_reset:
504 if (arizona->pdata.reset) { 507 if (arizona->pdata.reset) {
505 gpio_set_value_cansleep(arizona->pdata.reset, 1); 508 gpio_set_value_cansleep(arizona->pdata.reset, 1);
506 gpio_free(arizona->pdata.reset); 509 gpio_free(arizona->pdata.reset);
507 } 510 }
511err_dcvdd:
512 regulator_disable(arizona->dcvdd);
508err_enable: 513err_enable:
509 regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies), 514 regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
510 arizona->core_supplies); 515 arizona->core_supplies);
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index 0157d845c2ff..3ef32b4c1136 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -77,6 +77,7 @@ struct arizona {
77 77
78 int num_core_supplies; 78 int num_core_supplies;
79 struct regulator_bulk_data core_supplies[ARIZONA_MAX_CORE_SUPPLIES]; 79 struct regulator_bulk_data core_supplies[ARIZONA_MAX_CORE_SUPPLIES];
80 struct regulator *dcvdd;
80 81
81 struct arizona_pdata pdata; 82 struct arizona_pdata pdata;
82 83