aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2010-06-07 03:50:39 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-06-07 05:43:35 -0400
commit9d7db2b2cb507f31ff29e339e9ed2f825edb555d (patch)
treeecbb45951d65b823d869fa82342763dd43b4a959
parentddc29b0104d69e3742e6a9f23184fb6184614403 (diff)
ASoC: tlv320dac33: Add support for changing upper threshold
Upper threshold is used in mode7 of DAC33. Instead of hard wired UTHR, add control to change the upper threshold value. Changing upper threshold is not allowed when the playback is already running, since wrongly timed change in the UTHR can cause problems with the codec. With this control the length of the burst in mode7 can be changed. 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>
-rw-r--r--sound/soc/codecs/tlv320dac33.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 65adc77eada1..2fa946ce23a2 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -120,6 +120,8 @@ struct tlv320dac33_priv {
120 * samples */ 120 * samples */
121 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */ 121 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */
122 122
123 unsigned int uthr;
124
123 enum dac33_state state; 125 enum dac33_state state;
124}; 126};
125 127
@@ -442,6 +444,39 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
442 return ret; 444 return ret;
443} 445}
444 446
447static int dac33_get_uthr(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
449{
450 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
452
453 ucontrol->value.integer.value[0] = dac33->uthr;
454
455 return 0;
456}
457
458static int dac33_set_uthr(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
460{
461 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
463 int ret = 0;
464
465 if (dac33->substream)
466 return -EBUSY;
467
468 if (dac33->uthr == ucontrol->value.integer.value[0])
469 return 0;
470
471 if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) ||
472 ucontrol->value.integer.value[0] > MODE7_UTHR)
473 ret = -EINVAL;
474 else
475 dac33->uthr = ucontrol->value.integer.value[0];
476
477 return ret;
478}
479
445static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, 480static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol) 481 struct snd_ctl_elem_value *ucontrol)
447{ 482{
@@ -506,6 +541,8 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
506static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 541static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
507 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, 542 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
508 dac33_get_nsample, dac33_set_nsample), 543 dac33_get_nsample, dac33_set_nsample),
544 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
545 dac33_get_uthr, dac33_set_uthr),
509 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum, 546 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
510 dac33_get_fifo_mode, dac33_set_fifo_mode), 547 dac33_get_fifo_mode, dac33_set_fifo_mode),
511}; 548};
@@ -985,7 +1022,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
985 * Configure the threshold levels, and leave 10 sample space 1022 * Configure the threshold levels, and leave 10 sample space
986 * at the bottom, and also at the top of the FIFO 1023 * at the bottom, and also at the top of the FIFO
987 */ 1024 */
988 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR)); 1025 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
989 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); 1026 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
990 break; 1027 break;
991 default: 1028 default:
@@ -1052,8 +1089,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1052 break; 1089 break;
1053 case DAC33_FIFO_MODE7: 1090 case DAC33_FIFO_MODE7:
1054 dac33->mode7_us_to_lthr = 1091 dac33->mode7_us_to_lthr =
1055 SAMPLES_TO_US(substream->runtime->rate, 1092 SAMPLES_TO_US(substream->runtime->rate,
1056 MODE7_UTHR - MODE7_LTHR + 1); 1093 dac33->uthr - MODE7_LTHR + 1);
1057 dac33->t_stamp1 = 0; 1094 dac33->t_stamp1 = 0;
1058 break; 1095 break;
1059 default: 1096 default:
@@ -1104,7 +1141,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1104 struct snd_soc_codec *codec = socdev->card->codec; 1141 struct snd_soc_codec *codec = socdev->card->codec;
1105 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1142 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1106 unsigned long long t0, t1, t_now; 1143 unsigned long long t0, t1, t_now;
1107 unsigned int time_delta; 1144 unsigned int time_delta, uthr;
1108 int samples_out, samples_in, samples; 1145 int samples_out, samples_in, samples;
1109 snd_pcm_sframes_t delay = 0; 1146 snd_pcm_sframes_t delay = 0;
1110 1147
@@ -1182,6 +1219,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1182 case DAC33_FIFO_MODE7: 1219 case DAC33_FIFO_MODE7:
1183 spin_lock(&dac33->lock); 1220 spin_lock(&dac33->lock);
1184 t0 = dac33->t_stamp1; 1221 t0 = dac33->t_stamp1;
1222 uthr = dac33->uthr;
1185 spin_unlock(&dac33->lock); 1223 spin_unlock(&dac33->lock);
1186 t_now = ktime_to_us(ktime_get()); 1224 t_now = ktime_to_us(ktime_get());
1187 1225
@@ -1194,7 +1232,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1194 * Either the timestamps are messed or equal. Report 1232 * Either the timestamps are messed or equal. Report
1195 * maximum delay 1233 * maximum delay
1196 */ 1234 */
1197 delay = MODE7_UTHR; 1235 delay = uthr;
1198 goto out; 1236 goto out;
1199 } 1237 }
1200 1238
@@ -1208,8 +1246,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1208 substream->runtime->rate, 1246 substream->runtime->rate,
1209 time_delta); 1247 time_delta);
1210 1248
1211 if (likely(MODE7_UTHR > samples_out)) 1249 if (likely(uthr > samples_out))
1212 delay = MODE7_UTHR - samples_out; 1250 delay = uthr - samples_out;
1213 else 1251 else
1214 delay = 0; 1252 delay = 0;
1215 } else { 1253 } else {
@@ -1227,8 +1265,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1227 time_delta); 1265 time_delta);
1228 delay = MODE7_LTHR + samples_in - samples_out; 1266 delay = MODE7_LTHR + samples_in - samples_out;
1229 1267
1230 if (unlikely(delay > MODE7_UTHR)) 1268 if (unlikely(delay > uthr))
1231 delay = MODE7_UTHR; 1269 delay = uthr;
1232 } 1270 }
1233 break; 1271 break;
1234 default: 1272 default:
@@ -1484,6 +1522,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1484 dac33->irq = client->irq; 1522 dac33->irq = client->irq;
1485 dac33->nsample = NSAMPLE_MAX; 1523 dac33->nsample = NSAMPLE_MAX;
1486 dac33->nsample_max = NSAMPLE_MAX; 1524 dac33->nsample_max = NSAMPLE_MAX;
1525 dac33->uthr = MODE7_UTHR;
1487 /* Disable FIFO use by default */ 1526 /* Disable FIFO use by default */
1488 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1527 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1489 1528