Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
arizona-core.c
Go to the documentation of this file.
1 /*
2  * Arizona core driver
3  *
4  * Copyright 2012 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/gpio.h>
16 #include <linux/interrupt.h>
17 #include <linux/mfd/core.h>
18 #include <linux/module.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
22 #include <linux/slab.h>
23 
24 #include <linux/mfd/arizona/core.h>
26 
27 #include "arizona.h"
28 
29 static const char *wm5102_core_supplies[] = {
30  "AVDD",
31  "DBVDD1",
32 };
33 
35 {
36  int ret = 0;
37 
38  mutex_lock(&arizona->clk_lock);
39 
40  arizona->clk32k_ref++;
41 
42  if (arizona->clk32k_ref == 1)
46 
47  if (ret != 0)
48  arizona->clk32k_ref--;
49 
50  mutex_unlock(&arizona->clk_lock);
51 
52  return ret;
53 }
55 
57 {
58  int ret = 0;
59 
60  mutex_lock(&arizona->clk_lock);
61 
62  BUG_ON(arizona->clk32k_ref <= 0);
63 
64  arizona->clk32k_ref--;
65 
66  if (arizona->clk32k_ref == 0)
69 
70  mutex_unlock(&arizona->clk_lock);
71 
72  return ret;
73 }
75 
76 static irqreturn_t arizona_clkgen_err(int irq, void *data)
77 {
78  struct arizona *arizona = data;
79 
80  dev_err(arizona->dev, "CLKGEN error\n");
81 
82  return IRQ_HANDLED;
83 }
84 
85 static irqreturn_t arizona_underclocked(int irq, void *data)
86 {
87  struct arizona *arizona = data;
88  unsigned int val;
89  int ret;
90 
92  &val);
93  if (ret != 0) {
94  dev_err(arizona->dev, "Failed to read underclock status: %d\n",
95  ret);
96  return IRQ_NONE;
97  }
98 
100  dev_err(arizona->dev, "AIF3 underclocked\n");
102  dev_err(arizona->dev, "AIF2 underclocked\n");
104  dev_err(arizona->dev, "AIF1 underclocked\n");
106  dev_err(arizona->dev, "ISRC2 underclocked\n");
108  dev_err(arizona->dev, "ISRC1 underclocked\n");
109  if (val & ARIZONA_FX_UNDERCLOCKED_STS)
110  dev_err(arizona->dev, "FX underclocked\n");
112  dev_err(arizona->dev, "ASRC underclocked\n");
114  dev_err(arizona->dev, "DAC underclocked\n");
116  dev_err(arizona->dev, "ADC underclocked\n");
118  dev_err(arizona->dev, "Mixer underclocked\n");
119 
120  return IRQ_HANDLED;
121 }
122 
123 static irqreturn_t arizona_overclocked(int irq, void *data)
124 {
125  struct arizona *arizona = data;
126  unsigned int val[2];
127  int ret;
128 
130  &val[0], 2);
131  if (ret != 0) {
132  dev_err(arizona->dev, "Failed to read overclock status: %d\n",
133  ret);
134  return IRQ_NONE;
135  }
136 
137  if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
138  dev_err(arizona->dev, "PWM overclocked\n");
139  if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
140  dev_err(arizona->dev, "FX core overclocked\n");
141  if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
142  dev_err(arizona->dev, "DAC SYS overclocked\n");
144  dev_err(arizona->dev, "DAC WARP overclocked\n");
145  if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
146  dev_err(arizona->dev, "ADC overclocked\n");
147  if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
148  dev_err(arizona->dev, "Mixer overclocked\n");
150  dev_err(arizona->dev, "AIF3 overclocked\n");
152  dev_err(arizona->dev, "AIF2 overclocked\n");
154  dev_err(arizona->dev, "AIF1 overclocked\n");
156  dev_err(arizona->dev, "Pad control overclocked\n");
157 
159  dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
161  dev_err(arizona->dev, "Slimbus async overclocked\n");
163  dev_err(arizona->dev, "Slimbus sync overclocked\n");
165  dev_err(arizona->dev, "ASRC async system overclocked\n");
167  dev_err(arizona->dev, "ASRC async WARP overclocked\n");
169  dev_err(arizona->dev, "ASRC sync system overclocked\n");
171  dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
172  if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
173  dev_err(arizona->dev, "DSP1 overclocked\n");
174  if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
175  dev_err(arizona->dev, "ISRC2 overclocked\n");
176  if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
177  dev_err(arizona->dev, "ISRC1 overclocked\n");
178 
179  return IRQ_HANDLED;
180 }
181 
182 static int arizona_wait_for_boot(struct arizona *arizona)
183 {
184  unsigned int reg;
185  int ret, i;
186 
187  /*
188  * We can't use an interrupt as we need to runtime resume to do so,
189  * we won't race with the interrupt handler as it'll be blocked on
190  * runtime resume.
191  */
192  for (i = 0; i < 5; i++) {
193  msleep(1);
194 
195  ret = regmap_read(arizona->regmap,
197  if (ret != 0) {
198  dev_err(arizona->dev, "Failed to read boot state: %d\n",
199  ret);
200  continue;
201  }
202 
203  if (reg & ARIZONA_BOOT_DONE_STS)
204  break;
205  }
206 
207  if (reg & ARIZONA_BOOT_DONE_STS) {
209  ARIZONA_BOOT_DONE_STS);
210  } else {
211  dev_err(arizona->dev, "Device boot timed out: %x\n", reg);
212  return -ETIMEDOUT;
213  }
214 
215  pm_runtime_mark_last_busy(arizona->dev);
216 
217  return 0;
218 }
219 
220 #ifdef CONFIG_PM_RUNTIME
221 static int arizona_runtime_resume(struct device *dev)
222 {
223  struct arizona *arizona = dev_get_drvdata(dev);
224  int ret;
225 
226  dev_dbg(arizona->dev, "Leaving AoD mode\n");
227 
228  ret = regulator_enable(arizona->dcvdd);
229  if (ret != 0) {
230  dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
231  return ret;
232  }
233 
234  regcache_cache_only(arizona->regmap, false);
235 
236  ret = arizona_wait_for_boot(arizona);
237  if (ret != 0) {
238  regulator_disable(arizona->dcvdd);
239  return ret;
240  }
241 
242  regcache_sync(arizona->regmap);
243 
244  return 0;
245 }
246 
247 static int arizona_runtime_suspend(struct device *dev)
248 {
249  struct arizona *arizona = dev_get_drvdata(dev);
250 
251  dev_dbg(arizona->dev, "Entering AoD mode\n");
252 
253  regulator_disable(arizona->dcvdd);
254  regcache_cache_only(arizona->regmap, true);
255  regcache_mark_dirty(arizona->regmap);
256 
257  return 0;
258 }
259 #endif
260 
261 const struct dev_pm_ops arizona_pm_ops = {
262  SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
263  arizona_runtime_resume,
264  NULL)
265 };
266 EXPORT_SYMBOL_GPL(arizona_pm_ops);
267 
268 static struct mfd_cell early_devs[] = {
269  { .name = "arizona-ldo1" },
270 };
271 
272 static struct mfd_cell wm5102_devs[] = {
273  { .name = "arizona-extcon" },
274  { .name = "arizona-gpio" },
275  { .name = "arizona-micsupp" },
276  { .name = "arizona-pwm" },
277  { .name = "wm5102-codec" },
278 };
279 
280 static struct mfd_cell wm5110_devs[] = {
281  { .name = "arizona-extcon" },
282  { .name = "arizona-gpio" },
283  { .name = "arizona-micsupp" },
284  { .name = "arizona-pwm" },
285  { .name = "wm5110-codec" },
286 };
287 
288 int __devinit arizona_dev_init(struct arizona *arizona)
289 {
290  struct device *dev = arizona->dev;
291  const char *type_name;
292  unsigned int reg, val;
293  int ret, i;
294 
295  dev_set_drvdata(arizona->dev, arizona);
296  mutex_init(&arizona->clk_lock);
297 
298  if (dev_get_platdata(arizona->dev))
299  memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
300  sizeof(arizona->pdata));
301 
302  regcache_cache_only(arizona->regmap, true);
303 
304  switch (arizona->type) {
305  case WM5102:
306  case WM5110:
307  for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
308  arizona->core_supplies[i].supply
309  = wm5102_core_supplies[i];
310  arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
311  break;
312  default:
313  dev_err(arizona->dev, "Unknown device type %d\n",
314  arizona->type);
315  return -EINVAL;
316  }
317 
318  ret = mfd_add_devices(arizona->dev, -1, early_devs,
319  ARRAY_SIZE(early_devs), NULL, 0, NULL);
320  if (ret != 0) {
321  dev_err(dev, "Failed to add early children: %d\n", ret);
322  return ret;
323  }
324 
325  ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
326  arizona->core_supplies);
327  if (ret != 0) {
328  dev_err(dev, "Failed to request core supplies: %d\n",
329  ret);
330  goto err_early;
331  }
332 
333  arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
334  if (IS_ERR(arizona->dcvdd)) {
335  ret = PTR_ERR(arizona->dcvdd);
336  dev_err(dev, "Failed to request DCVDD: %d\n", ret);
337  goto err_early;
338  }
339 
341  arizona->core_supplies);
342  if (ret != 0) {
343  dev_err(dev, "Failed to enable core supplies: %d\n",
344  ret);
345  goto err_early;
346  }
347 
348  ret = regulator_enable(arizona->dcvdd);
349  if (ret != 0) {
350  dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
351  goto err_enable;
352  }
353 
354  if (arizona->pdata.reset) {
355  /* Start out with /RESET low to put the chip into reset */
356  ret = gpio_request_one(arizona->pdata.reset,
358  "arizona /RESET");
359  if (ret != 0) {
360  dev_err(dev, "Failed to request /RESET: %d\n", ret);
361  goto err_dcvdd;
362  }
363 
364  gpio_set_value_cansleep(arizona->pdata.reset, 1);
365  }
366 
367  regcache_cache_only(arizona->regmap, false);
368 
369  ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
370  if (ret != 0) {
371  dev_err(dev, "Failed to read ID register: %d\n", ret);
372  goto err_reset;
373  }
374 
376  &arizona->rev);
377  if (ret != 0) {
378  dev_err(dev, "Failed to read revision register: %d\n", ret);
379  goto err_reset;
380  }
381  arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
382 
383  switch (reg) {
384 #ifdef CONFIG_MFD_WM5102
385  case 0x5102:
386  type_name = "WM5102";
387  if (arizona->type != WM5102) {
388  dev_err(arizona->dev, "WM5102 registered as %d\n",
389  arizona->type);
390  arizona->type = WM5102;
391  }
392  ret = wm5102_patch(arizona);
393  break;
394 #endif
395 #ifdef CONFIG_MFD_WM5110
396  case 0x5110:
397  type_name = "WM5110";
398  if (arizona->type != WM5110) {
399  dev_err(arizona->dev, "WM5110 registered as %d\n",
400  arizona->type);
401  arizona->type = WM5110;
402  }
403  ret = wm5110_patch(arizona);
404  break;
405 #endif
406  default:
407  dev_err(arizona->dev, "Unknown device ID %x\n", reg);
408  goto err_reset;
409  }
410 
411  dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
412 
413  if (ret != 0)
414  dev_err(arizona->dev, "Failed to apply patch: %d\n", ret);
415 
416  /* If we have a /RESET GPIO we'll already be reset */
417  if (!arizona->pdata.reset) {
418  regcache_mark_dirty(arizona->regmap);
419 
420  ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
421  if (ret != 0) {
422  dev_err(dev, "Failed to reset device: %d\n", ret);
423  goto err_reset;
424  }
425 
426  ret = regcache_sync(arizona->regmap);
427  if (ret != 0) {
428  dev_err(dev, "Failed to sync device: %d\n", ret);
429  goto err_reset;
430  }
431  }
432 
433  ret = arizona_wait_for_boot(arizona);
434  if (ret != 0) {
435  dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
436  goto err_reset;
437  }
438 
439  for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
440  if (!arizona->pdata.gpio_defaults[i])
441  continue;
442 
443  regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
444  arizona->pdata.gpio_defaults[i]);
445  }
446 
447  pm_runtime_set_autosuspend_delay(arizona->dev, 100);
448  pm_runtime_use_autosuspend(arizona->dev);
449  pm_runtime_enable(arizona->dev);
450 
451  /* Chip default */
452  if (!arizona->pdata.clk32k_src)
453  arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
454 
455  switch (arizona->pdata.clk32k_src) {
456  case ARIZONA_32KZ_MCLK1:
457  case ARIZONA_32KZ_MCLK2:
460  arizona->pdata.clk32k_src - 1);
461  break;
462  case ARIZONA_32KZ_NONE:
465  break;
466  default:
467  dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
468  arizona->pdata.clk32k_src);
469  ret = -EINVAL;
470  goto err_reset;
471  }
472 
473  for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
474  /* Default for both is 0 so noop with defaults */
475  val = arizona->pdata.dmic_ref[i]
477  val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT;
478 
479  regmap_update_bits(arizona->regmap,
480  ARIZONA_IN1L_CONTROL + (i * 8),
482  ARIZONA_IN1_MODE_MASK, val);
483  }
484 
485  for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
486  /* Default is 0 so noop with defaults */
487  if (arizona->pdata.out_mono[i])
488  val = ARIZONA_OUT1_MONO;
489  else
490  val = 0;
491 
492  regmap_update_bits(arizona->regmap,
494  ARIZONA_OUT1_MONO, val);
495  }
496 
497  for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
498  if (arizona->pdata.spk_mute[i])
499  regmap_update_bits(arizona->regmap,
500  ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
503  arizona->pdata.spk_mute[i]);
504 
505  if (arizona->pdata.spk_fmt[i])
506  regmap_update_bits(arizona->regmap,
507  ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
509  arizona->pdata.spk_fmt[i]);
510  }
511 
512  /* Set up for interrupts */
513  ret = arizona_irq_init(arizona);
514  if (ret != 0)
515  goto err_reset;
516 
517  arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
518  arizona_clkgen_err, arizona);
519  arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
520  arizona_overclocked, arizona);
521  arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
522  arizona_underclocked, arizona);
523 
524  switch (arizona->type) {
525  case WM5102:
526  ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
527  ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
528  break;
529  case WM5110:
530  ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
531  ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
532  break;
533  }
534 
535  if (ret != 0) {
536  dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
537  goto err_irq;
538  }
539 
540 #ifdef CONFIG_PM_RUNTIME
541  regulator_disable(arizona->dcvdd);
542 #endif
543 
544  return 0;
545 
546 err_irq:
547  arizona_irq_exit(arizona);
548 err_reset:
549  if (arizona->pdata.reset) {
550  gpio_set_value_cansleep(arizona->pdata.reset, 1);
551  gpio_free(arizona->pdata.reset);
552  }
553 err_dcvdd:
554  regulator_disable(arizona->dcvdd);
555 err_enable:
557  arizona->core_supplies);
558 err_early:
559  mfd_remove_devices(dev);
560  return ret;
561 }
563 
564 int __devexit arizona_dev_exit(struct arizona *arizona)
565 {
566  mfd_remove_devices(arizona->dev);
567  arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
568  arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
569  arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
570  pm_runtime_disable(arizona->dev);
571  arizona_irq_exit(arizona);
572  return 0;
573 }