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