diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-12-08 03:13:53 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:57 -0500 |
commit | 7dc7ad38f4f375c21ef5e05461639061e6483c73 (patch) | |
tree | 9e8d1fad646c19e5f8232d031d9cd8450bb779ff /drivers/media/video/gspca/vc032x.c | |
parent | e18fd01e63aada731efbcadba6232fde28a20ff5 (diff) |
V4L/DVB (9866): gspca - vc032x: V and H flips added for sensors ov7660 and 7670.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/vc032x.c')
-rw-r--r-- | drivers/media/video/gspca/vc032x.c | 137 |
1 files changed, 128 insertions, 9 deletions
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 5d5bdbeff504..0c93a753a0af 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -32,8 +32,10 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | unsigned char autogain; | 35 | __u8 autogain; |
36 | unsigned char lightfreq; | 36 | __u8 hflip; |
37 | __u8 vflip; | ||
38 | __u8 lightfreq; | ||
37 | 39 | ||
38 | char qindex; | 40 | char qindex; |
39 | char bridge; | 41 | char bridge; |
@@ -52,6 +54,10 @@ struct sd { | |||
52 | /* V4L2 controls supported by the driver */ | 54 | /* V4L2 controls supported by the driver */ |
53 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 55 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
54 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 56 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); |
57 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
60 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | 61 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); |
56 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 62 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
57 | 63 | ||
@@ -70,7 +76,38 @@ static struct ctrl sd_ctrls[] = { | |||
70 | .set = sd_setautogain, | 76 | .set = sd_setautogain, |
71 | .get = sd_getautogain, | 77 | .get = sd_getautogain, |
72 | }, | 78 | }, |
73 | #define LIGHTFREQ_IDX 1 | 79 | /* next 2 controls work with ov7660 and ov7670 only */ |
80 | #define HFLIP_IDX 1 | ||
81 | { | ||
82 | { | ||
83 | .id = V4L2_CID_HFLIP, | ||
84 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
85 | .name = "Mirror", | ||
86 | .minimum = 0, | ||
87 | .maximum = 1, | ||
88 | .step = 1, | ||
89 | #define HFLIP_DEF 0 | ||
90 | .default_value = HFLIP_DEF, | ||
91 | }, | ||
92 | .set = sd_sethflip, | ||
93 | .get = sd_gethflip, | ||
94 | }, | ||
95 | #define VFLIP_IDX 2 | ||
96 | { | ||
97 | { | ||
98 | .id = V4L2_CID_VFLIP, | ||
99 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
100 | .name = "Vflip", | ||
101 | .minimum = 0, | ||
102 | .maximum = 1, | ||
103 | .step = 1, | ||
104 | #define VFLIP_DEF 0 | ||
105 | .default_value = VFLIP_DEF, | ||
106 | }, | ||
107 | .set = sd_setvflip, | ||
108 | .get = sd_getvflip, | ||
109 | }, | ||
110 | #define LIGHTFREQ_IDX 3 | ||
74 | { | 111 | { |
75 | { | 112 | { |
76 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 113 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
@@ -112,6 +149,11 @@ static struct v4l2_pix_format vc0323_mode[] = { | |||
112 | .priv = 0}, | 149 | .priv = 0}, |
113 | }; | 150 | }; |
114 | 151 | ||
152 | /* OV7660/7670 registers */ | ||
153 | #define OV7660_REG_MVFP 0x1e | ||
154 | #define OV7660_MVFP_MIRROR 0x20 | ||
155 | #define OV7660_MVFP_VFLIP 0x10 | ||
156 | |||
115 | static const __u8 mi0360_matrix[9] = { | 157 | static const __u8 mi0360_matrix[9] = { |
116 | 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50 | 158 | 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50 |
117 | }; | 159 | }; |
@@ -1057,7 +1099,7 @@ static const __u8 ov7660_initVGA_data[][4] = { | |||
1057 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, | 1099 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, |
1058 | {0x00, 0x12, 0x80, 0xaa}, | 1100 | {0x00, 0x12, 0x80, 0xaa}, |
1059 | {0x00, 0x12, 0x05, 0xaa}, | 1101 | {0x00, 0x12, 0x05, 0xaa}, |
1060 | {0x00, 0x1e, 0x01, 0xaa}, | 1102 | {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */ |
1061 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ | 1103 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ |
1062 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ | 1104 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ |
1063 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, | 1105 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, |
@@ -1111,7 +1153,7 @@ static const __u8 ov7660_initQVGA_data[][4] = { | |||
1111 | {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, | 1153 | {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, |
1112 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, | 1154 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, |
1113 | {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, | 1155 | {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, |
1114 | {0x00, 0x1e, 0x01, 0xaa}, | 1156 | {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */ |
1115 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ | 1157 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ |
1116 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ | 1158 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ |
1117 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, | 1159 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, |
@@ -1217,7 +1259,8 @@ static const __u8 ov7670_initVGA_JPG[][4] = { | |||
1217 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | 1259 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, |
1218 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, | 1260 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, |
1219 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | 1261 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, |
1220 | {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, | 1262 | {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */ |
1263 | {0x00, 0x21, 0x02, 0xaa}, | ||
1221 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, | 1264 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, |
1222 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, | 1265 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, |
1223 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, | 1266 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, |
@@ -1282,7 +1325,8 @@ static const __u8 ov7670_initVGA_JPG[][4] = { | |||
1282 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, | 1325 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, |
1283 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, | 1326 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, |
1284 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | 1327 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, |
1285 | {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | 1328 | {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */ |
1329 | {0x00, 0xaa, 0x14, 0xaa}, | ||
1286 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, | 1330 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, |
1287 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, | 1331 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, |
1288 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, | 1332 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, |
@@ -1344,7 +1388,8 @@ static const __u8 ov7670_initQVGA_JPG[][4] = { | |||
1344 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | 1388 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, |
1345 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, | 1389 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, |
1346 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | 1390 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, |
1347 | {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, | 1391 | {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */ |
1392 | {0x00, 0x21, 0x02, 0xaa}, | ||
1348 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, | 1393 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, |
1349 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, | 1394 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, |
1350 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, | 1395 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, |
@@ -1409,7 +1454,8 @@ static const __u8 ov7670_initQVGA_JPG[][4] = { | |||
1409 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, | 1454 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, |
1410 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, | 1455 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, |
1411 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | 1456 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, |
1412 | {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | 1457 | {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */ |
1458 | {0x00, 0xaa, 0x14, 0xaa}, | ||
1413 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, | 1459 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, |
1414 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, | 1460 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, |
1415 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, | 1461 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, |
@@ -1695,10 +1741,25 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1695 | } | 1741 | } |
1696 | 1742 | ||
1697 | sd->qindex = 7; | 1743 | sd->qindex = 7; |
1744 | sd->hflip = HFLIP_DEF; | ||
1745 | sd->vflip = VFLIP_DEF; | ||
1746 | if (sd->sensor == SENSOR_OV7670) { | ||
1747 | sd->hflip = 1; | ||
1748 | sd->vflip = 1; | ||
1749 | } | ||
1698 | sd->autogain = AUTOGAIN_DEF; | 1750 | sd->autogain = AUTOGAIN_DEF; |
1699 | sd->lightfreq = FREQ_DEF; | 1751 | sd->lightfreq = FREQ_DEF; |
1700 | if (sd->sensor != SENSOR_OV7670) | 1752 | if (sd->sensor != SENSOR_OV7670) |
1701 | gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); | 1753 | gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); |
1754 | switch (sd->sensor) { | ||
1755 | case SENSOR_OV7660: | ||
1756 | case SENSOR_OV7670: | ||
1757 | break; | ||
1758 | default: | ||
1759 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | ||
1760 | | (1 << VFLIP_IDX); | ||
1761 | break; | ||
1762 | } | ||
1702 | 1763 | ||
1703 | if (sd->bridge == BRIDGE_VC0321) { | 1764 | if (sd->bridge == BRIDGE_VC0321) { |
1704 | reg_r(gspca_dev, 0x8a, 0, 3); | 1765 | reg_r(gspca_dev, 0x8a, 0, 3); |
@@ -1720,6 +1781,27 @@ static void setquality(struct gspca_dev *gspca_dev) | |||
1720 | { | 1781 | { |
1721 | } | 1782 | } |
1722 | 1783 | ||
1784 | /* for OV7660 and OV7670 only */ | ||
1785 | static void sethvflip(struct gspca_dev *gspca_dev) | ||
1786 | { | ||
1787 | struct sd *sd = (struct sd *) gspca_dev; | ||
1788 | __u8 data; | ||
1789 | |||
1790 | switch (sd->sensor) { | ||
1791 | case SENSOR_OV7660: | ||
1792 | data = 1; | ||
1793 | break; | ||
1794 | case SENSOR_OV7670: | ||
1795 | data = 7; | ||
1796 | break; | ||
1797 | default: | ||
1798 | return; | ||
1799 | } | ||
1800 | data |= OV7660_MVFP_MIRROR * sd->hflip | ||
1801 | | OV7660_MVFP_VFLIP * sd->vflip; | ||
1802 | i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1); | ||
1803 | } | ||
1804 | |||
1723 | static void setautogain(struct gspca_dev *gspca_dev) | 1805 | static void setautogain(struct gspca_dev *gspca_dev) |
1724 | { | 1806 | { |
1725 | } | 1807 | } |
@@ -1863,6 +1945,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1863 | reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); | 1945 | reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); |
1864 | msleep(100); | 1946 | msleep(100); |
1865 | setquality(gspca_dev); | 1947 | setquality(gspca_dev); |
1948 | sethvflip(gspca_dev); | ||
1866 | setautogain(gspca_dev); | 1949 | setautogain(gspca_dev); |
1867 | setlightfreq(gspca_dev); | 1950 | setlightfreq(gspca_dev); |
1868 | } | 1951 | } |
@@ -1931,6 +2014,42 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | |||
1931 | return 0; | 2014 | return 0; |
1932 | } | 2015 | } |
1933 | 2016 | ||
2017 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2018 | { | ||
2019 | struct sd *sd = (struct sd *) gspca_dev; | ||
2020 | |||
2021 | sd->hflip = val; | ||
2022 | if (gspca_dev->streaming) | ||
2023 | sethvflip(gspca_dev); | ||
2024 | return 0; | ||
2025 | } | ||
2026 | |||
2027 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2028 | { | ||
2029 | struct sd *sd = (struct sd *) gspca_dev; | ||
2030 | |||
2031 | *val = sd->hflip; | ||
2032 | return 0; | ||
2033 | } | ||
2034 | |||
2035 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2036 | { | ||
2037 | struct sd *sd = (struct sd *) gspca_dev; | ||
2038 | |||
2039 | sd->vflip = val; | ||
2040 | if (gspca_dev->streaming) | ||
2041 | sethvflip(gspca_dev); | ||
2042 | return 0; | ||
2043 | } | ||
2044 | |||
2045 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2046 | { | ||
2047 | struct sd *sd = (struct sd *) gspca_dev; | ||
2048 | |||
2049 | *val = sd->vflip; | ||
2050 | return 0; | ||
2051 | } | ||
2052 | |||
1934 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | 2053 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) |
1935 | { | 2054 | { |
1936 | struct sd *sd = (struct sd *) gspca_dev; | 2055 | struct sd *sd = (struct sd *) gspca_dev; |