All of lore.kernel.org
 help / color / mirror / Atom feed
* possible fix for buffer underruns on msm7k alsa driver
@ 2010-08-14 18:29 Denis 'GNUtoo' Carikli
  2010-08-15 11:29 ` Mark Brown
  0 siblings, 1 reply; 6+ messages in thread
From: Denis 'GNUtoo' Carikli @ 2010-08-14 18:29 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

hi, I'm still rebasing the codeaurora alsa driver for msm soc like the
htcdream on the android msm 2.6.32 kernel.
I looked the commits for the other socs like msm7kv2 and
qsd8k(snapdragon)

and I found that commit:
commit ac97ef246a754b9a2b4236ca08c6ade389dc206f
Author: Pradeep Jilagam <pjilagam@qualcomm.com>
Date:   Wed Apr 7 17:38:20 2010 +0530

    alsa: 8k: Limit period size for sample rates greater than 8KHz
    
    The DSP interrupts are non-periodic. ALSA expects periodic
    acknowledgement for the buffers sent. Hence, the alsa driver uses
    timer as alternate interrupt source. The min resolution is 10ms
    which results in distorted audio for some sample rates. Hence
    restricting the minimum period size for sample rates greater
    than 8KHz to 512 frames.
    
    Change-Id: Ic8c4180fbee7242fa3139230ddcf6a9f98e4c7ab
    CRs-fixed: 231784
    Signed-off-by: Pradeep Jilagam <pjilagam@qualcomm.com>

I tried a big buck bunny at 44100 Hz: lots(too much) of buffer underrun
=> too bad to be usable.
Then I tried it with 8000 Hz and found nearly no buffer underruns =>
usable.

So I've great expectations for that fix.

here's the source code involved in the fix:

static int hw_rule_periodsize_by_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_interval *ps = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
struct snd_interval *r = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval ch;

if (!ps || !r){
pr_debug("REMOVE_THAT: exiting from !ps||!r\n");
return 0;
}else{
pr_debug("REMOVE_THAT: not exiting\n");
}
snd_interval_any(&ch);

if (r->min > 8000) {
ch.min = 512;
pr_debug("Minimum period size is adjusted to 512\n");
return snd_interval_refine(ps, &ch);
}
return 0;
}


static int msm_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct msm_audio *prtd;
int ret = 0;

prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL);
if (prtd == NULL) {
ret = -ENOMEM;
return ret;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
msm_vol_ctl.update = 1; /* Update Volume, with Cached value */
runtime->hw = msm_pcm_playback_hardware;
prtd->dir = SNDRV_PCM_STREAM_PLAYBACK;
prtd->playback_substream = substream;
prtd->eos_ack = 0;
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
runtime->hw = msm_pcm_capture_hardware;
prtd->dir = SNDRV_PCM_STREAM_CAPTURE;
prtd->capture_substream = substream;
}
ret = snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&constraints_sample_rates);
if (ret < 0)
goto out;
/* Ensure that buffer size is a multiple of period size */
ret = snd_pcm_hw_constraint_integer(runtime,
    SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
goto out;


ret = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
hw_rule_periodsize_by_rate, substream,
SNDRV_PCM_HW_PARAM_RATE, -1);

if (ret < 0)
goto out;

prtd->ops = &snd_msm_audio_ops;
prtd->out[0].used = BUF_INVALID_LEN;
prtd->out_head = 1; /* point to second buffer on startup */
runtime->private_data = prtd;

ret = alsa_adsp_configure(prtd);
if (ret)
goto out;
copy_count = 0;
return 0;

out:
kfree(prtd);
return ret;
}

Unfortunately it doesn't seem to print the REMOVE_THAT debug messages in
dmesg,after playing something with mplayer, like a 44100 Hz song in mp3
format with mplayer.

I wonder why the hw_rule_periodsize_by_rate function is not executed.

Background:
The htcdream is the first android smartphone and has by default a dsp
interface that is not alsa nor oss nor something that was created
before.
Codeaurora(qualcomm) had some alsa driver,I rebased it  but it was
buggy,so I tried to debug it and succedded at making mplayer run,but it
had many buffer underruns...

Denis.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: possible fix for buffer underruns on msm7k alsa driver
  2010-08-14 18:29 possible fix for buffer underruns on msm7k alsa driver Denis 'GNUtoo' Carikli
@ 2010-08-15 11:29 ` Mark Brown
  2010-08-15 17:58   ` Denis 'GNUtoo' Carikli
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2010-08-15 11:29 UTC (permalink / raw)
  To: Denis 'GNUtoo' Carikli; +Cc: alsa-devel

On Sat, Aug 14, 2010 at 08:29:44PM +0200, Denis 'GNUtoo' Carikli wrote:
> hi, I'm still rebasing the codeaurora alsa driver for msm soc like the
> htcdream on the android msm 2.6.32 kernel.
> I looked the commits for the other socs like msm7kv2 and
> qsd8k(snapdragon)

Your mail is very lengthy and something seems to have stripped all the
indentation from the source code you've pasted.  This all makes it
extremely hard to read, and the fact that it's discussing drivers which
have never been sent upstream doesn't help either.

The last time I looked at MSM audio drivers I noticed several abuses of
APIs in there which make me concerned about the robustness of any
changes that one might make to the code.  I've no idea if this was the
same set of drivers as you are looking at, it's really unfortunate that
work on these drivers appears so fragmented.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: possible fix for buffer underruns on msm7k alsa driver
  2010-08-15 11:29 ` Mark Brown
