summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/gspca/spca501.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/gspca/spca501.c')
-rw-r--r--linux/drivers/media/video/gspca/spca501.c132
1 files changed, 111 insertions, 21 deletions
diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c
index 979344907..17dab9859 100644
--- a/linux/drivers/media/video/gspca/spca501.c
+++ b/linux/drivers/media/video/gspca/spca501.c
@@ -34,6 +34,8 @@ struct sd {
unsigned short contrast;
__u8 brightness;
__u8 colors;
+ __u8 blue_balance;
+ __u8 red_balance;
char subtype;
#define Arowana300KCMOSCamera 0
@@ -52,6 +54,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
#define MY_BRIGHTNESS 0
@@ -63,7 +69,7 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 127,
.step = 1,
- .default_value = 63,
+ .default_value = 0,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
@@ -75,9 +81,9 @@ static struct ctrl sd_ctrls[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Contrast",
.minimum = 0,
- .maximum = 0xffff,
+ .maximum = 64725,
.step = 1,
- .default_value = 0xaa00,
+ .default_value = 64725,
},
.set = sd_setcontrast,
.get = sd_getcontrast,
@@ -91,11 +97,39 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 63,
.step = 1,
- .default_value = 31,
+ .default_value = 20,
},
.set = sd_setcolors,
.get = sd_getcolors,
},
+#define MY_BLUE_BALANCE 3
+ {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue Balance",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = sd_setblue_balance,
+ .get = sd_getblue_balance,
+ },
+#define MY_RED_BALANCE 4
+ {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red Balance",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = sd_setred_balance,
+ .get = sd_getred_balance,
+ },
};
static struct v4l2_pix_format vga_mode[] = {
@@ -1822,6 +1856,7 @@ static int reg_write(struct usb_device *dev,
return ret;
}
+#if 0
/* returns: negative is error, pos or zero is data */
static int reg_read(struct gspca_dev *gspca_dev,
__u16 req, /* bRequest */
@@ -1845,6 +1880,7 @@ static int reg_read(struct gspca_dev *gspca_dev,
}
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
+#endif
static int write_vector(struct gspca_dev *gspca_dev,
const __u16 data[][3])
@@ -1869,18 +1905,18 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness);
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
- reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness);
}
static void getbrightness(struct gspca_dev *gspca_dev)
{
+#if 0
struct sd *sd = (struct sd *) gspca_dev;
__u16 brightness;
- brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2);
- sd->brightness = brightness << 1;
+ brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x12, 2);
+ sd->brightness = brightness;
+#endif
}
static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1906,7 +1942,6 @@ static void getcontrast(struct gspca_dev *gspca_dev)
0x01,
1) & 0xff);
#endif
-/* spca50x->contrast = 0xaa01; */
}
static void setcolors(struct gspca_dev *gspca_dev)
@@ -1918,11 +1953,25 @@ static void setcolors(struct gspca_dev *gspca_dev)
static void getcolors(struct gspca_dev *gspca_dev)
{
+#if 0
struct sd *sd = (struct sd *) gspca_dev;
sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2);
-/* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */
-/* 2) & 0xFF) << 8; */
+#endif
+}
+
+static void setblue_balance(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->blue_balance);
+}
+
+static void setred_balance(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->red_balance);
}
/* this function is called at probe time */
@@ -1941,6 +1990,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value;
+ 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;
+
switch (sd->subtype) {
case Arowana300KCMOSCamera:
case SmileIntlCamera:
@@ -1959,15 +2016,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
goto error;
break;
}
+ PDEBUG(D_STREAM, "Initializing SPCA501 finished");
return 0;
error:
return -EINVAL;
}
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
+static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int mode;
switch (sd->subtype) {
case ThreeComHomeConnectLite:
@@ -1987,14 +2046,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* Generic 501 open data */
write_vector(gspca_dev, spca501_open_data);
}
- PDEBUG(D_STREAM, "Initializing SPCA501 finished");
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- int mode;
/* memorize the wanted pixel format */
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2033,8 +2084,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00);
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
+ if (!gspca_dev->present)
+ return;
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
}
@@ -2121,6 +2175,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->blue_balance = val;
+ if (gspca_dev->streaming)
+ setblue_balance(gspca_dev);
+ return 0;
+}
+
+static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->blue_balance;
+ return 0;
+}
+
+static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->red_balance = val;
+ if (gspca_dev->streaming)
+ setred_balance(gspca_dev);
+ return 0;
+}
+
+static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->red_balance;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,