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