diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-07-29 04:25:28 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-08-06 05:57:10 -0400 |
commit | 0cd6759da646aae9d117df278ce3d5f3cab31904 (patch) | |
tree | 36275dcb84804917c9bd199b1465e86a0dc79711 /drivers/media | |
parent | c2cfcf701881c9a4ef42d5a956f9f2d006c2af8e (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')
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 114 |
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); | |||
77 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 79 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
78 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 80 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
79 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 81 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
82 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
83 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
84 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
85 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
80 | 86 | ||
81 | static struct ctrl sd_ctrls[] = { | 87 | static 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 | ||
126 | static struct v4l2_pix_format vga_mode[] = { | 161 | static 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; |
1379 | error: | 1407 | error: |
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 | ||
1713 | static 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 | |||
1723 | static 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 | |||
1685 | static int set_ov_sensor_window(struct sd *sd, | 1733 | static 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 | ||
2162 | static 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 | |||
2171 | static 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 | |||
2179 | static 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 | |||
2188 | static 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 */ |
2114 | static const struct sd_desc sd_desc = { | 2197 | static 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 | ||
2179 | module_param(frame_rate, int, 0644); | 2262 | module_param(frame_rate, int, 0644); |
2180 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); | 2263 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); |
2181 | |||