From: Troy Kisky <troy.kisky@boundarydevices.com>
To: davinci-linux-open-source@linux.davincidsp.com
Cc: alsa-devel@alsa-project.org, broonie@sirena.org.uk,
Troy Kisky <troy.kisky@boundarydevices.com>
Subject: [PATCH 3/5] ASoC: DaVinci: i2s, reduce underruns by combining into 1 element
Date: Thu, 6 Aug 2009 16:55:33 -0700 [thread overview]
Message-ID: <1249602935-1267-3-git-send-email-troy.kisky@boundarydevices.com> (raw)
In-Reply-To: <1249602935-1267-2-git-send-email-troy.kisky@boundarydevices.com>
Allow the left and right 16 bit samples to be shifted out as 1
32 bit sample.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
arch/arm/mach-davinci/include/mach/asp.h | 6 +++
sound/soc/davinci/davinci-i2s.c | 73 ++++++++++++++++++++++-------
2 files changed, 61 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h
index cdf1f44..73b60b6 100644
--- a/arch/arm/mach-davinci/include/mach/asp.h
+++ b/arch/arm/mach-davinci/include/mach/asp.h
@@ -37,6 +37,12 @@ struct snd_platform_data {
u32 rx_dma_offset;
enum dma_event_q eventq_no; /* event queue number */
unsigned int codec_fmt;
+ /*
+ * Allowing this is more efficient and eliminates left and right swaps
+ * caused by underruns, but will swap the left and right channels
+ * when compared to previous behavior.
+ */
+ unsigned disable_channel_combine:1;
/* McASP specific fields */
int tdm_slots;
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 2a56fb7..9587e00 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -97,6 +97,23 @@ enum {
DAVINCI_MCBSP_WORD_32,
};
+static const unsigned char data_type[SNDRV_PCM_FORMAT_S32_LE + 1] = {
+ [SNDRV_PCM_FORMAT_S8] = 1,
+ [SNDRV_PCM_FORMAT_S16_LE] = 2,
+ [SNDRV_PCM_FORMAT_S32_LE] = 4,
+};
+
+static const unsigned char asp_word_length[SNDRV_PCM_FORMAT_S32_LE + 1] = {
+ [SNDRV_PCM_FORMAT_S8] = DAVINCI_MCBSP_WORD_8,
+ [SNDRV_PCM_FORMAT_S16_LE] = DAVINCI_MCBSP_WORD_16,
+ [SNDRV_PCM_FORMAT_S32_LE] = DAVINCI_MCBSP_WORD_32,
+};
+
+static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
+ [SNDRV_PCM_FORMAT_S8] = SNDRV_PCM_FORMAT_S16_LE,
+ [SNDRV_PCM_FORMAT_S16_LE] = SNDRV_PCM_FORMAT_S32_LE,
+};
+
static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
.name = "I2S PCM Stereo out",
};
@@ -113,6 +130,27 @@ struct davinci_mcbsp_dev {
u32 pcr;
struct clk *clk;
struct davinci_pcm_dma_params *dma_params[2];
+ /*
+ * Combining both channels into 1 element will at least double the
+ * amount of time between servicing the dma channel, increase
+ * effiency, and reduce the chance of overrun/underrun. But,
+ * it will result in the left & right channels being swapped.
+ *
+ * If relabeling the left and right channels is not possible,
+ * you may want to let the codec know to swap them back.
+ *
+ * It may allow x10 the amount of time to service dma requests,
+ * if the codec is master and is using an unnecessarily fast bit clock
+ * (ie. tlvaic23b), independent of the sample rate. So, having an
+ * entire frame at once means it can be serviced at the sample rate
+ * instead of the bit clock rate.
+ *
+ * In the now unlikely case that an underrun still
+ * occurs, both the left and right samples will be repeated
+ * so that no pops are heard, and the left and right channels
+ * won't end up being swapped because of the underrun.
+ */
+ unsigned disable_channel_combine:1;
};
static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -359,6 +397,8 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
int mcbsp_word_length;
unsigned int rcr, xcr, srgr;
u32 spcr;
+ snd_pcm_format_t fmt;
+ unsigned element_cnt = 1;
/* general line settings */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -388,26 +428,22 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
}
/* Determine xfer data type */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- dma_params->data_type = 1;
- mcbsp_word_length = DAVINCI_MCBSP_WORD_8;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- dma_params->data_type = 2;
- mcbsp_word_length = DAVINCI_MCBSP_WORD_16;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- dma_params->data_type = 4;
- mcbsp_word_length = DAVINCI_MCBSP_WORD_32;
- break;
- default:
+ fmt = params_format(params);
+ if ((fmt > SNDRV_PCM_FORMAT_S32_LE) || !data_type[fmt]) {
printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
return -EINVAL;
}
-
- rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1);
- xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1);
+ if (params_channels(params) == 2) {
+ element_cnt = 2;
+ if (double_fmt[fmt] && !dev->disable_channel_combine) {
+ element_cnt = 1;
+ fmt = double_fmt[fmt];
+ }
+ }
+ dma_params->data_type = data_type[fmt];
+ mcbsp_word_length = asp_word_length[fmt];
+ rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
+ xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
@@ -523,7 +559,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto err_release_region;
}
-
+ if (pdata)
+ dev->disable_channel_combine = pdata->disable_channel_combine;
dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
ret = -ENODEV;
--
1.5.6.3
next prev parent reply other threads:[~2009-08-06 23:55 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-06 23:55 [PATCH 1/5] ASoC: DaVinci: i2s: don't bounce through rtd to get dai Troy Kisky
[not found] ` <1249602935-1267-1-git-send-email-troy.kisky-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
2009-08-06 23:55 ` [PATCH 2/5] ASoC: DaVinci: pcm, constrain buffer size to multiple of period Troy Kisky
2009-08-06 23:55 ` Troy Kisky [this message]
2009-08-06 23:55 ` [PATCH 4/5] ASoC: DaVinci: pcm, rename variables in prep for ping/pong Troy Kisky
2009-08-06 23:55 ` [PATCH 5/5] ASoC: DaVinci: pcm, fix underruns by using sram Troy Kisky
2009-08-07 2:05 ` Troy Kisky
2009-08-08 9:17 ` Mark Brown
2009-08-11 0:32 ` Troy Kisky
2009-08-11 9:59 ` Mark Brown
2009-08-08 8:59 ` [PATCH 3/5] ASoC: DaVinci: i2s, reduce underruns by combining into 1 element Mark Brown
2009-08-08 9:07 ` Mark Brown
2009-08-07 10:41 ` [PATCH 1/5] ASoC: DaVinci: i2s: don't bounce through rtd to get dai Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1249602935-1267-3-git-send-email-troy.kisky@boundarydevices.com \
--to=troy.kisky@boundarydevices.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@sirena.org.uk \
--cc=davinci-linux-open-source@linux.davincidsp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox