diff options
author | Antonio Ospite <ospite@studenti.unina.it> | 2012-05-14 07:07:45 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 08:48:00 -0400 |
commit | e89fca923f32de26b69bf4cd604f7b960b161551 (patch) | |
tree | ef5424c7d31eb424a86b5776ea9ed8bbd7a411d5 | |
parent | c8e1fb4a67eed95364a50f33f5201a88877c5215 (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.c | 65 |
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 */ |
55 | enum e_ctrl { | 57 | enum 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 */ |
93 | static void sethue(struct gspca_dev *gspca_dev); | ||
90 | static void setsaturation(struct gspca_dev *gspca_dev); | 94 | static void setsaturation(struct gspca_dev *gspca_dev); |
91 | static void setbrightness(struct gspca_dev *gspca_dev); | 95 | static void setbrightness(struct gspca_dev *gspca_dev); |
92 | static void setcontrast(struct gspca_dev *gspca_dev); | 96 | static void setcontrast(struct gspca_dev *gspca_dev); |
@@ -103,6 +107,18 @@ static int sd_start(struct gspca_dev *gspca_dev); | |||
103 | static void sd_stopN(struct gspca_dev *gspca_dev); | 107 | static void sd_stopN(struct gspca_dev *gspca_dev); |
104 | 108 | ||
105 | static const struct ctrl sd_ctrls[] = { | 109 | static 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 | ||
974 | static 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 | |||
958 | static void setsaturation(struct gspca_dev *gspca_dev) | 1016 | static 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); |