summaryrefslogtreecommitdiff
path: root/drivers/media/usb/gspca
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 03:55:48 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 03:55:48 +0300
commit5b4ca4447757019f11a601b0009534ef84bed801 (patch)
tree09bc8445e61aea621580d7587c21ac3f2b0cafb4 /drivers/media/usb/gspca
parent0db9723cacf4d62bc3685fb15179b39ee4e17679 (diff)
parentfaebbd8f134f0c054f372982c8ddd1bbcc41b440 (diff)
downloadlinux-5b4ca4447757019f11a601b0009534ef84bed801.tar.xz
Merge tag 'media/v4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - Lots of improvements at the DVB API DocBook documentation. Now, the frontend and the network APIs are fully in sync with the Kernel and looks more like the rest of the media documentation; - New frontend driver: cx24120 - New driver for a PCI device: cobalt. This driver is actually not sold in the market, but it is a good example of a multi-HDMI input device; - The dt3155 driver were promoted from staging; - The mantis driver got remote controller support; - New V4L2 driver for ST bdisp SoC chipsets; - Make sparse and smatch happier: several bugs were solved by fixing the issues reported by those static code analyzers. - Lots of new device additions, new features, improvements and cleanups at the existing drivers. * tag 'media/v4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (553 commits) [media] lmedm04: fix the range for relative measurements [media] lmedm04: use u32 instead of u64 for relative stats [media] omap3isp: remove unused var [media] saa7134: fix page size on some archs [media] use CONFIG_PM_SLEEP for suspend/resume [media] tuner-i2c: be consistent with I2C declaration [media] si470x: cleanup define namespace [media] bdisp: prevent compiling on random arch [media] vb2: Don't WARN when v4l2_buffer.bytesused is 0 for multiplanar buffers [media] MAINTAINERS: Add entry for the Renesas VSP1 driver [media] videodev2.h: fix copy-and-paste error in V4L2_MAP_XFER_FUNC_DEFAULT [media] Revert "[media] vb2: Push mmap_sem down to memops" [media] mantis: cleanup a warning [media] bdisp-debug: don't try to divide by s64 [media] cx88: don't declare restart_video_queue if not used [media] au0828: move dev->boards atribuition to happen earlier [media] lmedm04: implement dvb v5 statistics [media] bdisp: remove unused var [media] bdisp: remove needless check ts2020: fix compilation on i386 ...
Diffstat (limited to 'drivers/media/usb/gspca')
-rw-r--r--drivers/media/usb/gspca/benq.c4
-rw-r--r--drivers/media/usb/gspca/sn9c2028.c241
-rw-r--r--drivers/media/usb/gspca/sn9c2028.h18
-rw-r--r--drivers/media/usb/gspca/sonixj.c2
-rw-r--r--drivers/media/usb/gspca/stk014.c2
-rw-r--r--drivers/media/usb/gspca/xirlink_cit.c12
-rw-r--r--drivers/media/usb/gspca/zc3xx.c16
7 files changed, 276 insertions, 19 deletions
diff --git a/drivers/media/usb/gspca/benq.c b/drivers/media/usb/gspca/benq.c
index 05f406deae13..790baed33963 100644
--- a/drivers/media/usb/gspca/benq.c
+++ b/drivers/media/usb/gspca/benq.c
@@ -236,8 +236,8 @@ static void sd_isoc_irq(struct urb *urb)
}
data = (u8 *) urb->transfer_buffer
+ urb->iso_frame_desc[i].offset;
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, SD_PKT_SZ);
+ gspca_frame_add(gspca_dev, INTER_PACKET,
+ data, SD_PKT_SZ);
}
/* resubmit the URBs */
diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c
index 39b6b2e02963..c75b7388a85c 100644
--- a/drivers/media/usb/gspca/sn9c2028.c
+++ b/drivers/media/usb/gspca/sn9c2028.c
@@ -33,6 +33,16 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
u8 sof_read;
u16 model;
+
+#define MIN_AVG_LUM 8500
+#define MAX_AVG_LUM 10000
+ int avg_lum;
+ u8 avg_lum_l;
+
+ struct { /* autogain and gain control cluster */
+ struct v4l2_ctrl *autogain;
+ struct v4l2_ctrl *gain;
+ };
};
struct init_command {
@@ -128,7 +138,7 @@ static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
status = -1;
for (i = 0; i < 256 && status < 2; i++)
status = sn9c2028_read1(gspca_dev);
- if (status != 2) {
+ if (status < 0) {
pr_err("long command status read error %d\n", status);
return (status < 0) ? status : -EIO;
}
@@ -178,6 +188,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
case 0x7005:
PDEBUG(D_PROBE, "Genius Smart 300 camera");
break;
+ case 0x7003:
+ PDEBUG(D_PROBE, "Genius Videocam Live v2");
+ break;
case 0x8000:
PDEBUG(D_PROBE, "DC31VC");
break;
@@ -248,6 +261,78 @@ static int run_start_commands(struct gspca_dev *gspca_dev,
return 0;
}
+static void set_gain(struct gspca_dev *gspca_dev, s32 g)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ struct init_command genius_vcam_live_gain_cmds[] = {
+ {{0x1d, 0x25, 0x10 /* This byte is gain */,
+ 0x20, 0xab, 0x00}, 0},
+ };
+ if (!gspca_dev->streaming)
+ return;
+
+ switch (sd->model) {
+ case 0x7003:
+ genius_vcam_live_gain_cmds[0].instruction[2] = g;
+ run_start_commands(gspca_dev, genius_vcam_live_gain_cmds,
+ ARRAY_SIZE(genius_vcam_live_gain_cmds));
+ break;
+ default:
+ break;
+ }
+}
+
+static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct gspca_dev *gspca_dev =
+ container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
+ struct sd *sd = (struct sd *)gspca_dev;
+
+ gspca_dev->usb_err = 0;
+
+ if (!gspca_dev->streaming)
+ return 0;
+
+ switch (ctrl->id) {
+ /* standalone gain control */
+ case V4L2_CID_GAIN:
+ set_gain(gspca_dev, ctrl->val);
+ break;
+ /* autogain */
+ case V4L2_CID_AUTOGAIN:
+ set_gain(gspca_dev, sd->gain->val);
+ break;
+ }
+ return gspca_dev->usb_err;
+}
+
+static const struct v4l2_ctrl_ops sd_ctrl_ops = {
+ .s_ctrl = sd_s_ctrl,
+};
+
+
+static int sd_init_controls(struct gspca_dev *gspca_dev)
+{
+ struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
+ struct sd *sd = (struct sd *)gspca_dev;
+
+ gspca_dev->vdev.ctrl_handler = hdl;
+ v4l2_ctrl_handler_init(hdl, 2);
+
+ switch (sd->model) {
+ case 0x7003:
+ sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_GAIN, 0, 20, 1, 0);
+ sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
static int start_spy_cam(struct gspca_dev *gspca_dev)
{
struct init_command spy_start_commands[] = {
@@ -530,6 +615,119 @@ static int start_genius_cam(struct gspca_dev *gspca_dev)
ARRAY_SIZE(genius_start_commands));
}
+static int start_genius_videocam_live(struct gspca_dev *gspca_dev)
+{
+ int r;
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct init_command genius_vcam_live_start_commands[] = {
+ {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 0},
+ {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
+ {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
+
+ {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
+ {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
+ {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
+ {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+ {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
+ {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
+ {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
+ {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
+ {{0x1c, 0x20, 0x00, 0x2d, 0x00, 0x00}, 4},
+ {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x22, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
+ {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
+ {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
+ {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
+ {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
+ {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
+ {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+ {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
+ {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
+ {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
+ {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
+ {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x01, 0x04, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x02, 0x92, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
+ {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
+ {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
+ {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
+ {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
+ {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
+ {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+ {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
+ {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
+ {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
+ {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
+ {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
+ {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
+ {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0},
+ /* Camera should start to capture now. */
+ {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 0},
+ {{0x1b, 0x32, 0x26, 0x00, 0x00, 0x00}, 0},
+ {{0x1d, 0x25, 0x10, 0x20, 0xab, 0x00}, 0},
+ };
+
+ r = run_start_commands(gspca_dev, genius_vcam_live_start_commands,
+ ARRAY_SIZE(genius_vcam_live_start_commands));
+ if (r < 0)
+ return r;
+
+ if (sd->gain)
+ set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
+
+ return r;
+}
+
static int start_vivitar_cam(struct gspca_dev *gspca_dev)
{
struct init_command vivitar_start_commands[] = {
@@ -623,6 +821,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
case 0x7005:
err_code = start_genius_cam(gspca_dev);
break;
+ case 0x7003:
+ err_code = start_genius_videocam_live(gspca_dev);
+ break;
case 0x8001:
err_code = start_spy_cam(gspca_dev);
break;
@@ -640,6 +841,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
return -ENXIO;
}
+ sd->avg_lum = -1;
+
return err_code;
}
@@ -659,6 +862,39 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PERR("Camera Stop command failed");
}
+static void do_autogain(struct gspca_dev *gspca_dev, int avg_lum)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
+
+ if (avg_lum == -1)
+ return;
+
+ if (avg_lum < MIN_AVG_LUM) {
+ if (cur_gain == sd->gain->maximum)
+ return;
+ cur_gain++;
+ v4l2_ctrl_s_ctrl(sd->gain, cur_gain);
+ }
+ if (avg_lum > MAX_AVG_LUM) {
+ if (cur_gain == sd->gain->minimum)
+ return;
+ cur_gain--;
+ v4l2_ctrl_s_ctrl(sd->gain, cur_gain);
+ }
+
+}
+
+static void sd_dqcallback(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
+ return;
+
+ do_autogain(gspca_dev, sd->avg_lum);
+}
+
/* Include sn9c2028 sof detection functions */
#include "sn9c2028.h"
@@ -693,14 +929,17 @@ static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
.config = sd_config,
.init = sd_init,
+ .init_controls = sd_init_controls,
.start = sd_start,
.stopN = sd_stopN,
+ .dq_callback = sd_dqcallback,
.pkt_scan = sd_pkt_scan,
};
/* -- module initialisation -- */
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
+ {USB_DEVICE(0x0458, 0x7003)}, /* Genius Videocam Live v2 */
/* The Genius Smart is untested. I can't find an owner ! */
/* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */
{USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */
diff --git a/drivers/media/usb/gspca/sn9c2028.h b/drivers/media/usb/gspca/sn9c2028.h
index 8fd1d3e05665..f85bc106bc52 100644
--- a/drivers/media/usb/gspca/sn9c2028.h
+++ b/drivers/media/usb/gspca/sn9c2028.h
@@ -21,8 +21,15 @@
*
*/
-static const unsigned char sn9c2028_sof_marker[5] =
- { 0xff, 0xff, 0x00, 0xc4, 0xc4 };
+static const unsigned char sn9c2028_sof_marker[] = {
+ 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96,
+ 0x00,
+ 0x00, /* seq */
+ 0x00,
+ 0x00,
+ 0x00, /* avg luminance lower 8 bit */
+ 0x00, /* avg luminance higher 8 bit */
+};
static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
unsigned char *m, int len)
@@ -32,8 +39,13 @@ static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
/* Search for the SOF marker (fixed part) in the header */
for (i = 0; i < len; i++) {
- if (m[i] == sn9c2028_sof_marker[sd->sof_read]) {
+ if ((m[i] == sn9c2028_sof_marker[sd->sof_read]) ||
+ (sd->sof_read > 5)) {
sd->sof_read++;
+ if (sd->sof_read == 11)
+ sd->avg_lum_l = m[i];
+ if (sd->sof_read == 12)
+ sd->avg_lum = (m[i] << 8) + sd->avg_lum_l;
if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
PDEBUG(D_FRAM,
"SOF found, bytes to analyze: %u."
diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c
index c69b45d7cfbf..fd1c8706d86a 100644
--- a/drivers/media/usb/gspca/sonixj.c
+++ b/drivers/media/usb/gspca/sonixj.c
@@ -1789,7 +1789,7 @@ static u32 expo_adjust(struct gspca_dev *gspca_dev,
if (expo > 0x03ff)
expo = 0x03ff;
- if (expo < 0x0001)
+ if (expo < 0x0001)
expo = 0x0001;
gainOm[3] = expo >> 2;
i2c_w8(gspca_dev, gainOm);
diff --git a/drivers/media/usb/gspca/stk014.c b/drivers/media/usb/gspca/stk014.c
index b0c70fea760b..d324d001e114 100644
--- a/drivers/media/usb/gspca/stk014.c
+++ b/drivers/media/usb/gspca/stk014.c
@@ -276,7 +276,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
gspca_dev->usb_err = ret;
goto out;
}
- reg_r(gspca_dev, 0x0630);
+ reg_r(gspca_dev, 0x0630);
rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
reg_r(gspca_dev, 0x0650);
snd_val(gspca_dev, 0x000020, 0xffffffff);
diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c
index a41aa7817c54..d5ed9d36ce25 100644
--- a/drivers/media/usb/gspca/xirlink_cit.c
+++ b/drivers/media/usb/gspca/xirlink_cit.c
@@ -1772,7 +1772,8 @@ static int cit_start_model2(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
sd->sof_len = 2;
break;
- /* case VIDEOSIZE_352x240: */
+#if 0
+ case VIDEOSIZE_352x240:
cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
@@ -1780,6 +1781,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
sd->sof_len = 2;
break;
+#endif
case 352: /* 352x288 */
cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
@@ -1853,13 +1855,15 @@ static int cit_start_model2(struct gspca_dev *gspca_dev)
cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
clock_div = 8;
break;
- /* case VIDEOSIZE_352x240: */
+#if 0
+ case VIDEOSIZE_352x240:
/* This mode doesn't work as Windows programs it; changed to work */
cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
clock_div = 10;
break;
+#endif
case 352: /* 352x288 */
cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
@@ -1906,9 +1910,11 @@ static int cit_start_model2(struct gspca_dev *gspca_dev)
case 320: /* 320x240 */
cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
break;
- /* case VIDEOSIZE_352x240: */
+#if 0
+ case VIDEOSIZE_352x240:
cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
break;
+#endif
case 352: /* 352x288 */
cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
break;
diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c
index d3e1b6d8bf49..c5d8ee6fa3c7 100644
--- a/drivers/media/usb/gspca/zc3xx.c
+++ b/drivers/media/usb/gspca/zc3xx.c
@@ -5942,23 +5942,23 @@ static void transfer_update(struct work_struct *work)
reg07 = 0;
good = 0;
- for (;;) {
+ while (1) {
msleep(100);
/* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
mutex_lock(&gspca_dev->usb_lock);
#ifdef CONFIG_PM
if (gspca_dev->frozen)
- goto err;
+ break;
#endif
if (!gspca_dev->present || !gspca_dev->streaming)
- goto err;
+ break;
/* Bit 0 of register 11 indicates FIFO overflow */
gspca_dev->usb_err = 0;
reg11 = reg_r(gspca_dev, 0x0011);
if (gspca_dev->usb_err)
- goto err;
+ break;
change = reg11 & 0x01;
if (change) { /* overflow */
@@ -5987,12 +5987,12 @@ static void transfer_update(struct work_struct *work)
gspca_dev->usb_err = 0;
reg_w(gspca_dev, reg07, 0x0007);
if (gspca_dev->usb_err)
- goto err;
+ break;
}
mutex_unlock(&gspca_dev->usb_lock);
}
- return;
-err:
+
+ /* Something went wrong. Unlock and return */
mutex_unlock(&gspca_dev->usb_lock);
}
@@ -6360,7 +6360,7 @@ static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->val <= jpeg_qual[i])
break;
}
- if (i > 0 && i == qual && ctrl->val < jpeg_qual[i])
+ if (i == ARRAY_SIZE(jpeg_qual) || (i > 0 && i == qual && ctrl->val < jpeg_qual[i]))
i--;
/* With high quality settings we need max bandwidth */