@ 2010-08-15 17:58   ` Denis 'GNUtoo' Carikli
  2010-08-15 18:08     ` [PATCH 1/4] sound: soc: msm7k: add mmap interface Denis 'GNUtoo' Carikli
                       ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Denis 'GNUtoo' Carikli @ 2010-08-15 17:58 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel


>Your mail is very lengthy and something seems to have stripped all the
>indentation from the source code you've pasted.  This all makes it
>extremely hard to read, and the fact that it's discussing drivers which
>have never been sent upstream doesn't help either.
>
>The last time I looked at MSM audio drivers I noticed several abuses of
>APIs in there which make me concerned about the robustness of any
>changes that one might make to the code.  I've no idea if this was the
>same set of drivers as you are looking at, it's really unfortunate that
>work on these drivers appears so fragmented.

The reference code source is at:
http://gitorious.org/htc-msm-2-6-32/leviathan-incoming/trees/android-msm-2.6.32-rebase/sound/soc/msm

And the audio patch that I rebased were attached
The most important one is that one:
[PATCH 2/4] sound: soc: msm7k: improve buffer underrun issue

There are only 2 patches.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] sound: soc: msm7k: add mmap interface
  2010-08-15 17:58   ` Denis 'GNUtoo' Carikli
@ 2010-08-15 18:08     ` Denis 'GNUtoo' Carikli
  2010-08-15 18:08     ` [PATCH 2/4] sound: soc: msm7k: improve buffer underrun issue Denis 'GNUtoo' Carikli
  2010-08-15 19:55     ` possible fix for buffer underruns on msm7k alsa driver Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Denis 'GNUtoo' Carikli @ 2010-08-15 18:08 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Denis 'GNUtoo' Carikli

The mmap interface is a patch rebased from this msm7kv2 alsa driver patch:
 commit c25698fee4fbd82a325394263752cb8b843fcfdc
 Author: Asish Bhattacharya <asishb@qualcomm.com>
 Date:   Thu Jan 21 14:38:41 2010 +0530

     alsa: soc: MMAP capability to playback stream

     The current code supports playback non-mmap(copy) mode playback.
     Adding support to do mmap-mode playback.

     Signed-off-by: Asish Bhattacharya <asishb@qualcomm.com>
It is comming from git://codeaurora.org/kernel/msm.git

Note that this is still not usable,because the buffer underrun
  are a lot worse than with non-mmaped interface.
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
---
 sound/soc/msm/TODO        |    4 ++
 sound/soc/msm/msm-pcm.c   |    8 ++-
 sound/soc/msm/msm-pcm.h   |    7 ++-
 sound/soc/msm/msm7k-pcm.c |  110 ++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 117 insertions(+), 12 deletions(-)
 create mode 100644 sound/soc/msm/TODO

diff --git a/sound/soc/msm/TODO b/sound/soc/msm/TODO
new file mode 100644
index 0000000..87084ea
--- /dev/null
+++ b/sound/soc/msm/TODO
@@ -0,0 +1,4 @@
+ad4974853c00ac1b6ac388a2915d86c06a04447f
+87a86ea6bd2868d9e9b3113f366e7ca440ef6199
+35240ee6cc224db5c916b345ae7a23fbe9b1ade6
+3d02aeb5607c558dec70054a234b2f36007ea362
diff --git a/sound/soc/msm/msm-pcm.c b/sound/soc/msm/msm-pcm.c
index f90c778..23c2c55 100644
--- a/sound/soc/msm/msm-pcm.c
+++ b/sound/soc/msm/msm-pcm.c
@@ -47,8 +47,6 @@
 	msm_adsp_write(prtd->audrec, QDSP_uPAudRecCmdQueue, cmd, len)
 
 int intcnt;
