Skip to contentSkip to conversation

tm6000-alsa: rework audio buffer allocation/deallocation

PATCH New Mauro Carvalho Chehab 1 participant 6 messages Jun 5, 2010 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#3 lore raw

PATCH 3/6 tm6000-alsa: rework audio buffer allocation/deallocation

In reply to a message not in the archive
drivers/staging/tm6000/tm6000-alsa.c +32 -27
index 8520434..ca9aec5 100644
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
+#include <linux/vmalloc.h>
 
 #include <asm/delay.h>
 #include <sound/core.h>
@@ -105,19 +106,39 @@ static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
 	return 0;
 }
 
-static int dsp_buffer_free(struct snd_tm6000_card *chip)
+static void dsp_buffer_free(struct snd_pcm_substream *substream)
 {
-	BUG_ON(!chip->bufsize);
+	struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
 
 	dprintk(2, "Freeing buffer\n");
 
-	/* FIXME: Frees buffer */
+	vfree(substream->runtime->dma_area);
+	substream->runtime->dma_area = NULL;
+	substream->runtime->dma_bytes = 0;
+}
+
+static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size)
+{
+	struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
+
+	dprintk(2, "Allocating buffer\n");
 
-	chip->bufsize = 0;
+	if (substream->runtime->dma_area) {
+		if (substream->runtime->dma_bytes > size)
+			return 0;
+		dsp_buffer_free(substream);
+	}
 
-       return 0;
+	substream->runtime->dma_area = vmalloc(size);
+	if (!substream->runtime->dma_area)
+		return -ENOMEM;
+
+	substream->runtime->dma_bytes = size;
+
+	return 0;
 }
 
+
 /****************************************************************************
 				ALSA PCM Interface
  ****************************************************************************/
@@ -184,23 +205,13 @@ static int snd_tm6000_close(struct snd_pcm_substream *substream)
 static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
 			      struct snd_pcm_hw_params *hw_params)
 {
-	struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
+	int size, rc;
 
-	if (substream->runtime->dma_area) {
-		dsp_buffer_free(chip);
-		substream->runtime->dma_area = NULL;
-	}
-
-	chip->period_size = params_period_bytes(hw_params);
-	chip->num_periods = params_periods(hw_params);
-	chip->bufsize = chip->period_size * params_periods(hw_params);
-
-	BUG_ON(!chip->bufsize);
-
-	dprintk(1, "Setting buffer\n");
-
-	/* FIXME: Allocate buffer for audio */
+	size = params_period_bytes(hw_params) * params_periods(hw_params);
 
+	rc = dsp_buffer_alloc(substream, size);
+	if (rc < 0)
+		return rc;
 
 	return 0;
 }
@@ -210,13 +221,7 @@ static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
  */
 static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
 {
-
-	struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
-	if (substream->runtime->dma_area) {
-		dsp_buffer_free(chip);
-		substream->runtime->dma_area = NULL;
-	}
+	dsp_buffer_free(substream);
 
 	return 0;
 }
drivers/staging/tm6000/tm6000.h +0 -4
index 18d1e51..a1d96d6 100644
@@ -136,11 +136,7 @@ struct snd_tm6000_card {
 	struct snd_card			*card;
 	spinlock_t			reg_lock;
 	atomic_t			count;
-	unsigned int			period_size;
-	unsigned int			num_periods;
 	struct tm6000_core		*core;
-	struct tm6000_buffer		*buf;
-	int				bufsize;
 	struct snd_pcm_substream	*substream;
 };
 
Signature · 1 line
1.7.1
#1 lore raw

PATCH 1/6 tm6000: Fix compilation breakages

In reply to a message not in the archive

A previous patch seemed to break compilation of the driver.

 mode change 100644 => 100755 Documentation/video4linux/extract_xc3028.pl
Documentation/video4linux/extract_xc3028.pl +0 -0
old mode 100644
new mode 100755
drivers/staging/tm6000/tm6000-cards.c +0 -1
index 4a8c659..50756e5 100644
@@ -683,7 +683,6 @@ static int tm6000_init_dev(struct tm6000_core *dev)
 	tm6000_add_into_devlist(dev);
 	tm6000_init_extension(dev);
 
-	}
 	mutex_unlock(&dev->lock);
 	return 0;
 
drivers/staging/tm6000/tm6000-core.c +1 -2
index 2fbf4f6..1f2765c 100644
@@ -295,7 +295,6 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
 			tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
 		else	/* Enable Hfilter and disable TS Drop err */
 			tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
-		}
 
 		tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
 		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23);
@@ -401,7 +400,7 @@ int tm6000_init_digital_mode(struct tm6000_core *dev)
 
 	return 0;
 }
