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