aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/zc3xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/zc3xx.c')
-rw-r--r--drivers/media/video/gspca/zc3xx.c328
1 files changed, 237 insertions, 91 deletions
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index b9e15bb0328b..7d9a4f1be9dc 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Z-Star/Vimicro zc301/zc302p/vc30x library 2 * Z-Star/Vimicro zc301/zc302p/vc30x driver
3 * 3 *
4 * Copyright (C) 2009-2011 Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr 5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,6 @@
21 21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 23
24#define MODULE_NAME "zc3xx"
25
26#include <linux/input.h> 24#include <linux/input.h>
27#include "gspca.h" 25#include "gspca.h"
28#include "jpeg.h" 26#include "jpeg.h"
@@ -34,7 +32,7 @@ MODULE_LICENSE("GPL");
34 32
35static int force_sensor = -1; 33static int force_sensor = -1;
36 34
37#define QUANT_VAL 1 /* quantization table */ 35#define REG08_DEF 3 /* default JPEG compression (70%) */
38#include "zc3xx-reg.h" 36#include "zc3xx-reg.h"
39 37
40/* controls */ 38/* controls */
@@ -46,6 +44,7 @@ enum e_ctrl {
46 AUTOGAIN, 44 AUTOGAIN,
47 LIGHTFREQ, 45 LIGHTFREQ,
48 SHARPNESS, 46 SHARPNESS,
47 QUALITY,
49 NCTRLS /* number of controls */ 48 NCTRLS /* number of controls */
50}; 49};
51 50
@@ -57,10 +56,10 @@ struct sd {
57 56
58 struct gspca_ctrl ctrls[NCTRLS]; 57 struct gspca_ctrl ctrls[NCTRLS];
59 58
60 u8 quality; /* image quality */ 59 struct work_struct work;
61#define QUALITY_MIN 50 60 struct workqueue_struct *work_thread;
62#define QUALITY_MAX 80 61
63#define QUALITY_DEF 70 62 u8 reg08; /* webcam compression quality */
64 63
65 u8 bridge; 64 u8 bridge;
66 u8 sensor; /* Type of image sensor chip */ 65 u8 sensor; /* Type of image sensor chip */
@@ -101,6 +100,7 @@ static void setexposure(struct gspca_dev *gspca_dev);
101static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 100static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
102static void setlightfreq(struct gspca_dev *gspca_dev); 101static void setlightfreq(struct gspca_dev *gspca_dev);
103static void setsharpness(struct gspca_dev *gspca_dev); 102static void setsharpness(struct gspca_dev *gspca_dev);
103static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val);
104 104
105static const struct ctrl sd_ctrls[NCTRLS] = { 105static const struct ctrl sd_ctrls[NCTRLS] = {
106[BRIGHTNESS] = { 106[BRIGHTNESS] = {
@@ -188,6 +188,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
188 }, 188 },
189 .set_control = setsharpness 189 .set_control = setsharpness
190 }, 190 },
191[QUALITY] = {
192 {
193 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Compression Quality",
196 .minimum = 40,
197 .maximum = 70,
198 .step = 1,
199 .default_value = 70 /* updated in sd_init() */
200 },
201 .set = sd_setquality
202 },
191}; 203};
192 204
193static const struct v4l2_pix_format vga_mode[] = { 205static const struct v4l2_pix_format vga_mode[] = {
@@ -229,6 +241,9 @@ static const struct v4l2_pix_format sif_mode[] = {
229 .priv = 0}, 241 .priv = 0},
230}; 242};
231 243
244/* bridge reg08 -> JPEG quality conversion table */
245static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/};
246
232/* usb exchanges */ 247/* usb exchanges */
233struct usb_action { 248struct usb_action {
234 u8 req; 249 u8 req;
@@ -3894,7 +3909,6 @@ static const struct usb_action pas106b_Initial[] = { /* 352x288 */
3894/* Gains */ 3909/* Gains */
3895 {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, 3910 {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
3896 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, 3911 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
3897 {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
3898 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 3912 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
3899/* Auto correction */ 3913/* Auto correction */
3900 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, 3914 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
@@ -5640,7 +5654,7 @@ static const struct usb_action gc0303_NoFlikerScale[] = {
5640 {} 5654 {}
5641}; 5655};
5642 5656
5643static u8 reg_r_i(struct gspca_dev *gspca_dev, 5657static u8 reg_r(struct gspca_dev *gspca_dev,
5644 u16 index) 5658 u16 index)
5645{ 5659{
5646 int ret; 5660 int ret;
@@ -5655,24 +5669,14 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev,
5655 index, gspca_dev->usb_buf, 1, 5669 index, gspca_dev->usb_buf, 1,
5656 500); 5670 500);
5657 if (ret < 0) { 5671 if (ret < 0) {
5658 pr_err("reg_r_i err %d\n", ret); 5672 pr_err("reg_r err %d\n", ret);
5659 gspca_dev->usb_err = ret; 5673 gspca_dev->usb_err = ret;
5660 return 0; 5674 return 0;
5661 } 5675 }
5662 return gspca_dev->usb_buf[0]; 5676 return gspca_dev->usb_buf[0];
5663} 5677}
5664 5678
5665static u8 reg_r(struct gspca_dev *gspca_dev, 5679static void reg_w(struct gspca_dev *gspca_dev,
5666 u16 index)
5667{
5668 u8 ret;
5669
5670 ret = reg_r_i(gspca_dev, index);
5671 PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
5672 return ret;
5673}
5674
5675static void reg_w_i(struct gspca_dev *gspca_dev,
5676 u8 value, 5680 u8 value,
5677 u16 index) 5681 u16 index)
5678{ 5682{
@@ -5692,14 +5696,6 @@ static void reg_w_i(struct gspca_dev *gspca_dev,
5692 } 5696 }
5693} 5697}
5694 5698
5695static void reg_w(struct gspca_dev *gspca_dev,
5696 u8 value,
5697 u16 index)
5698{
5699 PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
5700 reg_w_i(gspca_dev, value, index);
5701}
5702
5703static u16 i2c_read(struct gspca_dev *gspca_dev, 5699static u16 i2c_read(struct gspca_dev *gspca_dev,
5704 u8 reg) 5700 u8 reg)
5705{ 5701{
@@ -5708,16 +5704,14 @@ static u16 i2c_read(struct gspca_dev *gspca_dev,
5708 5704
5709 if (gspca_dev->usb_err < 0) 5705 if (gspca_dev->usb_err < 0)
5710 return 0; 5706 return 0;
5711 reg_w_i(gspca_dev, reg, 0x0092); 5707 reg_w(gspca_dev, reg, 0x0092);
5712 reg_w_i(gspca_dev, 0x02, 0x0090); /* <- read command */ 5708 reg_w(gspca_dev, 0x02, 0x0090); /* <- read command */
5713 msleep(20); 5709 msleep(20);
5714 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5710 retbyte = reg_r(gspca_dev, 0x0091); /* read status */
5715 if (retbyte != 0x00) 5711 if (retbyte != 0x00)
5716 pr_err("i2c_r status error %02x\n", retbyte); 5712 pr_err("i2c_r status error %02x\n", retbyte);
5717 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 5713 retval = reg_r(gspca_dev, 0x0095); /* read Lowbyte */
5718 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 5714 retval |= reg_r(gspca_dev, 0x0096) << 8; /* read Hightbyte */
5719 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
5720 reg, retval, retbyte);
5721 return retval; 5715 return retval;
5722} 5716}
5723 5717
@@ -5730,16 +5724,14 @@ static u8 i2c_write(struct gspca_dev *gspca_dev,
5730 5724
5731 if (gspca_dev->usb_err < 0) 5725 if (gspca_dev->usb_err < 0)
5732 return 0; 5726 return 0;
5733 reg_w_i(gspca_dev, reg, 0x92); 5727 reg_w(gspca_dev, reg, 0x92);
5734 reg_w_i(gspca_dev, valL, 0x93); 5728 reg_w(gspca_dev, valL, 0x93);
5735 reg_w_i(gspca_dev, valH, 0x94); 5729 reg_w(gspca_dev, valH, 0x94);
5736 reg_w_i(gspca_dev, 0x01, 0x90); /* <- write command */ 5730 reg_w(gspca_dev, 0x01, 0x90); /* <- write command */
5737 msleep(1); 5731 msleep(1);
5738 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5732 retbyte = reg_r(gspca_dev, 0x0091); /* read status */
5739 if (retbyte != 0x00) 5733 if (retbyte != 0x00)
5740 pr_err("i2c_w status error %02x\n", retbyte); 5734 pr_err("i2c_w status error %02x\n", retbyte);
5741 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
5742 reg, valH, valL, retbyte);
5743 return retbyte; 5735 return retbyte;
5744} 5736}
5745 5737
@@ -5906,6 +5898,8 @@ static void getexposure(struct gspca_dev *gspca_dev)
5906{ 5898{
5907 struct sd *sd = (struct sd *) gspca_dev; 5899 struct sd *sd = (struct sd *) gspca_dev;
5908 5900
5901 if (sd->sensor != SENSOR_HV7131R)
5902 return;
5909 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9) 5903 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
5910 | (i2c_read(gspca_dev, 0x26) << 1) 5904 | (i2c_read(gspca_dev, 0x26) << 1)
5911 | (i2c_read(gspca_dev, 0x27) >> 7); 5905 | (i2c_read(gspca_dev, 0x27) >> 7);
@@ -5916,6 +5910,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
5916 struct sd *sd = (struct sd *) gspca_dev; 5910 struct sd *sd = (struct sd *) gspca_dev;
5917 int val; 5911 int val;
5918 5912
5913 if (sd->sensor != SENSOR_HV7131R)
5914 return;
5919 val = sd->ctrls[EXPOSURE].val; 5915 val = sd->ctrls[EXPOSURE].val;
5920 i2c_write(gspca_dev, 0x25, val >> 9, 0x00); 5916 i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
5921 i2c_write(gspca_dev, 0x26, val >> 1, 0x00); 5917 i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
@@ -5925,32 +5921,20 @@ static void setexposure(struct gspca_dev *gspca_dev)
5925static void setquality(struct gspca_dev *gspca_dev) 5921static void setquality(struct gspca_dev *gspca_dev)
5926{ 5922{
5927 struct sd *sd = (struct sd *) gspca_dev; 5923 struct sd *sd = (struct sd *) gspca_dev;
5928 u8 frxt; 5924 s8 reg07;
5929 5925
5926 reg07 = 0;
5930 switch (sd->sensor) { 5927 switch (sd->sensor) {
5931 case SENSOR_ADCM2700:
5932 case SENSOR_GC0305:
5933 case SENSOR_HV7131B:
5934 case SENSOR_HV7131R:
5935 case SENSOR_OV7620: 5928 case SENSOR_OV7620:
5929 reg07 = 0x30;
5930 break;
5931 case SENSOR_HV7131R:
5936 case SENSOR_PAS202B: 5932 case SENSOR_PAS202B:
5937 case SENSOR_PO2030: 5933 return; /* done by work queue */
5938 return;
5939 } 5934 }
5940/*fixme: is it really 0008 0007 0018 for all other sensors? */ 5935 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
5941 reg_w(gspca_dev, QUANT_VAL, 0x0008); 5936 if (reg07 != 0)
5942 frxt = 0x30; 5937 reg_w(gspca_dev, reg07, 0x0007);
5943 reg_w(gspca_dev, frxt, 0x0007);
5944#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
5945 frxt = 0xff;
5946#elif QUANT_VAL == 3
5947 frxt = 0xf0;
5948#elif QUANT_VAL == 4
5949 frxt = 0xe0;
5950#else
5951 frxt = 0x20;
5952#endif
5953 reg_w(gspca_dev, frxt, 0x0018);
5954} 5938}
5955 5939
5956/* Matches the sensor's internal frame rate to the lighting frequency. 5940/* Matches the sensor's internal frame rate to the lighting frequency.
@@ -6084,6 +6068,115 @@ static void setautogain(struct gspca_dev *gspca_dev)
6084 reg_w(gspca_dev, autoval, 0x0180); 6068 reg_w(gspca_dev, autoval, 0x0180);
6085} 6069}
6086 6070
6071/* update the transfer parameters */
6072/* This function is executed from a work queue. */
6073/* The exact use of the bridge registers 07 and 08 is not known.
6074 * The following algorithm has been adapted from ms-win traces */
6075static void transfer_update(struct work_struct *work)
6076{
6077 struct sd *sd = container_of(work, struct sd, work);
6078 struct gspca_dev *gspca_dev = &sd->gspca_dev;
6079 int change, good;
6080 u8 reg07, reg11;
6081
6082 /* synchronize with the main driver and initialize the registers */
6083 mutex_lock(&gspca_dev->usb_lock);
6084 reg07 = 0; /* max */
6085 reg_w(gspca_dev, reg07, 0x0007);
6086 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
6087 mutex_unlock(&gspca_dev->usb_lock);
6088
6089 good = 0;
6090 for (;;) {
6091 msleep(100);
6092
6093 /* get the transfer status */
6094 /* the bit 0 of the bridge register 11 indicates overflow */
6095 mutex_lock(&gspca_dev->usb_lock);
6096 if (!gspca_dev->present || !gspca_dev->streaming)
6097 goto err;
6098 reg11 = reg_r(gspca_dev, 0x0011);
6099 if (gspca_dev->usb_err < 0
6100 || !gspca_dev->present || !gspca_dev->streaming)
6101 goto err;
6102
6103 change = reg11 & 0x01;
6104 if (change) { /* overflow */
6105 switch (reg07) {
6106 case 0: /* max */
6107 reg07 = sd->sensor == SENSOR_HV7131R
6108 ? 0x30 : 0x32;
6109 if (sd->reg08 != 0) {
6110 change = 3;
6111 sd->reg08--;
6112 }
6113 break;
6114 case 0x32:
6115 reg07 -= 4;
6116 break;
6117 default:
6118 reg07 -= 2;
6119 break;
6120 case 2:
6121 change = 0; /* already min */
6122 break;
6123 }
6124 good = 0;
6125 } else { /* no overflow */
6126 if (reg07 != 0) { /* if not max */
6127 good++;
6128 if (good >= 10) {
6129 good = 0;
6130 change = 1;
6131 reg07 += 2;
6132 switch (reg07) {
6133 case 0x30:
6134 if (sd->sensor == SENSOR_PAS202B)
6135 reg07 += 2;
6136 break;
6137 case 0x32:
6138 case 0x34:
6139 reg07 = 0;
6140 break;
6141 }
6142 }
6143 } else { /* reg07 max */
6144 if (sd->reg08 < sizeof jpeg_qual - 1) {
6145 good++;
6146 if (good > 10) {
6147 sd->reg08++;
6148 change = 2;
6149 }
6150 }
6151 }
6152 }
6153 if (change) {
6154 if (change & 1) {
6155 reg_w(gspca_dev, reg07, 0x0007);
6156 if (gspca_dev->usb_err < 0
6157 || !gspca_dev->present
6158 || !gspca_dev->streaming)
6159 goto err;
6160 }
6161 if (change & 2) {
6162 reg_w(gspca_dev, sd->reg08,
6163 ZC3XX_R008_CLOCKSETTING);
6164 if (gspca_dev->usb_err < 0
6165 || !gspca_dev->present
6166 || !gspca_dev->streaming)
6167 goto err;
6168 sd->ctrls[QUALITY].val = jpeg_qual[sd->reg08];
6169 jpeg_set_qual(sd->jpeg_hdr,
6170 jpeg_qual[sd->reg08]);
6171 }
6172 }
6173 mutex_unlock(&gspca_dev->usb_lock);
6174 }
6175 return;
6176err:
6177 mutex_unlock(&gspca_dev->usb_lock);
6178}
6179
6087static void send_unknown(struct gspca_dev *gspca_dev, int sensor) 6180static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
6088{ 6181{
6089 reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */ 6182 reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */
@@ -6411,7 +6504,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
6411 sd->sensor = id->driver_info; 6504 sd->sensor = id->driver_info;
6412 6505
6413 gspca_dev->cam.ctrls = sd->ctrls; 6506 gspca_dev->cam.ctrls = sd->ctrls;
6414 sd->quality = QUALITY_DEF; 6507 sd->reg08 = REG08_DEF;
6508
6509 INIT_WORK(&sd->work, transfer_update);
6415 6510
6416 return 0; 6511 return 0;
6417} 6512}
@@ -6464,6 +6559,27 @@ static int sd_init(struct gspca_dev *gspca_dev)
6464 [SENSOR_PO2030] = 1, 6559 [SENSOR_PO2030] = 1,
6465 [SENSOR_TAS5130C] = 1, 6560 [SENSOR_TAS5130C] = 1,
6466 }; 6561 };
6562 static const u8 reg08_tb[SENSOR_MAX] = {
6563 [SENSOR_ADCM2700] = 1,
6564 [SENSOR_CS2102] = 3,
6565 [SENSOR_CS2102K] = 3,
6566 [SENSOR_GC0303] = 2,
6567 [SENSOR_GC0305] = 3,
6568 [SENSOR_HDCS2020] = 1,
6569 [SENSOR_HV7131B] = 3,
6570 [SENSOR_HV7131R] = 3,
6571 [SENSOR_ICM105A] = 3,
6572 [SENSOR_MC501CB] = 3,
6573 [SENSOR_MT9V111_1] = 3,
6574 [SENSOR_MT9V111_3] = 3,
6575 [SENSOR_OV7620] = 1,
6576 [SENSOR_OV7630C] = 3,
6577 [SENSOR_PAS106] = 3,
6578 [SENSOR_PAS202B] = 3,
6579 [SENSOR_PB0330] = 3,
6580 [SENSOR_PO2030] = 2,
6581 [SENSOR_TAS5130C] = 3,
6582 };
6467 6583
6468 sensor = zcxx_probeSensor(gspca_dev); 6584 sensor = zcxx_probeSensor(gspca_dev);
6469 if (sensor >= 0) 6585 if (sensor >= 0)
@@ -6528,7 +6644,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
6528 case 0x0e: 6644 case 0x0e:
6529 PDEBUG(D_PROBE, "Find Sensor PAS202B"); 6645 PDEBUG(D_PROBE, "Find Sensor PAS202B");
6530 sd->sensor = SENSOR_PAS202B; 6646 sd->sensor = SENSOR_PAS202B;
6531/* sd->sharpness = 1; */
6532 break; 6647 break;
6533 case 0x0f: 6648 case 0x0f:
6534 PDEBUG(D_PROBE, "Find Sensor PAS106"); 6649 PDEBUG(D_PROBE, "Find Sensor PAS106");
@@ -6616,13 +6731,21 @@ static int sd_init(struct gspca_dev *gspca_dev)
6616 } 6731 }
6617 6732
6618 sd->ctrls[GAMMA].def = gamma[sd->sensor]; 6733 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6734 sd->reg08 = reg08_tb[sd->sensor];
6735 sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08];
6736 sd->ctrls[QUALITY].min = jpeg_qual[0];
6737 sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1];
6619 6738
6620 switch (sd->sensor) { 6739 switch (sd->sensor) {
6621 case SENSOR_HV7131R: 6740 case SENSOR_HV7131R:
6741 gspca_dev->ctrl_dis = (1 << QUALITY);
6622 break; 6742 break;
6623 case SENSOR_OV7630C: 6743 case SENSOR_OV7630C:
6624 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE); 6744 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6625 break; 6745 break;
6746 case SENSOR_PAS202B:
6747 gspca_dev->ctrl_dis = (1 << QUALITY) | (1 << EXPOSURE);
6748 break;
6626 default: 6749 default:
6627 gspca_dev->ctrl_dis = (1 << EXPOSURE); 6750 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6628 break; 6751 break;
@@ -6685,7 +6808,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
6685 /* create the JPEG header */ 6808 /* create the JPEG header */
6686 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 6809 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
6687 0x21); /* JPEG 422 */ 6810 0x21); /* JPEG 422 */
6688 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6689 6811
6690 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 6812 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6691 switch (sd->sensor) { 6813 switch (sd->sensor) {
@@ -6761,10 +6883,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
6761 reg_r(gspca_dev, 0x0180); /* from win */ 6883 reg_r(gspca_dev, 0x0180); /* from win */
6762 reg_w(gspca_dev, 0x00, 0x0180); 6884 reg_w(gspca_dev, 0x00, 0x0180);
6763 break; 6885 break;
6764 default:
6765 setquality(gspca_dev);
6766 break;
6767 } 6886 }
6887 setquality(gspca_dev);
6888 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]);
6768 setlightfreq(gspca_dev); 6889 setlightfreq(gspca_dev);
6769 6890
6770 switch (sd->sensor) { 6891 switch (sd->sensor) {
@@ -6776,8 +6897,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6776 reg_w(gspca_dev, 0x40, 0x0117); 6897 reg_w(gspca_dev, 0x40, 0x0117);
6777 break; 6898 break;
6778 case SENSOR_HV7131R: 6899 case SENSOR_HV7131R:
6779 if (!sd->ctrls[AUTOGAIN].val) 6900 setexposure(gspca_dev);
6780 setexposure(gspca_dev);
6781 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6901 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
6782 break; 6902 break;
6783 case SENSOR_GC0305: 6903 case SENSOR_GC0305:
@@ -6802,13 +6922,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
6802 } 6922 }
6803 6923
6804 setautogain(gspca_dev); 6924 setautogain(gspca_dev);
6805 switch (sd->sensor) { 6925
6806 case SENSOR_PO2030: 6926 /* start the transfer update thread if needed */
6807 msleep(50); 6927 if (gspca_dev->usb_err >= 0) {
6808 reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */ 6928 switch (sd->sensor) {
6809 reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING); 6929 case SENSOR_HV7131R:
6810 break; 6930 case SENSOR_PAS202B:
6931 sd->work_thread =
6932 create_singlethread_workqueue(KBUILD_MODNAME);
6933 queue_work(sd->work_thread, &sd->work);
6934 break;
6935 }
6811 } 6936 }
6937
6812 return gspca_dev->usb_err; 6938 return gspca_dev->usb_err;
6813} 6939}
6814 6940
@@ -6817,6 +6943,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
6817{ 6943{
6818 struct sd *sd = (struct sd *) gspca_dev; 6944 struct sd *sd = (struct sd *) gspca_dev;
6819 6945
6946 if (sd->work_thread != NULL) {
6947 mutex_unlock(&gspca_dev->usb_lock);
6948 destroy_workqueue(sd->work_thread);
6949 mutex_lock(&gspca_dev->usb_lock);
6950 sd->work_thread = NULL;
6951 }
6820 if (!gspca_dev->present) 6952 if (!gspca_dev->present)
6821 return; 6953 return;
6822 send_unknown(gspca_dev, sd->sensor); 6954 send_unknown(gspca_dev, sd->sensor);
@@ -6893,19 +7025,33 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
6893 return -EINVAL; 7025 return -EINVAL;
6894} 7026}
6895 7027
7028static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val)
7029{
7030 struct sd *sd = (struct sd *) gspca_dev;
7031 int i;
7032
7033 for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
7034 if (val <= jpeg_qual[i])
7035 break;
7036 }
7037 if (i > 0
7038 && i == sd->reg08
7039 && val < jpeg_qual[sd->reg08])
7040 i--;
7041 sd->reg08 = i;
7042 sd->ctrls[QUALITY].val = jpeg_qual[i];
7043 if (gspca_dev->streaming)
7044 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
7045 return gspca_dev->usb_err;
7046}
7047
6896static int sd_set_jcomp(struct gspca_dev *gspca_dev, 7048static int sd_set_jcomp(struct gspca_dev *gspca_dev,
6897 struct v4l2_jpegcompression *jcomp) 7049 struct v4l2_jpegcompression *jcomp)
6898{ 7050{
6899 struct sd *sd = (struct sd *) gspca_dev; 7051 struct sd *sd = (struct sd *) gspca_dev;
6900 7052
6901 if (jcomp->quality < QUALITY_MIN) 7053 sd_setquality(gspca_dev, jcomp->quality);
6902 sd->quality = QUALITY_MIN; 7054 jcomp->quality = sd->ctrls[QUALITY].val;
6903 else if (jcomp->quality > QUALITY_MAX)
6904 sd->quality = QUALITY_MAX;
6905 else
6906 sd->quality = jcomp->quality;
6907 if (gspca_dev->streaming)
6908 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6909 return gspca_dev->usb_err; 7055 return gspca_dev->usb_err;
6910} 7056}
6911 7057
@@ -6915,7 +7061,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
6915 struct sd *sd = (struct sd *) gspca_dev; 7061 struct sd *sd = (struct sd *) gspca_dev;
6916 7062
6917 memset(jcomp, 0, sizeof *jcomp); 7063 memset(jcomp, 0, sizeof *jcomp);
6918 jcomp->quality = sd->quality; 7064 jcomp->quality = sd->ctrls[QUALITY].val;
6919 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 7065 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
6920 | V4L2_JPEG_MARKER_DQT; 7066 | V4L2_JPEG_MARKER_DQT;
6921 return 0; 7067 return 0;
@@ -6938,7 +7084,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
6938#endif 7084#endif
6939 7085
6940static const struct sd_desc sd_desc = { 7086static const struct sd_desc sd_desc = {
6941 .name = MODULE_NAME, 7087 .name = KBUILD_MODNAME,
6942 .ctrls = sd_ctrls, 7088 .ctrls = sd_ctrls,
6943 .nctrls = ARRAY_SIZE(sd_ctrls), 7089 .nctrls = ARRAY_SIZE(sd_ctrls),
6944 .config = sd_config, 7090 .config = sd_config,
@@ -7023,7 +7169,7 @@ static int sd_probe(struct usb_interface *intf,
7023 7169
7024/* USB driver */ 7170/* USB driver */
7025static struct usb_driver sd_driver = { 7171static struct usb_driver sd_driver = {
7026 .name = MODULE_NAME, 7172 .name = KBUILD_MODNAME,
7027 .id_table = device_table, 7173 .id_table = device_table,
7028 .probe = sd_probe, 7174 .probe = sd_probe,
7029 .disconnect = gspca_disconnect, 7175 .disconnect = gspca_disconnect,