diff --git a/[refs] b/[refs] index 492b721869c7..ce6ad9191cab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9d7db2b2cb507f31ff29e339e9ed2f825edb555d +refs/heads/master: 018334c045c95793ab58948fe1f63282459c4f8d diff --git a/trunk/arch/arm/mach-omap2/mcbsp.c b/trunk/arch/arm/mach-omap2/mcbsp.c index 8fb5e5345557..c29337074ad3 100644 --- a/trunk/arch/arm/mach-omap2/mcbsp.c +++ b/trunk/arch/arm/mach-omap2/mcbsp.c @@ -133,7 +133,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP1_IRQ_RX, .tx_irq = INT_24XX_MCBSP1_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x80, /* The FIFO has 128 locations */ + .buffer_size = 0x6F, }, { .phys_base = OMAP34XX_MCBSP2_BASE, @@ -143,7 +143,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP2_IRQ_RX, .tx_irq = INT_24XX_MCBSP2_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ + .buffer_size = 0x3FF, }, { .phys_base = OMAP34XX_MCBSP3_BASE, @@ -153,7 +153,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP3_IRQ_RX, .tx_irq = INT_24XX_MCBSP3_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x80, /* The FIFO has 128 locations */ + .buffer_size = 0x6F, }, { .phys_base = OMAP34XX_MCBSP4_BASE, @@ -162,7 +162,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP4_IRQ_RX, .tx_irq = INT_24XX_MCBSP4_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x80, /* The FIFO has 128 locations */ + .buffer_size = 0x6F, }, { .phys_base = OMAP34XX_MCBSP5_BASE, @@ -171,7 +171,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP5_IRQ_RX, .tx_irq = INT_24XX_MCBSP5_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x80, /* The FIFO has 128 locations */ + .buffer_size = 0x6F, }, }; #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) diff --git a/trunk/arch/arm/plat-omap/include/plat/mcbsp.h b/trunk/arch/arm/plat-omap/include/plat/mcbsp.h index b4ff6a11a8f2..975744f10a58 100644 --- a/trunk/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/trunk/arch/arm/plat-omap/include/plat/mcbsp.h @@ -473,7 +473,6 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); -u16 omap_mcbsp_get_fifo_size(unsigned int id); u16 omap_mcbsp_get_tx_delay(unsigned int id); u16 omap_mcbsp_get_rx_delay(unsigned int id); int omap_mcbsp_get_dma_op_mode(unsigned int id); @@ -484,7 +483,6 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { } static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } -static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; } static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index e31496e35b0f..7e669c9744d8 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -481,9 +481,9 @@ int omap_st_is_enabled(unsigned int id) EXPORT_SYMBOL(omap_st_is_enabled); /* - * omap_mcbsp_set_rx_threshold configures the transmit threshold in words. - * The threshold parameter is 1 based, and it is converted (threshold - 1) - * for the THRSH2 register. + * omap_mcbsp_set_tx_threshold configures how to deal + * with transmit threshold. the threshold value and handler can be + * configure in here. */ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) { @@ -498,15 +498,14 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) } mcbsp = id_to_mcbsp_ptr(id); - if (threshold && threshold <= mcbsp->max_tx_thres) - MCBSP_WRITE(mcbsp, THRSH2, threshold - 1); + MCBSP_WRITE(mcbsp, THRSH2, threshold); } EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold); /* - * omap_mcbsp_set_rx_threshold configures the receive threshold in words. - * The threshold parameter is 1 based, and it is converted (threshold - 1) - * for the THRSH1 register. + * omap_mcbsp_set_rx_threshold configures how to deal + * with receive threshold. the threshold value and handler can be + * configure in here. */ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { @@ -521,8 +520,7 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) } mcbsp = id_to_mcbsp_ptr(id); - if (threshold && threshold <= mcbsp->max_rx_thres) - MCBSP_WRITE(mcbsp, THRSH1, threshold - 1); + MCBSP_WRITE(mcbsp, THRSH1, threshold); } EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); @@ -562,20 +560,8 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) } EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); -u16 omap_mcbsp_get_fifo_size(unsigned int id) -{ - struct omap_mcbsp *mcbsp; - - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } - mcbsp = id_to_mcbsp_ptr(id); - - return mcbsp->pdata->buffer_size; -} -EXPORT_SYMBOL(omap_mcbsp_get_fifo_size); - +#define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ +#define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ /* * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO */ @@ -594,7 +580,10 @@ u16 omap_mcbsp_get_tx_delay(unsigned int id) buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); /* Number of slots are different in McBSP ports */ - return mcbsp->pdata->buffer_size - buffstat; + if (mcbsp->id == 2) + return MCBSP2_FIFO_SIZE - buffstat; + else + return MCBSP1345_FIFO_SIZE - buffstat; } EXPORT_SYMBOL(omap_mcbsp_get_tx_delay); @@ -1694,16 +1683,8 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) { mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; if (cpu_is_omap34xx()) { - /* - * Initially configure the maximum thresholds to a safe value. - * The McBSP FIFO usage with these values should not go under - * 16 locations. - * If the whole FIFO without safety buffer is used, than there - * is a possibility that the DMA will be not able to push the - * new data on time, causing channel shifts in runtime. - */ - mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10; - mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10; + mcbsp->max_tx_thres = max_thres(mcbsp); + mcbsp->max_rx_thres = max_thres(mcbsp); /* * REVISIT: Set dmap_op_mode to THRESHOLD as default * for mcbsp2 instances. diff --git a/trunk/sound/soc/codecs/tlv320dac33.c b/trunk/sound/soc/codecs/tlv320dac33.c index 2fa946ce23a2..65adc77eada1 100644 --- a/trunk/sound/soc/codecs/tlv320dac33.c +++ b/trunk/sound/soc/codecs/tlv320dac33.c @@ -120,8 +120,6 @@ struct tlv320dac33_priv { * samples */ unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */ - unsigned int uthr; - enum dac33_state state; }; @@ -444,39 +442,6 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol, return ret; } -static int dac33_get_uthr(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = dac33->uthr; - - return 0; -} - -static int dac33_set_uthr(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (dac33->substream) - return -EBUSY; - - if (dac33->uthr == ucontrol->value.integer.value[0]) - return 0; - - if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) || - ucontrol->value.integer.value[0] > MODE7_UTHR) - ret = -EINVAL; - else - dac33->uthr = ucontrol->value.integer.value[0]; - - return ret; -} - static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -541,8 +506,6 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = { static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, dac33_get_nsample, dac33_set_nsample), - SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0, - dac33_get_uthr, dac33_set_uthr), SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum, dac33_get_fifo_mode, dac33_set_fifo_mode), }; @@ -1022,7 +985,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) * Configure the threshold levels, and leave 10 sample space * at the bottom, and also at the top of the FIFO */ - dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr)); + dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR)); dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); break; default: @@ -1089,8 +1052,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) break; case DAC33_FIFO_MODE7: dac33->mode7_us_to_lthr = - SAMPLES_TO_US(substream->runtime->rate, - dac33->uthr - MODE7_LTHR + 1); + SAMPLES_TO_US(substream->runtime->rate, + MODE7_UTHR - MODE7_LTHR + 1); dac33->t_stamp1 = 0; break; default: @@ -1141,7 +1104,7 @@ static snd_pcm_sframes_t dac33_dai_delay( struct snd_soc_codec *codec = socdev->card->codec; struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); unsigned long long t0, t1, t_now; - unsigned int time_delta, uthr; + unsigned int time_delta; int samples_out, samples_in, samples; snd_pcm_sframes_t delay = 0; @@ -1219,7 +1182,6 @@ static snd_pcm_sframes_t dac33_dai_delay( case DAC33_FIFO_MODE7: spin_lock(&dac33->lock); t0 = dac33->t_stamp1; - uthr = dac33->uthr; spin_unlock(&dac33->lock); t_now = ktime_to_us(ktime_get()); @@ -1232,7 +1194,7 @@ static snd_pcm_sframes_t dac33_dai_delay( * Either the timestamps are messed or equal. Report * maximum delay */ - delay = uthr; + delay = MODE7_UTHR; goto out; } @@ -1246,8 +1208,8 @@ static snd_pcm_sframes_t dac33_dai_delay( substream->runtime->rate, time_delta); - if (likely(uthr > samples_out)) - delay = uthr - samples_out; + if (likely(MODE7_UTHR > samples_out)) + delay = MODE7_UTHR - samples_out; else delay = 0; } else { @@ -1265,8 +1227,8 @@ static snd_pcm_sframes_t dac33_dai_delay( time_delta); delay = MODE7_LTHR + samples_in - samples_out; - if (unlikely(delay > uthr)) - delay = uthr; + if (unlikely(delay > MODE7_UTHR)) + delay = MODE7_UTHR; } break; default: @@ -1522,7 +1484,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, dac33->irq = client->irq; dac33->nsample = NSAMPLE_MAX; dac33->nsample_max = NSAMPLE_MAX; - dac33->uthr = MODE7_UTHR; /* Disable FIFO use by default */ dac33->fifo_mode = DAC33_FIFO_BYPASS; diff --git a/trunk/sound/soc/nuc900/nuc900-ac97.c b/trunk/sound/soc/nuc900/nuc900-ac97.c index f7b44e081420..e1634a2f1701 100644 --- a/trunk/sound/soc/nuc900/nuc900-ac97.c +++ b/trunk/sound/soc/nuc900/nuc900-ac97.c @@ -222,7 +222,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct nuc900_audio *nuc900_audio = nuc900_ac97_data; - int ret, stype = SUBSTREAM_TYPE(substream); + int ret; unsigned long val, tmp; ret = 0; @@ -231,7 +231,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); - if (PCM_TX == stype) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); tmp |= (SLOT3_VALID | SLOT4_VALID | VALID_FRAME); AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp); @@ -254,7 +254,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); - if (PCM_TX == stype) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); tmp &= ~(SLOT3_VALID | SLOT4_VALID); AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp); diff --git a/trunk/sound/soc/nuc900/nuc900-auido.h b/trunk/sound/soc/nuc900/nuc900-auido.h index 95ac4ef2f353..3038f519729f 100644 --- a/trunk/sound/soc/nuc900/nuc900-auido.h +++ b/trunk/sound/soc/nuc900/nuc900-auido.h @@ -96,10 +96,6 @@ #define RESET_PRSR 0x00 #define AUDIO_WRITE(addr, val) __raw_writel(val, addr) #define AUDIO_READ(addr) __raw_readl(addr) -#define PCM_TX 0 -#define PCM_RX 1 -#define SUBSTREAM_TYPE(substream) \ - ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX) struct nuc900_audio { void __iomem *mmio; diff --git a/trunk/sound/soc/nuc900/nuc900-pcm.c b/trunk/sound/soc/nuc900/nuc900-pcm.c index 32a503c1c4be..445a18011d8e 100644 --- a/trunk/sound/soc/nuc900/nuc900-pcm.c +++ b/trunk/sound/soc/nuc900/nuc900-pcm.c @@ -47,7 +47,7 @@ static int nuc900_dma_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct nuc900_audio *nuc900_audio = runtime->private_data; - unsigned long flags, stype = SUBSTREAM_TYPE(substream); + unsigned long flags; int ret = 0; spin_lock_irqsave(&nuc900_audio->lock, flags); @@ -57,8 +57,9 @@ static int nuc900_dma_hw_params(struct snd_pcm_substream *substream, return ret; nuc900_audio->substream = substream; - nuc900_audio->dma_addr[stype] = runtime->dma_addr; - nuc900_audio->buffersize[stype] = params_buffer_bytes(params); + nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr; + nuc900_audio->buffersize[substream->stream] = + params_buffer_bytes(params); spin_unlock_irqrestore(&nuc900_audio->lock, flags); @@ -72,7 +73,7 @@ static void nuc900_update_dma_register(struct snd_pcm_substream *substream, struct nuc900_audio *nuc900_audio = runtime->private_data; void __iomem *mmio_addr, *mmio_len; - if (SUBSTREAM_TYPE(substream) == PCM_TX) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mmio_addr = nuc900_audio->mmio + ACTL_PDSTB; mmio_len = nuc900_audio->mmio + ACTL_PDST_LENGTH; } else { @@ -167,18 +168,19 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct nuc900_audio *nuc900_audio = runtime->private_data; - unsigned long flags, val, stype = SUBSTREAM_TYPE(substream);; + unsigned long flags, val; spin_lock_irqsave(&nuc900_audio->lock, flags); nuc900_update_dma_register(substream, - nuc900_audio->dma_addr[stype], nuc900_audio->buffersize[stype]); + nuc900_audio->dma_addr[substream->stream], + nuc900_audio->buffersize[substream->stream]); val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); switch (runtime->channels) { case 1: - if (PCM_TX == stype) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { val &= ~(PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL); val |= PLAY_RIGHT_CHNNEL; } else { @@ -188,7 +190,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream) AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); break; case 2: - if (PCM_TX == stype) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) val |= (PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL); else val |= (RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL); diff --git a/trunk/sound/soc/omap/omap-mcbsp.c b/trunk/sound/soc/omap/omap-mcbsp.c index aebd3af2ab79..6f44cb4d30b8 100644 --- a/trunk/sound/soc/omap/omap-mcbsp.c +++ b/trunk/sound/soc/omap/omap-mcbsp.c @@ -59,7 +59,6 @@ struct omap_mcbsp_data { int configured; unsigned int in_freq; int clk_div; - int wlen; }; #define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id) @@ -156,65 +155,19 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); - int words; + int samples; /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) - /* The FIFO size depends on the McBSP word configuration */ - words = snd_pcm_lib_period_bytes(substream) / - (mcbsp_data->wlen / 8); + samples = snd_pcm_lib_period_bytes(substream) >> 1; else - words = 1; + samples = 1; /* Configure McBSP internal buffer usage */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, words); + omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, samples - 1); else - omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, words); -} - -static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *buffer_size = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct omap_mcbsp_data *mcbsp_data = rule->private; - struct snd_interval frames; - int size; - - snd_interval_any(&frames); - size = omap_mcbsp_get_fifo_size(mcbsp_data->bus_id); - - frames.min = size / channels->min; - frames.integer = 1; - return snd_interval_refine(buffer_size, &frames); -} - -static int omap_mcbsp_hwrule_max_periodsize(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *period_size = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_pcm_substream *substream = rule->private; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); - struct snd_interval frames; - int size; - - snd_interval_any(&frames); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - size = omap_mcbsp_get_max_tx_threshold(mcbsp_data->bus_id); - else - size = omap_mcbsp_get_max_rx_threshold(mcbsp_data->bus_id); - - frames.max = size / channels->min; - frames.integer = 1; - return snd_interval_refine(period_size, &frames); + omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, samples - 1); } static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, @@ -229,45 +182,33 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, if (!cpu_dai->active) err = omap_mcbsp_request(bus_id); - /* - * OMAP3 McBSP FIFO is word structured. - * McBSP2 has 1024 + 256 = 1280 word long buffer, - * McBSP1,3,4,5 has 128 word long buffer - * This means that the size of the FIFO depends on the sample format. - * For example on McBSP3: - * 16bit samples: size is 128 * 2 = 256 bytes - * 32bit samples: size is 128 * 4 = 512 bytes - * It is simpler to place constraint for buffer and period based on - * channels. - * McBSP3 as example again (16 or 32 bit samples): - * 1 channel (mono): size is 128 frames (128 words) - * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) - * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) - */ if (cpu_is_omap343x()) { int dma_op_mode = omap_mcbsp_get_dma_op_mode(bus_id); + int max_period; /* - * The first rule is for the buffer size, we should not allow - * smaller buffer than the FIFO size to avoid underruns - */ - snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - omap_mcbsp_hwrule_min_buffersize, - mcbsp_data, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); - - /* - * In case of threshold mode, the rule will ensure, that the - * period size is not bigger than the maximum allowed threshold - * value. + * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer. + * Set constraint for minimum buffer size to the same than FIFO + * size in order to avoid underruns in playback startup because + * HW is keeping the DMA request active until FIFO is filled. */ + if (bus_id == 1) + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + 4096, UINT_MAX); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + max_period = omap_mcbsp_get_max_tx_threshold(bus_id); + else + max_period = omap_mcbsp_get_max_rx_threshold(bus_id); + + max_period++; + max_period <<= 1; + if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) - snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - omap_mcbsp_hwrule_max_periodsize, - substream, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + 32, max_period); } return err; @@ -468,7 +409,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, } omap_mcbsp_config(bus_id, &mcbsp_data->regs); - mcbsp_data->wlen = wlen; mcbsp_data->configured = 1; return 0;