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