From c13dd70411e87e1ad1ccca0ba9bc3cf0a555e5a0 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Date: Wed, 19 Sep 2007 07:36:34 -0300
Subject: [PATCH] V4L/DVB (12797): tm6000: Allow selecting audio bitrate

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/staging/tm6000/tm6000-core.c  |  2 ++
 drivers/staging/tm6000/tm6000-video.c | 37 +++++++++++++++++++--------
 drivers/staging/tm6000/tm6000.h       |  1 +
 3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 5497b7c4aea8..3f2727d5b957 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -722,9 +722,11 @@ printk("Original value=%d\n",val);
 	switch (bitrate) {
 	case 44100:
 		val|=0xd0;
+		dev->audio_bitrate=bitrate;
 		break;
 	case 48000:
 		val|=0x60;
+		dev->audio_bitrate=bitrate;
 		break;
 	}
 	val=tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, val);
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 65510d853814..ced4b478f6b1 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -566,8 +566,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev,
 		dev->isoc_ctl.urb[i] = urb;
 
 		dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev,
-			sb_size, GFP_KERNEL,
-			&dev->isoc_ctl.urb[i]->transfer_dma);
+			sb_size, GFP_KERNEL, &urb->transfer_dma);
 		if (!dev->isoc_ctl.transfer_buffer[i]) {
 			tm6000_err ("unable to allocate %i bytes for transfer"
 					" buffer %i\n", sb_size, i);
@@ -787,14 +786,32 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 		urb_init=1;
 
 	if (urb_init) {
-		/* Should allocate/request at least h
-		   res x v res x 2 bytes/pixel */
-		urbsize=(buf->vb.size+dev->max_isoc_in-1)/dev->max_isoc_in;
-
-		 /* Hack to allocate memory for Video + Audio */
-		/* FIXME: should also consider header ovehead of
-		   4 bytes/180 bytes */
-		urbsize+=((48000*4+24)/25+dev->max_isoc_in-1)/dev->max_isoc_in;
+		/* memory for video
+		   Should be at least
+		   Vres x Vres x 2 bytes/pixel by frame */
+		urbsize=buf->vb.size;
+
+		 /* memory for audio
+		    Should be at least
+		    bitrate * 2 channels * 2 bytes / frame rate */
+		if (dev->norm & V4L2_STD_525_60) {
+			urbsize+=(dev->audio_bitrate*4+29)/30;
+		} else {
+			urbsize+=(dev->audio_bitrate*4+24)/25;
+		}
+
+		/* each audio frame seeems to have a frame number
+		   with 2 bytes */
+		urbsize+=2;
+
+		/* Add 4 bytes by each 180 bytes frame */
+		urbsize+=((urbsize+179)/180)*4;
+
+		/* Round to an enough number of URBs */
+		urbsize=(urbsize+dev->max_isoc_in-1)/dev->max_isoc_in;
+
+
+printk("Allocating %d packets to handle %lu size\n",  urbsize,buf->vb.size);
 
 		dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d packets to handle "
 					"%lu size\n", urbsize,buf->vb.size);
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 479b4fb520dd..a5977e7ce51b 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -137,6 +137,7 @@ struct tm6000_core {
 	/* Demodulator configuration */
 	int				demod_addr;	/* demodulator address */
 
+	int				audio_bitrate;
 	/* i2c i/o */
 	struct i2c_adapter		i2c_adap;
 	struct i2c_client		i2c_client;
-- 
2.30.9