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