]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - sound/soc/codecs/arizona.c
mfd: Add Ricoh RN5T618 PMIC core driver
[mirror_ubuntu-eoan-kernel.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>
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>
b63144e6 22#include <linux/mfd/arizona/gpio.h>
07ed873e
MB
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
07ed873e
MB
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, ...) \
9092a6ea 69 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
07ed873e
MB
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, ...) \
9092a6ea 76 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
07ed873e 77
56447e13
MB
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;
f4a76e7c 86 int val;
56447e13
MB
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) {
3c43c695 104 regmap_write_async(arizona->regmap, 0x4f5, 0x25a);
56447e13
MB
105 priv->spk_ena_pending = true;
106 }
107 break;
108 case SND_SOC_DAPM_POST_PMU:
f4a76e7c 109 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
c0fe2c5b 110 if (val & ARIZONA_SPK_OVERHEAT_STS) {
f4a76e7c
MB
111 dev_crit(arizona->dev,
112 "Speaker not enabled due to temperature\n");
113 return -EBUSY;
114 }
115
3c43c695
MB
116 regmap_update_bits_async(arizona->regmap,
117 ARIZONA_OUTPUT_ENABLES_1,
118 1 << w->shift, 1 << w->shift);
f4a76e7c 119
56447e13
MB
120 if (priv->spk_ena_pending) {
121 msleep(75);
3c43c695 122 regmap_write_async(arizona->regmap, 0x4f5, 0xda);
56447e13
MB
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)
3c43c695
MB
131 regmap_write_async(arizona->regmap,
132 0x4f5, 0x25a);
56447e13 133 }
f4a76e7c 134
3c43c695
MB
135 regmap_update_bits_async(arizona->regmap,
136 ARIZONA_OUTPUT_ENABLES_1,
137 1 << w->shift, 0);
56447e13
MB
138 break;
139 case SND_SOC_DAPM_POST_PMD:
140 if (manual_ena) {
141 if (!priv->spk_ena)
3c43c695
MB
142 regmap_write_async(arizona->regmap,
143 0x4f5, 0x0da);
56447e13
MB
144 }
145 break;
146 }
147
148 return 0;
149}
150
899817e2
MB
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);
c0fe2c5b 162 } else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
899817e2
MB
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);
c0fe2c5b 180 } else if (val & ARIZONA_SPK_OVERHEAT_STS) {
899817e2 181 dev_crit(arizona->dev, "Thermal shutdown\n");
f4a76e7c
MB
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);
899817e2
MB
190 }
191
192 return IRQ_HANDLED;
193}
194
56447e13 195static const struct snd_soc_dapm_widget arizona_spkl =
f4a76e7c 196 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
56447e13
MB
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 =
f4a76e7c 201 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
56447e13
MB
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{
899817e2
MB
207 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
208 struct arizona *arizona = priv->arizona;
56447e13
MB
209 int ret;
210
211 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
212 if (ret != 0)
213 return ret;
214
40843aea
CK
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 }
56447e13 225
c0fe2c5b 226 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
899817e2
MB
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
c0fe2c5b 234 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
899817e2
MB
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
56447e13
MB
242 return 0;
243}
244EXPORT_SYMBOL_GPL(arizona_init_spk);
245
b60f363b
CK
246static const struct snd_soc_dapm_route arizona_mono_routes[] = {
247 { "OUT1R", NULL, "OUT1L" },
248 { "OUT2R", NULL, "OUT2L" },
249 { "OUT3R", NULL, "OUT3L" },
250 { "OUT4R", NULL, "OUT4L" },
251 { "OUT5R", NULL, "OUT5L" },
252 { "OUT6R", NULL, "OUT6L" },
253};
254
255int arizona_init_mono(struct snd_soc_codec *codec)
256{
257 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
258 struct arizona *arizona = priv->arizona;
259 int i;
260
261 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
262 if (arizona->pdata.out_mono[i])
263 snd_soc_dapm_add_routes(&codec->dapm,
264 &arizona_mono_routes[i], 1);
265 }
266
267 return 0;
268}
269EXPORT_SYMBOL_GPL(arizona_init_mono);
270
b63144e6
CK
271int arizona_init_gpio(struct snd_soc_codec *codec)
272{
273 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
274 struct arizona *arizona = priv->arizona;
275 int i;
276
277 switch (arizona->type) {
278 case WM5110:
279 snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
b79fae60
CK
280 break;
281 default:
282 break;
b63144e6
CK
283 }
284
285 snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
286
287 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
288 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
289 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
290 snd_soc_dapm_enable_pin(&codec->dapm,
291 "DRC1 Signal Activity");
292 break;
293 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
294 snd_soc_dapm_enable_pin(&codec->dapm,
295 "DRC2 Signal Activity");
296 break;
297 default:
298 break;
299 }
300 }
301
302 return 0;
303}
304EXPORT_SYMBOL_GPL(arizona_init_gpio);
305
07ed873e
MB
306const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
307 "None",
308 "Tone Generator 1",
309 "Tone Generator 2",
310 "Haptics",
311 "AEC",
312 "Mic Mute Mixer",
313 "Noise Generator",
314 "IN1L",
315 "IN1R",
316 "IN2L",
317 "IN2R",
318 "IN3L",
319 "IN3R",
c9c56fd0
MB
320 "IN4L",
321 "IN4R",
07ed873e
MB
322 "AIF1RX1",
323 "AIF1RX2",
324 "AIF1RX3",
325 "AIF1RX4",
326 "AIF1RX5",
327 "AIF1RX6",
328 "AIF1RX7",
329 "AIF1RX8",
330 "AIF2RX1",
331 "AIF2RX2",
e64001e8
RF
332 "AIF2RX3",
333 "AIF2RX4",
334 "AIF2RX5",
335 "AIF2RX6",
07ed873e
MB
336 "AIF3RX1",
337 "AIF3RX2",
338 "SLIMRX1",
339 "SLIMRX2",
340 "SLIMRX3",
341 "SLIMRX4",
342 "SLIMRX5",
343 "SLIMRX6",
344 "SLIMRX7",
345 "SLIMRX8",
346 "EQ1",
347 "EQ2",
348 "EQ3",
349 "EQ4",
350 "DRC1L",
351 "DRC1R",
352 "DRC2L",
353 "DRC2R",
354 "LHPF1",
355 "LHPF2",
356 "LHPF3",
357 "LHPF4",
358 "DSP1.1",
359 "DSP1.2",
360 "DSP1.3",
361 "DSP1.4",
362 "DSP1.5",
363 "DSP1.6",
c922cc4c
MB
364 "DSP2.1",
365 "DSP2.2",
366 "DSP2.3",
367 "DSP2.4",
368 "DSP2.5",
369 "DSP2.6",
370 "DSP3.1",
371 "DSP3.2",
372 "DSP3.3",
373 "DSP3.4",
374 "DSP3.5",
375 "DSP3.6",
376 "DSP4.1",
377 "DSP4.2",
378 "DSP4.3",
379 "DSP4.4",
380 "DSP4.5",
381 "DSP4.6",
07ed873e
MB
382 "ASRC1L",
383 "ASRC1R",
384 "ASRC2L",
385 "ASRC2R",
91660bd6
MB
386 "ISRC1INT1",
387 "ISRC1INT2",
388 "ISRC1INT3",
389 "ISRC1INT4",
390 "ISRC1DEC1",
391 "ISRC1DEC2",
392 "ISRC1DEC3",
393 "ISRC1DEC4",
394 "ISRC2INT1",
395 "ISRC2INT2",
396 "ISRC2INT3",
397 "ISRC2INT4",
398 "ISRC2DEC1",
399 "ISRC2DEC2",
400 "ISRC2DEC3",
401 "ISRC2DEC4",
402 "ISRC3INT1",
403 "ISRC3INT2",
404 "ISRC3INT3",
405 "ISRC3INT4",
406 "ISRC3DEC1",
407 "ISRC3DEC2",
408 "ISRC3DEC3",
409 "ISRC3DEC4",
07ed873e
MB
410};
411EXPORT_SYMBOL_GPL(arizona_mixer_texts);
412
413int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
414 0x00, /* None */
415 0x04, /* Tone */
416 0x05,
417 0x06, /* Haptics */
418 0x08, /* AEC */
419 0x0c, /* Noise mixer */
420 0x0d, /* Comfort noise */
421 0x10, /* IN1L */
422 0x11,
423 0x12,
424 0x13,
425 0x14,
426 0x15,
c9c56fd0
MB
427 0x16,
428 0x17,
07ed873e
MB
429 0x20, /* AIF1RX1 */
430 0x21,
431 0x22,
432 0x23,
433 0x24,
434 0x25,
435 0x26,
436 0x27,
437 0x28, /* AIF2RX1 */
438 0x29,
e64001e8
RF
439 0x2a,
440 0x2b,
441 0x2c,
442 0x2d,
07ed873e
MB
443 0x30, /* AIF3RX1 */
444 0x31,
445 0x38, /* SLIMRX1 */
446 0x39,
447 0x3a,
448 0x3b,
449 0x3c,
450 0x3d,
451 0x3e,
452 0x3f,
453 0x50, /* EQ1 */
454 0x51,
455 0x52,
456 0x53,
457 0x58, /* DRC1L */
458 0x59,
459 0x5a,
460 0x5b,
461 0x60, /* LHPF1 */
462 0x61,
463 0x62,
464 0x63,
465 0x68, /* DSP1.1 */
466 0x69,
467 0x6a,
468 0x6b,
469 0x6c,
470 0x6d,
c922cc4c
MB
471 0x70, /* DSP2.1 */
472 0x71,
473 0x72,
474 0x73,
475 0x74,
476 0x75,
477 0x78, /* DSP3.1 */
478 0x79,
479 0x7a,
480 0x7b,
481 0x7c,
482 0x7d,
483 0x80, /* DSP4.1 */
484 0x81,
485 0x82,
486 0x83,
487 0x84,
488 0x85,
07ed873e
MB
489 0x90, /* ASRC1L */
490 0x91,
491 0x92,
492 0x93,
91660bd6
MB
493 0xa0, /* ISRC1INT1 */
494 0xa1,
495 0xa2,
496 0xa3,
497 0xa4, /* ISRC1DEC1 */
498 0xa5,
499 0xa6,
500 0xa7,
501 0xa8, /* ISRC2DEC1 */
502 0xa9,
503 0xaa,
504 0xab,
505 0xac, /* ISRC2INT1 */
506 0xad,
507 0xae,
508 0xaf,
509 0xb0, /* ISRC3DEC1 */
510 0xb1,
511 0xb2,
512 0xb3,
513 0xb4, /* ISRC3INT1 */
514 0xb5,
515 0xb6,
516 0xb7,
07ed873e
MB
517};
518EXPORT_SYMBOL_GPL(arizona_mixer_values);
519
520const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
521EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
522
dc91428a
MB
523const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
524 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
525};
526EXPORT_SYMBOL_GPL(arizona_rate_text);
527
528const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
529 0, 1, 2, 8,
530};
531EXPORT_SYMBOL_GPL(arizona_rate_val);
532
533
fbedc8cb
CK
534const struct soc_enum arizona_isrc_fsh[] = {
535 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
536 ARIZONA_ISRC1_FSH_SHIFT, 0xf,
537 ARIZONA_RATE_ENUM_SIZE,
538 arizona_rate_text, arizona_rate_val),
539 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
540 ARIZONA_ISRC2_FSH_SHIFT, 0xf,
541 ARIZONA_RATE_ENUM_SIZE,
542 arizona_rate_text, arizona_rate_val),
543 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
544 ARIZONA_ISRC3_FSH_SHIFT, 0xf,
545 ARIZONA_RATE_ENUM_SIZE,
546 arizona_rate_text, arizona_rate_val),
547};
548EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
549
dc91428a
MB
550const struct soc_enum arizona_isrc_fsl[] = {
551 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
552 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
553 ARIZONA_RATE_ENUM_SIZE,
554 arizona_rate_text, arizona_rate_val),
555 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
556 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
557 ARIZONA_RATE_ENUM_SIZE,
558 arizona_rate_text, arizona_rate_val),
559 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
560 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
561 ARIZONA_RATE_ENUM_SIZE,
562 arizona_rate_text, arizona_rate_val),
563};
564EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
565
56d37d85
CK
566const struct soc_enum arizona_asrc_rate1 =
567 SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
568 ARIZONA_ASRC_RATE1_SHIFT, 0xf,
569 ARIZONA_RATE_ENUM_SIZE - 1,
570 arizona_rate_text, arizona_rate_val);
571EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
572
e853a00f
MB
573static const char *arizona_vol_ramp_text[] = {
574 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
575 "15ms/6dB", "30ms/6dB",
576};
577
27ca2c30
TI
578SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
579 ARIZONA_INPUT_VOLUME_RAMP,
580 ARIZONA_IN_VD_RAMP_SHIFT,
581 arizona_vol_ramp_text);
e853a00f
MB
582EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
583
27ca2c30
TI
584SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
585 ARIZONA_INPUT_VOLUME_RAMP,
586 ARIZONA_IN_VI_RAMP_SHIFT,
587 arizona_vol_ramp_text);
e853a00f
MB
588EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
589
27ca2c30
TI
590SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
591 ARIZONA_OUTPUT_VOLUME_RAMP,
592 ARIZONA_OUT_VD_RAMP_SHIFT,
593 arizona_vol_ramp_text);
e853a00f
MB
594EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
595
27ca2c30
TI
596SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
597 ARIZONA_OUTPUT_VOLUME_RAMP,
598 ARIZONA_OUT_VI_RAMP_SHIFT,
599 arizona_vol_ramp_text);
e853a00f
MB
600EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
601
07ed873e
MB
602static const char *arizona_lhpf_mode_text[] = {
603 "Low-pass", "High-pass"
604};
605
27ca2c30
TI
606SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
607 ARIZONA_HPLPF1_1,
608 ARIZONA_LHPF1_MODE_SHIFT,
609 arizona_lhpf_mode_text);
07ed873e
MB
610EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
611
27ca2c30
TI
612SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
613 ARIZONA_HPLPF2_1,
614 ARIZONA_LHPF2_MODE_SHIFT,
615 arizona_lhpf_mode_text);
07ed873e
MB
616EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
617
27ca2c30
TI
618SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
619 ARIZONA_HPLPF3_1,
620 ARIZONA_LHPF3_MODE_SHIFT,
621 arizona_lhpf_mode_text);
07ed873e
MB
622EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
623
27ca2c30
TI
624SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
625 ARIZONA_HPLPF4_1,
626 ARIZONA_LHPF4_MODE_SHIFT,
627 arizona_lhpf_mode_text);
07ed873e
MB
628EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
629
845571cc
MB
630static const char *arizona_ng_hold_text[] = {
631 "30ms", "120ms", "250ms", "500ms",
632};
633
27ca2c30
TI
634SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
635 ARIZONA_NOISE_GATE_CONTROL,
636 ARIZONA_NGATE_HOLD_SHIFT,
637 arizona_ng_hold_text);
845571cc
MB
638EXPORT_SYMBOL_GPL(arizona_ng_hold);
639
254dc326
CK
640static const char * const arizona_in_hpf_cut_text[] = {
641 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
642};
643
27ca2c30
TI
644SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
645 ARIZONA_HPF_CONTROL,
646 ARIZONA_IN_HPF_CUT_SHIFT,
647 arizona_in_hpf_cut_text);
254dc326
CK
648EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
649
c7f38435
CK
650static const char * const arizona_in_dmic_osr_text[] = {
651 "1.536MHz", "3.072MHz", "6.144MHz",
652};
653
654const struct soc_enum arizona_in_dmic_osr[] = {
655 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
656 ARRAY_SIZE(arizona_in_dmic_osr_text),
657 arizona_in_dmic_osr_text),
658 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
659 ARRAY_SIZE(arizona_in_dmic_osr_text),
660 arizona_in_dmic_osr_text),
661 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
662 ARRAY_SIZE(arizona_in_dmic_osr_text),
663 arizona_in_dmic_osr_text),
664 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
665 ARRAY_SIZE(arizona_in_dmic_osr_text),
666 arizona_in_dmic_osr_text),
667};
668EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
669
ddbce97c
MB
670static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
671{
672 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
673 unsigned int val;
674 int i;
675
676 if (ena)
677 val = ARIZONA_IN_VU;
678 else
679 val = 0;
680
681 for (i = 0; i < priv->num_inputs; i++)
682 snd_soc_update_bits(codec,
683 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
684 ARIZONA_IN_VU, val);
685}
686
07ed873e
MB
687int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
688 int event)
689{
ddbce97c 690 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
43cd8bf1
MB
691 unsigned int reg;
692
693 if (w->shift % 2)
694 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
695 else
696 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
697
698 switch (event) {
ddbce97c
MB
699 case SND_SOC_DAPM_PRE_PMU:
700 priv->in_pending++;
701 break;
43cd8bf1
MB
702 case SND_SOC_DAPM_POST_PMU:
703 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
ddbce97c
MB
704
705 /* If this is the last input pending then allow VU */
706 priv->in_pending--;
707 if (priv->in_pending == 0) {
708 msleep(1);
709 arizona_in_set_vu(w->codec, 1);
710 }
43cd8bf1
MB
711 break;
712 case SND_SOC_DAPM_PRE_PMD:
ddbce97c
MB
713 snd_soc_update_bits(w->codec, reg,
714 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
715 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
43cd8bf1 716 break;
ddbce97c
MB
717 case SND_SOC_DAPM_POST_PMD:
718 /* Disable volume updates if no inputs are enabled */
719 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
720 if (reg == 0)
721 arizona_in_set_vu(w->codec, 0);
43cd8bf1
MB
722 }
723
07ed873e
MB
724 return 0;
725}
726EXPORT_SYMBOL_GPL(arizona_in_ev);
727
728int arizona_out_ev(struct snd_soc_dapm_widget *w,
729 struct snd_kcontrol *kcontrol,
730 int event)
731{
1a2c7d56
MB
732 switch (event) {
733 case SND_SOC_DAPM_POST_PMU:
734 switch (w->shift) {
735 case ARIZONA_OUT1L_ENA_SHIFT:
736 case ARIZONA_OUT1R_ENA_SHIFT:
737 case ARIZONA_OUT2L_ENA_SHIFT:
738 case ARIZONA_OUT2R_ENA_SHIFT:
739 case ARIZONA_OUT3L_ENA_SHIFT:
740 case ARIZONA_OUT3R_ENA_SHIFT:
741 msleep(17);
742 break;
743
744 default:
745 break;
746 }
747 break;
748 }
749
07ed873e
MB
750 return 0;
751}
752EXPORT_SYMBOL_GPL(arizona_out_ev);
753
f607e31c
MB
754int arizona_hp_ev(struct snd_soc_dapm_widget *w,
755 struct snd_kcontrol *kcontrol,
756 int event)
757{
758 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
3c43c695 759 struct arizona *arizona = priv->arizona;
f607e31c
MB
760 unsigned int mask = 1 << w->shift;
761 unsigned int val;
762
763 switch (event) {
764 case SND_SOC_DAPM_POST_PMU:
765 val = mask;
766 break;
767 case SND_SOC_DAPM_PRE_PMD:
768 val = 0;
769 break;
770 default:
771 return -EINVAL;
772 }
773
774 /* Store the desired state for the HP outputs */
775 priv->arizona->hp_ena &= ~mask;
776 priv->arizona->hp_ena |= val;
777
778 /* Force off if HPDET magic is active */
779 if (priv->arizona->hpdet_magic)
780 val = 0;
781
3c43c695
MB
782 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
783 mask, val);
f607e31c
MB
784
785 return arizona_out_ev(w, kcontrol, event);
786}
787EXPORT_SYMBOL_GPL(arizona_hp_ev);
788
cbd840da
MB
789static unsigned int arizona_sysclk_48k_rates[] = {
790 6144000,
791 12288000,
96e1f18f 792 24576000,
cbd840da 793 49152000,
aeaeee1a
MB
794 73728000,
795 98304000,
796 147456000,
cbd840da
MB
797};
798
799static unsigned int arizona_sysclk_44k1_rates[] = {
800 5644800,
801 11289600,
96e1f18f 802 22579200,
cbd840da 803 45158400,
aeaeee1a
MB
804 67737600,
805 90316800,
806 135475200,
cbd840da
MB
807};
808
809static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
810 unsigned int freq)
811{
812 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
813 unsigned int reg;
814 unsigned int *rates;
815 int ref, div, refclk;
816
817 switch (clk) {
818 case ARIZONA_CLK_OPCLK:
819 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
820 refclk = priv->sysclk;
821 break;
822 case ARIZONA_CLK_ASYNC_OPCLK:
823 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
824 refclk = priv->asyncclk;
825 break;
826 default:
827 return -EINVAL;
828 }
829
830 if (refclk % 8000)
831 rates = arizona_sysclk_44k1_rates;
832 else
833 rates = arizona_sysclk_48k_rates;
834
835 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
836 rates[ref] <= refclk; ref++) {
837 div = 1;
838 while (rates[ref] / div >= freq && div < 32) {
839 if (rates[ref] / div == freq) {
840 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
841 freq);
842 snd_soc_update_bits(codec, reg,
843 ARIZONA_OPCLK_DIV_MASK |
844 ARIZONA_OPCLK_SEL_MASK,
845 (div <<
846 ARIZONA_OPCLK_DIV_SHIFT) |
847 ref);
848 return 0;
849 }
850 div++;
851 }
852 }
853
854 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
855 return -EINVAL;
856}
857
07ed873e
MB
858int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
859 int source, unsigned int freq, int dir)
860{
861 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
862 struct arizona *arizona = priv->arizona;
863 char *name;
864 unsigned int reg;
865 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
866 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
867 unsigned int *clk;
868
869 switch (clk_id) {
870 case ARIZONA_CLK_SYSCLK:
871 name = "SYSCLK";
872 reg = ARIZONA_SYSTEM_CLOCK_1;
873 clk = &priv->sysclk;
874 mask |= ARIZONA_SYSCLK_FRAC;
875 break;
876 case ARIZONA_CLK_ASYNCCLK:
877 name = "ASYNCCLK";
878 reg = ARIZONA_ASYNC_CLOCK_1;
879 clk = &priv->asyncclk;
880 break;
cbd840da
MB
881 case ARIZONA_CLK_OPCLK:
882 case ARIZONA_CLK_ASYNC_OPCLK:
883 return arizona_set_opclk(codec, clk_id, freq);
07ed873e
MB
884 default:
885 return -EINVAL;
886 }
887
888 switch (freq) {
889 case 5644800:
890 case 6144000:
891 break;
892 case 11289600:
893 case 12288000:
3f341f74 894 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
07ed873e
MB
895 break;
896 case 22579200:
897 case 24576000:
3f341f74 898 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
07ed873e
MB
899 break;
900 case 45158400:
901 case 49152000:
3f341f74 902 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
07ed873e 903 break;
38113360
MB
904 case 67737600:
905 case 73728000:
3f341f74 906 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
38113360
MB
907 break;
908 case 90316800:
909 case 98304000:
3f341f74 910 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
38113360
MB
911 break;
912 case 135475200:
913 case 147456000:
3f341f74 914 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
38113360 915 break;
f2c26d48
MB
916 case 0:
917 dev_dbg(arizona->dev, "%s cleared\n", name);
918 *clk = freq;
919 return 0;
07ed873e
MB
920 default:
921 return -EINVAL;
922 }
923
924 *clk = freq;
925
926 if (freq % 6144000)
927 val |= ARIZONA_SYSCLK_FRAC;
928
929 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
930
931 return regmap_update_bits(arizona->regmap, reg, mask, val);
932}
933EXPORT_SYMBOL_GPL(arizona_set_sysclk);
934
935static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
936{
937 struct snd_soc_codec *codec = dai->codec;
3c43c695
MB
938 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
939 struct arizona *arizona = priv->arizona;
07ed873e
MB
940 int lrclk, bclk, mode, base;
941
942 base = dai->driver->base;
943
944 lrclk = 0;
945 bclk = 0;
946
947 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
948 case SND_SOC_DAIFMT_DSP_A:
949 mode = 0;
950 break;
07ed873e
MB
951 case SND_SOC_DAIFMT_I2S:
952 mode = 2;
953 break;
07ed873e
MB
954 default:
955 arizona_aif_err(dai, "Unsupported DAI format %d\n",
956 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
957 return -EINVAL;
958 }
959
960 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
961 case SND_SOC_DAIFMT_CBS_CFS:
962 break;
963 case SND_SOC_DAIFMT_CBS_CFM:
964 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
965 break;
966 case SND_SOC_DAIFMT_CBM_CFS:
967 bclk |= ARIZONA_AIF1_BCLK_MSTR;
968 break;
969 case SND_SOC_DAIFMT_CBM_CFM:
970 bclk |= ARIZONA_AIF1_BCLK_MSTR;
971 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
972 break;
973 default:
974 arizona_aif_err(dai, "Unsupported master mode %d\n",
975 fmt & SND_SOC_DAIFMT_MASTER_MASK);
976 return -EINVAL;
977 }
978
979 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
980 case SND_SOC_DAIFMT_NB_NF:
981 break;
982 case SND_SOC_DAIFMT_IB_IF:
983 bclk |= ARIZONA_AIF1_BCLK_INV;
984 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
985 break;
986 case SND_SOC_DAIFMT_IB_NF:
987 bclk |= ARIZONA_AIF1_BCLK_INV;
988 break;
989 case SND_SOC_DAIFMT_NB_IF:
990 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
991 break;
992 default:
993 return -EINVAL;
994 }
995
3c43c695
MB
996 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
997 ARIZONA_AIF1_BCLK_INV |
998 ARIZONA_AIF1_BCLK_MSTR,
999 bclk);
1000 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1001 ARIZONA_AIF1TX_LRCLK_INV |
1002 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1003 regmap_update_bits_async(arizona->regmap,
1004 base + ARIZONA_AIF_RX_PIN_CTRL,
1005 ARIZONA_AIF1RX_LRCLK_INV |
1006 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1007 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1008 ARIZONA_AIF1_FMT_MASK, mode);
07ed873e
MB
1009
1010 return 0;
1011}
1012
949e6bc7 1013static const int arizona_48k_bclk_rates[] = {
07ed873e
MB
1014 -1,
1015 48000,
1016 64000,
1017 96000,
1018 128000,
1019 192000,
1020 256000,
1021 384000,
1022 512000,
1023 768000,
1024 1024000,
1025 1536000,
1026 2048000,
1027 3072000,
1028 4096000,
1029 6144000,
1030 8192000,
1031 12288000,
1032 24576000,
1033};
1034
5b2eec3f
MB
1035static const unsigned int arizona_48k_rates[] = {
1036 12000,
1037 24000,
1038 48000,
1039 96000,
1040 192000,
1041 384000,
1042 768000,
1043 4000,
1044 8000,
1045 16000,
1046 32000,
1047 64000,
1048 128000,
1049 256000,
1050 512000,
1051};
1052
1053static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
1054 .count = ARRAY_SIZE(arizona_48k_rates),
1055 .list = arizona_48k_rates,
1056};
1057
949e6bc7 1058static const int arizona_44k1_bclk_rates[] = {
07ed873e
MB
1059 -1,
1060 44100,
1061 58800,
1062 88200,
1063 117600,
1064 177640,
1065 235200,
1066 352800,
1067 470400,
1068 705600,
1069 940800,
1070 1411200,
1071 1881600,
4758be37 1072 2822400,
07ed873e
MB
1073 3763200,
1074 5644800,
1075 7526400,
1076 11289600,
1077 22579200,
1078};
1079
5b2eec3f
MB
1080static const unsigned int arizona_44k1_rates[] = {
1081 11025,
1082 22050,
1083 44100,
1084 88200,
1085 176400,
1086 352800,
1087 705600,
1088};
1089
1090static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
1091 .count = ARRAY_SIZE(arizona_44k1_rates),
1092 .list = arizona_44k1_rates,
1093};
1094
07ed873e
MB
1095static int arizona_sr_vals[] = {
1096 0,
1097 12000,
1098 24000,
1099 48000,
1100 96000,
1101 192000,
1102 384000,
1103 768000,
1104 0,
1105 11025,
1106 22050,
1107 44100,
1108 88200,
1109 176400,
1110 352800,
1111 705600,
1112 4000,
1113 8000,
1114 16000,
1115 32000,
1116 64000,
1117 128000,
1118 256000,
1119 512000,
1120};
1121
5b2eec3f
MB
1122static int arizona_startup(struct snd_pcm_substream *substream,
1123 struct snd_soc_dai *dai)
1124{
1125 struct snd_soc_codec *codec = dai->codec;
1126 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1127 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1128 const struct snd_pcm_hw_constraint_list *constraint;
1129 unsigned int base_rate;
1130
1131 switch (dai_priv->clk) {
1132 case ARIZONA_CLK_SYSCLK:
1133 base_rate = priv->sysclk;
1134 break;
1135 case ARIZONA_CLK_ASYNCCLK:
1136 base_rate = priv->asyncclk;
1137 break;
1138 default:
1139 return 0;
1140 }
1141
f2c26d48
MB
1142 if (base_rate == 0)
1143 return 0;
1144
5b2eec3f
MB
1145 if (base_rate % 8000)
1146 constraint = &arizona_44k1_constraint;
1147 else
1148 constraint = &arizona_48k_constraint;
1149
1150 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1151 SNDRV_PCM_HW_PARAM_RATE,
1152 constraint);
1153}
1154
cc9e9243
CK
1155static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
1156 unsigned int rate)
1157{
1158 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1159 struct arizona *arizona = priv->arizona;
1160 struct reg_default dac_comp[] = {
1161 { 0x80, 0x3 },
1162 { ARIZONA_DAC_COMP_1, 0 },
1163 { ARIZONA_DAC_COMP_2, 0 },
1164 { 0x80, 0x0 },
1165 };
1166
1167 mutex_lock(&codec->mutex);
1168
1169 dac_comp[1].def = arizona->dac_comp_coeff;
1170 if (rate >= 176400)
1171 dac_comp[2].def = arizona->dac_comp_enabled;
1172
1173 mutex_unlock(&codec->mutex);
1174
1175 regmap_multi_reg_write(arizona->regmap,
1176 dac_comp,
1177 ARRAY_SIZE(dac_comp));
1178}
1179
b272efc8
MB
1180static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1181 struct snd_pcm_hw_params *params,
1182 struct snd_soc_dai *dai)
1183{
1184 struct snd_soc_codec *codec = dai->codec;
1185 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1186 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1187 int base = dai->driver->base;
1188 int i, sr_val;
1189
1190 /*
1191 * We will need to be more flexible than this in future,
1192 * currently we use a single sample rate for SYSCLK.
1193 */
1194 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1195 if (arizona_sr_vals[i] == params_rate(params))
1196 break;
1197 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1198 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1199 params_rate(params));
1200 return -EINVAL;
1201 }
1202 sr_val = i;
1203
1204 switch (dai_priv->clk) {
1205 case ARIZONA_CLK_SYSCLK:
cc9e9243
CK
1206 switch (priv->arizona->type) {
1207 case WM5102:
1208 arizona_wm5102_set_dac_comp(codec,
1209 params_rate(params));
1210 break;
1211 default:
1212 break;
1213 }
1214
b272efc8
MB
1215 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1216 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1217 if (base)
1218 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1219 ARIZONA_AIF1_RATE_MASK, 0);
1220 break;
1221 case ARIZONA_CLK_ASYNCCLK:
1222 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1223 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
1224 if (base)
1225 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1226 ARIZONA_AIF1_RATE_MASK,
1227 8 << ARIZONA_AIF1_RATE_SHIFT);
1228 break;
1229 default:
1230 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1231 return -EINVAL;
1232 }
1233
1234 return 0;
1235}
1236
bedd4b19
RF
1237static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
1238 int base, int bclk, int lrclk, int frame)
1239{
1240 int val;
1241
1242 val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
1243 if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1244 return true;
1245
1246 val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
1247 if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1248 return true;
1249
1250 val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
1251 if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1252 ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1253 return true;
1254
1255 return false;
1256}
1257
07ed873e
MB
1258static int arizona_hw_params(struct snd_pcm_substream *substream,
1259 struct snd_pcm_hw_params *params,
1260 struct snd_soc_dai *dai)
1261{
1262 struct snd_soc_codec *codec = dai->codec;
c013b27a 1263 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
c94aa30e 1264 struct arizona *arizona = priv->arizona;
07ed873e
MB
1265 int base = dai->driver->base;
1266 const int *rates;
76bf969e 1267 int i, ret, val;
ed70f3a2 1268 int channels = params_channels(params);
c94aa30e 1269 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
ed70f3a2
CK
1270 int tdm_width = arizona->tdm_width[dai->id - 1];
1271 int tdm_slots = arizona->tdm_slots[dai->id - 1];
c94aa30e 1272 int bclk, lrclk, wl, frame, bclk_target;
bedd4b19
RF
1273 bool reconfig;
1274 unsigned int aif_tx_state, aif_rx_state;
07ed873e
MB
1275
1276 if (params_rate(params) % 8000)
949e6bc7 1277 rates = &arizona_44k1_bclk_rates[0];
07ed873e 1278 else
949e6bc7 1279 rates = &arizona_48k_bclk_rates[0];
07ed873e 1280
d114e5f7
NO
1281 wl = snd_pcm_format_width(params_format(params));
1282
ed70f3a2
CK
1283 if (tdm_slots) {
1284 arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1285 tdm_slots, tdm_width);
1286 bclk_target = tdm_slots * tdm_width * params_rate(params);
1287 channels = tdm_slots;
1288 } else {
1289 bclk_target = snd_soc_params_to_bclk(params);
d114e5f7 1290 tdm_width = wl;
ed70f3a2
CK
1291 }
1292
1293 if (chan_limit && chan_limit < channels) {
c94aa30e 1294 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
ed70f3a2 1295 bclk_target /= channels;
c94aa30e
MB
1296 bclk_target *= chan_limit;
1297 }
1298
ed70f3a2 1299 /* Force multiple of 2 channels for I2S mode */
76bf969e 1300 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
ed70f3a2 1301 if ((channels & 1) && (val & ARIZONA_AIF1_FMT_MASK)) {
76bf969e 1302 arizona_aif_dbg(dai, "Forcing stereo mode\n");
ed70f3a2
CK
1303 bclk_target /= channels;
1304 bclk_target *= channels + 1;
76bf969e
MB
1305 }
1306
949e6bc7 1307 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
c94aa30e 1308 if (rates[i] >= bclk_target &&
5001765f 1309 rates[i] % params_rate(params) == 0) {
07ed873e
MB
1310 bclk = i;
1311 break;
1312 }
1313 }
949e6bc7 1314 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
07ed873e
MB
1315 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1316 params_rate(params));
1317 return -EINVAL;
1318 }
1319
b59e0f82 1320 lrclk = rates[bclk] / params_rate(params);
07ed873e
MB
1321
1322 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1323 rates[bclk], rates[bclk] / lrclk);
1324
d114e5f7 1325 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
07ed873e 1326
bedd4b19
RF
1327 reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
1328
1329 if (reconfig) {
1330 /* Save AIF TX/RX state */
1331 aif_tx_state = snd_soc_read(codec,
1332 base + ARIZONA_AIF_TX_ENABLES);
1333 aif_rx_state = snd_soc_read(codec,
1334 base + ARIZONA_AIF_RX_ENABLES);
1335 /* Disable AIF TX/RX before reconfiguring it */
1336 regmap_update_bits_async(arizona->regmap,
1337 base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
1338 regmap_update_bits(arizona->regmap,
1339 base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1340 }
1341
b272efc8
MB
1342 ret = arizona_hw_params_rate(substream, params, dai);
1343 if (ret != 0)
bedd4b19 1344 goto restore_aif;
c013b27a 1345
bedd4b19
RF
1346 if (reconfig) {
1347 regmap_update_bits_async(arizona->regmap,
1348 base + ARIZONA_AIF_BCLK_CTRL,
1349 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1350 regmap_update_bits_async(arizona->regmap,
1351 base + ARIZONA_AIF_TX_BCLK_RATE,
1352 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1353 regmap_update_bits_async(arizona->regmap,
1354 base + ARIZONA_AIF_RX_BCLK_RATE,
1355 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1356 regmap_update_bits_async(arizona->regmap,
1357 base + ARIZONA_AIF_FRAME_CTRL_1,
1358 ARIZONA_AIF1TX_WL_MASK |
1359 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1360 regmap_update_bits(arizona->regmap,
1361 base + ARIZONA_AIF_FRAME_CTRL_2,
1362 ARIZONA_AIF1RX_WL_MASK |
1363 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1364 }
07ed873e 1365
bedd4b19
RF
1366restore_aif:
1367 if (reconfig) {
1368 /* Restore AIF TX/RX state */
1369 regmap_update_bits_async(arizona->regmap,
1370 base + ARIZONA_AIF_TX_ENABLES,
1371 0xff, aif_tx_state);
1372 regmap_update_bits(arizona->regmap,
1373 base + ARIZONA_AIF_RX_ENABLES,
1374 0xff, aif_rx_state);
1375 }
1376 return ret;
07ed873e
MB
1377}
1378
410837a7
MB
1379static const char *arizona_dai_clk_str(int clk_id)
1380{
1381 switch (clk_id) {
1382 case ARIZONA_CLK_SYSCLK:
1383 return "SYSCLK";
1384 case ARIZONA_CLK_ASYNCCLK:
1385 return "ASYNCCLK";
1386 default:
1387 return "Unknown clock";
1388 }
1389}
1390
5b2eec3f
MB
1391static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1392 int clk_id, unsigned int freq, int dir)
1393{
1394 struct snd_soc_codec *codec = dai->codec;
1395 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1396 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
410837a7 1397 struct snd_soc_dapm_route routes[2];
5b2eec3f
MB
1398
1399 switch (clk_id) {
1400 case ARIZONA_CLK_SYSCLK:
1401 case ARIZONA_CLK_ASYNCCLK:
1402 break;
1403 default:
1404 return -EINVAL;
1405 }
1406
410837a7
MB
1407 if (clk_id == dai_priv->clk)
1408 return 0;
1409
1410 if (dai->active) {
5b2eec3f
MB
1411 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1412 dai->id);
1413 return -EBUSY;
1414 }
1415
c8d35a6a
MB
1416 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1417 arizona_dai_clk_str(clk_id));
1418
410837a7
MB
1419 memset(&routes, 0, sizeof(routes));
1420 routes[0].sink = dai->driver->capture.stream_name;
1421 routes[1].sink = dai->driver->playback.stream_name;
5b2eec3f 1422
410837a7
MB
1423 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1424 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1425 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1426
1427 routes[0].source = arizona_dai_clk_str(clk_id);
1428 routes[1].source = arizona_dai_clk_str(clk_id);
1429 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1430
0c778e86
MB
1431 dai_priv->clk = clk_id;
1432
410837a7 1433 return snd_soc_dapm_sync(&codec->dapm);
5b2eec3f
MB
1434}
1435
01df259f
MB
1436static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1437{
1438 struct snd_soc_codec *codec = dai->codec;
1439 int base = dai->driver->base;
1440 unsigned int reg;
1441
1442 if (tristate)
1443 reg = ARIZONA_AIF1_TRI;
1444 else
1445 reg = 0;
1446
1447 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1448 ARIZONA_AIF1_TRI, reg);
1449}
1450
ed70f3a2
CK
1451static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1452 unsigned int base,
1453 int channels, unsigned int mask)
1454{
1455 struct snd_soc_codec *codec = dai->codec;
1456 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1457 struct arizona *arizona = priv->arizona;
1458 int slot, i;
1459
1460 for (i = 0; i < channels; ++i) {
1461 slot = ffs(mask) - 1;
1462 if (slot < 0)
1463 return;
1464
1465 regmap_write(arizona->regmap, base + i, slot);
1466
1467 mask &= ~(1 << slot);
1468 }
1469
1470 if (mask)
1471 arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1472}
1473
1474static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1475 unsigned int rx_mask, int slots, int slot_width)
1476{
1477 struct snd_soc_codec *codec = dai->codec;
1478 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1479 struct arizona *arizona = priv->arizona;
1480 int base = dai->driver->base;
1481 int rx_max_chan = dai->driver->playback.channels_max;
1482 int tx_max_chan = dai->driver->capture.channels_max;
1483
1484 /* Only support TDM for the physical AIFs */
1485 if (dai->id > ARIZONA_MAX_AIF)
1486 return -ENOTSUPP;
1487
1488 if (slots == 0) {
1489 tx_mask = (1 << tx_max_chan) - 1;
1490 rx_mask = (1 << rx_max_chan) - 1;
1491 }
1492
1493 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
1494 tx_max_chan, tx_mask);
1495 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
1496 rx_max_chan, rx_mask);
1497
1498 arizona->tdm_width[dai->id - 1] = slot_width;
1499 arizona->tdm_slots[dai->id - 1] = slots;
1500
1501 return 0;
1502}
1503
07ed873e 1504const struct snd_soc_dai_ops arizona_dai_ops = {
5b2eec3f 1505 .startup = arizona_startup,
07ed873e 1506 .set_fmt = arizona_set_fmt,
ed70f3a2 1507 .set_tdm_slot = arizona_set_tdm_slot,
07ed873e 1508 .hw_params = arizona_hw_params,
5b2eec3f 1509 .set_sysclk = arizona_dai_set_sysclk,
01df259f 1510 .set_tristate = arizona_set_tristate,
07ed873e 1511};
a837987e 1512EXPORT_SYMBOL_GPL(arizona_dai_ops);
07ed873e 1513
bd1dd885
MB
1514const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1515 .startup = arizona_startup,
1516 .hw_params = arizona_hw_params_rate,
1517 .set_sysclk = arizona_dai_set_sysclk,
1518};
1519EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1520
5b2eec3f
MB
1521int arizona_init_dai(struct arizona_priv *priv, int id)
1522{
1523 struct arizona_dai_priv *dai_priv = &priv->dai[id];
1524
1525 dai_priv->clk = ARIZONA_CLK_SYSCLK;
1526
1527 return 0;
1528}
1529EXPORT_SYMBOL_GPL(arizona_init_dai);
1530
07ed873e
MB
1531static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
1532{
1533 struct arizona_fll *fll = data;
1534
1535 arizona_fll_dbg(fll, "clock OK\n");
1536
1537 complete(&fll->ok);
1538
1539 return IRQ_HANDLED;
1540}
1541
1542static struct {
1543 unsigned int min;
1544 unsigned int max;
1545 u16 fratio;
1546 int ratio;
1547} fll_fratios[] = {
1548 { 0, 64000, 4, 16 },
1549 { 64000, 128000, 3, 8 },
1550 { 128000, 256000, 2, 4 },
1551 { 256000, 1000000, 1, 2 },
1552 { 1000000, 13500000, 0, 1 },
1553};
1554
8f113d7d
MB
1555static struct {
1556 unsigned int min;
1557 unsigned int max;
1558 u16 gain;
1559} fll_gains[] = {
1560 { 0, 256000, 0 },
1561 { 256000, 1000000, 2 },
1562 { 1000000, 13500000, 4 },
1563};
1564
07ed873e
MB
1565struct arizona_fll_cfg {
1566 int n;
1567 int theta;
1568 int lambda;
1569 int refdiv;
1570 int outdiv;
1571 int fratio;
8f113d7d 1572 int gain;
07ed873e
MB
1573};
1574
23f785a8
CK
1575static int arizona_validate_fll(struct arizona_fll *fll,
1576 unsigned int Fref,
1577 unsigned int Fout)
07ed873e 1578{
23f785a8
CK
1579 unsigned int Fvco_min;
1580
c8badda8
CK
1581 if (fll->fout && Fout != fll->fout) {
1582 arizona_fll_err(fll,
1583 "Can't change output on active FLL\n");
1584 return -EINVAL;
1585 }
1586
23f785a8
CK
1587 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
1588 arizona_fll_err(fll,
1589 "Can't scale %dMHz in to <=13.5MHz\n",
1590 Fref);
1591 return -EINVAL;
1592 }
07ed873e 1593
23f785a8
CK
1594 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
1595 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
1596 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1597 Fout);
1598 return -EINVAL;
1599 }
1600
1601 return 0;
1602}
1603
d0800342
CK
1604static int arizona_find_fratio(unsigned int Fref, int *fratio)
1605{
1606 int i;
1607
1608 /* Find an appropriate FLL_FRATIO */
1609 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1610 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1611 if (fratio)
1612 *fratio = fll_fratios[i].fratio;
1613 return fll_fratios[i].ratio;
1614 }
1615 }
1616
1617 return -EINVAL;
1618}
1619
1620static int arizona_calc_fratio(struct arizona_fll *fll,
1621 struct arizona_fll_cfg *cfg,
1622 unsigned int target,
1623 unsigned int Fref, bool sync)
1624{
1625 int init_ratio, ratio;
1626 int refdiv, div;
07ed873e 1627
d0800342 1628 /* Fref must be <=13.5MHz, find initial refdiv */
07ed873e
MB
1629 div = 1;
1630 cfg->refdiv = 0;
d0800342 1631 while (Fref > ARIZONA_FLL_MAX_FREF) {
07ed873e 1632 div *= 2;
d0800342 1633 Fref /= 2;
07ed873e
MB
1634 cfg->refdiv++;
1635
d0800342 1636 if (div > ARIZONA_FLL_MAX_REFDIV)
07ed873e 1637 return -EINVAL;
d0800342
CK
1638 }
1639
1640 /* Find an appropriate FLL_FRATIO */
1641 init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
1642 if (init_ratio < 0) {
1643 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1644 Fref);
1645 return init_ratio;
1646 }
1647
1648 switch (fll->arizona->type) {
1649 case WM5110:
1650 if (fll->arizona->rev < 3 || sync)
1651 return init_ratio;
1652 break;
1653 default:
1654 return init_ratio;
1655 }
1656
1657 cfg->fratio = init_ratio - 1;
1658
1659 /* Adjust FRATIO/refdiv to avoid integer mode if possible */
1660 refdiv = cfg->refdiv;
1661
1662 while (div <= ARIZONA_FLL_MAX_REFDIV) {
1663 for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
1664 ratio++) {
35a730a0
CK
1665 if ((ARIZONA_FLL_VCO_CORNER / 2) /
1666 (fll->vco_mult * ratio) < Fref)
29fee829
CK
1667 break;
1668
d0800342
CK
1669 if (target % (ratio * Fref)) {
1670 cfg->refdiv = refdiv;
1671 cfg->fratio = ratio - 1;
1672 return ratio;
1673 }
07ed873e 1674 }
d0800342 1675
4714bc01 1676 for (ratio = init_ratio - 1; ratio > 0; ratio--) {
d0800342
CK
1677 if (target % (ratio * Fref)) {
1678 cfg->refdiv = refdiv;
1679 cfg->fratio = ratio - 1;
1680 return ratio;
1681 }
1682 }
1683
1684 div *= 2;
1685 Fref /= 2;
1686 refdiv++;
1687 init_ratio = arizona_find_fratio(Fref, NULL);
07ed873e
MB
1688 }
1689
d0800342
CK
1690 arizona_fll_warn(fll, "Falling back to integer mode operation\n");
1691 return cfg->fratio + 1;
1692}
1693
07ed873e
MB
1694static int arizona_calc_fll(struct arizona_fll *fll,
1695 struct arizona_fll_cfg *cfg,
d0800342 1696 unsigned int Fref, bool sync)
07ed873e
MB
1697{
1698 unsigned int target, div, gcd_fll;
1699 int i, ratio;
1700
8ccefcd2 1701 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
07ed873e 1702
2b4d39fc 1703 /* Fvco should be over the targt; don't check the upper bound */
f641aec6
CK
1704 div = ARIZONA_FLL_MIN_OUTDIV;
1705 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
07ed873e 1706 div++;
f641aec6 1707 if (div > ARIZONA_FLL_MAX_OUTDIV)
07ed873e 1708 return -EINVAL;
07ed873e 1709 }
f641aec6 1710 target = fll->fout * div / fll->vco_mult;
07ed873e
MB
1711 cfg->outdiv = div;
1712
1713 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1714
d0800342
CK
1715 /* Find an appropriate FLL_FRATIO and refdiv */
1716 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
1717 if (ratio < 0)
1718 return ratio;
07ed873e 1719
07ed873e 1720 /* Apply the division for our remaining calculations */
d0800342 1721 Fref = Fref / (1 << cfg->refdiv);
8f113d7d 1722
07ed873e
MB
1723 cfg->n = target / (ratio * Fref);
1724
01f58153 1725 if (target % (ratio * Fref)) {
07ed873e
MB
1726 gcd_fll = gcd(target, ratio * Fref);
1727 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1728
1729 cfg->theta = (target - (cfg->n * ratio * Fref))
1730 / gcd_fll;
1731 cfg->lambda = (ratio * Fref) / gcd_fll;
1732 } else {
1733 cfg->theta = 0;
1734 cfg->lambda = 0;
1735 }
1736
01f58153
RT
1737 /* Round down to 16bit range with cost of accuracy lost.
1738 * Denominator must be bigger than numerator so we only
1739 * take care of it.
1740 */
1741 while (cfg->lambda >= (1 << 16)) {
1742 cfg->theta >>= 1;
1743 cfg->lambda >>= 1;
1744 }
1745
5a3935c7
CK
1746 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1747 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1748 cfg->gain = fll_gains[i].gain;
1749 break;
1750 }
1751 }
1752 if (i == ARRAY_SIZE(fll_gains)) {
1753 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1754 Fref);
1755 return -EINVAL;
1756 }
1757
07ed873e
MB
1758 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1759 cfg->n, cfg->theta, cfg->lambda);
1760 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1761 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
8f113d7d 1762 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
07ed873e
MB
1763
1764 return 0;
1765
1766}
1767
1768static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
8f113d7d
MB
1769 struct arizona_fll_cfg *cfg, int source,
1770 bool sync)
07ed873e 1771{
3c43c695
MB
1772 regmap_update_bits_async(arizona->regmap, base + 3,
1773 ARIZONA_FLL1_THETA_MASK, cfg->theta);
1774 regmap_update_bits_async(arizona->regmap, base + 4,
1775 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1776 regmap_update_bits_async(arizona->regmap, base + 5,
1777 ARIZONA_FLL1_FRATIO_MASK,
1778 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1779 regmap_update_bits_async(arizona->regmap, base + 6,
1780 ARIZONA_FLL1_CLK_REF_DIV_MASK |
1781 ARIZONA_FLL1_CLK_REF_SRC_MASK,
1782 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1783 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
07ed873e 1784
61719db8
CK
1785 if (sync) {
1786 regmap_update_bits(arizona->regmap, base + 0x7,
1787 ARIZONA_FLL1_GAIN_MASK,
1788 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1789 } else {
1790 regmap_update_bits(arizona->regmap, base + 0x5,
1791 ARIZONA_FLL1_OUTDIV_MASK,
1792 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1793 regmap_update_bits(arizona->regmap, base + 0x9,
1794 ARIZONA_FLL1_GAIN_MASK,
1795 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1796 }
8f113d7d 1797
3c43c695
MB
1798 regmap_update_bits_async(arizona->regmap, base + 2,
1799 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1800 ARIZONA_FLL1_CTRL_UPD | cfg->n);
07ed873e
MB
1801}
1802
c393aca9 1803static int arizona_is_enabled_fll(struct arizona_fll *fll)
d122d6c9
CK
1804{
1805 struct arizona *arizona = fll->arizona;
1806 unsigned int reg;
1807 int ret;
1808
1809 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1810 if (ret != 0) {
1811 arizona_fll_err(fll, "Failed to read current state: %d\n",
1812 ret);
1813 return ret;
1814 }
1815
1816 return reg & ARIZONA_FLL1_ENA;
1817}
1818
c393aca9 1819static int arizona_enable_fll(struct arizona_fll *fll)
35722815
CK
1820{
1821 struct arizona *arizona = fll->arizona;
1822 int ret;
49c60547 1823 bool use_sync = false;
c393aca9 1824 int already_enabled = arizona_is_enabled_fll(fll);
23f785a8 1825 struct arizona_fll_cfg cfg;
35722815 1826
c393aca9
CK
1827 if (already_enabled < 0)
1828 return already_enabled;
1829
c8badda8
CK
1830 if (already_enabled) {
1831 /* Facilitate smooth refclk across the transition */
1832 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x7,
1833 ARIZONA_FLL1_GAIN_MASK, 0);
1834 regmap_update_bits_async(fll->arizona->regmap, fll->base + 1,
1835 ARIZONA_FLL1_FREERUN,
1836 ARIZONA_FLL1_FREERUN);
1837 }
1838
ff680a17
MB
1839 /*
1840 * If we have both REFCLK and SYNCCLK then enable both,
1841 * otherwise apply the SYNCCLK settings to REFCLK.
1842 */
49c60547
CK
1843 if (fll->ref_src >= 0 && fll->ref_freq &&
1844 fll->ref_src != fll->sync_src) {
d0800342 1845 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
ff680a17 1846
23f785a8 1847 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
8f113d7d 1848 false);
49c60547 1849 if (fll->sync_src >= 0) {
d0800342 1850 arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
23f785a8
CK
1851
1852 arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
8f113d7d 1853 fll->sync_src, true);
49c60547
CK
1854 use_sync = true;
1855 }
ff680a17 1856 } else if (fll->sync_src >= 0) {
d0800342 1857 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
ff680a17 1858
23f785a8 1859 arizona_apply_fll(arizona, fll->base, &cfg,
8f113d7d 1860 fll->sync_src, false);
eca2e8e2 1861
3c43c695
MB
1862 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
1863 ARIZONA_FLL1_SYNC_ENA, 0);
ff680a17
MB
1864 } else {
1865 arizona_fll_err(fll, "No clocks provided\n");
c393aca9 1866 return -EINVAL;
ff680a17 1867 }
35722815 1868
576411be
MB
1869 /*
1870 * Increase the bandwidth if we're not using a low frequency
1871 * sync source.
1872 */
49c60547 1873 if (use_sync && fll->sync_freq > 100000)
3c43c695
MB
1874 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
1875 ARIZONA_FLL1_SYNC_BW, 0);
576411be 1876 else
3c43c695
MB
1877 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
1878 ARIZONA_FLL1_SYNC_BW,
1879 ARIZONA_FLL1_SYNC_BW);
576411be 1880
c393aca9 1881 if (!already_enabled)
35722815
CK
1882 pm_runtime_get(arizona->dev);
1883
1884 /* Clear any pending completions */
1885 try_wait_for_completion(&fll->ok);
1886
3c43c695
MB
1887 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1888 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
49c60547 1889 if (use_sync)
3c43c695
MB
1890 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
1891 ARIZONA_FLL1_SYNC_ENA,
1892 ARIZONA_FLL1_SYNC_ENA);
35722815 1893
c8badda8
CK
1894 if (already_enabled)
1895 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1896 ARIZONA_FLL1_FREERUN, 0);
1897
35722815
CK
1898 ret = wait_for_completion_timeout(&fll->ok,
1899 msecs_to_jiffies(250));
1900 if (ret == 0)
1901 arizona_fll_warn(fll, "Timed out waiting for lock\n");
c393aca9
CK
1902
1903 return 0;
35722815
CK
1904}
1905
7604054e
CK
1906static void arizona_disable_fll(struct arizona_fll *fll)
1907{
1908 struct arizona *arizona = fll->arizona;
1909 bool change;
1910
3c43c695
MB
1911 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1912 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
7604054e
CK
1913 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1914 ARIZONA_FLL1_ENA, 0, &change);
1915 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1916 ARIZONA_FLL1_SYNC_ENA, 0);
5e39a50b
CK
1917 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1918 ARIZONA_FLL1_FREERUN, 0);
7604054e
CK
1919
1920 if (change)
1921 pm_runtime_put_autosuspend(arizona->dev);
1922}
1923
ee929a97
CK
1924int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1925 unsigned int Fref, unsigned int Fout)
1926{
c393aca9 1927 int ret = 0;
ee929a97 1928
1c5617fc 1929 if (fll->ref_src == source && fll->ref_freq == Fref)
ee929a97
CK
1930 return 0;
1931
23f785a8
CK
1932 if (fll->fout && Fref > 0) {
1933 ret = arizona_validate_fll(fll, Fref, fll->fout);
1934 if (ret != 0)
1935 return ret;
ee929a97
CK
1936 }
1937
1938 fll->ref_src = source;
1939 fll->ref_freq = Fref;
ee929a97 1940
86cd684f 1941 if (fll->fout && Fref > 0) {
c393aca9 1942 ret = arizona_enable_fll(fll);
ee929a97
CK
1943 }
1944
c393aca9 1945 return ret;
ee929a97
CK
1946}
1947EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1948
07ed873e
MB
1949int arizona_set_fll(struct arizona_fll *fll, int source,
1950 unsigned int Fref, unsigned int Fout)
1951{
c393aca9 1952 int ret = 0;
07ed873e 1953
ff680a17
MB
1954 if (fll->sync_src == source &&
1955 fll->sync_freq == Fref && fll->fout == Fout)
1956 return 0;
9e359c64 1957
ff680a17
MB
1958 if (Fout) {
1959 if (fll->ref_src >= 0) {
23f785a8 1960 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
9e359c64
CK
1961 if (ret != 0)
1962 return ret;
1963 }
1964
23f785a8 1965 ret = arizona_validate_fll(fll, Fref, Fout);
ff680a17
MB
1966 if (ret != 0)
1967 return ret;
9e359c64 1968 }
ff680a17
MB
1969
1970 fll->sync_src = source;
1971 fll->sync_freq = Fref;
de1e6eed 1972 fll->fout = Fout;
9e359c64 1973
613124ce 1974 if (Fout)
c393aca9 1975 ret = arizona_enable_fll(fll);
613124ce 1976 else
7604054e 1977 arizona_disable_fll(fll);
07ed873e 1978
c393aca9 1979 return ret;
07ed873e
MB
1980}
1981EXPORT_SYMBOL_GPL(arizona_set_fll);
1982
1983int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1984 int ok_irq, struct arizona_fll *fll)
1985{
1986 int ret;
19b34bdc 1987 unsigned int val;
07ed873e 1988
07ed873e
MB
1989 init_completion(&fll->ok);
1990
1991 fll->id = id;
1992 fll->base = base;
1993 fll->arizona = arizona;
f3f1163d 1994 fll->sync_src = ARIZONA_FLL_SRC_NONE;
07ed873e 1995
19b34bdc
CK
1996 /* Configure default refclk to 32kHz if we have one */
1997 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1998 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1999 case ARIZONA_CLK_SRC_MCLK1:
2000 case ARIZONA_CLK_SRC_MCLK2:
2001 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2002 break;
2003 default:
f3f1163d 2004 fll->ref_src = ARIZONA_FLL_SRC_NONE;
19b34bdc
CK
2005 }
2006 fll->ref_freq = 32768;
2007
07ed873e
MB
2008 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2009 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2010 "FLL%d clock OK", id);
2011
07ed873e
MB
2012 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
2013 arizona_fll_clock_ok, fll);
2014 if (ret != 0) {
2015 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
2016 id, ret);
2017 }
2018
e31c1946
CK
2019 regmap_update_bits(arizona->regmap, fll->base + 1,
2020 ARIZONA_FLL1_FREERUN, 0);
2021
07ed873e
MB
2022 return 0;
2023}
2024EXPORT_SYMBOL_GPL(arizona_init_fll);
2025
bc9ab6d3
MB
2026/**
2027 * arizona_set_output_mode - Set the mode of the specified output
2028 *
2029 * @codec: Device to configure
2030 * @output: Output number
2031 * @diff: True to set the output to differential mode
2032 *
2033 * Some systems use external analogue switches to connect more
2034 * analogue devices to the CODEC than are supported by the device. In
2035 * some systems this requires changing the switched output from single
2036 * ended to differential mode dynamically at runtime, an operation
2037 * supported using this function.
2038 *
2039 * Most systems have a single static configuration and should use
2040 * platform data instead.
2041 */
2042int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
2043{
2044 unsigned int reg, val;
2045
2046 if (output < 1 || output > 6)
2047 return -EINVAL;
2048
2049 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2050
2051 if (diff)
2052 val = ARIZONA_OUT1_MONO;
2053 else
2054 val = 0;
2055
2056 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
2057}
2058EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2059
07ed873e
MB
2060MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2061MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2062MODULE_LICENSE("GPL");