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