aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/ov534.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/ov534.c')
-rw-r--r--drivers/media/video/gspca/ov534.c146
1 files changed, 107 insertions, 39 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 04753391de3e..b5acb1e4b4e7 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -34,6 +34,8 @@
34 34
35#include "gspca.h" 35#include "gspca.h"
36 36
37#include <linux/fixp-arith.h>
38
37#define OV534_REG_ADDRESS 0xf1 /* sensor address */ 39#define OV534_REG_ADDRESS 0xf1 /* sensor address */
38#define OV534_REG_SUBADDR 0xf2 40#define OV534_REG_SUBADDR 0xf2
39#define OV534_REG_WRITE 0xf3 41#define OV534_REG_WRITE 0xf3
@@ -53,6 +55,8 @@ MODULE_LICENSE("GPL");
53 55
54/* controls */ 56/* controls */
55enum e_ctrl { 57enum e_ctrl {
58 HUE,
59 SATURATION,
56 BRIGHTNESS, 60 BRIGHTNESS,
57 CONTRAST, 61 CONTRAST,
58 GAIN, 62 GAIN,
@@ -63,7 +67,6 @@ enum e_ctrl {
63 SHARPNESS, 67 SHARPNESS,
64 HFLIP, 68 HFLIP,
65 VFLIP, 69 VFLIP,
66 COLORS,
67 LIGHTFREQ, 70 LIGHTFREQ,
68 NCTRLS /* number of controls */ 71 NCTRLS /* number of controls */
69}; 72};
@@ -87,6 +90,8 @@ enum sensors {
87}; 90};
88 91
89/* V4L2 controls supported by the driver */ 92/* V4L2 controls supported by the driver */
93static void sethue(struct gspca_dev *gspca_dev);
94static void setsaturation(struct gspca_dev *gspca_dev);
90static void setbrightness(struct gspca_dev *gspca_dev); 95static void setbrightness(struct gspca_dev *gspca_dev);
91static void setcontrast(struct gspca_dev *gspca_dev); 96static void setcontrast(struct gspca_dev *gspca_dev);
92static void setgain(struct gspca_dev *gspca_dev); 97static void setgain(struct gspca_dev *gspca_dev);
@@ -96,13 +101,36 @@ static void setawb(struct gspca_dev *gspca_dev);
96static void setaec(struct gspca_dev *gspca_dev); 101static void setaec(struct gspca_dev *gspca_dev);
97static void setsharpness(struct gspca_dev *gspca_dev); 102static void setsharpness(struct gspca_dev *gspca_dev);
98static void sethvflip(struct gspca_dev *gspca_dev); 103static void sethvflip(struct gspca_dev *gspca_dev);
99static void setcolors(struct gspca_dev *gspca_dev);
100static void setlightfreq(struct gspca_dev *gspca_dev); 104static void setlightfreq(struct gspca_dev *gspca_dev);
101 105
102static int sd_start(struct gspca_dev *gspca_dev); 106static int sd_start(struct gspca_dev *gspca_dev);
103static void sd_stopN(struct gspca_dev *gspca_dev); 107static void sd_stopN(struct gspca_dev *gspca_dev);
104 108
105static const struct ctrl sd_ctrls[] = { 109static const struct ctrl sd_ctrls[] = {
110[HUE] = {
111 {
112 .id = V4L2_CID_HUE,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Hue",
115 .minimum = -90,
116 .maximum = 90,
117 .step = 1,
118 .default_value = 0,
119 },
120 .set_control = sethue
121 },
122[SATURATION] = {
123 {
124 .id = V4L2_CID_SATURATION,
125 .type = V4L2_CTRL_TYPE_INTEGER,
126 .name = "Saturation",
127 .minimum = 0,
128 .maximum = 255,
129 .step = 1,
130 .default_value = 64,
131 },
132 .set_control = setsaturation
133 },
106[BRIGHTNESS] = { 134[BRIGHTNESS] = {
107 { 135 {
108 .id = V4L2_CID_BRIGHTNESS, 136 .id = V4L2_CID_BRIGHTNESS,
@@ -223,18 +251,6 @@ static const struct ctrl sd_ctrls[] = {
223 }, 251 },
224 .set_control = sethvflip 252 .set_control = sethvflip
225 }, 253 },
226[COLORS] = {
227 {
228 .id = V4L2_CID_SATURATION,
229 .type = V4L2_CTRL_TYPE_INTEGER,
230 .name = "Saturation",
231 .minimum = 0,
232 .maximum = 6,
233 .step = 1,
234 .default_value = 3,
235 },
236 .set_control = setcolors
237 },
238[LIGHTFREQ] = { 254[LIGHTFREQ] = {
239 { 255 {
240 .id = V4L2_CID_POWER_LINE_FREQUENCY, 256 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -684,7 +700,7 @@ static const u8 sensor_init_772x[][2] = {
684 { 0x9c, 0x20 }, 700 { 0x9c, 0x20 },
685 { 0x9e, 0x81 }, 701 { 0x9e, 0x81 },
686 702
687 { 0xa6, 0x04 }, 703 { 0xa6, 0x07 },
688 { 0x7e, 0x0c }, 704 { 0x7e, 0x0c },
689 { 0x7f, 0x16 }, 705 { 0x7f, 0x16 },
690 { 0x80, 0x2a }, 706 { 0x80, 0x2a },
@@ -955,6 +971,74 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
955 PDEBUG(D_PROBE, "frame_rate: %d", r->fps); 971 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
956} 972}
957 973
974static void sethue(struct gspca_dev *gspca_dev)
975{
976 struct sd *sd = (struct sd *) gspca_dev;
977 int val;
978
979 val = sd->ctrls[HUE].val;
980 if (sd->sensor == SENSOR_OV767x) {
981 /* TBD */
982 } else {
983 s16 huesin;
984 s16 huecos;
985
986 /* fixp_sin and fixp_cos accept only positive values, while
987 * our val is between -90 and 90
988 */
989 val += 360;
990
991 /* According to the datasheet the registers expect HUESIN and
992 * HUECOS to be the result of the trigonometric functions,
993 * scaled by 0x80.
994 *
995 * The 0x100 here represents the maximun absolute value
996 * returned byt fixp_sin and fixp_cos, so the scaling will
997 * consider the result like in the interval [-1.0, 1.0].
998 */
999 huesin = fixp_sin(val) * 0x80 / 0x100;
1000 huecos = fixp_cos(val) * 0x80 / 0x100;
1001
1002 if (huesin < 0) {
1003 sccb_reg_write(gspca_dev, 0xab,
1004 sccb_reg_read(gspca_dev, 0xab) | 0x2);
1005 huesin = -huesin;
1006 } else {
1007 sccb_reg_write(gspca_dev, 0xab,
1008 sccb_reg_read(gspca_dev, 0xab) & ~0x2);
1009
1010 }
1011 sccb_reg_write(gspca_dev, 0xa9, (u8)huecos);
1012 sccb_reg_write(gspca_dev, 0xaa, (u8)huesin);
1013 }
1014}
1015
1016static void setsaturation(struct gspca_dev *gspca_dev)
1017{
1018 struct sd *sd = (struct sd *) gspca_dev;
1019 int val;
1020
1021 val = sd->ctrls[SATURATION].val;
1022 if (sd->sensor == SENSOR_OV767x) {
1023 int i;
1024 static u8 color_tb[][6] = {
1025 {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1026 {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1027 {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1028 {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1029 {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1030 {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1031 {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1032 };
1033
1034 for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
1035 sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
1036 } else {
1037 sccb_reg_write(gspca_dev, 0xa7, val); /* U saturation */
1038 sccb_reg_write(gspca_dev, 0xa8, val); /* V saturation */
1039 }
1040}
1041
958static void setbrightness(struct gspca_dev *gspca_dev) 1042static void setbrightness(struct gspca_dev *gspca_dev)
959{ 1043{
960 struct sd *sd = (struct sd *) gspca_dev; 1044 struct sd *sd = (struct sd *) gspca_dev;
@@ -1132,26 +1216,6 @@ static void sethvflip(struct gspca_dev *gspca_dev)
1132 } 1216 }
1133} 1217}
1134 1218
1135static void setcolors(struct gspca_dev *gspca_dev)
1136{
1137 struct sd *sd = (struct sd *) gspca_dev;
1138 u8 val;
1139 int i;
1140 static u8 color_tb[][6] = {
1141 {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1142 {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1143 {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1144 {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1145 {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1146 {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1147 {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1148 };
1149
1150 val = sd->ctrls[COLORS].val;
1151 for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
1152 sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
1153}
1154
1155static void setlightfreq(struct gspca_dev *gspca_dev) 1219static void setlightfreq(struct gspca_dev *gspca_dev)
1156{ 1220{
1157 struct sd *sd = (struct sd *) gspca_dev; 1221 struct sd *sd = (struct sd *) gspca_dev;
@@ -1225,9 +1289,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
1225 1289
1226 if ((sensor_id & 0xfff0) == 0x7670) { 1290 if ((sensor_id & 0xfff0) == 0x7670) {
1227 sd->sensor = SENSOR_OV767x; 1291 sd->sensor = SENSOR_OV767x;
1228 gspca_dev->ctrl_dis = (1 << GAIN) | 1292 gspca_dev->ctrl_dis = (1 << HUE) |
1293 (1 << GAIN) |
1229 (1 << AGC) | 1294 (1 << AGC) |
1230 (1 << SHARPNESS); /* auto */ 1295 (1 << SHARPNESS); /* auto */
1296 sd->ctrls[SATURATION].min = 0,
1297 sd->ctrls[SATURATION].max = 6,
1298 sd->ctrls[SATURATION].def = 3,
1231 sd->ctrls[BRIGHTNESS].min = -127; 1299 sd->ctrls[BRIGHTNESS].min = -127;
1232 sd->ctrls[BRIGHTNESS].max = 127; 1300 sd->ctrls[BRIGHTNESS].max = 127;
1233 sd->ctrls[BRIGHTNESS].def = 0; 1301 sd->ctrls[BRIGHTNESS].def = 0;
@@ -1243,7 +1311,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1243 gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode); 1311 gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode);
1244 } else { 1312 } else {
1245 sd->sensor = SENSOR_OV772x; 1313 sd->sensor = SENSOR_OV772x;
1246 gspca_dev->ctrl_dis = (1 << COLORS);
1247 gspca_dev->cam.bulk = 1; 1314 gspca_dev->cam.bulk = 1;
1248 gspca_dev->cam.bulk_size = 16384; 1315 gspca_dev->cam.bulk_size = 16384;
1249 gspca_dev->cam.bulk_nurbs = 2; 1316 gspca_dev->cam.bulk_nurbs = 2;
@@ -1302,6 +1369,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1302 1369
1303 set_frame_rate(gspca_dev); 1370 set_frame_rate(gspca_dev);
1304 1371
1372 if (!(gspca_dev->ctrl_dis & (1 << HUE)))
1373 sethue(gspca_dev);
1374 setsaturation(gspca_dev);
1305 if (!(gspca_dev->ctrl_dis & (1 << AGC))) 1375 if (!(gspca_dev->ctrl_dis & (1 << AGC)))
1306 setagc(gspca_dev); 1376 setagc(gspca_dev);
1307 setawb(gspca_dev); 1377 setawb(gspca_dev);
@@ -1314,8 +1384,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1314 if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS))) 1384 if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS)))
1315 setsharpness(gspca_dev); 1385 setsharpness(gspca_dev);
1316 sethvflip(gspca_dev); 1386 sethvflip(gspca_dev);
1317 if (!(gspca_dev->ctrl_dis & (1 << COLORS)))
1318 setcolors(gspca_dev);
1319 setlightfreq(gspca_dev); 1387 setlightfreq(gspca_dev);
1320 1388
1321 ov534_set_led(gspca_dev, 1); 1389 ov534_set_led(gspca_dev, 1);