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