diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-09-05 06:03:48 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:04:45 -0400 |
commit | 59f8b0bf3c12598cf4a5b333b0287774dbbdbe1f (patch) | |
tree | 76e5cb4c3b817f62df12c4bc8779a63fe6294a76 /drivers | |
parent | 55c1b7d3572c9f7e7177447fdd2f48d9787e7ff3 (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.c | 54 |
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 | ||
2761 | static 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 | |||
2761 | static void sd_stopN(struct gspca_dev *gspca_dev) | 2780 | static 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) | |||
2766 | static void sd_stop0(struct gspca_dev *gspca_dev) | 2785 | static 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 | ||
3164 | static 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 -- */ |
3139 | static const __devinitdata struct usb_device_id device_table[] = { | 3178 | static 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); | |||
3152 | static int sd_probe(struct usb_interface *intf, | 3191 | static 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 | ||
3174 | static struct usb_driver sd_driver = { | 3220 | static struct usb_driver sd_driver = { |