Merge tag 'pci-v3.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa...
[deliverable/linux.git] / sound / soc / codecs / arizona.c
1 /*
2 * arizona.c - Wolfson Arizona class device shared support
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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/gcd.h>
15 #include <linux/module.h>
16 #include <linux/pm_runtime.h>
17 #include <sound/pcm.h>
18 #include <sound/pcm_params.h>
19 #include <sound/tlv.h>
20
21 #include <linux/mfd/arizona/core.h>
22 #include <linux/mfd/arizona/gpio.h>
23 #include <linux/mfd/arizona/registers.h>
24
25 #include "arizona.h"
26
27 #define ARIZONA_AIF_BCLK_CTRL 0x00
28 #define ARIZONA_AIF_TX_PIN_CTRL 0x01
29 #define ARIZONA_AIF_RX_PIN_CTRL 0x02
30 #define ARIZONA_AIF_RATE_CTRL 0x03
31 #define ARIZONA_AIF_FORMAT 0x04
32 #define ARIZONA_AIF_TX_BCLK_RATE 0x05
33 #define ARIZONA_AIF_RX_BCLK_RATE 0x06
34 #define ARIZONA_AIF_FRAME_CTRL_1 0x07
35 #define ARIZONA_AIF_FRAME_CTRL_2 0x08
36 #define ARIZONA_AIF_FRAME_CTRL_3 0x09
37 #define ARIZONA_AIF_FRAME_CTRL_4 0x0A
38 #define ARIZONA_AIF_FRAME_CTRL_5 0x0B
39 #define ARIZONA_AIF_FRAME_CTRL_6 0x0C
40 #define ARIZONA_AIF_FRAME_CTRL_7 0x0D
41 #define ARIZONA_AIF_FRAME_CTRL_8 0x0E
42 #define ARIZONA_AIF_FRAME_CTRL_9 0x0F
43 #define ARIZONA_AIF_FRAME_CTRL_10 0x10
44 #define ARIZONA_AIF_FRAME_CTRL_11 0x11
45 #define ARIZONA_AIF_FRAME_CTRL_12 0x12
46 #define ARIZONA_AIF_FRAME_CTRL_13 0x13
47 #define ARIZONA_AIF_FRAME_CTRL_14 0x14
48 #define ARIZONA_AIF_FRAME_CTRL_15 0x15
49 #define ARIZONA_AIF_FRAME_CTRL_16 0x16
50 #define ARIZONA_AIF_FRAME_CTRL_17 0x17
51 #define ARIZONA_AIF_FRAME_CTRL_18 0x18
52 #define ARIZONA_AIF_TX_ENABLES 0x19
53 #define ARIZONA_AIF_RX_ENABLES 0x1A
54 #define ARIZONA_AIF_FORCE_WRITE 0x1B
55
56 #define arizona_fll_err(_fll, fmt, ...) \
57 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58 #define arizona_fll_warn(_fll, fmt, ...) \
59 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60 #define arizona_fll_dbg(_fll, fmt, ...) \
61 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
62
63 #define arizona_aif_err(_dai, fmt, ...) \
64 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65 #define arizona_aif_warn(_dai, fmt, ...) \
66 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 #define arizona_aif_dbg(_dai, fmt, ...) \
68 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
69
70 static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
71 struct snd_kcontrol *kcontrol,
72 int event)
73 {
74 struct snd_soc_codec *codec = w->codec;
75 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
76 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
77 bool manual_ena = false;
78 int val;
79
80 switch (arizona->type) {
81 case WM5102:
82 switch (arizona->rev) {
83 case 0:
84 break;
85 default:
86 manual_ena = true;
87 break;
88 }
89 default:
90 break;
91 }
92
93 switch (event) {
94 case SND_SOC_DAPM_PRE_PMU:
95 if (!priv->spk_ena && manual_ena) {
96 regmap_write_async(arizona->regmap, 0x4f5, 0x25a);
97 priv->spk_ena_pending = true;
98 }
99 break;
100 case SND_SOC_DAPM_POST_PMU:
101 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
102 if (val & ARIZONA_SPK_SHUTDOWN_STS) {
103 dev_crit(arizona->dev,
104 "Speaker not enabled due to temperature\n");
105 return -EBUSY;
106 }
107
108 regmap_update_bits_async(arizona->regmap,
109 ARIZONA_OUTPUT_ENABLES_1,
110 1 << w->shift, 1 << w->shift);
111
112 if (priv->spk_ena_pending) {
113 msleep(75);
114 regmap_write_async(arizona->regmap, 0x4f5, 0xda);
115 priv->spk_ena_pending = false;
116 priv->spk_ena++;
117 }
118 break;
119 case SND_SOC_DAPM_PRE_PMD:
120 if (manual_ena) {
121 priv->spk_ena--;
122 if (!priv->spk_ena)
123 regmap_write_async(arizona->regmap,
124 0x4f5, 0x25a);
125 }
126
127 regmap_update_bits_async(arizona->regmap,
128 ARIZONA_OUTPUT_ENABLES_1,
129 1 << w->shift, 0);
130 break;
131 case SND_SOC_DAPM_POST_PMD:
132 if (manual_ena) {
133 if (!priv->spk_ena)
134 regmap_write_async(arizona->regmap,
135 0x4f5, 0x0da);
136 }
137 break;
138 }
139
140 return 0;
141 }
142
143 static irqreturn_t arizona_thermal_warn(int irq, void *data)
144 {
145 struct arizona *arizona = data;
146 unsigned int val;
147 int ret;
148
149 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
150 &val);
151 if (ret != 0) {
152 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
153 ret);
154 } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
155 dev_crit(arizona->dev, "Thermal warning\n");
156 }
157
158 return IRQ_HANDLED;
159 }
160
161 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
162 {
163 struct arizona *arizona = data;
164 unsigned int val;
165 int ret;
166
167 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
168 &val);
169 if (ret != 0) {
170 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
171 ret);
172 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
173 dev_crit(arizona->dev, "Thermal shutdown\n");
174 ret = regmap_update_bits(arizona->regmap,
175 ARIZONA_OUTPUT_ENABLES_1,
176 ARIZONA_OUT4L_ENA |
177 ARIZONA_OUT4R_ENA, 0);
178 if (ret != 0)
179 dev_crit(arizona->dev,
180 "Failed to disable speaker outputs: %d\n",
181 ret);
182 }
183
184 return IRQ_HANDLED;
185 }
186
187 static const struct snd_soc_dapm_widget arizona_spkl =
188 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
189 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
190 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
191
192 static const struct snd_soc_dapm_widget arizona_spkr =
193 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
194 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
195 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
196
197 int arizona_init_spk(struct snd_soc_codec *codec)
198 {
199 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
200 struct arizona *arizona = priv->arizona;
201 int ret;
202
203 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
204 if (ret != 0)
205 return ret;
206
207 switch (arizona->type) {
208 case WM8997:
209 break;
210 default:
211 ret = snd_soc_dapm_new_controls(&codec->dapm,
212 &arizona_spkr, 1);
213 if (ret != 0)
214 return ret;
215 break;
216 }
217
218 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
219 "Thermal warning", arizona_thermal_warn,
220 arizona);
221 if (ret != 0)
222 dev_err(arizona->dev,
223 "Failed to get thermal warning IRQ: %d\n",
224 ret);
225
226 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
227 "Thermal shutdown", arizona_thermal_shutdown,
228 arizona);
229 if (ret != 0)
230 dev_err(arizona->dev,
231 "Failed to get thermal shutdown IRQ: %d\n",
232 ret);
233
234 return 0;
235 }
236 EXPORT_SYMBOL_GPL(arizona_init_spk);
237
238 int arizona_init_gpio(struct snd_soc_codec *codec)
239 {
240 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
241 struct arizona *arizona = priv->arizona;
242 int i;
243
244 switch (arizona->type) {
245 case WM5110:
246 snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
247 break;
248 default:
249 break;
250 }
251
252 snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
253
254 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
255 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
256 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
257 snd_soc_dapm_enable_pin(&codec->dapm,
258 "DRC1 Signal Activity");
259 break;
260 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
261 snd_soc_dapm_enable_pin(&codec->dapm,
262 "DRC2 Signal Activity");
263 break;
264 default:
265 break;
266 }
267 }
268
269 return 0;
270 }
271 EXPORT_SYMBOL_GPL(arizona_init_gpio);
272
273 const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
274 "None",
275 "Tone Generator 1",
276 "Tone Generator 2",
277 "Haptics",
278 "AEC",
279 "Mic Mute Mixer",
280 "Noise Generator",
281 "IN1L",
282 "IN1R",
283 "IN2L",
284 "IN2R",
285 "IN3L",
286 "IN3R",
287 "IN4L",
288 "IN4R",
289 "AIF1RX1",
290 "AIF1RX2",
291 "AIF1RX3",
292 "AIF1RX4",
293 "AIF1RX5",
294 "AIF1RX6",
295 "AIF1RX7",
296 "AIF1RX8",
297 "AIF2RX1",
298 "AIF2RX2",
299 "AIF2RX3",
300 "AIF2RX4",
301 "AIF2RX5",
302 "AIF2RX6",
303 "AIF3RX1",
304 "AIF3RX2",
305 "SLIMRX1",
306 "SLIMRX2",
307 "SLIMRX3",
308 "SLIMRX4",
309 "SLIMRX5",
310 "SLIMRX6",
311 "SLIMRX7",
312 "SLIMRX8",
313 "EQ1",
314 "EQ2",
315 "EQ3",
316 "EQ4",
317 "DRC1L",
318 "DRC1R",
319 "DRC2L",
320 "DRC2R",
321 "LHPF1",
322 "LHPF2",
323 "LHPF3",
324 "LHPF4",
325 "DSP1.1",
326 "DSP1.2",
327 "DSP1.3",
328 "DSP1.4",
329 "DSP1.5",
330 "DSP1.6",
331 "DSP2.1",
332 "DSP2.2",
333 "DSP2.3",
334 "DSP2.4",
335 "DSP2.5",
336 "DSP2.6",
337 "DSP3.1",
338 "DSP3.2",
339 "DSP3.3",
340 "DSP3.4",
341 "DSP3.5",
342 "DSP3.6",
343 "DSP4.1",
344 "DSP4.2",
345 "DSP4.3",
346 "DSP4.4",
347 "DSP4.5",
348 "DSP4.6",
349 "ASRC1L",
350 "ASRC1R",
351 "ASRC2L",
352 "ASRC2R",
353 "ISRC1INT1",
354 "ISRC1INT2",
355 "ISRC1INT3",
356 "ISRC1INT4",
357 "ISRC1DEC1",
358 "ISRC1DEC2",
359 "ISRC1DEC3",
360 "ISRC1DEC4",
361 "ISRC2INT1",
362 "ISRC2INT2",
363 "ISRC2INT3",
364 "ISRC2INT4",
365 "ISRC2DEC1",
366 "ISRC2DEC2",
367 "ISRC2DEC3",
368 "ISRC2DEC4",
369 "ISRC3INT1",
370 "ISRC3INT2",
371 "ISRC3INT3",
372 "ISRC3INT4",
373 "ISRC3DEC1",
374 "ISRC3DEC2",
375 "ISRC3DEC3",
376 "ISRC3DEC4",
377 };
378 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
379
380 int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
381 0x00, /* None */
382 0x04, /* Tone */
383 0x05,
384 0x06, /* Haptics */
385 0x08, /* AEC */
386 0x0c, /* Noise mixer */
387 0x0d, /* Comfort noise */
388 0x10, /* IN1L */
389 0x11,
390 0x12,
391 0x13,
392 0x14,
393 0x15,
394 0x16,
395 0x17,
396 0x20, /* AIF1RX1 */
397 0x21,
398 0x22,
399 0x23,
400 0x24,
401 0x25,
402 0x26,
403 0x27,
404 0x28, /* AIF2RX1 */
405 0x29,
406 0x2a,
407 0x2b,
408 0x2c,
409 0x2d,
410 0x30, /* AIF3RX1 */
411 0x31,
412 0x38, /* SLIMRX1 */
413 0x39,
414 0x3a,
415 0x3b,
416 0x3c,
417 0x3d,
418 0x3e,
419 0x3f,
420 0x50, /* EQ1 */
421 0x51,
422 0x52,
423 0x53,
424 0x58, /* DRC1L */
425 0x59,
426 0x5a,
427 0x5b,
428 0x60, /* LHPF1 */
429 0x61,
430 0x62,
431 0x63,
432 0x68, /* DSP1.1 */
433 0x69,
434 0x6a,
435 0x6b,
436 0x6c,
437 0x6d,
438 0x70, /* DSP2.1 */
439 0x71,
440 0x72,
441 0x73,
442 0x74,
443 0x75,
444 0x78, /* DSP3.1 */
445 0x79,
446 0x7a,
447 0x7b,
448 0x7c,
449 0x7d,
450 0x80, /* DSP4.1 */
451 0x81,
452 0x82,
453 0x83,
454 0x84,
455 0x85,
456 0x90, /* ASRC1L */
457 0x91,
458 0x92,
459 0x93,
460 0xa0, /* ISRC1INT1 */
461 0xa1,
462 0xa2,
463 0xa3,
464 0xa4, /* ISRC1DEC1 */
465 0xa5,
466 0xa6,
467 0xa7,
468 0xa8, /* ISRC2DEC1 */
469 0xa9,
470 0xaa,
471 0xab,
472 0xac, /* ISRC2INT1 */
473 0xad,
474 0xae,
475 0xaf,
476 0xb0, /* ISRC3DEC1 */
477 0xb1,
478 0xb2,
479 0xb3,
480 0xb4, /* ISRC3INT1 */
481 0xb5,
482 0xb6,
483 0xb7,
484 };
485 EXPORT_SYMBOL_GPL(arizona_mixer_values);
486
487 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
488 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
489
490 const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
491 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
492 };
493 EXPORT_SYMBOL_GPL(arizona_rate_text);
494
495 const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
496 0, 1, 2, 8,
497 };
498 EXPORT_SYMBOL_GPL(arizona_rate_val);
499
500
501 const struct soc_enum arizona_isrc_fsh[] = {
502 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
503 ARIZONA_ISRC1_FSH_SHIFT, 0xf,
504 ARIZONA_RATE_ENUM_SIZE,
505 arizona_rate_text, arizona_rate_val),
506 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
507 ARIZONA_ISRC2_FSH_SHIFT, 0xf,
508 ARIZONA_RATE_ENUM_SIZE,
509 arizona_rate_text, arizona_rate_val),
510 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
511 ARIZONA_ISRC3_FSH_SHIFT, 0xf,
512 ARIZONA_RATE_ENUM_SIZE,
513 arizona_rate_text, arizona_rate_val),
514 };
515 EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
516
517 const struct soc_enum arizona_isrc_fsl[] = {
518 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
519 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
520 ARIZONA_RATE_ENUM_SIZE,
521 arizona_rate_text, arizona_rate_val),
522 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
523 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
524 ARIZONA_RATE_ENUM_SIZE,
525 arizona_rate_text, arizona_rate_val),
526 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
527 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
528 ARIZONA_RATE_ENUM_SIZE,
529 arizona_rate_text, arizona_rate_val),
530 };
531 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
532
533 const struct soc_enum arizona_asrc_rate1 =
534 SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
535 ARIZONA_ASRC_RATE1_SHIFT, 0xf,
536 ARIZONA_RATE_ENUM_SIZE - 1,
537 arizona_rate_text, arizona_rate_val);
538 EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
539
540 static const char *arizona_vol_ramp_text[] = {
541 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
542 "15ms/6dB", "30ms/6dB",
543 };
544
545 const struct soc_enum arizona_in_vd_ramp =
546 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
547 ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
548 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
549
550 const struct soc_enum arizona_in_vi_ramp =
551 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
552 ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
553 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
554
555 const struct soc_enum arizona_out_vd_ramp =
556 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
557 ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
558 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
559
560 const struct soc_enum arizona_out_vi_ramp =
561 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
562 ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
563 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
564
565 static const char *arizona_lhpf_mode_text[] = {
566 "Low-pass", "High-pass"
567 };
568
569 const struct soc_enum arizona_lhpf1_mode =
570 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
571 arizona_lhpf_mode_text);
572 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
573
574 const struct soc_enum arizona_lhpf2_mode =
575 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
576 arizona_lhpf_mode_text);
577 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
578
579 const struct soc_enum arizona_lhpf3_mode =
580 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
581 arizona_lhpf_mode_text);
582 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
583
584 const struct soc_enum arizona_lhpf4_mode =
585 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
586 arizona_lhpf_mode_text);
587 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
588
589 static const char *arizona_ng_hold_text[] = {
590 "30ms", "120ms", "250ms", "500ms",
591 };
592
593 const struct soc_enum arizona_ng_hold =
594 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
595 4, arizona_ng_hold_text);
596 EXPORT_SYMBOL_GPL(arizona_ng_hold);
597
598 static const char * const arizona_in_hpf_cut_text[] = {
599 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
600 };
601
602 const struct soc_enum arizona_in_hpf_cut_enum =
603 SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT,
604 ARRAY_SIZE(arizona_in_hpf_cut_text),
605 arizona_in_hpf_cut_text);
606 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
607
608 static const char * const arizona_in_dmic_osr_text[] = {
609 "1.536MHz", "3.072MHz", "6.144MHz",
610 };
611
612 const struct soc_enum arizona_in_dmic_osr[] = {
613 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
614 ARRAY_SIZE(arizona_in_dmic_osr_text),
615 arizona_in_dmic_osr_text),
616 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
617 ARRAY_SIZE(arizona_in_dmic_osr_text),
618 arizona_in_dmic_osr_text),
619 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
620 ARRAY_SIZE(arizona_in_dmic_osr_text),
621 arizona_in_dmic_osr_text),
622 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
623 ARRAY_SIZE(arizona_in_dmic_osr_text),
624 arizona_in_dmic_osr_text),
625 };
626 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
627
628 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
629 {
630 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
631 unsigned int val;
632 int i;
633
634 if (ena)
635 val = ARIZONA_IN_VU;
636 else
637 val = 0;
638
639 for (i = 0; i < priv->num_inputs; i++)
640 snd_soc_update_bits(codec,
641 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
642 ARIZONA_IN_VU, val);
643 }
644
645 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
646 int event)
647 {
648 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
649 unsigned int reg;
650
651 if (w->shift % 2)
652 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
653 else
654 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
655
656 switch (event) {
657 case SND_SOC_DAPM_PRE_PMU:
658 priv->in_pending++;
659 break;
660 case SND_SOC_DAPM_POST_PMU:
661 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
662
663 /* If this is the last input pending then allow VU */
664 priv->in_pending--;
665 if (priv->in_pending == 0) {
666 msleep(1);
667 arizona_in_set_vu(w->codec, 1);
668 }
669 break;
670 case SND_SOC_DAPM_PRE_PMD:
671 snd_soc_update_bits(w->codec, reg,
672 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
673 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
674 break;
675 case SND_SOC_DAPM_POST_PMD:
676 /* Disable volume updates if no inputs are enabled */
677 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
678 if (reg == 0)
679 arizona_in_set_vu(w->codec, 0);
680 }
681
682 return 0;
683 }
684 EXPORT_SYMBOL_GPL(arizona_in_ev);
685
686 int arizona_out_ev(struct snd_soc_dapm_widget *w,
687 struct snd_kcontrol *kcontrol,
688 int event)
689 {
690 switch (event) {
691 case SND_SOC_DAPM_POST_PMU:
692 switch (w->shift) {
693 case ARIZONA_OUT1L_ENA_SHIFT:
694 case ARIZONA_OUT1R_ENA_SHIFT:
695 case ARIZONA_OUT2L_ENA_SHIFT:
696 case ARIZONA_OUT2R_ENA_SHIFT:
697 case ARIZONA_OUT3L_ENA_SHIFT:
698 case ARIZONA_OUT3R_ENA_SHIFT:
699 msleep(17);
700 break;
701
702 default:
703 break;
704 }
705 break;
706 }
707
708 return 0;
709 }
710 EXPORT_SYMBOL_GPL(arizona_out_ev);
711
712 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
713 struct snd_kcontrol *kcontrol,
714 int event)
715 {
716 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
717 struct arizona *arizona = priv->arizona;
718 unsigned int mask = 1 << w->shift;
719 unsigned int val;
720
721 switch (event) {
722 case SND_SOC_DAPM_POST_PMU:
723 val = mask;
724 break;
725 case SND_SOC_DAPM_PRE_PMD:
726 val = 0;
727 break;
728 default:
729 return -EINVAL;
730 }
731
732 /* Store the desired state for the HP outputs */
733 priv->arizona->hp_ena &= ~mask;
734 priv->arizona->hp_ena |= val;
735
736 /* Force off if HPDET magic is active */
737 if (priv->arizona->hpdet_magic)
738 val = 0;
739
740 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
741 mask, val);
742
743 return arizona_out_ev(w, kcontrol, event);
744 }
745 EXPORT_SYMBOL_GPL(arizona_hp_ev);
746
747 static unsigned int arizona_sysclk_48k_rates[] = {
748 6144000,
749 12288000,
750 24576000,
751 49152000,
752 73728000,
753 98304000,
754 147456000,
755 };
756
757 static unsigned int arizona_sysclk_44k1_rates[] = {
758 5644800,
759 11289600,
760 22579200,
761 45158400,
762 67737600,
763 90316800,
764 135475200,
765 };
766
767 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
768 unsigned int freq)
769 {
770 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
771 unsigned int reg;
772 unsigned int *rates;
773 int ref, div, refclk;
774
775 switch (clk) {
776 case ARIZONA_CLK_OPCLK:
777 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
778 refclk = priv->sysclk;
779 break;
780 case ARIZONA_CLK_ASYNC_OPCLK:
781 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
782 refclk = priv->asyncclk;
783 break;
784 default:
785 return -EINVAL;
786 }
787
788 if (refclk % 8000)
789 rates = arizona_sysclk_44k1_rates;
790 else
791 rates = arizona_sysclk_48k_rates;
792
793 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
794 rates[ref] <= refclk; ref++) {
795 div = 1;
796 while (rates[ref] / div >= freq && div < 32) {
797 if (rates[ref] / div == freq) {
798 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
799 freq);
800 snd_soc_update_bits(codec, reg,
801 ARIZONA_OPCLK_DIV_MASK |
802 ARIZONA_OPCLK_SEL_MASK,
803 (div <<
804 ARIZONA_OPCLK_DIV_SHIFT) |
805 ref);
806 return 0;
807 }
808 div++;
809 }
810 }
811
812 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
813 return -EINVAL;
814 }
815
816 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
817 int source, unsigned int freq, int dir)
818 {
819 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
820 struct arizona *arizona = priv->arizona;
821 char *name;
822 unsigned int reg;
823 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
824 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
825 unsigned int *clk;
826
827 switch (clk_id) {
828 case ARIZONA_CLK_SYSCLK:
829 name = "SYSCLK";
830 reg = ARIZONA_SYSTEM_CLOCK_1;
831 clk = &priv->sysclk;
832 mask |= ARIZONA_SYSCLK_FRAC;
833 break;
834 case ARIZONA_CLK_ASYNCCLK:
835 name = "ASYNCCLK";
836 reg = ARIZONA_ASYNC_CLOCK_1;
837 clk = &priv->asyncclk;
838 break;
839 case ARIZONA_CLK_OPCLK:
840 case ARIZONA_CLK_ASYNC_OPCLK:
841 return arizona_set_opclk(codec, clk_id, freq);
842 default:
843 return -EINVAL;
844 }
845
846 switch (freq) {
847 case 5644800:
848 case 6144000:
849 break;
850 case 11289600:
851 case 12288000:
852 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
853 break;
854 case 22579200:
855 case 24576000:
856 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
857 break;
858 case 45158400:
859 case 49152000:
860 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
861 break;
862 case 67737600:
863 case 73728000:
864 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
865 break;
866 case 90316800:
867 case 98304000:
868 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
869 break;
870 case 135475200:
871 case 147456000:
872 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
873 break;
874 case 0:
875 dev_dbg(arizona->dev, "%s cleared\n", name);
876 *clk = freq;
877 return 0;
878 default:
879 return -EINVAL;
880 }
881
882 *clk = freq;
883
884 if (freq % 6144000)
885 val |= ARIZONA_SYSCLK_FRAC;
886
887 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
888
889 return regmap_update_bits(arizona->regmap, reg, mask, val);
890 }
891 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
892
893 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
894 {
895 struct snd_soc_codec *codec = dai->codec;
896 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
897 struct arizona *arizona = priv->arizona;
898 int lrclk, bclk, mode, base;
899
900 base = dai->driver->base;
901
902 lrclk = 0;
903 bclk = 0;
904
905 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
906 case SND_SOC_DAIFMT_DSP_A:
907 mode = 0;
908 break;
909 case SND_SOC_DAIFMT_I2S:
910 mode = 2;
911 break;
912 default:
913 arizona_aif_err(dai, "Unsupported DAI format %d\n",
914 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
915 return -EINVAL;
916 }
917
918 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
919 case SND_SOC_DAIFMT_CBS_CFS:
920 break;
921 case SND_SOC_DAIFMT_CBS_CFM:
922 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
923 break;
924 case SND_SOC_DAIFMT_CBM_CFS:
925 bclk |= ARIZONA_AIF1_BCLK_MSTR;
926 break;
927 case SND_SOC_DAIFMT_CBM_CFM:
928 bclk |= ARIZONA_AIF1_BCLK_MSTR;
929 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
930 break;
931 default:
932 arizona_aif_err(dai, "Unsupported master mode %d\n",
933 fmt & SND_SOC_DAIFMT_MASTER_MASK);
934 return -EINVAL;
935 }
936
937 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
938 case SND_SOC_DAIFMT_NB_NF:
939 break;
940 case SND_SOC_DAIFMT_IB_IF:
941 bclk |= ARIZONA_AIF1_BCLK_INV;
942 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
943 break;
944 case SND_SOC_DAIFMT_IB_NF:
945 bclk |= ARIZONA_AIF1_BCLK_INV;
946 break;
947 case SND_SOC_DAIFMT_NB_IF:
948 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
949 break;
950 default:
951 return -EINVAL;
952 }
953
954 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
955 ARIZONA_AIF1_BCLK_INV |
956 ARIZONA_AIF1_BCLK_MSTR,
957 bclk);
958 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
959 ARIZONA_AIF1TX_LRCLK_INV |
960 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
961 regmap_update_bits_async(arizona->regmap,
962 base + ARIZONA_AIF_RX_PIN_CTRL,
963 ARIZONA_AIF1RX_LRCLK_INV |
964 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
965 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
966 ARIZONA_AIF1_FMT_MASK, mode);
967
968 return 0;
969 }
970
971 static const int arizona_48k_bclk_rates[] = {
972 -1,
973 48000,
974 64000,
975 96000,
976 128000,
977 192000,
978 256000,
979 384000,
980 512000,
981 768000,
982 1024000,
983 1536000,
984 2048000,
985 3072000,
986 4096000,
987 6144000,
988 8192000,
989 12288000,
990 24576000,
991 };
992
993 static const unsigned int arizona_48k_rates[] = {
994 12000,
995 24000,
996 48000,
997 96000,
998 192000,
999 384000,
1000 768000,
1001 4000,
1002 8000,
1003 16000,
1004 32000,
1005 64000,
1006 128000,
1007 256000,
1008 512000,
1009 };
1010
1011 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
1012 .count = ARRAY_SIZE(arizona_48k_rates),
1013 .list = arizona_48k_rates,
1014 };
1015
1016 static const int arizona_44k1_bclk_rates[] = {
1017 -1,
1018 44100,
1019 58800,
1020 88200,
1021 117600,
1022 177640,
1023 235200,
1024 352800,
1025 470400,
1026 705600,
1027 940800,
1028 1411200,
1029 1881600,
1030 2822400,
1031 3763200,
1032 5644800,
1033 7526400,
1034 11289600,
1035 22579200,
1036 };
1037
1038 static const unsigned int arizona_44k1_rates[] = {
1039 11025,
1040 22050,
1041 44100,
1042 88200,
1043 176400,
1044 352800,
1045 705600,
1046 };
1047
1048 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
1049 .count = ARRAY_SIZE(arizona_44k1_rates),
1050 .list = arizona_44k1_rates,
1051 };
1052
1053 static int arizona_sr_vals[] = {
1054 0,
1055 12000,
1056 24000,
1057 48000,
1058 96000,
1059 192000,
1060 384000,
1061 768000,
1062 0,
1063 11025,
1064 22050,
1065 44100,
1066 88200,
1067 176400,
1068 352800,
1069 705600,
1070 4000,
1071 8000,
1072 16000,
1073 32000,
1074 64000,
1075 128000,
1076 256000,
1077 512000,
1078 };
1079
1080 static int arizona_startup(struct snd_pcm_substream *substream,
1081 struct snd_soc_dai *dai)
1082 {
1083 struct snd_soc_codec *codec = dai->codec;
1084 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1085 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1086 const struct snd_pcm_hw_constraint_list *constraint;
1087 unsigned int base_rate;
1088
1089 switch (dai_priv->clk) {
1090 case ARIZONA_CLK_SYSCLK:
1091 base_rate = priv->sysclk;
1092 break;
1093 case ARIZONA_CLK_ASYNCCLK:
1094 base_rate = priv->asyncclk;
1095 break;
1096 default:
1097 return 0;
1098 }
1099
1100 if (base_rate == 0)
1101 return 0;
1102
1103 if (base_rate % 8000)
1104 constraint = &arizona_44k1_constraint;
1105 else
1106 constraint = &arizona_48k_constraint;
1107
1108 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1109 SNDRV_PCM_HW_PARAM_RATE,
1110 constraint);
1111 }
1112
1113 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1114 struct snd_pcm_hw_params *params,
1115 struct snd_soc_dai *dai)
1116 {
1117 struct snd_soc_codec *codec = dai->codec;
1118 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1119 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1120 int base = dai->driver->base;
1121 int i, sr_val;
1122
1123 /*
1124 * We will need to be more flexible than this in future,
1125 * currently we use a single sample rate for SYSCLK.
1126 */
1127 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1128 if (arizona_sr_vals[i] == params_rate(params))
1129 break;
1130 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1131 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1132 params_rate(params));
1133 return -EINVAL;
1134 }
1135 sr_val = i;
1136
1137 switch (dai_priv->clk) {
1138 case ARIZONA_CLK_SYSCLK:
1139 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1140 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1141 if (base)
1142 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1143 ARIZONA_AIF1_RATE_MASK, 0);
1144 break;
1145 case ARIZONA_CLK_ASYNCCLK:
1146 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1147 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
1148 if (base)
1149 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1150 ARIZONA_AIF1_RATE_MASK,
1151 8 << ARIZONA_AIF1_RATE_SHIFT);
1152 break;
1153 default:
1154 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1155 return -EINVAL;
1156 }
1157
1158 return 0;
1159 }
1160
1161 static int arizona_hw_params(struct snd_pcm_substream *substream,
1162 struct snd_pcm_hw_params *params,
1163 struct snd_soc_dai *dai)
1164 {
1165 struct snd_soc_codec *codec = dai->codec;
1166 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1167 struct arizona *arizona = priv->arizona;
1168 int base = dai->driver->base;
1169 const int *rates;
1170 int i, ret, val;
1171 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1172 int bclk, lrclk, wl, frame, bclk_target;
1173
1174 if (params_rate(params) % 8000)
1175 rates = &arizona_44k1_bclk_rates[0];
1176 else
1177 rates = &arizona_48k_bclk_rates[0];
1178
1179 bclk_target = snd_soc_params_to_bclk(params);
1180 if (chan_limit && chan_limit < params_channels(params)) {
1181 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1182 bclk_target /= params_channels(params);
1183 bclk_target *= chan_limit;
1184 }
1185
1186 /* Force stereo for I2S mode */
1187 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1188 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1189 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1190 bclk_target *= 2;
1191 }
1192
1193 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1194 if (rates[i] >= bclk_target &&
1195 rates[i] % params_rate(params) == 0) {
1196 bclk = i;
1197 break;
1198 }
1199 }
1200 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1201 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1202 params_rate(params));
1203 return -EINVAL;
1204 }
1205
1206 lrclk = rates[bclk] / params_rate(params);
1207
1208 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1209 rates[bclk], rates[bclk] / lrclk);
1210
1211 wl = snd_pcm_format_width(params_format(params));
1212 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
1213
1214 ret = arizona_hw_params_rate(substream, params, dai);
1215 if (ret != 0)
1216 return ret;
1217
1218 regmap_update_bits_async(arizona->regmap,
1219 base + ARIZONA_AIF_BCLK_CTRL,
1220 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1221 regmap_update_bits_async(arizona->regmap,
1222 base + ARIZONA_AIF_TX_BCLK_RATE,
1223 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1224 regmap_update_bits_async(arizona->regmap,
1225 base + ARIZONA_AIF_RX_BCLK_RATE,
1226 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1227 regmap_update_bits_async(arizona->regmap,
1228 base + ARIZONA_AIF_FRAME_CTRL_1,
1229 ARIZONA_AIF1TX_WL_MASK |
1230 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1231 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2,
1232 ARIZONA_AIF1RX_WL_MASK |
1233 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1234
1235 return 0;
1236 }
1237
1238 static const char *arizona_dai_clk_str(int clk_id)
1239 {
1240 switch (clk_id) {
1241 case ARIZONA_CLK_SYSCLK:
1242 return "SYSCLK";
1243 case ARIZONA_CLK_ASYNCCLK:
1244 return "ASYNCCLK";
1245 default:
1246 return "Unknown clock";
1247 }
1248 }
1249
1250 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1251 int clk_id, unsigned int freq, int dir)
1252 {
1253 struct snd_soc_codec *codec = dai->codec;
1254 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1255 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1256 struct snd_soc_dapm_route routes[2];
1257
1258 switch (clk_id) {
1259 case ARIZONA_CLK_SYSCLK:
1260 case ARIZONA_CLK_ASYNCCLK:
1261 break;
1262 default:
1263 return -EINVAL;
1264 }
1265
1266 if (clk_id == dai_priv->clk)
1267 return 0;
1268
1269 if (dai->active) {
1270 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1271 dai->id);
1272 return -EBUSY;
1273 }
1274
1275 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1276 arizona_dai_clk_str(clk_id));
1277
1278 memset(&routes, 0, sizeof(routes));
1279 routes[0].sink = dai->driver->capture.stream_name;
1280 routes[1].sink = dai->driver->playback.stream_name;
1281
1282 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1283 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1284 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1285
1286 routes[0].source = arizona_dai_clk_str(clk_id);
1287 routes[1].source = arizona_dai_clk_str(clk_id);
1288 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1289
1290 dai_priv->clk = clk_id;
1291
1292 return snd_soc_dapm_sync(&codec->dapm);
1293 }
1294
1295 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1296 {
1297 struct snd_soc_codec *codec = dai->codec;
1298 int base = dai->driver->base;
1299 unsigned int reg;
1300
1301 if (tristate)
1302 reg = ARIZONA_AIF1_TRI;
1303 else
1304 reg = 0;
1305
1306 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1307 ARIZONA_AIF1_TRI, reg);
1308 }
1309
1310 const struct snd_soc_dai_ops arizona_dai_ops = {
1311 .startup = arizona_startup,
1312 .set_fmt = arizona_set_fmt,
1313 .hw_params = arizona_hw_params,
1314 .set_sysclk = arizona_dai_set_sysclk,
1315 .set_tristate = arizona_set_tristate,
1316 };
1317 EXPORT_SYMBOL_GPL(arizona_dai_ops);
1318
1319 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1320 .startup = arizona_startup,
1321 .hw_params = arizona_hw_params_rate,
1322 .set_sysclk = arizona_dai_set_sysclk,
1323 };
1324 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1325
1326 int arizona_init_dai(struct arizona_priv *priv, int id)
1327 {
1328 struct arizona_dai_priv *dai_priv = &priv->dai[id];
1329
1330 dai_priv->clk = ARIZONA_CLK_SYSCLK;
1331
1332 return 0;
1333 }
1334 EXPORT_SYMBOL_GPL(arizona_init_dai);
1335
1336 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
1337 {
1338 struct arizona_fll *fll = data;
1339
1340 arizona_fll_dbg(fll, "clock OK\n");
1341
1342 complete(&fll->ok);
1343
1344 return IRQ_HANDLED;
1345 }
1346
1347 static struct {
1348 unsigned int min;
1349 unsigned int max;
1350 u16 fratio;
1351 int ratio;
1352 } fll_fratios[] = {
1353 { 0, 64000, 4, 16 },
1354 { 64000, 128000, 3, 8 },
1355 { 128000, 256000, 2, 4 },
1356 { 256000, 1000000, 1, 2 },
1357 { 1000000, 13500000, 0, 1 },
1358 };
1359
1360 static struct {
1361 unsigned int min;
1362 unsigned int max;
1363 u16 gain;
1364 } fll_gains[] = {
1365 { 0, 256000, 0 },
1366 { 256000, 1000000, 2 },
1367 { 1000000, 13500000, 4 },
1368 };
1369
1370 struct arizona_fll_cfg {
1371 int n;
1372 int theta;
1373 int lambda;
1374 int refdiv;
1375 int outdiv;
1376 int fratio;
1377 int gain;
1378 };
1379
1380 static int arizona_calc_fll(struct arizona_fll *fll,
1381 struct arizona_fll_cfg *cfg,
1382 unsigned int Fref,
1383 unsigned int Fout)
1384 {
1385 unsigned int target, div, gcd_fll;
1386 int i, ratio;
1387
1388 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
1389
1390 /* Fref must be <=13.5MHz */
1391 div = 1;
1392 cfg->refdiv = 0;
1393 while ((Fref / div) > 13500000) {
1394 div *= 2;
1395 cfg->refdiv++;
1396
1397 if (div > 8) {
1398 arizona_fll_err(fll,
1399 "Can't scale %dMHz in to <=13.5MHz\n",
1400 Fref);
1401 return -EINVAL;
1402 }
1403 }
1404
1405 /* Apply the division for our remaining calculations */
1406 Fref /= div;
1407
1408 /* Fvco should be over the targt; don't check the upper bound */
1409 div = 1;
1410 while (Fout * div < 90000000 * fll->vco_mult) {
1411 div++;
1412 if (div > 7) {
1413 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1414 Fout);
1415 return -EINVAL;
1416 }
1417 }
1418 target = Fout * div / fll->vco_mult;
1419 cfg->outdiv = div;
1420
1421 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1422
1423 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1424 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1425 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1426 cfg->fratio = fll_fratios[i].fratio;
1427 ratio = fll_fratios[i].ratio;
1428 break;
1429 }
1430 }
1431 if (i == ARRAY_SIZE(fll_fratios)) {
1432 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1433 Fref);
1434 return -EINVAL;
1435 }
1436
1437 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1438 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1439 cfg->gain = fll_gains[i].gain;
1440 break;
1441 }
1442 }
1443 if (i == ARRAY_SIZE(fll_gains)) {
1444 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1445 Fref);
1446 return -EINVAL;
1447 }
1448
1449 cfg->n = target / (ratio * Fref);
1450
1451 if (target % (ratio * Fref)) {
1452 gcd_fll = gcd(target, ratio * Fref);
1453 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1454
1455 cfg->theta = (target - (cfg->n * ratio * Fref))
1456 / gcd_fll;
1457 cfg->lambda = (ratio * Fref) / gcd_fll;
1458 } else {
1459 cfg->theta = 0;
1460 cfg->lambda = 0;
1461 }
1462
1463 /* Round down to 16bit range with cost of accuracy lost.
1464 * Denominator must be bigger than numerator so we only
1465 * take care of it.
1466 */
1467 while (cfg->lambda >= (1 << 16)) {
1468 cfg->theta >>= 1;
1469 cfg->lambda >>= 1;
1470 }
1471
1472 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1473 cfg->n, cfg->theta, cfg->lambda);
1474 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1475 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1476 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1477
1478 return 0;
1479
1480 }
1481
1482 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1483 struct arizona_fll_cfg *cfg, int source,
1484 bool sync)
1485 {
1486 regmap_update_bits_async(arizona->regmap, base + 3,
1487 ARIZONA_FLL1_THETA_MASK, cfg->theta);
1488 regmap_update_bits_async(arizona->regmap, base + 4,
1489 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1490 regmap_update_bits_async(arizona->regmap, base + 5,
1491 ARIZONA_FLL1_FRATIO_MASK,
1492 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1493 regmap_update_bits_async(arizona->regmap, base + 6,
1494 ARIZONA_FLL1_CLK_REF_DIV_MASK |
1495 ARIZONA_FLL1_CLK_REF_SRC_MASK,
1496 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1497 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1498
1499 if (sync)
1500 regmap_update_bits_async(arizona->regmap, base + 0x7,
1501 ARIZONA_FLL1_GAIN_MASK,
1502 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1503 else
1504 regmap_update_bits_async(arizona->regmap, base + 0x9,
1505 ARIZONA_FLL1_GAIN_MASK,
1506 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1507
1508 regmap_update_bits_async(arizona->regmap, base + 2,
1509 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1510 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1511 }
1512
1513 static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1514 {
1515 struct arizona *arizona = fll->arizona;
1516 unsigned int reg;
1517 int ret;
1518
1519 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1520 if (ret != 0) {
1521 arizona_fll_err(fll, "Failed to read current state: %d\n",
1522 ret);
1523 return ret;
1524 }
1525
1526 return reg & ARIZONA_FLL1_ENA;
1527 }
1528
1529 static void arizona_enable_fll(struct arizona_fll *fll,
1530 struct arizona_fll_cfg *ref,
1531 struct arizona_fll_cfg *sync)
1532 {
1533 struct arizona *arizona = fll->arizona;
1534 int ret;
1535 bool use_sync = false;
1536
1537 /*
1538 * If we have both REFCLK and SYNCCLK then enable both,
1539 * otherwise apply the SYNCCLK settings to REFCLK.
1540 */
1541 if (fll->ref_src >= 0 && fll->ref_freq &&
1542 fll->ref_src != fll->sync_src) {
1543 regmap_update_bits_async(arizona->regmap, fll->base + 5,
1544 ARIZONA_FLL1_OUTDIV_MASK,
1545 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1546
1547 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1548 false);
1549 if (fll->sync_src >= 0) {
1550 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1551 fll->sync_src, true);
1552 use_sync = true;
1553 }
1554 } else if (fll->sync_src >= 0) {
1555 regmap_update_bits_async(arizona->regmap, fll->base + 5,
1556 ARIZONA_FLL1_OUTDIV_MASK,
1557 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1558
1559 arizona_apply_fll(arizona, fll->base, sync,
1560 fll->sync_src, false);
1561
1562 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
1563 ARIZONA_FLL1_SYNC_ENA, 0);
1564 } else {
1565 arizona_fll_err(fll, "No clocks provided\n");
1566 return;
1567 }
1568
1569 /*
1570 * Increase the bandwidth if we're not using a low frequency
1571 * sync source.
1572 */
1573 if (use_sync && fll->sync_freq > 100000)
1574 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
1575 ARIZONA_FLL1_SYNC_BW, 0);
1576 else
1577 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
1578 ARIZONA_FLL1_SYNC_BW,
1579 ARIZONA_FLL1_SYNC_BW);
1580
1581 if (!arizona_is_enabled_fll(fll))
1582 pm_runtime_get(arizona->dev);
1583
1584 /* Clear any pending completions */
1585 try_wait_for_completion(&fll->ok);
1586
1587 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1588 ARIZONA_FLL1_FREERUN, 0);
1589 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1590 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1591 if (use_sync)
1592 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
1593 ARIZONA_FLL1_SYNC_ENA,
1594 ARIZONA_FLL1_SYNC_ENA);
1595
1596 ret = wait_for_completion_timeout(&fll->ok,
1597 msecs_to_jiffies(250));
1598 if (ret == 0)
1599 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1600 }
1601
1602 static void arizona_disable_fll(struct arizona_fll *fll)
1603 {
1604 struct arizona *arizona = fll->arizona;
1605 bool change;
1606
1607 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1608 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
1609 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1610 ARIZONA_FLL1_ENA, 0, &change);
1611 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1612 ARIZONA_FLL1_SYNC_ENA, 0);
1613
1614 if (change)
1615 pm_runtime_put_autosuspend(arizona->dev);
1616 }
1617
1618 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1619 unsigned int Fref, unsigned int Fout)
1620 {
1621 struct arizona_fll_cfg ref, sync;
1622 int ret;
1623
1624 if (fll->ref_src == source && fll->ref_freq == Fref)
1625 return 0;
1626
1627 if (fll->fout) {
1628 if (Fref > 0) {
1629 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1630 if (ret != 0)
1631 return ret;
1632 }
1633
1634 if (fll->sync_src >= 0) {
1635 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1636 fll->fout);
1637 if (ret != 0)
1638 return ret;
1639 }
1640 }
1641
1642 fll->ref_src = source;
1643 fll->ref_freq = Fref;
1644
1645 if (fll->fout && Fref > 0) {
1646 arizona_enable_fll(fll, &ref, &sync);
1647 }
1648
1649 return 0;
1650 }
1651 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1652
1653 int arizona_set_fll(struct arizona_fll *fll, int source,
1654 unsigned int Fref, unsigned int Fout)
1655 {
1656 struct arizona_fll_cfg ref, sync;
1657 int ret;
1658
1659 if (fll->sync_src == source &&
1660 fll->sync_freq == Fref && fll->fout == Fout)
1661 return 0;
1662
1663 if (Fout) {
1664 if (fll->ref_src >= 0) {
1665 ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1666 Fout);
1667 if (ret != 0)
1668 return ret;
1669 }
1670
1671 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1672 if (ret != 0)
1673 return ret;
1674 }
1675
1676 fll->sync_src = source;
1677 fll->sync_freq = Fref;
1678 fll->fout = Fout;
1679
1680 if (Fout) {
1681 arizona_enable_fll(fll, &ref, &sync);
1682 } else {
1683 arizona_disable_fll(fll);
1684 }
1685
1686 return 0;
1687 }
1688 EXPORT_SYMBOL_GPL(arizona_set_fll);
1689
1690 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1691 int ok_irq, struct arizona_fll *fll)
1692 {
1693 int ret;
1694 unsigned int val;
1695
1696 init_completion(&fll->ok);
1697
1698 fll->id = id;
1699 fll->base = base;
1700 fll->arizona = arizona;
1701 fll->sync_src = ARIZONA_FLL_SRC_NONE;
1702
1703 /* Configure default refclk to 32kHz if we have one */
1704 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1705 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1706 case ARIZONA_CLK_SRC_MCLK1:
1707 case ARIZONA_CLK_SRC_MCLK2:
1708 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1709 break;
1710 default:
1711 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1712 }
1713 fll->ref_freq = 32768;
1714
1715 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1716 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1717 "FLL%d clock OK", id);
1718
1719 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1720 arizona_fll_clock_ok, fll);
1721 if (ret != 0) {
1722 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1723 id, ret);
1724 }
1725
1726 regmap_update_bits(arizona->regmap, fll->base + 1,
1727 ARIZONA_FLL1_FREERUN, 0);
1728
1729 return 0;
1730 }
1731 EXPORT_SYMBOL_GPL(arizona_init_fll);
1732
1733 /**
1734 * arizona_set_output_mode - Set the mode of the specified output
1735 *
1736 * @codec: Device to configure
1737 * @output: Output number
1738 * @diff: True to set the output to differential mode
1739 *
1740 * Some systems use external analogue switches to connect more
1741 * analogue devices to the CODEC than are supported by the device. In
1742 * some systems this requires changing the switched output from single
1743 * ended to differential mode dynamically at runtime, an operation
1744 * supported using this function.
1745 *
1746 * Most systems have a single static configuration and should use
1747 * platform data instead.
1748 */
1749 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1750 {
1751 unsigned int reg, val;
1752
1753 if (output < 1 || output > 6)
1754 return -EINVAL;
1755
1756 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1757
1758 if (diff)
1759 val = ARIZONA_OUT1_MONO;
1760 else
1761 val = 0;
1762
1763 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1764 }
1765 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1766
1767 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1768 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1769 MODULE_LICENSE("GPL");
This page took 0.105791 seconds and 6 git commands to generate.