summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-06-04 15:38:12 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-06-04 15:38:12 -0700
commite620d1e39aa33b43bed96aa7f2ebbc88914aed58 (patch)
tree0e8a0c36430f10c1e490464f1d6524ce5612f614 /drivers/staging
parentd2dd328b7f7bc6cebe167648289337755944ad2a (diff)
parent666092c679f7d9eb9f5230087f960a487fda721c (diff)
downloadlinux-e620d1e39aa33b43bed96aa7f2ebbc88914aed58.tar.gz
linux-e620d1e39aa33b43bed96aa7f2ebbc88914aed58.tar.bz2
linux-e620d1e39aa33b43bed96aa7f2ebbc88914aed58.zip
Merge branch 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (87 commits) V4L/DVB: ivtv: Timing tweaks and code re-order to try and improve stability V4L/DVB: ivtv: Avoid accidental video standard change V4L/DVB: ivtvfb : Module load / unload fixes V4L/DVB: cx2341x: Report correct temporal setting for log-status V4L/DVB: cx18, cx23885, v4l2 doc, MAINTAINERS: Update Andy Walls' email address V4L/DVB: drivers/media: Eliminate a NULL pointer dereference V4L/DVB: dvb-core: Fix ULE decapsulation bug V4L/DVB: Bug fix: make IR work again for dm1105 V4L/DVB: media/IR: nec-decoder needs to select BITREV V4L/DVB: video/saa7134: change dprintk() to i2cdprintk() V4L/DVB: video/saa7134: remove duplicate break V4L/DVB: IR/imon: add auto-config for 0xffdc rf device V4L/DVB: IR/imon: clean up usage of bools V4L/DVB: em28xx: remove unneeded null checks V4L/DVB: ngene: remove unused #include <linux/version.h> V4L/DVB: ak881x needs slab.h V4L/DVB: FusionHDTV: Use quick reads for I2C IR device probing V4L/DVB: Technotrend S2-3200 ships with a TT 1500 remote V4L/DVB: drivers/media: Use kzalloc V4L/DVB: m920x: Select simple tuner ...
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/tm6000/Kconfig3
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c25
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c45
-rw-r--r--drivers/staging/tm6000/tm6000-core.c121
-rw-r--r--drivers/staging/tm6000/tm6000-dvb.c74
-rw-r--r--drivers/staging/tm6000/tm6000-video.c104
-rw-r--r--drivers/staging/tm6000/tm6000.h25
7 files changed, 309 insertions, 88 deletions
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index 5fe759cc2ee9..3657e33e8817 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -2,7 +2,8 @@ config VIDEO_TM6000
tristate "TV Master TM5600/6000/6010 driver"
depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL
select VIDEO_TUNER
- select TUNER_XC2028
+ select MEDIA_TUNER_XC2028
+ select MEDIA_TUNER_XC5000
select VIDEOBUF_VMALLOC
help
Support for TM5600/TM6000/TM6010 USB Device
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index bc89f9d28002..ce081cd44ad4 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -410,5 +410,28 @@ error:
snd_card_free(card);
return rc;
}
-EXPORT_SYMBOL_GPL(tm6000_audio_init);
+static int tm6000_audio_fini(struct tm6000_core *dev)
+{
+ return 0;
+}
+
+struct tm6000_ops audio_ops = {
+ .id = TM6000_AUDIO,
+ .name = "TM6000 Audio Extension",
+ .init = tm6000_audio_init,
+ .fini = tm6000_audio_fini,
+};
+
+static int __init tm6000_alsa_register(void)
+{
+ return tm6000_register_extension(&audio_ops);
+}
+
+static void __exit tm6000_alsa_unregister(void)
+{
+ tm6000_unregister_extension(&audio_ops);
+}
+
+module_init(tm6000_alsa_register);
+module_exit(tm6000_alsa_unregister);
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 6143e20d139d..cedd9044022f 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -363,13 +363,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
0x02, arg);
msleep(10);
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- TM6000_GPIO_CLK, 0);
- if (rc < 0)
- return rc;
- msleep(10);
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- TM6000_GPIO_CLK, 1);
+ rc = tm6000_i2c_reset(dev, 10);
break;
case XC2028_TUNER_RESET:
/* Reset codes during load firmware */
@@ -423,14 +417,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
break;
case 2:
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- TM6000_GPIO_CLK, 0);
- if (rc < 0)
- return rc;
- msleep(100);
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- TM6000_GPIO_CLK, 1);
- msleep(100);
+ rc = tm6000_i2c_reset(dev, 100);
break;
}
}
@@ -563,7 +550,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
switch (dev->tuner_type) {
case TUNER_XC2028:
- tun_setup.tuner_callback = tm6000_tuner_callback;;
+ tun_setup.tuner_callback = tm6000_tuner_callback;
break;
case TUNER_XC5000:
tun_setup.tuner_callback = tm6000_xc5000_callback;
@@ -692,6 +679,10 @@ static int tm6000_init_dev(struct tm6000_core *dev)
if (rc < 0)
goto err;
+ tm6000_add_into_devlist(dev);
+
+ tm6000_init_extension(dev);
+
if (dev->caps.has_dvb) {
dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
if (!dev->dvb) {
@@ -921,6 +912,25 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
}
#endif
+ if (dev->gpio.power_led) {
+ switch (dev->model) {
+ case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
+ case TM6010_BOARD_TWINHAN_TU501:
+ /* Power led off */
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.power_led, 0x01);
+ msleep(15);
+ break;
+ case TM6010_BOARD_BEHOLD_WANDER:
+ case TM6010_BOARD_BEHOLD_VOYAGER:
+ /* Power led off */
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.power_led, 0x00);
+ msleep(15);
+ break;
+ }
+ }
tm6000_v4l2_unregister(dev);
tm6000_i2c_unregister(dev);
@@ -931,6 +941,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
usb_put_dev(dev->udev);
+ tm6000_remove_from_devlist(dev);
+ tm6000_close_extension(dev);
+
mutex_unlock(&dev->lock);
kfree(dev);
}
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index bfbc53bd2912..27f3f551b545 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -153,6 +153,22 @@ int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24;
}
+int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep)
+{
+ int rc;
+
+ rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0);
+ if (rc < 0)
+ return rc;
+
+ msleep(tsleep);
+
+ rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
+ msleep(tsleep);
+
+ return rc;
+}
+
void tm6000_set_fourcc_format(struct tm6000_core *dev)
{
if (dev->dev_type == TM6010) {
@@ -323,6 +339,12 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
tm6000_set_standard (dev, &dev->norm);
tm6000_set_audio_bitrate (dev,48000);
+ /* switch dvb led off */
+ if (dev->gpio.dvb_led) {
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.dvb_led, 0x01);
+ }
+
return 0;
}
@@ -375,6 +397,13 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
msleep(100);
}
+
+ /* switch dvb led on */
+ if (dev->gpio.dvb_led) {
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.dvb_led, 0x00);
+ }
+
return 0;
}
@@ -600,3 +629,95 @@ printk("Original value=%d\n",val);
return val;
}
EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
+
+static LIST_HEAD(tm6000_devlist);
+static DEFINE_MUTEX(tm6000_devlist_mutex);
+
+/*
+ * tm6000_realease_resource()
+ */
+
+void tm6000_remove_from_devlist(struct tm6000_core *dev)
+{
+ mutex_lock(&tm6000_devlist_mutex);
+ list_del(&dev->devlist);
+ mutex_unlock(&tm6000_devlist_mutex);
+};
+
+void tm6000_add_into_devlist(struct tm6000_core *dev)
+{
+ mutex_lock(&tm6000_devlist_mutex);
+ list_add_tail(&dev->devlist, &tm6000_devlist);
+ mutex_unlock(&tm6000_devlist_mutex);
+};
+
+/*
+ * Extension interface
+ */
+
+static LIST_HEAD(tm6000_extension_devlist);
+static DEFINE_MUTEX(tm6000_extension_devlist_lock);
+
+int tm6000_register_extension(struct tm6000_ops *ops)
+{
+ struct tm6000_core *dev = NULL;
+
+ mutex_lock(&tm6000_devlist_mutex);
+ mutex_lock(&tm6000_extension_devlist_lock);
+ list_add_tail(&ops->next, &tm6000_extension_devlist);
+ list_for_each_entry(dev, &tm6000_devlist, devlist) {
+ if (dev)
+ ops->init(dev);
+ }
+ printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name);
+ mutex_unlock(&tm6000_extension_devlist_lock);
+ mutex_unlock(&tm6000_devlist_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(tm6000_register_extension);
+
+void tm6000_unregister_extension(struct tm6000_ops *ops)
+{
+ struct tm6000_core *dev = NULL;
+
+ mutex_lock(&tm6000_devlist_mutex);
+ list_for_each_entry(dev, &tm6000_devlist, devlist) {
+ if (dev)
+ ops->fini(dev);
+ }
+
+ mutex_lock(&tm6000_extension_devlist_lock);
+ printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name);
+ list_del(&ops->next);
+ mutex_unlock(&tm6000_extension_devlist_lock);
+ mutex_unlock(&tm6000_devlist_mutex);
+}
+EXPORT_SYMBOL(tm6000_unregister_extension);
+
+void tm6000_init_extension(struct tm6000_core *dev)
+{
+ struct tm6000_ops *ops = NULL;
+
+ mutex_lock(&tm6000_extension_devlist_lock);
+ if (!list_empty(&tm6000_extension_devlist)) {
+ list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+ if (ops->init)
+ ops->init(dev);
+ }
+ }
+ mutex_unlock(&tm6000_extension_devlist_lock);
+}
+
+void tm6000_close_extension(struct tm6000_core *dev)
+{
+ struct tm6000_ops *ops = NULL;
+
+ mutex_lock(&tm6000_extension_devlist_lock);
+ if (!list_empty(&tm6000_extension_devlist)) {
+ list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+ if (ops->fini)
+ ops->fini(dev);
+ }
+ }
+ mutex_unlock(&tm6000_extension_devlist_lock);
+}
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index eafc89c22b6b..261e66acbe46 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -28,6 +28,7 @@
#include <media/tuner.h>
#include "tuner-xc2028.h"
+#include "xc5000.h"
static void inline print_err_status (struct tm6000_core *dev,
int packet, int status)
@@ -100,7 +101,10 @@ int tm6000_start_stream(struct tm6000_core *dev)
printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
- tm6000_init_digital_mode(dev);
+ if (dev->mode != TM6000_MODE_DIGITAL) {
+ tm6000_init_digital_mode(dev);
+ dev->mode = TM6000_MODE_DIGITAL;
+ }
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
if(dvb->bulk_urb == NULL) {
@@ -254,27 +258,55 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->adapter.priv = dev;
if (dvb->frontend) {
- struct xc2028_config cfg = {
- .i2c_adap = &dev->i2c_adap,
- .i2c_addr = dev->tuner_addr,
- };
-
- dvb->frontend->callback = tm6000_tuner_callback;
- ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
- if (ret < 0) {
- printk(KERN_ERR
- "tm6000: couldn't register frontend\n");
- goto adapter_err;
- }
-
- if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
- printk(KERN_ERR "tm6000: couldn't register "
- "frontend (xc3028)\n");
- ret = -EINVAL;
- goto frontend_err;
+ switch (dev->tuner_type) {
+ case TUNER_XC2028: {
+ struct xc2028_config cfg = {
+ .i2c_adap = &dev->i2c_adap,
+ .i2c_addr = dev->tuner_addr,
+ };
+
+ dvb->frontend->callback = tm6000_tuner_callback;
+ ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "tm6000: couldn't register frontend\n");
+ goto adapter_err;
+ }
+
+ if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
+ printk(KERN_ERR "tm6000: couldn't register "
+ "frontend (xc3028)\n");
+ ret = -EINVAL;
+ goto frontend_err;
+ }
+ printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
+ "attached to frontend!\n");
+ break;
+ }
+ case TUNER_XC5000: {
+ struct xc5000_config cfg = {
+ .i2c_address = dev->tuner_addr,
+ };
+
+ dvb->frontend->callback = tm6000_xc5000_callback;
+ ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "tm6000: couldn't register frontend\n");
+ goto adapter_err;
+ }
+
+ if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) {
+ printk(KERN_ERR "tm6000: couldn't register "
+ "frontend (xc5000)\n");
+ ret = -EINVAL;
+ goto frontend_err;
+ }
+ printk(KERN_INFO "tm6000: XC5000 asked to be "
+ "attached to frontend!\n");
+ break;
+ }
}
- printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
- "attached to frontend!\n");
} else {
printk(KERN_ERR "tm6000: no frontend found\n");
}
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index f2b7fe4a3581..56fa371e08c8 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -48,7 +48,7 @@
#define TM6000_MIN_BUF 4
#define TM6000_DEF_BUF 8
-#define TM6000_MAX_ISO_PACKETS 40 /* Max number of ISO packets */
+#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */
/* Declare static vars that will be used as parameters */
static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
@@ -205,7 +205,11 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
c = (header >> 24) & 0xff;
/* split the header fields */
- size = (((header & 0x7e) << 1) -1) *4;
+ size = ((header & 0x7e) << 1);
+
+ if (size > 0)
+ size -= 4;
+
block = (header >> 7) & 0xf;
field = (header >> 11) & 0x1;
line = (header >> 12) & 0x1ff;
@@ -307,10 +311,12 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
case TM6000_URB_MSG_PTS:
break;
case TM6000_URB_MSG_AUDIO:
-/* Need some code to process audio */
-printk ("%ld: cmd=%s, size=%d\n", jiffies,
+ /* Need some code to process audio */
+ printk ("%ld: cmd=%s, size=%d\n", jiffies,
tm6000_msg_type[cmd],size);
break;
+ case TM6000_URB_MSG_VBI:
+ break;
default:
dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
tm6000_msg_type[cmd],size);
@@ -333,14 +339,23 @@ printk ("%ld: cmd=%s, size=%d\n", jiffies,
return rc;
}
-static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
- struct urb *urb, struct tm6000_buffer **buf)
+static int copy_streams(u8 *data, unsigned long len,
+ struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
u8 *ptr=data, *endp=data+len;
unsigned long header=0;
int rc=0;
+ struct tm6000_buffer *buf;
+ char *outp = NULL;
+
+ get_next_buf(dma_q, &buf);
+ if (buf)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ if (!outp)
+ return 0;
for (ptr=data; ptr<endp;) {
if (!dev->isoc_ctl.cmd) {
@@ -388,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
}
HEADER:
/* Copy or continue last copy */
- rc=copy_packet(urb,header,&ptr,endp,out_p,buf);
+ rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
if (rc<0) {
buf=NULL;
printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
jiffies);
return rc;
}
- if (!*buf)
+ if (!buf)
return 0;
}
@@ -404,31 +419,40 @@ HEADER:
/*
* Identify the tm5600/6000 buffer header type and properly handles
*/
-static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len,
- struct urb *urb, struct tm6000_buffer **buf)
+static int copy_multiplexed(u8 *ptr, unsigned long len,
+ struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
unsigned int pos=dev->isoc_ctl.pos,cpysize;
int rc=1;
+ struct tm6000_buffer *buf;
+ char *outp = NULL;
+
+ get_next_buf(dma_q, &buf);
+ if (buf)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ if (!outp)
+ return 0;
while (len>0) {
- cpysize=min(len,(*buf)->vb.size-pos);
-//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
- memcpy(&out_p[pos], ptr, cpysize);
+ cpysize=min(len,buf->vb.size-pos);
+ //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
+ memcpy(&outp[pos], ptr, cpysize);
pos+=cpysize;
ptr+=cpysize;
len-=cpysize;
- if (pos >= (*buf)->vb.size) {
+ if (pos >= buf->vb.size) {
pos=0;
/* Announces that a new buffer were filled */
- buffer_filled (dev, dma_q, *buf);
+ buffer_filled (dev, dma_q, buf);
dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
- get_next_buf (dma_q, buf);
- if (!*buf)
+ get_next_buf (dma_q, &buf);
+ if (!buf)
break;
- out_p = videobuf_to_vmalloc(&((*buf)->vb));
- if (!out_p)
+ outp = videobuf_to_vmalloc(&(buf->vb));
+ if (!outp)
return rc;
pos = 0;
}
@@ -487,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb)
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
struct tm6000_buffer *buf;
- int i, len=0, rc=1;
- int size;
- char *outp = NULL, *p;
- unsigned long copied;
-
- get_next_buf(dma_q, &buf);
- if (buf)
- outp = videobuf_to_vmalloc(&buf->vb);
+ int i, len=0, rc=1, status;
+ char *p;
- if (!outp)
- return 0;
-
- size = buf->vb.size;
-
- copied=0;
-
- if (urb->status<0) {
- print_err_status (dev,-1,urb->status);
+ if (urb->status < 0) {
+ print_err_status (dev, -1, urb->status);
return 0;
}
for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
+ status = urb->iso_frame_desc[i].status;
if (status<0) {
print_err_status (dev,i,status);
continue;
}
- len=urb->iso_frame_desc[i].actual_length;
+ len = urb->iso_frame_desc[i].actual_length;
-// if (len>=TM6000_URB_MSG_LEN) {
- p=urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ if (len > 0) {
+ p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (!urb->iso_frame_desc[i].status) {
- if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) {
- rc=copy_multiplexed(p, outp, len, urb, &buf);
+ if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) {
+ rc=copy_multiplexed(p, len, urb);
if (rc<=0)
return rc;
} else {
- copy_streams(p, outp, len, urb, &buf);
+ copy_streams(p, len, urb);
}
}
- copied += len;
- if (copied >= size || !buf)
- break;
-// }
+ }
}
return rc;
}
@@ -612,7 +620,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
{
struct tm6000_dmaqueue *dma_q = &dev->vidq;
- int i, j, sb_size, pipe, size, max_packets, num_bufs = 5;
+ int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
struct urb *urb;
/* De-allocates all pending stuff */
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 6812d6867d57..7bbaf26dea14 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -168,6 +168,10 @@ struct tm6000_core {
struct i2c_adapter i2c_adap;
struct i2c_client i2c_client;
+
+ /* extension */
+ struct list_head devlist;
+
/* video for linux */
int users;
@@ -203,6 +207,16 @@ struct tm6000_core {
spinlock_t slock;
};
+#define TM6000_AUDIO 0x10
+
+struct tm6000_ops {
+ struct list_head next;
+ char *name;
+ int id;
+ int (*init)(struct tm6000_core *);
+ int (*fini)(struct tm6000_core *);
+};
+
struct tm6000_fh {
struct tm6000_core *dev;
@@ -232,6 +246,8 @@ int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
+int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
+
int tm6000_init (struct tm6000_core *dev);
int tm6000_init_analog_mode (struct tm6000_core *dev);
@@ -246,6 +262,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev);
int tm6000_v4l2_exit(void);
void tm6000_set_fourcc_format(struct tm6000_core *dev);
+void tm6000_remove_from_devlist(struct tm6000_core *dev);
+void tm6000_add_into_devlist(struct tm6000_core *dev);
+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);
+
/* In tm6000-stds.c */
void tm6000_get_std_res(struct tm6000_core *dev);
int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
@@ -275,7 +298,7 @@ unsigned int tm6000_v4l2_poll(struct file *file,
int tm6000_queue_init(struct tm6000_core *dev);
/* In tm6000-alsa.c */
-int tm6000_audio_init(struct tm6000_core *dev, int idx);
+/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/
/* Debug stuff */