diff options
author | Mark Brown <broonie@kernel.org> | 2015-02-09 02:10:02 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-02-09 02:10:02 -0500 |
commit | 103004749235915190b81108f6bf4dbf53f220b9 (patch) | |
tree | d15f43ad6a9ecb7e4815e86d4aceef671d1d1df7 /sound | |
parent | 1d03ab06d7337497f369350ec6f22a7172d30a2c (diff) | |
parent | 9c7da1a57bb5938f1d874c8cd5e50d2494830d08 (diff) |
Merge remote-tracking branch 'asoc/topic/pcm512x' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/pcm_lib.c | 85 | ||||
-rw-r--r-- | sound/soc/codecs/pcm512x.c | 932 | ||||
-rw-r--r-- | sound/soc/codecs/pcm512x.h | 109 |
3 files changed, 1104 insertions, 22 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ec9e7866177f..446c00bd908b 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1015,6 +1015,60 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, | |||
1015 | 1015 | ||
1016 | EXPORT_SYMBOL(snd_interval_list); | 1016 | EXPORT_SYMBOL(snd_interval_list); |
1017 | 1017 | ||
1018 | /** | ||
1019 | * snd_interval_ranges - refine the interval value from the list of ranges | ||
1020 | * @i: the interval value to refine | ||
1021 | * @count: the number of elements in the list of ranges | ||
1022 | * @ranges: the ranges list | ||
1023 | * @mask: the bit-mask to evaluate | ||
1024 | * | ||
1025 | * Refines the interval value from the list of ranges. | ||
1026 | * When mask is non-zero, only the elements corresponding to bit 1 are | ||
1027 | * evaluated. | ||
1028 | * | ||
1029 | * Return: Positive if the value is changed, zero if it's not changed, or a | ||
1030 | * negative error code. | ||
1031 | */ | ||
1032 | int snd_interval_ranges(struct snd_interval *i, unsigned int count, | ||
1033 | const struct snd_interval *ranges, unsigned int mask) | ||
1034 | { | ||
1035 | unsigned int k; | ||
1036 | struct snd_interval range_union; | ||
1037 | struct snd_interval range; | ||
1038 | |||
1039 | if (!count) { | ||
1040 | snd_interval_none(i); | ||
1041 | return -EINVAL; | ||
1042 | } | ||
1043 | snd_interval_any(&range_union); | ||
1044 | range_union.min = UINT_MAX; | ||
1045 | range_union.max = 0; | ||
1046 | for (k = 0; k < count; k++) { | ||
1047 | if (mask && !(mask & (1 << k))) | ||
1048 | continue; | ||
1049 | snd_interval_copy(&range, &ranges[k]); | ||
1050 | if (snd_interval_refine(&range, i) < 0) | ||
1051 | continue; | ||
1052 | if (snd_interval_empty(&range)) | ||
1053 | continue; | ||
1054 | |||
1055 | if (range.min < range_union.min) { | ||
1056 | range_union.min = range.min; | ||
1057 | range_union.openmin = 1; | ||
1058 | } | ||
1059 | if (range.min == range_union.min && !range.openmin) | ||
1060 | range_union.openmin = 0; | ||
1061 | if (range.max > range_union.max) { | ||
1062 | range_union.max = range.max; | ||
1063 | range_union.openmax = 1; | ||
1064 | } | ||
1065 | if (range.max == range_union.max && !range.openmax) | ||
1066 | range_union.openmax = 0; | ||
1067 | } | ||
1068 | return snd_interval_refine(i, &range_union); | ||
1069 | } | ||
1070 | EXPORT_SYMBOL(snd_interval_ranges); | ||
1071 | |||
1018 | static int snd_interval_step(struct snd_interval *i, unsigned int step) | 1072 | static int snd_interval_step(struct snd_interval *i, unsigned int step) |
1019 | { | 1073 | { |
1020 | unsigned int n; | 1074 | unsigned int n; |
@@ -1221,6 +1275,37 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, | |||
1221 | 1275 | ||
1222 | EXPORT_SYMBOL(snd_pcm_hw_constraint_list); | 1276 | EXPORT_SYMBOL(snd_pcm_hw_constraint_list); |
1223 | 1277 | ||
1278 | static int snd_pcm_hw_rule_ranges(struct snd_pcm_hw_params *params, | ||
1279 | struct snd_pcm_hw_rule *rule) | ||
1280 | { | ||
1281 | struct snd_pcm_hw_constraint_ranges *r = rule->private; | ||
1282 | return snd_interval_ranges(hw_param_interval(params, rule->var), | ||
1283 | r->count, r->ranges, r->mask); | ||
1284 | } | ||
1285 | |||
1286 | |||
1287 | /** | ||
1288 | * snd_pcm_hw_constraint_ranges - apply list of range constraints to a parameter | ||
1289 | * @runtime: PCM runtime instance | ||
1290 | * @cond: condition bits | ||
1291 | * @var: hw_params variable to apply the list of range constraints | ||
1292 | * @r: ranges | ||
1293 | * | ||
1294 | * Apply the list of range constraints to an interval parameter. | ||
1295 | * | ||
1296 | * Return: Zero if successful, or a negative error code on failure. | ||
1297 | */ | ||
1298 | int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime, | ||
1299 | unsigned int cond, | ||
1300 | snd_pcm_hw_param_t var, | ||
1301 | const struct snd_pcm_hw_constraint_ranges *r) | ||
1302 | { | ||
1303 | return snd_pcm_hw_rule_add(runtime, cond, var, | ||
1304 | snd_pcm_hw_rule_ranges, (void *)r, | ||
1305 | var, -1); | ||
1306 | } | ||
1307 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ranges); | ||
1308 | |||
1224 | static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, | 1309 | static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, |
1225 | struct snd_pcm_hw_rule *rule) | 1310 | struct snd_pcm_hw_rule *rule) |
1226 | { | 1311 | { |
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 30c673cdc12e..9974f201a08f 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -21,12 +21,19 @@ | |||
21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
22 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
24 | #include <linux/gcd.h> | ||
24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
25 | #include <sound/soc-dapm.h> | 26 | #include <sound/soc-dapm.h> |
27 | #include <sound/pcm_params.h> | ||
26 | #include <sound/tlv.h> | 28 | #include <sound/tlv.h> |
27 | 29 | ||
28 | #include "pcm512x.h" | 30 | #include "pcm512x.h" |
29 | 31 | ||
32 | #define DIV_ROUND_DOWN_ULL(ll, d) \ | ||
33 | ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) | ||
34 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
35 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
36 | |||
30 | #define PCM512x_NUM_SUPPLIES 3 | 37 | #define PCM512x_NUM_SUPPLIES 3 |
31 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { | 38 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { |
32 | "AVDD", | 39 | "AVDD", |
@@ -39,6 +46,14 @@ struct pcm512x_priv { | |||
39 | struct clk *sclk; | 46 | struct clk *sclk; |
40 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; | 47 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; |
41 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; | 48 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; |
49 | int fmt; | ||
50 | int pll_in; | ||
51 | int pll_out; | ||
52 | int pll_r; | ||
53 | int pll_j; | ||
54 | int pll_d; | ||
55 | int pll_p; | ||
56 | unsigned long real_pll; | ||
42 | }; | 57 | }; |
43 | 58 | ||
44 | /* | 59 | /* |
@@ -69,6 +84,7 @@ static const struct reg_default pcm512x_reg_defaults[] = { | |||
69 | { PCM512x_MUTE, 0x00 }, | 84 | { PCM512x_MUTE, 0x00 }, |
70 | { PCM512x_DSP, 0x00 }, | 85 | { PCM512x_DSP, 0x00 }, |
71 | { PCM512x_PLL_REF, 0x00 }, | 86 | { PCM512x_PLL_REF, 0x00 }, |
87 | { PCM512x_DAC_REF, 0x00 }, | ||
72 | { PCM512x_DAC_ROUTING, 0x11 }, | 88 | { PCM512x_DAC_ROUTING, 0x11 }, |
73 | { PCM512x_DSP_PROGRAM, 0x01 }, | 89 | { PCM512x_DSP_PROGRAM, 0x01 }, |
74 | { PCM512x_CLKDET, 0x00 }, | 90 | { PCM512x_CLKDET, 0x00 }, |
@@ -87,6 +103,25 @@ static const struct reg_default pcm512x_reg_defaults[] = { | |||
87 | { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, | 103 | { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, |
88 | { PCM512x_VCOM_CTRL_1, 0x00 }, | 104 | { PCM512x_VCOM_CTRL_1, 0x00 }, |
89 | { PCM512x_VCOM_CTRL_2, 0x01 }, | 105 | { PCM512x_VCOM_CTRL_2, 0x01 }, |
106 | { PCM512x_BCLK_LRCLK_CFG, 0x00 }, | ||
107 | { PCM512x_MASTER_MODE, 0x7c }, | ||
108 | { PCM512x_GPIO_DACIN, 0x00 }, | ||
109 | { PCM512x_GPIO_PLLIN, 0x00 }, | ||
110 | { PCM512x_SYNCHRONIZE, 0x10 }, | ||
111 | { PCM512x_PLL_COEFF_0, 0x00 }, | ||
112 | { PCM512x_PLL_COEFF_1, 0x00 }, | ||
113 | { PCM512x_PLL_COEFF_2, 0x00 }, | ||
114 | { PCM512x_PLL_COEFF_3, 0x00 }, | ||
115 | { PCM512x_PLL_COEFF_4, 0x00 }, | ||
116 | { PCM512x_DSP_CLKDIV, 0x00 }, | ||
117 | { PCM512x_DAC_CLKDIV, 0x00 }, | ||
118 | { PCM512x_NCP_CLKDIV, 0x00 }, | ||
119 | { PCM512x_OSR_CLKDIV, 0x00 }, | ||
120 | { PCM512x_MASTER_CLKDIV_1, 0x00 }, | ||
121 | { PCM512x_MASTER_CLKDIV_2, 0x00 }, | ||
122 | { PCM512x_FS_SPEED_MODE, 0x00 }, | ||
123 | { PCM512x_IDAC_1, 0x01 }, | ||
124 | { PCM512x_IDAC_2, 0x00 }, | ||
90 | }; | 125 | }; |
91 | 126 | ||
92 | static bool pcm512x_readable(struct device *dev, unsigned int reg) | 127 | static bool pcm512x_readable(struct device *dev, unsigned int reg) |
@@ -103,6 +138,10 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
103 | case PCM512x_DSP_GPIO_INPUT: | 138 | case PCM512x_DSP_GPIO_INPUT: |
104 | case PCM512x_MASTER_MODE: | 139 | case PCM512x_MASTER_MODE: |
105 | case PCM512x_PLL_REF: | 140 | case PCM512x_PLL_REF: |
141 | case PCM512x_DAC_REF: | ||
142 | case PCM512x_GPIO_DACIN: | ||
143 | case PCM512x_GPIO_PLLIN: | ||
144 | case PCM512x_SYNCHRONIZE: | ||
106 | case PCM512x_PLL_COEFF_0: | 145 | case PCM512x_PLL_COEFF_0: |
107 | case PCM512x_PLL_COEFF_1: | 146 | case PCM512x_PLL_COEFF_1: |
108 | case PCM512x_PLL_COEFF_2: | 147 | case PCM512x_PLL_COEFF_2: |
@@ -143,6 +182,7 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
143 | case PCM512x_RATE_DET_2: | 182 | case PCM512x_RATE_DET_2: |
144 | case PCM512x_RATE_DET_3: | 183 | case PCM512x_RATE_DET_3: |
145 | case PCM512x_RATE_DET_4: | 184 | case PCM512x_RATE_DET_4: |
185 | case PCM512x_CLOCK_STATUS: | ||
146 | case PCM512x_ANALOG_MUTE_DET: | 186 | case PCM512x_ANALOG_MUTE_DET: |
147 | case PCM512x_GPIN: | 187 | case PCM512x_GPIN: |
148 | case PCM512x_DIGITAL_MUTE_DET: | 188 | case PCM512x_DIGITAL_MUTE_DET: |
@@ -154,6 +194,8 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
154 | case PCM512x_VCOM_CTRL_1: | 194 | case PCM512x_VCOM_CTRL_1: |
155 | case PCM512x_VCOM_CTRL_2: | 195 | case PCM512x_VCOM_CTRL_2: |
156 | case PCM512x_CRAM_CTRL: | 196 | case PCM512x_CRAM_CTRL: |
197 | case PCM512x_FLEX_A: | ||
198 | case PCM512x_FLEX_B: | ||
157 | return true; | 199 | return true; |
158 | default: | 200 | default: |
159 | /* There are 256 raw register addresses */ | 201 | /* There are 256 raw register addresses */ |
@@ -170,6 +212,7 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg) | |||
170 | case PCM512x_RATE_DET_2: | 212 | case PCM512x_RATE_DET_2: |
171 | case PCM512x_RATE_DET_3: | 213 | case PCM512x_RATE_DET_3: |
172 | case PCM512x_RATE_DET_4: | 214 | case PCM512x_RATE_DET_4: |
215 | case PCM512x_CLOCK_STATUS: | ||
173 | case PCM512x_ANALOG_MUTE_DET: | 216 | case PCM512x_ANALOG_MUTE_DET: |
174 | case PCM512x_GPIN: | 217 | case PCM512x_GPIN: |
175 | case PCM512x_DIGITAL_MUTE_DET: | 218 | case PCM512x_DIGITAL_MUTE_DET: |
@@ -277,7 +320,7 @@ SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r), | |||
277 | SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3, | 320 | SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3, |
278 | PCM512x_ACTL_SHIFT, 1, 0), | 321 | PCM512x_ACTL_SHIFT, 1, 0), |
279 | SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT, | 322 | SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT, |
280 | PCM512x_AMLR_SHIFT, 1, 0), | 323 | PCM512x_AMRE_SHIFT, 1, 0), |
281 | 324 | ||
282 | SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf), | 325 | SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf), |
283 | SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds), | 326 | SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds), |
@@ -303,6 +346,136 @@ static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = { | |||
303 | { "OUTR", NULL, "DACR" }, | 346 | { "OUTR", NULL, "DACR" }, |
304 | }; | 347 | }; |
305 | 348 | ||
349 | static const u32 pcm512x_dai_rates[] = { | ||
350 | 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, | ||
351 | 88200, 96000, 176400, 192000, 384000, | ||
352 | }; | ||
353 | |||
354 | static const struct snd_pcm_hw_constraint_list constraints_slave = { | ||
355 | .count = ARRAY_SIZE(pcm512x_dai_rates), | ||
356 | .list = pcm512x_dai_rates, | ||
357 | }; | ||
358 | |||
359 | static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params, | ||
360 | struct snd_pcm_hw_rule *rule) | ||
361 | { | ||
362 | struct snd_interval ranges[2]; | ||
363 | int frame_size; | ||
364 | |||
365 | frame_size = snd_soc_params_to_frame_size(params); | ||
366 | if (frame_size < 0) | ||
367 | return frame_size; | ||
368 | |||
369 | switch (frame_size) { | ||
370 | case 32: | ||
371 | /* No hole when the frame size is 32. */ | ||
372 | return 0; | ||
373 | case 48: | ||
374 | case 64: | ||
375 | /* There is only one hole in the range of supported | ||
376 | * rates, but it moves with the frame size. | ||
377 | */ | ||
378 | memset(ranges, 0, sizeof(ranges)); | ||
379 | ranges[0].min = 8000; | ||
380 | ranges[0].max = 25000000 / frame_size / 2; | ||
381 | ranges[1].min = DIV_ROUND_UP(16000000, frame_size); | ||
382 | ranges[1].max = 384000; | ||
383 | break; | ||
384 | default: | ||
385 | return -EINVAL; | ||
386 | } | ||
387 | |||
388 | return snd_interval_ranges(hw_param_interval(params, rule->var), | ||
389 | ARRAY_SIZE(ranges), ranges, 0); | ||
390 | } | ||
391 | |||
392 | static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream, | ||
393 | struct snd_soc_dai *dai) | ||
394 | { | ||
395 | struct snd_soc_codec *codec = dai->codec; | ||
396 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
397 | struct device *dev = dai->dev; | ||
398 | struct snd_pcm_hw_constraint_ratnums *constraints_no_pll; | ||
399 | struct snd_ratnum *rats_no_pll; | ||
400 | |||
401 | if (IS_ERR(pcm512x->sclk)) { | ||
402 | dev_err(dev, "Need SCLK for master mode: %ld\n", | ||
403 | PTR_ERR(pcm512x->sclk)); | ||
404 | return PTR_ERR(pcm512x->sclk); | ||
405 | } | ||
406 | |||
407 | if (pcm512x->pll_out) | ||
408 | return snd_pcm_hw_rule_add(substream->runtime, 0, | ||
409 | SNDRV_PCM_HW_PARAM_RATE, | ||
410 | pcm512x_hw_rule_rate, | ||
411 | NULL, | ||
412 | SNDRV_PCM_HW_PARAM_FRAME_BITS, | ||
413 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
414 | |||
415 | constraints_no_pll = devm_kzalloc(dev, sizeof(*constraints_no_pll), | ||
416 | GFP_KERNEL); | ||
417 | if (!constraints_no_pll) | ||
418 | return -ENOMEM; | ||
419 | constraints_no_pll->nrats = 1; | ||
420 | rats_no_pll = devm_kzalloc(dev, sizeof(*rats_no_pll), GFP_KERNEL); | ||
421 | if (!rats_no_pll) | ||
422 | return -ENOMEM; | ||
423 | constraints_no_pll->rats = rats_no_pll; | ||
424 | rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; | ||
425 | rats_no_pll->den_min = 1; | ||
426 | rats_no_pll->den_max = 128; | ||
427 | rats_no_pll->den_step = 1; | ||
428 | |||
429 | return snd_pcm_hw_constraint_ratnums(substream->runtime, 0, | ||
430 | SNDRV_PCM_HW_PARAM_RATE, | ||
431 | constraints_no_pll); | ||
432 | } | ||
433 | |||
434 | static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream, | ||
435 | struct snd_soc_dai *dai) | ||
436 | { | ||
437 | struct snd_soc_codec *codec = dai->codec; | ||
438 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
439 | struct device *dev = dai->dev; | ||
440 | struct regmap *regmap = pcm512x->regmap; | ||
441 | |||
442 | if (IS_ERR(pcm512x->sclk)) { | ||
443 | dev_info(dev, "No SCLK, using BCLK: %ld\n", | ||
444 | PTR_ERR(pcm512x->sclk)); | ||
445 | |||
446 | /* Disable reporting of missing SCLK as an error */ | ||
447 | regmap_update_bits(regmap, PCM512x_ERROR_DETECT, | ||
448 | PCM512x_IDCH, PCM512x_IDCH); | ||
449 | |||
450 | /* Switch PLL input to BCLK */ | ||
451 | regmap_update_bits(regmap, PCM512x_PLL_REF, | ||
452 | PCM512x_SREF, PCM512x_SREF_BCK); | ||
453 | } | ||
454 | |||
455 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
456 | SNDRV_PCM_HW_PARAM_RATE, | ||
457 | &constraints_slave); | ||
458 | } | ||
459 | |||
460 | static int pcm512x_dai_startup(struct snd_pcm_substream *substream, | ||
461 | struct snd_soc_dai *dai) | ||
462 | { | ||
463 | struct snd_soc_codec *codec = dai->codec; | ||
464 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
465 | |||
466 | switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
467 | case SND_SOC_DAIFMT_CBM_CFM: | ||
468 | case SND_SOC_DAIFMT_CBM_CFS: | ||
469 | return pcm512x_dai_startup_master(substream, dai); | ||
470 | |||
471 | case SND_SOC_DAIFMT_CBS_CFS: | ||
472 | return pcm512x_dai_startup_slave(substream, dai); | ||
473 | |||
474 | default: | ||
475 | return -EINVAL; | ||
476 | } | ||
477 | } | ||
478 | |||
306 | static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | 479 | static int pcm512x_set_bias_level(struct snd_soc_codec *codec, |
307 | enum snd_soc_bias_level level) | 480 | enum snd_soc_bias_level level) |
308 | { | 481 | { |
@@ -340,17 +513,717 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | |||
340 | return 0; | 513 | return 0; |
341 | } | 514 | } |
342 | 515 | ||
516 | static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai, | ||
517 | unsigned long bclk_rate) | ||
518 | { | ||
519 | struct device *dev = dai->dev; | ||
520 | unsigned long sck_rate; | ||
521 | int pow2; | ||
522 | |||
523 | /* 64 MHz <= pll_rate <= 100 MHz, VREF mode */ | ||
524 | /* 16 MHz <= sck_rate <= 25 MHz, VREF mode */ | ||
525 | |||
526 | /* select sck_rate as a multiple of bclk_rate but still with | ||
527 | * as many factors of 2 as possible, as that makes it easier | ||
528 | * to find a fast DAC rate | ||
529 | */ | ||
530 | pow2 = 1 << fls((25000000 - 16000000) / bclk_rate); | ||
531 | for (; pow2; pow2 >>= 1) { | ||
532 | sck_rate = rounddown(25000000, bclk_rate * pow2); | ||
533 | if (sck_rate >= 16000000) | ||
534 | break; | ||
535 | } | ||
536 | if (!pow2) { | ||
537 | dev_err(dev, "Impossible to generate a suitable SCK\n"); | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | dev_dbg(dev, "sck_rate %lu\n", sck_rate); | ||
542 | return sck_rate; | ||
543 | } | ||
544 | |||
545 | /* pll_rate = pllin_rate * R * J.D / P | ||
546 | * 1 <= R <= 16 | ||
547 | * 1 <= J <= 63 | ||
548 | * 0 <= D <= 9999 | ||
549 | * 1 <= P <= 15 | ||
550 | * 64 MHz <= pll_rate <= 100 MHz | ||
551 | * if D == 0 | ||
552 | * 1 MHz <= pllin_rate / P <= 20 MHz | ||
553 | * else if D > 0 | ||
554 | * 6.667 MHz <= pllin_rate / P <= 20 MHz | ||
555 | * 4 <= J <= 11 | ||
556 | * R = 1 | ||
557 | */ | ||
558 | static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai, | ||
559 | unsigned long pllin_rate, | ||
560 | unsigned long pll_rate) | ||
561 | { | ||
562 | struct device *dev = dai->dev; | ||
563 | struct snd_soc_codec *codec = dai->codec; | ||
564 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
565 | unsigned long common; | ||
566 | int R, J, D, P; | ||
567 | unsigned long K; /* 10000 * J.D */ | ||
568 | unsigned long num; | ||
569 | unsigned long den; | ||
570 | |||
571 | common = gcd(pll_rate, pllin_rate); | ||
572 | dev_dbg(dev, "pll %lu pllin %lu common %lu\n", | ||
573 | pll_rate, pllin_rate, common); | ||
574 | num = pll_rate / common; | ||
575 | den = pllin_rate / common; | ||
576 | |||
577 | /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */ | ||
578 | if (pllin_rate / den > 20000000 && num < 8) { | ||
579 | num *= 20000000 / (pllin_rate / den); | ||
580 | den *= 20000000 / (pllin_rate / den); | ||
581 | } | ||
582 | dev_dbg(dev, "num / den = %lu / %lu\n", num, den); | ||
583 | |||
584 | P = den; | ||
585 | if (den <= 15 && num <= 16 * 63 | ||
586 | && 1000000 <= pllin_rate / P && pllin_rate / P <= 20000000) { | ||
587 | /* Try the case with D = 0 */ | ||
588 | D = 0; | ||
589 | /* factor 'num' into J and R, such that R <= 16 and J <= 63 */ | ||
590 | for (R = 16; R; R--) { | ||
591 | if (num % R) | ||
592 | continue; | ||
593 | J = num / R; | ||
594 | if (J == 0 || J > 63) | ||
595 | continue; | ||
596 | |||
597 | dev_dbg(dev, "R * J / P = %d * %d / %d\n", R, J, P); | ||
598 | pcm512x->real_pll = pll_rate; | ||
599 | goto done; | ||
600 | } | ||
601 | /* no luck */ | ||
602 | } | ||
603 | |||
604 | R = 1; | ||
605 | |||
606 | if (num > 0xffffffffUL / 10000) | ||
607 | goto fallback; | ||
608 | |||
609 | /* Try to find an exact pll_rate using the D > 0 case */ | ||
610 | common = gcd(10000 * num, den); | ||
611 | num = 10000 * num / common; | ||
612 | den /= common; | ||
613 | dev_dbg(dev, "num %lu den %lu common %lu\n", num, den, common); | ||
614 | |||
615 | for (P = den; P <= 15; P++) { | ||
616 | if (pllin_rate / P < 6667000 || 200000000 < pllin_rate / P) | ||
617 | continue; | ||
618 | if (num * P % den) | ||
619 | continue; | ||
620 | K = num * P / den; | ||
621 | /* J == 12 is ok if D == 0 */ | ||
622 | if (K < 40000 || K > 120000) | ||
623 | continue; | ||
624 | |||
625 | J = K / 10000; | ||
626 | D = K % 10000; | ||
627 | dev_dbg(dev, "J.D / P = %d.%04d / %d\n", J, D, P); | ||
628 | pcm512x->real_pll = pll_rate; | ||
629 | goto done; | ||
630 | } | ||
631 | |||
632 | /* Fall back to an approximate pll_rate */ | ||
633 | |||
634 | fallback: | ||
635 | /* find smallest possible P */ | ||
636 | P = DIV_ROUND_UP(pllin_rate, 20000000); | ||
637 | if (!P) | ||
638 | P = 1; | ||
639 | else if (P > 15) { | ||
640 | dev_err(dev, "Need a slower clock as pll-input\n"); | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | if (pllin_rate / P < 6667000) { | ||
644 | dev_err(dev, "Need a faster clock as pll-input\n"); | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | K = DIV_ROUND_CLOSEST_ULL(10000ULL * pll_rate * P, pllin_rate); | ||
648 | if (K < 40000) | ||
649 | K = 40000; | ||
650 | /* J == 12 is ok if D == 0 */ | ||
651 | if (K > 120000) | ||
652 | K = 120000; | ||
653 | J = K / 10000; | ||
654 | D = K % 10000; | ||
655 | dev_dbg(dev, "J.D / P ~ %d.%04d / %d\n", J, D, P); | ||
656 | pcm512x->real_pll = DIV_ROUND_DOWN_ULL((u64)K * pllin_rate, 10000 * P); | ||
657 | |||
658 | done: | ||
659 | pcm512x->pll_r = R; | ||
660 | pcm512x->pll_j = J; | ||
661 | pcm512x->pll_d = D; | ||
662 | pcm512x->pll_p = P; | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai, | ||
667 | unsigned long osr_rate, | ||
668 | unsigned long pllin_rate) | ||
669 | { | ||
670 | struct snd_soc_codec *codec = dai->codec; | ||
671 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
672 | unsigned long dac_rate; | ||
673 | |||
674 | if (!pcm512x->pll_out) | ||
675 | return 0; /* no PLL to bypass, force SCK as DAC input */ | ||
676 | |||
677 | if (pllin_rate % osr_rate) | ||
678 | return 0; /* futile, quit early */ | ||
679 | |||
680 | /* run DAC no faster than 6144000 Hz */ | ||
681 | for (dac_rate = rounddown(6144000, osr_rate); | ||
682 | dac_rate; | ||
683 | dac_rate -= osr_rate) { | ||
684 | |||
685 | if (pllin_rate / dac_rate > 128) | ||
686 | return 0; /* DAC divider would be too big */ | ||
687 | |||
688 | if (!(pllin_rate % dac_rate)) | ||
689 | return dac_rate; | ||
690 | |||
691 | dac_rate -= osr_rate; | ||
692 | } | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int pcm512x_set_dividers(struct snd_soc_dai *dai, | ||
698 | struct snd_pcm_hw_params *params) | ||
699 | { | ||
700 | struct device *dev = dai->dev; | ||
701 | struct snd_soc_codec *codec = dai->codec; | ||
702 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
703 | unsigned long pllin_rate = 0; | ||
704 | unsigned long pll_rate; | ||
705 | unsigned long sck_rate; | ||
706 | unsigned long mck_rate; | ||
707 | unsigned long bclk_rate; | ||
708 | unsigned long sample_rate; | ||
709 | unsigned long osr_rate; | ||
710 | unsigned long dacsrc_rate; | ||
711 | int bclk_div; | ||
712 | int lrclk_div; | ||
713 | int dsp_div; | ||
714 | int dac_div; | ||
715 | unsigned long dac_rate; | ||
716 | int ncp_div; | ||
717 | int osr_div; | ||
718 | int ret; | ||
719 | int idac; | ||
720 | int fssp; | ||
721 | int gpio; | ||
722 | |||
723 | lrclk_div = snd_soc_params_to_frame_size(params); | ||
724 | if (lrclk_div == 0) { | ||
725 | dev_err(dev, "No LRCLK?\n"); | ||
726 | return -EINVAL; | ||
727 | } | ||
728 | |||
729 | if (!pcm512x->pll_out) { | ||
730 | sck_rate = clk_get_rate(pcm512x->sclk); | ||
731 | bclk_div = params->rate_den * 64 / lrclk_div; | ||
732 | bclk_rate = DIV_ROUND_CLOSEST(sck_rate, bclk_div); | ||
733 | |||
734 | mck_rate = sck_rate; | ||
735 | } else { | ||
736 | ret = snd_soc_params_to_bclk(params); | ||
737 | if (ret < 0) { | ||
738 | dev_err(dev, "Failed to find suitable BCLK: %d\n", ret); | ||
739 | return ret; | ||
740 | } | ||
741 | if (ret == 0) { | ||
742 | dev_err(dev, "No BCLK?\n"); | ||
743 | return -EINVAL; | ||
744 | } | ||
745 | bclk_rate = ret; | ||
746 | |||
747 | pllin_rate = clk_get_rate(pcm512x->sclk); | ||
748 | |||
749 | sck_rate = pcm512x_find_sck(dai, bclk_rate); | ||
750 | if (!sck_rate) | ||
751 | return -EINVAL; | ||
752 | pll_rate = 4 * sck_rate; | ||
753 | |||
754 | ret = pcm512x_find_pll_coeff(dai, pllin_rate, pll_rate); | ||
755 | if (ret != 0) | ||
756 | return ret; | ||
757 | |||
758 | ret = regmap_write(pcm512x->regmap, | ||
759 | PCM512x_PLL_COEFF_0, pcm512x->pll_p - 1); | ||
760 | if (ret != 0) { | ||
761 | dev_err(dev, "Failed to write PLL P: %d\n", ret); | ||
762 | return ret; | ||
763 | } | ||
764 | |||
765 | ret = regmap_write(pcm512x->regmap, | ||
766 | PCM512x_PLL_COEFF_1, pcm512x->pll_j); | ||
767 | if (ret != 0) { | ||
768 | dev_err(dev, "Failed to write PLL J: %d\n", ret); | ||
769 | return ret; | ||
770 | } | ||
771 | |||
772 | ret = regmap_write(pcm512x->regmap, | ||
773 | PCM512x_PLL_COEFF_2, pcm512x->pll_d >> 8); | ||
774 | if (ret != 0) { | ||
775 | dev_err(dev, "Failed to write PLL D msb: %d\n", ret); | ||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | ret = regmap_write(pcm512x->regmap, | ||
780 | PCM512x_PLL_COEFF_3, pcm512x->pll_d & 0xff); | ||
781 | if (ret != 0) { | ||
782 | dev_err(dev, "Failed to write PLL D lsb: %d\n", ret); | ||
783 | return ret; | ||
784 | } | ||
785 | |||
786 | ret = regmap_write(pcm512x->regmap, | ||
787 | PCM512x_PLL_COEFF_4, pcm512x->pll_r - 1); | ||
788 | if (ret != 0) { | ||
789 | dev_err(dev, "Failed to write PLL R: %d\n", ret); | ||
790 | return ret; | ||
791 | } | ||
792 | |||
793 | mck_rate = pcm512x->real_pll; | ||
794 | |||
795 | bclk_div = DIV_ROUND_CLOSEST(sck_rate, bclk_rate); | ||
796 | } | ||
797 | |||
798 | if (bclk_div > 128) { | ||
799 | dev_err(dev, "Failed to find BCLK divider\n"); | ||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | /* the actual rate */ | ||
804 | sample_rate = sck_rate / bclk_div / lrclk_div; | ||
805 | osr_rate = 16 * sample_rate; | ||
806 | |||
807 | /* run DSP no faster than 50 MHz */ | ||
808 | dsp_div = mck_rate > 50000000 ? 2 : 1; | ||
809 | |||
810 | dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate); | ||
811 | if (dac_rate) { | ||
812 | /* the desired clock rate is "compatible" with the pll input | ||
813 | * clock, so use that clock as dac input instead of the pll | ||
814 | * output clock since the pll will introduce jitter and thus | ||
815 | * noise. | ||
816 | */ | ||
817 | dev_dbg(dev, "using pll input as dac input\n"); | ||
818 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF, | ||
819 | PCM512x_SDAC, PCM512x_SDAC_GPIO); | ||
820 | if (ret != 0) { | ||
821 | dev_err(codec->dev, | ||
822 | "Failed to set gpio as dacref: %d\n", ret); | ||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1; | ||
827 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_DACIN, | ||
828 | PCM512x_GREF, gpio); | ||
829 | if (ret != 0) { | ||
830 | dev_err(codec->dev, | ||
831 | "Failed to set gpio %d as dacin: %d\n", | ||
832 | pcm512x->pll_in, ret); | ||
833 | return ret; | ||
834 | } | ||
835 | |||
836 | dacsrc_rate = pllin_rate; | ||
837 | } else { | ||
838 | /* run DAC no faster than 6144000 Hz */ | ||
839 | unsigned long dac_mul = 6144000 / osr_rate; | ||
840 | unsigned long sck_mul = sck_rate / osr_rate; | ||
841 | |||
842 | for (; dac_mul; dac_mul--) { | ||
843 | if (!(sck_mul % dac_mul)) | ||
844 | break; | ||
845 | } | ||
846 | if (!dac_mul) { | ||
847 | dev_err(dev, "Failed to find DAC rate\n"); | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | |||
851 | dac_rate = dac_mul * osr_rate; | ||
852 | dev_dbg(dev, "dac_rate %lu sample_rate %lu\n", | ||
853 | dac_rate, sample_rate); | ||
854 | |||
855 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF, | ||
856 | PCM512x_SDAC, PCM512x_SDAC_SCK); | ||
857 | if (ret != 0) { | ||
858 | dev_err(codec->dev, | ||
859 | "Failed to set sck as dacref: %d\n", ret); | ||
860 | return ret; | ||
861 | } | ||
862 | |||
863 | dacsrc_rate = sck_rate; | ||
864 | } | ||
865 | |||
866 | dac_div = DIV_ROUND_CLOSEST(dacsrc_rate, dac_rate); | ||
867 | if (dac_div > 128) { | ||
868 | dev_err(dev, "Failed to find DAC divider\n"); | ||
869 | return -EINVAL; | ||
870 | } | ||
871 | |||
872 | ncp_div = DIV_ROUND_CLOSEST(dacsrc_rate / dac_div, 1536000); | ||
873 | if (ncp_div > 128 || dacsrc_rate / dac_div / ncp_div > 2048000) { | ||
874 | /* run NCP no faster than 2048000 Hz, but why? */ | ||
875 | ncp_div = DIV_ROUND_UP(dacsrc_rate / dac_div, 2048000); | ||
876 | if (ncp_div > 128) { | ||
877 | dev_err(dev, "Failed to find NCP divider\n"); | ||
878 | return -EINVAL; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | osr_div = DIV_ROUND_CLOSEST(dac_rate, osr_rate); | ||
883 | if (osr_div > 128) { | ||
884 | dev_err(dev, "Failed to find OSR divider\n"); | ||
885 | return -EINVAL; | ||
886 | } | ||
887 | |||
888 | idac = mck_rate / (dsp_div * sample_rate); | ||
889 | |||
890 | ret = regmap_write(pcm512x->regmap, PCM512x_DSP_CLKDIV, dsp_div - 1); | ||
891 | if (ret != 0) { | ||
892 | dev_err(dev, "Failed to write DSP divider: %d\n", ret); | ||
893 | return ret; | ||
894 | } | ||
895 | |||
896 | ret = regmap_write(pcm512x->regmap, PCM512x_DAC_CLKDIV, dac_div - 1); | ||
897 | if (ret != 0) { | ||
898 | dev_err(dev, "Failed to write DAC divider: %d\n", ret); | ||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | ret = regmap_write(pcm512x->regmap, PCM512x_NCP_CLKDIV, ncp_div - 1); | ||
903 | if (ret != 0) { | ||
904 | dev_err(dev, "Failed to write NCP divider: %d\n", ret); | ||
905 | return ret; | ||
906 | } | ||
907 | |||
908 | ret = regmap_write(pcm512x->regmap, PCM512x_OSR_CLKDIV, osr_div - 1); | ||
909 | if (ret != 0) { | ||
910 | dev_err(dev, "Failed to write OSR divider: %d\n", ret); | ||
911 | return ret; | ||
912 | } | ||
913 | |||
914 | ret = regmap_write(pcm512x->regmap, | ||
915 | PCM512x_MASTER_CLKDIV_1, bclk_div - 1); | ||
916 | if (ret != 0) { | ||
917 | dev_err(dev, "Failed to write BCLK divider: %d\n", ret); | ||
918 | return ret; | ||
919 | } | ||
920 | |||
921 | ret = regmap_write(pcm512x->regmap, | ||
922 | PCM512x_MASTER_CLKDIV_2, lrclk_div - 1); | ||
923 | if (ret != 0) { | ||
924 | dev_err(dev, "Failed to write LRCLK divider: %d\n", ret); | ||
925 | return ret; | ||
926 | } | ||
927 | |||
928 | ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_1, idac >> 8); | ||
929 | if (ret != 0) { | ||
930 | dev_err(dev, "Failed to write IDAC msb divider: %d\n", ret); | ||
931 | return ret; | ||
932 | } | ||
933 | |||
934 | ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_2, idac & 0xff); | ||
935 | if (ret != 0) { | ||
936 | dev_err(dev, "Failed to write IDAC lsb divider: %d\n", ret); | ||
937 | return ret; | ||
938 | } | ||
939 | |||
940 | if (sample_rate <= 48000) | ||
941 | fssp = PCM512x_FSSP_48KHZ; | ||
942 | else if (sample_rate <= 96000) | ||
943 | fssp = PCM512x_FSSP_96KHZ; | ||
944 | else if (sample_rate <= 192000) | ||
945 | fssp = PCM512x_FSSP_192KHZ; | ||
946 | else | ||
947 | fssp = PCM512x_FSSP_384KHZ; | ||
948 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_FS_SPEED_MODE, | ||
949 | PCM512x_FSSP, fssp); | ||
950 | if (ret != 0) { | ||
951 | dev_err(codec->dev, "Failed to set fs speed: %d\n", ret); | ||
952 | return ret; | ||
953 | } | ||
954 | |||
955 | dev_dbg(codec->dev, "DSP divider %d\n", dsp_div); | ||
956 | dev_dbg(codec->dev, "DAC divider %d\n", dac_div); | ||
957 | dev_dbg(codec->dev, "NCP divider %d\n", ncp_div); | ||
958 | dev_dbg(codec->dev, "OSR divider %d\n", osr_div); | ||
959 | dev_dbg(codec->dev, "BCK divider %d\n", bclk_div); | ||
960 | dev_dbg(codec->dev, "LRCK divider %d\n", lrclk_div); | ||
961 | dev_dbg(codec->dev, "IDAC %d\n", idac); | ||
962 | dev_dbg(codec->dev, "1<<FSSP %d\n", 1 << fssp); | ||
963 | |||
964 | return 0; | ||
965 | } | ||
966 | |||
967 | static int pcm512x_hw_params(struct snd_pcm_substream *substream, | ||
968 | struct snd_pcm_hw_params *params, | ||
969 | struct snd_soc_dai *dai) | ||
970 | { | ||
971 | struct snd_soc_codec *codec = dai->codec; | ||
972 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
973 | int alen; | ||
974 | int gpio; | ||
975 | int clock_output; | ||
976 | int master_mode; | ||
977 | int ret; | ||
978 | |||
979 | dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n", | ||
980 | params_rate(params), | ||
981 | params_channels(params)); | ||
982 | |||
983 | switch (snd_pcm_format_width(params_format(params))) { | ||
984 | case 16: | ||
985 | alen = PCM512x_ALEN_16; | ||
986 | break; | ||
987 | case 20: | ||
988 | alen = PCM512x_ALEN_20; | ||
989 | break; | ||
990 | case 24: | ||
991 | alen = PCM512x_ALEN_24; | ||
992 | break; | ||
993 | case 32: | ||
994 | alen = PCM512x_ALEN_32; | ||
995 | break; | ||
996 | default: | ||
997 | dev_err(codec->dev, "Bad frame size: %d\n", | ||
998 | snd_pcm_format_width(params_format(params))); | ||
999 | return -EINVAL; | ||
1000 | } | ||
1001 | |||
1002 | switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1003 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1004 | ret = regmap_update_bits(pcm512x->regmap, | ||
1005 | PCM512x_BCLK_LRCLK_CFG, | ||
1006 | PCM512x_BCKP | ||
1007 | | PCM512x_BCKO | PCM512x_LRKO, | ||
1008 | 0); | ||
1009 | if (ret != 0) { | ||
1010 | dev_err(codec->dev, | ||
1011 | "Failed to enable slave mode: %d\n", ret); | ||
1012 | return ret; | ||
1013 | } | ||
1014 | |||
1015 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
1016 | PCM512x_DCAS, 0); | ||
1017 | if (ret != 0) { | ||
1018 | dev_err(codec->dev, | ||
1019 | "Failed to enable clock divider autoset: %d\n", | ||
1020 | ret); | ||
1021 | return ret; | ||
1022 | } | ||
1023 | return 0; | ||
1024 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1025 | clock_output = PCM512x_BCKO | PCM512x_LRKO; | ||
1026 | master_mode = PCM512x_RLRK | PCM512x_RBCK; | ||
1027 | break; | ||
1028 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1029 | clock_output = PCM512x_BCKO; | ||
1030 | master_mode = PCM512x_RBCK; | ||
1031 | break; | ||
1032 | default: | ||
1033 | return -EINVAL; | ||
1034 | } | ||
1035 | |||
1036 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1, | ||
1037 | PCM512x_ALEN, alen); | ||
1038 | if (ret != 0) { | ||
1039 | dev_err(codec->dev, "Failed to set frame size: %d\n", ret); | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | if (pcm512x->pll_out) { | ||
1044 | ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11); | ||
1045 | if (ret != 0) { | ||
1046 | dev_err(codec->dev, "Failed to set FLEX_A: %d\n", ret); | ||
1047 | return ret; | ||
1048 | } | ||
1049 | |||
1050 | ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff); | ||
1051 | if (ret != 0) { | ||
1052 | dev_err(codec->dev, "Failed to set FLEX_B: %d\n", ret); | ||
1053 | return ret; | ||
1054 | } | ||
1055 | |||
1056 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
1057 | PCM512x_IDFS | PCM512x_IDBK | ||
1058 | | PCM512x_IDSK | PCM512x_IDCH | ||
1059 | | PCM512x_IDCM | PCM512x_DCAS | ||
1060 | | PCM512x_IPLK, | ||
1061 | PCM512x_IDFS | PCM512x_IDBK | ||
1062 | | PCM512x_IDSK | PCM512x_IDCH | ||
1063 | | PCM512x_DCAS); | ||
1064 | if (ret != 0) { | ||
1065 | dev_err(codec->dev, | ||
1066 | "Failed to ignore auto-clock failures: %d\n", | ||
1067 | ret); | ||
1068 | return ret; | ||
1069 | } | ||
1070 | } else { | ||
1071 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
1072 | PCM512x_IDFS | PCM512x_IDBK | ||
1073 | | PCM512x_IDSK | PCM512x_IDCH | ||
1074 | | PCM512x_IDCM | PCM512x_DCAS | ||
1075 | | PCM512x_IPLK, | ||
1076 | PCM512x_IDFS | PCM512x_IDBK | ||
1077 | | PCM512x_IDSK | PCM512x_IDCH | ||
1078 | | PCM512x_DCAS | PCM512x_IPLK); | ||
1079 | if (ret != 0) { | ||
1080 | dev_err(codec->dev, | ||
1081 | "Failed to ignore auto-clock failures: %d\n", | ||
1082 | ret); | ||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | ||
1087 | PCM512x_PLLE, 0); | ||
1088 | if (ret != 0) { | ||
1089 | dev_err(codec->dev, "Failed to disable pll: %d\n", ret); | ||
1090 | return ret; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | ret = pcm512x_set_dividers(dai, params); | ||
1095 | if (ret != 0) | ||
1096 | return ret; | ||
1097 | |||
1098 | if (pcm512x->pll_out) { | ||
1099 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_REF, | ||
1100 | PCM512x_SREF, PCM512x_SREF_GPIO); | ||
1101 | if (ret != 0) { | ||
1102 | dev_err(codec->dev, | ||
1103 | "Failed to set gpio as pllref: %d\n", ret); | ||
1104 | return ret; | ||
1105 | } | ||
1106 | |||
1107 | gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1; | ||
1108 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_PLLIN, | ||
1109 | PCM512x_GREF, gpio); | ||
1110 | if (ret != 0) { | ||
1111 | dev_err(codec->dev, | ||
1112 | "Failed to set gpio %d as pllin: %d\n", | ||
1113 | pcm512x->pll_in, ret); | ||
1114 | return ret; | ||
1115 | } | ||
1116 | |||
1117 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | ||
1118 | PCM512x_PLLE, PCM512x_PLLE); | ||
1119 | if (ret != 0) { | ||
1120 | dev_err(codec->dev, "Failed to enable pll: %d\n", ret); | ||
1121 | return ret; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_BCLK_LRCLK_CFG, | ||
1126 | PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO, | ||
1127 | clock_output); | ||
1128 | if (ret != 0) { | ||
1129 | dev_err(codec->dev, "Failed to enable clock output: %d\n", ret); | ||
1130 | return ret; | ||
1131 | } | ||
1132 | |||
1133 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_MASTER_MODE, | ||
1134 | PCM512x_RLRK | PCM512x_RBCK, | ||
1135 | master_mode); | ||
1136 | if (ret != 0) { | ||
1137 | dev_err(codec->dev, "Failed to enable master mode: %d\n", ret); | ||
1138 | return ret; | ||
1139 | } | ||
1140 | |||
1141 | if (pcm512x->pll_out) { | ||
1142 | gpio = PCM512x_G1OE << (pcm512x->pll_out - 1); | ||
1143 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN, | ||
1144 | gpio, gpio); | ||
1145 | if (ret != 0) { | ||
1146 | dev_err(codec->dev, "Failed to enable gpio %d: %d\n", | ||
1147 | pcm512x->pll_out, ret); | ||
1148 | return ret; | ||
1149 | } | ||
1150 | |||
1151 | gpio = PCM512x_GPIO_OUTPUT_1 + pcm512x->pll_out - 1; | ||
1152 | ret = regmap_update_bits(pcm512x->regmap, gpio, | ||
1153 | PCM512x_GxSL, PCM512x_GxSL_PLLCK); | ||
1154 | if (ret != 0) { | ||
1155 | dev_err(codec->dev, "Failed to output pll on %d: %d\n", | ||
1156 | ret, pcm512x->pll_out); | ||
1157 | return ret; | ||
1158 | } | ||
1159 | |||
1160 | gpio = PCM512x_G1OE << (4 - 1); | ||
1161 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN, | ||
1162 | gpio, gpio); | ||
1163 | if (ret != 0) { | ||
1164 | dev_err(codec->dev, "Failed to enable gpio %d: %d\n", | ||
1165 | 4, ret); | ||
1166 | return ret; | ||
1167 | } | ||
1168 | |||
1169 | gpio = PCM512x_GPIO_OUTPUT_1 + 4 - 1; | ||
1170 | ret = regmap_update_bits(pcm512x->regmap, gpio, | ||
1171 | PCM512x_GxSL, PCM512x_GxSL_PLLLK); | ||
1172 | if (ret != 0) { | ||
1173 | dev_err(codec->dev, | ||
1174 | "Failed to output pll lock on %d: %d\n", | ||
1175 | ret, 4); | ||
1176 | return ret; | ||
1177 | } | ||
1178 | } | ||
1179 | |||
1180 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, | ||
1181 | PCM512x_RQSY, PCM512x_RQSY_HALT); | ||
1182 | if (ret != 0) { | ||
1183 | dev_err(codec->dev, "Failed to halt clocks: %d\n", ret); | ||
1184 | return ret; | ||
1185 | } | ||
1186 | |||
1187 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, | ||
1188 | PCM512x_RQSY, PCM512x_RQSY_RESUME); | ||
1189 | if (ret != 0) { | ||
1190 | dev_err(codec->dev, "Failed to resume clocks: %d\n", ret); | ||
1191 | return ret; | ||
1192 | } | ||
1193 | |||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1197 | static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
1198 | { | ||
1199 | struct snd_soc_codec *codec = dai->codec; | ||
1200 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
1201 | |||
1202 | pcm512x->fmt = fmt; | ||
1203 | |||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | static const struct snd_soc_dai_ops pcm512x_dai_ops = { | ||
1208 | .startup = pcm512x_dai_startup, | ||
1209 | .hw_params = pcm512x_hw_params, | ||
1210 | .set_fmt = pcm512x_set_fmt, | ||
1211 | }; | ||
1212 | |||
343 | static struct snd_soc_dai_driver pcm512x_dai = { | 1213 | static struct snd_soc_dai_driver pcm512x_dai = { |
344 | .name = "pcm512x-hifi", | 1214 | .name = "pcm512x-hifi", |
345 | .playback = { | 1215 | .playback = { |
346 | .stream_name = "Playback", | 1216 | .stream_name = "Playback", |
347 | .channels_min = 2, | 1217 | .channels_min = 2, |
348 | .channels_max = 2, | 1218 | .channels_max = 2, |
349 | .rates = SNDRV_PCM_RATE_8000_192000, | 1219 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
1220 | .rate_min = 8000, | ||
1221 | .rate_max = 384000, | ||
350 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 1222 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
351 | SNDRV_PCM_FMTBIT_S24_LE | | 1223 | SNDRV_PCM_FMTBIT_S24_LE | |
352 | SNDRV_PCM_FMTBIT_S32_LE | 1224 | SNDRV_PCM_FMTBIT_S32_LE |
353 | }, | 1225 | }, |
1226 | .ops = &pcm512x_dai_ops, | ||
354 | }; | 1227 | }; |
355 | 1228 | ||
356 | static struct snd_soc_codec_driver pcm512x_codec_driver = { | 1229 | static struct snd_soc_codec_driver pcm512x_codec_driver = { |
@@ -448,21 +1321,9 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) | |||
448 | } | 1321 | } |
449 | 1322 | ||
450 | pcm512x->sclk = devm_clk_get(dev, NULL); | 1323 | pcm512x->sclk = devm_clk_get(dev, NULL); |
451 | if (IS_ERR(pcm512x->sclk)) { | 1324 | if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) |
452 | if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) | 1325 | return -EPROBE_DEFER; |
453 | return -EPROBE_DEFER; | 1326 | if (!IS_ERR(pcm512x->sclk)) { |
454 | |||
455 | dev_info(dev, "No SCLK, using BCLK: %ld\n", | ||
456 | PTR_ERR(pcm512x->sclk)); | ||
457 | |||
458 | /* Disable reporting of missing SCLK as an error */ | ||
459 | regmap_update_bits(regmap, PCM512x_ERROR_DETECT, | ||
460 | PCM512x_IDCH, PCM512x_IDCH); | ||
461 | |||
462 | /* Switch PLL input to BCLK */ | ||
463 | regmap_update_bits(regmap, PCM512x_PLL_REF, | ||
464 | PCM512x_SREF, PCM512x_SREF); | ||
465 | } else { | ||
466 | ret = clk_prepare_enable(pcm512x->sclk); | 1327 | ret = clk_prepare_enable(pcm512x->sclk); |
467 | if (ret != 0) { | 1328 | if (ret != 0) { |
468 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); | 1329 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); |
@@ -483,6 +1344,43 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) | |||
483 | pm_runtime_enable(dev); | 1344 | pm_runtime_enable(dev); |
484 | pm_runtime_idle(dev); | 1345 | pm_runtime_idle(dev); |
485 | 1346 | ||
1347 | #ifdef CONFIG_OF | ||
1348 | if (dev->of_node) { | ||
1349 | const struct device_node *np = dev->of_node; | ||
1350 | u32 val; | ||
1351 | |||
1352 | if (of_property_read_u32(np, "pll-in", &val) >= 0) { | ||
1353 | if (val > 6) { | ||
1354 | dev_err(dev, "Invalid pll-in\n"); | ||
1355 | ret = -EINVAL; | ||
1356 | goto err_clk; | ||
1357 | } | ||
1358 | pcm512x->pll_in = val; | ||
1359 | } | ||
1360 | |||
1361 | if (of_property_read_u32(np, "pll-out", &val) >= 0) { | ||
1362 | if (val > 6) { | ||
1363 | dev_err(dev, "Invalid pll-out\n"); | ||
1364 | ret = -EINVAL; | ||
1365 | goto err_clk; | ||
1366 | } | ||
1367 | pcm512x->pll_out = val; | ||
1368 | } | ||
1369 | |||
1370 | if (!pcm512x->pll_in != !pcm512x->pll_out) { | ||
1371 | dev_err(dev, | ||
1372 | "Error: both pll-in and pll-out, or none\n"); | ||
1373 | ret = -EINVAL; | ||
1374 | goto err_clk; | ||
1375 | } | ||
1376 | if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) { | ||
1377 | dev_err(dev, "Error: pll-in == pll-out\n"); | ||
1378 | ret = -EINVAL; | ||
1379 | goto err_clk; | ||
1380 | } | ||
1381 | } | ||
1382 | #endif | ||
1383 | |||
486 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, | 1384 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, |
487 | &pcm512x_dai, 1); | 1385 | &pcm512x_dai, 1); |
488 | if (ret != 0) { | 1386 | if (ret != 0) { |
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h index 6ee76aaca09a..b7c310207223 100644 --- a/sound/soc/codecs/pcm512x.h +++ b/sound/soc/codecs/pcm512x.h | |||
@@ -37,6 +37,10 @@ | |||
37 | #define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10) | 37 | #define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10) |
38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) | 38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) |
39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) | 39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) |
40 | #define PCM512x_DAC_REF (PCM512x_PAGE_BASE(0) + 14) | ||
41 | #define PCM512x_GPIO_DACIN (PCM512x_PAGE_BASE(0) + 16) | ||
42 | #define PCM512x_GPIO_PLLIN (PCM512x_PAGE_BASE(0) + 18) | ||
43 | #define PCM512x_SYNCHRONIZE (PCM512x_PAGE_BASE(0) + 19) | ||
40 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) | 44 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) |
41 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) | 45 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) |
42 | #define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22) | 46 | #define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22) |
@@ -77,6 +81,7 @@ | |||
77 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) | 81 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) |
78 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) | 82 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) |
79 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) | 83 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) |
84 | #define PCM512x_CLOCK_STATUS (PCM512x_PAGE_BASE(0) + 95) | ||
80 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) | 85 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) |
81 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) | 86 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) |
82 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) | 87 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) |
@@ -91,7 +96,10 @@ | |||
91 | 96 | ||
92 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) | 97 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) |
93 | 98 | ||
94 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1) | 99 | #define PCM512x_FLEX_A (PCM512x_PAGE_BASE(253) + 63) |
100 | #define PCM512x_FLEX_B (PCM512x_PAGE_BASE(253) + 64) | ||
101 | |||
102 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(253) + 64) | ||
95 | 103 | ||
96 | /* Page 0, Register 1 - reset */ | 104 | /* Page 0, Register 1 - reset */ |
97 | #define PCM512x_RSTR (1 << 0) | 105 | #define PCM512x_RSTR (1 << 0) |
@@ -108,8 +116,8 @@ | |||
108 | #define PCM512x_RQML_SHIFT 4 | 116 | #define PCM512x_RQML_SHIFT 4 |
109 | 117 | ||
110 | /* Page 0, Register 4 - PLL */ | 118 | /* Page 0, Register 4 - PLL */ |
111 | #define PCM512x_PLCE (1 << 0) | 119 | #define PCM512x_PLLE (1 << 0) |
112 | #define PCM512x_RLCE_SHIFT 0 | 120 | #define PCM512x_PLLE_SHIFT 0 |
113 | #define PCM512x_PLCK (1 << 4) | 121 | #define PCM512x_PLCK (1 << 4) |
114 | #define PCM512x_PLCK_SHIFT 4 | 122 | #define PCM512x_PLCK_SHIFT 4 |
115 | 123 | ||
@@ -119,8 +127,66 @@ | |||
119 | #define PCM512x_DEMP (1 << 4) | 127 | #define PCM512x_DEMP (1 << 4) |
120 | #define PCM512x_DEMP_SHIFT 4 | 128 | #define PCM512x_DEMP_SHIFT 4 |
121 | 129 | ||
130 | /* Page 0, Register 8 - GPIO output enable */ | ||
131 | #define PCM512x_G1OE (1 << 0) | ||
132 | #define PCM512x_G2OE (1 << 1) | ||
133 | #define PCM512x_G3OE (1 << 2) | ||
134 | #define PCM512x_G4OE (1 << 3) | ||
135 | #define PCM512x_G5OE (1 << 4) | ||
136 | #define PCM512x_G6OE (1 << 5) | ||
137 | |||
138 | /* Page 0, Register 9 - BCK, LRCLK configuration */ | ||
139 | #define PCM512x_LRKO (1 << 0) | ||
140 | #define PCM512x_LRKO_SHIFT 0 | ||
141 | #define PCM512x_BCKO (1 << 4) | ||
142 | #define PCM512x_BCKO_SHIFT 4 | ||
143 | #define PCM512x_BCKP (1 << 5) | ||
144 | #define PCM512x_BCKP_SHIFT 5 | ||
145 | |||
146 | /* Page 0, Register 12 - Master mode BCK, LRCLK reset */ | ||
147 | #define PCM512x_RLRK (1 << 0) | ||
148 | #define PCM512x_RLRK_SHIFT 0 | ||
149 | #define PCM512x_RBCK (1 << 1) | ||
150 | #define PCM512x_RBCK_SHIFT 1 | ||
151 | |||
122 | /* Page 0, Register 13 - PLL reference */ | 152 | /* Page 0, Register 13 - PLL reference */ |
123 | #define PCM512x_SREF (1 << 4) | 153 | #define PCM512x_SREF (7 << 4) |
154 | #define PCM512x_SREF_SHIFT 4 | ||
155 | #define PCM512x_SREF_SCK (0 << 4) | ||
156 | #define PCM512x_SREF_BCK (1 << 4) | ||
157 | #define PCM512x_SREF_GPIO (3 << 4) | ||
158 | |||
159 | /* Page 0, Register 14 - DAC reference */ | ||
160 | #define PCM512x_SDAC (7 << 4) | ||
161 | #define PCM512x_SDAC_SHIFT 4 | ||
162 | #define PCM512x_SDAC_MCK (0 << 4) | ||
163 | #define PCM512x_SDAC_PLL (1 << 4) | ||
164 | #define PCM512x_SDAC_SCK (3 << 4) | ||
165 | #define PCM512x_SDAC_BCK (4 << 4) | ||
166 | #define PCM512x_SDAC_GPIO (5 << 4) | ||
167 | |||
168 | /* Page 0, Register 16, 18 - GPIO source for DAC, PLL */ | ||
169 | #define PCM512x_GREF (7 << 0) | ||
170 | #define PCM512x_GREF_SHIFT 0 | ||
171 | #define PCM512x_GREF_GPIO1 (0 << 0) | ||
172 | #define PCM512x_GREF_GPIO2 (1 << 0) | ||
173 | #define PCM512x_GREF_GPIO3 (2 << 0) | ||
174 | #define PCM512x_GREF_GPIO4 (3 << 0) | ||
175 | #define PCM512x_GREF_GPIO5 (4 << 0) | ||
176 | #define PCM512x_GREF_GPIO6 (5 << 0) | ||
177 | |||
178 | /* Page 0, Register 19 - synchronize */ | ||
179 | #define PCM512x_RQSY (1 << 0) | ||
180 | #define PCM512x_RQSY_RESUME (0 << 0) | ||
181 | #define PCM512x_RQSY_HALT (1 << 0) | ||
182 | |||
183 | /* Page 0, Register 34 - fs speed mode */ | ||
184 | #define PCM512x_FSSP (3 << 0) | ||
185 | #define PCM512x_FSSP_SHIFT 0 | ||
186 | #define PCM512x_FSSP_48KHZ (0 << 0) | ||
187 | #define PCM512x_FSSP_96KHZ (1 << 0) | ||
188 | #define PCM512x_FSSP_192KHZ (2 << 0) | ||
189 | #define PCM512x_FSSP_384KHZ (3 << 0) | ||
124 | 190 | ||
125 | /* Page 0, Register 37 - Error detection */ | 191 | /* Page 0, Register 37 - Error detection */ |
126 | #define PCM512x_IPLK (1 << 0) | 192 | #define PCM512x_IPLK (1 << 0) |
@@ -131,6 +197,20 @@ | |||
131 | #define PCM512x_IDBK (1 << 5) | 197 | #define PCM512x_IDBK (1 << 5) |
132 | #define PCM512x_IDFS (1 << 6) | 198 | #define PCM512x_IDFS (1 << 6) |
133 | 199 | ||
200 | /* Page 0, Register 40 - I2S configuration */ | ||
201 | #define PCM512x_ALEN (3 << 0) | ||
202 | #define PCM512x_ALEN_SHIFT 0 | ||
203 | #define PCM512x_ALEN_16 (0 << 0) | ||
204 | #define PCM512x_ALEN_20 (1 << 0) | ||
205 | #define PCM512x_ALEN_24 (2 << 0) | ||
206 | #define PCM512x_ALEN_32 (3 << 0) | ||
207 | #define PCM512x_AFMT (3 << 4) | ||
208 | #define PCM512x_AFMT_SHIFT 4 | ||
209 | #define PCM512x_AFMT_I2S (0 << 4) | ||
210 | #define PCM512x_AFMT_DSP (1 << 4) | ||
211 | #define PCM512x_AFMT_RTJ (2 << 4) | ||
212 | #define PCM512x_AFMT_LTJ (3 << 4) | ||
213 | |||
134 | /* Page 0, Register 42 - DAC routing */ | 214 | /* Page 0, Register 42 - DAC routing */ |
135 | #define PCM512x_AUPR_SHIFT 0 | 215 | #define PCM512x_AUPR_SHIFT 0 |
136 | #define PCM512x_AUPL_SHIFT 4 | 216 | #define PCM512x_AUPL_SHIFT 4 |
@@ -152,7 +232,26 @@ | |||
152 | /* Page 0, Register 65 - Digital mute enables */ | 232 | /* Page 0, Register 65 - Digital mute enables */ |
153 | #define PCM512x_ACTL_SHIFT 2 | 233 | #define PCM512x_ACTL_SHIFT 2 |
154 | #define PCM512x_AMLE_SHIFT 1 | 234 | #define PCM512x_AMLE_SHIFT 1 |
155 | #define PCM512x_AMLR_SHIFT 0 | 235 | #define PCM512x_AMRE_SHIFT 0 |
236 | |||
237 | /* Page 0, Register 80-85, GPIO output selection */ | ||
238 | #define PCM512x_GxSL (31 << 0) | ||
239 | #define PCM512x_GxSL_SHIFT 0 | ||
240 | #define PCM512x_GxSL_OFF (0 << 0) | ||
241 | #define PCM512x_GxSL_DSP (1 << 0) | ||
242 | #define PCM512x_GxSL_REG (2 << 0) | ||
243 | #define PCM512x_GxSL_AMUTB (3 << 0) | ||
244 | #define PCM512x_GxSL_AMUTL (4 << 0) | ||
245 | #define PCM512x_GxSL_AMUTR (5 << 0) | ||
246 | #define PCM512x_GxSL_CLKI (6 << 0) | ||
247 | #define PCM512x_GxSL_SDOUT (7 << 0) | ||
248 | #define PCM512x_GxSL_ANMUL (8 << 0) | ||
249 | #define PCM512x_GxSL_ANMUR (9 << 0) | ||
250 | #define PCM512x_GxSL_PLLLK (10 << 0) | ||
251 | #define PCM512x_GxSL_CPCLK (11 << 0) | ||
252 | #define PCM512x_GxSL_UV0_7 (14 << 0) | ||
253 | #define PCM512x_GxSL_UV0_3 (15 << 0) | ||
254 | #define PCM512x_GxSL_PLLCK (16 << 0) | ||
156 | 255 | ||
157 | /* Page 1, Register 2 - analog volume control */ | 256 | /* Page 1, Register 2 - analog volume control */ |
158 | #define PCM512x_RAGN_SHIFT 0 | 257 | #define PCM512x_RAGN_SHIFT 0 |