aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/Kconfig16
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/conex.c2
-rw-r--r--drivers/media/video/gspca/gspca.c73
-rw-r--r--drivers/media/video/gspca/gspca.h9
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c6
-rw-r--r--drivers/media/video/gspca/mars.c2
-rw-r--r--drivers/media/video/gspca/sn9c20x.c2434
-rw-r--r--drivers/media/video/gspca/sonixj.c4
-rw-r--r--drivers/media/video/gspca/spca500.c2
-rw-r--r--drivers/media/video/gspca/stk014.c2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.h4
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c16
-rw-r--r--drivers/media/video/gspca/sunplus.c2
-rw-r--r--drivers/media/video/gspca/zc3xx.c2
15 files changed, 2560 insertions, 16 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 578dc4ffc965..34f46f2bc040 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -102,6 +102,22 @@ config USB_GSPCA_PAC7311
102 To compile this driver as a module, choose M here: the 102 To compile this driver as a module, choose M here: the
103 module will be called gspca_pac7311. 103 module will be called gspca_pac7311.
104 104
105config USB_GSPCA_SN9C20X
106 tristate "SN9C20X USB Camera Driver"
107 depends on VIDEO_V4L2 && USB_GSPCA
108 help
109 Say Y here if you want support for cameras based on the
110 sn9c20x chips (SN9C201 and SN9C202).
111
112 To compile this driver as a module, choose M here: the
113 module will be called gspca_sn9c20x.
114
115config USB_GSPCA_SN9C20X_EVDEV
116 bool "Enable evdev support"
117 depends on USB_GSPCA_SN9C20X
118 ---help---
119 Say Y here in order to enable evdev support for sn9c20x webcam button.
120
105config USB_GSPCA_SONIXB 121config USB_GSPCA_SONIXB
106 tristate "SONIX Bayer USB Camera Driver" 122 tristate "SONIX Bayer USB Camera Driver"
107 depends on VIDEO_V4L2 && USB_GSPCA 123 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 8a6643e8eb96..f6d3b86e9ad5 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
8obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 8obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
9obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 9obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
10obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 10obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
11obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
11obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 12obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
12obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o 13obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
13obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o 14obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
@@ -35,6 +36,7 @@ gspca_ov519-objs := ov519.o
35gspca_ov534-objs := ov534.o 36gspca_ov534-objs := ov534.o
36gspca_pac207-objs := pac207.o 37gspca_pac207-objs := pac207.o
37gspca_pac7311-objs := pac7311.o 38gspca_pac7311-objs := pac7311.o
39gspca_sn9c20x-objs := sn9c20x.o
38gspca_sonixb-objs := sonixb.o 40gspca_sonixb-objs := sonixb.o
39gspca_sonixj-objs := sonixj.o 41gspca_sonixj-objs := sonixj.o
40gspca_spca500-objs := spca500.o 42gspca_spca500-objs := spca500.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 219cfa6fb877..8d48ea1742c2 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -846,6 +846,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
846 846
847 /* create the JPEG header */ 847 /* create the JPEG header */
848 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 848 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
849 if (!sd->jpeg_hdr)
850 return -ENOMEM;
849 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 851 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
850 0x22); /* JPEG 411 */ 852 0x22); /* JPEG 411 */
851 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 853 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 1e89600986c8..b8561dfb6c8c 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -727,6 +727,74 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev,
727 return -EINVAL; 727 return -EINVAL;
728} 728}
729 729
730#ifdef CONFIG_VIDEO_ADV_DEBUG
731static int vidioc_g_register(struct file *file, void *priv,
732 struct v4l2_dbg_register *reg)
733{
734 int ret;
735 struct gspca_dev *gspca_dev = priv;
736
737 if (!gspca_dev->sd_desc->get_chip_ident)
738 return -EINVAL;
739
740 if (!gspca_dev->sd_desc->get_register)
741 return -EINVAL;
742
743 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
744 return -ERESTARTSYS;
745 if (gspca_dev->present)
746 ret = gspca_dev->sd_desc->get_register(gspca_dev, reg);
747 else
748 ret = -ENODEV;
749 mutex_unlock(&gspca_dev->usb_lock);
750
751 return ret;
752}
753
754static int vidioc_s_register(struct file *file, void *priv,
755 struct v4l2_dbg_register *reg)
756{
757 int ret;
758 struct gspca_dev *gspca_dev = priv;
759
760 if (!gspca_dev->sd_desc->get_chip_ident)
761 return -EINVAL;
762
763 if (!gspca_dev->sd_desc->set_register)
764 return -EINVAL;
765
766 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
767 return -ERESTARTSYS;
768 if (gspca_dev->present)
769 ret = gspca_dev->sd_desc->set_register(gspca_dev, reg);
770 else
771 ret = -ENODEV;
772 mutex_unlock(&gspca_dev->usb_lock);
773
774 return ret;
775}
776#endif
777
778static int vidioc_g_chip_ident(struct file *file, void *priv,
779 struct v4l2_dbg_chip_ident *chip)
780{
781 int ret;
782 struct gspca_dev *gspca_dev = priv;
783
784 if (!gspca_dev->sd_desc->get_chip_ident)
785 return -EINVAL;
786
787 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
788 return -ERESTARTSYS;
789 if (gspca_dev->present)
790 ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
791 else
792 ret = -ENODEV;
793 mutex_unlock(&gspca_dev->usb_lock);
794
795 return ret;
796}
797
730static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 798static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
731 struct v4l2_fmtdesc *fmtdesc) 799 struct v4l2_fmtdesc *fmtdesc)
732{ 800{
@@ -1883,6 +1951,11 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
1883 .vidioc_s_parm = vidioc_s_parm, 1951 .vidioc_s_parm = vidioc_s_parm,
1884 .vidioc_s_std = vidioc_s_std, 1952 .vidioc_s_std = vidioc_s_std,
1885 .vidioc_enum_framesizes = vidioc_enum_framesizes, 1953 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1954#ifdef CONFIG_VIDEO_ADV_DEBUG
1955 .vidioc_g_register = vidioc_g_register,
1956 .vidioc_s_register = vidioc_s_register,
1957#endif
1958 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1886#ifdef CONFIG_VIDEO_V4L1_COMPAT 1959#ifdef CONFIG_VIDEO_V4L1_COMPAT
1887 .vidiocgmbuf = vidiocgmbuf, 1960 .vidiocgmbuf = vidiocgmbuf,
1888#endif 1961#endif
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index bd1faff88644..46c4effdfcd5 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -69,6 +69,10 @@ typedef void (*cam_v_op) (struct gspca_dev *);
69typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); 69typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
70typedef int (*cam_jpg_op) (struct gspca_dev *, 70typedef int (*cam_jpg_op) (struct gspca_dev *,
71 struct v4l2_jpegcompression *); 71 struct v4l2_jpegcompression *);
72typedef int (*cam_reg_op) (struct gspca_dev *,
73 struct v4l2_dbg_register *);
74typedef int (*cam_ident_op) (struct gspca_dev *,
75 struct v4l2_dbg_chip_ident *);
72typedef int (*cam_streamparm_op) (struct gspca_dev *, 76typedef int (*cam_streamparm_op) (struct gspca_dev *,
73 struct v4l2_streamparm *); 77 struct v4l2_streamparm *);
74typedef int (*cam_qmnu_op) (struct gspca_dev *, 78typedef int (*cam_qmnu_op) (struct gspca_dev *,
@@ -105,6 +109,11 @@ struct sd_desc {
105 cam_qmnu_op querymenu; 109 cam_qmnu_op querymenu;
106 cam_streamparm_op get_streamparm; 110 cam_streamparm_op get_streamparm;
107 cam_streamparm_op set_streamparm; 111 cam_streamparm_op set_streamparm;
112#ifdef CONFIG_VIDEO_ADV_DEBUG
113 cam_reg_op set_register;
114 cam_reg_op get_register;
115#endif
116 cam_ident_op get_chip_ident;
108}; 117};
109 118
110/* packet types when moving from iso buf to frame buf */ 119/* packet types when moving from iso buf to frame buf */
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 191bcd718979..0163903d1c0f 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -476,9 +476,6 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
476 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 476 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
477 if (err < 0) 477 if (err < 0)
478 return err; 478 return err;
479 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
480 if (err < 0)
481 return err;
482 479
483 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); 480 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
484 if (err < 0) 481 if (err < 0)
@@ -524,9 +521,6 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
524 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 521 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
525 if (err < 0) 522 if (err < 0)
526 return err; 523 return err;
527 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
528 if (err < 0)
529 return err;
530 524
531 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); 525 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
532 if (err < 0) 526 if (err < 0)
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 75e8d14e4ac7..de769caf013d 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -201,6 +201,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
201 201
202 /* create the JPEG header */ 202 /* create the JPEG header */
203 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 203 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
204 if (!sd->jpeg_hdr)
205 return -ENOMEM;
204 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 206 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
205 0x21); /* JPEG 422 */ 207 0x21); /* JPEG 422 */
206 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 208 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
new file mode 100644
index 000000000000..fcfbbd329b4c
--- /dev/null
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -0,0 +1,2434 @@
1/*
2 * Sonix sn9c201 sn9c202 library
3 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
4 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
22#include <linux/kthread.h>
23#include <linux/freezer.h>
24#include <linux/usb/input.h>
25#include <linux/input.h>
26#endif
27
28#include "gspca.h"
29#include "jpeg.h"
30
31#include <media/v4l2-chip-ident.h>
32
33MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
34 "microdia project <microdia@googlegroups.com>");
35MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
36MODULE_LICENSE("GPL");
37
38#define MODULE_NAME "sn9c20x"
39
40#define MODE_RAW 0x10
41#define MODE_JPEG 0x20
42#define MODE_SXGA 0x80
43
44#define SENSOR_OV9650 0
45#define SENSOR_OV9655 1
46#define SENSOR_SOI968 2
47#define SENSOR_OV7660 3
48#define SENSOR_OV7670 4
49#define SENSOR_MT9V011 5
50#define SENSOR_MT9V111 6
51#define SENSOR_MT9V112 7
52#define SENSOR_MT9M001 8
53#define SENSOR_MT9M111 9
54#define SENSOR_HV7131R 10
55#define SENSOR_MT9VPRB 20
56
57/* specific webcam descriptor */
58struct sd {
59 struct gspca_dev gspca_dev;
60
61#define MIN_AVG_LUM 80
62#define MAX_AVG_LUM 130
63 atomic_t avg_lum;
64 u8 old_step;
65 u8 older_step;
66 u8 exposure_step;
67
68 u8 brightness;
69 u8 contrast;
70 u8 saturation;
71 s16 hue;
72 u8 gamma;
73 u8 red;
74 u8 blue;
75
76 u8 hflip;
77 u8 vflip;
78 u8 gain;
79 u16 exposure;
80 u8 auto_exposure;
81
82 u8 i2c_addr;
83 u8 sensor;
84 u8 hstart;
85 u8 vstart;
86
87 u8 *jpeg_hdr;
88 u8 quality;
89
90#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
91 struct input_dev *input_dev;
92 u8 input_gpio;
93 struct task_struct *input_task;
94#endif
95};
96
97static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
98static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
99static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
100static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
101static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
102static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
103static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
104static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
105static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
106static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
107static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
108static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
109static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
110static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
111static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
112static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
113static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
114static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
115static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
116static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
117static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
118static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
119static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
120static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
121
122static struct ctrl sd_ctrls[] = {
123 {
124#define BRIGHTNESS_IDX 0
125 {
126 .id = V4L2_CID_BRIGHTNESS,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Brightness",
129 .minimum = 0,
130 .maximum = 0xff,
131 .step = 1,
132#define BRIGHTNESS_DEFAULT 0x7f
133 .default_value = BRIGHTNESS_DEFAULT,
134 },
135 .set = sd_setbrightness,
136 .get = sd_getbrightness,
137 },
138 {
139#define CONTRAST_IDX 1
140 {
141 .id = V4L2_CID_CONTRAST,
142 .type = V4L2_CTRL_TYPE_INTEGER,
143 .name = "Contrast",
144 .minimum = 0,
145 .maximum = 0xff,
146 .step = 1,
147#define CONTRAST_DEFAULT 0x7f
148 .default_value = CONTRAST_DEFAULT,
149 },
150 .set = sd_setcontrast,
151 .get = sd_getcontrast,
152 },
153 {
154#define SATURATION_IDX 2
155 {
156 .id = V4L2_CID_SATURATION,
157 .type = V4L2_CTRL_TYPE_INTEGER,
158 .name = "Saturation",
159 .minimum = 0,
160 .maximum = 0xff,
161 .step = 1,
162#define SATURATION_DEFAULT 0x7f
163 .default_value = SATURATION_DEFAULT,
164 },
165 .set = sd_setsaturation,
166 .get = sd_getsaturation,
167 },
168 {
169#define HUE_IDX 3
170 {
171 .id = V4L2_CID_HUE,
172 .type = V4L2_CTRL_TYPE_INTEGER,
173 .name = "Hue",
174 .minimum = -180,
175 .maximum = 180,
176 .step = 1,
177#define HUE_DEFAULT 0
178 .default_value = HUE_DEFAULT,
179 },
180 .set = sd_sethue,
181 .get = sd_gethue,
182 },
183 {
184#define GAMMA_IDX 4
185 {
186 .id = V4L2_CID_GAMMA,
187 .type = V4L2_CTRL_TYPE_INTEGER,
188 .name = "Gamma",
189 .minimum = 0,
190 .maximum = 0xff,
191 .step = 1,
192#define GAMMA_DEFAULT 0x10
193 .default_value = GAMMA_DEFAULT,
194 },
195 .set = sd_setgamma,
196 .get = sd_getgamma,
197 },
198 {
199#define BLUE_IDX 5
200 {
201 .id = V4L2_CID_BLUE_BALANCE,
202 .type = V4L2_CTRL_TYPE_INTEGER,
203 .name = "Blue Balance",
204 .minimum = 0,
205 .maximum = 0x7f,
206 .step = 1,
207#define BLUE_DEFAULT 0x28
208 .default_value = BLUE_DEFAULT,
209 },
210 .set = sd_setbluebalance,
211 .get = sd_getbluebalance,
212 },
213 {
214#define RED_IDX 6
215 {
216 .id = V4L2_CID_RED_BALANCE,
217 .type = V4L2_CTRL_TYPE_INTEGER,
218 .name = "Red Balance",
219 .minimum = 0,
220 .maximum = 0x7f,
221 .step = 1,
222#define RED_DEFAULT 0x28
223 .default_value = RED_DEFAULT,
224 },
225 .set = sd_setredbalance,
226 .get = sd_getredbalance,
227 },
228 {
229#define HFLIP_IDX 7
230 {
231 .id = V4L2_CID_HFLIP,
232 .type = V4L2_CTRL_TYPE_BOOLEAN,
233 .name = "Horizontal Flip",
234 .minimum = 0,
235 .maximum = 1,
236 .step = 1,
237#define HFLIP_DEFAULT 0
238 .default_value = HFLIP_DEFAULT,
239 },
240 .set = sd_sethflip,
241 .get = sd_gethflip,
242 },
243 {
244#define VFLIP_IDX 8
245 {
246 .id = V4L2_CID_VFLIP,
247 .type = V4L2_CTRL_TYPE_BOOLEAN,
248 .name = "Vertical Flip",
249 .minimum = 0,
250 .maximum = 1,
251 .step = 1,
252#define VFLIP_DEFAULT 0
253 .default_value = VFLIP_DEFAULT,
254 },
255 .set = sd_setvflip,
256 .get = sd_getvflip,
257 },
258 {
259#define EXPOSURE_IDX 9
260 {
261 .id = V4L2_CID_EXPOSURE,
262 .type = V4L2_CTRL_TYPE_INTEGER,
263 .name = "Exposure",
264 .minimum = 0,
265 .maximum = 0x1780,
266 .step = 1,
267#define EXPOSURE_DEFAULT 0x33
268 .default_value = EXPOSURE_DEFAULT,
269 },
270 .set = sd_setexposure,
271 .get = sd_getexposure,
272 },
273 {
274#define GAIN_IDX 10
275 {
276 .id = V4L2_CID_GAIN,
277 .type = V4L2_CTRL_TYPE_INTEGER,
278 .name = "Gain",
279 .minimum = 0,
280 .maximum = 28,
281 .step = 1,
282#define GAIN_DEFAULT 0x00
283 .default_value = GAIN_DEFAULT,
284 },
285 .set = sd_setgain,
286 .get = sd_getgain,
287 },
288 {
289#define AUTOGAIN_IDX 11
290 {
291 .id = V4L2_CID_AUTOGAIN,
292 .type = V4L2_CTRL_TYPE_BOOLEAN,
293 .name = "Auto Exposure",
294 .minimum = 0,
295 .maximum = 1,
296 .step = 1,
297#define AUTO_EXPOSURE_DEFAULT 1
298 .default_value = AUTO_EXPOSURE_DEFAULT,
299 },
300 .set = sd_setautoexposure,
301 .get = sd_getautoexposure,
302 },
303};
304
305static const struct v4l2_pix_format vga_mode[] = {
306 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
307 .bytesperline = 240,
308 .sizeimage = 240 * 120,
309 .colorspace = V4L2_COLORSPACE_JPEG,
310 .priv = 0 | MODE_JPEG},
311 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
312 .bytesperline = 160,
313 .sizeimage = 160 * 120,
314 .colorspace = V4L2_COLORSPACE_SRGB,
315 .priv = 0 | MODE_RAW},
316 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
317 .bytesperline = 240,
318 .sizeimage = 240 * 120,
319 .colorspace = V4L2_COLORSPACE_SRGB,
320 .priv = 0},
321 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
322 .bytesperline = 480,
323 .sizeimage = 480 * 240 ,
324 .colorspace = V4L2_COLORSPACE_JPEG,
325 .priv = 1 | MODE_JPEG},
326 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
327 .bytesperline = 320,
328 .sizeimage = 320 * 240 ,
329 .colorspace = V4L2_COLORSPACE_SRGB,
330 .priv = 1 | MODE_RAW},
331 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
332 .bytesperline = 480,
333 .sizeimage = 480 * 240 ,
334 .colorspace = V4L2_COLORSPACE_SRGB,
335 .priv = 1},
336 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
337 .bytesperline = 960,
338 .sizeimage = 960 * 480,
339 .colorspace = V4L2_COLORSPACE_JPEG,
340 .priv = 2 | MODE_JPEG},
341 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
342 .bytesperline = 640,
343 .sizeimage = 640 * 480,
344 .colorspace = V4L2_COLORSPACE_SRGB,
345 .priv = 2 | MODE_RAW},
346 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
347 .bytesperline = 960,
348 .sizeimage = 960 * 480,
349 .colorspace = V4L2_COLORSPACE_SRGB,
350 .priv = 2},
351};
352
353static const struct v4l2_pix_format sxga_mode[] = {
354 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
355 .bytesperline = 240,
356 .sizeimage = 240 * 120,
357 .colorspace = V4L2_COLORSPACE_JPEG,
358 .priv = 0 | MODE_JPEG},
359 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
360 .bytesperline = 160,
361 .sizeimage = 160 * 120,
362 .colorspace = V4L2_COLORSPACE_SRGB,
363 .priv = 0 | MODE_RAW},
364 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
365 .bytesperline = 240,
366 .sizeimage = 240 * 120,
367 .colorspace = V4L2_COLORSPACE_SRGB,
368 .priv = 0},
369 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
370 .bytesperline = 480,
371 .sizeimage = 480 * 240 ,
372 .colorspace = V4L2_COLORSPACE_JPEG,
373 .priv = 1 | MODE_JPEG},
374 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
375 .bytesperline = 320,
376 .sizeimage = 320 * 240 ,
377 .colorspace = V4L2_COLORSPACE_SRGB,
378 .priv = 1 | MODE_RAW},
379 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
380 .bytesperline = 480,
381 .sizeimage = 480 * 240 ,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = 1},
384 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
385 .bytesperline = 960,
386 .sizeimage = 960 * 480,
387 .colorspace = V4L2_COLORSPACE_JPEG,
388 .priv = 2 | MODE_JPEG},
389 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
390 .bytesperline = 640,
391 .sizeimage = 640 * 480,
392 .colorspace = V4L2_COLORSPACE_SRGB,
393 .priv = 2 | MODE_RAW},
394 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
395 .bytesperline = 960,
396 .sizeimage = 960 * 480,
397 .colorspace = V4L2_COLORSPACE_SRGB,
398 .priv = 2},
399 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
400 .bytesperline = 1280,
401 .sizeimage = (1280 * 1024) + 64,
402 .colorspace = V4L2_COLORSPACE_SRGB,
403 .priv = 3 | MODE_RAW | MODE_SXGA},
404};
405
406static const int hsv_red_x[] = {
407 41, 44, 46, 48, 50, 52, 54, 56,
408 58, 60, 62, 64, 66, 68, 70, 72,
409 74, 76, 78, 80, 81, 83, 85, 87,
410 88, 90, 92, 93, 95, 97, 98, 100,
411 101, 102, 104, 105, 107, 108, 109, 110,
412 112, 113, 114, 115, 116, 117, 118, 119,
413 120, 121, 122, 123, 123, 124, 125, 125,
414 126, 127, 127, 128, 128, 129, 129, 129,
415 130, 130, 130, 130, 131, 131, 131, 131,
416 131, 131, 131, 131, 130, 130, 130, 130,
417 129, 129, 129, 128, 128, 127, 127, 126,
418 125, 125, 124, 123, 122, 122, 121, 120,
419 119, 118, 117, 116, 115, 114, 112, 111,
420 110, 109, 107, 106, 105, 103, 102, 101,
421 99, 98, 96, 94, 93, 91, 90, 88,
422 86, 84, 83, 81, 79, 77, 75, 74,
423 72, 70, 68, 66, 64, 62, 60, 58,
424 56, 54, 52, 49, 47, 45, 43, 41,
425 39, 36, 34, 32, 30, 28, 25, 23,
426 21, 19, 16, 14, 12, 9, 7, 5,
427 3, 0, -1, -3, -6, -8, -10, -12,
428 -15, -17, -19, -22, -24, -26, -28, -30,
429 -33, -35, -37, -39, -41, -44, -46, -48,
430 -50, -52, -54, -56, -58, -60, -62, -64,
431 -66, -68, -70, -72, -74, -76, -78, -80,
432 -81, -83, -85, -87, -88, -90, -92, -93,
433 -95, -97, -98, -100, -101, -102, -104, -105,
434 -107, -108, -109, -110, -112, -113, -114, -115,
435 -116, -117, -118, -119, -120, -121, -122, -123,
436 -123, -124, -125, -125, -126, -127, -127, -128,
437 -128, -128, -128, -128, -128, -128, -128, -128,
438 -128, -128, -128, -128, -128, -128, -128, -128,
439 -128, -128, -128, -128, -128, -128, -128, -128,
440 -128, -127, -127, -126, -125, -125, -124, -123,
441 -122, -122, -121, -120, -119, -118, -117, -116,
442 -115, -114, -112, -111, -110, -109, -107, -106,
443 -105, -103, -102, -101, -99, -98, -96, -94,
444 -93, -91, -90, -88, -86, -84, -83, -81,
445 -79, -77, -75, -74, -72, -70, -68, -66,
446 -64, -62, -60, -58, -56, -54, -52, -49,
447 -47, -45, -43, -41, -39, -36, -34, -32,
448 -30, -28, -25, -23, -21, -19, -16, -14,
449 -12, -9, -7, -5, -3, 0, 1, 3,
450 6, 8, 10, 12, 15, 17, 19, 22,
451 24, 26, 28, 30, 33, 35, 37, 39, 41
452};
453
454static const int hsv_red_y[] = {
455 82, 80, 78, 76, 74, 73, 71, 69,
456 67, 65, 63, 61, 58, 56, 54, 52,
457 50, 48, 46, 44, 41, 39, 37, 35,
458 32, 30, 28, 26, 23, 21, 19, 16,
459 14, 12, 10, 7, 5, 3, 0, -1,
460 -3, -6, -8, -10, -13, -15, -17, -19,
461 -22, -24, -26, -29, -31, -33, -35, -38,
462 -40, -42, -44, -46, -48, -51, -53, -55,
463 -57, -59, -61, -63, -65, -67, -69, -71,
464 -73, -75, -77, -79, -81, -82, -84, -86,
465 -88, -89, -91, -93, -94, -96, -98, -99,
466 -101, -102, -104, -105, -106, -108, -109, -110,
467 -112, -113, -114, -115, -116, -117, -119, -120,
468 -120, -121, -122, -123, -124, -125, -126, -126,
469 -127, -128, -128, -128, -128, -128, -128, -128,
470 -128, -128, -128, -128, -128, -128, -128, -128,
471 -128, -128, -128, -128, -128, -128, -128, -128,
472 -128, -128, -128, -128, -128, -128, -128, -128,
473 -127, -127, -126, -125, -125, -124, -123, -122,
474 -121, -120, -119, -118, -117, -116, -115, -114,
475 -113, -111, -110, -109, -107, -106, -105, -103,
476 -102, -100, -99, -97, -96, -94, -92, -91,
477 -89, -87, -85, -84, -82, -80, -78, -76,
478 -74, -73, -71, -69, -67, -65, -63, -61,
479 -58, -56, -54, -52, -50, -48, -46, -44,
480 -41, -39, -37, -35, -32, -30, -28, -26,
481 -23, -21, -19, -16, -14, -12, -10, -7,
482 -5, -3, 0, 1, 3, 6, 8, 10,
483 13, 15, 17, 19, 22, 24, 26, 29,
484 31, 33, 35, 38, 40, 42, 44, 46,
485 48, 51, 53, 55, 57, 59, 61, 63,
486 65, 67, 69, 71, 73, 75, 77, 79,
487 81, 82, 84, 86, 88, 89, 91, 93,
488 94, 96, 98, 99, 101, 102, 104, 105,
489 106, 108, 109, 110, 112, 113, 114, 115,
490 116, 117, 119, 120, 120, 121, 122, 123,
491 124, 125, 126, 126, 127, 128, 128, 129,
492 129, 130, 130, 131, 131, 131, 131, 132,
493 132, 132, 132, 132, 132, 132, 132, 132,
494 132, 132, 132, 131, 131, 131, 130, 130,
495 130, 129, 129, 128, 127, 127, 126, 125,
496 125, 124, 123, 122, 121, 120, 119, 118,
497 117, 116, 115, 114, 113, 111, 110, 109,
498 107, 106, 105, 103, 102, 100, 99, 97,
499 96, 94, 92, 91, 89, 87, 85, 84, 82
500};
501
502static const int hsv_green_x[] = {
503 -124, -124, -125, -125, -125, -125, -125, -125,
504 -125, -126, -126, -125, -125, -125, -125, -125,
505 -125, -124, -124, -124, -123, -123, -122, -122,
506 -121, -121, -120, -120, -119, -118, -117, -117,
507 -116, -115, -114, -113, -112, -111, -110, -109,
508 -108, -107, -105, -104, -103, -102, -100, -99,
509 -98, -96, -95, -93, -92, -91, -89, -87,
510 -86, -84, -83, -81, -79, -77, -76, -74,
511 -72, -70, -69, -67, -65, -63, -61, -59,
512 -57, -55, -53, -51, -49, -47, -45, -43,
513 -41, -39, -37, -35, -33, -30, -28, -26,
514 -24, -22, -20, -18, -15, -13, -11, -9,
515 -7, -4, -2, 0, 1, 3, 6, 8,
516 10, 12, 14, 17, 19, 21, 23, 25,
517 27, 29, 32, 34, 36, 38, 40, 42,
518 44, 46, 48, 50, 52, 54, 56, 58,
519 60, 62, 64, 66, 68, 70, 71, 73,
520 75, 77, 78, 80, 82, 83, 85, 87,
521 88, 90, 91, 93, 94, 96, 97, 98,
522 100, 101, 102, 104, 105, 106, 107, 108,
523 109, 111, 112, 113, 113, 114, 115, 116,
524 117, 118, 118, 119, 120, 120, 121, 122,
525 122, 123, 123, 124, 124, 124, 125, 125,
526 125, 125, 125, 125, 125, 126, 126, 125,
527 125, 125, 125, 125, 125, 124, 124, 124,
528 123, 123, 122, 122, 121, 121, 120, 120,
529 119, 118, 117, 117, 116, 115, 114, 113,
530 112, 111, 110, 109, 108, 107, 105, 104,
531 103, 102, 100, 99, 98, 96, 95, 93,
532 92, 91, 89, 87, 86, 84, 83, 81,
533 79, 77, 76, 74, 72, 70, 69, 67,
534 65, 63, 61, 59, 57, 55, 53, 51,
535 49, 47, 45, 43, 41, 39, 37, 35,
536 33, 30, 28, 26, 24, 22, 20, 18,
537 15, 13, 11, 9, 7, 4, 2, 0,
538 -1, -3, -6, -8, -10, -12, -14, -17,
539 -19, -21, -23, -25, -27, -29, -32, -34,
540 -36, -38, -40, -42, -44, -46, -48, -50,
541 -52, -54, -56, -58, -60, -62, -64, -66,
542 -68, -70, -71, -73, -75, -77, -78, -80,
543 -82, -83, -85, -87, -88, -90, -91, -93,
544 -94, -96, -97, -98, -100, -101, -102, -104,
545 -105, -106, -107, -108, -109, -111, -112, -113,
546 -113, -114, -115, -116, -117, -118, -118, -119,
547 -120, -120, -121, -122, -122, -123, -123, -124, -124
548};
549
550static const int hsv_green_y[] = {
551 -100, -99, -98, -97, -95, -94, -93, -91,
552 -90, -89, -87, -86, -84, -83, -81, -80,
553 -78, -76, -75, -73, -71, -70, -68, -66,
554 -64, -63, -61, -59, -57, -55, -53, -51,
555 -49, -48, -46, -44, -42, -40, -38, -36,
556 -34, -32, -30, -27, -25, -23, -21, -19,
557 -17, -15, -13, -11, -9, -7, -4, -2,
558 0, 1, 3, 5, 7, 9, 11, 14,
559 16, 18, 20, 22, 24, 26, 28, 30,
560 32, 34, 36, 38, 40, 42, 44, 46,
561 48, 50, 52, 54, 56, 58, 59, 61,
562 63, 65, 67, 68, 70, 72, 74, 75,
563 77, 78, 80, 82, 83, 85, 86, 88,
564 89, 90, 92, 93, 95, 96, 97, 98,
565 100, 101, 102, 103, 104, 105, 106, 107,
566 108, 109, 110, 111, 112, 112, 113, 114,
567 115, 115, 116, 116, 117, 117, 118, 118,
568 119, 119, 119, 120, 120, 120, 120, 120,
569 121, 121, 121, 121, 121, 121, 120, 120,
570 120, 120, 120, 119, 119, 119, 118, 118,
571 117, 117, 116, 116, 115, 114, 114, 113,
572 112, 111, 111, 110, 109, 108, 107, 106,
573 105, 104, 103, 102, 100, 99, 98, 97,
574 95, 94, 93, 91, 90, 89, 87, 86,
575 84, 83, 81, 80, 78, 76, 75, 73,
576 71, 70, 68, 66, 64, 63, 61, 59,
577 57, 55, 53, 51, 49, 48, 46, 44,
578 42, 40, 38, 36, 34, 32, 30, 27,
579 25, 23, 21, 19, 17, 15, 13, 11,
580 9, 7, 4, 2, 0, -1, -3, -5,
581 -7, -9, -11, -14, -16, -18, -20, -22,
582 -24, -26, -28, -30, -32, -34, -36, -38,
583 -40, -42, -44, -46, -48, -50, -52, -54,
584 -56, -58, -59, -61, -63, -65, -67, -68,
585 -70, -72, -74, -75, -77, -78, -80, -82,
586 -83, -85, -86, -88, -89, -90, -92, -93,
587 -95, -96, -97, -98, -100, -101, -102, -103,
588 -104, -105, -106, -107, -108, -109, -110, -111,
589 -112, -112, -113, -114, -115, -115, -116, -116,
590 -117, -117, -118, -118, -119, -119, -119, -120,
591 -120, -120, -120, -120, -121, -121, -121, -121,
592 -121, -121, -120, -120, -120, -120, -120, -119,
593 -119, -119, -118, -118, -117, -117, -116, -116,
594 -115, -114, -114, -113, -112, -111, -111, -110,
595 -109, -108, -107, -106, -105, -104, -103, -102, -100
596};
597
598static const int hsv_blue_x[] = {
599 112, 113, 114, 114, 115, 116, 117, 117,
600 118, 118, 119, 119, 120, 120, 120, 121,
601 121, 121, 122, 122, 122, 122, 122, 122,
602 122, 122, 122, 122, 122, 122, 121, 121,
603 121, 120, 120, 120, 119, 119, 118, 118,
604 117, 116, 116, 115, 114, 113, 113, 112,
605 111, 110, 109, 108, 107, 106, 105, 104,
606 103, 102, 100, 99, 98, 97, 95, 94,
607 93, 91, 90, 88, 87, 85, 84, 82,
608 80, 79, 77, 76, 74, 72, 70, 69,
609 67, 65, 63, 61, 60, 58, 56, 54,
610 52, 50, 48, 46, 44, 42, 40, 38,
611 36, 34, 32, 30, 28, 26, 24, 22,
612 19, 17, 15, 13, 11, 9, 7, 5,
613 2, 0, -1, -3, -5, -7, -9, -12,
614 -14, -16, -18, -20, -22, -24, -26, -28,
615 -31, -33, -35, -37, -39, -41, -43, -45,
616 -47, -49, -51, -53, -54, -56, -58, -60,
617 -62, -64, -66, -67, -69, -71, -73, -74,
618 -76, -78, -79, -81, -83, -84, -86, -87,
619 -89, -90, -92, -93, -94, -96, -97, -98,
620 -99, -101, -102, -103, -104, -105, -106, -107,
621 -108, -109, -110, -111, -112, -113, -114, -114,
622 -115, -116, -117, -117, -118, -118, -119, -119,
623 -120, -120, -120, -121, -121, -121, -122, -122,
624 -122, -122, -122, -122, -122, -122, -122, -122,
625 -122, -122, -121, -121, -121, -120, -120, -120,
626 -119, -119, -118, -118, -117, -116, -116, -115,
627 -114, -113, -113, -112, -111, -110, -109, -108,
628 -107, -106, -105, -104, -103, -102, -100, -99,
629 -98, -97, -95, -94, -93, -91, -90, -88,
630 -87, -85, -84, -82, -80, -79, -77, -76,
631 -74, -72, -70, -69, -67, -65, -63, -61,
632 -60, -58, -56, -54, -52, -50, -48, -46,
633 -44, -42, -40, -38, -36, -34, -32, -30,
634 -28, -26, -24, -22, -19, -17, -15, -13,
635 -11, -9, -7, -5, -2, 0, 1, 3,
636 5, 7, 9, 12, 14, 16, 18, 20,
637 22, 24, 26, 28, 31, 33, 35, 37,
638 39, 41, 43, 45, 47, 49, 51, 53,
639 54, 56, 58, 60, 62, 64, 66, 67,
640 69, 71, 73, 74, 76, 78, 79, 81,
641 83, 84, 86, 87, 89, 90, 92, 93,
642 94, 96, 97, 98, 99, 101, 102, 103,
643 104, 105, 106, 107, 108, 109, 110, 111, 112
644};
645
646static const int hsv_blue_y[] = {
647 -11, -13, -15, -17, -19, -21, -23, -25,
648 -27, -29, -31, -33, -35, -37, -39, -41,
649 -43, -45, -46, -48, -50, -52, -54, -55,
650 -57, -59, -61, -62, -64, -66, -67, -69,
651 -71, -72, -74, -75, -77, -78, -80, -81,
652 -83, -84, -86, -87, -88, -90, -91, -92,
653 -93, -95, -96, -97, -98, -99, -100, -101,
654 -102, -103, -104, -105, -106, -106, -107, -108,
655 -109, -109, -110, -111, -111, -112, -112, -113,
656 -113, -114, -114, -114, -115, -115, -115, -115,
657 -116, -116, -116, -116, -116, -116, -116, -116,
658 -116, -115, -115, -115, -115, -114, -114, -114,
659 -113, -113, -112, -112, -111, -111, -110, -110,
660 -109, -108, -108, -107, -106, -105, -104, -103,
661 -102, -101, -100, -99, -98, -97, -96, -95,
662 -94, -93, -91, -90, -89, -88, -86, -85,
663 -84, -82, -81, -79, -78, -76, -75, -73,
664 -71, -70, -68, -67, -65, -63, -62, -60,
665 -58, -56, -55, -53, -51, -49, -47, -45,
666 -44, -42, -40, -38, -36, -34, -32, -30,
667 -28, -26, -24, -22, -20, -18, -16, -14,
668 -12, -10, -8, -6, -4, -2, 0, 1,
669 3, 5, 7, 9, 11, 13, 15, 17,
670 19, 21, 23, 25, 27, 29, 31, 33,
671 35, 37, 39, 41, 43, 45, 46, 48,
672 50, 52, 54, 55, 57, 59, 61, 62,
673 64, 66, 67, 69, 71, 72, 74, 75,
674 77, 78, 80, 81, 83, 84, 86, 87,
675 88, 90, 91, 92, 93, 95, 96, 97,
676 98, 99, 100, 101, 102, 103, 104, 105,
677 106, 106, 107, 108, 109, 109, 110, 111,
678 111, 112, 112, 113, 113, 114, 114, 114,
679 115, 115, 115, 115, 116, 116, 116, 116,
680 116, 116, 116, 116, 116, 115, 115, 115,
681 115, 114, 114, 114, 113, 113, 112, 112,
682 111, 111, 110, 110, 109, 108, 108, 107,
683 106, 105, 104, 103, 102, 101, 100, 99,
684 98, 97, 96, 95, 94, 93, 91, 90,
685 89, 88, 86, 85, 84, 82, 81, 79,
686 78, 76, 75, 73, 71, 70, 68, 67,
687 65, 63, 62, 60, 58, 56, 55, 53,
688 51, 49, 47, 45, 44, 42, 40, 38,
689 36, 34, 32, 30, 28, 26, 24, 22,
690 20, 18, 16, 14, 12, 10, 8, 6,
691 4, 2, 0, -1, -3, -5, -7, -9, -11
692};
693
694static u16 i2c_ident[] = {
695 V4L2_IDENT_OV9650,
696 V4L2_IDENT_OV9655,
697 V4L2_IDENT_SOI968,
698 V4L2_IDENT_OV7660,
699 V4L2_IDENT_OV7670,
700 V4L2_IDENT_MT9V011,
701 V4L2_IDENT_MT9V111,
702 V4L2_IDENT_MT9V112,
703 V4L2_IDENT_MT9M001C12ST,
704 V4L2_IDENT_MT9M111,
705 V4L2_IDENT_HV7131R,
706};
707
708static u16 bridge_init[][2] = {
709 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
710 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
711 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
712 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
713 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
714 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
715 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
716 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
717 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
718 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
719 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
720 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
721 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
722 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
723 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
724 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
725 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
726 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
727 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}
728};
729
730/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
731static u8 ov_gain[] = {
732 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
733 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
734 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
735 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
736 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
737 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
738 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
739 0x70 /* 8x */
740};
741
742/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
743static u16 micron1_gain[] = {
744 /* 1x 1.25x 1.5x 1.75x */
745 0x0020, 0x0028, 0x0030, 0x0038,
746 /* 2x 2.25x 2.5x 2.75x */
747 0x00a0, 0x00a4, 0x00a8, 0x00ac,
748 /* 3x 3.25x 3.5x 3.75x */
749 0x00b0, 0x00b4, 0x00b8, 0x00bc,
750 /* 4x 4.25x 4.5x 4.75x */
751 0x00c0, 0x00c4, 0x00c8, 0x00cc,
752 /* 5x 5.25x 5.5x 5.75x */
753 0x00d0, 0x00d4, 0x00d8, 0x00dc,
754 /* 6x 6.25x 6.5x 6.75x */
755 0x00e0, 0x00e4, 0x00e8, 0x00ec,
756 /* 7x 7.25x 7.5x 7.75x */
757 0x00f0, 0x00f4, 0x00f8, 0x00fc,
758 /* 8x */
759 0x01c0
760};
761
762/* mt9m001 sensor uses a different gain formula then other micron sensors */
763/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
764static u16 micron2_gain[] = {
765 /* 1x 1.25x 1.5x 1.75x */
766 0x0008, 0x000a, 0x000c, 0x000e,
767 /* 2x 2.25x 2.5x 2.75x */
768 0x0010, 0x0012, 0x0014, 0x0016,
769 /* 3x 3.25x 3.5x 3.75x */
770 0x0018, 0x001a, 0x001c, 0x001e,
771 /* 4x 4.25x 4.5x 4.75x */
772 0x0020, 0x0051, 0x0052, 0x0053,
773 /* 5x 5.25x 5.5x 5.75x */
774 0x0054, 0x0055, 0x0056, 0x0057,
775 /* 6x 6.25x 6.5x 6.75x */
776 0x0058, 0x0059, 0x005a, 0x005b,
777 /* 7x 7.25x 7.5x 7.75x */
778 0x005c, 0x005d, 0x005e, 0x005f,
779 /* 8x */
780 0x0060
781};
782
783/* Gain = .5 + bit[7:0] / 16 */
784static u8 hv7131r_gain[] = {
785 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
786 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
787 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
788 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
789 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
790 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
791 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
792 0x78 /* 8x */
793};
794
795static u8 soi968_init[][2] = {
796 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
797 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
798 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
799 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
800 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
801 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
802 {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13},
803 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
804 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
805 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
806 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
807};
808
809static u8 ov7660_init[][2] = {
810 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
811 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
812 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
813 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
814 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
815 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
816};
817
818static u8 ov7670_init[][2] = {
819 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
820 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
821 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
822 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
823 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
824 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
825 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
826 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
827 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
828 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
829 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
830 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
831 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
832 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
833 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
834 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
835 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
836 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
837 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
838 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
839 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
840 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
841 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
842 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
843 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
844 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
845 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
846 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
847 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
848 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
849 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
850 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
851 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
852 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
853 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
854 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
855 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
856 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
857 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
858 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
859 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
860 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
861 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
862 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
863 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
864 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
865 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
866 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
867 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
868 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
869 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
870 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
871 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
872 {0x93, 0x00},
873};
874
875static u8 ov9650_init[][2] = {
876 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
877 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
878 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
879 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
880 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
881 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
882 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
883 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
884 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
885 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
886 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
887 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
888 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
889 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
890 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
891 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
892 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
893 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
894 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
895 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
896 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
897 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
898 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
899 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
900 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
901 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
902 {0xaa, 0x92}, {0xab, 0x0a},
903};
904
905static u8 ov9655_init[][2] = {
906 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
907 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
908 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
909 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf},
910 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12},
911 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c},
912 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40},
913 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a},
914 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc},
915 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04},
916 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02},
917 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c},
918 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60},
919 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04},
920 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80},
921 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf},
922 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
923 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
924 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
925 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61},
926 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
927 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01},
928 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10},
929 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04},
930 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00},
931 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
932 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
933 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
934 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
935 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
936 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
937 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
938 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
939 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
940};
941
942static u16 mt9v112_init[][2] = {
943 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
944 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
945 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
946 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
947 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
948 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
949 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
950 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
951 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
952 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
953 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
954 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
955 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
956 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
957 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
958 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
959};
960
961static u16 mt9v111_init[][2] = {
962 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
963 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
964 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
965 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
966 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
967 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
968 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
969 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
970 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
971 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
972 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
973 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
974 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
975 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
976 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
977 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
978 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
979 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
980 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
981 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
982 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
983 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
984 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
985 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
986};
987
988static u16 mt9v011_init[][2] = {
989 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
990 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
991 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
992 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
993 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
994 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
995 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
996 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
997 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
998 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
999 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1000 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1001 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1002 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1003 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1004 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1005 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1006 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1007 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1008 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1009 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1010 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1011 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1012 {0x06, 0x0029}, {0x05, 0x0009},
1013};
1014
1015static u16 mt9m001_init[][2] = {
1016 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1017 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1018 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1019 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1020 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1021 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1022 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1023 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1024 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1025 {0x2e, 0x0029}, {0x07, 0x0002},
1026};
1027
1028static u16 mt9m111_init[][2] = {
1029 {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009},
1030 {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300},
1031 {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200},
1032 {0x06, 0x308e}, {0xf0, 0x0000},
1033};
1034
1035static u8 hv7131r_init[][2] = {
1036 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1037 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1038 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1039 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1040 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1041 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1042 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1043 {0x23, 0x09}, {0x01, 0x08},
1044};
1045
1046int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1047{
1048 struct usb_device *dev = gspca_dev->dev;
1049 int result;
1050 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1051 0x00,
1052 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1053 reg,
1054 0x00,
1055 gspca_dev->usb_buf,
1056 length,
1057 500);
1058 if (unlikely(result < 0 || result != length)) {
1059 err("Read register failed 0x%02X", reg);
1060 return -EIO;
1061 }
1062 return 0;
1063}
1064
1065int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
1066{
1067 struct usb_device *dev = gspca_dev->dev;
1068 int result;
1069 memcpy(gspca_dev->usb_buf, buffer, length);
1070 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1071 0x08,
1072 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1073 reg,
1074 0x00,
1075 gspca_dev->usb_buf,
1076 length,
1077 500);
1078 if (unlikely(result < 0 || result != length)) {
1079 err("Write register failed index 0x%02X", reg);
1080 return -EIO;
1081 }
1082 return 0;
1083}
1084
1085int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1086{
1087 u8 data[1] = {value};
1088 return reg_w(gspca_dev, reg, data, 1);
1089}
1090
1091int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1092{
1093 int i;
1094 reg_w(gspca_dev, 0x10c0, buffer, 8);
1095 for (i = 0; i < 5; i++) {
1096 reg_r(gspca_dev, 0x10c0, 1);
1097 if (gspca_dev->usb_buf[0] & 0x04) {
1098 if (gspca_dev->usb_buf[0] & 0x08)
1099 return -1;
1100 return 0;
1101 }
1102 msleep(1);
1103 }
1104 return -1;
1105}
1106
1107int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1108{
1109 struct sd *sd = (struct sd *) gspca_dev;
1110
1111 u8 row[8];
1112
1113 /*
1114 * from the point of view of the bridge, the length
1115 * includes the address
1116 */
1117 row[0] = 0x81 | (2 << 4);
1118 row[1] = sd->i2c_addr;
1119 row[2] = reg;
1120 row[3] = val;
1121 row[4] = 0x00;
1122 row[5] = 0x00;
1123 row[6] = 0x00;
1124 row[7] = 0x10;
1125
1126 return i2c_w(gspca_dev, row);
1127}
1128
1129int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1130{
1131 struct sd *sd = (struct sd *) gspca_dev;
1132 u8 row[8];
1133
1134 /*
1135 * from the point of view of the bridge, the length
1136 * includes the address
1137 */
1138 row[0] = 0x81 | (3 << 4);
1139 row[1] = sd->i2c_addr;
1140 row[2] = reg;
1141 row[3] = (val >> 8) & 0xff;
1142 row[4] = val & 0xff;
1143 row[5] = 0x00;
1144 row[6] = 0x00;
1145 row[7] = 0x10;
1146
1147 return i2c_w(gspca_dev, row);
1148}
1149
1150int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1151{
1152 struct sd *sd = (struct sd *) gspca_dev;
1153 u8 row[8];
1154
1155 row[0] = 0x81 | 0x10;
1156 row[1] = sd->i2c_addr;
1157 row[2] = reg;
1158 row[3] = 0;
1159 row[4] = 0;
1160 row[5] = 0;
1161 row[6] = 0;
1162 row[7] = 0x10;
1163 reg_w(gspca_dev, 0x10c0, row, 8);
1164 msleep(1);
1165 row[0] = 0x81 | (2 << 4) | 0x02;
1166 row[2] = 0;
1167 reg_w(gspca_dev, 0x10c0, row, 8);
1168 msleep(1);
1169 reg_r(gspca_dev, 0x10c2, 5);
1170 *val = gspca_dev->usb_buf[3];
1171 return 0;
1172}
1173
1174int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1175{
1176 struct sd *sd = (struct sd *) gspca_dev;
1177 u8 row[8];
1178
1179 row[0] = 0x81 | 0x10;
1180 row[1] = sd->i2c_addr;
1181 row[2] = reg;
1182 row[3] = 0;
1183 row[4] = 0;
1184 row[5] = 0;
1185 row[6] = 0;
1186 row[7] = 0x10;
1187 reg_w(gspca_dev, 0x10c0, row, 8);
1188 msleep(1);
1189 row[0] = 0x81 | (3 << 4) | 0x02;
1190 row[2] = 0;
1191 reg_w(gspca_dev, 0x10c0, row, 8);
1192 msleep(1);
1193 reg_r(gspca_dev, 0x10c2, 5);
1194 *val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3];
1195 return 0;
1196}
1197
1198static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1199{
1200 int i;
1201 struct sd *sd = (struct sd *) gspca_dev;
1202
1203 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1204 if (i2c_w1(gspca_dev, ov9650_init[i][0],
1205 ov9650_init[i][1]) < 0) {
1206 err("OV9650 sensor initialization failed");
1207 return -ENODEV;
1208 }
1209 }
1210 sd->hstart = 1;
1211 sd->vstart = 7;
1212 return 0;
1213}
1214
1215static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1216{
1217 int i;
1218 struct sd *sd = (struct sd *) gspca_dev;
1219
1220 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1221 if (i2c_w1(gspca_dev, ov9655_init[i][0],
1222 ov9655_init[i][1]) < 0) {
1223 err("OV9655 sensor initialization failed");
1224 return -ENODEV;
1225 }
1226 }
1227 /* disable hflip and vflip */
1228 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1229 sd->hstart = 0;
1230 sd->vstart = 7;
1231 return 0;
1232}
1233
1234static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1235{
1236 int i;
1237 struct sd *sd = (struct sd *) gspca_dev;
1238
1239 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1240 if (i2c_w1(gspca_dev, soi968_init[i][0],
1241 soi968_init[i][1]) < 0) {
1242 err("SOI968 sensor initialization failed");
1243 return -ENODEV;
1244 }
1245 }
1246 /* disable hflip and vflip */
1247 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1248 sd->hstart = 60;
1249 sd->vstart = 11;
1250 return 0;
1251}
1252
1253static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1254{
1255 int i;
1256 struct sd *sd = (struct sd *) gspca_dev;
1257
1258 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1259 if (i2c_w1(gspca_dev, ov7660_init[i][0],
1260 ov7660_init[i][1]) < 0) {
1261 err("OV7660 sensor initialization failed");
1262 return -ENODEV;
1263 }
1264 }
1265 /* disable hflip and vflip */
1266 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1267 sd->hstart = 1;
1268 sd->vstart = 1;
1269 return 0;
1270}
1271
1272static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1273{
1274 int i;
1275 struct sd *sd = (struct sd *) gspca_dev;
1276
1277 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1278 if (i2c_w1(gspca_dev, ov7670_init[i][0],
1279 ov7670_init[i][1]) < 0) {
1280 err("OV7670 sensor initialization failed");
1281 return -ENODEV;
1282 }
1283 }
1284 /* disable hflip and vflip */
1285 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1286 sd->hstart = 0;
1287 sd->vstart = 1;
1288 return 0;
1289}
1290
1291static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1292{
1293 struct sd *sd = (struct sd *) gspca_dev;
1294 int i;
1295 u16 value;
1296 int ret;
1297
1298 sd->i2c_addr = 0x5d;
1299 ret = i2c_r2(gspca_dev, 0xff, &value);
1300 if ((ret == 0) && (value == 0x8243)) {
1301 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1302 if (i2c_w2(gspca_dev, mt9v011_init[i][0],
1303 mt9v011_init[i][1]) < 0) {
1304 err("MT9V011 sensor initialization failed");
1305 return -ENODEV;
1306 }
1307 }
1308 sd->hstart = 2;
1309 sd->vstart = 2;
1310 sd->sensor = SENSOR_MT9V011;
1311 info("MT9V011 sensor detected");
1312 return 0;
1313 }
1314
1315 sd->i2c_addr = 0x5c;
1316 i2c_w2(gspca_dev, 0x01, 0x0004);
1317 ret = i2c_r2(gspca_dev, 0xff, &value);
1318 if ((ret == 0) && (value == 0x823a)) {
1319 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1320 if (i2c_w2(gspca_dev, mt9v111_init[i][0],
1321 mt9v111_init[i][1]) < 0) {
1322 err("MT9V111 sensor initialization failed");
1323 return -ENODEV;
1324 }
1325 }
1326 sd->hstart = 2;
1327 sd->vstart = 2;
1328 sd->sensor = SENSOR_MT9V111;
1329 info("MT9V111 sensor detected");
1330 return 0;
1331 }
1332
1333 sd->i2c_addr = 0x5d;
1334 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1335 if (ret < 0) {
1336 sd->i2c_addr = 0x48;
1337 i2c_w2(gspca_dev, 0xf0, 0x0000);
1338 }
1339 ret = i2c_r2(gspca_dev, 0x00, &value);
1340 if ((ret == 0) && (value == 0x1229)) {
1341 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1342 if (i2c_w2(gspca_dev, mt9v112_init[i][0],
1343 mt9v112_init[i][1]) < 0) {
1344 err("MT9V112 sensor initialization failed");
1345 return -ENODEV;
1346 }
1347 }
1348 sd->hstart = 6;
1349 sd->vstart = 2;
1350 sd->sensor = SENSOR_MT9V112;
1351 info("MT9V112 sensor detected");
1352 return 0;
1353 }
1354
1355 return -ENODEV;
1356}
1357
1358static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1359{
1360 struct sd *sd = (struct sd *) gspca_dev;
1361 int i;
1362 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1363 if (i2c_w2(gspca_dev, mt9m111_init[i][0],
1364 mt9m111_init[i][1]) < 0) {
1365 err("MT9M111 sensor initialization failed");
1366 return -ENODEV;
1367 }
1368 }
1369 sd->hstart = 0;
1370 sd->vstart = 2;
1371 return 0;
1372}
1373
1374static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1375{
1376 struct sd *sd = (struct sd *) gspca_dev;
1377 int i;
1378 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1379 if (i2c_w2(gspca_dev, mt9m001_init[i][0],
1380 mt9m001_init[i][1]) < 0) {
1381 err("MT9M001 sensor initialization failed");
1382 return -ENODEV;
1383 }
1384 }
1385 /* disable hflip and vflip */
1386 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1387 sd->hstart = 2;
1388 sd->vstart = 2;
1389 return 0;
1390}
1391
1392static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1393{
1394 int i;
1395 struct sd *sd = (struct sd *) gspca_dev;
1396
1397 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1398 if (i2c_w1(gspca_dev, hv7131r_init[i][0],
1399 hv7131r_init[i][1]) < 0) {
1400 err("HV7131R Sensor initialization failed");
1401 return -ENODEV;
1402 }
1403 }
1404 sd->hstart = 0;
1405 sd->vstart = 1;
1406 return 0;
1407}
1408
1409#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1410static int input_kthread(void *data)
1411{
1412 struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
1413 struct sd *sd = (struct sd *) gspca_dev;
1414
1415 DECLARE_WAIT_QUEUE_HEAD(wait);
1416 set_freezable();
1417 for (;;) {
1418 if (kthread_should_stop())
1419 break;
1420
1421 if (reg_r(gspca_dev, 0x1005, 1) < 0)
1422 continue;
1423
1424 input_report_key(sd->input_dev,
1425 KEY_CAMERA,
1426 gspca_dev->usb_buf[0] & sd->input_gpio);
1427 input_sync(sd->input_dev);
1428
1429 wait_event_freezable_timeout(wait,
1430 kthread_should_stop(),
1431 msecs_to_jiffies(100));
1432 }
1433 return 0;
1434}
1435
1436
1437static int sn9c20x_input_init(struct gspca_dev *gspca_dev)
1438{
1439 struct sd *sd = (struct sd *) gspca_dev;
1440 if (sd->input_gpio == 0)
1441 return 0;
1442
1443 sd->input_dev = input_allocate_device();
1444 if (!sd->input_dev)
1445 return -ENOMEM;
1446
1447 sd->input_dev->name = "SN9C20X Webcam";
1448
1449 sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s",
1450 gspca_dev->dev->bus->bus_name,
1451 gspca_dev->dev->devpath);
1452
1453 if (!sd->input_dev->phys)
1454 return -ENOMEM;
1455
1456 usb_to_input_id(gspca_dev->dev, &sd->input_dev->id);
1457 sd->input_dev->dev.parent = &gspca_dev->dev->dev;
1458
1459 set_bit(EV_KEY, sd->input_dev->evbit);
1460 set_bit(KEY_CAMERA, sd->input_dev->keybit);
1461
1462 if (input_register_device(sd->input_dev))
1463 return -EINVAL;
1464
1465 sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d",
1466 gspca_dev->vdev.minor);
1467
1468 if (IS_ERR(sd->input_task))
1469 return -EINVAL;
1470
1471 return 0;
1472}
1473
1474static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev)
1475{
1476 struct sd *sd = (struct sd *) gspca_dev;
1477 if (sd->input_task != NULL && !IS_ERR(sd->input_task))
1478 kthread_stop(sd->input_task);
1479
1480 if (sd->input_dev != NULL) {
1481 input_unregister_device(sd->input_dev);
1482 kfree(sd->input_dev->phys);
1483 input_free_device(sd->input_dev);
1484 sd->input_dev = NULL;
1485 }
1486}
1487#endif
1488
1489static int set_cmatrix(struct gspca_dev *gspca_dev)
1490{
1491 struct sd *sd = (struct sd *) gspca_dev;
1492 s32 hue_coord, hue_index = 180 + sd->hue;
1493 u8 cmatrix[21];
1494 memset(cmatrix, 0, 21);
1495
1496 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1497 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1498 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1499 cmatrix[18] = sd->brightness - 0x80;
1500
1501 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1502 cmatrix[6] = (unsigned char)(hue_coord & 0xff);
1503 cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f);
1504
1505 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1506 cmatrix[8] = (unsigned char)(hue_coord & 0xff);
1507 cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f);
1508
1509 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1510 cmatrix[10] = (unsigned char)(hue_coord & 0xff);
1511 cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f);
1512
1513 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1514 cmatrix[12] = (unsigned char)(hue_coord & 0xff);
1515 cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f);
1516
1517 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1518 cmatrix[14] = (unsigned char)(hue_coord & 0xff);
1519 cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f);
1520
1521 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1522 cmatrix[16] = (unsigned char)(hue_coord & 0xff);
1523 cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f);
1524
1525 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1526}
1527
1528static int set_gamma(struct gspca_dev *gspca_dev)
1529{
1530 struct sd *sd = (struct sd *) gspca_dev;
1531 u8 gamma[17];
1532 u8 gval = sd->gamma * 0xb8 / 0x100;
1533
1534
1535 gamma[0] = 0x0a;
1536 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1537 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1538 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1539 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1540 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1541 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1542 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1543 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1544 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1545 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1546 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1547 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1548 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1549 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1550 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1551 gamma[16] = 0xf5;
1552
1553 return reg_w(gspca_dev, 0x1190, gamma, 17);
1554}
1555
1556static int set_redblue(struct gspca_dev *gspca_dev)
1557{
1558 struct sd *sd = (struct sd *) gspca_dev;
1559 reg_w1(gspca_dev, 0x118c, sd->red);
1560 reg_w1(gspca_dev, 0x118f, sd->blue);
1561 return 0;
1562}
1563
1564static int set_hvflip(struct gspca_dev *gspca_dev)
1565{
1566 u8 value, tslb;
1567 u16 value2;
1568 struct sd *sd = (struct sd *) gspca_dev;
1569 switch (sd->sensor) {
1570 case SENSOR_OV9650:
1571 i2c_r1(gspca_dev, 0x1e, &value);
1572 value &= ~0x30;
1573 tslb = 0x01;
1574 if (sd->hflip)
1575 value |= 0x20;
1576 if (sd->vflip) {
1577 value |= 0x10;
1578 tslb = 0x49;
1579 }
1580 i2c_w1(gspca_dev, 0x1e, value);
1581 i2c_w1(gspca_dev, 0x3a, tslb);
1582 break;
1583 case SENSOR_MT9V111:
1584 case SENSOR_MT9V011:
1585 i2c_r2(gspca_dev, 0x20, &value2);
1586 value2 &= ~0xc0a0;
1587 if (sd->hflip)
1588 value2 |= 0x8080;
1589 if (sd->vflip)
1590 value2 |= 0x4020;
1591 i2c_w2(gspca_dev, 0x20, value2);
1592 break;
1593 case SENSOR_MT9M111:
1594 case SENSOR_MT9V112:
1595 i2c_r2(gspca_dev, 0x20, &value2);
1596 value2 &= ~0x0003;
1597 if (sd->hflip)
1598 value2 |= 0x0002;
1599 if (sd->vflip)
1600 value2 |= 0x0001;
1601 i2c_w2(gspca_dev, 0x20, value2);
1602 break;
1603 case SENSOR_HV7131R:
1604 i2c_r1(gspca_dev, 0x01, &value);
1605 value &= ~0x03;
1606 if (sd->vflip)
1607 value |= 0x01;
1608 if (sd->hflip)
1609 value |= 0x02;
1610 i2c_w1(gspca_dev, 0x01, value);
1611 break;
1612 }
1613 return 0;
1614}
1615
1616static int set_exposure(struct gspca_dev *gspca_dev)
1617{
1618 struct sd *sd = (struct sd *) gspca_dev;
1619 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1620 switch (sd->sensor) {
1621 case SENSOR_OV7660:
1622 case SENSOR_OV7670:
1623 case SENSOR_SOI968:
1624 case SENSOR_OV9655:
1625 case SENSOR_OV9650:
1626 exp[0] |= (3 << 4);
1627 exp[2] = 0x2d;
1628 exp[3] = sd->exposure & 0xff;
1629 exp[4] = sd->exposure >> 8;
1630 break;
1631 case SENSOR_MT9M001:
1632 case SENSOR_MT9M111:
1633 case SENSOR_MT9V112:
1634 case SENSOR_MT9V111:
1635 case SENSOR_MT9V011:
1636 exp[0] |= (3 << 4);
1637 exp[2] = 0x09;
1638 exp[3] = sd->exposure >> 8;
1639 exp[4] = sd->exposure & 0xff;
1640 break;
1641 case SENSOR_HV7131R:
1642 exp[0] |= (4 << 4);
1643 exp[2] = 0x25;
1644 exp[3] = ((sd->exposure * 0xffffff) / 0xffff) >> 16;
1645 exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8;
1646 exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff;
1647 break;
1648 }
1649 i2c_w(gspca_dev, exp);
1650 return 0;
1651}
1652
1653static int set_gain(struct gspca_dev *gspca_dev)
1654{
1655 struct sd *sd = (struct sd *) gspca_dev;
1656 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1657 switch (sd->sensor) {
1658 case SENSOR_OV7660:
1659 case SENSOR_OV7670:
1660 case SENSOR_SOI968:
1661 case SENSOR_OV9655:
1662 case SENSOR_OV9650:
1663 gain[0] |= (2 << 4);
1664 gain[3] = ov_gain[sd->gain];
1665 break;
1666 case SENSOR_MT9V011:
1667 case SENSOR_MT9V111:
1668 gain[0] |= (3 << 4);
1669 gain[2] = 0x35;
1670 gain[3] = micron1_gain[sd->gain] >> 8;
1671 gain[4] = micron1_gain[sd->gain] & 0xff;
1672 break;
1673 case SENSOR_MT9V112:
1674 case SENSOR_MT9M111:
1675 gain[0] |= (3 << 4);
1676 gain[2] = 0x2f;
1677 gain[3] = micron1_gain[sd->gain] >> 8;
1678 gain[4] = micron1_gain[sd->gain] & 0xff;
1679 break;
1680 case SENSOR_MT9M001:
1681 gain[0] |= (3 << 4);
1682 gain[2] = 0x2f;
1683 gain[3] = micron2_gain[sd->gain] >> 8;
1684 gain[4] = micron2_gain[sd->gain] & 0xff;
1685 break;
1686 case SENSOR_HV7131R:
1687 gain[0] |= (2 << 4);
1688 gain[2] = 0x30;
1689 gain[3] = hv7131r_gain[sd->gain];
1690 break;
1691 }
1692 i2c_w(gspca_dev, gain);
1693 return 0;
1694}
1695
1696static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1697{
1698 struct sd *sd = (struct sd *) gspca_dev;
1699
1700 sd->brightness = val;
1701 if (gspca_dev->streaming)
1702 return set_cmatrix(gspca_dev);
1703 return 0;
1704}
1705
1706static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1707{
1708 struct sd *sd = (struct sd *) gspca_dev;
1709 *val = sd->brightness;
1710 return 0;
1711}
1712
1713
1714static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1715{
1716 struct sd *sd = (struct sd *) gspca_dev;
1717
1718 sd->contrast = val;
1719 if (gspca_dev->streaming)
1720 return set_cmatrix(gspca_dev);
1721 return 0;
1722}
1723
1724static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1725{
1726 struct sd *sd = (struct sd *) gspca_dev;
1727 *val = sd->contrast;
1728 return 0;
1729}
1730
1731static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1732{
1733 struct sd *sd = (struct sd *) gspca_dev;
1734
1735 sd->saturation = val;
1736 if (gspca_dev->streaming)
1737 return set_cmatrix(gspca_dev);
1738 return 0;
1739}
1740
1741static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1742{
1743 struct sd *sd = (struct sd *) gspca_dev;
1744 *val = sd->saturation;
1745 return 0;
1746}
1747
1748static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1749{
1750 struct sd *sd = (struct sd *) gspca_dev;
1751
1752 sd->hue = val;
1753 if (gspca_dev->streaming)
1754 return set_cmatrix(gspca_dev);
1755 return 0;
1756}
1757
1758static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1759{
1760 struct sd *sd = (struct sd *) gspca_dev;
1761 *val = sd->hue;
1762 return 0;
1763}
1764
1765static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1766{
1767 struct sd *sd = (struct sd *) gspca_dev;
1768
1769 sd->gamma = val;
1770 if (gspca_dev->streaming)
1771 return set_gamma(gspca_dev);
1772 return 0;
1773}
1774
1775static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1776{
1777 struct sd *sd = (struct sd *) gspca_dev;
1778 *val = sd->gamma;
1779 return 0;
1780}
1781
1782static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1783{
1784 struct sd *sd = (struct sd *) gspca_dev;
1785
1786 sd->red = val;
1787 if (gspca_dev->streaming)
1788 return set_redblue(gspca_dev);
1789 return 0;
1790}
1791
1792static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1793{
1794 struct sd *sd = (struct sd *) gspca_dev;
1795 *val = sd->red;
1796 return 0;
1797}
1798
1799static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1800{
1801 struct sd *sd = (struct sd *) gspca_dev;
1802
1803 sd->blue = val;
1804 if (gspca_dev->streaming)
1805 return set_redblue(gspca_dev);
1806 return 0;
1807}
1808
1809static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1810{
1811 struct sd *sd = (struct sd *) gspca_dev;
1812 *val = sd->blue;
1813 return 0;
1814}
1815
1816static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1817{
1818 struct sd *sd = (struct sd *) gspca_dev;
1819
1820 sd->hflip = val;
1821 if (gspca_dev->streaming)
1822 return set_hvflip(gspca_dev);
1823 return 0;
1824}
1825
1826static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1827{
1828 struct sd *sd = (struct sd *) gspca_dev;
1829 *val = sd->hflip;
1830 return 0;
1831}
1832
1833static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1834{
1835 struct sd *sd = (struct sd *) gspca_dev;
1836
1837 sd->vflip = val;
1838 if (gspca_dev->streaming)
1839 return set_hvflip(gspca_dev);
1840 return 0;
1841}
1842
1843static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1844{
1845 struct sd *sd = (struct sd *) gspca_dev;
1846 *val = sd->vflip;
1847 return 0;
1848}
1849
1850static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1851{
1852 struct sd *sd = (struct sd *) gspca_dev;
1853
1854 sd->exposure = val;
1855 if (gspca_dev->streaming)
1856 return set_exposure(gspca_dev);
1857 return 0;
1858}
1859
1860static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1861{
1862 struct sd *sd = (struct sd *) gspca_dev;
1863 *val = sd->exposure;
1864 return 0;
1865}
1866
1867static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1868{
1869 struct sd *sd = (struct sd *) gspca_dev;
1870
1871 sd->gain = val;
1872 if (gspca_dev->streaming)
1873 return set_gain(gspca_dev);
1874 return 0;
1875}
1876
1877static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1878{
1879 struct sd *sd = (struct sd *) gspca_dev;
1880 *val = sd->gain;
1881 return 0;
1882}
1883
1884static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1885{
1886 struct sd *sd = (struct sd *) gspca_dev;
1887 sd->auto_exposure = val;
1888 return 0;
1889}
1890
1891static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1892{
1893 struct sd *sd = (struct sd *) gspca_dev;
1894 *val = sd->auto_exposure;
1895 return 0;
1896}
1897
1898#ifdef CONFIG_VIDEO_ADV_DEBUG
1899static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1900 struct v4l2_dbg_register *reg)
1901{
1902 struct sd *sd = (struct sd *) gspca_dev;
1903 switch (reg->match.type) {
1904 case V4L2_CHIP_MATCH_HOST:
1905 if (reg->match.addr != 0)
1906 return -EINVAL;
1907 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1908 return -EINVAL;
1909 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1910 return -EINVAL;
1911 reg->val = gspca_dev->usb_buf[0];
1912 return 0;
1913 case V4L2_CHIP_MATCH_I2C_ADDR:
1914 if (reg->match.addr != sd->i2c_addr)
1915 return -EINVAL;
1916 if (sd->sensor >= SENSOR_MT9V011 &&
1917 sd->sensor <= SENSOR_MT9M111) {
1918 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0)
1919 return -EINVAL;
1920 } else {
1921 if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0)
1922 return -EINVAL;
1923 }
1924 return 0;
1925 }
1926 return -EINVAL;
1927}
1928
1929static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1930 struct v4l2_dbg_register *reg)
1931{
1932 struct sd *sd = (struct sd *) gspca_dev;
1933 switch (reg->match.type) {
1934 case V4L2_CHIP_MATCH_HOST:
1935 if (reg->match.addr != 0)
1936 return -EINVAL;
1937 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1938 return -EINVAL;
1939 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1940 return -EINVAL;
1941 return 0;
1942 case V4L2_CHIP_MATCH_I2C_ADDR:
1943 if (reg->match.addr != sd->i2c_addr)
1944 return -EINVAL;
1945 if (sd->sensor >= SENSOR_MT9V011 &&
1946 sd->sensor <= SENSOR_MT9M111) {
1947 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1948 return -EINVAL;
1949 } else {
1950 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1951 return -EINVAL;
1952 }
1953 return 0;
1954 }
1955 return -EINVAL;
1956}
1957#endif
1958
1959static int sd_chip_ident(struct gspca_dev *gspca_dev,
1960 struct v4l2_dbg_chip_ident *chip)
1961{
1962 struct sd *sd = (struct sd *) gspca_dev;
1963
1964 switch (chip->match.type) {
1965 case V4L2_CHIP_MATCH_HOST:
1966 if (chip->match.addr != 0)
1967 return -EINVAL;
1968 chip->revision = 0;
1969 chip->ident = V4L2_IDENT_SN9C20X;
1970 return 0;
1971 case V4L2_CHIP_MATCH_I2C_ADDR:
1972 if (chip->match.addr != sd->i2c_addr)
1973 return -EINVAL;
1974 chip->revision = 0;
1975 chip->ident = i2c_ident[sd->sensor];
1976 return 0;
1977 }
1978 return -EINVAL;
1979}
1980
1981static int sd_config(struct gspca_dev *gspca_dev,
1982 const struct usb_device_id *id)
1983{
1984 struct sd *sd = (struct sd *) gspca_dev;
1985 struct cam *cam;
1986
1987 cam = &gspca_dev->cam;
1988
1989 sd->sensor = (id->driver_info >> 8) & 0xff;
1990 sd->i2c_addr = id->driver_info & 0xff;
1991
1992 switch (sd->sensor) {
1993 case SENSOR_OV9650:
1994 cam->cam_mode = sxga_mode;
1995 cam->nmodes = ARRAY_SIZE(sxga_mode);
1996 break;
1997 default:
1998 cam->cam_mode = vga_mode;
1999 cam->nmodes = ARRAY_SIZE(vga_mode);
2000 }
2001
2002 sd->old_step = 0;
2003 sd->older_step = 0;
2004 sd->exposure_step = 16;
2005
2006 sd->brightness = BRIGHTNESS_DEFAULT;
2007 sd->contrast = CONTRAST_DEFAULT;
2008 sd->saturation = SATURATION_DEFAULT;
2009 sd->hue = HUE_DEFAULT;
2010 sd->gamma = GAMMA_DEFAULT;
2011 sd->red = RED_DEFAULT;
2012 sd->blue = BLUE_DEFAULT;
2013
2014 sd->hflip = HFLIP_DEFAULT;
2015 sd->vflip = VFLIP_DEFAULT;
2016 sd->exposure = EXPOSURE_DEFAULT;
2017 sd->gain = GAIN_DEFAULT;
2018 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2019
2020 sd->quality = 95;
2021
2022#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2023 sd->input_gpio = (id->driver_info >> 16) & 0xff;
2024 if (sn9c20x_input_init(gspca_dev) < 0)
2025 return -ENODEV;
2026#endif
2027 return 0;
2028}
2029
2030static int sd_init(struct gspca_dev *gspca_dev)
2031{
2032 struct sd *sd = (struct sd *) gspca_dev;
2033 int i;
2034 u8 value;
2035 u8 i2c_init[9] =
2036 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2037
2038 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2039 value = bridge_init[i][1];
2040 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2041 err("Device initialization failed");
2042 return -ENODEV;
2043 }
2044 }
2045
2046 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2047 err("Device initialization failed");
2048 return -ENODEV;
2049 }
2050
2051 switch (sd->sensor) {
2052 case SENSOR_OV9650:
2053 if (ov9650_init_sensor(gspca_dev) < 0)
2054 return -ENODEV;
2055 info("OV9650 sensor detected");
2056 break;
2057 case SENSOR_OV9655:
2058 if (ov9655_init_sensor(gspca_dev) < 0)
2059 return -ENODEV;
2060 info("OV9655 sensor detected");
2061 break;
2062 case SENSOR_SOI968:
2063 if (soi968_init_sensor(gspca_dev) < 0)
2064 return -ENODEV;
2065 info("SOI968 sensor detected");
2066 break;
2067 case SENSOR_OV7660:
2068 if (ov7660_init_sensor(gspca_dev) < 0)
2069 return -ENODEV;
2070 info("OV7660 sensor detected");
2071 break;
2072 case SENSOR_OV7670:
2073 if (ov7670_init_sensor(gspca_dev) < 0)
2074 return -ENODEV;
2075 info("OV7670 sensor detected");
2076 break;
2077 case SENSOR_MT9VPRB:
2078 if (mt9v_init_sensor(gspca_dev) < 0)
2079 return -ENODEV;
2080 break;
2081 case SENSOR_MT9M111:
2082 if (mt9m111_init_sensor(gspca_dev) < 0)
2083 return -ENODEV;
2084 info("MT9M111 sensor detected");
2085 break;
2086 case SENSOR_MT9M001:
2087 if (mt9m001_init_sensor(gspca_dev) < 0)
2088 return -ENODEV;
2089 info("MT9M001 sensor detected");
2090 break;
2091 case SENSOR_HV7131R:
2092 if (hv7131r_init_sensor(gspca_dev) < 0)
2093 return -ENODEV;
2094 info("HV7131R sensor detected");
2095 break;
2096 default:
2097 info("Unsupported Sensor");
2098 return -ENODEV;
2099 }
2100
2101 return 0;
2102}
2103
2104static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2105{
2106 struct sd *sd = (struct sd *) gspca_dev;
2107 u8 value;
2108 switch (sd->sensor) {
2109 case SENSOR_OV9650:
2110 if (mode & MODE_SXGA) {
2111 i2c_w1(gspca_dev, 0x17, 0x1b);
2112 i2c_w1(gspca_dev, 0x18, 0xbc);
2113 i2c_w1(gspca_dev, 0x19, 0x01);
2114 i2c_w1(gspca_dev, 0x1a, 0x82);
2115 i2c_r1(gspca_dev, 0x12, &value);
2116 i2c_w1(gspca_dev, 0x12, value & 0x07);
2117 } else {
2118 i2c_w1(gspca_dev, 0x17, 0x24);
2119 i2c_w1(gspca_dev, 0x18, 0xc5);
2120 i2c_w1(gspca_dev, 0x19, 0x00);
2121 i2c_w1(gspca_dev, 0x1a, 0x3c);
2122 i2c_r1(gspca_dev, 0x12, &value);
2123 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2124 }
2125 break;
2126 }
2127}
2128
2129#define HW_WIN(mode, hstart, vstart) \
2130((const u8 []){hstart & 0xff, hstart >> 8, \
2131vstart & 0xff, vstart >> 8, \
2132(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2133(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2134
2135#define CLR_WIN(width, height) \
2136((const u8 [])\
2137{0, width >> 2, 0, height >> 1,\
2138((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2139
2140static int sd_start(struct gspca_dev *gspca_dev)
2141{
2142 struct sd *sd = (struct sd *) gspca_dev;
2143 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2144 int width = gspca_dev->width;
2145 int height = gspca_dev->height;
2146 u8 fmt, scale = 0;
2147
2148 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
2149 if (sd->jpeg_hdr == NULL)
2150 return -ENOMEM;
2151
2152 jpeg_define(sd->jpeg_hdr, height, width,
2153 0x21);
2154 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2155
2156 if (mode & MODE_RAW)
2157 fmt = 0x2d;
2158 else if (mode & MODE_JPEG)
2159 fmt = 0x2c;
2160 else
2161 fmt = 0x2f;
2162
2163 switch (mode & 0x0f) {
2164 case 3:
2165 scale = 0xc0;
2166 info("Set 1280x1024");
2167 break;
2168 case 2:
2169 scale = 0x80;
2170 info("Set 640x480");
2171 break;
2172 case 1:
2173 scale = 0x90;
2174 info("Set 320x240");
2175 break;
2176 case 0:
2177 scale = 0xa0;
2178 info("Set 160x120");
2179 break;
2180 }
2181
2182 configure_sensor_output(gspca_dev, mode);
2183 reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
2184 reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
2185 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2186 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2187 reg_w1(gspca_dev, 0x1189, scale);
2188 reg_w1(gspca_dev, 0x10e0, fmt);
2189
2190 set_cmatrix(gspca_dev);
2191 set_gamma(gspca_dev);
2192 set_redblue(gspca_dev);
2193 set_gain(gspca_dev);
2194 set_exposure(gspca_dev);
2195 set_hvflip(gspca_dev);
2196
2197 reg_r(gspca_dev, 0x1061, 1);
2198 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2199 return 0;
2200}
2201
2202static void sd_stopN(struct gspca_dev *gspca_dev)
2203{
2204 reg_r(gspca_dev, 0x1061, 1);
2205 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2206}
2207
2208static void sd_stop0(struct gspca_dev *gspca_dev)
2209{
2210 struct sd *sd = (struct sd *) gspca_dev;
2211 kfree(sd->jpeg_hdr);
2212}
2213
2214static void do_autoexposure(struct gspca_dev *gspca_dev)
2215{
2216 struct sd *sd = (struct sd *) gspca_dev;
2217 int avg_lum, new_exp;
2218
2219 if (!sd->auto_exposure)
2220 return;
2221
2222 avg_lum = atomic_read(&sd->avg_lum);
2223
2224 /*
2225 * some hardcoded values are present
2226 * like those for maximal/minimal exposure
2227 * and exposure steps
2228 */
2229 if (avg_lum < MIN_AVG_LUM) {
2230 if (sd->exposure > 0x1770)
2231 return;
2232
2233 new_exp = sd->exposure + sd->exposure_step;
2234 if (new_exp > 0x1770)
2235 new_exp = 0x1770;
2236 if (new_exp < 0x10)
2237 new_exp = 0x10;
2238 sd->exposure = new_exp;
2239 set_exposure(gspca_dev);
2240
2241 sd->older_step = sd->old_step;
2242 sd->old_step = 1;
2243
2244 if (sd->old_step ^ sd->older_step)
2245 sd->exposure_step /= 2;
2246 else
2247 sd->exposure_step += 2;
2248 }
2249 if (avg_lum > MAX_AVG_LUM) {
2250 if (sd->exposure < 0x10)
2251 return;
2252 new_exp = sd->exposure - sd->exposure_step;
2253 if (new_exp > 0x1700)
2254 new_exp = 0x1770;
2255 if (new_exp < 0x10)
2256 new_exp = 0x10;
2257 sd->exposure = new_exp;
2258 set_exposure(gspca_dev);
2259 sd->older_step = sd->old_step;
2260 sd->old_step = 0;
2261
2262 if (sd->old_step ^ sd->older_step)
2263 sd->exposure_step /= 2;
2264 else
2265 sd->exposure_step += 2;
2266 }
2267}
2268
2269static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2270 struct gspca_frame *frame, /* target */
2271 u8 *data, /* isoc packet */
2272 int len) /* iso packet length */
2273{
2274 struct sd *sd = (struct sd *) gspca_dev;
2275 int avg_lum;
2276 static unsigned char frame_header[] =
2277 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2278 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2279 avg_lum = ((data[35] >> 2) & 3) |
2280 (data[20] << 2) |
2281 (data[19] << 10);
2282 avg_lum += ((data[35] >> 4) & 3) |
2283 (data[22] << 2) |
2284 (data[21] << 10);
2285 avg_lum += ((data[35] >> 6) & 3) |
2286 (data[24] << 2) |
2287 (data[23] << 10);
2288 avg_lum += (data[36] & 3) |
2289 (data[26] << 2) |
2290 (data[25] << 10);
2291 avg_lum += ((data[36] >> 2) & 3) |
2292 (data[28] << 2) |
2293 (data[27] << 10);
2294 avg_lum += ((data[36] >> 4) & 3) |
2295 (data[30] << 2) |
2296 (data[29] << 10);
2297 avg_lum += ((data[36] >> 6) & 3) |
2298 (data[32] << 2) |
2299 (data[31] << 10);
2300 avg_lum += ((data[44] >> 4) & 3) |
2301 (data[34] << 2) |
2302 (data[33] << 10);
2303 avg_lum >>= 9;
2304 atomic_set(&sd->avg_lum, avg_lum);
2305 gspca_frame_add(gspca_dev, LAST_PACKET,
2306 frame, data, len);
2307 return;
2308 }
2309 if (gspca_dev->last_packet_type == LAST_PACKET) {
2310 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2311 & MODE_JPEG) {
2312 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
2313 sd->jpeg_hdr, JPEG_HDR_SZ);
2314 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
2315 data, len);
2316 } else {
2317 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
2318 data, len);
2319 }
2320 } else {
2321 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
2322 }
2323}
2324
2325/* sub-driver description */
2326static const struct sd_desc sd_desc = {
2327 .name = MODULE_NAME,
2328 .ctrls = sd_ctrls,
2329 .nctrls = ARRAY_SIZE(sd_ctrls),
2330 .config = sd_config,
2331 .init = sd_init,
2332 .start = sd_start,
2333 .stopN = sd_stopN,
2334 .stop0 = sd_stop0,
2335 .pkt_scan = sd_pkt_scan,
2336 .dq_callback = do_autoexposure,
2337#ifdef CONFIG_VIDEO_ADV_DEBUG
2338 .set_register = sd_dbg_s_register,
2339 .get_register = sd_dbg_g_register,
2340#endif
2341 .get_chip_ident = sd_chip_ident,
2342};
2343
2344#define SN9C20X(sensor, i2c_addr, button_mask) \
2345 .driver_info = (button_mask << 16) \
2346 | (SENSOR_ ## sensor << 8) \
2347 | (i2c_addr)
2348
2349static const __devinitdata struct usb_device_id device_table[] = {
2350 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2351 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2352 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2353 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)},
2354 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2357 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2358 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2359 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2360 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2361 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2362 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2363 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2364 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2365 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2366 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2367 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2368 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2369 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2370 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2371 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2372 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2373 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2374 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2375 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2376 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2377 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2378 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2379 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2380 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2381 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2382 {}
2383};
2384MODULE_DEVICE_TABLE(usb, device_table);
2385
2386/* -- device connect -- */
2387static int sd_probe(struct usb_interface *intf,
2388 const struct usb_device_id *id)
2389{
2390 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2391 THIS_MODULE);
2392}
2393
2394static void sd_disconnect(struct usb_interface *intf)
2395{
2396#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2397 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2398
2399 sn9c20x_input_cleanup(gspca_dev);
2400#endif
2401
2402 gspca_disconnect(intf);
2403}
2404
2405static struct usb_driver sd_driver = {
2406 .name = MODULE_NAME,
2407 .id_table = device_table,
2408 .probe = sd_probe,
2409 .disconnect = sd_disconnect,
2410#ifdef CONFIG_PM
2411 .suspend = gspca_suspend,
2412 .resume = gspca_resume,
2413 .reset_resume = gspca_resume,
2414#endif
2415};
2416
2417/* -- module insert / remove -- */
2418static int __init sd_mod_init(void)
2419{
2420 int ret;
2421 ret = usb_register(&sd_driver);
2422 if (ret < 0)
2423 return ret;
2424 info("registered");
2425 return 0;
2426}
2427static void __exit sd_mod_exit(void)
2428{
2429 usb_deregister(&sd_driver);
2430 info("deregistered");
2431}
2432
2433module_init(sd_mod_init);
2434module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 0d02f41fa7d0..d6332ab80669 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1634,6 +1634,8 @@ static void setfreq(struct gspca_dev *gspca_dev)
1634{ 1634{
1635 struct sd *sd = (struct sd *) gspca_dev; 1635 struct sd *sd = (struct sd *) gspca_dev;
1636 1636
1637 if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
1638 return;
1637 if (sd->sensor == SENSOR_OV7660) { 1639 if (sd->sensor == SENSOR_OV7660) {
1638 switch (sd->freq) { 1640 switch (sd->freq) {
1639 case 0: /* Banding filter disabled */ 1641 case 0: /* Banding filter disabled */
@@ -1735,6 +1737,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1735 1737
1736 /* create the JPEG header */ 1738 /* create the JPEG header */
1737 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 1739 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
1740 if (!sd->jpeg_hdr)
1741 return -ENOMEM;
1738 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 1742 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1739 0x21); /* JPEG 422 */ 1743 0x21); /* JPEG 422 */
1740 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 1744 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 8806b2ff82be..fab7ef85a6c1 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -670,6 +670,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
670 670
671 /* create the JPEG header */ 671 /* create the JPEG header */
672 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 672 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
673 if (!sd->jpeg_hdr)
674 return -ENOMEM;
673 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 675 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
674 0x22); /* JPEG 411 */ 676 0x22); /* JPEG 411 */
675 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 677 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index f25be20cf1a6..47628964801e 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -333,6 +333,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
333 333
334 /* create the JPEG header */ 334 /* create the JPEG header */
335 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 335 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
336 if (!sd->jpeg_hdr)
337 return -ENOMEM;
336 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 338 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
337 0x22); /* JPEG 411 */ 339 0x22); /* JPEG 411 */
338 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 340 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
index 9df7137fe67e..992ce530f138 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -36,10 +36,6 @@
36 36
37#define STV_ISOC_ENDPOINT_ADDR 0x81 37#define STV_ISOC_ENDPOINT_ADDR 0x81
38 38
39#ifndef V4L2_PIX_FMT_SGRBG8
40#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
41#endif
42
43#define STV_REG23 0x0423 39#define STV_REG23 0x0423
44 40
45/* Control registers of the STV0600 ASIC */ 41/* Control registers of the STV0600 ASIC */
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index 3039ec208f3a..e5024c8496ef 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -64,7 +64,7 @@ static struct v4l2_pix_format hdcs1x00_mode[] = {
64 { 64 {
65 HDCS_1X00_DEF_WIDTH, 65 HDCS_1X00_DEF_WIDTH,
66 HDCS_1X00_DEF_HEIGHT, 66 HDCS_1X00_DEF_HEIGHT,
67 V4L2_PIX_FMT_SBGGR8, 67 V4L2_PIX_FMT_SGRBG8,
68 V4L2_FIELD_NONE, 68 V4L2_FIELD_NONE,
69 .sizeimage = 69 .sizeimage =
70 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, 70 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
@@ -80,7 +80,7 @@ static struct v4l2_pix_format hdcs1020_mode[] = {
80 { 80 {
81 HDCS_1020_DEF_WIDTH, 81 HDCS_1020_DEF_WIDTH,
82 HDCS_1020_DEF_HEIGHT, 82 HDCS_1020_DEF_HEIGHT,
83 V4L2_PIX_FMT_SBGGR8, 83 V4L2_PIX_FMT_SGRBG8,
84 V4L2_FIELD_NONE, 84 V4L2_FIELD_NONE,
85 .sizeimage = 85 .sizeimage =
86 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, 86 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
@@ -131,9 +131,11 @@ static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
131 (reg + len > 0xff))) 131 (reg + len > 0xff)))
132 return -EINVAL; 132 return -EINVAL;
133 133
134 for (i = 0; i < len; i++, reg++) { 134 for (i = 0; i < len; i++) {
135 regs[2*i] = reg; 135 regs[2 * i] = reg;
136 regs[2*i+1] = vals[i]; 136 regs[2 * i + 1] = vals[i];
137 /* All addresses are shifted left one bit as bit 0 toggles r/w */
138 reg += 2;
137 } 139 }
138 140
139 return stv06xx_write_sensor_bytes(sd, regs, len); 141 return stv06xx_write_sensor_bytes(sd, regs, len);
@@ -174,7 +176,9 @@ static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
174 } 176 }
175 177
176 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); 178 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
177 if (ret < 0) 179
180 /* Update the state if the write succeeded */
181 if (!ret)
178 hdcs->state = state; 182 hdcs->state = state;
179 183
180 return ret; 184 return ret;
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 9623f294bdac..5127bbf9dd26 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -973,6 +973,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
973 973
974 /* create the JPEG header */ 974 /* create the JPEG header */
975 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 975 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
976 if (!sd->jpeg_hdr)
977 return -ENOMEM;
976 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 978 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
977 0x22); /* JPEG 411 */ 979 0x22); /* JPEG 411 */
978 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 980 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 08422d315e68..3d2756f7874a 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -7243,6 +7243,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
7243 7243
7244 /* create the JPEG header */ 7244 /* create the JPEG header */
7245 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 7245 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
7246 if (!sd->jpeg_hdr)
7247 return -ENOMEM;
7246 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 7248 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
7247 0x21); /* JPEG 422 */ 7249 0x21); /* JPEG 422 */
7248 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 7250 jpeg_set_qual(sd->jpeg_hdr, sd->quality);