ASoC: tlv320dac33: Some cleanup for 32/24 bit support
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>
Wed, 22 Dec 2010 08:45:17 +0000 (10:45 +0200)
committerLiam Girdwood <lrg@slimlogic.co.uk>
Thu, 23 Dec 2010 14:38:33 +0000 (14:38 +0000)
Change the structure of FIFO handling in order to
pave the way for adding 32/24 bit audio support.

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>
sound/soc/codecs/tlv320dac33.c

index c574ae238973146dcd33ff3debabb84a879877ae..05a4e9fade47d014504345fce03755583985b0a1 100644 (file)
 #include <sound/tlv320dac33-plat.h>
 #include "tlv320dac33.h"
 
-#define DAC33_BUFFER_SIZE_BYTES                24576   /* bytes, 12288 16 bit words,
-                                                * 6144 stereo */
-#define DAC33_BUFFER_SIZE_SAMPLES      6144
-
-#define MODE7_LTHR             10
-#define MODE7_UTHR             (DAC33_BUFFER_SIZE_SAMPLES - 10)
+/*
+ * The internal FIFO is 24576 bytes long
+ * It can be configured to hold 16bit or 24bit samples
+ * In 16bit configuration the FIFO can hold 6144 stereo samples
+ * In 24bit configuration the FIFO can hold 4096 stereo samples
+ */
+#define DAC33_FIFO_SIZE_16BIT  6144
+#define DAC33_FIFO_SIZE_24BIT  4096
+#define DAC33_MODE7_MARGIN     10      /* Safety margin for FIFO in Mode7 */
 
 #define BURST_BASEFREQ_HZ      49152000
 
@@ -98,6 +101,7 @@ struct tlv320dac33_priv {
 
        unsigned int alarm_threshold;   /* set to be half of LATENCY_TIME_MS */
        enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
+       unsigned int fifo_size;         /* Size of the FIFO in samples */
        unsigned int nsample;           /* burst read amount from host */
        int mode1_latency;              /* latency caused by the i2c writes in
                                         * us */
@@ -650,7 +654,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
                spin_unlock_irq(&dac33->lock);
 
                dac33_write16(codec, DAC33_PREFILL_MSB,
-                               DAC33_THRREG(MODE7_LTHR));
+                               DAC33_THRREG(DAC33_MODE7_MARGIN));
 
                /* Enable Upper Threshold IRQ */
                dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
@@ -773,12 +777,15 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
        dac33->substream = NULL;
 }
 
+#define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \
+       (BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample)
 static int dac33_hw_params(struct snd_pcm_substream *substream,
                           struct snd_pcm_hw_params *params,
                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
+       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
 
        /* Check parameters for validity */
        switch (params_rate(params)) {
@@ -793,6 +800,8 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
+               dac33->fifo_size = DAC33_FIFO_SIZE_16BIT;
+               dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32);
                break;
        default:
                dev_err(codec->dev, "unsupported format %d\n",
@@ -994,7 +1003,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
                 * at the bottom, and also at the top of the FIFO
                 */
                dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
-               dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
+               dac33_write16(codec, DAC33_LTHR_MSB,
+                             DAC33_THRREG(DAC33_MODE7_MARGIN));
                break;
        default:
                break;
@@ -1023,8 +1033,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
                /* Number of samples under i2c latency */
                dac33->alarm_threshold = US_TO_SAMPLES(rate,
                                                dac33->mode1_latency);
-               nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
-                               dac33->alarm_threshold;
+               nsample_limit = dac33->fifo_size - dac33->alarm_threshold;
 
                if (period_size <= dac33->alarm_threshold)
                        /*
@@ -1048,14 +1057,14 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
        case DAC33_FIFO_MODE7:
                dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate,
                                                    dac33->burst_rate) + 9;
-               if (dac33->uthr > MODE7_UTHR)
-                       dac33->uthr = MODE7_UTHR;
-               if (dac33->uthr < (MODE7_LTHR + 10))
-                       dac33->uthr = (MODE7_LTHR + 10);
+               if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN))
+                       dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN;
+               if (dac33->uthr < (DAC33_MODE7_MARGIN + 10))
+                       dac33->uthr = (DAC33_MODE7_MARGIN + 10);
 
                dac33->mode7_us_to_lthr =
                                SAMPLES_TO_US(substream->runtime->rate,
-                                       dac33->uthr - MODE7_LTHR + 1);
+                                       dac33->uthr - DAC33_MODE7_MARGIN + 1);
                dac33->t_stamp1 = 0;
                break;
        default:
@@ -1173,8 +1182,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
                        samples += (samples_in - samples_out);
 
                        if (likely(samples > 0))
-                               delay = samples > DAC33_BUFFER_SIZE_SAMPLES ?
-                                       DAC33_BUFFER_SIZE_SAMPLES : samples;
+                               delay = samples > dac33->fifo_size ?
+                                       dac33->fifo_size : samples;
                        else
                                delay = 0;
                }
@@ -1226,7 +1235,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
                        samples_in = US_TO_SAMPLES(
                                        dac33->burst_rate,
                                        time_delta);
-                       delay = MODE7_LTHR + samples_in - samples_out;
+                       delay = DAC33_MODE7_MARGIN + samples_in - samples_out;
 
                        if (unlikely(delay > uthr))
                                delay = uthr;
@@ -1477,8 +1486,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
 
        dac33->power_gpio = pdata->power_gpio;
        dac33->burst_bclkdiv = pdata->burst_bclkdiv;
-       /* Pre calculate the burst rate */
-       dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
        dac33->keep_bclk = pdata->keep_bclk;
        dac33->mode1_latency = pdata->mode1_latency;
        if (!dac33->mode1_latency)