aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonio Ospite <ospite@studenti.unina.it>2012-05-14 07:07:45 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 08:48:00 -0400
commite89fca923f32de26b69bf4cd604f7b960b161551 (patch)
treeef5424c7d31eb424a86b5776ea9ed8bbd7a411d5
parentc8e1fb4a67eed95364a50f33f5201a88877c5215 (diff)
[media] gspca - ov534: Add Hue control
Signed-off-by: Antonio Ospite <ospite@studenti.unina.it> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/ov534.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index c15cf23d7758..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,7 @@ MODULE_LICENSE("GPL");
53 55
54/* controls */ 56/* controls */
55enum e_ctrl { 57enum e_ctrl {
58 HUE,
56 SATURATION, 59 SATURATION,
57 BRIGHTNESS, 60 BRIGHTNESS,
58 CONTRAST, 61 CONTRAST,
@@ -87,6 +90,7 @@ 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);
90static void setsaturation(struct gspca_dev *gspca_dev); 94static void setsaturation(struct gspca_dev *gspca_dev);
91static void setbrightness(struct gspca_dev *gspca_dev); 95static void setbrightness(struct gspca_dev *gspca_dev);
92static void setcontrast(struct gspca_dev *gspca_dev); 96static void setcontrast(struct gspca_dev *gspca_dev);
@@ -103,6 +107,18 @@ static 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 },
106[SATURATION] = { 122[SATURATION] = {
107 { 123 {
108 .id = V4L2_CID_SATURATION, 124 .id = V4L2_CID_SATURATION,
@@ -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, 0x06 }, 703 { 0xa6, 0x07 },
688 { 0x7e, 0x0c }, 704 { 0x7e, 0x0c },
689 { 0x7f, 0x16 }, 705 { 0x7f, 0x16 },
690 { 0x80, 0x2a }, 706 { 0x80, 0x2a },
@@ -955,6 +971,48 @@ 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
958static void setsaturation(struct gspca_dev *gspca_dev) 1016static void setsaturation(struct gspca_dev *gspca_dev)
959{ 1017{
960 struct sd *sd = (struct sd *) gspca_dev; 1018 struct sd *sd = (struct sd *) gspca_dev;
@@ -1231,7 +1289,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
1231 1289
1232 if ((sensor_id & 0xfff0) == 0x7670) { 1290 if ((sensor_id & 0xfff0) == 0x7670) {
1233 sd->sensor = SENSOR_OV767x; 1291 sd->sensor = SENSOR_OV767x;
1234 gspca_dev->ctrl_dis = (1 << GAIN) | 1292 gspca_dev->ctrl_dis = (1 << HUE) |
1293 (1 << GAIN) |
1235 (1 << AGC) | 1294 (1 << AGC) |
1236 (1 << SHARPNESS); /* auto */ 1295 (1 << SHARPNESS); /* auto */
1237 sd->ctrls[SATURATION].min = 0, 1296 sd->ctrls[SATURATION].min = 0,
@@ -1310,6 +1369,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1310 1369
1311 set_frame_rate(gspca_dev); 1370 set_frame_rate(gspca_dev);
1312 1371
1372 if (!(gspca_dev->ctrl_dis & (1 << HUE)))
1373 sethue(gspca_dev);
1313 setsaturation(gspca_dev); 1374 setsaturation(gspca_dev);
1314 if (!(gspca_dev->ctrl_dis & (1 << AGC))) 1375 if (!(gspca_dev->ctrl_dis & (1 << AGC)))
1315 setagc(gspca_dev); 1376 setagc(gspca_dev);