Commit a577b318fc7cb0c46f9f0cdefb5b267490ff8ce5

Authored by Peter Ujfalusi
Committed by Liam Girdwood
1 parent f430a27f05

ASoC: tlv320dac33: Add support for automatic FIFO configuration

Platform parameter to enable automatic FIFO configuration when
the codec is in Mode1 or Mode7 FIFO mode.
When this mode is selected, the controls for changing
nSample (in Mode1), and UTHR (in Mode7) are not added.
The driver configures the FIFO configuration based on
the stream's period size in a way, that every burst will
read period size of data from the host.
In Mode7 we need to use a formula, which gives close enough
aproximation for the burst length from the host point
of view.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>

Showing 2 changed files with 65 additions and 26 deletions Side-by-side Diff

include/sound/tlv320dac33-plat.h
... ... @@ -16,6 +16,7 @@
16 16 struct tlv320dac33_platform_data {
17 17 int power_gpio;
18 18 int mode1_latency; /* latency caused by the i2c writes in us */
  19 + int auto_fifo_config; /* FIFO config based on the period size */
19 20 int keep_bclk; /* Keep the BCLK running in FIFO modes */
20 21 u8 burst_bclkdiv;
21 22 };
sound/soc/codecs/tlv320dac33.c
... ... @@ -60,6 +60,9 @@
60 60 #define US_TO_SAMPLES(rate, us) \
61 61 (rate / (1000000 / us))
62 62  
  63 +#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
  64 + ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate)))
  65 +
63 66 static void dac33_calculate_times(struct snd_pcm_substream *substream);
64 67 static int dac33_prepare_chip(struct snd_pcm_substream *substream);
65 68  
... ... @@ -107,6 +110,8 @@
107 110 unsigned int nsample; /* burst read amount from host */
108 111 int mode1_latency; /* latency caused by the i2c writes in
109 112 * us */
  113 + int auto_fifo_config; /* Configure the FIFO based on the
  114 + * period size */
110 115 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
111 116 unsigned int burst_rate; /* Interface speed in Burst modes */
112 117  
113 118  
114 119  
... ... @@ -538,13 +543,16 @@
538 543 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
539 544 };
540 545  
541   -static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
  546 +static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
  547 + SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
  548 + dac33_get_fifo_mode, dac33_set_fifo_mode),
  549 +};
  550 +
  551 +static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = {
542 552 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
543   - dac33_get_nsample, dac33_set_nsample),
  553 + dac33_get_nsample, dac33_set_nsample),
544 554 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
545 555 dac33_get_uthr, dac33_set_uthr),
546   - SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
547   - dac33_get_fifo_mode, dac33_set_fifo_mode),
548 556 };
549 557  
550 558 /* Analog bypass */
551 559  
... ... @@ -1057,24 +1065,38 @@
1057 1065 /* Number of samples under i2c latency */
1058 1066 dac33->alarm_threshold = US_TO_SAMPLES(rate,
1059 1067 dac33->mode1_latency);
1060   - /* nSample time shall not be shorter than i2c latency */
1061   - dac33->nsample_min = dac33->alarm_threshold;
1062   - /*
1063   - * nSample should not be bigger than alsa buffer minus
1064   - * size of one period to avoid overruns
1065   - */
1066   - dac33->nsample_max = substream->runtime->buffer_size -
1067   - period_size;
1068   - nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
1069   - dac33->alarm_threshold;
1070   - if (dac33->nsample_max > nsample_limit)
1071   - dac33->nsample_max = nsample_limit;
  1068 + if (dac33->auto_fifo_config) {
  1069 + if (period_size <= dac33->alarm_threshold)
  1070 + /*
  1071 + * Configure nSamaple to number of periods,
  1072 + * which covers the latency requironment.
  1073 + */
  1074 + dac33->nsample = period_size *
  1075 + ((dac33->alarm_threshold / period_size) +
  1076 + (dac33->alarm_threshold % period_size ?
  1077 + 1 : 0));
  1078 + else
  1079 + dac33->nsample = period_size;
  1080 + } else {
  1081 + /* nSample time shall not be shorter than i2c latency */
  1082 + dac33->nsample_min = dac33->alarm_threshold;
  1083 + /*
  1084 + * nSample should not be bigger than alsa buffer minus
  1085 + * size of one period to avoid overruns
  1086 + */
  1087 + dac33->nsample_max = substream->runtime->buffer_size -
  1088 + period_size;
  1089 + nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
  1090 + dac33->alarm_threshold;
  1091 + if (dac33->nsample_max > nsample_limit)
  1092 + dac33->nsample_max = nsample_limit;
1072 1093  
1073   - /* Correct the nSample if it is outside of the ranges */
1074   - if (dac33->nsample < dac33->nsample_min)
1075   - dac33->nsample = dac33->nsample_min;
1076   - if (dac33->nsample > dac33->nsample_max)
1077   - dac33->nsample = dac33->nsample_max;
  1094 + /* Correct the nSample if it is outside of the ranges */
  1095 + if (dac33->nsample < dac33->nsample_min)
  1096 + dac33->nsample = dac33->nsample_min;
  1097 + if (dac33->nsample > dac33->nsample_max)
  1098 + dac33->nsample = dac33->nsample_max;
  1099 + }
