----- Forwarded Message ----
From: Thierry MERLE <thierry.merle@xxxxxxx>
To: Linux and Kernel Video <video4linux-list@xxxxxxxxxx>
Sent: Tuesday, January 16, 2007 3:01:49 AM
Subject: [PATCH] usbvision: set alternate interface modification
From: Thierry MERLE <thierry.merle@xxxxxxx>
To: Linux and Kernel Video <video4linux-list@xxxxxxxxxx>
Sent: Tuesday, January 16, 2007 3:01:49 AM
Subject: [PATCH] usbvision: set alternate interface modification
Hello,
I modified the alternate selection so that this is the one with the
biggest packet size that is selected (as it is done in em28xx).
I fixed the 0 values got from sysfs for controls
(brightness/contrast/hue/saturation).
There was no need to divide the values by 256 as it was done.
Patch contents:
- usb alternate selection modified to get the biggest endpoint packet size.
- fix sysfs get values for brightness/contrast/hue/saturation
Signed-off-by: Thierry MERLE <thierry.merle@xxxxxxx>
Cheers,
Thierry
I modified the alternate selection so that this is the one with the
biggest packet size that is selected (as it is done in em28xx).
I fixed the 0 values got from sysfs for controls
(brightness/contrast/hue/saturation).
There was no need to divide the values by 256 as it was done.
Patch contents:
- usb alternate selection modified to get the biggest endpoint packet size.
- fix sysfs get values for brightness/contrast/hue/saturation
Signed-off-by: Thierry MERLE <thierry.merle@xxxxxxx>
Cheers,
Thierry
diff -r 344763ebb94b linux/drivers/media/video/usbvision/Kconfig
--- a/linux/drivers/media/video/usbvision/Kconfig Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/Kconfig Tue Jan 16 08:24:37 2007 +0100
@@ -1,6 +1,6 @@ config VIDEO_USBVISION
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2 && USB
select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision-core.c
--- a/linux/drivers/media/video/usbvision/usbvision-core.c Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c Tue Jan 16 08:53:46 2007 +0100
@@ -2432,6 +2432,32 @@ int usbvision_setup(struct usb_usbvision
return USBVISION_IS_OPERATIONAL(usbvision);
}
+int usbvision_set_alternate(struct usb_usbvision *dev)
+{
+ int errCode, prev_alt = dev->ifaceAlt;
+ int i;
+
+ dev->ifaceAlt=0;
+ for(i=0;i< dev->num_alt; i++)
+ if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt])
+ dev->ifaceAlt=i;
+
+ if (dev->ifaceAlt != prev_alt) {
+ dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt];
+ PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
+ errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
+ if (errCode < 0) {
+ err ("cannot change alternate number to %d (error=%i)",
+ dev->ifaceAlt, errCode);
+ return errCode;
+ }
+ }
+
+ PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize);
+
+ return 0;
+}
+
/*
* usbvision_init_isoc()
*
@@ -2449,15 +2475,13 @@ int usbvision_init_isoc(struct usb_usbvi
scratch_reset(usbvision);
/* Alternate interface 1 is is the biggest frame size */
- errCode = usb_set_interface(dev, usbvision->iface, usbvision->ifaceAltActive);
+ errCode = usbvision_set_alternate(usbvision);
if (errCode < 0) {
usbvision->last_error = errCode;
return -EBUSY;
}
regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
usbvision->usb_bandwidth = regValue >> 1;
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
@@ -2584,8 +2608,9 @@ void usbvision_stop_isoc(struct usb_usbv
if (!usbvision->remove_pending) {
/* Set packet size to 0 */
+ usbvision->ifaceAlt=0;
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->ifaceAltInactive);
+ usbvision->ifaceAlt);
if (errCode < 0) {
err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
usbvision->last_error = errCode;
diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision-video.c
--- a/linux/drivers/media/video/usbvision/usbvision-video.c Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c Tue Jan 16 08:45:45 2007 +0100
@@ -241,7 +241,7 @@ static ssize_t show_hue(struct class_dev
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
@@ -254,7 +254,7 @@ static ssize_t show_contrast(struct clas
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
@@ -267,7 +267,7 @@ static ssize_t show_brightness(struct cl
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
@@ -280,7 +280,7 @@ static ssize_t show_saturation(struct cl
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
@@ -833,8 +833,8 @@ static int usbvision_v4l2_do_ioctl(struc
case VIDIOC_G_CTRL:
{
struct v4l2_control *ctrl = arg;
+ call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value);
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
return 0;
}
case VIDIOC_S_CTRL:
@@ -1316,6 +1316,13 @@ static int usbvision_radio_open(struct i
}
}
+ /* Alternate interface 1 is is the biggest frame size */
+ errCode = usbvision_set_alternate(usbvision);
+ if (errCode < 0) {
+ usbvision->last_error = errCode;
+ return -EBUSY;
+ }
+
// If so far no errors then we shall start the radio
usbvision->radio = 1;
call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
@@ -1355,6 +1362,11 @@ static int usbvision_radio_close(struct
PDEBUG(DBG_IO, "");
down(&usbvision->lock);
+
+ /* Set packet size to 0 */
+ usbvision->ifaceAlt=0;
+ errCode = usb_set_interface(usbvision->dev, usbvision->iface,
+ usbvision->ifaceAlt);
usbvision_audio_off(usbvision);
usbvision->radio=0;
@@ -1950,16 +1962,18 @@ static void *usbvision_probe(struct usb_
#else
static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid)
{
- struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
+ struct usb_interface *uif;
__u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
const struct usb_host_interface *interface;
#endif
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
- int model;
+ int model,i;
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+
/* Is it an USBVISION video dev? */
model = 0;
for(model = 0; usbvision_device_data[model].idVendor; model++) {
@@ -1988,7 +2002,7 @@ static int __devinit usbvision_probe(str
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: USBVision Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes);
+ err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
return NULL;
}
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
@@ -1998,6 +2012,7 @@ static int __devinit usbvision_probe(str
MOD_INC_USE_COUNT;
+ /* Allocate the usbvision device structure so that we can set some variables */
if ((usbvision = usbvision_alloc(dev)) == NULL) {
err("%s: couldn't allocate USBVision struct", __FUNCTION__);
MOD_DEC_USE_COUNT;
@@ -2016,7 +2031,7 @@ static int __devinit usbvision_probe(str
endpoint = &interface->endpoint[1].desc;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes);
+ err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
return -ENODEV;
}
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
@@ -2044,6 +2059,28 @@ static int __devinit usbvision_probe(str
down(&usbvision->lock);
+ /* compute alternate max packet sizes */
+ uif = dev->actconfig->interface[0];
+
+ usbvision->num_alt=uif->num_altsetting;
+ PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt);
+ usbvision->alt_max_pkt_size = kmalloc(32*
+ usbvision->num_alt,GFP_KERNEL);
+ if (usbvision->alt_max_pkt_size == NULL) {
+ err("usbvision: out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < usbvision->num_alt ; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+ wMaxPacketSize);
+ usbvision->alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i,
+ usbvision->alt_max_pkt_size[i]);
+ }
+
+
usbvision->nr = usbvision_nr++;
usbvision->have_tuner = usbvision_device_data[model].Tuner;
@@ -2056,8 +2093,7 @@ static int __devinit usbvision_probe(str
usbvision->DevModel = model;
usbvision->remove_pending = 0;
usbvision->iface = ifnum;
- usbvision->ifaceAltInactive = 0;
- usbvision->ifaceAltActive = 1;
+ usbvision->ifaceAlt = 0;
usbvision->video_endp = endpoint->bEndpointAddress;
usbvision->isocPacketSize = 0;
usbvision->usb_bandwidth = 0;
diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision.h
--- a/linux/drivers/media/video/usbvision/usbvision.h Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision.h Tue Jan 16 08:28:44 2007 +0100
@@ -33,6 +33,7 @@
#include <linux/list.h>
#include <linux/usb.h>
+#include <linux/i2c.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -396,8 +397,11 @@ struct usb_usbvision {
/* Device structure */
struct usb_device *dev;
+ /* usb transfer */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
unsigned char iface; /* Video interface number */
- unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */
+ unsigned char ifaceAlt; /* Alt settings */
unsigned char Vin_Reg2_Preset;
struct semaphore lock;
struct timer_list powerOffTimer;
@@ -526,6 +530,7 @@ int usbvision_init_isoc(struct usb_usbvi
int usbvision_init_isoc(struct usb_usbvision *usbvision);
int usbvision_restart_isoc(struct usb_usbvision *usbvision);
void usbvision_stop_isoc(struct usb_usbvision *usbvision);
+int usbvision_set_alternate(struct usb_usbvision *dev);
int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel);
int usbvision_audio_off(struct usb_usbvision *usbvision);
--- a/linux/drivers/media/video/usbvision/Kconfig Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/Kconfig Tue Jan 16 08:24:37 2007 +0100
@@ -1,6 +1,6 @@ config VIDEO_USBVISION
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2 && USB
select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision-core.c
--- a/linux/drivers/media/video/usbvision/usbvision-core.c Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c Tue Jan 16 08:53:46 2007 +0100
@@ -2432,6 +2432,32 @@ int usbvision_setup(struct usb_usbvision
return USBVISION_IS_OPERATIONAL(usbvision);
}
+int usbvision_set_alternate(struct usb_usbvision *dev)
+{
+ int errCode, prev_alt = dev->ifaceAlt;
+ int i;
+
+ dev->ifaceAlt=0;
+ for(i=0;i< dev->num_alt; i++)
+ if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt])
+ dev->ifaceAlt=i;
+
+ if (dev->ifaceAlt != prev_alt) {
+ dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt];
+ PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
+ errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
+ if (errCode < 0) {
+ err ("cannot change alternate number to %d (error=%i)",
+ dev->ifaceAlt, errCode);
+ return errCode;
+ }
+ }
+
+ PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize);
+
+ return 0;
+}
+
/*
* usbvision_init_isoc()
*
@@ -2449,15 +2475,13 @@ int usbvision_init_isoc(struct usb_usbvi
scratch_reset(usbvision);
/* Alternate interface 1 is is the biggest frame size */
- errCode = usb_set_interface(dev, usbvision->iface, usbvision->ifaceAltActive);
+ errCode = usbvision_set_alternate(usbvision);
if (errCode < 0) {
usbvision->last_error = errCode;
return -EBUSY;
}
regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
usbvision->usb_bandwidth = regValue >> 1;
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
@@ -2584,8 +2608,9 @@ void usbvision_stop_isoc(struct usb_usbv
if (!usbvision->remove_pending) {
/* Set packet size to 0 */
+ usbvision->ifaceAlt=0;
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->ifaceAltInactive);
+ usbvision->ifaceAlt);
if (errCode < 0) {
err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
usbvision->last_error = errCode;
diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision-video.c
--- a/linux/drivers/media/video/usbvision/usbvision-video.c Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c Tue Jan 16 08:45:45 2007 +0100
@@ -241,7 +241,7 @@ static ssize_t show_hue(struct class_dev
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
@@ -254,7 +254,7 @@ static ssize_t show_contrast(struct clas
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
@@ -267,7 +267,7 @@ static ssize_t show_brightness(struct cl
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
@@ -280,7 +280,7 @@ static ssize_t show_saturation(struct cl
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
@@ -833,8 +833,8 @@ static int usbvision_v4l2_do_ioctl(struc
case VIDIOC_G_CTRL:
{
struct v4l2_control *ctrl = arg;
+ call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value);
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
return 0;
}
case VIDIOC_S_CTRL:
@@ -1316,6 +1316,13 @@ static int usbvision_radio_open(struct i
}
}
+ /* Alternate interface 1 is is the biggest frame size */
+ errCode = usbvision_set_alternate(usbvision);
+ if (errCode < 0) {
+ usbvision->last_error = errCode;
+ return -EBUSY;
+ }
+
// If so far no errors then we shall start the radio
usbvision->radio = 1;
call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
@@ -1355,6 +1362,11 @@ static int usbvision_radio_close(struct
PDEBUG(DBG_IO, "");
down(&usbvision->lock);
+
+ /* Set packet size to 0 */
+ usbvision->ifaceAlt=0;
+ errCode = usb_set_interface(usbvision->dev, usbvision->iface,
+ usbvision->ifaceAlt);
usbvision_audio_off(usbvision);
usbvision->radio=0;
@@ -1950,16 +1962,18 @@ static void *usbvision_probe(struct usb_
#else
static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid)
{
- struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
+ struct usb_interface *uif;
__u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
const struct usb_host_interface *interface;
#endif
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
- int model;
+ int model,i;
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+
/* Is it an USBVISION video dev? */
model = 0;
for(model = 0; usbvision_device_data[model].idVendor; model++) {
@@ -1988,7 +2002,7 @@ static int __devinit usbvision_probe(str
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: USBVision Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes);
+ err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
return NULL;
}
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
@@ -1998,6 +2012,7 @@ static int __devinit usbvision_probe(str
MOD_INC_USE_COUNT;
+ /* Allocate the usbvision device structure so that we can set some variables */
if ((usbvision = usbvision_alloc(dev)) == NULL) {
err("%s: couldn't allocate USBVision struct", __FUNCTION__);
MOD_DEC_USE_COUNT;
@@ -2016,7 +2031,7 @@ static int __devinit usbvision_probe(str
endpoint = &interface->endpoint[1].desc;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes);
+ err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
return -ENODEV;
}
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
@@ -2044,6 +2059,28 @@ static int __devinit usbvision_probe(str
down(&usbvision->lock);
+ /* compute alternate max packet sizes */
+ uif = dev->actconfig->interface[0];
+
+ usbvision->num_alt=uif->num_altsetting;
+ PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt);
+ usbvision->alt_max_pkt_size = kmalloc(32*
+ usbvision->num_alt,GFP_KERNEL);
+ if (usbvision->alt_max_pkt_size == NULL) {
+ err("usbvision: out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < usbvision->num_alt ; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+ wMaxPacketSize);
+ usbvision->alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i,
+ usbvision->alt_max_pkt_size[i]);
+ }
+
+
usbvision->nr = usbvision_nr++;
usbvision->have_tuner = usbvision_device_data[model].Tuner;
@@ -2056,8 +2093,7 @@ static int __devinit usbvision_probe(str
usbvision->DevModel = model;
usbvision->remove_pending = 0;
usbvision->iface = ifnum;
- usbvision->ifaceAltInactive = 0;
- usbvision->ifaceAltActive = 1;
+ usbvision->ifaceAlt = 0;
usbvision->video_endp = endpoint->bEndpointAddress;
usbvision->isocPacketSize = 0;
usbvision->usb_bandwidth = 0;
diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision.h
--- a/linux/drivers/media/video/usbvision/usbvision.h Sun Jan 14 09:33:24 2007 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision.h Tue Jan 16 08:28:44 2007 +0100
@@ -33,6 +33,7 @@
#include <linux/list.h>
#include <linux/usb.h>
+#include <linux/i2c.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -396,8 +397,11 @@ struct usb_usbvision {
/* Device structure */
struct usb_device *dev;
+ /* usb transfer */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
unsigned char iface; /* Video interface number */
- unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */
+ unsigned char ifaceAlt; /* Alt settings */
unsigned char Vin_Reg2_Preset;
struct semaphore lock;
struct timer_list powerOffTimer;
@@ -526,6 +530,7 @@ int usbvision_init_isoc(struct usb_usbvi
int usbvision_init_isoc(struct usb_usbvision *usbvision);
int usbvision_restart_isoc(struct usb_usbvision *usbvision);
void usbvision_stop_isoc(struct usb_usbvision *usbvision);
+int usbvision_set_alternate(struct usb_usbvision *dev);
int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel);
int usbvision_audio_off(struct usb_usbvision *usbvision);
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@xxxxxxxxxx?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@xxxxxxxxxx?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list
diff -r 344763ebb94b linux/drivers/media/video/usbvision/Kconfig --- a/linux/drivers/media/video/usbvision/Kconfig Sun Jan 14 09:33:24 2007 -0200 +++ b/linux/drivers/media/video/usbvision/Kconfig Tue Jan 16 08:24:37 2007 +0100 @@ -1,6 +1,6 @@ config VIDEO_USBVISION config VIDEO_USBVISION tristate "USB video devices based on Nogatech NT1003/1004/1005" - depends on I2C && VIDEO_V4L2 + depends on I2C && VIDEO_V4L2 && USB select VIDEO_TUNER select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO ---help--- diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision-core.c --- a/linux/drivers/media/video/usbvision/usbvision-core.c Sun Jan 14 09:33:24 2007 -0200 +++ b/linux/drivers/media/video/usbvision/usbvision-core.c Tue Jan 16 08:53:46 2007 +0100 @@ -2432,6 +2432,32 @@ int usbvision_setup(struct usb_usbvision return USBVISION_IS_OPERATIONAL(usbvision); } +int usbvision_set_alternate(struct usb_usbvision *dev) +{ + int errCode, prev_alt = dev->ifaceAlt; + int i; + + dev->ifaceAlt=0; + for(i=0;i< dev->num_alt; i++) + if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt]) + dev->ifaceAlt=i; + + if (dev->ifaceAlt != prev_alt) { + dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt]; + PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize); + errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt); + if (errCode < 0) { + err ("cannot change alternate number to %d (error=%i)", + dev->ifaceAlt, errCode); + return errCode; + } + } + + PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize); + + return 0; +} + /* * usbvision_init_isoc() * @@ -2449,15 +2475,13 @@ int usbvision_init_isoc(struct usb_usbvi scratch_reset(usbvision); /* Alternate interface 1 is is the biggest frame size */ - errCode = usb_set_interface(dev, usbvision->iface, usbvision->ifaceAltActive); + errCode = usbvision_set_alternate(usbvision); if (errCode < 0) { usbvision->last_error = errCode; return -EBUSY; } regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; - usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1; - PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize); usbvision->usb_bandwidth = regValue >> 1; PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); @@ -2584,8 +2608,9 @@ void usbvision_stop_isoc(struct usb_usbv if (!usbvision->remove_pending) { /* Set packet size to 0 */ + usbvision->ifaceAlt=0; errCode = usb_set_interface(usbvision->dev, usbvision->iface, - usbvision->ifaceAltInactive); + usbvision->ifaceAlt); if (errCode < 0) { err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode); usbvision->last_error = errCode; diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision-video.c --- a/linux/drivers/media/video/usbvision/usbvision-video.c Sun Jan 14 09:33:24 2007 -0200 +++ b/linux/drivers/media/video/usbvision/usbvision-video.c Tue Jan 16 08:45:45 2007 +0100 @@ -241,7 +241,7 @@ static ssize_t show_hue(struct class_dev ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); @@ -254,7 +254,7 @@ static ssize_t show_contrast(struct clas ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); @@ -267,7 +267,7 @@ static ssize_t show_brightness(struct cl ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); @@ -280,7 +280,7 @@ static ssize_t show_saturation(struct cl ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); @@ -833,8 +833,8 @@ static int usbvision_v4l2_do_ioctl(struc case VIDIOC_G_CTRL: { struct v4l2_control *ctrl = arg; + call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); - call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); return 0; } case VIDIOC_S_CTRL: @@ -1316,6 +1316,13 @@ static int usbvision_radio_open(struct i } } + /* Alternate interface 1 is is the biggest frame size */ + errCode = usbvision_set_alternate(usbvision); + if (errCode < 0) { + usbvision->last_error = errCode; + return -EBUSY; + } + // If so far no errors then we shall start the radio usbvision->radio = 1; call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); @@ -1355,6 +1362,11 @@ static int usbvision_radio_close(struct PDEBUG(DBG_IO, ""); down(&usbvision->lock); + + /* Set packet size to 0 */ + usbvision->ifaceAlt=0; + errCode = usb_set_interface(usbvision->dev, usbvision->iface, + usbvision->ifaceAlt); usbvision_audio_off(usbvision); usbvision->radio=0; @@ -1950,16 +1962,18 @@ static void *usbvision_probe(struct usb_ #else static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid) { - struct usb_device *dev = interface_to_usbdev(intf); + struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf)); + struct usb_interface *uif; __u8 ifnum = intf->altsetting->desc.bInterfaceNumber; const struct usb_host_interface *interface; #endif struct usb_usbvision *usbvision = NULL; const struct usb_endpoint_descriptor *endpoint; - int model; + int model,i; PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); + /* Is it an USBVISION video dev? */ model = 0; for(model = 0; usbvision_device_data[model].idVendor; model++) { @@ -1988,7 +2002,7 @@ static int __devinit usbvision_probe(str if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); - err("%s: USBVision Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes); + err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes); return NULL; } if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { @@ -1998,6 +2012,7 @@ static int __devinit usbvision_probe(str MOD_INC_USE_COUNT; + /* Allocate the usbvision device structure so that we can set some variables */ if ((usbvision = usbvision_alloc(dev)) == NULL) { err("%s: couldn't allocate USBVision struct", __FUNCTION__); MOD_DEC_USE_COUNT; @@ -2016,7 +2031,7 @@ static int __devinit usbvision_probe(str endpoint = &interface->endpoint[1].desc; if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); - err("%s: Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes); + err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes); return -ENODEV; } if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { @@ -2044,6 +2059,28 @@ static int __devinit usbvision_probe(str down(&usbvision->lock); + /* compute alternate max packet sizes */ + uif = dev->actconfig->interface[0]; + + usbvision->num_alt=uif->num_altsetting; + PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt); + usbvision->alt_max_pkt_size = kmalloc(32* + usbvision->num_alt,GFP_KERNEL); + if (usbvision->alt_max_pkt_size == NULL) { + err("usbvision: out of memory!\n"); + return -ENOMEM; + } + + for (i = 0; i < usbvision->num_alt ; i++) { + u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. + wMaxPacketSize); + usbvision->alt_max_pkt_size[i] = + (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); + PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i, + usbvision->alt_max_pkt_size[i]); + } + + usbvision->nr = usbvision_nr++; usbvision->have_tuner = usbvision_device_data[model].Tuner; @@ -2056,8 +2093,7 @@ static int __devinit usbvision_probe(str usbvision->DevModel = model; usbvision->remove_pending = 0; usbvision->iface = ifnum; - usbvision->ifaceAltInactive = 0; - usbvision->ifaceAltActive = 1; + usbvision->ifaceAlt = 0; usbvision->video_endp = endpoint->bEndpointAddress; usbvision->isocPacketSize = 0; usbvision->usb_bandwidth = 0; diff -r 344763ebb94b linux/drivers/media/video/usbvision/usbvision.h --- a/linux/drivers/media/video/usbvision/usbvision.h Sun Jan 14 09:33:24 2007 -0200 +++ b/linux/drivers/media/video/usbvision/usbvision.h Tue Jan 16 08:28:44 2007 +0100 @@ -33,6 +33,7 @@ #include <linux/list.h> #include <linux/usb.h> +#include <linux/i2c.h> #include <media/v4l2-common.h> #include <media/tuner.h> #include <linux/videodev2.h> @@ -396,8 +397,11 @@ struct usb_usbvision { /* Device structure */ struct usb_device *dev; + /* usb transfer */ + int num_alt; /* Number of alternative settings */ + unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ unsigned char iface; /* Video interface number */ - unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */ + unsigned char ifaceAlt; /* Alt settings */ unsigned char Vin_Reg2_Preset; struct semaphore lock; struct timer_list powerOffTimer; @@ -526,6 +530,7 @@ int usbvision_init_isoc(struct usb_usbvi int usbvision_init_isoc(struct usb_usbvision *usbvision); int usbvision_restart_isoc(struct usb_usbvision *usbvision); void usbvision_stop_isoc(struct usb_usbvision *usbvision); +int usbvision_set_alternate(struct usb_usbvision *dev); int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel); int usbvision_audio_off(struct usb_usbvision *usbvision);
_______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb