Commit d66e065c authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next

parents 7b451962 f5023af6
...@@ -235,6 +235,8 @@ ...@@ -235,6 +235,8 @@
#define DISMOD (val)(val<<2) #define DISMOD (val)(val<<2)
#define TXSTATE BIT(4) #define TXSTATE BIT(4)
#define RXSTATE BIT(5) #define RXSTATE BIT(5)
#define SRMOD_MASK 3
#define SRMOD_INACTIVE 0
/* /*
* DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
...@@ -643,26 +645,33 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, ...@@ -643,26 +645,33 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
/* mapping of the XSSZ bit-field as described in the datasheet */ /* mapping of the XSSZ bit-field as described in the datasheet */
fmt = (word_length >> 1) - 1; fmt = (word_length >> 1) - 1;
if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) {
mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
RXSSZ(fmt), RXSSZ(0x0F)); RXSSZ(fmt), RXSSZ(0x0F));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
TXSSZ(fmt), TXSSZ(0x0F)); TXSSZ(fmt), TXSSZ(0x0F));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
TXROT(7)); TXROT(rotate), TXROT(7));
mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
RXROT(7)); RXROT(rotate), RXROT(7));
mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG,
mask);
}
mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask);
mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask);
return 0; return 0;
} }
static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream,
int channels)
{ {
int i; int i;
u8 tx_ser = 0; u8 tx_ser = 0;
u8 rx_ser = 0; u8 rx_ser = 0;
u8 ser;
u8 slots = dev->tdm_slots;
u8 max_active_serializers = (channels + slots - 1) / slots;
/* Default configuration */ /* Default configuration */
mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
...@@ -682,15 +691,31 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) ...@@ -682,15 +691,31 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
for (i = 0; i < dev->num_serializer; i++) { for (i = 0; i < dev->num_serializer; i++) {
mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
dev->serial_dir[i]); dev->serial_dir[i]);
if (dev->serial_dir[i] == TX_MODE) { if (dev->serial_dir[i] == TX_MODE &&
tx_ser < max_active_serializers) {
mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
AXR(i)); AXR(i));
tx_ser++; tx_ser++;
} else if (dev->serial_dir[i] == RX_MODE) { } else if (dev->serial_dir[i] == RX_MODE &&
rx_ser < max_active_serializers) {
mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
AXR(i)); AXR(i));
rx_ser++; rx_ser++;
} else {
mcasp_mod_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
SRMOD_INACTIVE, SRMOD_MASK);
}
} }
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
ser = tx_ser;
else
ser = rx_ser;
if (ser < max_active_serializers) {
dev_warn(dev->dev, "stream has more channels (%d) than are "
"enabled in mcasp (%d)\n", channels, ser * slots);
return -EINVAL;
} }
if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
...@@ -729,6 +754,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) ...@@ -729,6 +754,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
} }
} }
return 0;
} }
static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
...@@ -772,12 +799,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) ...@@ -772,12 +799,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
/* S/PDIF */ /* S/PDIF */
static void davinci_hw_dit_param(struct davinci_audio_dev *dev) static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
{ {
/* Set the PDIR for Serialiser as output */
mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
/* TXMASK for 24 bits */
mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
and LSB first */ and LSB first */
mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
...@@ -812,8 +833,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -812,8 +833,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
&dev->dma_params[substream->stream]; &dev->dma_params[substream->stream];
int word_length; int word_length;
u8 fifo_level; u8 fifo_level;
u8 slots = dev->tdm_slots;
int channels;
struct snd_interval *pcm_channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
channels = pcm_channels->min;
davinci_hw_common_param(dev, substream->stream); if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL)
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
fifo_level = dev->txnumevt; fifo_level = dev->txnumevt;
else else
...@@ -862,6 +889,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -862,6 +889,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
dma_params->acnt = dma_params->data_type; dma_params->acnt = dma_params->data_type;
dma_params->fifo_level = fifo_level; dma_params->fifo_level = fifo_level;
dma_params->active_serializers = (channels + slots - 1) / slots;
davinci_config_channel_size(dev, word_length); davinci_config_channel_size(dev, word_length);
return 0; return 0;
...@@ -936,13 +964,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { ...@@ -936,13 +964,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
.name = "davinci-mcasp.0", .name = "davinci-mcasp.0",
.playback = { .playback = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 32 * 16,
.rates = DAVINCI_MCASP_RATES, .rates = DAVINCI_MCASP_RATES,
.formats = DAVINCI_MCASP_PCM_FMTS, .formats = DAVINCI_MCASP_PCM_FMTS,
}, },
.capture = { .capture = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 32 * 16,
.rates = DAVINCI_MCASP_RATES, .rates = DAVINCI_MCASP_RATES,
.formats = DAVINCI_MCASP_PCM_FMTS, .formats = DAVINCI_MCASP_PCM_FMTS,
}, },
...@@ -1019,8 +1047,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( ...@@ -1019,8 +1047,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
pdata->op_mode = val; pdata->op_mode = val;
ret = of_property_read_u32(np, "tdm-slots", &val); ret = of_property_read_u32(np, "tdm-slots", &val);
if (ret >= 0) if (ret >= 0) {
if (val < 2 || val > 32) {
dev_err(&pdev->dev,
"tdm-slots must be in rage [2-32]\n");
ret = -EINVAL;
goto nodata;
}
pdata->tdm_slots = val; pdata->tdm_slots = val;
}
ret = of_property_read_u32(np, "num-serializer", &val); ret = of_property_read_u32(np, "num-serializer", &val);
if (ret >= 0) if (ret >= 0)
......
...@@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) ...@@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
unsigned short acnt; unsigned short acnt;
unsigned int count; unsigned int count;
unsigned int fifo_level; unsigned int fifo_level;
unsigned char serializers = prtd->params->active_serializers;
period_size = snd_pcm_lib_period_bytes(substream); period_size = snd_pcm_lib_period_bytes(substream);
dma_offset = prtd->period * period_size; dma_offset = prtd->period * period_size;
...@@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) ...@@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
data_type = prtd->params->data_type; data_type = prtd->params->data_type;
count = period_size / data_type; count = period_size / data_type;
if (fifo_level) if (fifo_level)
count /= fifo_level; count /= fifo_level * serializers;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
src = dma_pos; src = dma_pos;
dst = prtd->params->dma_addr; dst = prtd->params->dma_addr;
src_bidx = data_type; src_bidx = data_type;
dst_bidx = 0; dst_bidx = 4;
src_cidx = data_type * fifo_level; src_cidx = data_type * fifo_level * serializers;
dst_cidx = 0; dst_cidx = 0;
} else { } else {
src = prtd->params->dma_addr; src = prtd->params->dma_addr;
...@@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) ...@@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
src_bidx = 0; src_bidx = 0;
dst_bidx = data_type; dst_bidx = data_type;
src_cidx = 0; src_cidx = 0;
dst_cidx = data_type * fifo_level; dst_cidx = data_type * fifo_level * serializers;
} }
acnt = prtd->params->acnt; acnt = prtd->params->acnt;
...@@ -223,8 +224,9 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) ...@@ -223,8 +224,9 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
ASYNC); ASYNC);
else else
edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, edma_set_transfer_params(prtd->asp_link[0], acnt,
count, fifo_level, fifo_level * serializers,
count, fifo_level * serializers,
ABSYNC); ABSYNC);
} }
......
...@@ -27,6 +27,7 @@ struct davinci_pcm_dma_params { ...@@ -27,6 +27,7 @@ struct davinci_pcm_dma_params {
unsigned char data_type; /* xfer data type */ unsigned char data_type; /* xfer data type */
unsigned char convert_mono_stereo; unsigned char convert_mono_stereo;
unsigned int fifo_level; unsigned int fifo_level;
unsigned char active_serializers; /* num. of active audio serializers */
}; };
int davinci_soc_platform_register(struct device *dev); int davinci_soc_platform_register(struct device *dev);
......
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