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