Loading sound/soc/davinci/davinci-mcasp.c +59 −23 Original line number Diff line number Diff line Loading @@ -235,6 +235,8 @@ #define DISMOD (val)(val<<2) #define TXSTATE BIT(4) #define RXSTATE BIT(5) #define SRMOD_MASK 3 #define SRMOD_INACTIVE 0 /* * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits Loading Loading @@ -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 */ fmt = (word_length >> 1) - 1; if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) { mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), RXSSZ(0x0F)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), TXSSZ(0x0F)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), TXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), RXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), TXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, 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_RXMASK_REG, mask); 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; u8 tx_ser = 0; u8 rx_ser = 0; u8 ser; u8 slots = dev->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; /* Default configuration */ mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); Loading @@ -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++) { mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(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, AXR(i)); 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, AXR(i)); 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) { Loading Loading @@ -729,6 +754,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); } } return 0; } static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) Loading Loading @@ -772,12 +799,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) /* S/PDIF */ 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 and LSB first */ mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, Loading Loading @@ -812,8 +833,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, &dev->dma_params[substream->stream]; int word_length; 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) fifo_level = dev->txnumevt; else Loading Loading @@ -862,6 +889,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, dma_params->acnt = dma_params->data_type; dma_params->fifo_level = fifo_level; dma_params->active_serializers = (channels + slots - 1) / slots; davinci_config_channel_size(dev, word_length); return 0; Loading Loading @@ -936,13 +964,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { .name = "davinci-mcasp.0", .playback = { .channels_min = 2, .channels_max = 2, .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, .capture = { .channels_min = 2, .channels_max = 2, .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, Loading Loading @@ -1019,8 +1047,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( pdata->op_mode = 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; } ret = of_property_read_u32(np, "num-serializer", &val); if (ret >= 0) Loading sound/soc/davinci/davinci-pcm.c +9 −7 Original line number Diff line number Diff line Loading @@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) unsigned short acnt; unsigned int count; unsigned int fifo_level; unsigned char serializers = prtd->params->active_serializers; period_size = snd_pcm_lib_period_bytes(substream); dma_offset = prtd->period * period_size; Loading @@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) data_type = prtd->params->data_type; count = period_size / data_type; if (fifo_level) count /= fifo_level; count /= fifo_level * serializers; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { src = dma_pos; dst = prtd->params->dma_addr; src_bidx = data_type; dst_bidx = 0; src_cidx = data_type * fifo_level; dst_bidx = 4; src_cidx = data_type * fifo_level * serializers; dst_cidx = 0; } else { src = prtd->params->dma_addr; Loading @@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) src_bidx = 0; dst_bidx = data_type; src_cidx = 0; dst_cidx = data_type * fifo_level; dst_cidx = data_type * fifo_level * serializers; } acnt = prtd->params->acnt; Loading @@ -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, ASYNC); else edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, count, fifo_level, edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level * serializers, count, fifo_level * serializers, ABSYNC); } Loading sound/soc/davinci/davinci-pcm.h +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ struct davinci_pcm_dma_params { unsigned char data_type; /* xfer data type */ unsigned char convert_mono_stereo; unsigned int fifo_level; unsigned char active_serializers; /* num. of active audio serializers */ }; int davinci_soc_platform_register(struct device *dev); Loading Loading
sound/soc/davinci/davinci-mcasp.c +59 −23 Original line number Diff line number Diff line Loading @@ -235,6 +235,8 @@ #define DISMOD (val)(val<<2) #define TXSTATE BIT(4) #define RXSTATE BIT(5) #define SRMOD_MASK 3 #define SRMOD_INACTIVE 0 /* * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits Loading Loading @@ -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 */ fmt = (word_length >> 1) - 1; if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) { mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), RXSSZ(0x0F)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), TXSSZ(0x0F)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), TXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), RXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), TXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, 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_RXMASK_REG, mask); 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; u8 tx_ser = 0; u8 rx_ser = 0; u8 ser; u8 slots = dev->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; /* Default configuration */ mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); Loading @@ -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++) { mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(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, AXR(i)); 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, AXR(i)); 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) { Loading Loading @@ -729,6 +754,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); } } return 0; } static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) Loading Loading @@ -772,12 +799,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) /* S/PDIF */ 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 and LSB first */ mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, Loading Loading @@ -812,8 +833,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, &dev->dma_params[substream->stream]; int word_length; 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) fifo_level = dev->txnumevt; else Loading Loading @@ -862,6 +889,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, dma_params->acnt = dma_params->data_type; dma_params->fifo_level = fifo_level; dma_params->active_serializers = (channels + slots - 1) / slots; davinci_config_channel_size(dev, word_length); return 0; Loading Loading @@ -936,13 +964,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { .name = "davinci-mcasp.0", .playback = { .channels_min = 2, .channels_max = 2, .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, .capture = { .channels_min = 2, .channels_max = 2, .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, Loading Loading @@ -1019,8 +1047,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( pdata->op_mode = 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; } ret = of_property_read_u32(np, "num-serializer", &val); if (ret >= 0) Loading
sound/soc/davinci/davinci-pcm.c +9 −7 Original line number Diff line number Diff line Loading @@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) unsigned short acnt; unsigned int count; unsigned int fifo_level; unsigned char serializers = prtd->params->active_serializers; period_size = snd_pcm_lib_period_bytes(substream); dma_offset = prtd->period * period_size; Loading @@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) data_type = prtd->params->data_type; count = period_size / data_type; if (fifo_level) count /= fifo_level; count /= fifo_level * serializers; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { src = dma_pos; dst = prtd->params->dma_addr; src_bidx = data_type; dst_bidx = 0; src_cidx = data_type * fifo_level; dst_bidx = 4; src_cidx = data_type * fifo_level * serializers; dst_cidx = 0; } else { src = prtd->params->dma_addr; Loading @@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) src_bidx = 0; dst_bidx = data_type; src_cidx = 0; dst_cidx = data_type * fifo_level; dst_cidx = data_type * fifo_level * serializers; } acnt = prtd->params->acnt; Loading @@ -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, ASYNC); else edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, count, fifo_level, edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level * serializers, count, fifo_level * serializers, ABSYNC); } Loading
sound/soc/davinci/davinci-pcm.h +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ struct davinci_pcm_dma_params { unsigned char data_type; /* xfer data type */ unsigned char convert_mono_stereo; unsigned int fifo_level; unsigned char active_serializers; /* num. of active audio serializers */ }; int davinci_soc_platform_register(struct device *dev); Loading