Commit a577b318fc7cb0c46f9f0cdefb5b267490ff8ce5
Committed by
Liam Girdwood
1 parent
f430a27f05
Exists in
master
and in
4 other branches
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 */ |