aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/arizona.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/arizona.c')
-rw-r--r--sound/soc/codecs/arizona.c497
1 files changed, 428 insertions, 69 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e7d34711412c..389f23253831 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/delay.h>
13#include <linux/gcd.h> 14#include <linux/gcd.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
@@ -65,6 +66,163 @@
65#define arizona_aif_dbg(_dai, fmt, ...) \ 66#define arizona_aif_dbg(_dai, fmt, ...) \
66 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 67 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 68
69static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
70 struct snd_kcontrol *kcontrol,
71 int event)
72{
73 struct snd_soc_codec *codec = w->codec;
74 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
75 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
76 bool manual_ena = false;
77 int val;
78
79 switch (arizona->type) {
80 case WM5102:
81 switch (arizona->rev) {
82 case 0:
83 break;
84 default:
85 manual_ena = true;
86 break;
87 }
88 default:
89 break;
90 }
91
92 switch (event) {
93 case SND_SOC_DAPM_PRE_PMU:
94 if (!priv->spk_ena && manual_ena) {
95 snd_soc_write(codec, 0x4f5, 0x25a);
96 priv->spk_ena_pending = true;
97 }
98 break;
99 case SND_SOC_DAPM_POST_PMU:
100 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
101 if (val & ARIZONA_SPK_SHUTDOWN_STS) {
102 dev_crit(arizona->dev,
103 "Speaker not enabled due to temperature\n");
104 return -EBUSY;
105 }
106
107 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
108 1 << w->shift, 1 << w->shift);
109
110 if (priv->spk_ena_pending) {
111 msleep(75);
112 snd_soc_write(codec, 0x4f5, 0xda);
113 priv->spk_ena_pending = false;
114 priv->spk_ena++;
115 }
116 break;
117 case SND_SOC_DAPM_PRE_PMD:
118 if (manual_ena) {
119 priv->spk_ena--;
120 if (!priv->spk_ena)
121 snd_soc_write(codec, 0x4f5, 0x25a);
122 }
123
124 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
125 1 << w->shift, 0);
126 break;
127 case SND_SOC_DAPM_POST_PMD:
128 if (manual_ena) {
129 if (!priv->spk_ena)
130 snd_soc_write(codec, 0x4f5, 0x0da);
131 }
132 break;
133 }
134
135 return 0;
136}
137
138static irqreturn_t arizona_thermal_warn(int irq, void *data)
139{
140 struct arizona *arizona = data;
141 unsigned int val;
142 int ret;
143
144 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
145 &val);
146 if (ret != 0) {
147 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
148 ret);
149 } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
150 dev_crit(arizona->dev, "Thermal warning\n");
151 }
152
153 return IRQ_HANDLED;
154}
155
156static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
157{
158 struct arizona *arizona = data;
159 unsigned int val;
160 int ret;
161
162 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
163 &val);
164 if (ret != 0) {
165 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
166 ret);
167 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
168 dev_crit(arizona->dev, "Thermal shutdown\n");
169 ret = regmap_update_bits(arizona->regmap,
170 ARIZONA_OUTPUT_ENABLES_1,
171 ARIZONA_OUT4L_ENA |
172 ARIZONA_OUT4R_ENA, 0);
173 if (ret != 0)
174 dev_crit(arizona->dev,
175 "Failed to disable speaker outputs: %d\n",
176 ret);
177 }
178
179 return IRQ_HANDLED;
180}
181
182static const struct snd_soc_dapm_widget arizona_spkl =
183 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
184 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
185 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
186
187static const struct snd_soc_dapm_widget arizona_spkr =
188 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
189 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
190 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
191
192int arizona_init_spk(struct snd_soc_codec *codec)
193{
194 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
195 struct arizona *arizona = priv->arizona;
196 int ret;
197
198 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
199 if (ret != 0)
200 return ret;
201
202 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1);
203 if (ret != 0)
204 return ret;
205
206 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
207 "Thermal warning", arizona_thermal_warn,
208 arizona);
209 if (ret != 0)
210 dev_err(arizona->dev,
211 "Failed to get thermal warning IRQ: %d\n",
212 ret);
213
214 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
215 "Thermal shutdown", arizona_thermal_shutdown,
216 arizona);
217 if (ret != 0)
218 dev_err(arizona->dev,
219 "Failed to get thermal shutdown IRQ: %d\n",
220 ret);
221
222 return 0;
223}
224EXPORT_SYMBOL_GPL(arizona_init_spk);
225
68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 226const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 "None", 227 "None",
70 "Tone Generator 1", 228 "Tone Generator 1",
@@ -274,6 +432,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
274const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 432const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
275EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 433EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
276 434
435const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
436 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
437};
438EXPORT_SYMBOL_GPL(arizona_rate_text);
439
440const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
441 0, 1, 2, 8,
442};
443EXPORT_SYMBOL_GPL(arizona_rate_val);
444
445
446const struct soc_enum arizona_isrc_fsl[] = {
447 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
448 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
449 ARIZONA_RATE_ENUM_SIZE,
450 arizona_rate_text, arizona_rate_val),
451 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
452 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
453 ARIZONA_RATE_ENUM_SIZE,
454 arizona_rate_text, arizona_rate_val),
455 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
456 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
457 ARIZONA_RATE_ENUM_SIZE,
458 arizona_rate_text, arizona_rate_val),
459};
460EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
461
277static const char *arizona_vol_ramp_text[] = { 462static const char *arizona_vol_ramp_text[] = {
278 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", 463 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
279 "15ms/6dB", "30ms/6dB", 464 "15ms/6dB", "30ms/6dB",
@@ -332,9 +517,27 @@ const struct soc_enum arizona_ng_hold =
332 4, arizona_ng_hold_text); 517 4, arizona_ng_hold_text);
333EXPORT_SYMBOL_GPL(arizona_ng_hold); 518EXPORT_SYMBOL_GPL(arizona_ng_hold);
334 519
520static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
521{
522 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
523 unsigned int val;
524 int i;
525
526 if (ena)
527 val = ARIZONA_IN_VU;
528 else
529 val = 0;
530
531 for (i = 0; i < priv->num_inputs; i++)
532 snd_soc_update_bits(codec,
533 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
534 ARIZONA_IN_VU, val);
535}
536
335int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 537int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
336 int event) 538 int event)
337{ 539{
540 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
338 unsigned int reg; 541 unsigned int reg;
339 542
340 if (w->shift % 2) 543 if (w->shift % 2)
@@ -343,13 +546,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 546 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
344 547
345 switch (event) { 548 switch (event) {
549 case SND_SOC_DAPM_PRE_PMU:
550 priv->in_pending++;
551 break;
346 case SND_SOC_DAPM_POST_PMU: 552 case SND_SOC_DAPM_POST_PMU:
347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); 553 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
554
555 /* If this is the last input pending then allow VU */
556 priv->in_pending--;
557 if (priv->in_pending == 0) {
558 msleep(1);
559 arizona_in_set_vu(w->codec, 1);
560 }
348 break; 561 break;
349 case SND_SOC_DAPM_PRE_PMD: 562 case SND_SOC_DAPM_PRE_PMD:
350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 563 snd_soc_update_bits(w->codec, reg,
351 ARIZONA_IN1L_MUTE); 564 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
565 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
352 break; 566 break;
567 case SND_SOC_DAPM_POST_PMD:
568 /* Disable volume updates if no inputs are enabled */
569 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
570 if (reg == 0)
571 arizona_in_set_vu(w->codec, 0);
353 } 572 }
354 573
355 return 0; 574 return 0;
@@ -360,6 +579,24 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
360 struct snd_kcontrol *kcontrol, 579 struct snd_kcontrol *kcontrol,
361 int event) 580 int event)
362{ 581{
582 switch (event) {
583 case SND_SOC_DAPM_POST_PMU:
584 switch (w->shift) {
585 case ARIZONA_OUT1L_ENA_SHIFT:
586 case ARIZONA_OUT1R_ENA_SHIFT:
587 case ARIZONA_OUT2L_ENA_SHIFT:
588 case ARIZONA_OUT2R_ENA_SHIFT:
589 case ARIZONA_OUT3L_ENA_SHIFT:
590 case ARIZONA_OUT3R_ENA_SHIFT:
591 msleep(17);
592 break;
593
594 default:
595 break;
596 }
597 break;
598 }
599
363 return 0; 600 return 0;
364} 601}
365EXPORT_SYMBOL_GPL(arizona_out_ev); 602EXPORT_SYMBOL_GPL(arizona_out_ev);
@@ -502,27 +739,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
502 break; 739 break;
503 case 11289600: 740 case 11289600:
504 case 12288000: 741 case 12288000:
505 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; 742 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
506 break; 743 break;
507 case 22579200: 744 case 22579200:
508 case 24576000: 745 case 24576000:
509 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; 746 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
510 break; 747 break;
511 case 45158400: 748 case 45158400:
512 case 49152000: 749 case 49152000:
513 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; 750 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
514 break; 751 break;
515 case 67737600: 752 case 67737600:
516 case 73728000: 753 case 73728000:
517 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; 754 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
518 break; 755 break;
519 case 90316800: 756 case 90316800:
520 case 98304000: 757 case 98304000:
521 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; 758 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
522 break; 759 break;
523 case 135475200: 760 case 135475200:
524 case 147456000: 761 case 147456000:
525 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 762 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
526 break; 763 break;
527 case 0: 764 case 0:
528 dev_dbg(arizona->dev, "%s cleared\n", name); 765 dev_dbg(arizona->dev, "%s cleared\n", name);
@@ -816,7 +1053,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
816 struct arizona *arizona = priv->arizona; 1053 struct arizona *arizona = priv->arizona;
817 int base = dai->driver->base; 1054 int base = dai->driver->base;
818 const int *rates; 1055 const int *rates;
819 int i, ret; 1056 int i, ret, val;
820 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 1057 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
821 int bclk, lrclk, wl, frame, bclk_target; 1058 int bclk, lrclk, wl, frame, bclk_target;
822 1059
@@ -832,6 +1069,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
832 bclk_target *= chan_limit; 1069 bclk_target *= chan_limit;
833 } 1070 }
834 1071
1072 /* Force stereo for I2S mode */
1073 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1074 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1075 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1076 bclk_target *= 2;
1077 }
1078
835 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 1079 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
836 if (rates[i] >= bclk_target && 1080 if (rates[i] >= bclk_target &&
837 rates[i] % params_rate(params) == 0) { 1081 rates[i] % params_rate(params) == 0) {
@@ -988,6 +1232,16 @@ static struct {
988 { 1000000, 13500000, 0, 1 }, 1232 { 1000000, 13500000, 0, 1 },
989}; 1233};
990 1234
1235static struct {
1236 unsigned int min;
1237 unsigned int max;
1238 u16 gain;
1239} fll_gains[] = {
1240 { 0, 256000, 0 },
1241 { 256000, 1000000, 2 },
1242 { 1000000, 13500000, 4 },
1243};
1244
991struct arizona_fll_cfg { 1245struct arizona_fll_cfg {
992 int n; 1246 int n;
993 int theta; 1247 int theta;
@@ -995,6 +1249,7 @@ struct arizona_fll_cfg {
995 int refdiv; 1249 int refdiv;
996 int outdiv; 1250 int outdiv;
997 int fratio; 1251 int fratio;
1252 int gain;
998}; 1253};
999 1254
1000static int arizona_calc_fll(struct arizona_fll *fll, 1255static int arizona_calc_fll(struct arizona_fll *fll,
@@ -1054,6 +1309,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1054 return -EINVAL; 1309 return -EINVAL;
1055 } 1310 }
1056 1311
1312 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1313 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1314 cfg->gain = fll_gains[i].gain;
1315 break;
1316 }
1317 }
1318 if (i == ARRAY_SIZE(fll_gains)) {
1319 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1320 Fref);
1321 return -EINVAL;
1322 }
1323
1057 cfg->n = target / (ratio * Fref); 1324 cfg->n = target / (ratio * Fref);
1058 1325
1059 if (target % (ratio * Fref)) { 1326 if (target % (ratio * Fref)) {
@@ -1081,13 +1348,15 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1081 cfg->n, cfg->theta, cfg->lambda); 1348 cfg->n, cfg->theta, cfg->lambda);
1082 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1349 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1083 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 1350 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1351 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1084 1352
1085 return 0; 1353 return 0;
1086 1354
1087} 1355}
1088 1356
1089static void arizona_apply_fll(struct arizona *arizona, unsigned int base, 1357static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1090 struct arizona_fll_cfg *cfg, int source) 1358 struct arizona_fll_cfg *cfg, int source,
1359 bool sync)
1091{ 1360{
1092 regmap_update_bits(arizona->regmap, base + 3, 1361 regmap_update_bits(arizona->regmap, base + 3,
1093 ARIZONA_FLL1_THETA_MASK, cfg->theta); 1362 ARIZONA_FLL1_THETA_MASK, cfg->theta);
@@ -1102,87 +1371,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1102 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1371 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1103 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1372 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1104 1373
1374 if (sync)
1375 regmap_update_bits(arizona->regmap, base + 0x7,
1376 ARIZONA_FLL1_GAIN_MASK,
1377 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1378 else
1379 regmap_update_bits(arizona->regmap, base + 0x9,
1380 ARIZONA_FLL1_GAIN_MASK,
1381 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1382
1105 regmap_update_bits(arizona->regmap, base + 2, 1383 regmap_update_bits(arizona->regmap, base + 2,
1106 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1384 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1107 ARIZONA_FLL1_CTRL_UPD | cfg->n); 1385 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1108} 1386}
1109 1387
1110int arizona_set_fll(struct arizona_fll *fll, int source, 1388static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1111 unsigned int Fref, unsigned int Fout)
1112{ 1389{
1113 struct arizona *arizona = fll->arizona; 1390 struct arizona *arizona = fll->arizona;
1114 struct arizona_fll_cfg cfg, sync; 1391 unsigned int reg;
1115 unsigned int reg, val;
1116 int syncsrc;
1117 bool ena;
1118 int ret; 1392 int ret;
1119 1393
1120 if (fll->fref == Fref && fll->fout == Fout)
1121 return 0;
1122
1123 ret = regmap_read(arizona->regmap, fll->base + 1, &reg); 1394 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1124 if (ret != 0) { 1395 if (ret != 0) {
1125 arizona_fll_err(fll, "Failed to read current state: %d\n", 1396 arizona_fll_err(fll, "Failed to read current state: %d\n",
1126 ret); 1397 ret);
1127 return ret; 1398 return ret;
1128 } 1399 }
1129 ena = reg & ARIZONA_FLL1_ENA;
1130 1400
1131 if (Fout) { 1401 return reg & ARIZONA_FLL1_ENA;
1132 /* Do we have a 32kHz reference? */ 1402}
1133 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1134 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1135 case ARIZONA_CLK_SRC_MCLK1:
1136 case ARIZONA_CLK_SRC_MCLK2:
1137 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
1138 break;
1139 default:
1140 syncsrc = -1;
1141 }
1142 1403
1143 if (source == syncsrc) 1404static void arizona_enable_fll(struct arizona_fll *fll,
1144 syncsrc = -1; 1405 struct arizona_fll_cfg *ref,
1406 struct arizona_fll_cfg *sync)
1407{
1408 struct arizona *arizona = fll->arizona;
1409 int ret;
1145 1410
1146 if (syncsrc >= 0) { 1411 /*
1147 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1412 * If we have both REFCLK and SYNCCLK then enable both,
1148 if (ret != 0) 1413 * otherwise apply the SYNCCLK settings to REFCLK.
1149 return ret; 1414 */
1415 if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1416 regmap_update_bits(arizona->regmap, fll->base + 5,
1417 ARIZONA_FLL1_OUTDIV_MASK,
1418 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1419
1420 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1421 false);
1422 if (fll->sync_src >= 0)
1423 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1424 fll->sync_src, true);
1425 } else if (fll->sync_src >= 0) {
1426 regmap_update_bits(arizona->regmap, fll->base + 5,
1427 ARIZONA_FLL1_OUTDIV_MASK,
1428 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1429
1430 arizona_apply_fll(arizona, fll->base, sync,
1431 fll->sync_src, false);
1150 1432
1151 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1152 if (ret != 0)
1153 return ret;
1154 } else {
1155 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1156 if (ret != 0)
1157 return ret;
1158 }
1159 } else {
1160 regmap_update_bits(arizona->regmap, fll->base + 1,
1161 ARIZONA_FLL1_ENA, 0);
1162 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1433 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1163 ARIZONA_FLL1_SYNC_ENA, 0); 1434 ARIZONA_FLL1_SYNC_ENA, 0);
1164
1165 if (ena)
1166 pm_runtime_put_autosuspend(arizona->dev);
1167
1168 fll->fref = Fref;
1169 fll->fout = Fout;
1170
1171 return 0;
1172 }
1173
1174 regmap_update_bits(arizona->regmap, fll->base + 5,
1175 ARIZONA_FLL1_OUTDIV_MASK,
1176 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1177
1178 if (syncsrc >= 0) {
1179 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1180 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1181 } else { 1435 } else {
1182 arizona_apply_fll(arizona, fll->base, &cfg, source); 1436 arizona_fll_err(fll, "No clocks provided\n");
1437 return;
1183 } 1438 }
1184 1439
1185 if (!ena) 1440 /*
1441 * Increase the bandwidth if we're not using a low frequency
1442 * sync source.
1443 */
1444 if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1445 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1446 ARIZONA_FLL1_SYNC_BW, 0);
1447 else
1448 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1449 ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1450
1451 if (!arizona_is_enabled_fll(fll))
1186 pm_runtime_get(arizona->dev); 1452 pm_runtime_get(arizona->dev);
1187 1453
1188 /* Clear any pending completions */ 1454 /* Clear any pending completions */
@@ -1190,7 +1456,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1190 1456
1191 regmap_update_bits(arizona->regmap, fll->base + 1, 1457 regmap_update_bits(arizona->regmap, fll->base + 1,
1192 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); 1458 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1193 if (syncsrc >= 0) 1459 if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1460 fll->ref_src != fll->sync_src)
1194 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1461 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1195 ARIZONA_FLL1_SYNC_ENA, 1462 ARIZONA_FLL1_SYNC_ENA,
1196 ARIZONA_FLL1_SYNC_ENA); 1463 ARIZONA_FLL1_SYNC_ENA);
@@ -1199,10 +1466,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1199 msecs_to_jiffies(250)); 1466 msecs_to_jiffies(250));
1200 if (ret == 0) 1467 if (ret == 0)
1201 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1468 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1469}
1470
1471static void arizona_disable_fll(struct arizona_fll *fll)
1472{
1473 struct arizona *arizona = fll->arizona;
1474 bool change;
1475
1476 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1477 ARIZONA_FLL1_ENA, 0, &change);
1478 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1479 ARIZONA_FLL1_SYNC_ENA, 0);
1480
1481 if (change)
1482 pm_runtime_put_autosuspend(arizona->dev);
1483}
1484
1485int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1486 unsigned int Fref, unsigned int Fout)
1487{
1488 struct arizona_fll_cfg ref, sync;
1489 int ret;
1202 1490
1203 fll->fref = Fref; 1491 if (fll->ref_src == source && fll->ref_freq == Fref)
1492 return 0;
1493
1494 if (fll->fout && Fref > 0) {
1495 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1496 if (ret != 0)
1497 return ret;
1498
1499 if (fll->sync_src >= 0) {
1500 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1501 fll->fout);
1502 if (ret != 0)
1503 return ret;
1504 }
1505 }
1506
1507 fll->ref_src = source;
1508 fll->ref_freq = Fref;
1509
1510 if (fll->fout && Fref > 0) {
1511 arizona_enable_fll(fll, &ref, &sync);
1512 }
1513
1514 return 0;
1515}
1516EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1517
1518int arizona_set_fll(struct arizona_fll *fll, int source,
1519 unsigned int Fref, unsigned int Fout)
1520{
1521 struct arizona_fll_cfg ref, sync;
1522 int ret;
1523
1524 if (fll->sync_src == source &&
1525 fll->sync_freq == Fref && fll->fout == Fout)
1526 return 0;
1527
1528 if (Fout) {
1529 if (fll->ref_src >= 0) {
1530 ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1531 Fout);
1532 if (ret != 0)
1533 return ret;
1534 }
1535
1536 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1537 if (ret != 0)
1538 return ret;
1539 }
1540
1541 fll->sync_src = source;
1542 fll->sync_freq = Fref;
1204 fll->fout = Fout; 1543 fll->fout = Fout;
1205 1544
1545 if (Fout) {
1546 arizona_enable_fll(fll, &ref, &sync);
1547 } else {
1548 arizona_disable_fll(fll);
1549 }
1550
1206 return 0; 1551 return 0;
1207} 1552}
1208EXPORT_SYMBOL_GPL(arizona_set_fll); 1553EXPORT_SYMBOL_GPL(arizona_set_fll);
@@ -1211,12 +1556,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1211 int ok_irq, struct arizona_fll *fll) 1556 int ok_irq, struct arizona_fll *fll)
1212{ 1557{
1213 int ret; 1558 int ret;
1559 unsigned int val;
1214 1560
1215 init_completion(&fll->ok); 1561 init_completion(&fll->ok);
1216 1562
1217 fll->id = id; 1563 fll->id = id;
1218 fll->base = base; 1564 fll->base = base;
1219 fll->arizona = arizona; 1565 fll->arizona = arizona;
1566 fll->sync_src = ARIZONA_FLL_SRC_NONE;
1567
1568 /* Configure default refclk to 32kHz if we have one */
1569 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1570 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1571 case ARIZONA_CLK_SRC_MCLK1:
1572 case ARIZONA_CLK_SRC_MCLK2:
1573 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1574 break;
1575 default:
1576 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1577 }
1578 fll->ref_freq = 32768;
1220 1579
1221 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1580 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1222 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1581 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),