aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2010-10-27 08:12:30 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:40 -0500
commitc0b33bdc5b8d9c1120dece660480d4dd86b817ee (patch)
treeebcc92bf6b05336943b9268337ea3d994af4ca43 /drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
parentbc25068495b110fcdf35a22f43d32637e99fd018 (diff)
[media] gspca-stv06xx: support bandwidth changing
stv06xx devices have only one altsetting, but the actual used bandwidth can be programmed through a register. We were already setting this register lower then the max packetsize of the altsetting indicates. This patch makes the gspca-stv06xx update the usb descriptor for the alt setting to reflect the actual packetsize in use, so that the usb subsystem uses the correct information for scheduling usb transfers. This patch also tries to fallback to lower speeds in case a ENOSPC error is received when submitting urbs, but currently this is only supported with stv06xx cams with the pb0100 sensor, as this is the only one for which we know how to change the framerate. This patch is based on an initial incomplete patch by Lee Jones <lee.jones@canonical.com> Signed-off-by: Lee Jones <lee.jones@canonical.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c')
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index 285221e6b390..ac47b4c94388 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -208,11 +208,24 @@ static int pb0100_probe(struct sd *sd)
208 208
209static int pb0100_start(struct sd *sd) 209static int pb0100_start(struct sd *sd)
210{ 210{
211 int err; 211 int err, packet_size, max_packet_size;
212 struct usb_host_interface *alt;
213 struct usb_interface *intf;
212 struct cam *cam = &sd->gspca_dev.cam; 214 struct cam *cam = &sd->gspca_dev.cam;
213 s32 *sensor_settings = sd->sensor_priv; 215 s32 *sensor_settings = sd->sensor_priv;
214 u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 216 u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
215 217
218 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
219 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
220 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
221
222 /* If we don't have enough bandwidth use a lower framerate */
223 max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
224 if (packet_size < max_packet_size)
225 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
226 else
227 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
228
216 /* Setup sensor window */ 229 /* Setup sensor window */
217 if (mode & PB0100_CROP_TO_VGA) { 230 if (mode & PB0100_CROP_TO_VGA) {
218 stv06xx_write_sensor(sd, PB_RSTART, 30); 231 stv06xx_write_sensor(sd, PB_RSTART, 30);
@@ -328,9 +341,6 @@ static int pb0100_init(struct sd *sd)
328 stv06xx_write_bridge(sd, STV_REG03, 0x45); 341 stv06xx_write_bridge(sd, STV_REG03, 0x45);
329 stv06xx_write_bridge(sd, STV_REG04, 0x07); 342 stv06xx_write_bridge(sd, STV_REG04, 0x07);
330 343
331 /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
332 stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
333
334 /* Scan/timing for the sensor */ 344 /* Scan/timing for the sensor */
335 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); 345 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
336 stv06xx_write_sensor(sd, PB_CFILLIN, 14); 346 stv06xx_write_sensor(sd, PB_CFILLIN, 14);