-EXPORT_SYMBOL(tm6000_init_digial_mode);
+EXPORT_SYMBOL(tm6000_init_digital_mode);
 
 struct reg_init {
 	u8 req;
drivers/staging/tm6000/tm6000-dvb.c +5 -5
index 3ccc466..5ee1aff 100644
@@ -38,7 +38,7 @@ MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
 			"{{Trident, tm6000},"
 			"{{Trident, tm6010}");
 
-static int debug
+static int debug;
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable debug message");
@@ -191,7 +191,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
 		dvb->streams = 1;
 /*		mutex_init(&tm6000_dev->streming_mutex); */
 		tm6000_start_stream(dev);
-	} else {
+	} else
 		++(dvb->streams);
 	mutex_unlock(&dvb->mutex);
 
@@ -227,7 +227,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
 
 	if (dev->caps.has_zl10353) {
 		struct zl10353_config config = {
-				     demod_address = dev->demod_addr,
+				     .demod_address = dev->demod_addr,
 				     .no_tuner = 1,
 				     .parallel_ts = 1,
 				     .if2 = 45700,
@@ -390,7 +390,7 @@ static int dvb_init(struct tm6000_core *dev)
 	int rc;
 
 	if (!dev)
-		retrun 0;
+		return 0;
 
 	if (!dev->caps.has_dvb)
 		return 0;
@@ -427,7 +427,7 @@ static int dvb_fini(struct tm6000_core *dev)
 		dev->dvb = NULL;
 	}
 
-	retrun 0;
+	return 0;
 }
 
 static struct tm6000_ops dvb_ops = {
drivers/staging/tm6000/tm6000.h +0 -3
index 4b65094..18d1e51 100644
@@ -269,9 +269,6 @@ int tm6000_init_analog_mode(struct tm6000_core *dev);
 int tm6000_init_digital_mode(struct tm6000_core *dev);
 int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
 
-int tm6000_dvb_register(struct tm6000_core *dev);
-void tm6000_dvb_unregister(struct tm6000_core *dev);
-
 int tm6000_v4l2_register(struct tm6000_core *dev);
 int tm6000_v4l2_unregister(struct tm6000_core *dev);
 int tm6000_v4l2_exit(void);
Signature · 1 line
1.7.1
#2 lore raw

PATCH 2/6 tm6000: Avoid OOPS when loading tm6000-alsa module

In reply to a message not in the archive
drivers/staging/tm6000/tm6000-alsa.c +2 -2
index 55a0925..8520434 100644
@@ -39,7 +39,7 @@
  ****************************************************************************/
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
+
 static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
 
 module_param_array(enable, bool, NULL, 0444);
@@ -316,7 +316,7 @@ int tm6000_audio_init(struct tm6000_core *dev)
 	if (!enable[devnr])
 		return -ENOENT;
 
-	rc = snd_card_create(index[devnr], id[devnr], THIS_MODULE, 0, &card);
+	rc = snd_card_create(index[devnr], "tm6000", THIS_MODULE, 0, &card);
 	if (rc < 0) {
 		snd_printk(KERN_ERR "cannot create card instance %d\n", devnr);
 		return rc;
Signature · 1 line
1.7.1
#6 lore raw

PATCH 6/6 tm6000: avoid unknown symbol tm6000_debug

In reply to a message not in the archive

Reported by Stefan Ringel.

Thanks-to: Stefan Ringel <[email protected]>

drivers/staging/tm6000/tm6000-video.c +1 -0
index c0d6f6a..34e8ef5 100644
@@ -56,6 +56,7 @@ static int video_nr = -1;		/* /dev/videoN, -1 for autodetect */
 
 /* Debug level */
 int tm6000_debug;
+EXPORT_SYMBOL_GPL(tm6000_debug);
 
 /* supported controls */
 static struct v4l2_queryctrl tm6000_qctrl[] = {
Signature · 1 line
1.7.1
#5 lore raw

PATCH 5/6 tm6000: Add a callback code for buffer fill

In reply to a message not in the archive

Implements a callback to be used by tm6000-alsa, in order to allow filling audio data packets.

drivers/staging/tm6000/tm6000-alsa.c +16 -0
index db1eef9..e71579e 100644
@@ -199,6 +199,21 @@ static int snd_tm6000_close(struct snd_pcm_substream *substream)
 	return 0;
 }
 
+static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size)
+{
+	int i;
+
+	/* Need to add a real code to copy audio buffer */
+	printk("Audio (%i bytes): ", size);
+	for (i = 0; i < size - 3; i +=4)
+		printk("(0x%04x, 0x%04x), ",
+			*(u16 *)(buf + i), *(u16 *)(buf + i + 2));
+
+	printk("\n");
+
+	return 0;
+}
+
 /*
  * hw_params callback
  */
@@ -395,6 +410,7 @@ struct tm6000_ops audio_ops = {
 	.name	= "TM6000 Audio Extension",
 	.init	= tm6000_audio_init,
 	.fini	= tm6000_audio_fini,
+	.fillbuf = tm6000_fillbuf,
 };
 
 static int __init tm6000_alsa_register(void)
drivers/staging/tm6000/tm6000-core.c +17 -0
index 1f2765c..626b85e 100644
@@ -652,6 +652,23 @@ void tm6000_add_into_devlist(struct tm6000_core *dev)
 static LIST_HEAD(tm6000_extension_devlist);
 static DEFINE_MUTEX(tm6000_extension_devlist_lock);
 
+int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
+			char *buf, int size)
+{
+	struct tm6000_ops *ops = NULL;
+
+	/* FIXME: tm6000_extension_devlist_lock should be a spinlock */
+
+	if (!list_empty(&tm6000_extension_devlist)) {
+		list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+			if (ops->fillbuf && ops->type == type)
+				ops->fillbuf(dev, buf, size);
+		}
+	}
+
+	return 0;
+}
+
 int tm6000_register_extension(struct tm6000_ops *ops)
 {
 	struct tm6000_core *dev = NULL;
drivers/staging/tm6000/tm6000-video.c +1 -1
index 1e348ac..c0d6f6a 100644
@@ -301,7 +301,7 @@ static int copy_streams(u8 *data, unsigned long len,
 					memcpy (&voutp[pos], ptr, cpysize);
 				break;
 			case TM6000_URB_MSG_AUDIO:
-				/* Need some code to copy audio buffer */
+				tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
 				break;
 			case TM6000_URB_MSG_VBI:
 				/* Need some code to copy vbi buffer */
drivers/staging/tm6000/tm6000.h +4 -0
index 8fccf3e..db99959 100644
@@ -229,6 +229,7 @@ struct tm6000_ops {
 	enum tm6000_ops_type	type;
 	int (*init)(struct tm6000_core *);
 	int (*fini)(struct tm6000_core *);
+	int (*fillbuf)(struct tm6000_core *, char *buf, int size);
 };
 
 struct tm6000_fh {
@@ -278,6 +279,9 @@ int tm6000_register_extension(struct tm6000_ops *ops);
 void tm6000_unregister_extension(struct tm6000_ops *ops);
 void tm6000_init_extension(struct tm6000_core *dev);
 void tm6000_close_extension(struct tm6000_core *dev);
+int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
+			char *buf, int size);
+
 
 /* In tm6000-stds.c */
 void tm6000_get_std_res(struct tm6000_core *dev);
Signature · 1 line
1.7.1
#4 lore raw

PATCH 4/6 tm6000: Use an emum for extension type

In reply to a message not in the archive

In order to better document and be sure that the values are used at the proper places, convert extension type into an enum and name it as "type", instead of "id".

drivers/staging/tm6000/tm6000-alsa.c +1 -1
index ca9aec5..db1eef9 100644
@@ -391,7 +391,7 @@ static int tm6000_audio_fini(struct tm6000_core *dev)
 }
 
 struct tm6000_ops audio_ops = {
-	.id	= TM6000_AUDIO,
+	.type	= TM6000_AUDIO,
 	.name	= "TM6000 Audio Extension",
 	.init	= tm6000_audio_init,
 	.fini	= tm6000_audio_fini,
drivers/staging/tm6000/tm6000-dvb.c +1 -1
index 5ee1aff..ff9cc6d 100644
@@ -431,7 +431,7 @@ static int dvb_fini(struct tm6000_core *dev)
 }
 
 static struct tm6000_ops dvb_ops = {
-	.id	= TM6000_DVB,
+	.type	= TM6000_DVB,
 	.name	= "TM6000 dvb Extension",
 	.init	= dvb_init,
 	.fini	= dvb_fini,
drivers/staging/tm6000/tm6000.h +5 -3
index a1d96d6..8fccf3e 100644
@@ -218,13 +218,15 @@ struct tm6000_core {
 	spinlock_t                   slock;
 };
 
-#define TM6000_AUDIO 0x10
-#define TM6000_DVB	0x20
+enum tm6000_ops_type {
+	TM6000_AUDIO = 0x10,
+	TM6000_DVB = 0x20,
+};
 
 struct tm6000_ops {
 	struct list_head	next;
 	char			*name;
-	int			id;
+	enum tm6000_ops_type	type;
 	int (*init)(struct tm6000_core *);
 	int (*fini)(struct tm6000_core *);
 };
Signature · 1 line
1.7.1