diff options
Diffstat (limited to 'drivers/media/video/gspca')
32 files changed, 933 insertions, 142 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 103af3fe5aa..dfe268bfa4f 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -77,6 +77,16 @@ config USB_GSPCA_JEILINJ To compile this driver as a module, choose M here: the module will be called gspca_jeilinj. +config USB_GSPCA_JL2005BCD + tristate "JL2005B/C/D USB V4L2 driver" + depends on VIDEO_V4L2 && USB_GSPCA + help + Say Y here if you want support for cameras based the + JL2005B, JL2005C, or JL2005D chip. + + To compile this driver as a module, choose M here: the + module will be called gspca_jl2005bcd. + config USB_GSPCA_KINECT tristate "Kinect sensor device USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index f345f494d0f..79ebe46e1ad 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o +obj-$(CONFIG_USB_GSPCA_JL2005BCD) += gspca_jl2005bcd.o obj-$(CONFIG_USB_GSPCA_KINECT) += gspca_kinect.o obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o @@ -49,6 +50,7 @@ gspca_cpia1-objs := cpia1.o gspca_etoms-objs := etoms.o gspca_finepix-objs := finepix.o gspca_jeilinj-objs := jeilinj.o +gspca_jl2005bcd-objs := jl2005bcd.o gspca_kinect-objs := kinect.o gspca_konica-objs := konica.o gspca_mars-objs := mars.o diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c index 636627b57dc..9769f17915c 100644 --- a/drivers/media/video/gspca/benq.c +++ b/drivers/media/video/gspca/benq.c @@ -76,7 +76,6 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); gspca_dev->cam.no_urb_create = 1; - gspca_dev->cam.reverse_alts = 1; return 0; } @@ -135,13 +134,17 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { + struct usb_interface *intf; + reg_w(gspca_dev, 0x003c, 0x0003); reg_w(gspca_dev, 0x003c, 0x0004); reg_w(gspca_dev, 0x003c, 0x0005); reg_w(gspca_dev, 0x003c, 0x0006); reg_w(gspca_dev, 0x003c, 0x0007); + + intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); usb_set_interface(gspca_dev->dev, gspca_dev->iface, - gspca_dev->nbalt - 1); + intf->num_altsetting - 1); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index a8f54c20e58..c84e26006fc 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -337,7 +337,6 @@ static int sd_config(struct gspca_dev *gspca_dev, return -1; cam = &gspca_dev->cam; - gspca_dev->nbalt = 4; switch (sd->sensor) { case ID_MI1320: diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 2ca10dfec91..ca5a2b139d0 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -633,23 +633,32 @@ static u32 which_bandwidth(struct gspca_dev *gspca_dev) u32 bandwidth; int i; + /* get the (max) image size */ i = gspca_dev->curr_mode; bandwidth = gspca_dev->cam.cam_mode[i].sizeimage; - /* if the image is compressed, estimate the mean image size */ - if (bandwidth < gspca_dev->cam.cam_mode[i].width * + /* if the image is compressed, estimate its mean size */ + if (!gspca_dev->cam.needs_full_bandwidth && + bandwidth < gspca_dev->cam.cam_mode[i].width * gspca_dev->cam.cam_mode[i].height) - bandwidth /= 3; + bandwidth = bandwidth * 3 / 8; /* 0.375 */ /* estimate the frame rate */ if (gspca_dev->sd_desc->get_streamparm) { struct v4l2_streamparm parm; - parm.parm.capture.timeperframe.denominator = 15; gspca_dev->sd_desc->get_streamparm(gspca_dev, &parm); bandwidth *= parm.parm.capture.timeperframe.denominator; + bandwidth /= parm.parm.capture.timeperframe.numerator; } else { - bandwidth *= 15; /* 15 fps */ + + /* don't hope more than 15 fps with USB 1.1 and + * image resolution >= 640x480 */ + if (gspca_dev->width >= 640 + && gspca_dev->dev->speed == USB_SPEED_FULL) + bandwidth *= 15; /* 15 fps */ + else + bandwidth *= 30; /* 30 fps */ } PDEBUG(D_STREAM, "min bandwidth: %d", bandwidth); @@ -667,9 +676,8 @@ struct ep_tb_s { * build the table of the endpoints * and compute the minimum bandwidth for the image transfer */ -static int build_ep_tb(struct gspca_dev *gspca_dev, +static int build_isoc_ep_tb(struct gspca_dev *gspca_dev, struct usb_interface *intf, - int xfer, struct ep_tb_s *ep_tb) { struct usb_host_endpoint *ep; @@ -687,17 +695,21 @@ static int build_ep_tb(struct gspca_dev *gspca_dev, ep_tb->bandwidth = 2000 * 2000 * 120; found = 0; for (j = 0; j < nbalt; j++) { - ep = alt_xfer(&intf->altsetting[j], xfer); + ep = alt_xfer(&intf->altsetting[j], + USB_ENDPOINT_XFER_ISOC); if (ep == NULL) continue; + if (ep->desc.bInterval == 0) { + pr_err("alt %d iso endp with 0 interval\n", j); + continue; + } psize = le16_to_cpu(ep->desc.wMaxPacketSize); - if (!gspca_dev->cam.bulk) /* isoc */ - psize = (psize & 0x07ff) * - (1 + ((psize >> 11) & 3)); - bandwidth = psize * ep->desc.bInterval * 1000; + psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + bandwidth = psize * 1000; if (gspca_dev->dev->speed == USB_SPEED_HIGH || gspca_dev->dev->speed == USB_SPEED_SUPER) bandwidth *= 8; + bandwidth /= 1 << (ep->desc.bInterval - 1); if (bandwidth <= last_bw) continue; if (bandwidth < ep_tb->bandwidth) { @@ -715,6 +727,23 @@ static int build_ep_tb(struct gspca_dev *gspca_dev, ep_tb++; } + /* + * If the camera: + * has a usb audio class interface (a built in usb mic); and + * is a usb 1 full speed device; and + * uses the max full speed iso bandwidth; and + * and has more than 1 alt setting + * then skip the highest alt setting to spare bandwidth for the mic + */ + if (gspca_dev->audio && + gspca_dev->dev->speed == USB_SPEED_FULL && + last_bw >= 1000000 && + i > 1) { + PDEBUG(D_STREAM, "dev has usb audio, skipping highest alt"); + i--; + ep_tb--; + } + /* get the requested bandwidth and start at the highest atlsetting */ bandwidth = which_bandwidth(gspca_dev); ep_tb--; @@ -790,10 +819,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, ep->desc.bEndpointAddress); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - if (gspca_dev->dev->speed == USB_SPEED_LOW) - urb->interval = ep->desc.bInterval; - else - urb->interval = 1 << (ep->desc.bInterval - 1); + urb->interval = 1 << (ep->desc.bInterval - 1); urb->complete = isoc_irq; urb->number_of_packets = npkt; for (i = 0; i < npkt; i++) { @@ -848,7 +874,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK : USB_ENDPOINT_XFER_ISOC; - /* if the subdriver forced an altsetting, get the endpoint */ + /* if bulk or the subdriver forced an altsetting, get the endpoint */ if (gspca_dev->alt != 0) { gspca_dev->alt--; /* (previous version compatibility) */ ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer); @@ -863,7 +889,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) /* else, compute the minimum bandwidth * and build the endpoint table */ - alt_idx = build_ep_tb(gspca_dev, intf, xfer, ep_tb); + alt_idx = build_isoc_ep_tb(gspca_dev, intf, ep_tb); if (alt_idx <= 0) { pr_err("no transfer endpoint found\n"); ret = -EIO; @@ -880,7 +906,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) for (;;) { if (alt != gspca_dev->alt) { alt = gspca_dev->alt; - if (gspca_dev->nbalt > 1) { + if (intf->num_altsetting > 1) { ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, alt); @@ -2300,15 +2326,14 @@ int gspca_dev_probe2(struct usb_interface *intf, } gspca_dev->dev = dev; gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber; - gspca_dev->nbalt = intf->num_altsetting; /* check if any audio device */ - if (dev->config->desc.bNumInterfaces != 1) { + if (dev->actconfig->desc.bNumInterfaces != 1) { int i; struct usb_interface *intf2; - for (i = 0; i < dev->config->desc.bNumInterfaces; i++) { - intf2 = dev->config->interface[i]; + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { + intf2 = dev->actconfig->interface[i]; if (intf2 != NULL && intf2->altsetting != NULL && intf2->altsetting->desc.bInterfaceClass == @@ -2389,7 +2414,7 @@ int gspca_dev_probe(struct usb_interface *intf, } /* the USB video interface must be the first one */ - if (dev->config->desc.bNumInterfaces != 1 + if (dev->actconfig->desc.bNumInterfaces != 1 && intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index e444f16e149..589009f4496 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -69,7 +69,9 @@ struct cam { u8 bulk; /* image transfer by 0:isoc / 1:bulk */ u8 npkt; /* number of packets in an ISOC message * 0 is the default value: 32 packets */ - u8 reverse_alts; /* Alt settings are in high to low order */ + u8 needs_full_bandwidth;/* Set this flag to notify the bandwidth calc. + * code that the cam fills all image buffers to + * the max, even when using compression. */ }; struct gspca_dev; @@ -208,7 +210,6 @@ struct gspca_dev { char memory; /* memory type (V4L2_MEMORY_xxx) */ __u8 iface; /* USB interface number */ __u8 alt; /* USB alternate setting */ - __u8 nbalt; /* number of USB alternate settings */ u8 audio; /* presence of audio device */ }; diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c new file mode 100644 index 00000000000..53f58ef367c --- /dev/null +++ b/drivers/media/video/gspca/jl2005bcd.c @@ -0,0 +1,554 @@ +/* + * Jeilin JL2005B/C/D library + * + * Copyright (C) 2011 Theodore Kilgore <kilgota@auburn.edu> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "jl2005bcd" + +#include <linux/workqueue.h> +#include <linux/slab.h> +#include "gspca.h" + + +MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>"); +MODULE_DESCRIPTION("JL2005B/C/D USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* Default timeouts, in ms */ +#define JL2005C_CMD_TIMEOUT 500 +#define JL2005C_DATA_TIMEOUT 1000 + +/* Maximum transfer size to use. */ +#define JL2005C_MAX_TRANSFER 0x200 +#define FRAME_HEADER_LEN 16 + + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + unsigned char firmware_id[6]; + const struct v4l2_pix_format *cap_mode; + /* Driver stuff */ + struct work_struct work_struct; + struct workqueue_struct *work_thread; + u8 frame_brightness; + int block_size; /* block size of camera */ + int vga; /* 1 if vga cam, 0 if cif cam */ +}; + + +/* Camera has two resolution settings. What they are depends on model. */ +static const struct v4l2_pix_format cif_mode[] = { + {176, 144, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, + {352, 288, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, +}; + +static const struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, + {640, 480, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, +}; + +/* + * cam uses endpoint 0x03 to send commands, 0x84 for read commands, + * and 0x82 for bulk data transfer. + */ + +/* All commands are two bytes only */ +static int jl2005c_write2(struct gspca_dev *gspca_dev, unsigned char *command) +{ + int retval; + + memcpy(gspca_dev->usb_buf, command, 2); + retval = usb_bulk_msg(gspca_dev->dev, + usb_sndbulkpipe(gspca_dev->dev, 3), + gspca_dev->usb_buf, 2, NULL, 500); + if (retval < 0) + pr_err("command write [%02x] error %d\n", + gspca_dev->usb_buf[0], retval); + return retval; +} + +/* Response to a command is one byte in usb_buf[0], only if requested. */ +static int jl2005c_read1(struct gspca_dev *gspca_dev) +{ + int retval; + + retval = usb_bulk_msg(gspca_dev->dev, + usb_rcvbulkpipe(gspca_dev->dev, 0x84), + gspca_dev->usb_buf, 1, NULL, 500); + if (retval < 0) + pr_err("read command [0x%02x] error %d\n", + gspca_dev->usb_buf[0], retval); + return retval; +} + +/* Response appears in gspca_dev->usb_buf[0] */ +static int jl2005c_read_reg(struct gspca_dev *gspca_dev, unsigned char reg) +{ + int retval; + + static u8 instruction[2] = {0x95, 0x00}; + /* put register to read in byte 1 */ + instruction[1] = reg; + /* Send the read request */ + retval = jl2005c_write2(gspca_dev, instruction); + if (retval < 0) + return retval; + retval = jl2005c_read1(gspca_dev); + + return retval; +} + +static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev) +{ + int i; + int retval; + int frame_brightness = 0; + + static u8 instruction[2] = {0x7f, 0x01}; + + retval = jl2005c_write2(gspca_dev, instruction); + if (retval < 0) + return retval; + + i = 0; + while (i < 20 && !frame_brightness) { + /* If we tried 20 times, give up. */ + retval = jl2005c_read_reg(gspca_dev, 0x7e); + if (retval < 0) + return retval; + frame_brightness = gspca_dev->usb_buf[0]; + retval = jl2005c_read_reg(gspca_dev, 0x7d); + if (retval < 0) + return retval; + i++; + } + PDEBUG(D_FRAM, "frame_brightness is 0x%02x", gspca_dev->usb_buf[0]); + return retval; +} + +static int jl2005c_write_reg(struct gspca_dev *gspca_dev, unsigned char reg, + unsigned char value) +{ + int retval; + u8 instruction[2]; + + instruction[0] = reg; + instruction[1] = value; + + retval = jl2005c_write2(gspca_dev, instruction); + if (retval < 0) + return retval; + + return retval; +} + +static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *)gspca_dev; + int i = 0; + int retval = -1; + unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f}; + + PDEBUG(D_PROBE, "Running jl2005c_get_firmware_id"); + /* Read the first ID byte once for warmup */ + retval = jl2005c_read_reg(gspca_dev, regs_to_read[0]); + PDEBUG(D_PROBE, "response is %02x", gspca_dev->usb_buf[0]); + if (retval < 0) + return retval; + /* Now actually get the ID string */ + for (i = 0; i < 6; i++) { + retval = jl2005c_read_reg(gspca_dev, regs_to_read[i]); + if (retval < 0) + return retval; + sd->firmware_id[i] = gspca_dev->usb_buf[0]; + } + PDEBUG(D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x", + sd->firmware_id[0], + sd->firmware_id[1], + sd->firmware_id[2], + sd->firmware_id[3], + sd->firmware_id[4], + sd->firmware_id[5]); + return 0; +} + +static int jl2005c_stream_start_vga_lg + (struct gspca_dev *gspca_dev) +{ + int i; + int retval = -1; + static u8 instruction[][2] = { + {0x05, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x18}, + {0x02, 0x00}, + {0x01, 0x00}, + {0x04, 0x52}, + }; + + for (i = 0; i < ARRAY_SIZE(instruction); i++) { + msleep(60); + retval = jl2005c_write2(gspca_dev, instruction[i]); + if (retval < 0) + return retval; + } + msleep(60); + return retval; +} + +static int jl2005c_stream_start_vga_small(struct gspca_dev *gspca_dev) +{ + int i; + int retval = -1; + static u8 instruction[][2] = { + {0x06, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x1a}, + {0x02, 0x00}, + {0x01, 0x00}, + {0x04, 0x52}, + }; + + for (i = 0; i < ARRAY_SIZE(instruction); i++) { + msleep(60); + retval = jl2005c_write2(gspca_dev, instruction[i]); + if (retval < 0) + return retval; + } + msleep(60); + return retval; +} + +static int jl2005c_stream_start_cif_lg(struct gspca_dev *gspca_dev) +{ + int i; + int retval = -1; + static u8 instruction[][2] = { + {0x05, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x30}, + {0x02, 0x00}, + {0x01, 0x00}, + {0x04, 0x42}, + }; + + for (i = 0; i < ARRAY_SIZE(instruction); i++) { + msleep(60); + retval = jl2005c_write2(gspca_dev, instruction[i]); + if (retval < 0) + return retval; + } + msleep(60); + return retval; +} + +static int jl2005c_stream_start_cif_small(struct gspca_dev *gspca_dev) +{ + int i; + int retval = -1; + static u8 instruction[][2] = { + {0x06, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x32}, + {0x02, 0x00}, + {0x01, 0x00}, + {0x04, 0x42}, + }; + + for (i = 0; i < ARRAY_SIZE(instruction); i++) { + msleep(60); + retval = jl2005c_write2(gspca_dev, instruction[i]); + if (retval < 0) + return retval; + } + msleep(60); + return retval; +} + + +static int jl2005c_stop(struct gspca_dev *gspca_dev) +{ + int retval; + + retval = jl2005c_write_reg(gspca_dev, 0x07, 0x00); + return retval; +} + +/* This function is called as a workqueue function and runs whenever the camera + * is streaming data. Because it is a workqueue function it is allowed to sleep + * so we can use synchronous USB calls. To avoid possible collisions with other + * threads attempting to use the camera's USB interface the gspca usb_lock is + * used when performing the one USB control operation inside the workqueue, + * which tells the camera to close the stream. In practice the only thing + * which needs to be protected against is the usb_set_interface call that + * gspca makes during stream_off. Otherwise the camera doesn't provide any + * controls that the user could try to change. + */ +static void jl2005c_dostream(struct work_struct *work) +{ + struct sd *dev = container_of(work, struct sd, work_struct); + struct gspca_dev *gspca_dev = &dev->gspca_dev; + int bytes_left = 0; /* bytes remaining in current frame. */ + int data_len; /* size to use for the next read. */ + int header_read = 0; + unsigned char header_sig[2] = {0x4a, 0x4c}; + int act_len; + int packet_type; + int ret; + u8 *buffer; + + buffer = kmalloc(JL2005C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); + if (!buffer) { + pr_err("Couldn't allocate USB buffer\n"); + goto quit_stream; + } + + while (gspca_dev->present && gspca_dev->streaming) { + /* Check if this is a new frame. If so, start the frame first */ + if (!header_read) { + mutex_lock(&gspca_dev->usb_lock); + ret = jl2005c_start_new_frame(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + if (ret < 0) + goto quit_stream; + ret = usb_bulk_msg(gspca_dev->dev, + usb_rcvbulkpipe(gspca_dev->dev, 0x82), + buffer, JL2005C_MAX_TRANSFER, &act_len, + JL2005C_DATA_TIMEOUT); + PDEBUG(D_PACK, + "Got %d bytes out of %d for header", + act_len, JL2005C_MAX_TRANSFER); + if (ret < 0 || act_len < JL2005C_MAX_TRANSFER) + goto quit_stream; + /* Check whether we actually got the first blodk */ + if (memcmp(header_sig, buffer, 2) != 0) { + pr_err("First block is not the first block\n"); + goto quit_stream; + } + /* total size to fetch is byte 7, times blocksize + * of which we already got act_len */ + bytes_left = buffer[0x07] * dev->block_size - act_len; + PDEBUG(D_PACK, "bytes_left = 0x%x", bytes_left); + /* We keep the header. It has other information, too.*/ + packet_type = FIRST_PACKET; + gspca_frame_add(gspca_dev, packet_type, + buffer, act_len); + header_read = 1; + } + while (bytes_left > 0 && gspca_dev->present) { + data_len = bytes_left > JL2005C_MAX_TRANSFER ? + JL2005C_MAX_TRANSFER : bytes_left; + ret = usb_bulk_msg(gspca_dev->dev, + usb_rcvbulkpipe(gspca_dev->dev, 0x82), + buffer, data_len, &act_len, + JL2005C_DATA_TIMEOUT); + if (ret < 0 || act_len < data_len) + goto quit_stream; + PDEBUG(D_PACK, + "Got %d bytes out of %d for frame", + data_len, bytes_left); + bytes_left -= data_len; + if (bytes_left == 0) { + packet_type = LAST_PACKET; + header_read = 0; + } else + packet_type = INTER_PACKET; + gspca_frame_add(gspca_dev, packet_type, + buffer, data_len); + } + } +quit_stream: + if (gspca_dev->present) { + mutex_lock(&gspca_dev->usb_lock); + jl2005c_stop(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + } + kfree(buffer); +} + + + + +/* This function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct cam *cam; + struct sd *sd = (struct sd *) gspca_dev; + + cam = &gspca_dev->cam; + /* We don't use the buffer gspca allocates so make it small. */ + cam->bulk_size = 64; + cam->bulk = 1; + /* For the rest, the camera needs to be detected */ + jl2005c_get_firmware_id(gspca_dev); + /* Here are some known firmware IDs + * First some JL2005B cameras + * {0x41, 0x07, 0x04, 0x2c, 0xe8, 0xf2} Sakar KidzCam + * {0x45, 0x02, 0x08, 0xb9, 0x00, 0xd2} No-name JL2005B + * JL2005C cameras + * {0x01, 0x0c, 0x16, 0x10, 0xf8, 0xc8} Argus DC-1512 + * {0x12, 0x04, 0x03, 0xc0, 0x00, 0xd8} ICarly + * {0x86, 0x08, 0x05, 0x02, 0x00, 0xd4} Jazz + * + * Based upon this scanty evidence, we can detect a CIF camera by + * testing byte 0 for 0x4x. + */ + if ((sd->firmware_id[0] & 0xf0) == 0x40) { + cam->cam_mode = cif_mode; + cam->nmodes = ARRAY_SIZE(cif_mode); + sd->block_size = 0x80; + } else { + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); + sd->block_size = 0x200; + } + + INIT_WORK(&sd->work_struct, jl2005c_dostream); + + return 0; +} + +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + return 0; +} + +static int sd_start(struct gspca_dev *gspca_dev) +{ + + struct sd *sd = (struct sd *) gspca_dev; + sd->cap_mode = gspca_dev->cam.cam_mode; + + switch (gspca_dev->width) { + case 640: + PDEBUG(D_STREAM, "Start streaming at vga resolution"); + jl2005c_stream_start_vga_lg(gspca_dev); + break; + case 320: + PDEBUG(D_STREAM, "Start streaming at qvga resolution"); + jl2005c_stream_start_vga_small(gspca_dev); + break; + case 352: + PDEBUG(D_STREAM, "Start streaming at cif resolution"); + jl2005c_stream_start_cif_lg(gspca_dev); + break; + case 176: + PDEBUG(D_STREAM, "Start streaming at qcif resolution"); + jl2005c_stream_start_cif_small(gspca_dev); + break; + default: + pr_err("Unknown resolution specified\n"); + return -1; + } + + /* Start the workqueue function to do the streaming */ + sd->work_thread = create_singlethread_workqueue(MODULE_NAME); + queue_work(sd->work_thread, &sd->work_struct); + + return 0; +} + +/* called on streamoff with alt==0 and on disconnect */ +/* the usb_lock is held at entry - restore on exit */ +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + + /* wait for the work queue to terminate */ + mutex_unlock(&gspca_dev->usb_lock); + /* This waits for sq905c_dostream to finish */ + destroy_workqueue(dev->work_thread); + dev->work_thread = NULL; + mutex_lock(&gspca_dev->usb_lock); +} + + + +/* sub-driver description */ +static const struct sd_desc sd_desc = { + .name = MODULE_NAME, + /* .ctrls = none have been detected */ + /* .nctrls = ARRAY_SIZE(sd_ctrls), */ + .config = sd_config, + .init = sd_init, + .start = sd_start, + .stop0 = sd_stop0, +}; + +/* -- module initialisation -- */ +static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0979, 0x0227)}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + int ret; + + ret = usb_register(&sd_driver); + if (ret < 0) + return ret; + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c index b1da7f4096c..f0c0d74dfe9 100644 --- a/drivers/media/video/gspca/konica.c +++ b/drivers/media/video/gspca/konica.c @@ -247,9 +247,6 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); gspca_dev->cam.no_urb_create = 1; - /* The highest alt setting has an isoc packetsize of 0, so we - don't want to use it */ - gspca_dev->nbalt--; sd->brightness = BRIGHTNESS_DEFAULT; sd->contrast = CONTRAST_DEFAULT; diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 9fe3816b2aa..0c449367543 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c @@ -27,8 +27,8 @@ /* Kernel module parameters */ int force_sensor; -static int dump_bridge; -int dump_sensor; +static bool dump_bridge; +bool dump_sensor; static const struct usb_device_id m5602_table[] = { {USB_DEVICE(0x0402, 0x5602)}, diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index b1f0c492036..8c672b5c8c6 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h @@ -106,7 +106,7 @@ /* Kernel module parameters */ extern int force_sensor; -extern int dump_sensor; +extern bool dump_sensor; int mt9m111_probe(struct sd *sd); int mt9m111_init(struct sd *sd); diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h index 2efd607987e..2b6a13b508f 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov7660.h +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h @@ -86,7 +86,7 @@ /* Kernel module parameters */ extern int force_sensor; -extern int dump_sensor; +extern bool dump_sensor; int ov7660_probe(struct sd *sd); int ov7660_init(struct sd *sd); diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index da9a129b739..f7aa5bf6898 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h @@ -135,7 +135,7 @@ /* Kernel module parameters */ extern int force_sensor; -extern int dump_sensor; +extern bool dump_sensor; int ov9650_probe(struct sd *sd); int ov9650_init(struct sd *sd); diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index 33835959639..81a2bcb88fe 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h @@ -147,7 +147,7 @@ /* Kernel module parameters */ extern int force_sensor; -extern int dump_sensor; +extern bool dump_sensor; int po1030_probe(struct sd *sd); int po1030_init(struct sd *sd); diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index 8cc7a3f6da7..8e0035e731c 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h @@ -65,7 +65,7 @@ /* Kernel module parameters */ extern int force_sensor; -extern int dump_sensor; +extern bool dump_sensor; int s5k4aa_probe(struct sd *sd); int s5k4aa_init(struct sd *sd); diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 80a63a236e2..79952247b53 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h @@ -41,7 +41,7 @@ /* Kernel module parameters */ extern int force_sensor; -extern int dump_sensor; +extern bool dump_sensor; int s5k83a_probe(struct sd *sd); int s5k83a_init(struct sd *sd); diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 5c2ea05c46b..b0231465afa 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -263,7 +263,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(vga_mode); cam->ctrls = sd->ctrls; sd->quality = QUALITY_DEF; - gspca_dev->nbalt = 9; /* use the altsetting 08 */ return 0; } diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c index d4bec932177..7167cac7359 100644 --- a/drivers/media/video/gspca/nw80x.c +++ b/drivers/media/video/gspca/nw80x.c @@ -1763,8 +1763,8 @@ static int sd_config(struct gspca_dev *gspca_dev, if ((unsigned) webcam >= NWEBCAMS) webcam = 0; sd->webcam = webcam; - gspca_dev->cam.reverse_alts = 1; gspca_dev->cam.ctrls = sd->ctrls; + gspca_dev->cam.needs_full_bandwidth = 1; sd->ag_cnt = -1; /* diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 08b8ce1dee1..739e8a2a2d3 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -3348,7 +3348,6 @@ static int sd_config(struct gspca_dev *gspca_dev, case BRIDGE_W9968CF: cam->cam_mode = w9968cf_vga_mode; cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); - cam->reverse_alts = 1; break; } @@ -3684,8 +3683,8 @@ static void ov511_mode_init_regs(struct sd *sd) /* Check if we have enough bandwidth to disable compression */ fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1; needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2; - /* 1400 is a conservative estimate of the max nr of isoc packets/sec */ - if (needed > 1400 * packet_size) { + /* 1000 isoc packets/sec */ + if (needed > 1000 * packet_size) { /* Enable Y and UV quantization and compression */ reg_w(sd, R511_COMP_EN, 0x07); reg_w(sd, R511_COMP_LUT_EN, 0x03); diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index f30060d5063..fbfa02affa1 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c @@ -71,6 +71,7 @@ struct sd { enum sensors { SENSOR_OV965x, /* ov9657 */ SENSOR_OV971x, /* ov9712 */ + SENSOR_OV562x, /* ov5621 */ NSENSORS }; @@ -207,6 +208,14 @@ static const struct v4l2_pix_format ov971x_mode[] = { } }; +static const struct v4l2_pix_format ov562x_mode[] = { + {2592, 1680, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 2592, + .sizeimage = 2592 * 1680, + .colorspace = V4L2_COLORSPACE_SRGB + } +}; + static const u8 bridge_init[][2] = { {0x88, 0xf8}, {0x89, 0xff}, @@ -830,6 +839,124 @@ static const u8 ov965x_start_2_sxga[][2] = { {0xa3, 0x41}, /* bd60 */ }; +static const u8 ov562x_init[][2] = { + {0x88, 0x20}, + {0x89, 0x0a}, + {0x8a, 0x90}, + {0x8b, 0x06}, + {0x8c, 0x01}, + {0x8d, 0x10}, + {0x1c, 0x00}, + {0x1d, 0x48}, + {0x1d, 0x00}, + {0x1d, 0xff}, + {0x1c, 0x0a}, + {0x1d, 0x2e}, + {0x1d, 0x1e}, +}; + +static const u8 ov562x_init_2[][2] = { + {0x12, 0x80}, + {0x11, 0x41}, + {0x13, 0x00}, + {0x10, 0x1e}, + {0x3b, 0x07}, + {0x5b, 0x40}, + {0x39, 0x07}, + {0x53, 0x02}, + {0x54, 0x60}, + {0x04, 0x20}, + {0x27, 0x04}, + {0x3d, 0x40}, + {0x36, 0x00}, + {0xc5, 0x04}, + {0x4e, 0x00}, + {0x4f, 0x93}, + {0x50, 0x7b}, + {0xca, 0x0c}, + {0xcb, 0x0f}, + {0x39, 0x07}, + {0x4a, 0x10}, + {0x3e, 0x0a}, + {0x3d, 0x00}, + {0x0c, 0x38}, + {0x38, 0x90}, + {0x46, 0x30}, + {0x4f, 0x93}, + {0x50, 0x7b}, + {0xab, 0x00}, + {0xca, 0x0c}, + {0xcb, 0x0f}, + {0x37, 0x02}, + {0x44, 0x48}, + {0x8d, 0x44}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x32, 0x00}, + {0x38, 0x90}, + {0x53, 0x02}, + {0x54, 0x60}, + {0x12, 0x00}, + {0x17, 0x12}, + {0x18, 0xb4}, + {0x19, 0x0c}, + {0x1a, 0xf4}, + {0x03, 0x4a}, + {0x89, 0x20}, + {0x83, 0x80}, + {0xb7, 0x9d}, + {0xb6, 0x11}, + {0xb5, 0x55}, + {0xb4, 0x00}, + {0xa9, 0xf0}, + {0xa8, 0x0a}, + {0xb8, 0xf0}, + {0xb9, 0xf0}, + {0xba, 0xf0}, + {0x81, 0x07}, + {0x63, 0x44}, + {0x13, 0xc7}, + {0x14, 0x60}, + {0x33, 0x75}, + {0x2c, 0x00}, + {0x09, 0x00}, + {0x35, 0x30}, + {0x27, 0x04}, + {0x3c, 0x07}, + {0x3a, 0x0a}, + {0x3b, 0x07}, + {0x01, 0x40}, + {0x02, 0x40}, + {0x16, 0x40}, + {0x52, 0xb0}, + {0x51, 0x83}, + {0x21, 0xbb}, + {0x22, 0x10}, + {0x23, 0x03}, + {0x35, 0x38}, + {0x20, 0x90}, + {0x28, 0x30}, + {0x73, 0xe1}, + {0x6c, 0x00}, + {0x6d, 0x80}, + {0x6e, 0x00}, + {0x70, 0x04}, + {0x71, 0x00}, + {0x8d, 0x04}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x71, 0x94}, + {0x74, 0x20}, + {0x80, 0x09}, + {0x85, 0xc0}, +}; + static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val) { struct usb_device *udev = gspca_dev->dev; @@ -1210,6 +1337,17 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x56, 0x1f); else reg_w(gspca_dev, 0x56, 0x17); + } else if ((sensor_id & 0xfff0) == 0x5620) { + sd->sensor = SENSOR_OV562x; + + gspca_dev->cam.cam_mode = ov562x_mode; + gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); + + reg_w_array(gspca_dev, ov562x_init, + ARRAY_SIZE(ov562x_init)); + sccb_w_array(gspca_dev, ov562x_init_2, + ARRAY_SIZE(ov562x_init_2)); + reg_w(gspca_dev, 0xe0, 0x00); } else { err("Unknown sensor %04x", sensor_id); return -EINVAL; @@ -1222,7 +1360,7 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (sd->sensor == SENSOR_OV971x) + if (sd->sensor == SENSOR_OV971x || sd->sensor == SENSOR_OV562x) return gspca_dev->usb_err; switch (gspca_dev->curr_mode) { case QVGA_MODE: /* 320x240 */ @@ -1409,6 +1547,7 @@ static const struct sd_desc sd_desc = { static const struct usb_device_id device_table[] = { {USB_DEVICE(0x05a9, 0x8065)}, {USB_DEVICE(0x06f8, 0x3003)}, + {USB_DEVICE(0x05a9, 0x1550)}, {} }; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index ece8b1e82a1..3844c49f269 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -41,14 +41,14 @@ MODULE_LICENSE("GPL"); #define PAC207_BRIGHTNESS_DEFAULT 46 #define PAC207_EXPOSURE_MIN 3 -#define PAC207_EXPOSURE_MAX 26 +#define PAC207_EXPOSURE_MAX 90 /* 1 sec expo time / 1 fps */ #define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */ -#define PAC207_EXPOSURE_KNEE 8 /* 4 = 30 fps, 11 = 8, 15 = 6 */ +#define PAC207_EXPOSURE_KNEE 9 /* fps: 90 / exposure -> 9: 10 fps */ #define PAC207_GAIN_MIN 0 #define PAC207_GAIN_MAX 31 -#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */ -#define PAC207_GAIN_KNEE 31 +#define PAC207_GAIN_DEFAULT 7 /* power on default: 9 */ +#define PAC207_GAIN_KNEE 15 #define PAC207_AUTOGAIN_DEADZONE 30 @@ -332,7 +332,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) if (sd->autogain_ignore_frames > 0) sd->autogain_ignore_frames--; else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, - 100, PAC207_AUTOGAIN_DEADZONE, + 90, PAC207_AUTOGAIN_DEADZONE, PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; } diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 2811195258c..9db2b34d172 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -1197,6 +1197,7 @@ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x262a)}, {USB_DEVICE(0x093a, 0x262c)}, + {USB_DEVICE(0x145f, 0x013c)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c index 1494e1829d3..bb70092c222 100644 --- a/drivers/media/video/gspca/se401.c +++ b/drivers/media/video/gspca/se401.c @@ -376,7 +376,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->bulk_size = BULK_SIZE; cam->bulk_nurbs = 4; cam->ctrls = sd->ctrls; - gspca_dev->nbalt = 1; /* Ignore the bogus isoc alt settings */ sd->resetlevel = 0x2d; /* Set initial resetlevel */ /* See if the camera supports brightness */ @@ -395,6 +394,14 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } +/* function called at start time before URB creation */ +static int sd_isoc_init(struct gspca_dev *gspca_dev) +{ + gspca_dev->alt = 1; /* Ignore the bogus isoc alt settings */ + + return gspca_dev->usb_err; +} + /* -- start the camera -- */ static int sd_start(struct gspca_dev *gspca_dev) { @@ -714,6 +721,7 @@ static const struct sd_desc sd_desc = { .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .init = sd_init, + .isoc_init = sd_isoc_init, .start = sd_start, .stopN = sd_stopN, .dq_callback = sd_dq_callback, diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 33cabc342dc..9e198b45c3c 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -2048,6 +2048,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->needs_full_bandwidth = 1; sd->sensor = (id->driver_info >> 8) & 0xff; sd->i2c_addr = id->driver_info & 0xff; @@ -2233,6 +2234,42 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) } } +static int sd_isoc_init(struct gspca_dev *gspca_dev) +{ + struct usb_interface *intf; + u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv; + + /* + * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth + * than our regular bandwidth calculations reserve, so we force the + * use of a specific altsetting when using the SN9C20X_I420 fmt. + */ + if (!(flags & (MODE_RAW | MODE_JPEG))) { + intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); + + if (intf->num_altsetting != 9) { + pr_warn("sn9c20x camera with unknown number of alt " + "settings (%d), please report!\n", + intf->num_altsetting); + gspca_dev->alt = intf->num_altsetting; + return 0; + } + + switch (gspca_dev->width) { + case 160: /* 160x120 */ + gspca_dev->alt = 2; + break; + case 320: /* 320x240 */ + gspca_dev->alt = 6; + break; + default: /* >= 640x480 */ + gspca_dev->alt = 9; + } + } + + return 0; +} + #define HW_WIN(mode, hstart, vstart) \ ((const u8 []){hstart, 0, vstart, 0, \ (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ @@ -2473,6 +2510,7 @@ static const struct sd_desc sd_desc = { .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .init = sd_init, + .isoc_init = sd_isoc_init, .start = sd_start, .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index ddb392dc4f2..6a1148d7fe9 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1079,20 +1079,23 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam->npkt = 36; /* 36 packets per ISOC message */ - if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { - sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN; - sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX; - sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF; - } - return 0; } /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; const __u8 stop = 0x09; /* Disable stream turn of LED */ + if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { + sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN; + sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX; + sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF; + if (sd->ctrls[EXPOSURE].val > COARSE_EXPOSURE_MAX) + sd->ctrls[EXPOSURE].val = COARSE_EXPOSURE_DEF; + } + reg_w(gspca_dev, 0x01, &stop, 1); return 0; diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index afa3186b803..0c9e6ddabd2 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1235,7 +1235,7 @@ static const u8 po2030n_sensor_param1[][8] = { {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10}, + {0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */ /*param2*/ {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, @@ -1779,10 +1779,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->ag_cnt = -1; sd->quality = QUALITY_DEF; - /* if USB 1.1, let some bandwidth for the audio device */ - if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH) - gspca_dev->nbalt--; - INIT_WORK(&sd->work, qual_upd); return 0; @@ -2063,6 +2059,16 @@ static void setredblue(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + if (sd->sensor == SENSOR_PO2030N) { + u8 rg1b[] = /* red green1 blue (no g2) */ + {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; + + /* 0x40 = normal value = gain x 1 */ + rg1b[3] = sd->ctrls[RED].val * 2; + rg1b[5] = sd->ctrls[BLUE].val * 2; + i2c_w8(gspca_dev, rg1b); + return; + } reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); /* reg_w1(gspca_dev, 0x07, 32); */ reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); @@ -2397,7 +2403,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x17, reg17); reg01 &= ~S_PWR_DN; /* sensor power on */ reg_w1(gspca_dev, 0x01, reg01); - reg01 &= ~SYS_SEL_48M; + reg01 &= ~SCL_SEL_OD; /* remove open-drain mode */ reg_w1(gspca_dev, 0x01, reg01); switch (sd->sensor) { diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 259a0c73c66..4a5f209ce71 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -451,7 +451,7 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ + cam->needs_full_bandwidth = 1; sd->chip_revision = id->driver_info; if (sd->chip_revision == Rev012A) { diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 0ab425fbea9..91d99b4cc57 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -36,8 +36,8 @@ MODULE_AUTHOR("Erik Andrén"); MODULE_DESCRIPTION("STV06XX USB Camera Driver"); MODULE_LICENSE("GPL"); -static int dump_bridge; -static int dump_sensor; +static bool dump_bridge; +static bool dump_sensor; int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data) { @@ -304,7 +304,7 @@ static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; + alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); @@ -317,7 +317,7 @@ static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) struct usb_host_interface *alt; struct sd *sd = (struct sd *) gspca_dev; - alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; + alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; if (packet_size <= min_packet_size) diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index ea44deb66af..9b9f85a8e60 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -30,6 +30,7 @@ #define MODULE_NAME "t613" +#include <linux/input.h> #include <linux/slab.h> #include "gspca.h" @@ -57,6 +58,7 @@ struct sd { u8 effect; u8 sensor; + u8 button_pressed; }; enum sensors { SENSOR_OM6802, @@ -1095,15 +1097,35 @@ static void sd_stopN(struct gspca_dev *gspca_dev) msleep(20); reg_w(gspca_dev, 0x0309); } +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + /* If the last button state is pressed, release it now! */ + if (sd->button_pressed) { + input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); + input_sync(gspca_dev->input_dev); + sd->button_pressed = 0; + } +#endif } static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, /* isoc packet */ int len) /* iso packet length */ { + struct sd *sd = (struct sd *) gspca_dev; int pkt_type; if (data[0] == 0x5a) { +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + if (len > 20) { + u8 state = (data[20] & 0x80) ? 1 : 0; + if (sd->button_pressed != state) { + input_report_key(gspca_dev->input_dev, + KEY_CAMERA, state); + input_sync(gspca_dev->input_dev); + sd->button_pressed = state; + } + } +#endif /* Control Packet, after this came the header again, * but extra bytes came in the packet before this, * sometimes an EOF arrives, sometimes not... */ @@ -1410,6 +1432,9 @@ static const struct sd_desc sd_desc = { .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, +#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) + .other_input = 1, +#endif }; /* -- module initialisation -- */ diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c index b2695b1dc60..444d3c5b907 100644 --- a/drivers/media/video/gspca/topro.c +++ b/drivers/media/video/gspca/topro.c @@ -3946,7 +3946,7 @@ static int get_fr_idx(struct gspca_dev *gspca_dev) /* 640x480 * 30 fps does not work */ if (i == 6 /* if 30 fps */ && gspca_dev->width == 640) - i = 0x86; /* 15 fps */ + i = 0x05; /* 15 fps */ } else { for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) { if (sd->framerate >= rates_6810[i]) diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c index d12ea1518ac..911152e169d 100644 --- a/drivers/media/video/gspca/vicam.c +++ b/drivers/media/video/gspca/vicam.c @@ -324,7 +324,8 @@ static void sd_stop0(struct gspca_dev *gspca_dev) dev->work_thread = NULL; mutex_lock(&gspca_dev->usb_lock); - vicam_set_camera_power(gspca_dev, 0); + if (gspca_dev->present) + vicam_set_camera_power(gspca_dev, 0); } /* Table of supported USB devices */ diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c index fbb6ed25ec3..ecada178bce 100644 --- a/drivers/media/video/gspca/xirlink_cit.c +++ b/drivers/media/video/gspca/xirlink_cit.c @@ -995,14 +995,12 @@ static int sd_config(struct gspca_dev *gspca_dev, case CIT_MODEL0: cam->cam_mode = model0_mode; cam->nmodes = ARRAY_SIZE(model0_mode); - cam->reverse_alts = 1; gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP)); sd->sof_len = 4; break; case CIT_MODEL1: cam->cam_mode = cif_yuv_mode; cam->nmodes = ARRAY_SIZE(cif_yuv_mode); - cam->reverse_alts = 1; gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP); sd->sof_len = 4; break; @@ -2791,7 +2789,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) } /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; + alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size); return 0; @@ -2814,7 +2812,7 @@ static int sd_isoc_nego(struct gspca_dev *gspca_dev) break; } - alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; + alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); if (packet_size <= min_packet_size) return -EIO; diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 0202fead6b9..b9e15bb0328 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -5381,12 +5381,12 @@ static const struct usb_action tas5130c_NoFlikerScale[] = { {} }; -static const struct usb_action gc0303_InitialScale[] = { +/* from usbvm305.inf 0ac8:305b 07/06/15 (3 - tas5130c) */ +static const struct usb_action gc0303_Initial[] = { {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc, - * 0<->10 */ + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ @@ -5405,29 +5405,22 @@ static const struct usb_action gc0303_InitialScale[] = { * 6<->8 */ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ - {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ - {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ - {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ - {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ -/*?? {0xaa, 0x01, 0x0000}, */ {0xaa, 0x01, 0x0000}, {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ + {0xaa, 0x1b, 0x0000}, {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ - {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ - {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ - {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ - {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ - {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ - {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ - {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ -/*?? {0xa0, 0x00, 0x0039}, - {0xa1, 0x01, 0x0037}, */ + {0xaa, 0x0a, 0x0002}, + {0xaa, 0x0b, 0x0000}, + {0xaa, 0x0c, 0x0002}, + {0xaa, 0x0d, 0x0000}, + {0xaa, 0x0e, 0x0002}, + {0xaa, 0x0f, 0x0000}, + {0xaa, 0x10, 0x0002}, + {0xaa, 0x11, 0x0000}, {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ @@ -5442,17 +5435,18 @@ static const struct usb_action gc0303_InitialScale[] = { {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ + {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ + {0xaa, 0x1b, 0x0000}, {} }; -static const struct usb_action gc0303_Initial[] = { +static const struct usb_action gc0303_InitialScale[] = { {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc, */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ @@ -5471,34 +5465,26 @@ static const struct usb_action gc0303_Initial[] = { * 8<->6 */ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ - {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ - {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ - {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ - {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ -/*?? {0xaa, 0x01, 0x0000}, */ {0xaa, 0x01, 0x0000}, {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ + {0xaa, 0x1b, 0x0000}, {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ - {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ - {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ - {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ - {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ - {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ - {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ - {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ -/*?? {0xa0, 0x00, 0x0039}, - {0xa1, 0x01, 0x0037}, */ + {0xaa, 0x0a, 0x0001}, + {0xaa, 0x0b, 0x0000}, + {0xaa, 0x0c, 0x0001}, + {0xaa, 0x0d, 0x0000}, + {0xaa, 0x0e, 0x0001}, + {0xaa, 0x0f, 0x0000}, + {0xaa, 0x10, 0x0001}, + {0xaa, 0x11, 0x0000}, {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ - {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ @@ -5508,36 +5494,37 @@ static const struct usb_action gc0303_Initial[] = { {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ + {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ + {0xaa, 0x1b, 0x0000}, {} }; -static const struct usb_action gc0303_50HZScale[] = { +static const struct usb_action gc0303_50HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ - {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ + {0xaa, 0x84, 0x0063}, {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ - {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ + {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ + {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ + {0xa0, 0x7f, ZC3XX_R18D_YTARGET}, {} }; -static const struct usb_action gc0303_50HZ[] = { +static const struct usb_action gc0303_50HZScale[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ @@ -5550,21 +5537,21 @@ static const struct usb_action gc0303_50HZ[] = { {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ + {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ + {0xa0, 0x7f, ZC3XX_R18D_YTARGET}, {} }; -static const struct usb_action gc0303_60HZScale[] = { +static const struct usb_action gc0303_60HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ - {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ + {0xaa, 0x83, 0x0000}, + {0xaa, 0x84, 0x003b}, {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ @@ -5581,14 +5568,14 @@ static const struct usb_action gc0303_60HZScale[] = { {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ + {0xa0, 0x80, ZC3XX_R18D_YTARGET}, {} }; -static const struct usb_action gc0303_60HZ[] = { +static const struct usb_action gc0303_60HZScale[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ - {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ + {0xaa, 0x83, 0x0000}, + {0xaa, 0x84, 0x0076}, {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */ {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */ @@ -5605,18 +5592,18 @@ static const struct usb_action gc0303_60HZ[] = { {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,d,78,cc */ + {0xa0, 0x80, ZC3XX_R18D_YTARGET}, {} }; -static const struct usb_action gc0303_NoFlikerScale[] = { +static const struct usb_action gc0303_NoFliker[] = { {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */ - {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ - {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ + {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ @@ -5631,14 +5618,14 @@ static const struct usb_action gc0303_NoFlikerScale[] = { {} }; -static const struct usb_action gc0303_NoFliker[] = { +static const struct usb_action gc0303_NoFlikerScale[] = { {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ - {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc, */ - {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc, */ + {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ @@ -5809,7 +5796,7 @@ static void setmatrix(struct gspca_dev *gspca_dev) static const u8 tas5130c_matrix[9] = {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; static const u8 gc0303_matrix[9] = - {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; + {0x6c, 0xea, 0xea, 0xea, 0x6c, 0xea, 0xea, 0xea, 0x6c}; static const u8 *matrix_tb[SENSOR_MAX] = { [SENSOR_ADCM2700] = adcm2700_matrix, [SENSOR_CS2102] = ov7620_matrix, @@ -6426,10 +6413,6 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->cam.ctrls = sd->ctrls; sd->quality = QUALITY_DEF; - /* if USB 1.1, let some bandwidth for the audio device */ - if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH) - gspca_dev->nbalt--; - return 0; } |