aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixj.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-06-18 06:35:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-23 02:13:49 -0400
commit37c6dbe290c05023b47f52528e30ce51336b93eb (patch)
tree2fbfa66d28b283b8a1b81a4e7cc5df47195c2228 /drivers/media/video/gspca/sonixj.c
parent1fec747cd389b4812a9932a1416d76e8a53596b2 (diff)
V4L/DVB (12091): gspca_sonixj: Add light frequency control
gspca_sonixj: Add light frequency control Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
-rw-r--r--drivers/media/video/gspca/sonixj.c133
1 files changed, 123 insertions, 10 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 6f475b471fb9..7daa60299c0e 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -46,6 +46,7 @@ struct sd {
46 u8 gamma; 46 u8 gamma;
47 u8 vflip; /* ov7630/ov7648 only */ 47 u8 vflip; /* ov7630/ov7648 only */
48 u8 infrared; /* mt9v111 only */ 48 u8 infrared; /* mt9v111 only */
49 u8 freq; /* ov76xx only */
49 u8 quality; /* image quality */ 50 u8 quality; /* image quality */
50#define QUALITY_MIN 60 51#define QUALITY_MIN 60
51#define QUALITY_MAX 95 52#define QUALITY_MAX 95
@@ -96,6 +97,8 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 97static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); 98static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); 99static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
100static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
99 102
100static struct ctrl sd_ctrls[] = { 103static struct ctrl sd_ctrls[] = {
101#define BRIGHTNESS_IDX 0 104#define BRIGHTNESS_IDX 0
@@ -237,19 +240,35 @@ static struct ctrl sd_ctrls[] = {
237 .set = sd_setinfrared, 240 .set = sd_setinfrared,
238 .get = sd_getinfrared, 241 .get = sd_getinfrared,
239 }, 242 },
243/* ov7630/ov7648/ov7660 only */
244#define FREQ_IDX 9
245 {
246 {
247 .id = V4L2_CID_POWER_LINE_FREQUENCY,
248 .type = V4L2_CTRL_TYPE_MENU,
249 .name = "Light frequency filter",
250 .minimum = 0,
251 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
252 .step = 1,
253#define FREQ_DEF 2
254 .default_value = FREQ_DEF,
255 },
256 .set = sd_setfreq,
257 .get = sd_getfreq,
258 },
240}; 259};
241 260
242/* table of the disabled controls */ 261/* table of the disabled controls */
243static __u32 ctrl_dis[] = { 262static __u32 ctrl_dis[] = {
244 (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 263 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
245 /* SENSOR_HV7131R 0 */ 264 /* SENSOR_HV7131R 0 */
246 (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 265 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
247 /* SENSOR_MI0360 1 */ 266 /* SENSOR_MI0360 1 */
248 (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 267 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
249 /* SENSOR_MO4000 2 */ 268 /* SENSOR_MO4000 2 */
250 (1 << VFLIP_IDX), 269 (1 << VFLIP_IDX) | (1 << FREQ_IDX),
251 /* SENSOR_MT9V111 3 */ 270 /* SENSOR_MT9V111 3 */
252 (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 271 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
253 /* SENSOR_OM6802 4 */ 272 /* SENSOR_OM6802 4 */
254 (1 << INFRARED_IDX), 273 (1 << INFRARED_IDX),
255 /* SENSOR_OV7630 5 */ 274 /* SENSOR_OV7630 5 */
@@ -257,8 +276,8 @@ static __u32 ctrl_dis[] = {
257 /* SENSOR_OV7648 6 */ 276 /* SENSOR_OV7648 6 */
258 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 277 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
259 /* SENSOR_OV7660 7 */ 278 /* SENSOR_OV7660 7 */
260 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 279 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
261 /* SENSOR_SP80708 8 */ 280 (1 << FREQ_IDX), /* SENSOR_SP80708 8 */
262}; 281};
263 282
264static const struct v4l2_pix_format vga_mode[] = { 283static const struct v4l2_pix_format vga_mode[] = {
@@ -647,8 +666,8 @@ static const u8 ov7630_sensor_init[][8] = {
647 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, 666 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
648 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, 667 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
649/* */ 668/* */
650 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, 669/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
651 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, 670/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
652/* */ 671/* */
653 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10}, 672 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
654/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */ 673/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
@@ -681,7 +700,7 @@ static const u8 ov7648_sensor_init[][8] = {
681 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10}, 700 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
682/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */ 701/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
683/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */ 702/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
684 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, 703/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
685/*...*/ 704/*...*/
686/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ 705/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
687/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN 706/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
@@ -1307,6 +1326,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1307 else 1326 else
1308 sd->vflip = 1; 1327 sd->vflip = 1;
1309 sd->infrared = INFRARED_DEF; 1328 sd->infrared = INFRARED_DEF;
1329 sd->freq = FREQ_DEF;
1310 sd->quality = QUALITY_DEF; 1330 sd->quality = QUALITY_DEF;
1311 sd->jpegqual = 80; 1331 sd->jpegqual = 80;
1312 1332
@@ -1610,6 +1630,58 @@ static void setinfrared(struct sd *sd)
1610 sd->infrared ? 0x66 : 0x64); 1630 sd->infrared ? 0x66 : 0x64);
1611} 1631}
1612 1632
1633static void setfreq(struct gspca_dev *gspca_dev)
1634{
1635 struct sd *sd = (struct sd *) gspca_dev;
1636
1637 if (sd->sensor == SENSOR_OV7660) {
1638 switch (sd->freq) {
1639 case 0: /* Banding filter disabled */
1640 i2c_w1(gspca_dev, 0x13, 0xdf);
1641 break;
1642 case 1: /* 50 hz */
1643 i2c_w1(gspca_dev, 0x13, 0xff);
1644 i2c_w1(gspca_dev, 0x3b, 0x0a);
1645 break;
1646 case 2: /* 60 hz */
1647 i2c_w1(gspca_dev, 0x13, 0xff);
1648 i2c_w1(gspca_dev, 0x3b, 0x02);
1649 break;
1650 }
1651 } else {
1652 u8 reg2a = 0, reg2b = 0, reg2d = 0;
1653
1654 /* Get reg2a / reg2d base values */
1655 switch (sd->sensor) {
1656 case SENSOR_OV7630:
1657 reg2a = 0x08;
1658 reg2d = 0x01;
1659 break;
1660 case SENSOR_OV7648:
1661 reg2a = 0x11;
1662 reg2d = 0x81;
1663 break;
1664 }
1665
1666 switch (sd->freq) {
1667 case 0: /* Banding filter disabled */
1668 break;
1669 case 1: /* 50 hz (filter on and framerate adj) */
1670 reg2a |= 0x80;
1671 reg2b = 0xac;
1672 reg2d |= 0x04;
1673 break;
1674 case 2: /* 60 hz (filter on, no framerate adj) */
1675 reg2a |= 0x80;
1676 reg2d |= 0x04;
1677 break;
1678 }
1679 i2c_w1(gspca_dev, 0x2a, reg2a);
1680 i2c_w1(gspca_dev, 0x2b, reg2b);
1681 i2c_w1(gspca_dev, 0x2d, reg2d);
1682 }
1683}
1684
1613static void setjpegqual(struct gspca_dev *gspca_dev) 1685static void setjpegqual(struct gspca_dev *gspca_dev)
1614{ 1686{
1615 struct sd *sd = (struct sd *) gspca_dev; 1687 struct sd *sd = (struct sd *) gspca_dev;
@@ -1836,6 +1908,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1836 setbrightness(gspca_dev); 1908 setbrightness(gspca_dev);
1837 setcontrast(gspca_dev); 1909 setcontrast(gspca_dev);
1838 setautogain(gspca_dev); 1910 setautogain(gspca_dev);
1911 setfreq(gspca_dev);
1839 return 0; 1912 return 0;
1840} 1913}
1841 1914
@@ -2139,6 +2212,24 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2139 return 0; 2212 return 0;
2140} 2213}
2141 2214
2215static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2216{
2217 struct sd *sd = (struct sd *) gspca_dev;
2218
2219 sd->freq = val;
2220 if (gspca_dev->streaming)
2221 setfreq(gspca_dev);
2222 return 0;
2223}
2224
2225static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2226{
2227 struct sd *sd = (struct sd *) gspca_dev;
2228
2229 *val = sd->freq;
2230 return 0;
2231}
2232
2142static int sd_set_jcomp(struct gspca_dev *gspca_dev, 2233static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2143 struct v4l2_jpegcompression *jcomp) 2234 struct v4l2_jpegcompression *jcomp)
2144{ 2235{
@@ -2167,6 +2258,27 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2167 return 0; 2258 return 0;
2168} 2259}
2169 2260
2261static int sd_querymenu(struct gspca_dev *gspca_dev,
2262 struct v4l2_querymenu *menu)
2263{
2264 switch (menu->id) {
2265 case V4L2_CID_POWER_LINE_FREQUENCY:
2266 switch (menu->index) {
2267 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2268 strcpy((char *) menu->name, "NoFliker");
2269 return 0;
2270 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2271 strcpy((char *) menu->name, "50 Hz");
2272 return 0;
2273 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2274 strcpy((char *) menu->name, "60 Hz");
2275 return 0;
2276 }
2277 break;
2278 }
2279 return -EINVAL;
2280}
2281
2170/* sub-driver description */ 2282/* sub-driver description */
2171static const struct sd_desc sd_desc = { 2283static const struct sd_desc sd_desc = {
2172 .name = MODULE_NAME, 2284 .name = MODULE_NAME,
@@ -2181,6 +2293,7 @@ static const struct sd_desc sd_desc = {
2181 .dq_callback = do_autogain, 2293 .dq_callback = do_autogain,
2182 .get_jcomp = sd_get_jcomp, 2294 .get_jcomp = sd_get_jcomp,
2183 .set_jcomp = sd_set_jcomp, 2295 .set_jcomp = sd_set_jcomp,
2296 .querymenu = sd_querymenu,
2184}; 2297};
2185 2298
2186/* -- module initialisation -- */ 2299/* -- module initialisation -- */