ASoC: wm5110: Add FSH for ISRCs
[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 static const char *arizona_vol_ramp_text[] = {
534 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
535 "15ms/6dB", "30ms/6dB",
536 };
537
538 const struct soc_enum arizona_in_vd_ramp =
539 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
540 ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
541 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
542
543 const struct soc_enum arizona_in_vi_ramp =
544 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
545 ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
546 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
547
548 const struct soc_enum arizona_out_vd_ramp =
549 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
550 ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
551 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
552
553 const struct soc_enum arizona_out_vi_ramp =
554 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
555 ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
556 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
557
558 static const char *arizona_lhpf_mode_text[] = {
559 "Low-pass", "High-pass"
560 };
561
562 const struct soc_enum arizona_lhpf1_mode =
563 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
564 arizona_lhpf_mode_text);
565 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
566
567 const struct soc_enum arizona_lhpf2_mode =
568 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
569 arizona_lhpf_mode_text);
570 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
571
572 const struct soc_enum arizona_lhpf3_mode =
573 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
574 arizona_lhpf_mode_text);
575 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
576
577 const struct soc_enum arizona_lhpf4_mode =
578 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
579 arizona_lhpf_mode_text);
580 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
581
582 static const char *arizona_ng_hold_text[] = {
583 "30ms", "120ms", "250ms", "500ms",
584 };
585
586 const struct soc_enum arizona_ng_hold =
587 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
588 4, arizona_ng_hold_text);
589 EXPORT_SYMBOL_GPL(arizona_ng_hold);
590
591 static const char * const arizona_in_hpf_cut_text[] = {
592 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
593 };
594
595 const struct soc_enum arizona_in_hpf_cut_enum =
596 SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT,
597 ARRAY_SIZE(arizona_in_hpf_cut_text),
598 arizona_in_hpf_cut_text);
599 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
600
601 static const char * const arizona_in_dmic_osr_text[] = {
602 "1.536MHz", "3.072MHz", "6.144MHz",
603 };
604
605 const struct soc_enum arizona_in_dmic_osr[] = {
606 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
607 ARRAY_SIZE(arizona_in_dmic_osr_text),
608 arizona_in_dmic_osr_text),
609 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
610 ARRAY_SIZE(arizona_in_dmic_osr_text),
611 arizona_in_dmic_osr_text),
612 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
613 ARRAY_SIZE(arizona_in_dmic_osr_text),
614 arizona_in_dmic_osr_text),
615 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
616 ARRAY_SIZE(arizona_in_dmic_osr_text),
617 arizona_in_dmic_osr_text),
618 };
619 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
620
621 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
622 {
623 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
624 unsigned int val;
625 int i;
626
627 if (ena)
628 val = ARIZONA_IN_VU;
629 else
630 val = 0;
631
632 for (i = 0; i < priv->num_inputs; i++)
633 snd_soc_update_bits(codec,
634 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
635 ARIZONA_IN_VU, val);
636 }
637
638 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
639 int event)
640 {
641 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
642 unsigned int reg;
643
644 if (w->shift % 2)
645 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
646 else
647 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
648
649 switch (event) {
650 case SND_SOC_DAPM_PRE_PMU:
651 priv->in_pending++;
652 break;
653 case SND_SOC_DAPM_POST_PMU:
654 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
655
656 /* If this is the last input pending then allow VU */
657 priv->in_pending--;
658 if (priv->in_pending == 0) {
659 msleep(1);
660 arizona_in_set_vu(w->codec, 1);
661 }
662 break;
663 case SND_SOC_DAPM_PRE_PMD:
664 snd_soc_update_bits(w->codec, reg,
665 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
666 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
667 break;
668 case SND_SOC_DAPM_POST_PMD:
669 /* Disable volume updates if no inputs are enabled */
670 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
671 if (reg == 0)
672 arizona_in_set_vu(w->codec, 0);
673 }
674
675 return 0;
676 }
677 EXPORT_SYMBOL_GPL(arizona_in_ev);
678
679 int arizona_out_ev(struct snd_soc_dapm_widget *w,
680 struct snd_kcontrol *kcontrol,
681 int event)
682 {
683 switch (event) {
684 case SND_SOC_DAPM_POST_PMU:
685 switch (w->shift) {
686 case ARIZONA_OUT1L_ENA_SHIFT:
687 case ARIZONA_OUT1R_ENA_SHIFT:
688 case ARIZONA_OUT2L_ENA_SHIFT:
689 case ARIZONA_OUT2R_ENA_SHIFT:
690 case ARIZONA_OUT3L_ENA_SHIFT:
691 case ARIZONA_OUT3R_ENA_SHIFT:
692 msleep(17);
693 break;
694
695 default:
696 break;
697 }
698 break;
699 }
700
701 return 0;
702 }
703 EXPORT_SYMBOL_GPL(arizona_out_ev);
704
705 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
706 struct snd_kcontrol *kcontrol,
707 int event)
708 {
709 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
710 struct arizona *arizona = priv->arizona;
711 unsigned int mask = 1 << w->shift;
712 unsigned int val;
713
714 switch (event) {
715 case SND_SOC_DAPM_POST_PMU:
716 val = mask;
717 break;
718 case SND_SOC_DAPM_PRE_PMD:
719 val = 0;
720 break;
721 default:
722 return -EINVAL;
723 }
724
725 /* Store the desired state for the HP outputs */
726 priv->arizona->hp_ena &= ~mask;
727 priv->arizona->hp_ena |= val;
728
729 /* Force off if HPDET magic is active */
730 if (priv->arizona->hpdet_magic)
731 val = 0;
732
733 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
734 mask, val);
735
736 return arizona_out_ev(w, kcontrol, event);
737 }
738 EXPORT_SYMBOL_GPL(arizona_hp_ev);
739
740 static unsigned int arizona_sysclk_48k_rates[] = {
741 6144000,
742 12288000,
743 24576000,
744 49152000,
745 73728000,
746 98304000,
747 147456000,
748 };
749
750 static unsigned int arizona_sysclk_44k1_rates[] = {
751 5644800,
752 11289600,
753 22579200,
754 45158400,
755 67737600,
756 90316800,
757 135475200,
758 };
759
760 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
761 unsigned int freq)
762 {
763 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
764 unsigned int reg;
765 unsigned int *rates;
766 int ref, div, refclk;
767
768 switch (clk) {
769 case ARIZONA_CLK_OPCLK:
770 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
771 refclk = priv->sysclk;
772 break;
773 case ARIZONA_CLK_ASYNC_OPCLK:
774 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
775 refclk = priv->asyncclk;
776 break;
777 default:
778 return -EINVAL;
779 }
780
781 if (refclk % 8000)
782 rates = arizona_sysclk_44k1_rates;
783 else
784 rates = arizona_sysclk_48k_rates;
785
786 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
787 rates[ref] <= refclk; ref++) {
788 div = 1;
789 while (rates[ref] / div >= freq && div < 32) {
790 if (rates[ref] / div == freq) {
791 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
792 freq);
793 snd_soc_update_bits(codec, reg,
794 ARIZONA_OPCLK_DIV_MASK |
795 ARIZONA_OPCLK_SEL_MASK,
796 (div <<
797 ARIZONA_OPCLK_DIV_SHIFT) |
798 ref);
799 return 0;
800 }
801 div++;
802 }
803 }
804
805 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
806 return -EINVAL;
807 }
808
809 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
810 int source, unsigned int freq, int dir)
811 {
812 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
813 struct arizona *arizona = priv->arizona;
814 char *name;
815 unsigned int reg;
816 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
817 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
818 unsigned int *clk;
819
820 switch (clk_id) {
821 case ARIZONA_CLK_SYSCLK:
822 name = "SYSCLK";
823 reg = ARIZONA_SYSTEM_CLOCK_1;
824 clk = &priv->sysclk;
825 mask |= ARIZONA_SYSCLK_FRAC;
826 break;
827 case ARIZONA_CLK_ASYNCCLK:
828 name = "ASYNCCLK";
829 reg = ARIZONA_ASYNC_CLOCK_1;
830 clk = &priv->asyncclk;
831 break;
832 case ARIZONA_CLK_OPCLK:
833 case ARIZONA_CLK_ASYNC_OPCLK:
834 return arizona_set_opclk(codec, clk_id, freq);
835 default:
836 return -EINVAL;
837 }
838
839 switch (freq) {
840 case 5644800:
841 case 6144000:
842 break;
843 case 11289600:
844 case 12288000:
845 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
846 break;
847 case 22579200:
848 case 24576000:
849 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
850 break;
851 case 45158400:
852 case 49152000:
853 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
854 break;
855 case 67737600:
856 case 73728000:
857 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
858 break;
859 case 90316800:
860 case 98304000:
861 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
862 break;
863 case 135475200:
864 case 147456000:
865 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
866 break;
867 case 0:
868 dev_dbg(arizona->dev, "%s cleared\n", name);
869 *clk = freq;
870 return 0;
871 default:
872 return -EINVAL;
873 }
874
875 *clk = freq;
876
877 if (freq % 6144000)
878 val |= ARIZONA_SYSCLK_FRAC;
879
880 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
881
882 return regmap_update_bits(arizona->regmap, reg, mask, val);
883 }
884 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
885
886 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
887 {
888 struct snd_soc_codec *codec = dai->codec;
889 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
890 struct arizona *arizona = priv->arizona;
891 int lrclk, bclk, mode, base;
892
893 base = dai->driver->base;
894
895 lrclk = 0;
896 bclk = 0;
897
898 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
899 case SND_SOC_DAIFMT_DSP_A:
900 mode = 0;
901 break;
902 case SND_SOC_DAIFMT_I2S:
903 mode = 2;
904 break;
905 default:
906 arizona_aif_err(dai, "Unsupported DAI format %d\n",
907 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
908 return -EINVAL;
909 }
910
911 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
912 case SND_SOC_DAIFMT_CBS_CFS:
913 break;
914 case SND_SOC_DAIFMT_CBS_CFM:
915 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
916 break;
917 case SND_SOC_DAIFMT_CBM_CFS:
918 bclk |= ARIZONA_AIF1_BCLK_MSTR;
919 break;
920 case SND_SOC_DAIFMT_CBM_CFM:
921 bclk |= ARIZONA_AIF1_BCLK_MSTR;
922 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
923 break;
924 default:
925 arizona_aif_err(dai, "Unsupported master mode %d\n",
926 fmt & SND_SOC_DAIFMT_MASTER_MASK);
927 return -EINVAL;
928 }
929
930 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
931 case SND_SOC_DAIFMT_NB_NF:
932 break;
933 case SND_SOC_DAIFMT_IB_IF:
934 bclk |= ARIZONA_AIF1_BCLK_INV;
935 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
936 break;
937 case SND_SOC_DAIFMT_IB_NF:
938 bclk |= ARIZONA_AIF1_BCLK_INV;
939 break;
940 case SND_SOC_DAIFMT_NB_IF:
941 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
942 break;
943 default:
944 return -EINVAL;
945 }
946
947 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
948 ARIZONA_AIF1_BCLK_INV |
949 ARIZONA_AIF1_BCLK_MSTR,
950 bclk);
951 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
952 ARIZONA_AIF1TX_LRCLK_INV |
953 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
954 regmap_update_bits_async(arizona->regmap,
955 base + ARIZONA_AIF_RX_PIN_CTRL,
956 ARIZONA_AIF1RX_LRCLK_INV |
957 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
958 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
959 ARIZONA_AIF1_FMT_MASK, mode);
960
961 return 0;
962 }
963
964 static const int arizona_48k_bclk_rates[] = {
965 -1,
966 48000,
967 64000,
968 96000,
969 128000,
970 192000,
971 256000,
972 384000,
973 512000,
974 768000,
975 1024000,
976 1536000,
977 2048000,
978 3072000,
979 4096000,
980 6144000,
981 8192000,
982 12288000,
983 24576000,
984 };
985
986 static const unsigned int arizona_48k_rates[] = {
987 12000,
988 24000,
989 48000,
990 96000,
991 192000,
992 384000,
993 768000,
994 4000,
995 8000,
996 16000,
997 32000,
998 64000,
999 128000,
1000 256000,
1001 512000,
1002 };
1003
1004 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
1005 .count = ARRAY_SIZE(arizona_48k_rates),
1006 .list = arizona_48k_rates,
1007 };
1008
1009 static const int arizona_44k1_bclk_rates[] = {
1010 -1,
1011 44100,
1012 58800,
1013 88200,
1014 117600,
1015 177640,
1016 235200,
1017 352800,
1018 470400,
1019 705600,
1020 940800,
1021 1411200,
1022 1881600,
1023 2822400,
1024 3763200,
1025 5644800,
1026 7526400,
1027 11289600,
1028 22579200,
1029 };
1030
1031 static const unsigned int arizona_44k1_rates[] = {
1032 11025,
1033 22050,
1034 44100,
1035 88200,
1036 176400,
1037 352800,
1038 705600,
1039 };
1040
1041 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
1042 .count = ARRAY_SIZE(arizona_44k1_rates),
1043 .list = arizona_44k1_rates,
1044 };
1045
1046 static int arizona_sr_vals[] = {
1047 0,
1048 12000,
1049 24000,
1050 48000,
1051 96000,
1052 192000,
1053 384000,
1054 768000,
1055 0,
1056 11025,
1057 22050,
1058 44100,
1059 88200,
1060 176400,
1061 352800,
1062 705600,
1063 4000,
1064 8000,
1065 16000,
1066 32000,
1067 64000,
1068 128000,
1069 256000,
1070 512000,
1071 };
1072
1073 static int arizona_startup(struct snd_pcm_substream *substream,
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 const struct snd_pcm_hw_constraint_list *constraint;
1080 unsigned int base_rate;
1081
1082 switch (dai_priv->clk) {
1083 case ARIZONA_CLK_SYSCLK:
1084 base_rate = priv->sysclk;
1085 break;
1086 case ARIZONA_CLK_ASYNCCLK:
1087 base_rate = priv->asyncclk;
1088 break;
1089 default:
1090 return 0;
1091 }
1092
1093 if (base_rate == 0)
1094 return 0;
1095
1096 if (base_rate % 8000)
1097 constraint = &arizona_44k1_constraint;
1098 else
1099 constraint = &arizona_48k_constraint;
1100
1101 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1102 SNDRV_PCM_HW_PARAM_RATE,
1103 constraint);
1104 }
1105
1106 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1107 struct snd_pcm_hw_params *params,
1108 struct snd_soc_dai *dai)
1109 {
1110 struct snd_soc_codec *codec = dai->codec;
1111 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1112 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1113 int base = dai->driver->base;
1114 int i, sr_val;
1115
1116 /*
1117 * We will need to be more flexible than this in future,
1118 * currently we use a single sample rate for SYSCLK.
1119 */
1120 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1121 if (arizona_sr_vals[i] == params_rate(params))
1122 break;
1123 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1124 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1125 params_rate(params));
1126 return -EINVAL;
1127 }
1128 sr_val = i;
1129
1130 switch (dai_priv->clk) {
1131 case ARIZONA_CLK_SYSCLK:
1132 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1133 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1134 if (base)
1135 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1136 ARIZONA_AIF1_RATE_MASK, 0);
1137 break;
1138 case ARIZONA_CLK_ASYNCCLK:
1139 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1140 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
1141 if (base)
1142 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1143 ARIZONA_AIF1_RATE_MASK,
1144 8 << ARIZONA_AIF1_RATE_SHIFT);
1145 break;
1146 default:
1147 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1148 return -EINVAL;
1149 }
1150
1151 return 0;
1152 }
1153
1154 static int arizona_hw_params(struct snd_pcm_substream *substream,
1155 struct snd_pcm_hw_params *params,
1156 struct snd_soc_dai *dai)
1157 {
1158 struct snd_soc_codec *codec = dai->codec;
1159 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1160 struct arizona *arizona = priv->arizona;
1161 int base = dai->driver->base;
1162 const int *rates;
1163 int i, ret, val;
1164 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1165 int bclk, lrclk, wl, frame, bclk_target;
1166
1167 if (params_rate(params) % 8000)
1168 rates = &arizona_44k1_bclk_rates[0];
1169 else
1170 rates = &arizona_48k_bclk_rates[0];
1171
1172 bclk_target = snd_soc_params_to_bclk(params);
1173 if (chan_limit && chan_limit < params_channels(params)) {
1174 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1175 bclk_target /= params_channels(params);
1176 bclk_target *= chan_limit;
1177 }
1178
1179 /* Force stereo for I2S mode */
1180 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1181 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1182 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1183 bclk_target *= 2;
1184 }
1185
1186 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1187 if (rates[i] >= bclk_target &&
1188 rates[i] % params_rate(params) == 0) {
1189 bclk = i;
1190 break;
1191 }
1192 }
1193 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1194 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1195 params_rate(params));
1196 return -EINVAL;
1197 }
1198
1199 lrclk = rates[bclk] / params_rate(params);
1200
1201 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1202 rates[bclk], rates[bclk] / lrclk);
1203
1204 wl = snd_pcm_format_width(params_format(params));
1205 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
1206
1207 ret = arizona_hw_params_rate(substream, params, dai);
1208 if (ret != 0)
1209 return ret;
1210
1211 regmap_update_bits_async(arizona->regmap,
1212 base + ARIZONA_AIF_BCLK_CTRL,
1213 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1214 regmap_update_bits_async(arizona->regmap,
1215 base + ARIZONA_AIF_TX_BCLK_RATE,
1216 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1217 regmap_update_bits_async(arizona->regmap,
1218 base + ARIZONA_AIF_RX_BCLK_RATE,
1219 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1220 regmap_update_bits_async(arizona->regmap,
1221 base + ARIZONA_AIF_FRAME_CTRL_1,
1222 ARIZONA_AIF1TX_WL_MASK |
1223 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1224 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2,
1225 ARIZONA_AIF1RX_WL_MASK |
1226 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1227
1228 return 0;
1229 }
1230
1231 static const char *arizona_dai_clk_str(int clk_id)
1232 {
1233 switch (clk_id) {
1234 case ARIZONA_CLK_SYSCLK:
1235 return "SYSCLK";
1236 case ARIZONA_CLK_ASYNCCLK:
1237 return "ASYNCCLK";
1238 default:
1239 return "Unknown clock";
1240 }
1241 }
1242
1243 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1244 int clk_id, unsigned int freq, int dir)
1245 {
1246 struct snd_soc_codec *codec = dai->codec;
1247 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1248 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1249 struct snd_soc_dapm_route routes[2];
1250
1251 switch (clk_id) {
1252 case ARIZONA_CLK_SYSCLK:
1253 case ARIZONA_CLK_ASYNCCLK:
1254 break;
1255 default:
1256 return -EINVAL;
1257 }
1258
1259 if (clk_id == dai_priv->clk)
1260 return 0;
1261
1262 if (dai->active) {
1263 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1264 dai->id);
1265 return -EBUSY;
1266 }
1267
1268 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1269 arizona_dai_clk_str(clk_id));
1270
1271 memset(&routes, 0, sizeof(routes));
1272 routes[0].sink = dai->driver->capture.stream_name;
1273 routes[1].sink = dai->driver->playback.stream_name;
1274
1275 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1276 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1277 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1278
1279 routes[0].source = arizona_dai_clk_str(clk_id);
1280 routes[1].source = arizona_dai_clk_str(clk_id);
1281 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1282
1283 dai_priv->clk = clk_id;
1284
1285 return snd_soc_dapm_sync(&codec->dapm);
1286 }
1287
1288 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1289 {
1290 struct snd_soc_codec *codec = dai->codec;
1291 int base = dai->driver->base;
1292 unsigned int reg;
1293
1294 if (tristate)
1295 reg = ARIZONA_AIF1_TRI;
1296 else
1297 reg = 0;
1298
1299 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1300 ARIZONA_AIF1_TRI, reg);
1301 }
1302
1303 const struct snd_soc_dai_ops arizona_dai_ops = {
1304 .startup = arizona_startup,
1305 .set_fmt = arizona_set_fmt,
1306 .hw_params = arizona_hw_params,
1307 .set_sysclk = arizona_dai_set_sysclk,
1308 .set_tristate = arizona_set_tristate,
1309 };
1310 EXPORT_SYMBOL_GPL(arizona_dai_ops);
1311
1312 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1313 .startup = arizona_startup,
1314 .hw_params = arizona_hw_params_rate,
1315 .set_sysclk = arizona_dai_set_sysclk,
1316 };
1317 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1318
1319 int arizona_init_dai(struct arizona_priv *priv, int id)
1320 {
1321 struct arizona_dai_priv *dai_priv = &priv->dai[id];
1322
1323 dai_priv->clk = ARIZONA_CLK_SYSCLK;
1324
1325 return 0;
1326 }
1327 EXPORT_SYMBOL_GPL(arizona_init_dai);
1328
1329 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
1330 {
1331 struct arizona_fll *fll = data;
1332
1333 arizona_fll_dbg(fll, "clock OK\n");
1334
1335 complete(&fll->ok);
1336
1337 return IRQ_HANDLED;
1338 }
1339
1340 static struct {
1341 unsigned int min;
1342 unsigned int max;
1343 u16 fratio;
1344 int ratio;
1345 } fll_fratios[] = {
1346 { 0, 64000, 4, 16 },
1347 { 64000, 128000, 3, 8 },
1348 { 128000, 256000, 2, 4 },
1349 { 256000, 1000000, 1, 2 },
1350 { 1000000, 13500000, 0, 1 },
1351 };
1352
1353 static struct {
1354 unsigned int min;
1355 unsigned int max;
1356 u16 gain;
1357 } fll_gains[] = {
1358 { 0, 256000, 0 },
1359 { 256000, 1000000, 2 },
1360 { 1000000, 13500000, 4 },
1361 };
1362
1363 struct arizona_fll_cfg {
1364 int n;
1365 int theta;
1366 int lambda;
1367 int refdiv;
1368 int outdiv;
1369 int fratio;
1370 int gain;
1371 };
1372
1373 static int arizona_calc_fll(struct arizona_fll *fll,
1374 struct arizona_fll_cfg *cfg,
1375 unsigned int Fref,
1376 unsigned int Fout)
1377 {
1378 unsigned int target, div, gcd_fll;
1379 int i, ratio;
1380
1381 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
1382
1383 /* Fref must be <=13.5MHz */
1384 div = 1;
1385 cfg->refdiv = 0;
1386 while ((Fref / div) > 13500000) {
1387 div *= 2;
1388 cfg->refdiv++;
1389
1390 if (div > 8) {
1391 arizona_fll_err(fll,
1392 "Can't scale %dMHz in to <=13.5MHz\n",
1393 Fref);
1394 return -EINVAL;
1395 }
1396 }
1397
1398 /* Apply the division for our remaining calculations */
1399 Fref /= div;
1400
1401 /* Fvco should be over the targt; don't check the upper bound */
1402 div = 1;
1403 while (Fout * div < 90000000 * fll->vco_mult) {
1404 div++;
1405 if (div > 7) {
1406 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1407 Fout);
1408 return -EINVAL;
1409 }
1410 }
1411 target = Fout * div / fll->vco_mult;
1412 cfg->outdiv = div;
1413
1414 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1415
1416 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1417 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1418 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1419 cfg->fratio = fll_fratios[i].fratio;
1420 ratio = fll_fratios[i].ratio;
1421 break;
1422 }
1423 }
1424 if (i == ARRAY_SIZE(fll_fratios)) {
1425 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1426 Fref);
1427 return -EINVAL;
1428 }
1429
1430 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1431 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1432 cfg->gain = fll_gains[i].gain;
1433 break;
1434 }
1435 }
1436 if (i == ARRAY_SIZE(fll_gains)) {
1437 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1438 Fref);
1439 return -EINVAL;
1440 }
1441
1442 cfg->n = target / (ratio * Fref);
1443
1444 if (target % (ratio * Fref)) {
1445 gcd_fll = gcd(target, ratio * Fref);
1446 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1447
1448 cfg->theta = (target - (cfg->n * ratio * Fref))
1449 / gcd_fll;
1450 cfg->lambda = (ratio * Fref) / gcd_fll;
1451 } else {
1452 cfg->theta = 0;
1453 cfg->lambda = 0;
1454 }
1455
1456 /* Round down to 16bit range with cost of accuracy lost.
1457 * Denominator must be bigger than numerator so we only
1458 * take care of it.
1459 */
1460 while (cfg->lambda >= (1 << 16)) {
1461 cfg->theta >>= 1;
1462 cfg->lambda >>= 1;
1463 }
1464
1465 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1466 cfg->n, cfg->theta, cfg->lambda);
1467 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1468 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1469 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1470
1471 return 0;
1472
1473 }
1474
1475 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1476 struct arizona_fll_cfg *cfg, int source,
1477 bool sync)
1478 {
1479 regmap_update_bits_async(arizona->regmap, base + 3,
1480 ARIZONA_FLL1_THETA_MASK, cfg->theta);
1481 regmap_update_bits_async(arizona->regmap, base + 4,
1482 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1483 regmap_update_bits_async(arizona->regmap, base + 5,
1484 ARIZONA_FLL1_FRATIO_MASK,
1485 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1486 regmap_update_bits_async(arizona->regmap, base + 6,
1487 ARIZONA_FLL1_CLK_REF_DIV_MASK |
1488 ARIZONA_FLL1_CLK_REF_SRC_MASK,
1489 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1490 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1491
1492 if (sync)
1493 regmap_update_bits_async(arizona->regmap, base + 0x7,
1494 ARIZONA_FLL1_GAIN_MASK,
1495 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1496 else
1497 regmap_update_bits_async(arizona->regmap, base + 0x9,
1498 ARIZONA_FLL1_GAIN_MASK,
1499 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1500
1501 regmap_update_bits_async(arizona->regmap, base + 2,
1502 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1503 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1504 }
1505
1506 static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1507 {
1508 struct arizona *arizona = fll->arizona;
1509 unsigned int reg;
1510 int ret;
1511
1512 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1513 if (ret != 0) {
1514 arizona_fll_err(fll, "Failed to read current state: %d\n",
1515 ret);
1516 return ret;
1517 }
1518
1519 return reg & ARIZONA_FLL1_ENA;
1520 }
1521
1522 static void arizona_enable_fll(struct arizona_fll *fll,
1523 struct arizona_fll_cfg *ref,
1524 struct arizona_fll_cfg *sync)
1525 {
1526 struct arizona *arizona = fll->arizona;
1527 int ret;
1528 bool use_sync = false;
1529
1530 /*
1531 * If we have both REFCLK and SYNCCLK then enable both,
1532 * otherwise apply the SYNCCLK settings to REFCLK.
1533 */
1534 if (fll->ref_src >= 0 && fll->ref_freq &&
1535 fll->ref_src != fll->sync_src) {
1536 regmap_update_bits_async(arizona->regmap, fll->base + 5,
1537 ARIZONA_FLL1_OUTDIV_MASK,
1538 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1539
1540 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1541 false);
1542 if (fll->sync_src >= 0) {
1543 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1544 fll->sync_src, true);
1545 use_sync = true;
1546 }
1547 } else if (fll->sync_src >= 0) {
1548 regmap_update_bits_async(arizona->regmap, fll->base + 5,
1549 ARIZONA_FLL1_OUTDIV_MASK,
1550 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1551
1552 arizona_apply_fll(arizona, fll->base, sync,
1553 fll->sync_src, false);
1554
1555 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
1556 ARIZONA_FLL1_SYNC_ENA, 0);
1557 } else {
1558 arizona_fll_err(fll, "No clocks provided\n");
1559 return;
1560 }
1561
1562 /*
1563 * Increase the bandwidth if we're not using a low frequency
1564 * sync source.
1565 */
1566 if (use_sync && fll->sync_freq > 100000)
1567 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
1568 ARIZONA_FLL1_SYNC_BW, 0);
1569 else
1570 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
1571 ARIZONA_FLL1_SYNC_BW,
1572 ARIZONA_FLL1_SYNC_BW);
1573
1574 if (!arizona_is_enabled_fll(fll))
1575 pm_runtime_get(arizona->dev);
1576
1577 /* Clear any pending completions */
1578 try_wait_for_completion(&fll->ok);
1579
1580 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1581 ARIZONA_FLL1_FREERUN, 0);
1582 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1583 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1584 if (use_sync)
1585 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
1586 ARIZONA_FLL1_SYNC_ENA,
1587 ARIZONA_FLL1_SYNC_ENA);
1588
1589 ret = wait_for_completion_timeout(&fll->ok,
1590 msecs_to_jiffies(250));
1591 if (ret == 0)
1592 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1593 }
1594
1595 static void arizona_disable_fll(struct arizona_fll *fll)
1596 {
1597 struct arizona *arizona = fll->arizona;
1598 bool change;
1599
1600 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1601 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
1602 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1603 ARIZONA_FLL1_ENA, 0, &change);
1604 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1605 ARIZONA_FLL1_SYNC_ENA, 0);
1606
1607 if (change)
1608 pm_runtime_put_autosuspend(arizona->dev);
1609 }
1610
1611 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1612 unsigned int Fref, unsigned int Fout)
1613 {
1614 struct arizona_fll_cfg ref, sync;
1615 int ret;
1616
1617 if (fll->ref_src == source && fll->ref_freq == Fref)
1618 return 0;
1619
1620 if (fll->fout) {
1621 if (Fref > 0) {
1622 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1623 if (ret != 0)
1624 return ret;
1625 }
1626
1627 if (fll->sync_src >= 0) {
1628 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1629 fll->fout);
1630 if (ret != 0)
1631 return ret;
1632 }
1633 }
1634
1635 fll->ref_src = source;
1636 fll->ref_freq = Fref;
1637
1638 if (fll->fout && Fref > 0) {
1639 arizona_enable_fll(fll, &ref, &sync);
1640 }
1641
1642 return 0;
1643 }
1644 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1645
1646 int arizona_set_fll(struct arizona_fll *fll, int source,
1647 unsigned int Fref, unsigned int Fout)
1648 {
1649 struct arizona_fll_cfg ref, sync;
1650 int ret;
1651
1652 if (fll->sync_src == source &&
1653 fll->sync_freq == Fref && fll->fout == Fout)
1654 return 0;
1655
1656 if (Fout) {
1657 if (fll->ref_src >= 0) {
1658 ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1659 Fout);
1660 if (ret != 0)
1661 return ret;
1662 }
1663
1664 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1665 if (ret != 0)
1666 return ret;
1667 }
1668
1669 fll->sync_src = source;
1670 fll->sync_freq = Fref;
1671 fll->fout = Fout;
1672
1673 if (Fout) {
1674 arizona_enable_fll(fll, &ref, &sync);
1675 } else {
1676 arizona_disable_fll(fll);
1677 }
1678
1679 return 0;
1680 }
1681 EXPORT_SYMBOL_GPL(arizona_set_fll);
1682
1683 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1684 int ok_irq, struct arizona_fll *fll)
1685 {
1686 int ret;
1687 unsigned int val;
1688
1689 init_completion(&fll->ok);
1690
1691 fll->id = id;
1692 fll->base = base;
1693 fll->arizona = arizona;
1694 fll->sync_src = ARIZONA_FLL_SRC_NONE;
1695
1696 /* Configure default refclk to 32kHz if we have one */
1697 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1698 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1699 case ARIZONA_CLK_SRC_MCLK1:
1700 case ARIZONA_CLK_SRC_MCLK2:
1701 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1702 break;
1703 default:
1704 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1705 }
1706 fll->ref_freq = 32768;
1707
1708 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1709 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1710 "FLL%d clock OK", id);
1711
1712 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1713 arizona_fll_clock_ok, fll);
1714 if (ret != 0) {
1715 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1716 id, ret);
1717 }
1718
1719 regmap_update_bits(arizona->regmap, fll->base + 1,
1720 ARIZONA_FLL1_FREERUN, 0);
1721
1722 return 0;
1723 }
1724 EXPORT_SYMBOL_GPL(arizona_init_fll);
1725
1726 /**
1727 * arizona_set_output_mode - Set the mode of the specified output
1728 *
1729 * @codec: Device to configure
1730 * @output: Output number
1731 * @diff: True to set the output to differential mode
1732 *
1733 * Some systems use external analogue switches to connect more
1734 * analogue devices to the CODEC than are supported by the device. In
1735 * some systems this requires changing the switched output from single
1736 * ended to differential mode dynamically at runtime, an operation
1737 * supported using this function.
1738 *
1739 * Most systems have a single static configuration and should use
1740 * platform data instead.
1741 */
1742 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1743 {
1744 unsigned int reg, val;
1745
1746 if (output < 1 || output > 6)
1747 return -EINVAL;
1748
1749 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1750
1751 if (diff)
1752 val = ARIZONA_OUT1_MONO;
1753 else
1754 val = 0;
1755
1756 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1757 }
1758 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1759
1760 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1761 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1762 MODULE_LICENSE("GPL");
This page took 0.362542 seconds and 5 git commands to generate.