diff options
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 133 |
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); | |||
96 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | 97 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); |
97 | static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); | 98 | static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); |
98 | static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); | 99 | static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); |
100 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
101 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | 102 | ||
100 | static struct ctrl sd_ctrls[] = { | 103 | static 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 */ |
243 | static __u32 ctrl_dis[] = { | 262 | static __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 | ||
264 | static const struct v4l2_pix_format vga_mode[] = { | 283 | static 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 | ||
1633 | static 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 | |||
1613 | static void setjpegqual(struct gspca_dev *gspca_dev) | 1685 | static 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 | ||
2215 | static 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 | |||
2225 | static 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 | |||
2142 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 2233 | static 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 | ||
2261 | static 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 */ |
2171 | static const struct sd_desc sd_desc = { | 2283 | static 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 -- */ |