Pārlūkot izejas kodu

ASoC: tlv320dac33: Revisit the FIFO Mode1 handling

Replace the hardwired latency definition with platform data
parameter, and simplify the nSample parameter calculation.

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>
Peter Ujfalusi 15 gadi atpakaļ
vecāks
revīzija
f430a27f05
2 mainītis faili ar 35 papildinājumiem un 37 dzēšanām
  1. 1 0
      include/sound/tlv320dac33-plat.h
  2. 34 37
      sound/soc/codecs/tlv320dac33.c

+ 1 - 0
include/sound/tlv320dac33-plat.h

@@ -15,6 +15,7 @@
 
 
 struct tlv320dac33_platform_data {
 struct tlv320dac33_platform_data {
 	int power_gpio;
 	int power_gpio;
+	int mode1_latency; /* latency caused by the i2c writes in us */
 	int keep_bclk;	/* Keep the BCLK running in FIFO modes */
 	int keep_bclk;	/* Keep the BCLK running in FIFO modes */
 	u8 burst_bclkdiv;
 	u8 burst_bclkdiv;
 };
 };

+ 34 - 37
sound/soc/codecs/tlv320dac33.c

@@ -49,8 +49,6 @@
 
 
 #define NSAMPLE_MAX		5700
 #define NSAMPLE_MAX		5700
 
 
-#define LATENCY_TIME_MS		20
-
 #define MODE7_LTHR		10
 #define MODE7_LTHR		10
 #define MODE7_UTHR		(DAC33_BUFFER_SIZE_SAMPLES - 10)
 #define MODE7_UTHR		(DAC33_BUFFER_SIZE_SAMPLES - 10)
 
 
@@ -107,6 +105,8 @@ struct tlv320dac33_priv {
 					 * this */
 					 * this */
 	enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
 	enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
 	unsigned int nsample;		/* burst read amount from host */
 	unsigned int nsample;		/* burst read amount from host */
+	int mode1_latency;		/* latency caused by the i2c writes in
+					 * us */
 	u8 burst_bclkdiv;		/* BCLK divider value in burst mode */
 	u8 burst_bclkdiv;		/* BCLK divider value in burst mode */
 	unsigned int burst_rate;	/* Interface speed in Burst modes */
 	unsigned int burst_rate;	/* Interface speed in Burst modes */
 
 
@@ -649,7 +649,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 	switch (dac33->fifo_mode) {
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
 	case DAC33_FIFO_MODE1:
 		dac33_write16(codec, DAC33_NSAMPLE_MSB,
 		dac33_write16(codec, DAC33_NSAMPLE_MSB,
-			DAC33_THRREG(dac33->nsample + dac33->alarm_threshold));
+			DAC33_THRREG(dac33->nsample));
 
 
 		/* Take the timestamps */
 		/* Take the timestamps */
 		spin_lock_irq(&dac33->lock);
 		spin_lock_irq(&dac33->lock);
@@ -798,6 +798,10 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
 
 
 	dac33->substream = NULL;
 	dac33->substream = NULL;
+
+	/* Reset the nSample restrictions */
+	dac33->nsample_min = 0;
+	dac33->nsample_max = NSAMPLE_MAX;
 }
 }
 
 
 static int dac33_hw_params(struct snd_pcm_substream *substream,
 static int dac33_hw_params(struct snd_pcm_substream *substream,
@@ -1040,48 +1044,38 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
 	struct snd_soc_device *socdev = rtd->socdev;
 	struct snd_soc_device *socdev = rtd->socdev;
 	struct snd_soc_codec *codec = socdev->card->codec;
 	struct snd_soc_codec *codec = socdev->card->codec;
 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	unsigned int period_size = substream->runtime->period_size;
+	unsigned int rate = substream->runtime->rate;
 	unsigned int nsample_limit;
 	unsigned int nsample_limit;
 
 
 	/* In bypass mode we don't need to calculate */
 	/* In bypass mode we don't need to calculate */
 	if (!dac33->fifo_mode)
 	if (!dac33->fifo_mode)
 		return;
 		return;
 
 
-	/* Number of samples (16bit, stereo) in one period */
-	dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
-
-	/* Number of samples (16bit, stereo) in ALSA buffer */
-	dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
-	/* Subtract one period from the total */
-	dac33->nsample_max -= dac33->nsample_min;
-
-	/* Number of samples for LATENCY_TIME_MS / 2 */
-	dac33->alarm_threshold = substream->runtime->rate /
-				 (1000 / (LATENCY_TIME_MS / 2));
-
-	/* Find and fix up the lowest nsmaple limit */
-	nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
-
-	if (dac33->nsample_min < nsample_limit)
-		dac33->nsample_min = nsample_limit;
-
-	if (dac33->nsample < dac33->nsample_min)
-		dac33->nsample = dac33->nsample_min;
-
-	/*
-	 * Find and fix up the highest nsmaple limit
-	 * In order to not overflow the DAC33 buffer substract the
-	 * alarm_threshold value from the size of the DAC33 buffer
-	 */
-	nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
-
-	if (dac33->nsample_max > nsample_limit)
-		dac33->nsample_max = nsample_limit;
-
-	if (dac33->nsample > dac33->nsample_max)
-		dac33->nsample = dac33->nsample_max;
-
 	switch (dac33->fifo_mode) {
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
 	case DAC33_FIFO_MODE1:
+		/* Number of samples under i2c latency */
+		dac33->alarm_threshold = US_TO_SAMPLES(rate,
+						dac33->mode1_latency);
+		/* nSample time shall not be shorter than i2c latency */
+		dac33->nsample_min = dac33->alarm_threshold;
+		/*
+		 * nSample should not be bigger than alsa buffer minus
+		 * size of one period to avoid overruns
+		 */
+		dac33->nsample_max = substream->runtime->buffer_size -
+					period_size;
+		nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
+				dac33->alarm_threshold;
+		if (dac33->nsample_max > nsample_limit)
+			dac33->nsample_max = nsample_limit;
+
+		/* Correct the nSample if it is outside of the ranges */
+		if (dac33->nsample < dac33->nsample_min)
+			dac33->nsample = dac33->nsample_min;
+		if (dac33->nsample > dac33->nsample_max)
+			dac33->nsample = dac33->nsample_max;
+
 		dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
 		dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
 						      dac33->nsample);
 						      dac33->nsample);
 		dac33->t_stamp1 = 0;
 		dac33->t_stamp1 = 0;
@@ -1519,6 +1513,9 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
 	/* Pre calculate the burst rate */
 	/* Pre calculate the burst rate */
 	dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
 	dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
 	dac33->keep_bclk = pdata->keep_bclk;
 	dac33->keep_bclk = pdata->keep_bclk;
+	dac33->mode1_latency = pdata->mode1_latency;
+	if (!dac33->mode1_latency)
+		dac33->mode1_latency = 10000; /* 10ms */
 	dac33->irq = client->irq;
 	dac33->irq = client->irq;
 	dac33->nsample = NSAMPLE_MAX;
 	dac33->nsample = NSAMPLE_MAX;
 	dac33->nsample_max = NSAMPLE_MAX;
 	dac33->nsample_max = NSAMPLE_MAX;