summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/gspca/spca561.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/gspca/spca561.c')
-rw-r--r--linux/drivers/media/video/gspca/spca561.c100
1 files changed, 50 insertions, 50 deletions
diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c
index 075699433..86fc55bf9 100644
--- a/linux/drivers/media/video/gspca/spca561.c
+++ b/linux/drivers/media/video/gspca/spca561.c
@@ -38,9 +38,9 @@ struct sd {
#define CONTRAST_MAX 0x3fff
__u16 exposure; /* rev12a only */
-#define EXPOSURE_MIN 0x0120
-#define EXPOSURE_DEF 0x20ae
-#define EXPOSURE_MAX 0x5720
+#define EXPOSURE_MIN 0
+#define EXPOSURE_DEF 200
+#define EXPOSURE_MAX 762
__u8 brightness; /* rev72a only */
#define BRIGHTNESS_MIN 0
@@ -48,7 +48,7 @@ struct sd {
#define BRIGHTNESS_MAX 63
__u8 white; /* rev12a only */
-#define WHITE_MIN 0
+#define WHITE_MIN 1
#define WHITE_DEF 0x40
#define WHITE_MAX 0x7f
@@ -62,6 +62,9 @@ struct sd {
#define GAIN_DEF 0x24
#define GAIN_MAX 0x24
+#define EXPO12A_DEF 3
+ __u8 expo12a; /* expo/gain? for rev 12a */
+
__u8 chip_revision;
#define Rev012A 0
#define Rev072A 1
@@ -567,6 +570,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->exposure = EXPOSURE_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->gain = GAIN_DEF;
+ sd->expo12a = EXPO12A_DEF;
return 0;
}
@@ -600,28 +604,11 @@ static void setcontrast(struct gspca_dev *gspca_dev)
break;
default: {
/* case Rev012A: { */
-#if 1
static const __u8 Reg8391[] =
{ 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
-#else
- int expotimes;
- __u8 Reg8391[] =
- { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 };
-
-/*fixme: does not work..*/
- /* Write camera sensor settings */
- expotimes = sd->contrast >> 5;
- /* exposure is in 8309 2b, range 0120 - 5720 */
- Reg8391[0] = expotimes; /* exposure */
- Reg8391[1] = 0x18 | (expotimes >> 8);
- Reg8391[2] = sd->brightness; /* gain */
- /* gain in 8335, 2b range 0000 - 2400 */
- reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
- reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
-#endif
break;
}
}
@@ -635,17 +622,10 @@ static void setwhite(struct gspca_dev *gspca_dev)
__u8 reg8614, reg8616;
white = sd->white;
- if (sd->white == 0) {
- PDEBUG(D_CONF, "Discarding null whiteness");
- return;
- }
/* try to emulate MS-win as possible */
- if (white < 0x45)
- reg8616 = white;
- else
- reg8616 = 0x93 + (white >> 2);
- reg8614 = 0x28 + (white >> 4);
+ reg8616 = 0x90 - white * 5 / 8;
reg_w_val(gspca_dev->dev, 0x8616, reg8616);
+ reg8614 = 0x20 + white * 3 / 8;
reg_w_val(gspca_dev->dev, 0x8614, reg8614);
}
@@ -653,30 +633,34 @@ static void setwhite(struct gspca_dev *gspca_dev)
static void setexposure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
+ int expo;
+ __u8 data[2];
- reg_w_val(dev, 0x8309, sd->gain);
+ expo = sd->exposure + 0x20a8; /* from test */
+ data[0] = expo;
+ data[1] = expo >> 8;
+ reg_w_buf(gspca_dev, 0x8309, data, 2);
}
/* rev 12a only */
static void setgain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
+ __u8 data[2];
- reg_w_val(dev, 0x8335, sd->gain);
+ data[0] = sd->gain;
+ data[1] = 0;
+ reg_w_buf(gspca_dev, 0x8335, data, 2);
}
static void setautogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- if (sd->chip_revision == Rev072A) {
- if (sd->autogain)
- sd->ag_cnt = AG_CNT_START;
- else
- sd->ag_cnt = -1;
- }
+ if (sd->autogain)
+ sd->ag_cnt = AG_CNT_START;
+ else
+ sd->ag_cnt = -1;
}
static void sd_start_12a(struct gspca_dev *gspca_dev)
@@ -715,6 +699,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev->dev, 0x850b, 0x03);
setcontrast(gspca_dev);
setwhite(gspca_dev);
+ setautogain(gspca_dev);
}
static void sd_start_72a(struct gspca_dev *gspca_dev)
{
@@ -744,12 +729,24 @@ static void sd_start_72a(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- reg_w_val(gspca_dev->dev, 0x8112, 0x20);
- reg_w_val(gspca_dev->dev, 0x8102, 0x00); /* white balance - new */
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->chip_revision == Rev012A) {
+ reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
+ } else {
+ reg_w_val(gspca_dev->dev, 0x8112, 0x20);
+/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
+ }
}
static void sd_stop0(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->chip_revision == Rev012A) {
+ reg_w_val(gspca_dev->dev, 0x8118, 0x29);
+ reg_w_val(gspca_dev->dev, 0x8114, 0x08);
+ }
}
/* this function is called at close time */
@@ -758,7 +755,6 @@ static void sd_close(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev->dev, 0x8114, 0);
}
-/* rev72a only */
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -770,6 +766,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
__u8 luma_mean = 110;
__u8 luma_delta = 20;
__u8 spring = 4;
+ __u8 reg8339[2];
if (sd->ag_cnt < 0)
return;
@@ -824,13 +821,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
}
break;
case Rev012A:
- /* sensor registers is access and memory mapped to 0x8300 */
- /* readind all 0x83xx block the sensor */
- /*
- * The data from the header seem wrong where is the luma
- * and chroma mean value
- * at the moment set exposure in contrast set
- */
+ reg_r(gspca_dev, 0x8330, 2);
+ if (gspca_dev->usb_buf[1] > 0x08) {
+ reg8339[0] = ++sd->expo12a;
+ reg8339[1] = 0;
+ reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
+ } else if (gspca_dev->usb_buf[1] < 0x02) {
+ reg8339[0] = --sd->expo12a;
+ reg8339[1] = 0;
+ reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
+ }
break;
}
}