aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorPeter Rosin <peda@axentia.se>2015-02-23 15:03:33 -0500
committerMark Brown <broonie@kernel.org>2015-02-24 09:14:25 -0500
commitf29933c9ae4b8f30c713186d3babb630c7cfb4f2 (patch)
tree37284ecb886e0b2d14901e165320701c52863ea6 /sound/soc
parent5890bd5256bc026c425361fa087dc05c7a24d853 (diff)
ASoC: pcm512x: Allow independently overclocking PLL, DAC and DSP
When using non-standard rates, a relatively small amount of overclocking can make a big difference to a number of cases. - Not all rates are possible to achieve with the PLL, due to divider restrictions. - The higher oversampling rates that can be used by the DAC, the simpler the analog output filters get (mirror frequencies move up, away from the desired spectrum). - The more work the DSP can perform per sample, the better. For standard rates, there is little to gain as everything is designed just right, and the needed overclocking to make a real difference would be significant. Signed-off-by: Peter Rosin <peda@axentia.se> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/pcm512x.c161
1 files changed, 150 insertions, 11 deletions
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index f11c76f1acfe..4b5f1fe9be97 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -54,6 +54,9 @@ struct pcm512x_priv {
54 int pll_d; 54 int pll_d;
55 int pll_p; 55 int pll_p;
56 unsigned long real_pll; 56 unsigned long real_pll;
57 unsigned long overclock_pll;
58 unsigned long overclock_dac;
59 unsigned long overclock_dsp;
57}; 60};
58 61
59/* 62/*
@@ -224,6 +227,90 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg)
224 } 227 }
225} 228}
226 229
230static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_value *ucontrol)
232{
233 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
234 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
235
236 ucontrol->value.integer.value[0] = pcm512x->overclock_pll;
237 return 0;
238}
239
240static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
241 struct snd_ctl_elem_value *ucontrol)
242{
243 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
244 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
245
246 switch (codec->dapm.bias_level) {
247 case SND_SOC_BIAS_OFF:
248 case SND_SOC_BIAS_STANDBY:
249 break;
250 default:
251 return -EBUSY;
252 }
253
254 pcm512x->overclock_pll = ucontrol->value.integer.value[0];
255 return 0;
256}
257
258static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_value *ucontrol)
260{
261 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
262 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
263
264 ucontrol->value.integer.value[0] = pcm512x->overclock_dsp;
265 return 0;
266}
267
268static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
272 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
273
274 switch (codec->dapm.bias_level) {
275 case SND_SOC_BIAS_OFF:
276 case SND_SOC_BIAS_STANDBY:
277 break;
278 default:
279 return -EBUSY;
280 }
281
282 pcm512x->overclock_dsp = ucontrol->value.integer.value[0];
283 return 0;
284}
285
286static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
290 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
291
292 ucontrol->value.integer.value[0] = pcm512x->overclock_dac;
293 return 0;
294}
295
296static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
298{
299 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
300 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
301
302 switch (codec->dapm.bias_level) {
303 case SND_SOC_BIAS_OFF:
304 case SND_SOC_BIAS_STANDBY:
305 break;
306 default:
307 return -EBUSY;
308 }
309
310 pcm512x->overclock_dac = ucontrol->value.integer.value[0];
311 return 0;
312}
313
227static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1); 314static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
228static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0); 315static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
229static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0); 316static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
@@ -328,6 +415,13 @@ SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
328SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus), 415SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
329SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf), 416SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
330SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds), 417SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
418
419SOC_SINGLE_EXT("Max Overclock PLL", SND_SOC_NOPM, 0, 20, 0,
420 pcm512x_overclock_pll_get, pcm512x_overclock_pll_put),
421SOC_SINGLE_EXT("Max Overclock DSP", SND_SOC_NOPM, 0, 40, 0,
422 pcm512x_overclock_dsp_get, pcm512x_overclock_dsp_put),
423SOC_SINGLE_EXT("Max Overclock DAC", SND_SOC_NOPM, 0, 40, 0,
424 pcm512x_overclock_dac_get, pcm512x_overclock_dac_put),
331}; 425};
332 426
333static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = { 427static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
@@ -346,6 +440,45 @@ static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
346 { "OUTR", NULL, "DACR" }, 440 { "OUTR", NULL, "DACR" },
347}; 441};
348 442
443static unsigned long pcm512x_pll_max(struct pcm512x_priv *pcm512x)
444{
445 return 25000000 + 25000000 * pcm512x->overclock_pll / 100;
446}
447
448static unsigned long pcm512x_dsp_max(struct pcm512x_priv *pcm512x)
449{
450 return 50000000 + 50000000 * pcm512x->overclock_dsp / 100;
451}
452
453static unsigned long pcm512x_dac_max(struct pcm512x_priv *pcm512x,
454 unsigned long rate)
455{
456 return rate + rate * pcm512x->overclock_dac / 100;
457}
458
459static unsigned long pcm512x_sck_max(struct pcm512x_priv *pcm512x)
460{
461 if (!pcm512x->pll_out)
462 return 25000000;
463 return pcm512x_pll_max(pcm512x);
464}
465
466static unsigned long pcm512x_ncp_target(struct pcm512x_priv *pcm512x,
467 unsigned long dac_rate)
468{
469 /*
470 * If the DAC is not actually overclocked, use the good old
471 * NCP target rate...
472 */
473 if (dac_rate <= 6144000)
474 return 1536000;
475 /*
476 * ...but if the DAC is in fact overclocked, bump the NCP target
477 * rate to get the recommended dividers even when overclocking.
478 */
479 return pcm512x_dac_max(pcm512x, 1536000);
480}
481
349static const u32 pcm512x_dai_rates[] = { 482static const u32 pcm512x_dai_rates[] = {
350 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 483 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
351 88200, 96000, 176400, 192000, 384000, 484 88200, 96000, 176400, 192000, 384000,
@@ -359,6 +492,7 @@ static const struct snd_pcm_hw_constraint_list constraints_slave = {
359static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params, 492static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
360 struct snd_pcm_hw_rule *rule) 493 struct snd_pcm_hw_rule *rule)
361{ 494{
495 struct pcm512x_priv *pcm512x = rule->private;
362 struct snd_interval ranges[2]; 496 struct snd_interval ranges[2];
363 int frame_size; 497 int frame_size;
364 498
@@ -377,7 +511,7 @@ static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
377 */ 511 */
378 memset(ranges, 0, sizeof(ranges)); 512 memset(ranges, 0, sizeof(ranges));
379 ranges[0].min = 8000; 513 ranges[0].min = 8000;
380 ranges[0].max = 25000000 / frame_size / 2; 514 ranges[0].max = pcm512x_sck_max(pcm512x) / frame_size / 2;
381 ranges[1].min = DIV_ROUND_UP(16000000, frame_size); 515 ranges[1].min = DIV_ROUND_UP(16000000, frame_size);
382 ranges[1].max = 384000; 516 ranges[1].max = 384000;
383 break; 517 break;
@@ -408,7 +542,7 @@ static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
408 return snd_pcm_hw_rule_add(substream->runtime, 0, 542 return snd_pcm_hw_rule_add(substream->runtime, 0,
409 SNDRV_PCM_HW_PARAM_RATE, 543 SNDRV_PCM_HW_PARAM_RATE,
410 pcm512x_hw_rule_rate, 544 pcm512x_hw_rule_rate,
411 NULL, 545 pcm512x,
412 SNDRV_PCM_HW_PARAM_FRAME_BITS, 546 SNDRV_PCM_HW_PARAM_FRAME_BITS,
413 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 547 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
414 548
@@ -517,6 +651,8 @@ static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
517 unsigned long bclk_rate) 651 unsigned long bclk_rate)
518{ 652{
519 struct device *dev = dai->dev; 653 struct device *dev = dai->dev;
654 struct snd_soc_codec *codec = dai->codec;
655 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
520 unsigned long sck_rate; 656 unsigned long sck_rate;
521 int pow2; 657 int pow2;
522 658
@@ -527,9 +663,10 @@ static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
527 * as many factors of 2 as possible, as that makes it easier 663 * as many factors of 2 as possible, as that makes it easier
528 * to find a fast DAC rate 664 * to find a fast DAC rate
529 */ 665 */
530 pow2 = 1 << fls((25000000 - 16000000) / bclk_rate); 666 pow2 = 1 << fls((pcm512x_pll_max(pcm512x) - 16000000) / bclk_rate);
531 for (; pow2; pow2 >>= 1) { 667 for (; pow2; pow2 >>= 1) {
532 sck_rate = rounddown(25000000, bclk_rate * pow2); 668 sck_rate = rounddown(pcm512x_pll_max(pcm512x),
669 bclk_rate * pow2);
533 if (sck_rate >= 16000000) 670 if (sck_rate >= 16000000)
534 break; 671 break;
535 } 672 }
@@ -678,7 +815,7 @@ static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai,
678 return 0; /* futile, quit early */ 815 return 0; /* futile, quit early */
679 816
680 /* run DAC no faster than 6144000 Hz */ 817 /* run DAC no faster than 6144000 Hz */
681 for (dac_rate = rounddown(6144000, osr_rate); 818 for (dac_rate = rounddown(pcm512x_dac_max(pcm512x, 6144000), osr_rate);
682 dac_rate; 819 dac_rate;
683 dac_rate -= osr_rate) { 820 dac_rate -= osr_rate) {
684 821
@@ -805,7 +942,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
805 osr_rate = 16 * sample_rate; 942 osr_rate = 16 * sample_rate;
806 943
807 /* run DSP no faster than 50 MHz */ 944 /* run DSP no faster than 50 MHz */
808 dsp_div = mck_rate > 50000000 ? 2 : 1; 945 dsp_div = mck_rate > pcm512x_dsp_max(pcm512x) ? 2 : 1;
809 946
810 dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate); 947 dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate);
811 if (dac_rate) { 948 if (dac_rate) {
@@ -836,7 +973,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
836 dacsrc_rate = pllin_rate; 973 dacsrc_rate = pllin_rate;
837 } else { 974 } else {
838 /* run DAC no faster than 6144000 Hz */ 975 /* run DAC no faster than 6144000 Hz */
839 unsigned long dac_mul = 6144000 / osr_rate; 976 unsigned long dac_mul = pcm512x_dac_max(pcm512x, 6144000)
977 / osr_rate;
840 unsigned long sck_mul = sck_rate / osr_rate; 978 unsigned long sck_mul = sck_rate / osr_rate;
841 979
842 for (; dac_mul; dac_mul--) { 980 for (; dac_mul; dac_mul--) {
@@ -876,7 +1014,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
876 } 1014 }
877 dac_rate = dacsrc_rate / dac_div; 1015 dac_rate = dacsrc_rate / dac_div;
878 1016
879 ncp_div = DIV_ROUND_CLOSEST(dac_rate, 1536000); 1017 ncp_div = DIV_ROUND_CLOSEST(dac_rate,
1018 pcm512x_ncp_target(pcm512x, dac_rate));
880 if (ncp_div > 128 || dac_rate / ncp_div > 2048000) { 1019 if (ncp_div > 128 || dac_rate / ncp_div > 2048000) {
881 /* run NCP no faster than 2048000 Hz, but why? */ 1020 /* run NCP no faster than 2048000 Hz, but why? */
882 ncp_div = DIV_ROUND_UP(dac_rate, 2048000); 1021 ncp_div = DIV_ROUND_UP(dac_rate, 2048000);
@@ -938,11 +1077,11 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
938 return ret; 1077 return ret;
939 } 1078 }
940 1079
941 if (sample_rate <= 48000) 1080 if (sample_rate <= pcm512x_dac_max(pcm512x, 48000))
942 fssp = PCM512x_FSSP_48KHZ; 1081 fssp = PCM512x_FSSP_48KHZ;
943 else if (sample_rate <= 96000) 1082 else if (sample_rate <= pcm512x_dac_max(pcm512x, 96000))
944 fssp = PCM512x_FSSP_96KHZ; 1083 fssp = PCM512x_FSSP_96KHZ;
945 else if (sample_rate <= 192000) 1084 else if (sample_rate <= pcm512x_dac_max(pcm512x, 192000))
946 fssp = PCM512x_FSSP_192KHZ; 1085 fssp = PCM512x_FSSP_192KHZ;
947 else 1086 else
948 fssp = PCM512x_FSSP_384KHZ; 1087 fssp = PCM512x_FSSP_384KHZ;