aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/ov519.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-07-29 04:25:28 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-08-06 05:57:10 -0400
commit0cd6759da646aae9d117df278ce3d5f3cab31904 (patch)
tree36275dcb84804917c9bd199b1465e86a0dc79711 /drivers/media/video/gspca/ov519.c
parentc2cfcf701881c9a4ef42d5a956f9f2d006c2af8e (diff)
V4L/DVB (8567): gspca: hflip and vflip controls added for ov519 - ov7670 plus init cleanup.
The hflip and vflip controls work for ov7670 only. This bridge/sensor inverts blue and red - not fixed. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/ov519.c')
-rw-r--r--drivers/media/video/gspca/ov519.c114
1 files changed, 98 insertions, 16 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 83139efc4629..b825941089b4 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -48,6 +48,8 @@ struct sd {
48 unsigned char brightness; 48 unsigned char brightness;
49 unsigned char contrast; 49 unsigned char contrast;
50 unsigned char colors; 50 unsigned char colors;
51 __u8 hflip;
52 __u8 vflip;
51 53
52 char compress; /* Should the next frame be compressed? */ 54 char compress; /* Should the next frame be compressed? */
53 char compress_inited; /* Are compression params uploaded? */ 55 char compress_inited; /* Are compression params uploaded? */
@@ -77,6 +79,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 80static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 81static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
80 86
81static struct ctrl sd_ctrls[] = { 87static struct ctrl sd_ctrls[] = {
82#define SD_BRIGHTNESS 0 88#define SD_BRIGHTNESS 0
@@ -121,6 +127,35 @@ static struct ctrl sd_ctrls[] = {
121 .set = sd_setcolors, 127 .set = sd_setcolors,
122 .get = sd_getcolors, 128 .get = sd_getcolors,
123 }, 129 },
130/* next controls work with ov7670 only */
131 {
132 {
133 .id = V4L2_CID_HFLIP,
134 .type = V4L2_CTRL_TYPE_BOOLEAN,
135 .name = "Mirror",
136 .minimum = 0,
137 .maximum = 1,
138 .step = 1,
139#define HFLIP_DEF 0
140 .default_value = HFLIP_DEF,
141 },
142 .set = sd_sethflip,
143 .get = sd_gethflip,
144 },
145 {
146 {
147 .id = V4L2_CID_VFLIP,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Vflip",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153#define VFLIP_DEF 0
154 .default_value = VFLIP_DEF,
155 },
156 .set = sd_setvflip,
157 .get = sd_getvflip,
158 },
124}; 159};
125 160
126static struct v4l2_pix_format vga_mode[] = { 161static struct v4l2_pix_format vga_mode[] = {
@@ -225,6 +260,7 @@ static struct v4l2_pix_format sif_mode[] = {
225#define OV7670_REG_VSTART 0x19 /* Vert start high bits */ 260#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
226#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ 261#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
227#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ 262#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
263#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
228#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ 264#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
229#define OV7670_REG_AEW 0x24 /* AGC upper limit */ 265#define OV7670_REG_AEW 0x24 /* AGC upper limit */
230#define OV7670_REG_AEB 0x25 /* AGC lower limit */ 266#define OV7670_REG_AEB 0x25 /* AGC lower limit */
@@ -930,7 +966,10 @@ static int ov7xx0_configure(struct sd *sd)
930 { OV7670_REG_EDGE, 0 }, 966 { OV7670_REG_EDGE, 0 },
931 { 0x75, 0x05 }, { 0x76, 0xe1 }, 967 { 0x75, 0x05 }, { 0x76, 0xe1 },
932 { 0x4c, 0 }, { 0x77, 0x01 }, 968 { 0x4c, 0 }, { 0x77, 0x01 },
933 { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, 969 { OV7670_REG_COM13, OV7670_COM13_GAMMA
970 | OV7670_COM13_UVSAT
971 | 2}, /* was 3 */
972 { 0x4b, 0x09 },
934 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, 973 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
935 { 0x56, 0x40 }, 974 { 0x56, 0x40 },
936 975
@@ -957,19 +996,6 @@ static int ov7xx0_configure(struct sd *sd)
957 { 0x79, 0x05 }, { 0xc8, 0x30 }, 996 { 0x79, 0x05 }, { 0xc8, 0x30 },
958 { 0x79, 0x26 }, 997 { 0x79, 0x26 },
959 998
960 /* Format YUV422 */
961 { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */
962 { OV7670_REG_RGB444, 0 }, /* No RGB444 please */
963 { OV7670_REG_COM1, 0 },
964 { OV7670_REG_COM15, OV7670_COM15_R00FF },
965 { OV7670_REG_COM9, 0x18 },
966 /* 4x gain ceiling; 0x8 is reserved bit */
967 { 0x4f, 0x80 }, /* "matrix coefficient 1" */
968 { 0x50, 0x80 }, /* "matrix coefficient 2" */
969 { 0x52, 0x22 }, /* "matrix coefficient 4" */
970 { 0x53, 0x5e }, /* "matrix coefficient 5" */
971 { 0x54, 0x80 }, /* "matrix coefficient 6" */
972 { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT },
973}; 999};
974 1000
975 PDEBUG(D_PROBE, "starting OV7xx0 configuration"); 1001 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
@@ -1375,6 +1401,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1375 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 1401 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
1376 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 1402 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
1377 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 1403 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
1404 sd->hflip = HFLIP_DEF;
1405 sd->vflip = VFLIP_DEF;
1378 return 0; 1406 return 0;
1379error: 1407error:
1380 PDEBUG(D_ERR, "OV519 Config failed"); 1408 PDEBUG(D_ERR, "OV519 Config failed");
@@ -1682,6 +1710,26 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1682 return 0; 1710 return 0;
1683} 1711}
1684 1712
1713static void sethflip(struct sd *sd)
1714{
1715 if (sd->gspca_dev.streaming)
1716 ov51x_stop(sd);
1717 i2c_w_mask(sd, OV7670_REG_MVFP,
1718 OV7670_MVFP_MIRROR * sd->hflip, OV7670_MVFP_MIRROR);
1719 if (sd->gspca_dev.streaming)
1720 ov51x_restart(sd);
1721}
1722
1723static void setvflip(struct sd *sd)
1724{
1725 if (sd->gspca_dev.streaming)
1726 ov51x_stop(sd);
1727 i2c_w_mask(sd, OV7670_REG_MVFP,
1728 OV7670_MVFP_VFLIP * sd->vflip, OV7670_MVFP_VFLIP);
1729 if (sd->gspca_dev.streaming)
1730 ov51x_restart(sd);
1731}
1732
1685static int set_ov_sensor_window(struct sd *sd, 1733static int set_ov_sensor_window(struct sd *sd,
1686 struct ovsensor_window *win) 1734 struct ovsensor_window *win)
1687{ 1735{
@@ -1811,7 +1859,8 @@ static int set_ov_sensor_window(struct sd *sd,
1811 msleep(10); /* need to sleep between read and write to 1859 msleep(10); /* need to sleep between read and write to
1812 * same reg! */ 1860 * same reg! */
1813 i2c_w(sd, OV7670_REG_VREF, v); 1861 i2c_w(sd, OV7670_REG_VREF, v);
1814 1862 sethflip(sd);
1863 setvflip(sd);
1815 } else { 1864 } else {
1816 i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); 1865 i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale));
1817 i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); 1866 i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale));
@@ -2110,6 +2159,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2110 return 0; 2159 return 0;
2111} 2160}
2112 2161
2162static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2163{
2164 struct sd *sd = (struct sd *) gspca_dev;
2165
2166 sd->hflip = val;
2167 sethflip(sd);
2168 return 0;
2169}
2170
2171static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2172{
2173 struct sd *sd = (struct sd *) gspca_dev;
2174
2175 *val = sd->hflip;
2176 return 0;
2177}
2178
2179static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2180{
2181 struct sd *sd = (struct sd *) gspca_dev;
2182
2183 sd->vflip = val;
2184 setvflip(sd);
2185 return 0;
2186}
2187
2188static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2189{
2190 struct sd *sd = (struct sd *) gspca_dev;
2191
2192 *val = sd->vflip;
2193 return 0;
2194}
2195
2113/* sub-driver description */ 2196/* sub-driver description */
2114static const struct sd_desc sd_desc = { 2197static const struct sd_desc sd_desc = {
2115 .name = MODULE_NAME, 2198 .name = MODULE_NAME,
@@ -2178,4 +2261,3 @@ module_exit(sd_mod_exit);
2178 2261
2179module_param(frame_rate, int, 0644); 2262module_param(frame_rate, int, 0644);
2180MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); 2263MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
2181