aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2010-09-05 06:03:48 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:04:45 -0400
commit59f8b0bf3c12598cf4a5b333b0287774dbbdbe1f (patch)
tree76e5cb4c3b817f62df12c4bc8779a63fe6294a76 /drivers
parent55c1b7d3572c9f7e7177447fdd2f48d9787e7ff3 (diff)
V4L/DVB: gspca_xirlink_cit: support bandwidth changing for devices with 1 alt setting
Some xirlink_cit models have only 1 alt setting, but the actual used bandwidth can be programmed through a register use this to allow streaming while other isoc streams (for example sound) are active at the same time. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/xirlink_cit.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c
index b13ecbaf3e6..c4e9b8c2eef 100644
--- a/drivers/media/video/gspca/xirlink_cit.c
+++ b/drivers/media/video/gspca/xirlink_cit.c
@@ -2758,6 +2758,25 @@ static int sd_start(struct gspca_dev *gspca_dev)
2758 return 0; 2758 return 0;
2759} 2759}
2760 2760
2761static int sd_isoc_nego(struct gspca_dev *gspca_dev)
2762{
2763 int ret, packet_size;
2764 struct usb_host_interface *alt;
2765
2766 alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
2767 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
2768 packet_size -= 100;
2769 if (packet_size < 300)
2770 return -EIO;
2771 alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
2772
2773 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
2774 if (ret < 0)
2775 PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret);
2776
2777 return ret;
2778}
2779
2761static void sd_stopN(struct gspca_dev *gspca_dev) 2780static void sd_stopN(struct gspca_dev *gspca_dev)
2762{ 2781{
2763 cit_write_reg(gspca_dev, 0x0000, 0x010c); 2782 cit_write_reg(gspca_dev, 0x0000, 0x010c);
@@ -2766,12 +2785,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2766static void sd_stop0(struct gspca_dev *gspca_dev) 2785static void sd_stop0(struct gspca_dev *gspca_dev)
2767{ 2786{
2768 struct sd *sd = (struct sd *) gspca_dev; 2787 struct sd *sd = (struct sd *) gspca_dev;
2788 struct usb_host_interface *alt;
2769 2789
2770 /* We cannot use gspca_dev->present here as that is not set when 2790 /* We cannot use gspca_dev->present here as that is not set when
2771 sd_init gets called and we get called from sd_init */ 2791 sd_init gets called and we get called from sd_init */
2772 if (!gspca_dev->dev) 2792 if (!gspca_dev->dev)
2773 return; 2793 return;
2774 2794
2795 alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
2796
2775 switch (sd->model) { 2797 switch (sd->model) {
2776 case CIT_MODEL0: 2798 case CIT_MODEL0:
2777 /* HDG windows does this, but it causes the cams autogain to 2799 /* HDG windows does this, but it causes the cams autogain to
@@ -2826,6 +2848,10 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2826 restarting the stream after this */ 2848 restarting the stream after this */
2827 /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ 2849 /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
2828 cit_write_reg(gspca_dev, 0x00c0, 0x0100); 2850 cit_write_reg(gspca_dev, 0x00c0, 0x0100);
2851
2852 /* Start isoc bandwidth "negotiation" at max isoc bandwith
2853 next stream start */
2854 alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022);
2829 break; 2855 break;
2830 } 2856 }
2831} 2857}
@@ -3135,6 +3161,19 @@ static const struct sd_desc sd_desc = {
3135 .pkt_scan = sd_pkt_scan, 3161 .pkt_scan = sd_pkt_scan,
3136}; 3162};
3137 3163
3164static const struct sd_desc sd_desc_isoc_nego = {
3165 .name = MODULE_NAME,
3166 .ctrls = sd_ctrls,
3167 .nctrls = ARRAY_SIZE(sd_ctrls),
3168 .config = sd_config,
3169 .init = sd_init,
3170 .start = sd_start,
3171 .isoc_nego = sd_isoc_nego,
3172 .stopN = sd_stopN,
3173 .stop0 = sd_stop0,
3174 .pkt_scan = sd_pkt_scan,
3175};
3176
3138/* -- module initialisation -- */ 3177/* -- module initialisation -- */
3139static const __devinitdata struct usb_device_id device_table[] = { 3178static const __devinitdata struct usb_device_id device_table[] = {
3140 { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 }, 3179 { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
@@ -3152,6 +3191,8 @@ MODULE_DEVICE_TABLE(usb, device_table);
3152static int sd_probe(struct usb_interface *intf, 3191static int sd_probe(struct usb_interface *intf,
3153 const struct usb_device_id *id) 3192 const struct usb_device_id *id)
3154{ 3193{
3194 const struct sd_desc *desc = &sd_desc;
3195
3155 switch (id->driver_info) { 3196 switch (id->driver_info) {
3156 case CIT_MODEL0: 3197 case CIT_MODEL0:
3157 case CIT_MODEL1: 3198 case CIT_MODEL1:
@@ -3159,16 +3200,21 @@ static int sd_probe(struct usb_interface *intf,
3159 return -ENODEV; 3200 return -ENODEV;
3160 break; 3201 break;
3161 case CIT_MODEL2: 3202 case CIT_MODEL2:
3162 case CIT_MODEL3:
3163 case CIT_MODEL4: 3203 case CIT_MODEL4:
3164 case CIT_IBM_NETCAM_PRO:
3165 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 3204 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
3166 return -ENODEV; 3205 return -ENODEV;
3167 break; 3206 break;
3207 case CIT_MODEL3:
3208 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
3209 return -ENODEV;
3210 /* FIXME this likely applies to all model3 cams and probably
3211 to other models too. */
3212 if (ibm_netcam_pro)
3213 desc = &sd_desc_isoc_nego;
3214 break;
3168 } 3215 }
3169 3216
3170 return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd), 3217 return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
3171 THIS_MODULE);
3172} 3218}
3173 3219
3174static struct usb_driver sd_driver = { 3220static struct usb_driver sd_driver = {