diff options
-rw-r--r-- | sound/soc/blackfin/bf5xx-ad1836.c | 7 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-ad1938.c | 9 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-tdm-pcm.c | 9 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-tdm.c | 45 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-tdm.h | 11 |
5 files changed, 69 insertions, 12 deletions
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index cd361e304b0f..0f45a3f56be8 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c | |||
@@ -52,6 +52,7 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, | |||
52 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 52 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
53 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 53 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
54 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | 54 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; |
55 | unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; | ||
55 | int ret = 0; | 56 | int ret = 0; |
56 | /* set cpu DAI configuration */ | 57 | /* set cpu DAI configuration */ |
57 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | | 58 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | |
@@ -65,6 +66,12 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, | |||
65 | if (ret < 0) | 66 | if (ret < 0) |
66 | return ret; | 67 | return ret; |
67 | 68 | ||
69 | /* set cpu DAI channel mapping */ | ||
70 | ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), | ||
71 | channel_map, ARRAY_SIZE(channel_map), channel_map); | ||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | |||
68 | return 0; | 75 | return 0; |
69 | } | 76 | } |
70 | 77 | ||
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad1938.c index 08269e91810c..2ef1e5013b8c 100644 --- a/sound/soc/blackfin/bf5xx-ad1938.c +++ b/sound/soc/blackfin/bf5xx-ad1938.c | |||
@@ -61,6 +61,7 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream, | |||
61 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 61 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
62 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 62 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
63 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | 63 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; |
64 | unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
64 | int ret = 0; | 65 | int ret = 0; |
65 | /* set cpu DAI configuration */ | 66 | /* set cpu DAI configuration */ |
66 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | | 67 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | |
@@ -75,7 +76,13 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream, | |||
75 | return ret; | 76 | return ret; |
76 | 77 | ||
77 | /* set codec DAI slots, 8 channels, all channels are enabled */ | 78 | /* set codec DAI slots, 8 channels, all channels are enabled */ |
78 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 8); | 79 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32); |
80 | if (ret < 0) | ||
81 | return ret; | ||
82 | |||
83 | /* set cpu DAI channel mapping */ | ||
84 | ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), | ||
85 | channel_map, ARRAY_SIZE(channel_map), channel_map); | ||
79 | if (ret < 0) | 86 | if (ret < 0) |
80 | return ret; | 87 | return ret; |
81 | 88 | ||
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c index ccb5e823bd18..a8c73cbbd685 100644 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "bf5xx-tdm.h" | 43 | #include "bf5xx-tdm.h" |
44 | #include "bf5xx-sport.h" | 44 | #include "bf5xx-sport.h" |
45 | 45 | ||
46 | #define PCM_BUFFER_MAX 0x10000 | 46 | #define PCM_BUFFER_MAX 0x8000 |
47 | #define FRAGMENT_SIZE_MIN (4*1024) | 47 | #define FRAGMENT_SIZE_MIN (4*1024) |
48 | #define FRAGMENTS_MIN 2 | 48 | #define FRAGMENTS_MIN 2 |
49 | #define FRAGMENTS_MAX 32 | 49 | #define FRAGMENTS_MAX 32 |
@@ -177,6 +177,9 @@ out: | |||
177 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | 177 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, |
178 | snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) | 178 | snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) |
179 | { | 179 | { |
180 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
181 | struct sport_device *sport = runtime->private_data; | ||
182 | struct bf5xx_tdm_port *tdm_port = sport->private_data; | ||
180 | unsigned int *src; | 183 | unsigned int *src; |
181 | unsigned int *dst; | 184 | unsigned int *dst; |
182 | int i; | 185 | int i; |
@@ -188,7 +191,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | |||
188 | dst += pos * 8; | 191 | dst += pos * 8; |
189 | while (count--) { | 192 | while (count--) { |
190 | for (i = 0; i < substream->runtime->channels; i++) | 193 | for (i = 0; i < substream->runtime->channels; i++) |
191 | *(dst + i) = *src++; | 194 | *(dst + tdm_port->tx_map[i]) = *src++; |
192 | dst += 8; | 195 | dst += 8; |
193 | } | 196 | } |
194 | } else { | 197 | } else { |
@@ -198,7 +201,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | |||
198 | src += pos * 8; | 201 | src += pos * 8; |
199 | while (count--) { | 202 | while (count--) { |
200 | for (i = 0; i < substream->runtime->channels; i++) | 203 | for (i = 0; i < substream->runtime->channels; i++) |
201 | *dst++ = *(src+i); | 204 | *dst++ = *(src + tdm_port->rx_map[i]); |
202 | src += 8; | 205 | src += 8; |
203 | } | 206 | } |
204 | } | 207 | } |
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c index 3096badf09a5..600987d8a871 100644 --- a/sound/soc/blackfin/bf5xx-tdm.c +++ b/sound/soc/blackfin/bf5xx-tdm.c | |||
@@ -46,14 +46,6 @@ | |||
46 | #include "bf5xx-sport.h" | 46 | #include "bf5xx-sport.h" |
47 | #include "bf5xx-tdm.h" | 47 | #include "bf5xx-tdm.h" |
48 | 48 | ||
49 | struct bf5xx_tdm_port { | ||
50 | u16 tcr1; | ||
51 | u16 rcr1; | ||
52 | u16 tcr2; | ||
53 | u16 rcr2; | ||
54 | int configured; | ||
55 | }; | ||
56 | |||
57 | static struct bf5xx_tdm_port bf5xx_tdm; | 49 | static struct bf5xx_tdm_port bf5xx_tdm; |
58 | static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; | 50 | static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; |
59 | 51 | ||
@@ -181,6 +173,40 @@ static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream, | |||
181 | bf5xx_tdm.configured = 0; | 173 | bf5xx_tdm.configured = 0; |
182 | } | 174 | } |
183 | 175 | ||
176 | static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, | ||
177 | unsigned int tx_num, unsigned int *tx_slot, | ||
178 | unsigned int rx_num, unsigned int *rx_slot) | ||
179 | { | ||
180 | int i; | ||
181 | unsigned int slot; | ||
182 | unsigned int tx_mapped = 0, rx_mapped = 0; | ||
183 | |||
184 | if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) || | ||
185 | (rx_num > BFIN_TDM_DAI_MAX_SLOTS)) | ||
186 | return -EINVAL; | ||
187 | |||
188 | for (i = 0; i < tx_num; i++) { | ||
189 | slot = tx_slot[i]; | ||
190 | if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && | ||
191 | (!(tx_mapped & (1 << slot)))) { | ||
192 | bf5xx_tdm.tx_map[i] = slot; | ||
193 | tx_mapped |= 1 << slot; | ||
194 | } else | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | for (i = 0; i < rx_num; i++) { | ||
198 | slot = rx_slot[i]; | ||
199 | if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && | ||
200 | (!(rx_mapped & (1 << slot)))) { | ||
201 | bf5xx_tdm.rx_map[i] = slot; | ||
202 | rx_mapped |= 1 << slot; | ||
203 | } else | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
184 | #ifdef CONFIG_PM | 210 | #ifdef CONFIG_PM |
185 | static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) | 211 | static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) |
186 | { | 212 | { |
@@ -235,6 +261,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = { | |||
235 | .hw_params = bf5xx_tdm_hw_params, | 261 | .hw_params = bf5xx_tdm_hw_params, |
236 | .set_fmt = bf5xx_tdm_set_dai_fmt, | 262 | .set_fmt = bf5xx_tdm_set_dai_fmt, |
237 | .shutdown = bf5xx_tdm_shutdown, | 263 | .shutdown = bf5xx_tdm_shutdown, |
264 | .set_channel_map = bf5xx_tdm_set_channel_map, | ||
238 | }; | 265 | }; |
239 | 266 | ||
240 | struct snd_soc_dai bf5xx_tdm_dai = { | 267 | struct snd_soc_dai bf5xx_tdm_dai = { |
@@ -300,6 +327,8 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev) | |||
300 | pr_err("Failed to register DAI: %d\n", ret); | 327 | pr_err("Failed to register DAI: %d\n", ret); |
301 | goto sport_config_err; | 328 | goto sport_config_err; |
302 | } | 329 | } |
330 | |||
331 | sport_handle->private_data = &bf5xx_tdm; | ||
303 | return 0; | 332 | return 0; |
304 | 333 | ||
305 | sport_config_err: | 334 | sport_config_err: |
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h index 618ec3d90cd4..04189a18c1ba 100644 --- a/sound/soc/blackfin/bf5xx-tdm.h +++ b/sound/soc/blackfin/bf5xx-tdm.h | |||
@@ -9,6 +9,17 @@ | |||
9 | #ifndef _BF5XX_TDM_H | 9 | #ifndef _BF5XX_TDM_H |
10 | #define _BF5XX_TDM_H | 10 | #define _BF5XX_TDM_H |
11 | 11 | ||
12 | #define BFIN_TDM_DAI_MAX_SLOTS 8 | ||
13 | struct bf5xx_tdm_port { | ||
14 | u16 tcr1; | ||
15 | u16 rcr1; | ||
16 | u16 tcr2; | ||
17 | u16 rcr2; | ||
18 | unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS]; | ||
19 | unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS]; | ||
20 | int configured; | ||
21 | }; | ||
22 | |||
12 | extern struct snd_soc_dai bf5xx_tdm_dai; | 23 | extern struct snd_soc_dai bf5xx_tdm_dai; |
13 | 24 | ||
14 | #endif | 25 | #endif |