aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-08-02 06:10:52 -0400
committerTakashi Iwai <tiwai@suse.de>2010-08-02 06:10:52 -0400
commit988b0dc1547f9f6a7c8cae472cad0a55df31818c (patch)
tree6eea131119cf8035a91eddef23a40dee93d0389d
parent3bc280708e7b9a84cc6307c1f9acca57e0fafaac (diff)
parent998a8a69f3a40f9c82e83730bfdaceb63954d753 (diff)
Merge branch 'for-2.6.36' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into topic/asoc
-rw-r--r--include/sound/tlv320dac33-plat.h2
-rw-r--r--sound/soc/codecs/tlv320dac33.c125
-rw-r--r--sound/soc/codecs/twl4030.c2
-rw-r--r--sound/soc/omap/omap-mcbsp.c137
4 files changed, 158 insertions, 108 deletions
diff --git a/include/sound/tlv320dac33-plat.h b/include/sound/tlv320dac33-plat.h
index 3f428d53195b..6c6649656798 100644
--- a/include/sound/tlv320dac33-plat.h
+++ b/include/sound/tlv320dac33-plat.h
@@ -15,6 +15,8 @@
15 15
16struct tlv320dac33_platform_data { 16struct tlv320dac33_platform_data {
17 int power_gpio; 17 int power_gpio;
18 int mode1_latency; /* latency caused by the i2c writes in us */
19 int auto_fifo_config; /* FIFO config based on the period size */
18 int keep_bclk; /* Keep the BCLK running in FIFO modes */ 20 int keep_bclk; /* Keep the BCLK running in FIFO modes */
19 u8 burst_bclkdiv; 21 u8 burst_bclkdiv;
20}; 22};
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 2fa946ce23a2..8651b01ed223 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -49,8 +49,6 @@
49 49
50#define NSAMPLE_MAX 5700 50#define NSAMPLE_MAX 5700
51 51
52#define LATENCY_TIME_MS 20
53
54#define MODE7_LTHR 10 52#define MODE7_LTHR 10
55#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) 53#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10)
56 54
@@ -62,6 +60,9 @@
62#define US_TO_SAMPLES(rate, us) \ 60#define US_TO_SAMPLES(rate, us) \
63 (rate / (1000000 / us)) 61 (rate / (1000000 / us))
64 62
63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate)))
65
65static void dac33_calculate_times(struct snd_pcm_substream *substream); 66static void dac33_calculate_times(struct snd_pcm_substream *substream);
66static int dac33_prepare_chip(struct snd_pcm_substream *substream); 67static int dac33_prepare_chip(struct snd_pcm_substream *substream);
67 68
@@ -107,6 +108,10 @@ struct tlv320dac33_priv {
107 * this */ 108 * this */
108 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 109 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
109 unsigned int nsample; /* burst read amount from host */ 110 unsigned int nsample; /* burst read amount from host */
111 int mode1_latency; /* latency caused by the i2c writes in
112 * us */
113 int auto_fifo_config; /* Configure the FIFO based on the
114 * period size */
110 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 115 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
111 unsigned int burst_rate; /* Interface speed in Burst modes */ 116 unsigned int burst_rate; /* Interface speed in Burst modes */
112 117
@@ -538,13 +543,16 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
538 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1), 543 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
539}; 544};
540 545
541static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 546static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
547 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
548 dac33_get_fifo_mode, dac33_set_fifo_mode),
549};
550
551static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = {
542 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, 552 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
543 dac33_get_nsample, dac33_set_nsample), 553 dac33_get_nsample, dac33_set_nsample),
544 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0, 554 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
545 dac33_get_uthr, dac33_set_uthr), 555 dac33_get_uthr, dac33_set_uthr),
546 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
547 dac33_get_fifo_mode, dac33_set_fifo_mode),
548}; 556};
549 557
550/* Analog bypass */ 558/* Analog bypass */
@@ -649,7 +657,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
649 switch (dac33->fifo_mode) { 657 switch (dac33->fifo_mode) {
650 case DAC33_FIFO_MODE1: 658 case DAC33_FIFO_MODE1:
651 dac33_write16(codec, DAC33_NSAMPLE_MSB, 659 dac33_write16(codec, DAC33_NSAMPLE_MSB,
652 DAC33_THRREG(dac33->nsample + dac33->alarm_threshold)); 660 DAC33_THRREG(dac33->nsample));
653 661
654 /* Take the timestamps */ 662 /* Take the timestamps */
655 spin_lock_irq(&dac33->lock); 663 spin_lock_irq(&dac33->lock);
@@ -798,6 +806,10 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
798 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 806 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
799 807
800 dac33->substream = NULL; 808 dac33->substream = NULL;
809
810 /* Reset the nSample restrictions */
811 dac33->nsample_min = 0;
812 dac33->nsample_max = NSAMPLE_MAX;
801} 813}
802 814
803static int dac33_hw_params(struct snd_pcm_substream *substream, 815static int dac33_hw_params(struct snd_pcm_substream *substream,
@@ -1040,54 +1052,68 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1040 struct snd_soc_device *socdev = rtd->socdev; 1052 struct snd_soc_device *socdev = rtd->socdev;
1041 struct snd_soc_codec *codec = socdev->card->codec; 1053 struct snd_soc_codec *codec = socdev->card->codec;
1042 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1054 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int period_size = substream->runtime->period_size;
1056 unsigned int rate = substream->runtime->rate;
1043 unsigned int nsample_limit; 1057 unsigned int nsample_limit;
1044 1058
1045 /* In bypass mode we don't need to calculate */ 1059 /* In bypass mode we don't need to calculate */
1046 if (!dac33->fifo_mode) 1060 if (!dac33->fifo_mode)
1047 return; 1061 return;
1048 1062
1049 /* Number of samples (16bit, stereo) in one period */
1050 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
1051
1052 /* Number of samples (16bit, stereo) in ALSA buffer */
1053 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
1054 /* Subtract one period from the total */
1055 dac33->nsample_max -= dac33->nsample_min;
1056
1057 /* Number of samples for LATENCY_TIME_MS / 2 */
1058 dac33->alarm_threshold = substream->runtime->rate /
1059 (1000 / (LATENCY_TIME_MS / 2));
1060
1061 /* Find and fix up the lowest nsmaple limit */
1062 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
1063
1064 if (dac33->nsample_min < nsample_limit)
1065 dac33->nsample_min = nsample_limit;
1066
1067 if (dac33->nsample < dac33->nsample_min)
1068 dac33->nsample = dac33->nsample_min;
1069
1070 /*
1071 * Find and fix up the highest nsmaple limit
1072 * In order to not overflow the DAC33 buffer substract the
1073 * alarm_threshold value from the size of the DAC33 buffer
1074 */
1075 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
1076
1077 if (dac33->nsample_max > nsample_limit)
1078 dac33->nsample_max = nsample_limit;
1079
1080 if (dac33->nsample > dac33->nsample_max)
1081 dac33->nsample = dac33->nsample_max;
1082
1083 switch (dac33->fifo_mode) { 1063 switch (dac33->fifo_mode) {
1084 case DAC33_FIFO_MODE1: 1064 case DAC33_FIFO_MODE1:
1065 /* Number of samples under i2c latency */
1066 dac33->alarm_threshold = US_TO_SAMPLES(rate,
1067 dac33->mode1_latency);
1068 if (dac33->auto_fifo_config) {
1069 if (period_size <= dac33->alarm_threshold)
1070 /*
1071 * Configure nSamaple to number of periods,
1072 * which covers the latency requironment.
1073 */
1074 dac33->nsample = period_size *
1075 ((dac33->alarm_threshold / period_size) +
1076 (dac33->alarm_threshold % period_size ?
1077 1 : 0));
1078 else
1079 dac33->nsample = period_size;
1080 } else {
1081 /* nSample time shall not be shorter than i2c latency */
1082 dac33->nsample_min = dac33->alarm_threshold;
1083 /*
1084 * nSample should not be bigger than alsa buffer minus
1085 * size of one period to avoid overruns
1086 */
1087 dac33->nsample_max = substream->runtime->buffer_size -
1088 period_size;
1089 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
1090 dac33->alarm_threshold;
1091 if (dac33->nsample_max > nsample_limit)
1092 dac33->nsample_max = nsample_limit;
1093
1094 /* Correct the nSample if it is outside of the ranges */
1095 if (dac33->nsample < dac33->nsample_min)
1096 dac33->nsample = dac33->nsample_min;
1097 if (dac33->nsample > dac33->nsample_max)
1098 dac33->nsample = dac33->nsample_max;
1099 }
1100
1085 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, 1101 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1086 dac33->nsample); 1102 dac33->nsample);
1087 dac33->t_stamp1 = 0; 1103 dac33->t_stamp1 = 0;
1088 dac33->t_stamp2 = 0; 1104 dac33->t_stamp2 = 0;
1089 break; 1105 break;
1090 case DAC33_FIFO_MODE7: 1106 case DAC33_FIFO_MODE7:
1107 if (dac33->auto_fifo_config) {
1108 dac33->uthr = UTHR_FROM_PERIOD_SIZE(
1109 period_size,
1110 rate,
1111 dac33->burst_rate) + 9;
1112 if (dac33->uthr > MODE7_UTHR)
1113 dac33->uthr = MODE7_UTHR;
1114 if (dac33->uthr < (MODE7_LTHR + 10))
1115 dac33->uthr = (MODE7_LTHR + 10);
1116 }
1091 dac33->mode7_us_to_lthr = 1117 dac33->mode7_us_to_lthr =
1092 SAMPLES_TO_US(substream->runtime->rate, 1118 SAMPLES_TO_US(substream->runtime->rate,
1093 dac33->uthr - MODE7_LTHR + 1); 1119 dac33->uthr - MODE7_LTHR + 1);
@@ -1385,10 +1411,15 @@ static int dac33_soc_probe(struct platform_device *pdev)
1385 1411
1386 snd_soc_add_controls(codec, dac33_snd_controls, 1412 snd_soc_add_controls(codec, dac33_snd_controls,
1387 ARRAY_SIZE(dac33_snd_controls)); 1413 ARRAY_SIZE(dac33_snd_controls));
1388 /* Only add the nSample controls, if we have valid IRQ number */ 1414 /* Only add the FIFO controls, if we have valid IRQ number */
1389 if (dac33->irq >= 0) 1415 if (dac33->irq >= 0) {
1390 snd_soc_add_controls(codec, dac33_nsample_snd_controls, 1416 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1391 ARRAY_SIZE(dac33_nsample_snd_controls)); 1417 ARRAY_SIZE(dac33_mode_snd_controls));
1418 /* FIFO usage controls only, if autoio config is not selected */
1419 if (!dac33->auto_fifo_config)
1420 snd_soc_add_controls(codec, dac33_fifo_snd_controls,
1421 ARRAY_SIZE(dac33_fifo_snd_controls));
1422 }
1392 1423
1393 dac33_add_widgets(codec); 1424 dac33_add_widgets(codec);
1394 1425
@@ -1519,6 +1550,10 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1519 /* Pre calculate the burst rate */ 1550 /* Pre calculate the burst rate */
1520 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32; 1551 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1521 dac33->keep_bclk = pdata->keep_bclk; 1552 dac33->keep_bclk = pdata->keep_bclk;
1553 dac33->auto_fifo_config = pdata->auto_fifo_config;
1554 dac33->mode1_latency = pdata->mode1_latency;
1555 if (!dac33->mode1_latency)
1556 dac33->mode1_latency = 10000; /* 10ms */
1522 dac33->irq = client->irq; 1557 dac33->irq = client->irq;
1523 dac33->nsample = NSAMPLE_MAX; 1558 dac33->nsample = NSAMPLE_MAX;
1524 dac33->nsample_max = NSAMPLE_MAX; 1559 dac33->nsample_max = NSAMPLE_MAX;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index bd557c2bcb8c..d401c597d38f 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1432,11 +1432,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1432 TX2 Left/Right: either analog Left/Right or Digimic1 */ 1432 TX2 Left/Right: either analog Left/Right or Digimic1 */
1433 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0, 1433 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
1434 &twl4030_dapm_micpathtx1_control, micpath_event, 1434 &twl4030_dapm_micpathtx1_control, micpath_event,
1435 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
1436 SND_SOC_DAPM_POST_REG), 1435 SND_SOC_DAPM_POST_REG),
1437 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0, 1436 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1438 &twl4030_dapm_micpathtx2_control, micpath_event, 1437 &twl4030_dapm_micpathtx2_control, micpath_event,
1439 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
1440 SND_SOC_DAPM_POST_REG), 1438 SND_SOC_DAPM_POST_REG),
1441 1439
1442 /* Analog input mixers for the capture amplifiers */ 1440 /* Analog input mixers for the capture amplifiers */
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index aebd3af2ab79..86f213905e2c 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -155,13 +155,23 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
155 struct snd_soc_pcm_runtime *rtd = substream->private_data; 155 struct snd_soc_pcm_runtime *rtd = substream->private_data;
156 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 156 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
157 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 157 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
158 struct omap_pcm_dma_data *dma_data;
158 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); 159 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id);
159 int words; 160 int words;
160 161
162 dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
163
161 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 164 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
162 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) 165 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
163 /* The FIFO size depends on the McBSP word configuration */ 166 /*
164 words = snd_pcm_lib_period_bytes(substream) / 167 * Configure McBSP threshold based on either:
168 * packet_size, when the sDMA is in packet mode, or
169 * based on the period size.
170 */
171 if (dma_data->packet_size)
172 words = dma_data->packet_size;
173 else
174 words = snd_pcm_lib_period_bytes(substream) /
165 (mcbsp_data->wlen / 8); 175 (mcbsp_data->wlen / 8);
166 else 176 else
167 words = 1; 177 words = 1;
@@ -192,31 +202,6 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
192 return snd_interval_refine(buffer_size, &frames); 202 return snd_interval_refine(buffer_size, &frames);
193} 203}
194 204
195static int omap_mcbsp_hwrule_max_periodsize(struct snd_pcm_hw_params *params,
196 struct snd_pcm_hw_rule *rule)
197{
198 struct snd_interval *period_size = hw_param_interval(params,
199 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
200 struct snd_interval *channels = hw_param_interval(params,
201 SNDRV_PCM_HW_PARAM_CHANNELS);
202 struct snd_pcm_substream *substream = rule->private;
203 struct snd_soc_pcm_runtime *rtd = substream->private_data;
204 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
205 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
206 struct snd_interval frames;
207 int size;
208
209 snd_interval_any(&frames);
210 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
211 size = omap_mcbsp_get_max_tx_threshold(mcbsp_data->bus_id);
212 else
213 size = omap_mcbsp_get_max_rx_threshold(mcbsp_data->bus_id);
214
215 frames.max = size / channels->min;
216 frames.integer = 1;
217 return snd_interval_refine(period_size, &frames);
218}
219
220static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 205static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
221 struct snd_soc_dai *dai) 206 struct snd_soc_dai *dai)
222{ 207{
@@ -245,10 +230,8 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
245 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) 230 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
246 */ 231 */
247 if (cpu_is_omap343x()) { 232 if (cpu_is_omap343x()) {
248 int dma_op_mode = omap_mcbsp_get_dma_op_mode(bus_id);
249
250 /* 233 /*
251 * The first rule is for the buffer size, we should not allow 234 * Rule for the buffer size. We should not allow
252 * smaller buffer than the FIFO size to avoid underruns 235 * smaller buffer than the FIFO size to avoid underruns
253 */ 236 */
254 snd_pcm_hw_rule_add(substream->runtime, 0, 237 snd_pcm_hw_rule_add(substream->runtime, 0,
@@ -257,17 +240,9 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
257 mcbsp_data, 240 mcbsp_data,
258 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); 241 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
259 242
260 /* 243 /* Make sure, that the period size is always even */
261 * In case of threshold mode, the rule will ensure, that the 244 snd_pcm_hw_constraint_step(substream->runtime, 0,
262 * period size is not bigger than the maximum allowed threshold 245 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
263 * value.
264 */
265 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
266 snd_pcm_hw_rule_add(substream->runtime, 0,
267 SNDRV_PCM_HW_PARAM_CHANNELS,
268 omap_mcbsp_hwrule_max_periodsize,
269 substream,
270 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
271 } 246 }
272 247
273 return err; 248 return err;
@@ -348,11 +323,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
348 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 323 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
349 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 324 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
350 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 325 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
351 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 326 struct omap_pcm_dma_data *dma_data;
327 int dma, bus_id = mcbsp_data->bus_id;
352 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 328 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
329 int pkt_size = 0;
353 unsigned long port; 330 unsigned long port;
354 unsigned int format, div, framesize, master; 331 unsigned int format, div, framesize, master;
355 332
333 dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream];
356 if (cpu_class_is_omap1()) { 334 if (cpu_class_is_omap1()) {
357 dma = omap1_dma_reqs[bus_id][substream->stream]; 335 dma = omap1_dma_reqs[bus_id][substream->stream];
358 port = omap1_mcbsp_port[bus_id][substream->stream]; 336 port = omap1_mcbsp_port[bus_id][substream->stream];
@@ -365,35 +343,74 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
365 } else if (cpu_is_omap343x()) { 343 } else if (cpu_is_omap343x()) {
366 dma = omap24xx_dma_reqs[bus_id][substream->stream]; 344 dma = omap24xx_dma_reqs[bus_id][substream->stream];
367 port = omap34xx_mcbsp_port[bus_id][substream->stream]; 345 port = omap34xx_mcbsp_port[bus_id][substream->stream];
368 omap_mcbsp_dai_dma_params[id][substream->stream].set_threshold =
369 omap_mcbsp_set_threshold;
370 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
371 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
372 MCBSP_DMA_MODE_THRESHOLD)
373 sync_mode = OMAP_DMA_SYNC_FRAME;
374 } else { 346 } else {
375 return -ENODEV; 347 return -ENODEV;
376 } 348 }
377 omap_mcbsp_dai_dma_params[id][substream->stream].name =
378 substream->stream ? "Audio Capture" : "Audio Playback";
379 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
380 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
381 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
382 switch (params_format(params)) { 349 switch (params_format(params)) {
383 case SNDRV_PCM_FORMAT_S16_LE: 350 case SNDRV_PCM_FORMAT_S16_LE:
384 omap_mcbsp_dai_dma_params[id][substream->stream].data_type = 351 dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
385 OMAP_DMA_DATA_TYPE_S16; 352 wlen = 16;
386 break; 353 break;
387 case SNDRV_PCM_FORMAT_S32_LE: 354 case SNDRV_PCM_FORMAT_S32_LE:
388 omap_mcbsp_dai_dma_params[id][substream->stream].data_type = 355 dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
389 OMAP_DMA_DATA_TYPE_S32; 356 wlen = 32;
390 break; 357 break;
391 default: 358 default:
392 return -EINVAL; 359 return -EINVAL;
393 } 360 }
361 if (cpu_is_omap343x()) {
362 dma_data->set_threshold = omap_mcbsp_set_threshold;
363 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
364 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
365 MCBSP_DMA_MODE_THRESHOLD) {
366 int period_words, max_thrsh;
367
368 period_words = params_period_bytes(params) / (wlen / 8);
369 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
370 max_thrsh = omap_mcbsp_get_max_tx_threshold(
371 mcbsp_data->bus_id);
372 else
373 max_thrsh = omap_mcbsp_get_max_rx_threshold(
374 mcbsp_data->bus_id);
375 /*
376 * If the period contains less or equal number of words,
377 * we are using the original threshold mode setup:
378 * McBSP threshold = sDMA frame size = period_size
379 * Otherwise we switch to sDMA packet mode:
380 * McBSP threshold = sDMA packet size
381 * sDMA frame size = period size
382 */
383 if (period_words > max_thrsh) {
384 int divider = 0;
385
386 /*
387 * Look for the biggest threshold value, which
388 * divides the period size evenly.
389 */
390 divider = period_words / max_thrsh;
391 if (period_words % max_thrsh)
392 divider++;
393 while (period_words % divider &&
394 divider < period_words)
395 divider++;
396 if (divider == period_words)
397 return -EINVAL;
398
399 pkt_size = period_words / divider;
400 sync_mode = OMAP_DMA_SYNC_PACKET;
401 } else {
402 sync_mode = OMAP_DMA_SYNC_FRAME;
403 }
404 }
405 }
406
407 dma_data->name = substream->stream ? "Audio Capture" : "Audio Playback";
408 dma_data->dma_req = dma;
409 dma_data->port_addr = port;
410 dma_data->sync_mode = sync_mode;
411 dma_data->packet_size = pkt_size;
394 412
395 snd_soc_dai_set_dma_data(cpu_dai, substream, 413 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
396 &omap_mcbsp_dai_dma_params[id][substream->stream]);
397 414
398 if (mcbsp_data->configured) { 415 if (mcbsp_data->configured) {
399 /* McBSP already configured by another stream */ 416 /* McBSP already configured by another stream */
@@ -419,7 +436,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
419 switch (params_format(params)) { 436 switch (params_format(params)) {
420 case SNDRV_PCM_FORMAT_S16_LE: 437 case SNDRV_PCM_FORMAT_S16_LE:
421 /* Set word lengths */ 438 /* Set word lengths */
422 wlen = 16;
423 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16); 439 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16);
424 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16); 440 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16);
425 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16); 441 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
@@ -427,7 +443,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
427 break; 443 break;
428 case SNDRV_PCM_FORMAT_S32_LE: 444 case SNDRV_PCM_FORMAT_S32_LE:
429 /* Set word lengths */ 445 /* Set word lengths */
430 wlen = 32;
431 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32); 446 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32);
432 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32); 447 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32);
433 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32); 448 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32);