Commit 549675ed authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Liam Girdwood

ASoC: tlv320dac33: Some cleanup for 32/24 bit support

Change the structure of FIFO handling in order to
pave the way for adding 32/24 bit audio support.
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@nokia.com>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent 3591f4cd
...@@ -42,12 +42,15 @@ ...@@ -42,12 +42,15 @@
#include <sound/tlv320dac33-plat.h> #include <sound/tlv320dac33-plat.h>
#include "tlv320dac33.h" #include "tlv320dac33.h"
#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words, /*
* 6144 stereo */ * The internal FIFO is 24576 bytes long
#define DAC33_BUFFER_SIZE_SAMPLES 6144 * It can be configured to hold 16bit or 24bit samples
* In 16bit configuration the FIFO can hold 6144 stereo samples
#define MODE7_LTHR 10 * In 24bit configuration the FIFO can hold 4096 stereo samples
#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) */
#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 #define BURST_BASEFREQ_HZ 49152000
...@@ -98,6 +101,7 @@ struct tlv320dac33_priv { ...@@ -98,6 +101,7 @@ struct tlv320dac33_priv {
unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */ unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 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 */ unsigned int nsample; /* burst read amount from host */
int mode1_latency; /* latency caused by the i2c writes in int mode1_latency; /* latency caused by the i2c writes in
* us */ * us */
...@@ -650,7 +654,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) ...@@ -650,7 +654,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
spin_unlock_irq(&dac33->lock); spin_unlock_irq(&dac33->lock);
dac33_write16(codec, DAC33_PREFILL_MSB, dac33_write16(codec, DAC33_PREFILL_MSB,
DAC33_THRREG(MODE7_LTHR)); DAC33_THRREG(DAC33_MODE7_MARGIN));
/* Enable Upper Threshold IRQ */ /* Enable Upper Threshold IRQ */
dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT); dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
...@@ -773,12 +777,15 @@ static void dac33_shutdown(struct snd_pcm_substream *substream, ...@@ -773,12 +777,15 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
dac33->substream = NULL; 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, static int dac33_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
/* Check parameters for validity */ /* Check parameters for validity */
switch (params_rate(params)) { switch (params_rate(params)) {
...@@ -793,6 +800,8 @@ static int dac33_hw_params(struct snd_pcm_substream *substream, ...@@ -793,6 +800,8 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
dac33->fifo_size = DAC33_FIFO_SIZE_16BIT;
dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32);
break; break;
default: default:
dev_err(codec->dev, "unsupported format %d\n", dev_err(codec->dev, "unsupported format %d\n",
...@@ -994,7 +1003,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) ...@@ -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 * 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_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; break;
default: default:
break; break;
...@@ -1023,8 +1033,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) ...@@ -1023,8 +1033,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
/* Number of samples under i2c latency */ /* Number of samples under i2c latency */
dac33->alarm_threshold = US_TO_SAMPLES(rate, dac33->alarm_threshold = US_TO_SAMPLES(rate,
dac33->mode1_latency); dac33->mode1_latency);
nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - nsample_limit = dac33->fifo_size - dac33->alarm_threshold;
dac33->alarm_threshold;
if (period_size <= dac33->alarm_threshold) if (period_size <= dac33->alarm_threshold)
/* /*
...@@ -1048,14 +1057,14 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) ...@@ -1048,14 +1057,14 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
case DAC33_FIFO_MODE7: case DAC33_FIFO_MODE7:
dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate, dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate,
dac33->burst_rate) + 9; dac33->burst_rate) + 9;
if (dac33->uthr > MODE7_UTHR) if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN))
dac33->uthr = MODE7_UTHR; dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN;
if (dac33->uthr < (MODE7_LTHR + 10)) if (dac33->uthr < (DAC33_MODE7_MARGIN + 10))
dac33->uthr = (MODE7_LTHR + 10); dac33->uthr = (DAC33_MODE7_MARGIN + 10);
dac33->mode7_us_to_lthr = dac33->mode7_us_to_lthr =
SAMPLES_TO_US(substream->runtime->rate, SAMPLES_TO_US(substream->runtime->rate,
dac33->uthr - MODE7_LTHR + 1); dac33->uthr - DAC33_MODE7_MARGIN + 1);
dac33->t_stamp1 = 0; dac33->t_stamp1 = 0;
break; break;
default: default:
...@@ -1173,8 +1182,8 @@ static snd_pcm_sframes_t dac33_dai_delay( ...@@ -1173,8 +1182,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
samples += (samples_in - samples_out); samples += (samples_in - samples_out);
if (likely(samples > 0)) if (likely(samples > 0))
delay = samples > DAC33_BUFFER_SIZE_SAMPLES ? delay = samples > dac33->fifo_size ?
DAC33_BUFFER_SIZE_SAMPLES : samples; dac33->fifo_size : samples;
else else
delay = 0; delay = 0;
} }
...@@ -1226,7 +1235,7 @@ static snd_pcm_sframes_t dac33_dai_delay( ...@@ -1226,7 +1235,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
samples_in = US_TO_SAMPLES( samples_in = US_TO_SAMPLES(
dac33->burst_rate, dac33->burst_rate,
time_delta); time_delta);
delay = MODE7_LTHR + samples_in - samples_out; delay = DAC33_MODE7_MARGIN + samples_in - samples_out;
if (unlikely(delay > uthr)) if (unlikely(delay > uthr))
delay = uthr; delay = uthr;
...@@ -1477,8 +1486,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, ...@@ -1477,8 +1486,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
dac33->power_gpio = pdata->power_gpio; dac33->power_gpio = pdata->power_gpio;
dac33->burst_bclkdiv = pdata->burst_bclkdiv; 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->keep_bclk = pdata->keep_bclk;
dac33->mode1_latency = pdata->mode1_latency; dac33->mode1_latency = pdata->mode1_latency;
if (!dac33->mode1_latency) if (!dac33->mode1_latency)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment