aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-12 08:57:03 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-12 08:57:03 -0400
commitd66e065c5b8b64b03a9d9b8a7c5d674c7dfa2e3d (patch)
tree677fc1ab3f2266144e952fecc813011c43ba8302
parent7b451962c71266fa3fef4f33a49f0c35195f712a (diff)
parentf5023af65a9bdd586b33b56e83f1eb3529292991 (diff)
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
-rw-r--r--sound/soc/davinci/davinci-mcasp.c82
-rw-r--r--sound/soc/davinci/davinci-pcm.c16
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
3 files changed, 69 insertions, 30 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index c2e67f1f194c..aeb3a6627d6a 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -235,6 +235,8 @@
235#define DISMOD (val)(val<<2) 235#define DISMOD (val)(val<<2)
236#define TXSTATE BIT(4) 236#define TXSTATE BIT(4)
237#define RXSTATE BIT(5) 237#define RXSTATE BIT(5)
238#define SRMOD_MASK 3
239#define SRMOD_INACTIVE 0
238 240
239/* 241/*
240 * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits 242 * 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 /* mapping of the XSSZ bit-field as described in the datasheet */ 645 /* mapping of the XSSZ bit-field as described in the datasheet */
644 fmt = (word_length >> 1) - 1; 646 fmt = (word_length >> 1) - 1;
645 647
646 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, 648 if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) {
647 RXSSZ(fmt), RXSSZ(0x0F)); 649 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
648 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, 650 RXSSZ(fmt), RXSSZ(0x0F));
649 TXSSZ(fmt), TXSSZ(0x0F)); 651 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
650 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), 652 TXSSZ(fmt), TXSSZ(0x0F));
651 TXROT(7)); 653 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
652 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), 654 TXROT(rotate), TXROT(7));
653 RXROT(7)); 655 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
656 RXROT(rotate), RXROT(7));
657 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG,
658 mask);
659 }
660
654 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); 661 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask);
655 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask);
656 662
657 return 0; 663 return 0;
658} 664}
659 665
660static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) 666static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream,
667 int channels)
661{ 668{
662 int i; 669 int i;
663 u8 tx_ser = 0; 670 u8 tx_ser = 0;
664 u8 rx_ser = 0; 671 u8 rx_ser = 0;
665 672 u8 ser;
673 u8 slots = dev->tdm_slots;
674 u8 max_active_serializers = (channels + slots - 1) / slots;
666 /* Default configuration */ 675 /* Default configuration */
667 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); 676 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
668 677
@@ -682,17 +691,33 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
682 for (i = 0; i < dev->num_serializer; i++) { 691 for (i = 0; i < dev->num_serializer; i++) {
683 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), 692 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
684 dev->serial_dir[i]); 693 dev->serial_dir[i]);
685 if (dev->serial_dir[i] == TX_MODE) { 694 if (dev->serial_dir[i] == TX_MODE &&
695 tx_ser < max_active_serializers) {
686 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, 696 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
687 AXR(i)); 697 AXR(i));
688 tx_ser++; 698 tx_ser++;
689 } else if (dev->serial_dir[i] == RX_MODE) { 699 } else if (dev->serial_dir[i] == RX_MODE &&
700 rx_ser < max_active_serializers) {
690 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, 701 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
691 AXR(i)); 702 AXR(i));
692 rx_ser++; 703 rx_ser++;
704 } else {
705 mcasp_mod_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
706 SRMOD_INACTIVE, SRMOD_MASK);
693 } 707 }
694 } 708 }
695 709
710 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
711 ser = tx_ser;
712 else
713 ser = rx_ser;
714
715 if (ser < max_active_serializers) {
716 dev_warn(dev->dev, "stream has more channels (%d) than are "
717 "enabled in mcasp (%d)\n", channels, ser * slots);
718 return -EINVAL;
719 }
720
696 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { 721 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
697 if (dev->txnumevt * tx_ser > 64) 722 if (dev->txnumevt * tx_ser > 64)
698 dev->txnumevt = 1; 723 dev->txnumevt = 1;
@@ -729,6 +754,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
729 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); 754 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
730 } 755 }
731 } 756 }
757
758 return 0;
732} 759}
733 760
734static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) 761static 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/* S/PDIF */ 799/* S/PDIF */
773static void davinci_hw_dit_param(struct davinci_audio_dev *dev) 800static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
774{ 801{
775 /* Set the PDIR for Serialiser as output */
776 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
777
778 /* TXMASK for 24 bits */
779 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
780
781 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 802 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
782 and LSB first */ 803 and LSB first */
783 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, 804 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 &dev->dma_params[substream->stream]; 833 &dev->dma_params[substream->stream];
813 int word_length; 834 int word_length;
814 u8 fifo_level; 835 u8 fifo_level;
836 u8 slots = dev->tdm_slots;
837 int channels;
838 struct snd_interval *pcm_channels = hw_param_interval(params,
839 SNDRV_PCM_HW_PARAM_CHANNELS);
840 channels = pcm_channels->min;
815 841
816 davinci_hw_common_param(dev, substream->stream); 842 if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL)
843 return -EINVAL;
817 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 844 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
818 fifo_level = dev->txnumevt; 845 fifo_level = dev->txnumevt;
819 else 846 else
@@ -862,6 +889,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
862 dma_params->acnt = dma_params->data_type; 889 dma_params->acnt = dma_params->data_type;
863 890
864 dma_params->fifo_level = fifo_level; 891 dma_params->fifo_level = fifo_level;
892 dma_params->active_serializers = (channels + slots - 1) / slots;
865 davinci_config_channel_size(dev, word_length); 893 davinci_config_channel_size(dev, word_length);
866 894
867 return 0; 895 return 0;
@@ -936,13 +964,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
936 .name = "davinci-mcasp.0", 964 .name = "davinci-mcasp.0",
937 .playback = { 965 .playback = {
938 .channels_min = 2, 966 .channels_min = 2,
939 .channels_max = 2, 967 .channels_max = 32 * 16,
940 .rates = DAVINCI_MCASP_RATES, 968 .rates = DAVINCI_MCASP_RATES,
941 .formats = DAVINCI_MCASP_PCM_FMTS, 969 .formats = DAVINCI_MCASP_PCM_FMTS,
942 }, 970 },
943 .capture = { 971 .capture = {
944 .channels_min = 2, 972 .channels_min = 2,
945 .channels_max = 2, 973 .channels_max = 32 * 16,
946 .rates = DAVINCI_MCASP_RATES, 974 .rates = DAVINCI_MCASP_RATES,
947 .formats = DAVINCI_MCASP_PCM_FMTS, 975 .formats = DAVINCI_MCASP_PCM_FMTS,
948 }, 976 },
@@ -1019,8 +1047,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
1019 pdata->op_mode = val; 1047 pdata->op_mode = val;
1020 1048
1021 ret = of_property_read_u32(np, "tdm-slots", &val); 1049 ret = of_property_read_u32(np, "tdm-slots", &val);
1022 if (ret >= 0) 1050 if (ret >= 0) {
1051 if (val < 2 || val > 32) {
1052 dev_err(&pdev->dev,
1053 "tdm-slots must be in rage [2-32]\n");
1054 ret = -EINVAL;
1055 goto nodata;
1056 }
1057
1023 pdata->tdm_slots = val; 1058 pdata->tdm_slots = val;
1059 }
1024 1060
1025 ret = of_property_read_u32(np, "num-serializer", &val); 1061 ret = of_property_read_u32(np, "num-serializer", &val);
1026 if (ret >= 0) 1062 if (ret >= 0)
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index afab81f844ae..078031d61167 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
181 unsigned short acnt; 181 unsigned short acnt;
182 unsigned int count; 182 unsigned int count;
183 unsigned int fifo_level; 183 unsigned int fifo_level;
184 unsigned char serializers = prtd->params->active_serializers;
184 185
185 period_size = snd_pcm_lib_period_bytes(substream); 186 period_size = snd_pcm_lib_period_bytes(substream);
186 dma_offset = prtd->period * period_size; 187 dma_offset = prtd->period * period_size;
@@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
194 data_type = prtd->params->data_type; 195 data_type = prtd->params->data_type;
195 count = period_size / data_type; 196 count = period_size / data_type;
196 if (fifo_level) 197 if (fifo_level)
197 count /= fifo_level; 198 count /= fifo_level * serializers;
198 199
199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
200 src = dma_pos; 201 src = dma_pos;
201 dst = prtd->params->dma_addr; 202 dst = prtd->params->dma_addr;
202 src_bidx = data_type; 203 src_bidx = data_type;
203 dst_bidx = 0; 204 dst_bidx = 4;
204 src_cidx = data_type * fifo_level; 205 src_cidx = data_type * fifo_level * serializers;
205 dst_cidx = 0; 206 dst_cidx = 0;
206 } else { 207 } else {
207 src = prtd->params->dma_addr; 208 src = prtd->params->dma_addr;
@@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
209 src_bidx = 0; 210 src_bidx = 0;
210 dst_bidx = data_type; 211 dst_bidx = data_type;
211 src_cidx = 0; 212 src_cidx = 0;
212 dst_cidx = data_type * fifo_level; 213 dst_cidx = data_type * fifo_level * serializers;
213 } 214 }
214 215
215 acnt = prtd->params->acnt; 216 acnt = prtd->params->acnt;
@@ -223,9 +224,10 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
223 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, 224 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
224 ASYNC); 225 ASYNC);
225 else 226 else
226 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, 227 edma_set_transfer_params(prtd->asp_link[0], acnt,
227 count, fifo_level, 228 fifo_level * serializers,
228 ABSYNC); 229 count, fifo_level * serializers,
230 ABSYNC);
229} 231}
230 232
231static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 233static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index b6ef7039dd09..32d7634d7b26 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -27,6 +27,7 @@ struct davinci_pcm_dma_params {
27 unsigned char data_type; /* xfer data type */ 27 unsigned char data_type; /* xfer data type */
28 unsigned char convert_mono_stereo; 28 unsigned char convert_mono_stereo;
29 unsigned int fifo_level; 29 unsigned int fifo_level;
30 unsigned char active_serializers; /* num. of active audio serializers */
30}; 31};
31 32
32int davinci_soc_platform_register(struct device *dev); 33int davinci_soc_platform_register(struct device *dev);