diff options
author | Thierry MERLE <thierry.merle@free.fr> | 2007-02-07 08:14:38 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:35:19 -0500 |
commit | 2a9f8b5d25beacd034369fca416b548cbf931561 (patch) | |
tree | bed433e406281239c053c17cd8c068589fb92551 | |
parent | 6f78e186fe5d29dbff5e34f950adb573c4808de4 (diff) |
V4L/DVB (5206): Usbvision: set alternate interface modification
- 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@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/usbvision/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/video/usbvision/usbvision-core.c | 33 | ||||
-rw-r--r-- | drivers/media/video/usbvision/usbvision-video.c | 55 | ||||
-rw-r--r-- | drivers/media/video/usbvision/usbvision.h | 7 |
4 files changed, 81 insertions, 16 deletions
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig index fc24ef05b3f3..c43a5d899091 100644 --- a/drivers/media/video/usbvision/Kconfig +++ b/drivers/media/video/usbvision/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_USBVISION | 1 | config VIDEO_USBVISION |
2 | tristate "USB video devices based on Nogatech NT1003/1004/1005" | 2 | tristate "USB video devices based on Nogatech NT1003/1004/1005" |
3 | depends on I2C && VIDEO_V4L2 | 3 | depends on I2C && VIDEO_V4L2 && USB |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | 5 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO |
6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index d4fcd5736ba9..f2154dc072e2 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -2361,6 +2361,32 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format) | |||
2361 | return USBVISION_IS_OPERATIONAL(usbvision); | 2361 | return USBVISION_IS_OPERATIONAL(usbvision); |
2362 | } | 2362 | } |
2363 | 2363 | ||
2364 | int usbvision_set_alternate(struct usb_usbvision *dev) | ||
2365 | { | ||
2366 | int errCode, prev_alt = dev->ifaceAlt; | ||
2367 | int i; | ||
2368 | |||
2369 | dev->ifaceAlt=0; | ||
2370 | for(i=0;i< dev->num_alt; i++) | ||
2371 | if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt]) | ||
2372 | dev->ifaceAlt=i; | ||
2373 | |||
2374 | if (dev->ifaceAlt != prev_alt) { | ||
2375 | dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt]; | ||
2376 | PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize); | ||
2377 | errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt); | ||
2378 | if (errCode < 0) { | ||
2379 | err ("cannot change alternate number to %d (error=%i)", | ||
2380 | dev->ifaceAlt, errCode); | ||
2381 | return errCode; | ||
2382 | } | ||
2383 | } | ||
2384 | |||
2385 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize); | ||
2386 | |||
2387 | return 0; | ||
2388 | } | ||
2389 | |||
2364 | /* | 2390 | /* |
2365 | * usbvision_init_isoc() | 2391 | * usbvision_init_isoc() |
2366 | * | 2392 | * |
@@ -2378,15 +2404,13 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2378 | scratch_reset(usbvision); | 2404 | scratch_reset(usbvision); |
2379 | 2405 | ||
2380 | /* Alternate interface 1 is is the biggest frame size */ | 2406 | /* Alternate interface 1 is is the biggest frame size */ |
2381 | errCode = usb_set_interface(dev, usbvision->iface, usbvision->ifaceAltActive); | 2407 | errCode = usbvision_set_alternate(usbvision); |
2382 | if (errCode < 0) { | 2408 | if (errCode < 0) { |
2383 | usbvision->last_error = errCode; | 2409 | usbvision->last_error = errCode; |
2384 | return -EBUSY; | 2410 | return -EBUSY; |
2385 | } | 2411 | } |
2386 | 2412 | ||
2387 | regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; | 2413 | regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; |
2388 | usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1; | ||
2389 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize); | ||
2390 | 2414 | ||
2391 | usbvision->usb_bandwidth = regValue >> 1; | 2415 | usbvision->usb_bandwidth = regValue >> 1; |
2392 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); | 2416 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); |
@@ -2472,8 +2496,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) | |||
2472 | if (!usbvision->remove_pending) { | 2496 | if (!usbvision->remove_pending) { |
2473 | 2497 | ||
2474 | /* Set packet size to 0 */ | 2498 | /* Set packet size to 0 */ |
2499 | usbvision->ifaceAlt=0; | ||
2475 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, | 2500 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, |
2476 | usbvision->ifaceAltInactive); | 2501 | usbvision->ifaceAlt); |
2477 | if (errCode < 0) { | 2502 | if (errCode < 0) { |
2478 | err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode); | 2503 | err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode); |
2479 | usbvision->last_error = errCode; | 2504 | usbvision->last_error = errCode; |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index cfbfda47ec4f..ae5f42562c0c 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -230,7 +230,7 @@ static ssize_t show_hue(struct class_device *cd, char *buf) | |||
230 | ctrl.value = 0; | 230 | ctrl.value = 0; |
231 | if(usbvision->user) | 231 | if(usbvision->user) |
232 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); | 232 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); |
233 | return sprintf(buf, "%d\n", ctrl.value >> 8); | 233 | return sprintf(buf, "%d\n", ctrl.value); |
234 | } | 234 | } |
235 | static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); | 235 | static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); |
236 | 236 | ||
@@ -243,7 +243,7 @@ static ssize_t show_contrast(struct class_device *cd, char *buf) | |||
243 | ctrl.value = 0; | 243 | ctrl.value = 0; |
244 | if(usbvision->user) | 244 | if(usbvision->user) |
245 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); | 245 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); |
246 | return sprintf(buf, "%d\n", ctrl.value >> 8); | 246 | return sprintf(buf, "%d\n", ctrl.value); |
247 | } | 247 | } |
248 | static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); | 248 | static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); |
249 | 249 | ||
@@ -256,7 +256,7 @@ static ssize_t show_brightness(struct class_device *cd, char *buf) | |||
256 | ctrl.value = 0; | 256 | ctrl.value = 0; |
257 | if(usbvision->user) | 257 | if(usbvision->user) |
258 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); | 258 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); |
259 | return sprintf(buf, "%d\n", ctrl.value >> 8); | 259 | return sprintf(buf, "%d\n", ctrl.value); |
260 | } | 260 | } |
261 | static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); | 261 | static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); |
262 | 262 | ||
@@ -269,7 +269,7 @@ static ssize_t show_saturation(struct class_device *cd, char *buf) | |||
269 | ctrl.value = 0; | 269 | ctrl.value = 0; |
270 | if(usbvision->user) | 270 | if(usbvision->user) |
271 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); | 271 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); |
272 | return sprintf(buf, "%d\n", ctrl.value >> 8); | 272 | return sprintf(buf, "%d\n", ctrl.value); |
273 | } | 273 | } |
274 | static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); | 274 | static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); |
275 | 275 | ||
@@ -776,8 +776,8 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
776 | case VIDIOC_G_CTRL: | 776 | case VIDIOC_G_CTRL: |
777 | { | 777 | { |
778 | struct v4l2_control *ctrl = arg; | 778 | struct v4l2_control *ctrl = arg; |
779 | PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); | ||
780 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); | 779 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); |
780 | PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); | ||
781 | return 0; | 781 | return 0; |
782 | } | 782 | } |
783 | case VIDIOC_S_CTRL: | 783 | case VIDIOC_S_CTRL: |
@@ -1243,6 +1243,13 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) | |||
1243 | } | 1243 | } |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | /* Alternate interface 1 is is the biggest frame size */ | ||
1247 | errCode = usbvision_set_alternate(usbvision); | ||
1248 | if (errCode < 0) { | ||
1249 | usbvision->last_error = errCode; | ||
1250 | return -EBUSY; | ||
1251 | } | ||
1252 | |||
1246 | // If so far no errors then we shall start the radio | 1253 | // If so far no errors then we shall start the radio |
1247 | usbvision->radio = 1; | 1254 | usbvision->radio = 1; |
1248 | call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); | 1255 | call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); |
@@ -1274,6 +1281,11 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) | |||
1274 | 1281 | ||
1275 | down(&usbvision->lock); | 1282 | down(&usbvision->lock); |
1276 | 1283 | ||
1284 | /* Set packet size to 0 */ | ||
1285 | usbvision->ifaceAlt=0; | ||
1286 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, | ||
1287 | usbvision->ifaceAlt); | ||
1288 | |||
1277 | usbvision_audio_off(usbvision); | 1289 | usbvision_audio_off(usbvision); |
1278 | usbvision->radio=0; | 1290 | usbvision->radio=0; |
1279 | usbvision->user--; | 1291 | usbvision->user--; |
@@ -1765,15 +1777,17 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision) | |||
1765 | */ | 1777 | */ |
1766 | static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid) | 1778 | static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid) |
1767 | { | 1779 | { |
1768 | struct usb_device *dev = interface_to_usbdev(intf); | 1780 | struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf)); |
1781 | struct usb_interface *uif; | ||
1769 | __u8 ifnum = intf->altsetting->desc.bInterfaceNumber; | 1782 | __u8 ifnum = intf->altsetting->desc.bInterfaceNumber; |
1770 | const struct usb_host_interface *interface; | 1783 | const struct usb_host_interface *interface; |
1771 | struct usb_usbvision *usbvision = NULL; | 1784 | struct usb_usbvision *usbvision = NULL; |
1772 | const struct usb_endpoint_descriptor *endpoint; | 1785 | const struct usb_endpoint_descriptor *endpoint; |
1773 | int model; | 1786 | int model,i; |
1774 | 1787 | ||
1775 | PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", | 1788 | PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", |
1776 | dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); | 1789 | dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); |
1790 | |||
1777 | /* Is it an USBVISION video dev? */ | 1791 | /* Is it an USBVISION video dev? */ |
1778 | model = 0; | 1792 | model = 0; |
1779 | for(model = 0; usbvision_device_data[model].idVendor; model++) { | 1793 | for(model = 0; usbvision_device_data[model].idVendor; model++) { |
@@ -1800,7 +1814,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us | |||
1800 | endpoint = &interface->endpoint[1].desc; | 1814 | endpoint = &interface->endpoint[1].desc; |
1801 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { | 1815 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { |
1802 | err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); | 1816 | err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); |
1803 | err("%s: Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes); | 1817 | err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes); |
1804 | return -ENODEV; | 1818 | return -ENODEV; |
1805 | } | 1819 | } |
1806 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | 1820 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { |
@@ -1827,6 +1841,28 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us | |||
1827 | 1841 | ||
1828 | down(&usbvision->lock); | 1842 | down(&usbvision->lock); |
1829 | 1843 | ||
1844 | /* compute alternate max packet sizes */ | ||
1845 | uif = dev->actconfig->interface[0]; | ||
1846 | |||
1847 | usbvision->num_alt=uif->num_altsetting; | ||
1848 | PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt); | ||
1849 | usbvision->alt_max_pkt_size = kmalloc(32* | ||
1850 | usbvision->num_alt,GFP_KERNEL); | ||
1851 | if (usbvision->alt_max_pkt_size == NULL) { | ||
1852 | err("usbvision: out of memory!\n"); | ||
1853 | return -ENOMEM; | ||
1854 | } | ||
1855 | |||
1856 | for (i = 0; i < usbvision->num_alt ; i++) { | ||
1857 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. | ||
1858 | wMaxPacketSize); | ||
1859 | usbvision->alt_max_pkt_size[i] = | ||
1860 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1861 | PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i, | ||
1862 | usbvision->alt_max_pkt_size[i]); | ||
1863 | } | ||
1864 | |||
1865 | |||
1830 | usbvision->nr = usbvision_nr++; | 1866 | usbvision->nr = usbvision_nr++; |
1831 | 1867 | ||
1832 | usbvision->have_tuner = usbvision_device_data[model].Tuner; | 1868 | usbvision->have_tuner = usbvision_device_data[model].Tuner; |
@@ -1839,8 +1875,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us | |||
1839 | usbvision->DevModel = model; | 1875 | usbvision->DevModel = model; |
1840 | usbvision->remove_pending = 0; | 1876 | usbvision->remove_pending = 0; |
1841 | usbvision->iface = ifnum; | 1877 | usbvision->iface = ifnum; |
1842 | usbvision->ifaceAltInactive = 0; | 1878 | usbvision->ifaceAlt = 0; |
1843 | usbvision->ifaceAltActive = 1; | ||
1844 | usbvision->video_endp = endpoint->bEndpointAddress; | 1879 | usbvision->video_endp = endpoint->bEndpointAddress; |
1845 | usbvision->isocPacketSize = 0; | 1880 | usbvision->isocPacketSize = 0; |
1846 | usbvision->usb_bandwidth = 0; | 1881 | usbvision->usb_bandwidth = 0; |
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index 0e2b55699860..ad6afd3e42a4 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
36 | #include <linux/i2c.h> | ||
36 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
37 | #include <media/tuner.h> | 38 | #include <media/tuner.h> |
38 | #include <linux/videodev2.h> | 39 | #include <linux/videodev2.h> |
@@ -396,8 +397,11 @@ struct usb_usbvision { | |||
396 | 397 | ||
397 | /* Device structure */ | 398 | /* Device structure */ |
398 | struct usb_device *dev; | 399 | struct usb_device *dev; |
400 | /* usb transfer */ | ||
401 | int num_alt; /* Number of alternative settings */ | ||
402 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | ||
399 | unsigned char iface; /* Video interface number */ | 403 | unsigned char iface; /* Video interface number */ |
400 | unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */ | 404 | unsigned char ifaceAlt; /* Alt settings */ |
401 | unsigned char Vin_Reg2_Preset; | 405 | unsigned char Vin_Reg2_Preset; |
402 | struct semaphore lock; | 406 | struct semaphore lock; |
403 | struct timer_list powerOffTimer; | 407 | struct timer_list powerOffTimer; |
@@ -502,6 +506,7 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format); | |||
502 | int usbvision_init_isoc(struct usb_usbvision *usbvision); | 506 | int usbvision_init_isoc(struct usb_usbvision *usbvision); |
503 | int usbvision_restart_isoc(struct usb_usbvision *usbvision); | 507 | int usbvision_restart_isoc(struct usb_usbvision *usbvision); |
504 | void usbvision_stop_isoc(struct usb_usbvision *usbvision); | 508 | void usbvision_stop_isoc(struct usb_usbvision *usbvision); |
509 | int usbvision_set_alternate(struct usb_usbvision *dev); | ||
505 | 510 | ||
506 | int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel); | 511 | int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel); |
507 | int usbvision_audio_off(struct usb_usbvision *usbvision); | 512 | int usbvision_audio_off(struct usb_usbvision *usbvision); |