[alsa-devel] [PATCH] alsa: lx6464es - initialization fixes

Tim Blechmann tim at klingt.org
Mon Jul 25 20:34:56 CEST 2011


this using this fix, the driver is usable with non-rt kernels. the card
initialization is moved from the prepare to the hw_params callback. also
the error handling is improved.

Signed-off-by: Tim Blechmann <tim at klingt.org>
---
 sound/pci/lx6464es/lx6464es.c |   72 +++++++++++++++++++++--------------------
 sound/pci/lx6464es/lx6464es.h |    1 +
 sound/pci/lx6464es/lx_core.c  |   43 +++++++++++++++----------
 sound/pci/lx6464es/lx_core.h  |    3 +-
 4 files changed, 66 insertions(+), 53 deletions(-)

diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 1bd7a54..722212e 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -103,16 +103,14 @@ static int lx_set_granularity(struct lx6464es *chip, u32 gran);
 
 
 static int lx_hardware_open(struct lx6464es *chip,
-			    struct snd_pcm_substream *substream)
+			    struct snd_pcm_substream *substream,
+			    int channels, snd_pcm_uframes_t period_size)
 {
 	int err = 0;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	int channels = runtime->channels;
 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 
-	snd_pcm_uframes_t period_size = runtime->period_size;
-
-	snd_printd(LXP "allocating pipe for %d channels\n", channels);
+	snd_printk(LXP "allocating pipe for %d channels, %lu period size\n",
+		   channels, period_size);
 	err = lx_pipe_allocate(chip, 0, is_capture, channels);
 	if (err < 0) {
 		snd_printk(KERN_ERR LXP "allocating pipe failed\n");
@@ -130,14 +128,14 @@ static int lx_hardware_open(struct lx6464es *chip,
 }
 
 static int lx_hardware_start(struct lx6464es *chip,
-			     struct snd_pcm_substream *substream)
+			     struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *hw_params)
 {
 	int err = 0;
-	struct snd_pcm_runtime *runtime = substream->runtime;
 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 
 	snd_printd(LXP "setting stream format\n");
-	err = lx_stream_set_format(chip, runtime, 0, is_capture);
+	err = lx_stream_set_format(chip, hw_params, 0, is_capture);
 	if (err < 0) {
 		snd_printk(KERN_ERR LXP "setting stream format failed\n");
 		return err;
@@ -295,13 +293,33 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
 	return pos;
 }
 
+
 static int lx_pcm_prepare(struct snd_pcm_substream *substream)
 {
 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
 	int err = 0;
-	const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 
-	snd_printdd("->lx_pcm_prepare\n");
+	snd_printd("->lx_pcm_prepare %d\n", is_capture);
+
+	mutex_lock(&chip->setup_mutex);
+
+	if (chip->board_sample_rate != substream->runtime->rate) {
+		if (!err)
+			chip->board_sample_rate = substream->runtime->rate;
+	}
+
+	mutex_unlock(&chip->setup_mutex);
+	snd_printd("<-lx_pcm_prepare\n");
+	return err;
+}
+
+static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *hw_params, int is_capture)
+{
+	struct lx6464es *chip = snd_pcm_substream_chip(substream);
+	int err = 0;
+
+	snd_printd("->lx_pcm_hw_params\n");
 
 	mutex_lock(&chip->setup_mutex);
 
@@ -322,14 +340,16 @@ static int lx_pcm_prepare(struct snd_pcm_substream *substream)
 	}
 
 	snd_printd(LXP "opening hardware\n");
-	err = lx_hardware_open(chip, substream);
+	err = lx_hardware_open(chip, substream,
+			       params_channels(hw_params),
+			       params_period_size(hw_params));
 	if (err < 0) {
 		snd_printk(KERN_ERR LXP "failed to open hardware. "
 			   "Error code %d\n", err);
 		goto exit;
 	}
 
-	err = lx_hardware_start(chip, substream);
+	err = lx_hardware_start(chip, substream, hw_params);
 	if (err < 0) {
 		snd_printk(KERN_ERR LXP "failed to start hardware. "
 			   "Error code %d\n", err);
@@ -338,26 +358,6 @@ static int lx_pcm_prepare(struct snd_pcm_substream *substream)
 
 	chip->hardware_running[is_capture] = 1;
 
-	if (chip->board_sample_rate != substream->runtime->rate) {
-		if (!err)
-			chip->board_sample_rate = substream->runtime->rate;
-	}
-
-exit:
-	mutex_unlock(&chip->setup_mutex);
-	return err;
-}
-
-static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
-			    struct snd_pcm_hw_params *hw_params, int is_capture)
-{
-	struct lx6464es *chip = snd_pcm_substream_chip(substream);
-	int err = 0;
-
-	snd_printdd("->lx_pcm_hw_params\n");
-
-	mutex_lock(&chip->setup_mutex);
-
 	/* set dma buffer */
 	err = snd_pcm_lib_malloc_pages(substream,
 				       params_buffer_bytes(hw_params));
@@ -367,6 +367,7 @@ static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
 	else
 		chip->playback_stream.stream = substream;
 
+exit:
 	mutex_unlock(&chip->setup_mutex);
 	return err;
 }
@@ -389,7 +390,7 @@ static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
 	int err = 0;
 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 
-	snd_printdd("->lx_pcm_hw_free\n");
+	snd_printd("->lx_pcm_hw_free\n");
 	mutex_lock(&chip->setup_mutex);
 
 	if (chip->hardware_running[is_capture]) {
@@ -477,7 +478,7 @@ static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
 	int err;
 
 	snd_printd(LXP "stopping: stopping stream\n");
-	err = lx_stream_stop(chip, 0, is_capture);
+	err = lx_stream_pause(chip, 0, is_capture);
 	if (err < 0)
 		snd_printk(KERN_ERR LXP "couldn't stop stream\n");
 	else
@@ -1005,6 +1006,7 @@ static int __devinit snd_lx6464es_create(struct snd_card *card,
 	chip->card = card;
 	chip->pci = pci;
 	chip->irq = -1;
+	chip->hardware_running[0] = chip->hardware_running[1] = 0;
 
 	/* initialize synchronization structs */
 	spin_lock_init(&chip->lock);
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index aea621e..2a97a21 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -30,6 +30,7 @@
 
 #include <sound/core.h>
 #include <sound/pcm.h>
+#include <sound/pcm_params.h>
 
 #include "lx_core.h"
 
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 617f98b..3a9e1dd 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -353,8 +353,11 @@ polling_successful:
 			lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
 					   rmh->stat_len);
 		}
-	} else
+		lx_message_dump(rmh);
+	} else {
 		snd_printk(LXP "rmh error: %08x\n", reg);
+		dump_stack();
+	}
 
 	/* clear Reg_CSM_MR */
 	lx_dsp_reg_write(chip, eReg_CSM, 0);
@@ -362,15 +365,11 @@ polling_successful:
 	switch (reg) {
 	case ED_DSP_TIMED_OUT:
 		snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
-		return -ETIMEDOUT;
 
 	case ED_DSP_CRASHED:
 		snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
-		return -EAGAIN;
 	}
 
-	lx_message_dump(rmh);
-
 	return reg;
 }
 
@@ -532,10 +531,22 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
 	err = lx_message_send_atomic(chip, &chip->rmh);
 	spin_unlock_irqrestore(&chip->msg_lock, flags);
 
-	if (err != 0)
-		snd_printk(KERN_ERR "lx6464es: could not allocate pipe\n");
+	if (err == 0)
+		return 0;
 
-	return err;
+	switch (err) {
+	case EB_ALLOCATE_AUDIO_IMPOSSIBLE:
+		snd_printk(KERN_ERR "lx6464es: could not allocate pipe "
+			   "(EB_ALLOCATE_AUDIO_IMPOSSIBLE)\n");
+		break;
+
+	case EB_INVALID_AUDIO:
+		snd_printk(KERN_ERR "lx6464es: could not allocate pipe "
+			   "(EB_INVALID_AUDIO)\n");
+		break;
+	}
+
+	return -1;
 }
 
 int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture)
@@ -781,7 +792,8 @@ int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
 	return err;
 }
 
-int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
+int lx_stream_set_format(struct lx6464es *chip,
+			 struct snd_pcm_hw_params *params,
 			 u32 pipe, int is_capture)
 {
 	int err;
@@ -789,22 +801,19 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
 
 	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
 
-	u32 channels = runtime->channels;
-
-	if (runtime->channels != channels)
-		snd_printk(KERN_ERR LXP "channel count mismatch: %d vs %d",
-			   runtime->channels, channels);
+	const u32 channels = params_channels(params);
+	const snd_pcm_format_t format = params_format(params);
 
 	spin_lock_irqsave(&chip->msg_lock, flags);
 	lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);
 
 	chip->rmh.cmd[0] |= pipe_cmd;
 
-	if (runtime->sample_bits == 16)
+	if (snd_pcm_format_width(format) == 16)
 		/* 16 bit format */
 		chip->rmh.cmd[0] |= (STREAM_FMT_16b << STREAM_FMT_OFFSET);
 
-	if (snd_pcm_format_little_endian(runtime->format))
+	if (snd_pcm_format_little_endian(format))
 		/* little endian/intel format */
 		chip->rmh.cmd[0] |= (STREAM_FMT_intel << STREAM_FMT_OFFSET);
 
@@ -974,7 +983,7 @@ int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
 	chip->rmh.cmd[1] = (u32)(mute_mask >> (u64)32);	       /* hi part */
 	chip->rmh.cmd[2] = (u32)(mute_mask & (u64)0xFFFFFFFF); /* lo part */
 
-	snd_printk("mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1],
+	snd_printd("mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1],
 		   chip->rmh.cmd[2]);
 
 	err = lx_message_send_atomic(chip, &chip->rmh);
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h
index 6bd9cbb..378721a 100644
--- a/sound/pci/lx6464es/lx_core.h
+++ b/sound/pci/lx6464es/lx_core.h
@@ -134,7 +134,8 @@ int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture);
 int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture);
 
 /* low-level stream handling */
-int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
+int lx_stream_set_format(struct lx6464es *chip,
+			 struct snd_pcm_hw_params *runtime,
 			 u32 pipe, int is_capture);
 int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
 		    int *rstate);
-- 
1.7.4.1



More information about the Alsa-devel mailing list