1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/delay.h>
14#include <linux/gcd.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/pm_runtime.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21
22#include <linux/mfd/arizona/core.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_VCO_CORNER 141900000
57#define ARIZONA_FLL_MAX_FREF 13500000
58#define ARIZONA_FLL_MIN_FVCO 90000000
59#define ARIZONA_FLL_MAX_FRATIO 16
60#define ARIZONA_FLL_MAX_REFDIV 8
61#define ARIZONA_FLL_MIN_OUTDIV 2
62#define ARIZONA_FLL_MAX_OUTDIV 7
63
64#define ARIZONA_FMT_DSP_MODE_A 0
65#define ARIZONA_FMT_DSP_MODE_B 1
66#define ARIZONA_FMT_I2S_MODE 2
67#define ARIZONA_FMT_LEFT_JUSTIFIED_MODE 3
68
69#define arizona_fll_err(_fll, fmt, ...) \
70 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
71#define arizona_fll_warn(_fll, fmt, ...) \
72 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
73#define arizona_fll_dbg(_fll, fmt, ...) \
74 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
75
76#define arizona_aif_err(_dai, fmt, ...) \
77 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
78#define arizona_aif_warn(_dai, fmt, ...) \
79 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
80#define arizona_aif_dbg(_dai, fmt, ...) \
81 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
82
83static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
84 struct snd_kcontrol *kcontrol,
85 int event)
86{
87 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
88 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
89 int val;
90
91 switch (event) {
92 case SND_SOC_DAPM_POST_PMU:
93 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
94 if (val & ARIZONA_SPK_OVERHEAT_STS) {
95 dev_crit(arizona->dev,
96 "Speaker not enabled due to temperature\n");
97 return -EBUSY;
98 }
99
100 regmap_update_bits_async(arizona->regmap,
101 ARIZONA_OUTPUT_ENABLES_1,
102 1 << w->shift, 1 << w->shift);
103 break;
104 case SND_SOC_DAPM_PRE_PMD:
105 regmap_update_bits_async(arizona->regmap,
106 ARIZONA_OUTPUT_ENABLES_1,
107 1 << w->shift, 0);
108 break;
109 default:
110 break;
111 }
112
113 return arizona_out_ev(w, kcontrol, event);
114}
115
116static irqreturn_t arizona_thermal_warn(int irq, void *data)
117{
118 struct arizona *arizona = data;
119 unsigned int val;
120 int ret;
121
122 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
123 &val);
124 if (ret != 0) {
125 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
126 ret);
127 } else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
128 dev_crit(arizona->dev, "Thermal warning\n");
129 }
130
131 return IRQ_HANDLED;
132}
133
134static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
135{
136 struct arizona *arizona = data;
137 unsigned int val;
138 int ret;
139
140 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
141 &val);
142 if (ret != 0) {
143 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
144 ret);
145 } else if (val & ARIZONA_SPK_OVERHEAT_STS) {
146 dev_crit(arizona->dev, "Thermal shutdown\n");
147 ret = regmap_update_bits(arizona->regmap,
148 ARIZONA_OUTPUT_ENABLES_1,
149 ARIZONA_OUT4L_ENA |
150 ARIZONA_OUT4R_ENA, 0);
151 if (ret != 0)
152 dev_crit(arizona->dev,
153 "Failed to disable speaker outputs: %d\n",
154 ret);
155 }
156
157 return IRQ_HANDLED;
158}
159
160static const struct snd_soc_dapm_widget arizona_spkl =
161 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
162 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
163 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
164 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
165
166static const struct snd_soc_dapm_widget arizona_spkr =
167 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
168 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
169 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
170 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
171
172int arizona_init_spk(struct snd_soc_codec *codec)
173{
174 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
175 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
176 struct arizona *arizona = priv->arizona;
177 int ret;
178
179 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
180 if (ret != 0)
181 return ret;
182
183 switch (arizona->type) {
184 case WM8997:
185 case CS47L24:
186 case WM1831:
187 break;
188 default:
189 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
190 if (ret != 0)
191 return ret;
192 break;
193 }
194
195 return 0;
196}
197EXPORT_SYMBOL_GPL(arizona_init_spk);
198
199int arizona_init_spk_irqs(struct arizona *arizona)
200{
201 int ret;
202
203 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
204 "Thermal warning", arizona_thermal_warn,
205 arizona);
206 if (ret != 0)
207 dev_err(arizona->dev,
208 "Failed to get thermal warning IRQ: %d\n",
209 ret);
210
211 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
212 "Thermal shutdown", arizona_thermal_shutdown,
213 arizona);
214 if (ret != 0)
215 dev_err(arizona->dev,
216 "Failed to get thermal shutdown IRQ: %d\n",
217 ret);
218
219 return 0;
220}
221EXPORT_SYMBOL_GPL(arizona_init_spk_irqs);
222
223int arizona_free_spk_irqs(struct arizona *arizona)
224{
225 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona);
226 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona);
227
228 return 0;
229}
230EXPORT_SYMBOL_GPL(arizona_free_spk_irqs);
231
232static const struct snd_soc_dapm_route arizona_mono_routes[] = {
233 { "OUT1R", NULL, "OUT1L" },
234 { "OUT2R", NULL, "OUT2L" },
235 { "OUT3R", NULL, "OUT3L" },
236 { "OUT4R", NULL, "OUT4L" },
237 { "OUT5R", NULL, "OUT5L" },
238 { "OUT6R", NULL, "OUT6L" },
239};
240
241int arizona_init_mono(struct snd_soc_codec *codec)
242{
243 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
244 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
245 struct arizona *arizona = priv->arizona;
246 int i;
247
248 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
249 if (arizona->pdata.out_mono[i])
250 snd_soc_dapm_add_routes(dapm,
251 &arizona_mono_routes[i], 1);
252 }
253
254 return 0;
255}
256EXPORT_SYMBOL_GPL(arizona_init_mono);
257
258int arizona_init_gpio(struct snd_soc_codec *codec)
259{
260 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
261 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
262 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
263 struct arizona *arizona = priv->arizona;
264 int i;
265
266 switch (arizona->type) {
267 case WM5110:
268 case WM8280:
269 snd_soc_component_disable_pin(component,
270 "DRC2 Signal Activity");
271 break;
272 default:
273 break;
274 }
275
276 snd_soc_component_disable_pin(component, "DRC1 Signal Activity");
277
278 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
279 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
280 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
281 snd_soc_component_enable_pin(component,
282 "DRC1 Signal Activity");
283 break;
284 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
285 snd_soc_component_enable_pin(component,
286 "DRC2 Signal Activity");
287 break;
288 default:
289 break;
290 }
291 }
292
293 return 0;
294}
295EXPORT_SYMBOL_GPL(arizona_init_gpio);
296
297int arizona_init_common(struct arizona *arizona)
298{
299 struct arizona_pdata *pdata = &arizona->pdata;
300 unsigned int val, mask;
301 int i;
302
303 BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
304
305 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
306
307 if (pdata->out_mono[i])
308 val = ARIZONA_OUT1_MONO;
309 else
310 val = 0;
311
312 regmap_update_bits(arizona->regmap,
313 ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
314 ARIZONA_OUT1_MONO, val);
315 }
316
317 for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
318 if (pdata->spk_mute[i])
319 regmap_update_bits(arizona->regmap,
320 ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
321 ARIZONA_SPK1_MUTE_ENDIAN_MASK |
322 ARIZONA_SPK1_MUTE_SEQ1_MASK,
323 pdata->spk_mute[i]);
324
325 if (pdata->spk_fmt[i])
326 regmap_update_bits(arizona->regmap,
327 ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
328 ARIZONA_SPK1_FMT_MASK,
329 pdata->spk_fmt[i]);
330 }
331
332 for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
333
334 val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
335 if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
336 val |= 1 << ARIZONA_IN1_MODE_SHIFT;
337
338 switch (arizona->type) {
339 case WM8998:
340 case WM1814:
341 regmap_update_bits(arizona->regmap,
342 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
343 ARIZONA_IN1L_SRC_SE_MASK,
344 (pdata->inmode[i] & ARIZONA_INMODE_SE)
345 << ARIZONA_IN1L_SRC_SE_SHIFT);
346
347 regmap_update_bits(arizona->regmap,
348 ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
349 ARIZONA_IN1R_SRC_SE_MASK,
350 (pdata->inmode[i] & ARIZONA_INMODE_SE)
351 << ARIZONA_IN1R_SRC_SE_SHIFT);
352
353 mask = ARIZONA_IN1_DMIC_SUP_MASK |
354 ARIZONA_IN1_MODE_MASK;
355 break;
356 default:
357 if (pdata->inmode[i] & ARIZONA_INMODE_SE)
358 val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
359
360 mask = ARIZONA_IN1_DMIC_SUP_MASK |
361 ARIZONA_IN1_MODE_MASK |
362 ARIZONA_IN1_SINGLE_ENDED_MASK;
363 break;
364 }
365
366 regmap_update_bits(arizona->regmap,
367 ARIZONA_IN1L_CONTROL + (i * 8),
368 mask, val);
369 }
370
371 return 0;
372}
373EXPORT_SYMBOL_GPL(arizona_init_common);
374
375int arizona_init_vol_limit(struct arizona *arizona)
376{
377 int i;
378
379 for (i = 0; i < ARRAY_SIZE(arizona->pdata.out_vol_limit); ++i) {
380 if (arizona->pdata.out_vol_limit[i])
381 regmap_update_bits(arizona->regmap,
382 ARIZONA_DAC_VOLUME_LIMIT_1L + i * 4,
383 ARIZONA_OUT1L_VOL_LIM_MASK,
384 arizona->pdata.out_vol_limit[i]);
385 }
386
387 return 0;
388}
389EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
390
391const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
392 "None",
393 "Tone Generator 1",
394 "Tone Generator 2",
395 "Haptics",
396 "AEC",
397 "AEC2",
398 "Mic Mute Mixer",
399 "Noise Generator",
400 "IN1L",
401 "IN1R",
402 "IN2L",
403 "IN2R",
404 "IN3L",
405 "IN3R",
406 "IN4L",
407 "IN4R",
408 "AIF1RX1",
409 "AIF1RX2",
410 "AIF1RX3",
411 "AIF1RX4",
412 "AIF1RX5",
413 "AIF1RX6",
414 "AIF1RX7",
415 "AIF1RX8",
416 "AIF2RX1",
417 "AIF2RX2",
418 "AIF2RX3",
419 "AIF2RX4",
420 "AIF2RX5",
421 "AIF2RX6",
422 "AIF3RX1",
423 "AIF3RX2",
424 "SLIMRX1",
425 "SLIMRX2",
426 "SLIMRX3",
427 "SLIMRX4",
428 "SLIMRX5",
429 "SLIMRX6",
430 "SLIMRX7",
431 "SLIMRX8",
432 "EQ1",
433 "EQ2",
434 "EQ3",
435 "EQ4",
436 "DRC1L",
437 "DRC1R",
438 "DRC2L",
439 "DRC2R",
440 "LHPF1",
441 "LHPF2",
442 "LHPF3",
443 "LHPF4",
444 "DSP1.1",
445 "DSP1.2",
446 "DSP1.3",
447 "DSP1.4",
448 "DSP1.5",
449 "DSP1.6",
450 "DSP2.1",
451 "DSP2.2",
452 "DSP2.3",
453 "DSP2.4",
454 "DSP2.5",
455 "DSP2.6",
456 "DSP3.1",
457 "DSP3.2",
458 "DSP3.3",
459 "DSP3.4",
460 "DSP3.5",
461 "DSP3.6",
462 "DSP4.1",
463 "DSP4.2",
464 "DSP4.3",
465 "DSP4.4",
466 "DSP4.5",
467 "DSP4.6",
468 "ASRC1L",
469 "ASRC1R",
470 "ASRC2L",
471 "ASRC2R",
472 "ISRC1INT1",
473 "ISRC1INT2",
474 "ISRC1INT3",
475 "ISRC1INT4",
476 "ISRC1DEC1",
477 "ISRC1DEC2",
478 "ISRC1DEC3",
479 "ISRC1DEC4",
480 "ISRC2INT1",
481 "ISRC2INT2",
482 "ISRC2INT3",
483 "ISRC2INT4",
484 "ISRC2DEC1",
485 "ISRC2DEC2",
486 "ISRC2DEC3",
487 "ISRC2DEC4",
488 "ISRC3INT1",
489 "ISRC3INT2",
490 "ISRC3INT3",
491 "ISRC3INT4",
492 "ISRC3DEC1",
493 "ISRC3DEC2",
494 "ISRC3DEC3",
495 "ISRC3DEC4",
496};
497EXPORT_SYMBOL_GPL(arizona_mixer_texts);
498
499unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
500 0x00,
501 0x04,
502 0x05,
503 0x06,
504 0x08,
505 0x09,
506 0x0c,
507 0x0d,
508 0x10,
509 0x11,
510 0x12,
511 0x13,
512 0x14,
513 0x15,
514 0x16,
515 0x17,
516 0x20,
517 0x21,
518 0x22,
519 0x23,
520 0x24,
521 0x25,
522 0x26,
523 0x27,
524 0x28,
525 0x29,
526 0x2a,
527 0x2b,
528 0x2c,
529 0x2d,
530 0x30,
531 0x31,
532 0x38,
533 0x39,
534 0x3a,
535 0x3b,
536 0x3c,
537 0x3d,
538 0x3e,
539 0x3f,
540 0x50,
541 0x51,
542 0x52,
543 0x53,
544 0x58,
545 0x59,
546 0x5a,
547 0x5b,
548 0x60,
549 0x61,
550 0x62,
551 0x63,
552 0x68,
553 0x69,
554 0x6a,
555 0x6b,
556 0x6c,
557 0x6d,
558 0x70,
559 0x71,
560 0x72,
561 0x73,
562 0x74,
563 0x75,
564 0x78,
565 0x79,
566 0x7a,
567 0x7b,
568 0x7c,
569 0x7d,
570 0x80,
571 0x81,
572 0x82,
573 0x83,
574 0x84,
575 0x85,
576 0x90,
577 0x91,
578 0x92,
579 0x93,
580 0xa0,
581 0xa1,
582 0xa2,
583 0xa3,
584 0xa4,
585 0xa5,
586 0xa6,
587 0xa7,
588 0xa8,
589 0xa9,
590 0xaa,
591 0xab,
592 0xac,
593 0xad,
594 0xae,
595 0xaf,
596 0xb0,
597 0xb1,
598 0xb2,
599 0xb3,
600 0xb4,
601 0xb5,
602 0xb6,
603 0xb7,
604};
605EXPORT_SYMBOL_GPL(arizona_mixer_values);
606
607const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
608EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
609
610const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
611 "12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
612 "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
613 "4kHz", "8kHz", "16kHz", "32kHz",
614};
615EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
616
617const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
618 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
619 0x10, 0x11, 0x12, 0x13,
620};
621EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
622
623const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
624{
625 int i;
626
627 for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
628 if (arizona_sample_rate_val[i] == rate_val)
629 return arizona_sample_rate_text[i];
630 }
631
632 return "Illegal";
633}
634EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
635
636const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
637 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
638};
639EXPORT_SYMBOL_GPL(arizona_rate_text);
640
641const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
642 0, 1, 2, 8,
643};
644EXPORT_SYMBOL_GPL(arizona_rate_val);
645
646
647const struct soc_enum arizona_isrc_fsh[] = {
648 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
649 ARIZONA_ISRC1_FSH_SHIFT, 0xf,
650 ARIZONA_RATE_ENUM_SIZE,
651 arizona_rate_text, arizona_rate_val),
652 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
653 ARIZONA_ISRC2_FSH_SHIFT, 0xf,
654 ARIZONA_RATE_ENUM_SIZE,
655 arizona_rate_text, arizona_rate_val),
656 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
657 ARIZONA_ISRC3_FSH_SHIFT, 0xf,
658 ARIZONA_RATE_ENUM_SIZE,
659 arizona_rate_text, arizona_rate_val),
660};
661EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
662
663const struct soc_enum arizona_isrc_fsl[] = {
664 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
665 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
666 ARIZONA_RATE_ENUM_SIZE,
667 arizona_rate_text, arizona_rate_val),
668 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
669 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
670 ARIZONA_RATE_ENUM_SIZE,
671 arizona_rate_text, arizona_rate_val),
672 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
673 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
674 ARIZONA_RATE_ENUM_SIZE,
675 arizona_rate_text, arizona_rate_val),
676};
677EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
678
679const struct soc_enum arizona_asrc_rate1 =
680 SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
681 ARIZONA_ASRC_RATE1_SHIFT, 0xf,
682 ARIZONA_RATE_ENUM_SIZE - 1,
683 arizona_rate_text, arizona_rate_val);
684EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
685
686static const char * const arizona_vol_ramp_text[] = {
687 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
688 "15ms/6dB", "30ms/6dB",
689};
690
691SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
692 ARIZONA_INPUT_VOLUME_RAMP,
693 ARIZONA_IN_VD_RAMP_SHIFT,
694 arizona_vol_ramp_text);
695EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
696
697SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
698 ARIZONA_INPUT_VOLUME_RAMP,
699 ARIZONA_IN_VI_RAMP_SHIFT,
700 arizona_vol_ramp_text);
701EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
702
703SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
704 ARIZONA_OUTPUT_VOLUME_RAMP,
705 ARIZONA_OUT_VD_RAMP_SHIFT,
706 arizona_vol_ramp_text);
707EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
708
709SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
710 ARIZONA_OUTPUT_VOLUME_RAMP,
711 ARIZONA_OUT_VI_RAMP_SHIFT,
712 arizona_vol_ramp_text);
713EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
714
715static const char * const arizona_lhpf_mode_text[] = {
716 "Low-pass", "High-pass"
717};
718
719SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
720 ARIZONA_HPLPF1_1,
721 ARIZONA_LHPF1_MODE_SHIFT,
722 arizona_lhpf_mode_text);
723EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
724
725SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
726 ARIZONA_HPLPF2_1,
727 ARIZONA_LHPF2_MODE_SHIFT,
728 arizona_lhpf_mode_text);
729EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
730
731SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
732 ARIZONA_HPLPF3_1,
733 ARIZONA_LHPF3_MODE_SHIFT,
734 arizona_lhpf_mode_text);
735EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
736
737SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
738 ARIZONA_HPLPF4_1,
739 ARIZONA_LHPF4_MODE_SHIFT,
740 arizona_lhpf_mode_text);
741EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
742
743static const char * const arizona_ng_hold_text[] = {
744 "30ms", "120ms", "250ms", "500ms",
745};
746
747SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
748 ARIZONA_NOISE_GATE_CONTROL,
749 ARIZONA_NGATE_HOLD_SHIFT,
750 arizona_ng_hold_text);
751EXPORT_SYMBOL_GPL(arizona_ng_hold);
752
753static const char * const arizona_in_hpf_cut_text[] = {
754 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
755};
756
757SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
758 ARIZONA_HPF_CONTROL,
759 ARIZONA_IN_HPF_CUT_SHIFT,
760 arizona_in_hpf_cut_text);
761EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
762
763static const char * const arizona_in_dmic_osr_text[] = {
764 "1.536MHz", "3.072MHz", "6.144MHz", "768kHz",
765};
766
767const struct soc_enum arizona_in_dmic_osr[] = {
768 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
769 ARRAY_SIZE(arizona_in_dmic_osr_text),
770 arizona_in_dmic_osr_text),
771 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
772 ARRAY_SIZE(arizona_in_dmic_osr_text),
773 arizona_in_dmic_osr_text),
774 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
775 ARRAY_SIZE(arizona_in_dmic_osr_text),
776 arizona_in_dmic_osr_text),
777 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
778 ARRAY_SIZE(arizona_in_dmic_osr_text),
779 arizona_in_dmic_osr_text),
780};
781EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
782
783static const char * const arizona_anc_input_src_text[] = {
784 "None", "IN1", "IN2", "IN3", "IN4",
785};
786
787static const char * const arizona_anc_channel_src_text[] = {
788 "None", "Left", "Right", "Combine",
789};
790
791const struct soc_enum arizona_anc_input_src[] = {
792 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
793 ARIZONA_IN_RXANCL_SEL_SHIFT,
794 ARRAY_SIZE(arizona_anc_input_src_text),
795 arizona_anc_input_src_text),
796 SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
797 ARIZONA_FCL_MIC_MODE_SEL_SHIFT,
798 ARRAY_SIZE(arizona_anc_channel_src_text),
799 arizona_anc_channel_src_text),
800 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
801 ARIZONA_IN_RXANCR_SEL_SHIFT,
802 ARRAY_SIZE(arizona_anc_input_src_text),
803 arizona_anc_input_src_text),
804 SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
805 ARIZONA_FCR_MIC_MODE_SEL_SHIFT,
806 ARRAY_SIZE(arizona_anc_channel_src_text),
807 arizona_anc_channel_src_text),
808};
809EXPORT_SYMBOL_GPL(arizona_anc_input_src);
810
811static const char * const arizona_anc_ng_texts[] = {
812 "None",
813 "Internal",
814 "External",
815};
816
817SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
818 arizona_anc_ng_texts);
819EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
820
821static const char * const arizona_output_anc_src_text[] = {
822 "None", "RXANCL", "RXANCR",
823};
824
825const struct soc_enum arizona_output_anc_src[] = {
826 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
827 ARIZONA_OUT1L_ANC_SRC_SHIFT,
828 ARRAY_SIZE(arizona_output_anc_src_text),
829 arizona_output_anc_src_text),
830 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
831 ARIZONA_OUT1R_ANC_SRC_SHIFT,
832 ARRAY_SIZE(arizona_output_anc_src_text),
833 arizona_output_anc_src_text),
834 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
835 ARIZONA_OUT2L_ANC_SRC_SHIFT,
836 ARRAY_SIZE(arizona_output_anc_src_text),
837 arizona_output_anc_src_text),
838 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
839 ARIZONA_OUT2R_ANC_SRC_SHIFT,
840 ARRAY_SIZE(arizona_output_anc_src_text),
841 arizona_output_anc_src_text),
842 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
843 ARIZONA_OUT3L_ANC_SRC_SHIFT,
844 ARRAY_SIZE(arizona_output_anc_src_text),
845 arizona_output_anc_src_text),
846 SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
847 ARIZONA_OUT3R_ANC_SRC_SHIFT,
848 ARRAY_SIZE(arizona_output_anc_src_text),
849 arizona_output_anc_src_text),
850 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
851 ARIZONA_OUT4L_ANC_SRC_SHIFT,
852 ARRAY_SIZE(arizona_output_anc_src_text),
853 arizona_output_anc_src_text),
854 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
855 ARIZONA_OUT4R_ANC_SRC_SHIFT,
856 ARRAY_SIZE(arizona_output_anc_src_text),
857 arizona_output_anc_src_text),
858 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
859 ARIZONA_OUT5L_ANC_SRC_SHIFT,
860 ARRAY_SIZE(arizona_output_anc_src_text),
861 arizona_output_anc_src_text),
862 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
863 ARIZONA_OUT5R_ANC_SRC_SHIFT,
864 ARRAY_SIZE(arizona_output_anc_src_text),
865 arizona_output_anc_src_text),
866 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
867 ARIZONA_OUT6L_ANC_SRC_SHIFT,
868 ARRAY_SIZE(arizona_output_anc_src_text),
869 arizona_output_anc_src_text),
870 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
871 ARIZONA_OUT6R_ANC_SRC_SHIFT,
872 ARRAY_SIZE(arizona_output_anc_src_text),
873 arizona_output_anc_src_text),
874};
875EXPORT_SYMBOL_GPL(arizona_output_anc_src);
876
877const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
878 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
879 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0),
880 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0),
881 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0),
882};
883EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
884
885static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
886{
887 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
888 unsigned int val;
889 int i;
890
891 if (ena)
892 val = ARIZONA_IN_VU;
893 else
894 val = 0;
895
896 for (i = 0; i < priv->num_inputs; i++)
897 snd_soc_update_bits(codec,
898 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
899 ARIZONA_IN_VU, val);
900}
901
902bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
903{
904 unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
905 unsigned int val = snd_soc_read(codec, reg);
906
907 return !(val & ARIZONA_IN1_MODE_MASK);
908}
909EXPORT_SYMBOL_GPL(arizona_input_analog);
910
911int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
912 int event)
913{
914 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
915 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
916 unsigned int reg;
917
918 if (w->shift % 2)
919 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
920 else
921 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
922
923 switch (event) {
924 case SND_SOC_DAPM_PRE_PMU:
925 priv->in_pending++;
926 break;
927 case SND_SOC_DAPM_POST_PMU:
928 snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0);
929
930
931 priv->in_pending--;
932 if (priv->in_pending == 0) {
933 msleep(1);
934 arizona_in_set_vu(codec, 1);
935 }
936 break;
937 case SND_SOC_DAPM_PRE_PMD:
938 snd_soc_update_bits(codec, reg,
939 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
940 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
941 break;
942 case SND_SOC_DAPM_POST_PMD:
943
944 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
945 if (reg == 0)
946 arizona_in_set_vu(codec, 0);
947 break;
948 default:
949 break;
950 }
951
952 return 0;
953}
954EXPORT_SYMBOL_GPL(arizona_in_ev);
955
956int arizona_out_ev(struct snd_soc_dapm_widget *w,
957 struct snd_kcontrol *kcontrol,
958 int event)
959{
960 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
961 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
962 struct arizona *arizona = priv->arizona;
963
964 switch (event) {
965 case SND_SOC_DAPM_PRE_PMU:
966 switch (w->shift) {
967 case ARIZONA_OUT1L_ENA_SHIFT:
968 case ARIZONA_OUT1R_ENA_SHIFT:
969 case ARIZONA_OUT2L_ENA_SHIFT:
970 case ARIZONA_OUT2R_ENA_SHIFT:
971 case ARIZONA_OUT3L_ENA_SHIFT:
972 case ARIZONA_OUT3R_ENA_SHIFT:
973 priv->out_up_pending++;
974 priv->out_up_delay += 17;
975 break;
976 case ARIZONA_OUT4L_ENA_SHIFT:
977 case ARIZONA_OUT4R_ENA_SHIFT:
978 priv->out_up_pending++;
979 switch (arizona->type) {
980 case WM5102:
981 case WM8997:
982 break;
983 default:
984 priv->out_up_delay += 10;
985 break;
986 }
987 break;
988 default:
989 break;
990 }
991 break;
992 case SND_SOC_DAPM_POST_PMU:
993 switch (w->shift) {
994 case ARIZONA_OUT1L_ENA_SHIFT:
995 case ARIZONA_OUT1R_ENA_SHIFT:
996 case ARIZONA_OUT2L_ENA_SHIFT:
997 case ARIZONA_OUT2R_ENA_SHIFT:
998 case ARIZONA_OUT3L_ENA_SHIFT:
999 case ARIZONA_OUT3R_ENA_SHIFT:
1000 case ARIZONA_OUT4L_ENA_SHIFT:
1001 case ARIZONA_OUT4R_ENA_SHIFT:
1002 priv->out_up_pending--;
1003 if (!priv->out_up_pending && priv->out_up_delay) {
1004 dev_dbg(codec->dev, "Power up delay: %d\n",
1005 priv->out_up_delay);
1006 msleep(priv->out_up_delay);
1007 priv->out_up_delay = 0;
1008 }
1009 break;
1010
1011 default:
1012 break;
1013 }
1014 break;
1015 case SND_SOC_DAPM_PRE_PMD:
1016 switch (w->shift) {
1017 case ARIZONA_OUT1L_ENA_SHIFT:
1018 case ARIZONA_OUT1R_ENA_SHIFT:
1019 case ARIZONA_OUT2L_ENA_SHIFT:
1020 case ARIZONA_OUT2R_ENA_SHIFT:
1021 case ARIZONA_OUT3L_ENA_SHIFT:
1022 case ARIZONA_OUT3R_ENA_SHIFT:
1023 priv->out_down_pending++;
1024 priv->out_down_delay++;
1025 break;
1026 case ARIZONA_OUT4L_ENA_SHIFT:
1027 case ARIZONA_OUT4R_ENA_SHIFT:
1028 priv->out_down_pending++;
1029 switch (arizona->type) {
1030 case WM5102:
1031 case WM8997:
1032 break;
1033 case WM8998:
1034 case WM1814:
1035 priv->out_down_delay += 5;
1036 break;
1037 default:
1038 priv->out_down_delay++;
1039 break;
1040 }
1041 default:
1042 break;
1043 }
1044 break;
1045 case SND_SOC_DAPM_POST_PMD:
1046 switch (w->shift) {
1047 case ARIZONA_OUT1L_ENA_SHIFT:
1048 case ARIZONA_OUT1R_ENA_SHIFT:
1049 case ARIZONA_OUT2L_ENA_SHIFT:
1050 case ARIZONA_OUT2R_ENA_SHIFT:
1051 case ARIZONA_OUT3L_ENA_SHIFT:
1052 case ARIZONA_OUT3R_ENA_SHIFT:
1053 case ARIZONA_OUT4L_ENA_SHIFT:
1054 case ARIZONA_OUT4R_ENA_SHIFT:
1055 priv->out_down_pending--;
1056 if (!priv->out_down_pending && priv->out_down_delay) {
1057 dev_dbg(codec->dev, "Power down delay: %d\n",
1058 priv->out_down_delay);
1059 msleep(priv->out_down_delay);
1060 priv->out_down_delay = 0;
1061 }
1062 break;
1063 default:
1064 break;
1065 }
1066 break;
1067 default:
1068 break;
1069 }
1070
1071 return 0;
1072}
1073EXPORT_SYMBOL_GPL(arizona_out_ev);
1074
1075int arizona_hp_ev(struct snd_soc_dapm_widget *w,
1076 struct snd_kcontrol *kcontrol,
1077 int event)
1078{
1079 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1080 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1081 struct arizona *arizona = priv->arizona;
1082 unsigned int mask = 1 << w->shift;
1083 unsigned int val;
1084
1085 switch (event) {
1086 case SND_SOC_DAPM_POST_PMU:
1087 val = mask;
1088 break;
1089 case SND_SOC_DAPM_PRE_PMD:
1090 val = 0;
1091 break;
1092 case SND_SOC_DAPM_PRE_PMU:
1093 case SND_SOC_DAPM_POST_PMD:
1094 return arizona_out_ev(w, kcontrol, event);
1095 default:
1096 return -EINVAL;
1097 }
1098
1099
1100 priv->arizona->hp_ena &= ~mask;
1101 priv->arizona->hp_ena |= val;
1102
1103
1104 if (priv->arizona->hpdet_clamp)
1105 val = 0;
1106
1107 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1108 mask, val);
1109
1110 return arizona_out_ev(w, kcontrol, event);
1111}
1112EXPORT_SYMBOL_GPL(arizona_hp_ev);
1113
1114static int arizona_dvfs_enable(struct snd_soc_codec *codec)
1115{
1116 const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1117 struct arizona *arizona = priv->arizona;
1118 int ret;
1119
1120 ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1121 if (ret) {
1122 dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
1123 return ret;
1124 }
1125
1126 ret = regmap_update_bits(arizona->regmap,
1127 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1128 ARIZONA_SUBSYS_MAX_FREQ,
1129 ARIZONA_SUBSYS_MAX_FREQ);
1130 if (ret) {
1131 dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
1132 regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1133 return ret;
1134 }
1135
1136 return 0;
1137}
1138
1139static int arizona_dvfs_disable(struct snd_soc_codec *codec)
1140{
1141 const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1142 struct arizona *arizona = priv->arizona;
1143 int ret;
1144
1145 ret = regmap_update_bits(arizona->regmap,
1146 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1147 ARIZONA_SUBSYS_MAX_FREQ, 0);
1148 if (ret) {
1149 dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
1150 return ret;
1151 }
1152
1153 ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1154 if (ret) {
1155 dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
1156 return ret;
1157 }
1158
1159 return 0;
1160}
1161
1162int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
1163{
1164 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1165 int ret = 0;
1166
1167 mutex_lock(&priv->dvfs_lock);
1168
1169 if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1170 ret = arizona_dvfs_enable(codec);
1171 if (ret)
1172 goto err;
1173 }
1174
1175 priv->dvfs_reqs |= flags;
1176err:
1177 mutex_unlock(&priv->dvfs_lock);
1178 return ret;
1179}
1180EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1181
1182int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
1183{
1184 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1185 unsigned int old_reqs;
1186 int ret = 0;
1187
1188 mutex_lock(&priv->dvfs_lock);
1189
1190 old_reqs = priv->dvfs_reqs;
1191 priv->dvfs_reqs &= ~flags;
1192
1193 if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1194 ret = arizona_dvfs_disable(codec);
1195
1196 mutex_unlock(&priv->dvfs_lock);
1197 return ret;
1198}
1199EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1200
1201int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1202 struct snd_kcontrol *kcontrol, int event)
1203{
1204 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1205 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1206 int ret = 0;
1207
1208 mutex_lock(&priv->dvfs_lock);
1209
1210 switch (event) {
1211 case SND_SOC_DAPM_POST_PMU:
1212 if (priv->dvfs_reqs)
1213 ret = arizona_dvfs_enable(codec);
1214
1215 priv->dvfs_cached = false;
1216 break;
1217 case SND_SOC_DAPM_PRE_PMD:
1218
1219
1220
1221
1222 priv->dvfs_cached = true;
1223
1224 if (priv->dvfs_reqs)
1225 ret = arizona_dvfs_disable(codec);
1226 break;
1227 default:
1228 break;
1229 }
1230
1231 mutex_unlock(&priv->dvfs_lock);
1232 return ret;
1233}
1234EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1235
1236void arizona_init_dvfs(struct arizona_priv *priv)
1237{
1238 mutex_init(&priv->dvfs_lock);
1239}
1240EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1241
1242int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1243 struct snd_kcontrol *kcontrol,
1244 int event)
1245{
1246 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1247 unsigned int val;
1248
1249 switch (event) {
1250 case SND_SOC_DAPM_POST_PMU:
1251 val = 1 << w->shift;
1252 break;
1253 case SND_SOC_DAPM_PRE_PMD:
1254 val = 1 << (w->shift + 1);
1255 break;
1256 default:
1257 return 0;
1258 }
1259
1260 snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val);
1261
1262 return 0;
1263}
1264EXPORT_SYMBOL_GPL(arizona_anc_ev);
1265
1266static unsigned int arizona_opclk_ref_48k_rates[] = {
1267 6144000,
1268 12288000,
1269 24576000,
1270 49152000,
1271};
1272
1273static unsigned int arizona_opclk_ref_44k1_rates[] = {
1274 5644800,
1275 11289600,
1276 22579200,
1277 45158400,
1278};
1279
1280static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
1281 unsigned int freq)
1282{
1283 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1284 unsigned int reg;
1285 unsigned int *rates;
1286 int ref, div, refclk;
1287
1288 switch (clk) {
1289 case ARIZONA_CLK_OPCLK:
1290 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1291 refclk = priv->sysclk;
1292 break;
1293 case ARIZONA_CLK_ASYNC_OPCLK:
1294 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1295 refclk = priv->asyncclk;
1296 break;
1297 default:
1298 return -EINVAL;
1299 }
1300
1301 if (refclk % 8000)
1302 rates = arizona_opclk_ref_44k1_rates;
1303 else
1304 rates = arizona_opclk_ref_48k_rates;
1305
1306 for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1307 rates[ref] <= refclk; ref++) {
1308 div = 1;
1309 while (rates[ref] / div >= freq && div < 32) {
1310 if (rates[ref] / div == freq) {
1311 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
1312 freq);
1313 snd_soc_update_bits(codec, reg,
1314 ARIZONA_OPCLK_DIV_MASK |
1315 ARIZONA_OPCLK_SEL_MASK,
1316 (div <<
1317 ARIZONA_OPCLK_DIV_SHIFT) |
1318 ref);
1319 return 0;
1320 }
1321 div++;
1322 }
1323 }
1324
1325 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
1326 return -EINVAL;
1327}
1328
1329int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1330 struct snd_kcontrol *kcontrol, int event)
1331{
1332 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1333 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
1334 unsigned int val;
1335 int clk_idx;
1336 int ret;
1337
1338 ret = regmap_read(arizona->regmap, w->reg, &val);
1339 if (ret) {
1340 dev_err(codec->dev, "Failed to check clock source: %d\n", ret);
1341 return ret;
1342 }
1343
1344 val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1345
1346 switch (val) {
1347 case ARIZONA_CLK_SRC_MCLK1:
1348 clk_idx = ARIZONA_MCLK1;
1349 break;
1350 case ARIZONA_CLK_SRC_MCLK2:
1351 clk_idx = ARIZONA_MCLK2;
1352 break;
1353 default:
1354 return 0;
1355 }
1356
1357 switch (event) {
1358 case SND_SOC_DAPM_PRE_PMU:
1359 return clk_prepare_enable(arizona->mclk[clk_idx]);
1360 case SND_SOC_DAPM_POST_PMD:
1361 clk_disable_unprepare(arizona->mclk[clk_idx]);
1362 return 0;
1363 default:
1364 return 0;
1365 }
1366}
1367EXPORT_SYMBOL_GPL(arizona_clk_ev);
1368
1369int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1370 int source, unsigned int freq, int dir)
1371{
1372 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1373 struct arizona *arizona = priv->arizona;
1374 char *name;
1375 unsigned int reg;
1376 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1377 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1378 int *clk;
1379
1380 switch (clk_id) {
1381 case ARIZONA_CLK_SYSCLK:
1382 name = "SYSCLK";
1383 reg = ARIZONA_SYSTEM_CLOCK_1;
1384 clk = &priv->sysclk;
1385 mask |= ARIZONA_SYSCLK_FRAC;
1386 break;
1387 case ARIZONA_CLK_ASYNCCLK:
1388 name = "ASYNCCLK";
1389 reg = ARIZONA_ASYNC_CLOCK_1;
1390 clk = &priv->asyncclk;
1391 break;
1392 case ARIZONA_CLK_OPCLK:
1393 case ARIZONA_CLK_ASYNC_OPCLK:
1394 return arizona_set_opclk(codec, clk_id, freq);
1395 default:
1396 return -EINVAL;
1397 }
1398
1399 switch (freq) {
1400 case 5644800:
1401 case 6144000:
1402 break;
1403 case 11289600:
1404 case 12288000:
1405 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1406 break;
1407 case 22579200:
1408 case 24576000:
1409 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1410 break;
1411 case 45158400:
1412 case 49152000:
1413 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1414 break;
1415 case 67737600:
1416 case 73728000:
1417 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1418 break;
1419 case 90316800:
1420 case 98304000:
1421 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1422 break;
1423 case 135475200:
1424 case 147456000:
1425 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1426 break;
1427 case 0:
1428 dev_dbg(arizona->dev, "%s cleared\n", name);
1429 *clk = freq;
1430 return 0;
1431 default:
1432 return -EINVAL;
1433 }
1434
1435 *clk = freq;
1436
1437 if (freq % 6144000)
1438 val |= ARIZONA_SYSCLK_FRAC;
1439
1440 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1441
1442 return regmap_update_bits(arizona->regmap, reg, mask, val);
1443}
1444EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1445
1446static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1447{
1448 struct snd_soc_codec *codec = dai->codec;
1449 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1450 struct arizona *arizona = priv->arizona;
1451 int lrclk, bclk, mode, base;
1452
1453 base = dai->driver->base;
1454
1455 lrclk = 0;
1456 bclk = 0;
1457
1458 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1459 case SND_SOC_DAIFMT_DSP_A:
1460 mode = ARIZONA_FMT_DSP_MODE_A;
1461 break;
1462 case SND_SOC_DAIFMT_DSP_B:
1463 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1464 != SND_SOC_DAIFMT_CBM_CFM) {
1465 arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1466 return -EINVAL;
1467 }
1468 mode = ARIZONA_FMT_DSP_MODE_B;
1469 break;
1470 case SND_SOC_DAIFMT_I2S:
1471 mode = ARIZONA_FMT_I2S_MODE;
1472 break;
1473 case SND_SOC_DAIFMT_LEFT_J:
1474 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1475 != SND_SOC_DAIFMT_CBM_CFM) {
1476 arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1477 return -EINVAL;
1478 }
1479 mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1480 break;
1481 default:
1482 arizona_aif_err(dai, "Unsupported DAI format %d\n",
1483 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1484 return -EINVAL;
1485 }
1486
1487 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1488 case SND_SOC_DAIFMT_CBS_CFS:
1489 break;
1490 case SND_SOC_DAIFMT_CBS_CFM:
1491 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1492 break;
1493 case SND_SOC_DAIFMT_CBM_CFS:
1494 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1495 break;
1496 case SND_SOC_DAIFMT_CBM_CFM:
1497 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1498 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1499 break;
1500 default:
1501 arizona_aif_err(dai, "Unsupported master mode %d\n",
1502 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1503 return -EINVAL;
1504 }
1505
1506 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1507 case SND_SOC_DAIFMT_NB_NF:
1508 break;
1509 case SND_SOC_DAIFMT_IB_IF:
1510 bclk |= ARIZONA_AIF1_BCLK_INV;
1511 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1512 break;
1513 case SND_SOC_DAIFMT_IB_NF:
1514 bclk |= ARIZONA_AIF1_BCLK_INV;
1515 break;
1516 case SND_SOC_DAIFMT_NB_IF:
1517 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1518 break;
1519 default:
1520 return -EINVAL;
1521 }
1522
1523 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1524 ARIZONA_AIF1_BCLK_INV |
1525 ARIZONA_AIF1_BCLK_MSTR,
1526 bclk);
1527 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1528 ARIZONA_AIF1TX_LRCLK_INV |
1529 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1530 regmap_update_bits_async(arizona->regmap,
1531 base + ARIZONA_AIF_RX_PIN_CTRL,
1532 ARIZONA_AIF1RX_LRCLK_INV |
1533 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1534 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1535 ARIZONA_AIF1_FMT_MASK, mode);
1536
1537 return 0;
1538}
1539
1540static const int arizona_48k_bclk_rates[] = {
1541 -1,
1542 48000,
1543 64000,
1544 96000,
1545 128000,
1546 192000,
1547 256000,
1548 384000,
1549 512000,
1550 768000,
1551 1024000,
1552 1536000,
1553 2048000,
1554 3072000,
1555 4096000,
1556 6144000,
1557 8192000,
1558 12288000,
1559 24576000,
1560};
1561
1562static const int arizona_44k1_bclk_rates[] = {
1563 -1,
1564 44100,
1565 58800,
1566 88200,
1567 117600,
1568 177640,
1569 235200,
1570 352800,
1571 470400,
1572 705600,
1573 940800,
1574 1411200,
1575 1881600,
1576 2822400,
1577 3763200,
1578 5644800,
1579 7526400,
1580 11289600,
1581 22579200,
1582};
1583
1584static const unsigned int arizona_sr_vals[] = {
1585 0,
1586 12000,
1587 24000,
1588 48000,
1589 96000,
1590 192000,
1591 384000,
1592 768000,
1593 0,
1594 11025,
1595 22050,
1596 44100,
1597 88200,
1598 176400,
1599 352800,
1600 705600,
1601 4000,
1602 8000,
1603 16000,
1604 32000,
1605 64000,
1606 128000,
1607 256000,
1608 512000,
1609};
1610
1611#define ARIZONA_48K_RATE_MASK 0x0F003E
1612#define ARIZONA_44K1_RATE_MASK 0x003E00
1613#define ARIZONA_RATE_MASK (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1614
1615static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1616 .count = ARRAY_SIZE(arizona_sr_vals),
1617 .list = arizona_sr_vals,
1618};
1619
1620static int arizona_startup(struct snd_pcm_substream *substream,
1621 struct snd_soc_dai *dai)
1622{
1623 struct snd_soc_codec *codec = dai->codec;
1624 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1625 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1626 unsigned int base_rate;
1627
1628 if (!substream->runtime)
1629 return 0;
1630
1631 switch (dai_priv->clk) {
1632 case ARIZONA_CLK_SYSCLK:
1633 base_rate = priv->sysclk;
1634 break;
1635 case ARIZONA_CLK_ASYNCCLK:
1636 base_rate = priv->asyncclk;
1637 break;
1638 default:
1639 return 0;
1640 }
1641
1642 if (base_rate == 0)
1643 dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1644 else if (base_rate % 8000)
1645 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1646 else
1647 dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1648
1649 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1650 SNDRV_PCM_HW_PARAM_RATE,
1651 &dai_priv->constraint);
1652}
1653
1654static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
1655 unsigned int rate)
1656{
1657 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1658 struct arizona *arizona = priv->arizona;
1659 struct reg_sequence dac_comp[] = {
1660 { 0x80, 0x3 },
1661 { ARIZONA_DAC_COMP_1, 0 },
1662 { ARIZONA_DAC_COMP_2, 0 },
1663 { 0x80, 0x0 },
1664 };
1665
1666 mutex_lock(&arizona->dac_comp_lock);
1667
1668 dac_comp[1].def = arizona->dac_comp_coeff;
1669 if (rate >= 176400)
1670 dac_comp[2].def = arizona->dac_comp_enabled;
1671
1672 mutex_unlock(&arizona->dac_comp_lock);
1673
1674 regmap_multi_reg_write(arizona->regmap,
1675 dac_comp,
1676 ARRAY_SIZE(dac_comp));
1677}
1678
1679static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1680 struct snd_pcm_hw_params *params,
1681 struct snd_soc_dai *dai)
1682{
1683 struct snd_soc_codec *codec = dai->codec;
1684 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1685 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1686 int base = dai->driver->base;
1687 int i, sr_val, ret;
1688
1689
1690
1691
1692
1693 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1694 if (arizona_sr_vals[i] == params_rate(params))
1695 break;
1696 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1697 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1698 params_rate(params));
1699 return -EINVAL;
1700 }
1701 sr_val = i;
1702
1703 switch (priv->arizona->type) {
1704 case WM5102:
1705 case WM8997:
1706 if (arizona_sr_vals[sr_val] >= 88200)
1707 ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
1708 else
1709 ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
1710
1711 if (ret) {
1712 arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1713 return ret;
1714 }
1715 break;
1716 default:
1717 break;
1718 }
1719
1720 switch (dai_priv->clk) {
1721 case ARIZONA_CLK_SYSCLK:
1722 switch (priv->arizona->type) {
1723 case WM5102:
1724 arizona_wm5102_set_dac_comp(codec,
1725 params_rate(params));
1726 break;
1727 default:
1728 break;
1729 }
1730
1731 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1732 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1733 if (base)
1734 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1735 ARIZONA_AIF1_RATE_MASK, 0);
1736 break;
1737 case ARIZONA_CLK_ASYNCCLK:
1738 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1739 ARIZONA_ASYNC_SAMPLE_RATE_1_MASK, sr_val);
1740 if (base)
1741 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1742 ARIZONA_AIF1_RATE_MASK,
1743 8 << ARIZONA_AIF1_RATE_SHIFT);
1744 break;
1745 default:
1746 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1747 return -EINVAL;
1748 }
1749
1750 return 0;
1751}
1752
1753static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
1754 int base, int bclk, int lrclk, int frame)
1755{
1756 int val;
1757
1758 val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
1759 if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1760 return true;
1761
1762 val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
1763 if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1764 return true;
1765
1766 val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
1767 if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1768 ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1769 return true;
1770
1771 return false;
1772}
1773
1774static int arizona_hw_params(struct snd_pcm_substream *substream,
1775 struct snd_pcm_hw_params *params,
1776 struct snd_soc_dai *dai)
1777{
1778 struct snd_soc_codec *codec = dai->codec;
1779 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1780 struct arizona *arizona = priv->arizona;
1781 int base = dai->driver->base;
1782 const int *rates;
1783 int i, ret, val;
1784 int channels = params_channels(params);
1785 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1786 int tdm_width = arizona->tdm_width[dai->id - 1];
1787 int tdm_slots = arizona->tdm_slots[dai->id - 1];
1788 int bclk, lrclk, wl, frame, bclk_target;
1789 bool reconfig;
1790 unsigned int aif_tx_state, aif_rx_state;
1791
1792 if (params_rate(params) % 4000)
1793 rates = &arizona_44k1_bclk_rates[0];
1794 else
1795 rates = &arizona_48k_bclk_rates[0];
1796
1797 wl = params_width(params);
1798
1799 if (tdm_slots) {
1800 arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1801 tdm_slots, tdm_width);
1802 bclk_target = tdm_slots * tdm_width * params_rate(params);
1803 channels = tdm_slots;
1804 } else {
1805 bclk_target = snd_soc_params_to_bclk(params);
1806 tdm_width = wl;
1807 }
1808
1809 if (chan_limit && chan_limit < channels) {
1810 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1811 bclk_target /= channels;
1812 bclk_target *= chan_limit;
1813 }
1814
1815
1816 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1817 val &= ARIZONA_AIF1_FMT_MASK;
1818 if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1819 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1820 bclk_target /= channels;
1821 bclk_target *= channels + 1;
1822 }
1823
1824 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1825 if (rates[i] >= bclk_target &&
1826 rates[i] % params_rate(params) == 0) {
1827 bclk = i;
1828 break;
1829 }
1830 }
1831 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1832 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1833 params_rate(params));
1834 return -EINVAL;
1835 }
1836
1837 lrclk = rates[bclk] / params_rate(params);
1838
1839 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1840 rates[bclk], rates[bclk] / lrclk);
1841
1842 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1843
1844 reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
1845
1846 if (reconfig) {
1847
1848 aif_tx_state = snd_soc_read(codec,
1849 base + ARIZONA_AIF_TX_ENABLES);
1850 aif_rx_state = snd_soc_read(codec,
1851 base + ARIZONA_AIF_RX_ENABLES);
1852
1853 regmap_update_bits_async(arizona->regmap,
1854 base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
1855 regmap_update_bits(arizona->regmap,
1856 base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1857 }
1858
1859 ret = arizona_hw_params_rate(substream, params, dai);
1860 if (ret != 0)
1861 goto restore_aif;
1862
1863 if (reconfig) {
1864 regmap_update_bits_async(arizona->regmap,
1865 base + ARIZONA_AIF_BCLK_CTRL,
1866 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1867 regmap_update_bits_async(arizona->regmap,
1868 base + ARIZONA_AIF_TX_BCLK_RATE,
1869 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1870 regmap_update_bits_async(arizona->regmap,
1871 base + ARIZONA_AIF_RX_BCLK_RATE,
1872 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1873 regmap_update_bits_async(arizona->regmap,
1874 base + ARIZONA_AIF_FRAME_CTRL_1,
1875 ARIZONA_AIF1TX_WL_MASK |
1876 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1877 regmap_update_bits(arizona->regmap,
1878 base + ARIZONA_AIF_FRAME_CTRL_2,
1879 ARIZONA_AIF1RX_WL_MASK |
1880 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1881 }
1882
1883restore_aif:
1884 if (reconfig) {
1885
1886 regmap_update_bits_async(arizona->regmap,
1887 base + ARIZONA_AIF_TX_ENABLES,
1888 0xff, aif_tx_state);
1889 regmap_update_bits(arizona->regmap,
1890 base + ARIZONA_AIF_RX_ENABLES,
1891 0xff, aif_rx_state);
1892 }
1893 return ret;
1894}
1895
1896static const char *arizona_dai_clk_str(int clk_id)
1897{
1898 switch (clk_id) {
1899 case ARIZONA_CLK_SYSCLK:
1900 return "SYSCLK";
1901 case ARIZONA_CLK_ASYNCCLK:
1902 return "ASYNCCLK";
1903 default:
1904 return "Unknown clock";
1905 }
1906}
1907
1908static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1909 int clk_id, unsigned int freq, int dir)
1910{
1911 struct snd_soc_codec *codec = dai->codec;
1912 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1913 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1914 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1915 struct snd_soc_dapm_route routes[2];
1916
1917 switch (clk_id) {
1918 case ARIZONA_CLK_SYSCLK:
1919 case ARIZONA_CLK_ASYNCCLK:
1920 break;
1921 default:
1922 return -EINVAL;
1923 }
1924
1925 if (clk_id == dai_priv->clk)
1926 return 0;
1927
1928 if (dai->active) {
1929 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1930 dai->id);
1931 return -EBUSY;
1932 }
1933
1934 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1935 arizona_dai_clk_str(clk_id));
1936
1937 memset(&routes, 0, sizeof(routes));
1938 routes[0].sink = dai->driver->capture.stream_name;
1939 routes[1].sink = dai->driver->playback.stream_name;
1940
1941 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1942 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1943 snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1944
1945 routes[0].source = arizona_dai_clk_str(clk_id);
1946 routes[1].source = arizona_dai_clk_str(clk_id);
1947 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1948
1949 dai_priv->clk = clk_id;
1950
1951 return snd_soc_dapm_sync(dapm);
1952}
1953
1954static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1955{
1956 struct snd_soc_codec *codec = dai->codec;
1957 int base = dai->driver->base;
1958 unsigned int reg;
1959
1960 if (tristate)
1961 reg = ARIZONA_AIF1_TRI;
1962 else
1963 reg = 0;
1964
1965 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1966 ARIZONA_AIF1_TRI, reg);
1967}
1968
1969static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1970 unsigned int base,
1971 int channels, unsigned int mask)
1972{
1973 struct snd_soc_codec *codec = dai->codec;
1974 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1975 struct arizona *arizona = priv->arizona;
1976 int slot, i;
1977
1978 for (i = 0; i < channels; ++i) {
1979 slot = ffs(mask) - 1;
1980 if (slot < 0)
1981 return;
1982
1983 regmap_write(arizona->regmap, base + i, slot);
1984
1985 mask &= ~(1 << slot);
1986 }
1987
1988 if (mask)
1989 arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1990}
1991
1992static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1993 unsigned int rx_mask, int slots, int slot_width)
1994{
1995 struct snd_soc_codec *codec = dai->codec;
1996 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1997 struct arizona *arizona = priv->arizona;
1998 int base = dai->driver->base;
1999 int rx_max_chan = dai->driver->playback.channels_max;
2000 int tx_max_chan = dai->driver->capture.channels_max;
2001
2002
2003 if (dai->id > ARIZONA_MAX_AIF)
2004 return -ENOTSUPP;
2005
2006 if (slots == 0) {
2007 tx_mask = (1 << tx_max_chan) - 1;
2008 rx_mask = (1 << rx_max_chan) - 1;
2009 }
2010
2011 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2012 tx_max_chan, tx_mask);
2013 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2014 rx_max_chan, rx_mask);
2015
2016 arizona->tdm_width[dai->id - 1] = slot_width;
2017 arizona->tdm_slots[dai->id - 1] = slots;
2018
2019 return 0;
2020}
2021
2022const struct snd_soc_dai_ops arizona_dai_ops = {
2023 .startup = arizona_startup,
2024 .set_fmt = arizona_set_fmt,
2025 .set_tdm_slot = arizona_set_tdm_slot,
2026 .hw_params = arizona_hw_params,
2027 .set_sysclk = arizona_dai_set_sysclk,
2028 .set_tristate = arizona_set_tristate,
2029};
2030EXPORT_SYMBOL_GPL(arizona_dai_ops);
2031
2032const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2033 .startup = arizona_startup,
2034 .hw_params = arizona_hw_params_rate,
2035 .set_sysclk = arizona_dai_set_sysclk,
2036};
2037EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2038
2039int arizona_init_dai(struct arizona_priv *priv, int id)
2040{
2041 struct arizona_dai_priv *dai_priv = &priv->dai[id];
2042
2043 dai_priv->clk = ARIZONA_CLK_SYSCLK;
2044 dai_priv->constraint = arizona_constraint;
2045
2046 return 0;
2047}
2048EXPORT_SYMBOL_GPL(arizona_init_dai);
2049
2050static struct {
2051 unsigned int min;
2052 unsigned int max;
2053 u16 fratio;
2054 int ratio;
2055} fll_fratios[] = {
2056 { 0, 64000, 4, 16 },
2057 { 64000, 128000, 3, 8 },
2058 { 128000, 256000, 2, 4 },
2059 { 256000, 1000000, 1, 2 },
2060 { 1000000, 13500000, 0, 1 },
2061};
2062
2063static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2064 13500000,
2065 6144000,
2066 6144000,
2067 3072000,
2068 3072000,
2069 2822400,
2070 2822400,
2071 1536000,
2072 1536000,
2073 1536000,
2074 1536000,
2075 1536000,
2076 1536000,
2077 1536000,
2078 1536000,
2079 768000,
2080};
2081
2082static struct {
2083 unsigned int min;
2084 unsigned int max;
2085 u16 gain;
2086} fll_gains[] = {
2087 { 0, 256000, 0 },
2088 { 256000, 1000000, 2 },
2089 { 1000000, 13500000, 4 },
2090};
2091
2092struct arizona_fll_cfg {
2093 int n;
2094 unsigned int theta;
2095 unsigned int lambda;
2096 int refdiv;
2097 int outdiv;
2098 int fratio;
2099 int gain;
2100};
2101
2102static int arizona_validate_fll(struct arizona_fll *fll,
2103 unsigned int Fref,
2104 unsigned int Fout)
2105{
2106 unsigned int Fvco_min;
2107
2108 if (fll->fout && Fout != fll->fout) {
2109 arizona_fll_err(fll,
2110 "Can't change output on active FLL\n");
2111 return -EINVAL;
2112 }
2113
2114 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2115 arizona_fll_err(fll,
2116 "Can't scale %dMHz in to <=13.5MHz\n",
2117 Fref);
2118 return -EINVAL;
2119 }
2120
2121 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2122 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2123 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2124 Fout);
2125 return -EINVAL;
2126 }
2127
2128 return 0;
2129}
2130
2131static int arizona_find_fratio(unsigned int Fref, int *fratio)
2132{
2133 int i;
2134
2135
2136 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2137 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2138 if (fratio)
2139 *fratio = fll_fratios[i].fratio;
2140 return fll_fratios[i].ratio;
2141 }
2142 }
2143
2144 return -EINVAL;
2145}
2146
2147static int arizona_calc_fratio(struct arizona_fll *fll,
2148 struct arizona_fll_cfg *cfg,
2149 unsigned int target,
2150 unsigned int Fref, bool sync)
2151{
2152 int init_ratio, ratio;
2153 int refdiv, div;
2154
2155
2156 div = 1;
2157 cfg->refdiv = 0;
2158 while (Fref > ARIZONA_FLL_MAX_FREF) {
2159 div *= 2;
2160 Fref /= 2;
2161 cfg->refdiv++;
2162
2163 if (div > ARIZONA_FLL_MAX_REFDIV)
2164 return -EINVAL;
2165 }
2166
2167
2168 init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2169 if (init_ratio < 0) {
2170 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2171 Fref);
2172 return init_ratio;
2173 }
2174
2175 switch (fll->arizona->type) {
2176 case WM5102:
2177 case WM8997:
2178 return init_ratio;
2179 case WM5110:
2180 case WM8280:
2181 if (fll->arizona->rev < 3 || sync)
2182 return init_ratio;
2183 break;
2184 default:
2185 if (sync)
2186 return init_ratio;
2187 break;
2188 }
2189
2190 cfg->fratio = init_ratio - 1;
2191
2192
2193 refdiv = cfg->refdiv;
2194
2195 arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2196 init_ratio, Fref, refdiv);
2197
2198 while (div <= ARIZONA_FLL_MAX_REFDIV) {
2199
2200
2201
2202 for (ratio = init_ratio; ratio > 0; ratio--) {
2203 if (target % (ratio * Fref)) {
2204 cfg->refdiv = refdiv;
2205 cfg->fratio = ratio - 1;
2206 arizona_fll_dbg(fll,
2207 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2208 Fref, refdiv, div, ratio);
2209 return ratio;
2210 }
2211 }
2212
2213 for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2214 ratio++) {
2215 if ((ARIZONA_FLL_VCO_CORNER / 2) /
2216 (fll->vco_mult * ratio) < Fref) {
2217 arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2218 break;
2219 }
2220
2221 if (Fref > pseudo_fref_max[ratio - 1]) {
2222 arizona_fll_dbg(fll,
2223 "pseudo: exceeded max fref(%u) for ratio=%u\n",
2224 pseudo_fref_max[ratio - 1],
2225 ratio);
2226 break;
2227 }
2228
2229 if (target % (ratio * Fref)) {
2230 cfg->refdiv = refdiv;
2231 cfg->fratio = ratio - 1;
2232 arizona_fll_dbg(fll,
2233 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2234 Fref, refdiv, div, ratio);
2235 return ratio;
2236 }
2237 }
2238
2239 div *= 2;
2240 Fref /= 2;
2241 refdiv++;
2242 init_ratio = arizona_find_fratio(Fref, NULL);
2243 arizona_fll_dbg(fll,
2244 "pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2245 Fref, refdiv, div, init_ratio);
2246 }
2247
2248 arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2249 return cfg->fratio + 1;
2250}
2251
2252static int arizona_calc_fll(struct arizona_fll *fll,
2253 struct arizona_fll_cfg *cfg,
2254 unsigned int Fref, bool sync)
2255{
2256 unsigned int target, div, gcd_fll;
2257 int i, ratio;
2258
2259 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2260
2261
2262 div = ARIZONA_FLL_MIN_OUTDIV;
2263 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2264 div++;
2265 if (div > ARIZONA_FLL_MAX_OUTDIV)
2266 return -EINVAL;
2267 }
2268 target = fll->fout * div / fll->vco_mult;
2269 cfg->outdiv = div;
2270
2271 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2272
2273
2274 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2275 if (ratio < 0)
2276 return ratio;
2277
2278
2279 Fref = Fref / (1 << cfg->refdiv);
2280
2281 cfg->n = target / (ratio * Fref);
2282
2283 if (target % (ratio * Fref)) {
2284 gcd_fll = gcd(target, ratio * Fref);
2285 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2286
2287 cfg->theta = (target - (cfg->n * ratio * Fref))
2288 / gcd_fll;
2289 cfg->lambda = (ratio * Fref) / gcd_fll;
2290 } else {
2291 cfg->theta = 0;
2292 cfg->lambda = 0;
2293 }
2294
2295
2296
2297
2298
2299 while (cfg->lambda >= (1 << 16)) {
2300 cfg->theta >>= 1;
2301 cfg->lambda >>= 1;
2302 }
2303
2304 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2305 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2306 cfg->gain = fll_gains[i].gain;
2307 break;
2308 }
2309 }
2310 if (i == ARRAY_SIZE(fll_gains)) {
2311 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2312 Fref);
2313 return -EINVAL;
2314 }
2315
2316 arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2317 cfg->n, cfg->theta, cfg->lambda);
2318 arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2319 cfg->fratio, ratio, cfg->outdiv,
2320 cfg->refdiv, 1 << cfg->refdiv);
2321 arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2322
2323 return 0;
2324
2325}
2326
2327static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2328 struct arizona_fll_cfg *cfg, int source,
2329 bool sync)
2330{
2331 regmap_update_bits_async(arizona->regmap, base + 3,
2332 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2333 regmap_update_bits_async(arizona->regmap, base + 4,
2334 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2335 regmap_update_bits_async(arizona->regmap, base + 5,
2336 ARIZONA_FLL1_FRATIO_MASK,
2337 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2338 regmap_update_bits_async(arizona->regmap, base + 6,
2339 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2340 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2341 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2342 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2343
2344 if (sync) {
2345 regmap_update_bits(arizona->regmap, base + 0x7,
2346 ARIZONA_FLL1_GAIN_MASK,
2347 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2348 } else {
2349 regmap_update_bits(arizona->regmap, base + 0x5,
2350 ARIZONA_FLL1_OUTDIV_MASK,
2351 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2352 regmap_update_bits(arizona->regmap, base + 0x9,
2353 ARIZONA_FLL1_GAIN_MASK,
2354 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2355 }
2356
2357 regmap_update_bits_async(arizona->regmap, base + 2,
2358 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2359 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2360}
2361
2362static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2363{
2364 struct arizona *arizona = fll->arizona;
2365 unsigned int reg;
2366 int ret;
2367
2368 ret = regmap_read(arizona->regmap, base + 1, ®);
2369 if (ret != 0) {
2370 arizona_fll_err(fll, "Failed to read current state: %d\n",
2371 ret);
2372 return ret;
2373 }
2374
2375 return reg & ARIZONA_FLL1_ENA;
2376}
2377
2378static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2379{
2380 struct arizona *arizona = fll->arizona;
2381 unsigned int val;
2382 struct clk *clk;
2383 int ret;
2384
2385 ret = regmap_read(arizona->regmap, base + 6, &val);
2386 if (ret != 0) {
2387 arizona_fll_err(fll, "Failed to read current source: %d\n",
2388 ret);
2389 return ret;
2390 }
2391
2392 val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2393 val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2394
2395 switch (val) {
2396 case ARIZONA_FLL_SRC_MCLK1:
2397 clk = arizona->mclk[ARIZONA_MCLK1];
2398 break;
2399 case ARIZONA_FLL_SRC_MCLK2:
2400 clk = arizona->mclk[ARIZONA_MCLK2];
2401 break;
2402 default:
2403 return 0;
2404 }
2405
2406 if (ena) {
2407 return clk_prepare_enable(clk);
2408 } else {
2409 clk_disable_unprepare(clk);
2410 return 0;
2411 }
2412}
2413
2414static int arizona_enable_fll(struct arizona_fll *fll)
2415{
2416 struct arizona *arizona = fll->arizona;
2417 bool use_sync = false;
2418 int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2419 int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2420 struct arizona_fll_cfg cfg;
2421 int i;
2422 unsigned int val;
2423
2424 if (already_enabled < 0)
2425 return already_enabled;
2426 if (sync_enabled < 0)
2427 return sync_enabled;
2428
2429 if (already_enabled) {
2430
2431 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2432 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2433 udelay(32);
2434 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2435 ARIZONA_FLL1_GAIN_MASK, 0);
2436
2437 if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2438 arizona_set_fll_clks(fll, fll->base + 0x10, false);
2439 arizona_set_fll_clks(fll, fll->base, false);
2440 }
2441
2442
2443
2444
2445
2446 if (fll->ref_src >= 0 && fll->ref_freq &&
2447 fll->ref_src != fll->sync_src) {
2448 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2449
2450
2451 if (fll->sync_src >= 0 && cfg.lambda)
2452 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2453
2454 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2455 false);
2456 if (fll->sync_src >= 0) {
2457 arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2458
2459 arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2460 fll->sync_src, true);
2461 use_sync = true;
2462 }
2463 } else if (fll->sync_src >= 0) {
2464 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2465
2466 arizona_apply_fll(arizona, fll->base, &cfg,
2467 fll->sync_src, false);
2468
2469 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2470 ARIZONA_FLL1_SYNC_ENA, 0);
2471 } else {
2472 arizona_fll_err(fll, "No clocks provided\n");
2473 return -EINVAL;
2474 }
2475
2476 if (already_enabled && !!sync_enabled != use_sync)
2477 arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2478
2479
2480
2481
2482
2483 if (use_sync && fll->sync_freq > 100000)
2484 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2485 ARIZONA_FLL1_SYNC_BW, 0);
2486 else
2487 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2488 ARIZONA_FLL1_SYNC_BW,
2489 ARIZONA_FLL1_SYNC_BW);
2490
2491 if (!already_enabled)
2492 pm_runtime_get_sync(arizona->dev);
2493
2494 if (use_sync) {
2495 arizona_set_fll_clks(fll, fll->base + 0x10, true);
2496 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2497 ARIZONA_FLL1_SYNC_ENA,
2498 ARIZONA_FLL1_SYNC_ENA);
2499 }
2500 arizona_set_fll_clks(fll, fll->base, true);
2501 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2502 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2503
2504 if (already_enabled)
2505 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2506 ARIZONA_FLL1_FREERUN, 0);
2507
2508 arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2509 val = 0;
2510 for (i = 0; i < 15; i++) {
2511 if (i < 5)
2512 usleep_range(200, 400);
2513 else
2514 msleep(20);
2515
2516 regmap_read(arizona->regmap,
2517 ARIZONA_INTERRUPT_RAW_STATUS_5,
2518 &val);
2519 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2520 break;
2521 }
2522 if (i == 15)
2523 arizona_fll_warn(fll, "Timed out waiting for lock\n");
2524 else
2525 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2526
2527 return 0;
2528}
2529
2530static void arizona_disable_fll(struct arizona_fll *fll)
2531{
2532 struct arizona *arizona = fll->arizona;
2533 bool ref_change, sync_change;
2534
2535 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2536 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2537 regmap_update_bits_check(arizona->regmap, fll->base + 1,
2538 ARIZONA_FLL1_ENA, 0, &ref_change);
2539 regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2540 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2541 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2542 ARIZONA_FLL1_FREERUN, 0);
2543
2544 if (sync_change)
2545 arizona_set_fll_clks(fll, fll->base + 0x10, false);
2546
2547 if (ref_change) {
2548 arizona_set_fll_clks(fll, fll->base, false);
2549 pm_runtime_put_autosuspend(arizona->dev);
2550 }
2551}
2552
2553int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2554 unsigned int Fref, unsigned int Fout)
2555{
2556 int ret = 0;
2557
2558 if (fll->ref_src == source && fll->ref_freq == Fref)
2559 return 0;
2560
2561 if (fll->fout && Fref > 0) {
2562 ret = arizona_validate_fll(fll, Fref, fll->fout);
2563 if (ret != 0)
2564 return ret;
2565 }
2566
2567 fll->ref_src = source;
2568 fll->ref_freq = Fref;
2569
2570 if (fll->fout && Fref > 0) {
2571 ret = arizona_enable_fll(fll);
2572 }
2573
2574 return ret;
2575}
2576EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2577
2578int arizona_set_fll(struct arizona_fll *fll, int source,
2579 unsigned int Fref, unsigned int Fout)
2580{
2581 int ret = 0;
2582
2583 if (fll->sync_src == source &&
2584 fll->sync_freq == Fref && fll->fout == Fout)
2585 return 0;
2586
2587 if (Fout) {
2588 if (fll->ref_src >= 0) {
2589 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2590 if (ret != 0)
2591 return ret;
2592 }
2593
2594 ret = arizona_validate_fll(fll, Fref, Fout);
2595 if (ret != 0)
2596 return ret;
2597 }
2598
2599 fll->sync_src = source;
2600 fll->sync_freq = Fref;
2601 fll->fout = Fout;
2602
2603 if (Fout)
2604 ret = arizona_enable_fll(fll);
2605 else
2606 arizona_disable_fll(fll);
2607
2608 return ret;
2609}
2610EXPORT_SYMBOL_GPL(arizona_set_fll);
2611
2612int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2613 int ok_irq, struct arizona_fll *fll)
2614{
2615 unsigned int val;
2616
2617 fll->id = id;
2618 fll->base = base;
2619 fll->arizona = arizona;
2620 fll->sync_src = ARIZONA_FLL_SRC_NONE;
2621
2622
2623 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2624 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2625 case ARIZONA_CLK_SRC_MCLK1:
2626 case ARIZONA_CLK_SRC_MCLK2:
2627 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2628 break;
2629 default:
2630 fll->ref_src = ARIZONA_FLL_SRC_NONE;
2631 }
2632 fll->ref_freq = 32768;
2633
2634 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2635 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2636 "FLL%d clock OK", id);
2637
2638 regmap_update_bits(arizona->regmap, fll->base + 1,
2639 ARIZONA_FLL1_FREERUN, 0);
2640
2641 return 0;
2642}
2643EXPORT_SYMBOL_GPL(arizona_init_fll);
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
2662{
2663 unsigned int reg, val;
2664
2665 if (output < 1 || output > 6)
2666 return -EINVAL;
2667
2668 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2669
2670 if (diff)
2671 val = ARIZONA_OUT1_MONO;
2672 else
2673 val = 0;
2674
2675 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
2676}
2677EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2678
2679static const struct soc_enum arizona_adsp2_rate_enum[] = {
2680 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2681 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2682 ARIZONA_RATE_ENUM_SIZE,
2683 arizona_rate_text, arizona_rate_val),
2684 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2685 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2686 ARIZONA_RATE_ENUM_SIZE,
2687 arizona_rate_text, arizona_rate_val),
2688 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2689 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2690 ARIZONA_RATE_ENUM_SIZE,
2691 arizona_rate_text, arizona_rate_val),
2692 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2693 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2694 ARIZONA_RATE_ENUM_SIZE,
2695 arizona_rate_text, arizona_rate_val),
2696};
2697
2698const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2699 SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2700 SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2701 SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2702 SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2703};
2704EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2705
2706static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2707{
2708 s16 a = be16_to_cpu(_a);
2709 s16 b = be16_to_cpu(_b);
2710
2711 if (!mode) {
2712 return abs(a) >= 4096;
2713 } else {
2714 if (abs(b) >= 4096)
2715 return true;
2716
2717 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2718 }
2719}
2720
2721int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2722 struct snd_ctl_elem_value *ucontrol)
2723{
2724 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2725 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2726 struct soc_bytes *params = (void *)kcontrol->private_value;
2727 unsigned int val;
2728 __be16 *data;
2729 int len;
2730 int ret;
2731
2732 len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2733
2734 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2735 if (!data)
2736 return -ENOMEM;
2737
2738 data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2739
2740 if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2741 arizona_eq_filter_unstable(true, data[4], data[5]) ||
2742 arizona_eq_filter_unstable(true, data[8], data[9]) ||
2743 arizona_eq_filter_unstable(true, data[12], data[13]) ||
2744 arizona_eq_filter_unstable(false, data[16], data[17])) {
2745 dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2746 ret = -EINVAL;
2747 goto out;
2748 }
2749
2750 ret = regmap_read(arizona->regmap, params->base, &val);
2751 if (ret != 0)
2752 goto out;
2753
2754 val &= ~ARIZONA_EQ1_B1_MODE;
2755 data[0] |= cpu_to_be16(val);
2756
2757 ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2758
2759out:
2760 kfree(data);
2761 return ret;
2762}
2763EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2764
2765int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2766 struct snd_ctl_elem_value *ucontrol)
2767{
2768 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2769 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2770 __be16 *data = (__be16 *)ucontrol->value.bytes.data;
2771 s16 val = be16_to_cpu(*data);
2772
2773 if (abs(val) >= 4096) {
2774 dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2775 return -EINVAL;
2776 }
2777
2778 return snd_soc_bytes_put(kcontrol, ucontrol);
2779}
2780EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2781
2782int arizona_of_get_audio_pdata(struct arizona *arizona)
2783{
2784 struct arizona_pdata *pdata = &arizona->pdata;
2785 struct device_node *np = arizona->dev->of_node;
2786 struct property *prop;
2787 const __be32 *cur;
2788 u32 val;
2789 u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2790 int ret;
2791 int count = 0;
2792
2793 count = 0;
2794 of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2795 if (count == ARRAY_SIZE(pdata->inmode))
2796 break;
2797
2798 pdata->inmode[count] = val;
2799 count++;
2800 }
2801
2802 count = 0;
2803 of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2804 if (count == ARRAY_SIZE(pdata->dmic_ref))
2805 break;
2806
2807 pdata->dmic_ref[count] = val;
2808 count++;
2809 }
2810
2811 count = 0;
2812 of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2813 if (count == ARRAY_SIZE(pdata->out_mono))
2814 break;
2815
2816 pdata->out_mono[count] = !!val;
2817 count++;
2818 }
2819
2820 count = 0;
2821 of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2822 if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2823 break;
2824
2825 pdata->max_channels_clocked[count] = val;
2826 count++;
2827 }
2828
2829 count = 0;
2830 of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2831 if (count == ARRAY_SIZE(pdata->out_vol_limit))
2832 break;
2833
2834 pdata->out_vol_limit[count] = val;
2835 count++;
2836 }
2837
2838 ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2839 pdm_val, ARRAY_SIZE(pdm_val));
2840
2841 if (ret >= 0)
2842 for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2843 pdata->spk_fmt[count] = pdm_val[count];
2844
2845 ret = of_property_read_u32_array(np, "wlf,spk-mute",
2846 pdm_val, ARRAY_SIZE(pdm_val));
2847
2848 if (ret >= 0)
2849 for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2850 pdata->spk_mute[count] = pdm_val[count];
2851
2852 return 0;
2853}
2854EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2855
2856MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2857MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2858MODULE_LICENSE("GPL");
2859