diff options
author | Hans de Goede <j.w.r.degoede@hhs.nl> | 2008-07-17 09:30:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:27:46 -0400 |
commit | 12ff91264ce3e2f24013d667d44ba786f947506c (patch) | |
tree | 308b5aa64aeff2a93d29106bf8f71ce782598b07 /drivers/media | |
parent | 722103e390bb0a526f71440f44bf7f891614e1d6 (diff) |
V4L/DVB (8373): gspca: Hue, saturation and contrast controls added for sn9c10x ovxxxx.
(does not work with ov6650)
Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 177 |
1 files changed, 175 insertions, 2 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index d34d582e5f59..5b3490ad661a 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -45,6 +45,9 @@ struct sd { | |||
45 | unsigned char autogain; | 45 | unsigned char autogain; |
46 | unsigned char autogain_ignore_frames; | 46 | unsigned char autogain_ignore_frames; |
47 | unsigned char freq; /* light freq filter setting */ | 47 | unsigned char freq; /* light freq filter setting */ |
48 | unsigned char saturation; | ||
49 | unsigned char hue; | ||
50 | unsigned char contrast; | ||
48 | 51 | ||
49 | unsigned char fr_h_sz; /* size of frame header */ | 52 | unsigned char fr_h_sz; /* size of frame header */ |
50 | char sensor; /* Type of image sensor chip */ | 53 | char sensor; /* Type of image sensor chip */ |
@@ -89,6 +92,12 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | |||
89 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 92 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); |
90 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | 93 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); |
91 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 94 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
95 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); | ||
97 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
98 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
100 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | 101 | ||
93 | static struct ctrl sd_ctrls[] = { | 102 | static struct ctrl sd_ctrls[] = { |
94 | { | 103 | { |
@@ -165,6 +174,48 @@ static struct ctrl sd_ctrls[] = { | |||
165 | .set = sd_setfreq, | 174 | .set = sd_setfreq, |
166 | .get = sd_getfreq, | 175 | .get = sd_getfreq, |
167 | }, | 176 | }, |
177 | { | ||
178 | { | ||
179 | .id = V4L2_CID_SATURATION, | ||
180 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
181 | .name = "Saturation", | ||
182 | .minimum = 0, | ||
183 | .maximum = 255, | ||
184 | .step = 1, | ||
185 | #define SATURATION_DEF 127 | ||
186 | .default_value = SATURATION_DEF, | ||
187 | }, | ||
188 | .set = sd_setsaturation, | ||
189 | .get = sd_getsaturation, | ||
190 | }, | ||
191 | { | ||
192 | { | ||
193 | .id = V4L2_CID_HUE, | ||
194 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
195 | .name = "Hue", | ||
196 | .minimum = 0, | ||
197 | .maximum = 255, | ||
198 | .step = 1, | ||
199 | #define HUE_DEF 127 | ||
200 | .default_value = HUE_DEF, | ||
201 | }, | ||
202 | .set = sd_sethue, | ||
203 | .get = sd_gethue, | ||
204 | }, | ||
205 | { | ||
206 | { | ||
207 | .id = V4L2_CID_CONTRAST, | ||
208 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
209 | .name = "Contrast", | ||
210 | .minimum = 0, | ||
211 | .maximum = 255, | ||
212 | .step = 1, | ||
213 | #define CONTRAST_DEF 127 | ||
214 | .default_value = CONTRAST_DEF, | ||
215 | }, | ||
216 | .set = sd_setcontrast, | ||
217 | .get = sd_getcontrast, | ||
218 | }, | ||
168 | }; | 219 | }; |
169 | 220 | ||
170 | static struct v4l2_pix_format vga_mode[] = { | 221 | static struct v4l2_pix_format vga_mode[] = { |
@@ -735,6 +786,68 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
735 | } | 786 | } |
736 | } | 787 | } |
737 | 788 | ||
789 | static void setsaturation(struct gspca_dev *gspca_dev) | ||
790 | { | ||
791 | struct sd *sd = (struct sd *) gspca_dev; | ||
792 | |||
793 | switch (sd->sensor) { | ||
794 | /* case SENSOR_OV6650: */ | ||
795 | case SENSOR_OV7630_3: | ||
796 | case SENSOR_OV7630: { | ||
797 | __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
798 | i2c[1] = sd->sensor_addr; | ||
799 | i2c[3] = sd->saturation & 0xf0; | ||
800 | if (i2c_w(gspca_dev, i2c) < 0) | ||
801 | PDEBUG(D_ERR, "i2c error setsaturation"); | ||
802 | else | ||
803 | PDEBUG(D_CONF, "saturation set to: %d", | ||
804 | (int)sd->saturation); | ||
805 | break; | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | |||
810 | static void sethue(struct gspca_dev *gspca_dev) | ||
811 | { | ||
812 | struct sd *sd = (struct sd *) gspca_dev; | ||
813 | |||
814 | switch (sd->sensor) { | ||
815 | /* case SENSOR_OV6650: */ | ||
816 | case SENSOR_OV7630_3: | ||
817 | case SENSOR_OV7630: { | ||
818 | __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
819 | i2c[1] = sd->sensor_addr; | ||
820 | i2c[3] = 0x20 | (sd->hue >> 3); | ||
821 | if (i2c_w(gspca_dev, i2c) < 0) | ||
822 | PDEBUG(D_ERR, "i2c error setsaturation"); | ||
823 | else | ||
824 | PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue); | ||
825 | break; | ||
826 | } | ||
827 | } | ||
828 | } | ||
829 | |||
830 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
831 | { | ||
832 | struct sd *sd = (struct sd *) gspca_dev; | ||
833 | |||
834 | switch (sd->sensor) { | ||
835 | /* case SENSOR_OV6650: */ | ||
836 | case SENSOR_OV7630_3: | ||
837 | case SENSOR_OV7630: { | ||
838 | __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
839 | i2c[1] = sd->sensor_addr; | ||
840 | i2c[3] = 0x20 | (sd->contrast >> 3); | ||
841 | if (i2c_w(gspca_dev, i2c) < 0) | ||
842 | PDEBUG(D_ERR, "i2c error setcontrast"); | ||
843 | else | ||
844 | PDEBUG(D_CONF, "contrast set to: %d", | ||
845 | (int)sd->contrast); | ||
846 | break; | ||
847 | } | ||
848 | } | ||
849 | } | ||
850 | |||
738 | 851 | ||
739 | static void do_autogain(struct gspca_dev *gspca_dev) | 852 | static void do_autogain(struct gspca_dev *gspca_dev) |
740 | { | 853 | { |
@@ -771,7 +884,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
771 | sd->fr_h_sz = 12; /* default size of the frame header */ | 884 | sd->fr_h_sz = 12; /* default size of the frame header */ |
772 | sd->sd_desc.nctrls = 2; /* default nb of ctrls */ | 885 | sd->sd_desc.nctrls = 2; /* default nb of ctrls */ |
773 | sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ | 886 | sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ |
774 | sd->freq = FREQ_DEF; | ||
775 | 887 | ||
776 | product = id->idProduct; | 888 | product = id->idProduct; |
777 | /* switch (id->idVendor) { */ | 889 | /* switch (id->idVendor) { */ |
@@ -811,7 +923,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
811 | sd->sensor_addr = 0x21; | 923 | sd->sensor_addr = 0x21; |
812 | sd->fr_h_sz = 18; /* size of frame header */ | 924 | sd->fr_h_sz = 18; /* size of frame header */ |
813 | sd->sensor_has_gain = 1; | 925 | sd->sensor_has_gain = 1; |
814 | sd->sd_desc.nctrls = 5; | 926 | sd->sd_desc.nctrls = 8; |
815 | sd->sd_desc.dq_callback = do_autogain; | 927 | sd->sd_desc.dq_callback = do_autogain; |
816 | sd->autogain = 0; | 928 | sd->autogain = 0; |
817 | break; | 929 | break; |
@@ -851,6 +963,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
851 | sd->brightness = BRIGHTNESS_DEF; | 963 | sd->brightness = BRIGHTNESS_DEF; |
852 | sd->gain = GAIN_DEF; | 964 | sd->gain = GAIN_DEF; |
853 | sd->exposure = EXPOSURE_DEF; | 965 | sd->exposure = EXPOSURE_DEF; |
966 | sd->freq = FREQ_DEF; | ||
967 | sd->contrast = CONTRAST_DEF; | ||
968 | sd->saturation = SATURATION_DEF; | ||
969 | sd->hue = HUE_DEF; | ||
854 | if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ | 970 | if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ |
855 | reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); | 971 | reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); |
856 | return 0; | 972 | return 0; |
@@ -1033,6 +1149,9 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1033 | setbrightness(gspca_dev); | 1149 | setbrightness(gspca_dev); |
1034 | setexposure(gspca_dev); | 1150 | setexposure(gspca_dev); |
1035 | setfreq(gspca_dev); | 1151 | setfreq(gspca_dev); |
1152 | setsaturation(gspca_dev); | ||
1153 | sethue(gspca_dev); | ||
1154 | setcontrast(gspca_dev); | ||
1036 | 1155 | ||
1037 | sd->autogain_ignore_frames = 0; | 1156 | sd->autogain_ignore_frames = 0; |
1038 | atomic_set(&sd->avg_lum, -1); | 1157 | atomic_set(&sd->avg_lum, -1); |
@@ -1208,6 +1327,60 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | |||
1208 | return 0; | 1327 | return 0; |
1209 | } | 1328 | } |
1210 | 1329 | ||
1330 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) | ||
1331 | { | ||
1332 | struct sd *sd = (struct sd *) gspca_dev; | ||
1333 | |||
1334 | sd->saturation = val; | ||
1335 | if (gspca_dev->streaming) | ||
1336 | setsaturation(gspca_dev); | ||
1337 | return 0; | ||
1338 | } | ||
1339 | |||
1340 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) | ||
1341 | { | ||
1342 | struct sd *sd = (struct sd *) gspca_dev; | ||
1343 | |||
1344 | *val = sd->saturation; | ||
1345 | return 0; | ||
1346 | } | ||
1347 | |||
1348 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
1349 | { | ||
1350 | struct sd *sd = (struct sd *) gspca_dev; | ||
1351 | |||
1352 | sd->hue = val; | ||
1353 | if (gspca_dev->streaming) | ||
1354 | sethue(gspca_dev); | ||
1355 | return 0; | ||
1356 | } | ||
1357 | |||
1358 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
1359 | { | ||
1360 | struct sd *sd = (struct sd *) gspca_dev; | ||
1361 | |||
1362 | *val = sd->hue; | ||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1367 | { | ||
1368 | struct sd *sd = (struct sd *) gspca_dev; | ||
1369 | |||
1370 | sd->contrast = val; | ||
1371 | if (gspca_dev->streaming) | ||
1372 | setcontrast(gspca_dev); | ||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1377 | { | ||
1378 | struct sd *sd = (struct sd *) gspca_dev; | ||
1379 | |||
1380 | *val = sd->contrast; | ||
1381 | return 0; | ||
1382 | } | ||
1383 | |||
1211 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 1384 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
1212 | struct v4l2_querymenu *menu) | 1385 | struct v4l2_querymenu *menu) |
1213 | { | 1386 | { |