-static int audio_dsp_send_buffer(struct msm_audio *prtd,
-			unsigned idx, unsigned len);
 
 struct audio_frame {
 	uint16_t count_low;
@@ -141,6 +139,9 @@ void alsa_dsp_event(void *data, unsigned id, uint16_t *msg)
 			if (prtd->ops->playback)
 				prtd->ops->playback(prtd);
 
+			if (prtd->mmap_flag)
+                                break;
+
 			spin_lock_irqsave(&the_locks.write_dsp_lock, flag);
 			if (prtd->running) {
 				prtd->out[idx].used = 0;
@@ -631,7 +632,7 @@ int alsa_buffer_read(struct msm_audio *prtd, void __user *buf,
 }
 EXPORT_SYMBOL(alsa_buffer_read);
 
-static int audio_dsp_send_buffer(struct msm_audio *prtd,
+int audio_dsp_send_buffer(struct msm_audio *prtd,
 					unsigned idx, unsigned len)
 {
 	audpp_cmd_pcm_intf_send_buffer cmd;
@@ -645,6 +646,7 @@ static int audio_dsp_send_buffer(struct msm_audio *prtd,
 	return audpp_send_queue2(&cmd, sizeof(cmd));
 }
 
+
 int alsa_rec_dsp_enable(struct msm_audio *prtd, int enable)
 {
 	audrec_cmd_cfg cmd;
diff --git a/sound/soc/msm/msm-pcm.h b/sound/soc/msm/msm-pcm.h
index 9551bb0..62651a7 100644
--- a/sound/soc/msm/msm-pcm.h
+++ b/sound/soc/msm/msm-pcm.h
@@ -52,8 +52,7 @@
 			(SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
 #define USE_RATE_MIN            8000
 #define USE_RATE_MAX            48000
-#define MAX_BUFFER_PLAYBACK_SIZE \
-				(4800*4)
+#define MAX_BUFFER_PLAYBACK_SIZE PLAYBACK_DMASZ
 /* 2048 frames (Mono), 1024 frames (Stereo) */
 #define CAPTURE_SIZE		4096
 #define MAX_BUFFER_CAPTURE_SIZE (4096*4)
@@ -174,6 +173,8 @@ struct msm_audio {
 	int running;
 	int stopped; /* set when stopped, cleared on flush */
 	int eos_ack;
+        int mmap_flag;
+        int period;
 };
 
 
@@ -193,6 +194,8 @@ extern int alsa_audio_disable(struct msm_audio *prtd);
 extern int alsa_adsp_configure(struct msm_audio *prtd);
 extern int alsa_buffer_read(struct msm_audio *prtd, void __user *buf,
 					size_t count, loff_t *pos);
+extern int audio_dsp_send_buffer(struct msm_audio *prtd,
+			unsigned idx, unsigned len);
 ssize_t alsa_send_buffer(struct msm_audio *prtd, const char __user *buf,
 					size_t count, loff_t *pos, int copy_count);
 int msm_audio_volume_update(unsigned id,
diff --git a/sound/soc/msm/msm7k-pcm.c b/sound/soc/msm/msm7k-pcm.c
index c366902..9561e91 100644
--- a/sound/soc/msm/msm7k-pcm.c
+++ b/sound/soc/msm/msm7k-pcm.c
@@ -108,7 +108,9 @@ static unsigned convert_samp_rate(unsigned hz)
 }
 
 static struct snd_pcm_hardware msm_pcm_playback_hardware = {
-	.info =                 SNDRV_PCM_INFO_INTERLEAVED,
+	.info =                 SNDRV_PCM_INFO_MMAP |
+	                        SNDRV_PCM_INFO_MMAP_VALID |
+                                SNDRV_PCM_INFO_INTERLEAVED,
 	.formats =              USE_FORMATS,
 	.rates =                USE_RATE,
 	.rate_min =             USE_RATE_MIN,
@@ -150,10 +152,35 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
 	.mask = 0,
 };
 
+static void msm_pcm_enqueue_data(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_audio *prtd = runtime->private_data;
+	unsigned int period_size;
+
+	period_size = snd_pcm_lib_period_bytes(substream);
+	audio_dsp_send_buffer(prtd, prtd->out_tail, period_size);
+	prtd->out_tail ^= 1;
+	++copy_count;
+	prtd->period++;
+	if (unlikely(prtd->period >= runtime->periods))
+		prtd->period = 0;
+
+}
+
+
 static void playback_event_handler(void *data)
 {
 	struct msm_audio *prtd = data;
 	snd_pcm_period_elapsed(prtd->playback_substream);
+	if (prtd->mmap_flag) {
+		if (prtd->dir == SNDRV_PCM_STREAM_CAPTURE)
+			return;
+		if (!prtd->stopped)
+			msm_pcm_enqueue_data(prtd->playback_substream);
+		else
+			prtd->out_needed++;
+	}
 }
 
 static void capture_event_handler(void *data)
@@ -171,10 +198,30 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
 	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
 	prtd->pcm_irq_pos = 0;
 	prtd->pcm_buf_pos = 0;
+	if (prtd->enabled)
+		return 0;
 
 	/* rate and channels are sent to audio driver */
 	prtd->out_sample_rate = runtime->rate;
 	prtd->out_channel_mode = runtime->channels;
+	/* prtd->data = prtd->substream->dma_buffer.area; */
+	/* prtd->phys = prtd->substream->dma_buffer.addr; */
+	/* prtd->out[0].data = prtd->data + 0; */
+	/* prtd->out[0].addr = prtd->phys + 0; */
+	/* prtd->out[0].size = BUFSZ; */
+	/* prtd->out[1].data = prtd->data + BUFSZ; */
+	/* prtd->out[1].addr = prtd->phys + BUFSZ; */
+	/* prtd->out[1].size = BUFSZ; */
+
+	if (prtd->enabled | !(prtd->mmap_flag))
+		return 0;
+
+	prtd->out[0].used = prtd->pcm_count;
+	prtd->out[1].used = prtd->pcm_count;
+
+	mutex_lock(&the_locks.lock);
+	alsa_audio_configure(prtd);
+	mutex_unlock(&the_locks.lock);
 
 	return 0;
 }
@@ -230,19 +277,56 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
 
 static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_audio *prtd = runtime->private_data;
+	unsigned long flag = 0;
 	int ret = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			|| !prtd->mmap_flag)
+			break;
+		if (!prtd->out_needed) {
+			prtd->stopped = 0;
+			break;
+		}
+		spin_lock_irqsave(&the_locks.write_dsp_lock, flag);
+		if (prtd->running == 1) {
+			if (prtd->stopped == 1) {
+				prtd->stopped = 0;
+				prtd->period = 0;
+				if (prtd->pcm_irq_pos == 0) {
+					prtd->out_tail = 0;
+					msm_pcm_enqueue_data(prtd->playback_substream);
+					prtd->out_needed--;
+				} else {
+					prtd->out_tail = 1;
+					msm_pcm_enqueue_data(prtd->playback_substream);
+					prtd->out_needed--;
+				}
+				if (prtd->out_needed) {
+					prtd->out_tail ^= 1;
+					msm_pcm_enqueue_data(prtd->playback_substream);
+					prtd->out_needed--;
+				}
+			}
+		}
+		spin_unlock_irqrestore(&the_locks.write_dsp_lock, flag);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+                if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+                        || !prtd->mmap_flag)
+			break;
+		prtd->stopped = 1;
 		break;
 	default:
 		ret = -EINVAL;
+		break;
 	}
 
 	return ret;
@@ -463,16 +547,27 @@ static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
 int msm_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
-
-	if (substream->pcm->device & 1) {
-		runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
-		runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
-	}
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 	return 0;
 
 }
 
+int msm_pcm_mmap(struct snd_pcm_substream *substream,
+				struct vm_area_struct *vma)
+ {
+        struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_audio *prtd = runtime->private_data;
+
+	prtd->out_head = 0; /* point to First buffer on startup */
+	prtd->mmap_flag = 1;
+	runtime->dma_bytes = snd_pcm_lib_period_bytes(substream)*2;
+	dma_mmap_coherent(substream->pcm->card->dev, vma,
+				     runtime->dma_area,
+				     runtime->dma_addr,
+				     runtime->dma_bytes);
+	return 0;
+}
+
 static struct snd_pcm_ops msm_pcm_ops = {
 	.open           = msm_pcm_open,
 	.copy		= msm_pcm_copy,
@@ -483,6 +578,7 @@ static struct snd_pcm_ops msm_pcm_ops = {
 	.prepare        = msm_pcm_prepare,
 	.trigger        = msm_pcm_trigger,
 	.pointer        = msm_pcm_pointer,
+	.mmap           = msm_pcm_mmap,
 };
 
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] sound: soc: msm7k: improve buffer underrun issue
  2010-08-15 17:58   ` Denis 'GNUtoo' Carikli
  2010-08-15 18:08     ` [PATCH 1/4] sound: soc: msm7k: add mmap interface Denis 'GNUtoo' Carikli
@ 2010-08-15 18:08     ` Denis 'GNUtoo' Carikli
  2010-08-15 19:55     ` possible fix for buffer underruns on msm7k alsa driver Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Denis 'GNUtoo' Carikli @ 2010-08-15 18:08 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Denis 'GNUtoo' Carikli

This commit is a rebase of the following patch:
 commit ac97ef246a754b9a2b4236ca08c6ade389dc206f
 Author: Pradeep Jilagam <pjilagam@qualcomm.com>
 Date:   Wed Apr 7 17:38:20 2010 +0530

     alsa: 8k: Limit period size for sample rates greater than 8KHz

     The DSP interrupts are non-periodic. ALSA expects periodic
     acknowledgement for the buffers sent. Hence, the alsa driver uses
     timer as alternate interrupt source. The min resolution is 10ms
     which results in distorted audio for some sample rates. Hence
     restricting the minimum period size for sample rates greater
     than 8KHz to 512 frames.

     Change-Id: Ic8c4180fbee7242fa3139230ddcf6a9f98e4c7ab
     CRs-fixed: 231784
     Signed-off-by: Pradeep Jilagam <pjilagam@qualcomm.com>
>From git://codeaurora.org/kernel/msm.git
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
---
 sound/soc/msm/file        |   61 +++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/msm/msm7k-pcm.c |   38 +++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 1 deletions(-)
 create mode 100644 sound/soc/msm/file

diff --git a/sound/soc/msm/file b/sound/soc/msm/file
new file mode 100644
index 0000000..8c62299
--- /dev/null
+++ b/sound/soc/msm/file
@@ -0,0 +1,61 @@
+diff --git a/sound/soc/msm/msm7k-pcm.c b/sound/soc/msm/msm7k-pcm.c
+index 9561e91..2d90797 100644
+--- a/sound/soc/msm/msm7k-pcm.c
++++ b/sound/soc/msm/msm7k-pcm.c
+@@ -31,6 +31,7 @@
+ #include <sound/soc.h>
+ #include <sound/soc-dapm.h>
+ #include <sound/pcm.h>
++#include <sound/pcm_params.h>
+ #include <sound/initval.h>
+ #include <sound/control.h>
+ #include <asm/dma.h>
+@@ -398,6 +399,32 @@ struct  msm_audio_event_callbacks snd_msm_audio_ops = {
+ 	.capture = capture_event_handler,
+ };
+ 
++static int hw_rule_periodsize_by_rate(struct snd_pcm_hw_params *params,
++					struct snd_pcm_hw_rule *rule)
++{
++	struct snd_interval *ps = hw_param_interval(params,
++						SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
++	struct snd_interval *r = hw_param_interval(params,
++						SNDRV_PCM_HW_PARAM_RATE);
++	struct snd_interval ch;
++
++	if (!ps || !r){
++		pr_debug("REMOVE_THAT: exiting from !ps||!r\n");
++		return 0;
++	}else{
++		pr_debug("REMOVE_THAT: not exiting\n");
++	}
++	snd_interval_any(&ch);
++
++	if (r->min > 8000) {
++		ch.min = 512;
++		pr_debug("Minimum period size is adjusted to 512\n");
++		return snd_interval_refine(ps, &ch);
++	}
++	return 0;
++}
++
++
+ static int msm_pcm_open(struct snd_pcm_substream *substream)
+ {
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
+@@ -431,6 +458,15 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
+ 	if (ret < 0)
+ 		goto out;
+ 
++
++	ret = snd_pcm_hw_rule_add(substream->runtime, 0,
++			SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
++			hw_rule_periodsize_by_rate, substream,
++			SNDRV_PCM_HW_PARAM_RATE, -1);
++
++	if (ret < 0)
++		goto out;
++
+ 	prtd->ops = &snd_msm_audio_ops;
+ 	prtd->out[0].used = BUF_INVALID_LEN;
+ 	prtd->out_head = 1; /* point to second buffer on startup */
diff --git a/sound/soc/msm/msm7k-pcm.c b/sound/soc/msm/msm7k-pcm.c
index 9561e91..fc6c7fc 100644
--- a/sound/soc/msm/msm7k-pcm.c
+++ b/sound/soc/msm/msm7k-pcm.c
@@ -1,6 +1,6 @@
 /* linux/sound/soc/msm/msm7k-pcm.c
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
@@ -31,6 +31,7 @@
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/pcm.h>
+#include <sound/pcm_params.h>
 #include <sound/initval.h>
 #include <sound/control.h>
 #include <asm/dma.h>
@@ -398,6 +399,32 @@ struct  msm_audio_event_callbacks snd_msm_audio_ops = {
 	.capture = capture_event_handler,
 };
 
+static int hw_rule_periodsize_by_rate(struct snd_pcm_hw_params *params,
+					struct snd_pcm_hw_rule *rule)
+{
+	struct snd_interval *ps = hw_param_interval(params,
+						SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+	struct snd_interval *r = hw_param_interval(params,
+						SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval ch;
+
+	if (!ps || !r){
+		pr_debug("REMOVE_THAT: exiting from !ps||!r\n");
+		return 0;
+	}else{
+		pr_debug("REMOVE_THAT: not exiting\n");
+	}
+	snd_interval_any(&ch);
+
+	if (r->min > 8000) {
+		ch.min = 512;
+		pr_debug("Minimum period size is adjusted to 512\n");
+		return snd_interval_refine(ps, &ch);
+	}
+	return 0;
+}
+
+
 static int msm_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -431,6 +458,15 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
 	if (ret < 0)
 		goto out;
 
+
+	ret = snd_pcm_hw_rule_add(substream->runtime, 0,
+			SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+			hw_rule_periodsize_by_rate, substream,
+			SNDRV_PCM_HW_PARAM_RATE, -1);
+
+	if (ret < 0)
+		goto out;
+
 	prtd->ops = &snd_msm_audio_ops;
 	prtd->out[0].used = BUF_INVALID_LEN;
 	prtd->out_head = 1; /* point to second buffer on startup */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: possible fix for buffer underruns on msm7k alsa driver
  2010-08-15 17:58   ` Denis 'GNUtoo' Carikli
  2010-08-15 18:08     ` [PATCH 1/4] sound: soc: msm7k: add mmap interface Denis 'GNUtoo' Carikli
  2010-08-15 18:08     ` [PATCH 2/4] sound: soc: msm7k: improve buffer underrun issue Denis 'GNUtoo' Carikli
@ 2010-08-15 19:55     ` Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2010-08-15 19:55 UTC (permalink / raw)
  To: Denis 'GNUtoo' Carikli; +Cc: alsa-devel

On Sun, Aug 15, 2010 at 07:58:01PM +0200, Denis 'GNUtoo' Carikli wrote:

> >The last time I looked at MSM audio drivers I noticed several abuses of
> >APIs in there which make me concerned about the robustness of any
> >changes that one might make to the code.  I've no idea if this was the
> >same set of drivers as you are looking at, it's really unfortunate that
> >work on these drivers appears so fragmented.

> The reference code source is at:
> http://gitorious.org/htc-msm-2-6-32/leviathan-incoming/trees/android-msm-2.6.32-rebase/sound/soc/msm

That looks roughly like the problematic code I mentioned above.

> And the audio patch that I rebased were attached
> The most important one is that one:
> [PATCH 2/4] sound: soc: msm7k: improve buffer underrun issue

> There are only 2 patches.

Sorry, I'm a bit lost as to what the actual question is here?

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-08-15 19:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-14 18:29 possible fix for buffer underruns on msm7k alsa driver Denis 'GNUtoo' Carikli
2010-08-15 11:29 ` Mark Brown
2010-08-15 17:58   ` Denis 'GNUtoo' Carikli
2010-08-15 18:08     ` [PATCH 1/4] sound: soc: msm7k: add mmap interface Denis 'GNUtoo' Carikli
2010-08-15 18:08     ` [PATCH 2/4] sound: soc: msm7k: improve buffer underrun issue Denis 'GNUtoo' Carikli
2010-08-15 19:55     ` possible fix for buffer underruns on msm7k alsa driver Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.