1078 1100  
1079 1101 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1080 1102 dac33->nsample);
... ... @@ -1082,6 +1104,16 @@
1082 1104 dac33->t_stamp2 = 0;
1083 1105 break;
1084 1106 case DAC33_FIFO_MODE7:
  1107 + if (dac33->auto_fifo_config) {
  1108 + dac33->uthr = UTHR_FROM_PERIOD_SIZE(
  1109 + period_size,
  1110 + rate,
  1111 + dac33->burst_rate) + 9;
  1112 + if (dac33->uthr > MODE7_UTHR)
  1113 + dac33->uthr = MODE7_UTHR;
  1114 + if (dac33->uthr < (MODE7_LTHR + 10))
  1115 + dac33->uthr = (MODE7_LTHR + 10);
  1116 + }
1085 1117 dac33->mode7_us_to_lthr =
1086 1118 SAMPLES_TO_US(substream->runtime->rate,
1087 1119 dac33->uthr - MODE7_LTHR + 1);
... ... @@ -1379,10 +1411,15 @@
1379 1411  
1380 1412 snd_soc_add_controls(codec, dac33_snd_controls,
1381 1413 ARRAY_SIZE(dac33_snd_controls));
1382   - /* Only add the nSample controls, if we have valid IRQ number */
1383   - if (dac33->irq >= 0)
1384   - snd_soc_add_controls(codec, dac33_nsample_snd_controls,
1385   - ARRAY_SIZE(dac33_nsample_snd_controls));
  1414 + /* Only add the FIFO controls, if we have valid IRQ number */
  1415 + if (dac33->irq >= 0) {
  1416 + snd_soc_add_controls(codec, dac33_mode_snd_controls,
  1417 + ARRAY_SIZE(dac33_mode_snd_controls));
  1418 + /* FIFO usage controls only, if autoio config is not selected */
  1419 + if (!dac33->auto_fifo_config)
  1420 + snd_soc_add_controls(codec, dac33_fifo_snd_controls,
  1421 + ARRAY_SIZE(dac33_fifo_snd_controls));
  1422 + }
1386 1423  
1387 1424 dac33_add_widgets(codec);
1388 1425  
... ... @@ -1513,6 +1550,7 @@
1513 1550 /* Pre calculate the burst rate */
1514 1551 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1515 1552 dac33->keep_bclk = pdata->keep_bclk;
  1553 + dac33->auto_fifo_config = pdata->auto_fifo_config;
1516 1554 dac33->mode1_latency = pdata->mode1_latency;
1517 1555 if (!dac33->mode1_latency)
1518 1556 dac33->mode1_latency = 10000; /* 10ms */