blob: 1220340e76028654385ec448c7a98a310d3d89f6 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/*
2 * sonix sn9c102 (bayer) library
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003 *
Jean-François Moine75b79ff2011-03-13 16:07:25 -03004 * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
5 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
6 * Add Pas106 Stefano Mozzi (C) 2004
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
Hans de Goede93627732008-09-04 16:20:12 -030023/* Some documentation on known sonixb registers:
24
25Reg Use
Hans de Goede0a76cb82011-01-05 13:55:43 -030026sn9c101 / sn9c102:
Hans de Goede93627732008-09-04 16:20:12 -0300270x10 high nibble red gain low nibble blue gain
280x11 low nibble green gain
Hans de Goede0a76cb82011-01-05 13:55:43 -030029sn9c103:
300x05 red gain 0-127
310x06 blue gain 0-127
320x07 green gain 0-127
33all:
340x08-0x0f i2c / 3wire registers
Hans de Goede93627732008-09-04 16:20:12 -0300350x12 hstart
360x13 vstart
370x15 hsize (hsize = register-value * 16)
380x16 vsize (vsize = register-value * 16)
390x17 bit 0 toggle compression quality (according to sn9c102 driver)
400x18 bit 7 enables compression, bit 4-5 set image down scaling:
41 00 scale 1, 01 scale 1/2, 10, scale 1/4
420x19 high-nibble is sensor clock divider, changes exposure on sensors which
43 use a clock generated by the bridge. Some sensors have their own clock.
440x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
450x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
460x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
470x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
48*/
49
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030050#define MODULE_NAME "sonixb"
51
Hans de Goedef65e93d2010-01-31 10:35:15 -030052#include <linux/input.h>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030053#include "gspca.h"
54
Jean-François Moine75b79ff2011-03-13 16:07:25 -030055MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030056MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
57MODULE_LICENSE("GPL");
58
59/* specific webcam descriptor */
60struct sd {
61 struct gspca_dev gspca_dev; /* !! must be the first item */
Jean-François Moinef51a8ca2011-03-13 15:04:11 -030062
Hans de Goede9153ac32012-05-15 04:23:55 -030063 struct v4l2_ctrl *brightness;
64 struct v4l2_ctrl *plfreq;
Jean-François Moinef51a8ca2011-03-13 15:04:11 -030065
Hans de Goededcef3232008-07-10 10:40:53 -030066 atomic_t avg_lum;
Hans de Goedebf2a2202008-09-04 16:22:56 -030067 int prev_avg_lum;
Hans de Goede9153ac32012-05-15 04:23:55 -030068 int exposure_knee;
Hans de Goede2b3e2842010-12-12 08:55:04 -030069 int header_read;
70 u8 header[12]; /* Header without sof marker */
Hans de Goededcef3232008-07-10 10:40:53 -030071
Hans de Goededcef3232008-07-10 10:40:53 -030072 unsigned char autogain_ignore_frames;
Hans de Goede6af492e2008-07-22 07:09:33 -030073 unsigned char frames_to_drop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030074
Hans de Goedef45f06b2008-09-03 17:12:21 -030075 __u8 bridge; /* Type of bridge */
76#define BRIDGE_101 0
77#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
78#define BRIDGE_103 1
79
80 __u8 sensor; /* Type of image sensor chip */
Hans de Goede00765f12010-12-12 15:55:03 -030081#define SENSOR_HV7131D 0
82#define SENSOR_HV7131R 1
83#define SENSOR_OV6650 2
84#define SENSOR_OV7630 3
85#define SENSOR_PAS106 4
86#define SENSOR_PAS202 5
87#define SENSOR_TAS5110C 6
88#define SENSOR_TAS5110D 7
89#define SENSOR_TAS5130CXX 8
Hans de Goede6af492e2008-07-22 07:09:33 -030090 __u8 reg11;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030091};
92
Hans de Goedef45f06b2008-09-03 17:12:21 -030093typedef const __u8 sensor_init_t[8];
94
95struct sensor_data {
Hans de Goede0a76cb82011-01-05 13:55:43 -030096 const __u8 *bridge_init;
Hans de Goedef45f06b2008-09-03 17:12:21 -030097 sensor_init_t *sensor_init;
98 int sensor_init_size;
Hans de Goedef45f06b2008-09-03 17:12:21 -030099 int flags;
Hans de Goedef45f06b2008-09-03 17:12:21 -0300100 __u8 sensor_addr;
101};
102
103/* sensor_data flags */
Hans de Goede9153ac32012-05-15 04:23:55 -0300104#define F_SIF 0x01 /* sif or vga */
Hans de Goedec437d652008-09-03 17:12:22 -0300105
106/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
107#define MODE_RAW 0x10 /* raw bayer mode */
Hans de Goede93627732008-09-04 16:20:12 -0300108#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
Hans de Goedef45f06b2008-09-03 17:12:21 -0300109
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300110#define COMP 0xc7 /* 0x87 //0x07 */
111#define COMP1 0xc9 /* 0x89 //0x09 */
112
113#define MCK_INIT 0x63
114#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
115
116#define SYS_CLK 0x04
117
Hans de Goede9153ac32012-05-15 04:23:55 -0300118#define SENS(bridge, sensor, _flags, _sensor_addr) \
Hans de Goedef45f06b2008-09-03 17:12:21 -0300119{ \
Hans de Goede0a76cb82011-01-05 13:55:43 -0300120 .bridge_init = bridge, \
Hans de Goedef45f06b2008-09-03 17:12:21 -0300121 .sensor_init = sensor, \
122 .sensor_init_size = sizeof(sensor), \
Hans de Goede9153ac32012-05-15 04:23:55 -0300123 .flags = _flags, .sensor_addr = _sensor_addr \
Hans de Goedef45f06b2008-09-03 17:12:21 -0300124}
125
Hans de Goededcef3232008-07-10 10:40:53 -0300126/* We calculate the autogain at the end of the transfer of a frame, at this
Hans de Goede26984b02010-02-01 13:18:37 -0300127 moment a frame with the old settings is being captured and transmitted. So
128 if we adjust the gain or exposure we must ignore atleast the next frame for
129 the new settings to come into effect before doing any other adjustments. */
130#define AUTOGAIN_IGNORE_FRAMES 1
Hans de Goededcef3232008-07-10 10:40:53 -0300131
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300132static const struct v4l2_pix_format vga_mode[] = {
Hans de Goedec437d652008-09-03 17:12:22 -0300133 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
134 .bytesperline = 160,
Mauro Carvalho Chehab2389b362008-08-06 20:13:46 -0300135 .sizeimage = 160 * 120,
Hans de Goedec437d652008-09-03 17:12:22 -0300136 .colorspace = V4L2_COLORSPACE_SRGB,
137 .priv = 2 | MODE_RAW},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300138 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
139 .bytesperline = 160,
Hans de Goede5c51518d2008-09-03 17:12:22 -0300140 .sizeimage = 160 * 120 * 5 / 4,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300141 .colorspace = V4L2_COLORSPACE_SRGB,
142 .priv = 2},
143 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
144 .bytesperline = 320,
Hans de Goede5c51518d2008-09-03 17:12:22 -0300145 .sizeimage = 320 * 240 * 5 / 4,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300146 .colorspace = V4L2_COLORSPACE_SRGB,
147 .priv = 1},
148 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
149 .bytesperline = 640,
Hans de Goede5c51518d2008-09-03 17:12:22 -0300150 .sizeimage = 640 * 480 * 5 / 4,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300151 .colorspace = V4L2_COLORSPACE_SRGB,
152 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300153};
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300154static const struct v4l2_pix_format sif_mode[] = {
Hans de Goede93627732008-09-04 16:20:12 -0300155 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
156 .bytesperline = 160,
157 .sizeimage = 160 * 120,
158 .colorspace = V4L2_COLORSPACE_SRGB,
159 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
160 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
161 .bytesperline = 160,
162 .sizeimage = 160 * 120 * 5 / 4,
163 .colorspace = V4L2_COLORSPACE_SRGB,
164 .priv = 1 | MODE_REDUCED_SIF},
Hans de Goedec437d652008-09-03 17:12:22 -0300165 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
166 .bytesperline = 176,
Mauro Carvalho Chehab2389b362008-08-06 20:13:46 -0300167 .sizeimage = 176 * 144,
Hans de Goedec437d652008-09-03 17:12:22 -0300168 .colorspace = V4L2_COLORSPACE_SRGB,
169 .priv = 1 | MODE_RAW},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300170 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
171 .bytesperline = 176,
Hans de Goede5c51518d2008-09-03 17:12:22 -0300172 .sizeimage = 176 * 144 * 5 / 4,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300173 .colorspace = V4L2_COLORSPACE_SRGB,
174 .priv = 1},
Hans de Goede93627732008-09-04 16:20:12 -0300175 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
176 .bytesperline = 320,
177 .sizeimage = 320 * 240 * 5 / 4,
178 .colorspace = V4L2_COLORSPACE_SRGB,
179 .priv = 0 | MODE_REDUCED_SIF},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300180 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
181 .bytesperline = 352,
Hans de Goede5c51518d2008-09-03 17:12:22 -0300182 .sizeimage = 352 * 288 * 5 / 4,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300183 .colorspace = V4L2_COLORSPACE_SRGB,
184 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300185};
186
Hans de Goede00765f12010-12-12 15:55:03 -0300187static const __u8 initHv7131d[] = {
188 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
189 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
191 0x28, 0x1e, 0x60, 0x8e, 0x42,
Hans de Goede00765f12010-12-12 15:55:03 -0300192};
193static const __u8 hv7131d_sensor_init[][8] = {
194 {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
195 {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
196 {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
197 {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */
198 {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */
199};
200
201static const __u8 initHv7131r[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300202 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
203 0x00, 0x00,
Hans de Goedec437d652008-09-03 17:12:22 -0300204 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300205 0x28, 0x1e, 0x60, 0x8a, 0x20,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300206};
Hans de Goede00765f12010-12-12 15:55:03 -0300207static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300208 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
209 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
210 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
211 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
212 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
213};
214static const __u8 initOv6650[] = {
215 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
216 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Hans de Goedec437d652008-09-03 17:12:22 -0300217 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
Hans de Goede0a76cb82011-01-05 13:55:43 -0300218 0x10,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300219};
Jean-François Moine780e3122010-10-19 04:29:10 -0300220static const __u8 ov6650_sensor_init[][8] = {
André Goddard Rosaaf901ca2009-11-14 13:09:05 -0200221 /* Bright, contrast, etc are set through SCBB interface.
Jean-François Moine780e3122010-10-19 04:29:10 -0300222 * AVCAP on win2 do not send any data on this controls. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300223 /* Anyway, some registers appears to alter bright and constrat */
Hans de Goededcef3232008-07-10 10:40:53 -0300224
225 /* Reset sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300226 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
Hans de Goededcef3232008-07-10 10:40:53 -0300227 /* Set clock register 0x11 low nibble is clock divider */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300228 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
Hans de Goededcef3232008-07-10 10:40:53 -0300229 /* Next some unknown stuff */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300230 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
231/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
232 * THIS SET GREEN SCREEN
233 * (pixels could be innverted in decode kind of "brg",
234 * but blue wont be there. Avoid this data ... */
235 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
236 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
Jean-François Moine1d00d6c2010-10-29 13:58:22 -0300237 {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
Hans de Goede722103e2008-07-17 10:24:47 -0300238 /* Enable rgb brightness control */
239 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
240 /* HDG: Note windows uses the line below, which sets both register 0x60
241 and 0x61 I believe these registers of the ov6650 are identical as
242 those of the ov7630, because if this is true the windows settings
243 add a bit additional red gain and a lot additional blue gain, which
244 matches my findings that the windows settings make blue much too
245 blue and red a little too red.
246 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
Hans de Goededcef3232008-07-10 10:40:53 -0300247 /* Some more unknown stuff */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300248 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
249 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300250};
Hans de Goededcef3232008-07-10 10:40:53 -0300251
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300252static const __u8 initOv7630[] = {
253 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
254 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
Hans de Goedec437d652008-09-03 17:12:22 -0300255 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300256 0x28, 0x1e, /* H & V sizes r15 .. r16 */
Andoni Zubimendi51fc8e32008-07-10 11:12:24 -0300257 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300258};
Hans de Goede6af492e2008-07-22 07:09:33 -0300259static const __u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300260 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
261 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
262/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
Hans de Goede4c775902011-01-07 07:29:24 -0300263 {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300264 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
265 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
266 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
267 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
268 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
269 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
270 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
Andoni Zubimendi794af522008-07-16 08:33:14 -0300271 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
272/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300273 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
274 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
275 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
276 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
277 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
278 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
279};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300280
281static const __u8 initPas106[] = {
282 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
283 0x00, 0x00,
Hans de Goedec437d652008-09-03 17:12:22 -0300284 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
Hans de Goedef45f06b2008-09-03 17:12:21 -0300285 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300286};
287/* compression 0x86 mckinit1 0x2b */
Hans de Goede421763e2010-02-10 18:57:40 -0300288
289/* "Known" PAS106B registers:
290 0x02 clock divider
291 0x03 Variable framerate bits 4-11
292 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
293 The variable framerate control must never be set lower then 300,
294 which sets the framerate at 90 / reg02, otherwise vsync is lost.
295 0x05 Shutter Time Line Offset, this can be used as an exposure control:
296 0 = use full frame time, 255 = no exposure at all
297 Note this may never be larger then "var-framerate control" / 2 - 2.
298 When var-framerate control is < 514, no exposure is reached at the max
299 allowed value for the framerate control value, rather then at 255.
300 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
301 only a very little bit, leave at 0xcd
302 0x07 offset sign bit (bit0 1 > negative offset)
303 0x08 offset
304 0x09 Blue Gain
305 0x0a Green1 Gain
306 0x0b Green2 Gain
307 0x0c Red Gain
308 0x0e Global gain
309 0x13 Write 1 to commit settings to sensor
310*/
311
Hans de Goedef45f06b2008-09-03 17:12:21 -0300312static const __u8 pas106_sensor_init[][8] = {
313 /* Pixel Clock Divider 6 */
314 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
315 /* Frame Time MSB (also seen as 0x12) */
316 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
317 /* Frame Time LSB (also seen as 0x05) */
318 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
319 /* Shutter Time Line Offset (also seen as 0x6d) */
320 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
321 /* Shutter Time Pixel Offset (also seen as 0xb1) */
322 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
323 /* Black Level Subtract Sign (also seen 0x00) */
324 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
325 /* Black Level Subtract Level (also seen 0x01) */
326 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
327 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
328 /* Color Gain B Pixel 5 a */
329 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
330 /* Color Gain G1 Pixel 1 5 */
331 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
332 /* Color Gain G2 Pixel 1 0 5 */
333 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
334 /* Color Gain R Pixel 3 1 */
335 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
336 /* Color GainH Pixel */
337 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
338 /* Global Gain */
339 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
340 /* Contrast */
341 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
342 /* H&V synchro polarity */
343 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
344 /* ?default */
345 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
346 /* DAC scale */
347 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
348 /* ?default */
349 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
350 /* Validate Settings */
351 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300352};
Hans de Goedef45f06b2008-09-03 17:12:21 -0300353
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300354static const __u8 initPas202[] = {
355 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
356 0x00, 0x00,
Hans de Goedec437d652008-09-03 17:12:22 -0300357 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
Hans de Goede82e839c2010-02-03 14:37:30 -0300358 0x28, 0x1e, 0x20, 0x89, 0x20,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300359};
Hans de Goede82e839c2010-02-03 14:37:30 -0300360
361/* "Known" PAS202BCB registers:
362 0x02 clock divider
363 0x04 Variable framerate bits 6-11 (*)
364 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
365 0x07 Blue Gain
366 0x08 Green Gain
367 0x09 Red Gain
368 0x0b offset sign bit (bit0 1 > negative offset)
369 0x0c offset
370 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
371 leave at 1 otherwise we get a jump in our exposure control
372 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
373 0x10 Master gain 0 - 31
374 0x11 write 1 to apply changes
375 (*) The variable framerate control must never be set lower then 500
376 which sets the framerate at 30 / reg02, otherwise vsync is lost.
377*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300378static const __u8 pas202_sensor_init[][8] = {
Hans de Goede82e839c2010-02-03 14:37:30 -0300379 /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
380 to set it lower, but for some reason the bridge starts missing
381 vsync's then */
382 {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300383 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
384 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
Jean-François Moine1d00d6c2010-10-29 13:58:22 -0300385 {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300386 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
387 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
388 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
389 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
390 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
391 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300392};
393
Hans de Goedeb10af3f2010-01-10 19:31:34 -0300394static const __u8 initTas5110c[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300395 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
396 0x00, 0x00,
Hans de Goede4efcfa02010-02-01 07:48:17 -0300397 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300398 0x16, 0x12, 0x60, 0x86, 0x2b,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300399};
Hans de Goedeb10af3f2010-01-10 19:31:34 -0300400/* Same as above, except a different hstart */
401static const __u8 initTas5110d[] = {
402 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
403 0x00, 0x00,
Hans de Goede4efcfa02010-02-01 07:48:17 -0300404 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
Hans de Goedeb10af3f2010-01-10 19:31:34 -0300405 0x16, 0x12, 0x60, 0x86, 0x2b,
Hans de Goedeb10af3f2010-01-10 19:31:34 -0300406};
Hans de Goede0d0d7ef2011-01-06 07:55:20 -0300407/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */
408static const __u8 tas5110c_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300409 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
410 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
Hans de Goede0d0d7ef2011-01-06 07:55:20 -0300411};
412/* Known TAS5110D registers
413 * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain
414 * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted)
415 * Note: writing reg03 seems to only work when written together with 02
416 */
417static const __u8 tas5110d_sensor_init[][8] = {
418 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300419};
420
421static const __u8 initTas5130[] = {
422 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
423 0x00, 0x00,
Hans de Goede4efcfa02010-02-01 07:48:17 -0300424 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300425 0x28, 0x1e, 0x60, COMP, MCK_INIT,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300426};
427static const __u8 tas5130_sensor_init[][8] = {
Jean-François Moine780e3122010-10-19 04:29:10 -0300428/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300429 * shutter 0x47 short exposure? */
430 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
431 /* shutter 0x01 long exposure */
432 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
433};
434
Jean-François Moine75b79ff2011-03-13 16:07:25 -0300435static const struct sensor_data sensor_data[] = {
Hans de Goede9153ac32012-05-15 04:23:55 -0300436 SENS(initHv7131d, hv7131d_sensor_init, 0, 0),
437 SENS(initHv7131r, hv7131r_sensor_init, 0, 0),
438 SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60),
439 SENS(initOv7630, ov7630_sensor_init, 0, 0x21),
440 SENS(initPas106, pas106_sensor_init, F_SIF, 0),
441 SENS(initPas202, pas202_sensor_init, 0, 0),
442 SENS(initTas5110c, tas5110c_sensor_init, F_SIF, 0),
443 SENS(initTas5110d, tas5110d_sensor_init, F_SIF, 0),
444 SENS(initTas5130, tas5130_sensor_init, 0, 0),
Hans de Goedef45f06b2008-09-03 17:12:21 -0300445};
446
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300447/* get one byte in gspca_dev->usb_buf */
448static void reg_r(struct gspca_dev *gspca_dev,
449 __u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300450{
Hans de Goede4848ea72012-05-14 15:21:25 -0300451 int res;
452
453 if (gspca_dev->usb_err < 0)
454 return;
455
456 res = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300457 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300458 0, /* request */
459 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
460 value,
461 0, /* index */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300462 gspca_dev->usb_buf, 1,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300463 500);
Hans de Goede4848ea72012-05-14 15:21:25 -0300464
465 if (res < 0) {
466 dev_err(gspca_dev->v4l2_dev.dev,
467 "Error reading register %02x: %d\n", value, res);
468 gspca_dev->usb_err = res;
469 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300470}
471
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300472static void reg_w(struct gspca_dev *gspca_dev,
473 __u16 value,
474 const __u8 *buffer,
475 int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300476{
Hans de Goede4848ea72012-05-14 15:21:25 -0300477 int res;
478
479 if (gspca_dev->usb_err < 0)
Hans de Goede0d2a7222008-07-03 08:15:22 -0300480 return;
Hans de Goede4848ea72012-05-14 15:21:25 -0300481
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300482 memcpy(gspca_dev->usb_buf, buffer, len);
Hans de Goede4848ea72012-05-14 15:21:25 -0300483 res = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300484 usb_sndctrlpipe(gspca_dev->dev, 0),
485 0x08, /* request */
486 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
487 value,
488 0, /* index */
489 gspca_dev->usb_buf, len,
490 500);
Hans de Goede4848ea72012-05-14 15:21:25 -0300491
492 if (res < 0) {
493 dev_err(gspca_dev->v4l2_dev.dev,
494 "Error writing register %02x: %d\n", value, res);
495 gspca_dev->usb_err = res;
496 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300497}
498
Hans de Goede18fa0d32012-12-21 08:08:47 -0300499static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buf)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300500{
501 int retry = 60;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300502
Hans de Goede4848ea72012-05-14 15:21:25 -0300503 if (gspca_dev->usb_err < 0)
504 return;
505
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300506 /* is i2c ready */
Hans de Goede18fa0d32012-12-21 08:08:47 -0300507 reg_w(gspca_dev, 0x08, buf, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300508 while (retry--) {
Hans de Goede4848ea72012-05-14 15:21:25 -0300509 if (gspca_dev->usb_err < 0)
510 return;
Hans de Goede18fa0d32012-12-21 08:08:47 -0300511 msleep(1);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300512 reg_r(gspca_dev, 0x08);
Andoni Zubimendib7474cf92008-07-16 08:40:30 -0300513 if (gspca_dev->usb_buf[0] & 0x04) {
Hans de Goede4848ea72012-05-14 15:21:25 -0300514 if (gspca_dev->usb_buf[0] & 0x08) {
515 dev_err(gspca_dev->v4l2_dev.dev,
Hans de Goede18fa0d32012-12-21 08:08:47 -0300516 "i2c error writing %02x %02x %02x %02x"
517 " %02x %02x %02x %02x\n",
518 buf[0], buf[1], buf[2], buf[3],
519 buf[4], buf[5], buf[6], buf[7]);
Hans de Goede4848ea72012-05-14 15:21:25 -0300520 gspca_dev->usb_err = -EIO;
521 }
522 return;
Andoni Zubimendib7474cf92008-07-16 08:40:30 -0300523 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300524 }
Hans de Goede4848ea72012-05-14 15:21:25 -0300525
526 dev_err(gspca_dev->v4l2_dev.dev, "i2c write timeout\n");
527 gspca_dev->usb_err = -EIO;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300528}
529
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300530static void i2c_w_vector(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300531 const __u8 buffer[][8], int len)
532{
533 for (;;) {
Hans de Goede4848ea72012-05-14 15:21:25 -0300534 if (gspca_dev->usb_err < 0)
535 return;
Hans de Goede18fa0d32012-12-21 08:08:47 -0300536 i2c_w(gspca_dev, *buffer);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300537 len -= 8;
538 if (len <= 0)
539 break;
540 buffer++;
541 }
542}
543
544static void setbrightness(struct gspca_dev *gspca_dev)
545{
546 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300547
548 switch (sd->sensor) {
Hans de Goedea975a522008-07-16 15:29:11 -0300549 case SENSOR_OV6650:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300550 case SENSOR_OV7630: {
551 __u8 i2cOV[] =
Hans de Goedea975a522008-07-16 15:29:11 -0300552 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300553
554 /* change reg 0x06 */
Hans de Goedef45f06b2008-09-03 17:12:21 -0300555 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
Hans de Goede9153ac32012-05-15 04:23:55 -0300556 i2cOV[3] = sd->brightness->val;
Hans de Goede4848ea72012-05-14 15:21:25 -0300557 i2c_w(gspca_dev, i2cOV);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300558 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300559 }
Hans de Goede421763e2010-02-10 18:57:40 -0300560 case SENSOR_PAS106:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300561 case SENSOR_PAS202: {
Hans de Goede82e839c2010-02-03 14:37:30 -0300562 __u8 i2cpbright[] =
563 {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
Hans de Goede421763e2010-02-10 18:57:40 -0300564 __u8 i2cpdoit[] =
Hans de Goede82e839c2010-02-03 14:37:30 -0300565 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300566
Hans de Goede421763e2010-02-10 18:57:40 -0300567 /* PAS106 uses reg 7 and 8 instead of b and c */
568 if (sd->sensor == SENSOR_PAS106) {
569 i2cpbright[2] = 7;
570 i2cpdoit[2] = 0x13;
571 }
572
Hans de Goede9153ac32012-05-15 04:23:55 -0300573 if (sd->brightness->val < 127) {
Hans de Goede82e839c2010-02-03 14:37:30 -0300574 /* change reg 0x0b, signreg */
575 i2cpbright[3] = 0x01;
576 /* set reg 0x0c, offset */
Hans de Goede9153ac32012-05-15 04:23:55 -0300577 i2cpbright[4] = 127 - sd->brightness->val;
Hans de Goede82e839c2010-02-03 14:37:30 -0300578 } else
Hans de Goede9153ac32012-05-15 04:23:55 -0300579 i2cpbright[4] = sd->brightness->val - 127;
Hans de Goede82e839c2010-02-03 14:37:30 -0300580
Hans de Goede4848ea72012-05-14 15:21:25 -0300581 i2c_w(gspca_dev, i2cpbright);
582 i2c_w(gspca_dev, i2cpdoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300583 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300584 }
Hans de Goede4848ea72012-05-14 15:21:25 -0300585 default:
586 break;
587 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300588}
Hans de Goededcef3232008-07-10 10:40:53 -0300589
Hans de Goede9153ac32012-05-15 04:23:55 -0300590static void setgain(struct gspca_dev *gspca_dev)
Hans de Goededcef3232008-07-10 10:40:53 -0300591{
592 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede9153ac32012-05-15 04:23:55 -0300593 u8 gain = gspca_dev->gain->val;
Hans de Goededcef3232008-07-10 10:40:53 -0300594
595 switch (sd->sensor) {
Hans de Goede00765f12010-12-12 15:55:03 -0300596 case SENSOR_HV7131D: {
597 __u8 i2c[] =
598 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
Hans de Goededcef3232008-07-10 10:40:53 -0300599
Hans de Goede9153ac32012-05-15 04:23:55 -0300600 i2c[3] = 0x3f - gain;
601 i2c[4] = 0x3f - gain;
602 i2c[5] = 0x3f - gain;
Hans de Goede00765f12010-12-12 15:55:03 -0300603
Hans de Goede4848ea72012-05-14 15:21:25 -0300604 i2c_w(gspca_dev, i2c);
Hans de Goede00765f12010-12-12 15:55:03 -0300605 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300606 }
Hans de Goede4e17cd22011-01-06 10:58:53 -0300607 case SENSOR_TAS5110C:
608 case SENSOR_TAS5130CXX: {
Hans de Goededcef3232008-07-10 10:40:53 -0300609 __u8 i2c[] =
610 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
611
Hans de Goedea975a522008-07-16 15:29:11 -0300612 i2c[4] = 255 - gain;
Hans de Goede4848ea72012-05-14 15:21:25 -0300613 i2c_w(gspca_dev, i2c);
Andoni Zubimendi51fc8e32008-07-10 11:12:24 -0300614 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300615 }
Hans de Goede0d0d7ef2011-01-06 07:55:20 -0300616 case SENSOR_TAS5110D: {
617 __u8 i2c[] = {
618 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
619 gain = 255 - gain;
620 /* The bits in the register are the wrong way around!! */
621 i2c[3] |= (gain & 0x80) >> 7;
622 i2c[3] |= (gain & 0x40) >> 5;
623 i2c[3] |= (gain & 0x20) >> 3;
624 i2c[3] |= (gain & 0x10) >> 1;
625 i2c[3] |= (gain & 0x08) << 1;
626 i2c[3] |= (gain & 0x04) << 3;
627 i2c[3] |= (gain & 0x02) << 5;
628 i2c[3] |= (gain & 0x01) << 7;
Hans de Goede4848ea72012-05-14 15:21:25 -0300629 i2c_w(gspca_dev, i2c);
Hans de Goede0d0d7ef2011-01-06 07:55:20 -0300630 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300631 }
Hans de Goedea975a522008-07-16 15:29:11 -0300632 case SENSOR_OV6650:
Hans de Goede6af492e2008-07-22 07:09:33 -0300633 case SENSOR_OV7630: {
Hans de Goedea975a522008-07-16 15:29:11 -0300634 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
Andoni Zubimendi794af522008-07-16 08:33:14 -0300635
Hans de Goede8b3a19b2012-05-16 07:14:54 -0300636 /*
637 * The ov7630's gain is weird, at 32 the gain drops to the
638 * same level as at 16, so skip 32-47 (of the 0-63 scale).
639 */
640 if (sd->sensor == SENSOR_OV7630 && gain >= 32)
641 gain += 16;
642
Hans de Goedef45f06b2008-09-03 17:12:21 -0300643 i2c[1] = sensor_data[sd->sensor].sensor_addr;
Hans de Goede9153ac32012-05-15 04:23:55 -0300644 i2c[3] = gain;
Hans de Goede4848ea72012-05-14 15:21:25 -0300645 i2c_w(gspca_dev, i2c);
Andoni Zubimendi794af522008-07-16 08:33:14 -0300646 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300647 }
Hans de Goede421763e2010-02-10 18:57:40 -0300648 case SENSOR_PAS106:
Hans de Goede82e839c2010-02-03 14:37:30 -0300649 case SENSOR_PAS202: {
650 __u8 i2cpgain[] =
Hans de Goede421763e2010-02-10 18:57:40 -0300651 {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
Hans de Goede82e839c2010-02-03 14:37:30 -0300652 __u8 i2cpcolorgain[] =
653 {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
Hans de Goede421763e2010-02-10 18:57:40 -0300654 __u8 i2cpdoit[] =
655 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
656
657 /* PAS106 uses different regs (and has split green gains) */
658 if (sd->sensor == SENSOR_PAS106) {
659 i2cpgain[2] = 0x0e;
660 i2cpcolorgain[0] = 0xd0;
661 i2cpcolorgain[2] = 0x09;
662 i2cpdoit[2] = 0x13;
663 }
Hans de Goede82e839c2010-02-03 14:37:30 -0300664
Hans de Goede9153ac32012-05-15 04:23:55 -0300665 i2cpgain[3] = gain;
666 i2cpcolorgain[3] = gain >> 1;
667 i2cpcolorgain[4] = gain >> 1;
668 i2cpcolorgain[5] = gain >> 1;
669 i2cpcolorgain[6] = gain >> 1;
Hans de Goede82e839c2010-02-03 14:37:30 -0300670
Hans de Goede4848ea72012-05-14 15:21:25 -0300671 i2c_w(gspca_dev, i2cpgain);
672 i2c_w(gspca_dev, i2cpcolorgain);
673 i2c_w(gspca_dev, i2cpdoit);
Hans de Goede82e839c2010-02-03 14:37:30 -0300674 break;
Hans de Goededcef3232008-07-10 10:40:53 -0300675 }
Hans de Goede4848ea72012-05-14 15:21:25 -0300676 default:
Hans de Goede9153ac32012-05-15 04:23:55 -0300677 if (sd->bridge == BRIDGE_103) {
678 u8 buf[3] = { gain, gain, gain }; /* R, G, B */
679 reg_w(gspca_dev, 0x05, buf, 3);
680 } else {
681 u8 buf[2];
682 buf[0] = gain << 4 | gain; /* Red and blue */
683 buf[1] = gain; /* Green */
684 reg_w(gspca_dev, 0x10, buf, 2);
685 }
Hans de Goede0a76cb82011-01-05 13:55:43 -0300686 }
Hans de Goededcef3232008-07-10 10:40:53 -0300687}
688
689static void setexposure(struct gspca_dev *gspca_dev)
690{
691 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goededcef3232008-07-10 10:40:53 -0300692
693 switch (sd->sensor) {
Hans de Goede00765f12010-12-12 15:55:03 -0300694 case SENSOR_HV7131D: {
695 /* Note the datasheet wrongly says line mode exposure uses reg
696 0x26 and 0x27, testing has shown 0x25 + 0x26 */
697 __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
Hans de Goede9153ac32012-05-15 04:23:55 -0300698 u16 reg = gspca_dev->exposure->val;
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300699
Hans de Goede00765f12010-12-12 15:55:03 -0300700 i2c[3] = reg >> 8;
701 i2c[4] = reg & 0xff;
Hans de Goede4848ea72012-05-14 15:21:25 -0300702 i2c_w(gspca_dev, i2c);
Hans de Goede00765f12010-12-12 15:55:03 -0300703 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300704 }
Hans de Goedeb10af3f2010-01-10 19:31:34 -0300705 case SENSOR_TAS5110C:
706 case SENSOR_TAS5110D: {
Hans de Goededcef3232008-07-10 10:40:53 -0300707 /* register 19's high nibble contains the sn9c10x clock divider
708 The high nibble configures the no fps according to the
709 formula: 60 / high_nibble. With a maximum of 30 fps */
Hans de Goede9153ac32012-05-15 04:23:55 -0300710 u8 reg = gspca_dev->exposure->val;
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300711
Hans de Goededcef3232008-07-10 10:40:53 -0300712 reg = (reg << 4) | 0x0b;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300713 reg_w(gspca_dev, 0x19, &reg, 1);
Andoni Zubimendi51fc8e32008-07-10 11:12:24 -0300714 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300715 }
Hans de Goedea975a522008-07-16 15:29:11 -0300716 case SENSOR_OV6650:
Hans de Goede6af492e2008-07-22 07:09:33 -0300717 case SENSOR_OV7630: {
Hans de Goedea975a522008-07-16 15:29:11 -0300718 /* The ov6650 / ov7630 have 2 registers which both influence
719 exposure, register 11, whose low nibble sets the nr off fps
Hans de Goedef4d52022008-07-15 09:36:42 -0300720 according to: fps = 30 / (low_nibble + 1)
721
722 The fps configures the maximum exposure setting, but it is
723 possible to use less exposure then what the fps maximum
724 allows by setting register 10. register 10 configures the
725 actual exposure as quotient of the full exposure, with 0
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300726 being no exposure at all (not very useful) and reg10_max
Hans de Goedef4d52022008-07-15 09:36:42 -0300727 being max exposure possible at that framerate.
728
729 The code maps our 0 - 510 ms exposure ctrl to these 2
730 registers, trying to keep fps as high as possible.
731 */
Hans de Goede6af492e2008-07-22 07:09:33 -0300732 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
733 int reg10, reg11, reg10_max;
734
Hans de Goede66f35822008-07-16 10:16:28 -0300735 /* ov6645 datasheet says reg10_max is 9a, but that uses
736 tline * 2 * reg10 as formula for calculating texpo, the
737 ov6650 probably uses the same formula as the 7730 which uses
738 tline * 4 * reg10, which explains why the reg10max we've
739 found experimentally for the ov6650 is exactly half that of
Hans de Goedea975a522008-07-16 15:29:11 -0300740 the ov6645. The ov7630 datasheet says the max is 0x41. */
Hans de Goede6af492e2008-07-22 07:09:33 -0300741 if (sd->sensor == SENSOR_OV6650) {
742 reg10_max = 0x4d;
743 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
744 } else
745 reg10_max = 0x41;
Hans de Goedef4d52022008-07-15 09:36:42 -0300746
Hans de Goede9153ac32012-05-15 04:23:55 -0300747 reg11 = (15 * gspca_dev->exposure->val + 999) / 1000;
Hans de Goedef4d52022008-07-15 09:36:42 -0300748 if (reg11 < 1)
749 reg11 = 1;
750 else if (reg11 > 16)
751 reg11 = 16;
752
Hans de Goede10bb7532010-02-04 06:10:55 -0300753 /* In 640x480, if the reg11 has less than 4, the image is
754 unstable (the bridge goes into a higher compression mode
755 which we have not reverse engineered yet). */
756 if (gspca_dev->width == 640 && reg11 < 4)
757 reg11 = 4;
Hans de Goedee2ad2a52008-09-03 17:12:15 -0300758
Hans de Goedef4d52022008-07-15 09:36:42 -0300759 /* frame exposure time in ms = 1000 * reg11 / 30 ->
Hans de Goede9153ac32012-05-15 04:23:55 -0300760 reg10 = (gspca_dev->exposure->val / 2) * reg10_max
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300761 / (1000 * reg11 / 30) */
Hans de Goede9153ac32012-05-15 04:23:55 -0300762 reg10 = (gspca_dev->exposure->val * 15 * reg10_max)
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300763 / (1000 * reg11);
Hans de Goedea975a522008-07-16 15:29:11 -0300764
765 /* Don't allow this to get below 10 when using autogain, the
766 steps become very large (relatively) when below 10 causing
767 the image to oscilate from much too dark, to much too bright
768 and back again. */
Hans de Goede9153ac32012-05-15 04:23:55 -0300769 if (gspca_dev->autogain->val && reg10 < 10)
Hans de Goedea975a522008-07-16 15:29:11 -0300770 reg10 = 10;
Hans de Goedef4d52022008-07-15 09:36:42 -0300771 else if (reg10 > reg10_max)
772 reg10 = reg10_max;
773
774 /* Write reg 10 and reg11 low nibble */
Hans de Goedef45f06b2008-09-03 17:12:21 -0300775 i2c[1] = sensor_data[sd->sensor].sensor_addr;
Andoni Zubimendi794af522008-07-16 08:33:14 -0300776 i2c[3] = reg10;
777 i2c[4] |= reg11 - 1;
Hans de Goede6af492e2008-07-22 07:09:33 -0300778
779 /* If register 11 didn't change, don't change it */
Jean-François Moine780e3122010-10-19 04:29:10 -0300780 if (sd->reg11 == reg11)
Hans de Goede6af492e2008-07-22 07:09:33 -0300781 i2c[0] = 0xa0;
782
Hans de Goede4848ea72012-05-14 15:21:25 -0300783 i2c_w(gspca_dev, i2c);
784 if (gspca_dev->usb_err == 0)
Hans de Goede6af492e2008-07-22 07:09:33 -0300785 sd->reg11 = reg11;
Hans de Goede82e839c2010-02-03 14:37:30 -0300786 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300787 }
Hans de Goede82e839c2010-02-03 14:37:30 -0300788 case SENSOR_PAS202: {
789 __u8 i2cpframerate[] =
790 {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
791 __u8 i2cpexpo[] =
792 {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
793 const __u8 i2cpdoit[] =
794 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
795 int framerate_ctrl;
796
797 /* The exposure knee for the autogain algorithm is 200
798 (100 ms / 10 fps on other sensors), for values below this
799 use the control for setting the partial frame expose time,
800 above that use variable framerate. This way we run at max
801 framerate (640x480@7.5 fps, 320x240@10fps) until the knee
802 is reached. Using the variable framerate control above 200
803 is better then playing around with both clockdiv + partial
804 frame exposure times (like we are doing with the ov chips),
805 as that sometimes leads to jumps in the exposure control,
806 which are bad for auto exposure. */
Hans de Goede9153ac32012-05-15 04:23:55 -0300807 if (gspca_dev->exposure->val < 200) {
808 i2cpexpo[3] = 255 - (gspca_dev->exposure->val * 255)
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300809 / 200;
Hans de Goede82e839c2010-02-03 14:37:30 -0300810 framerate_ctrl = 500;
811 } else {
812 /* The PAS202's exposure control goes from 0 - 4095,
813 but anything below 500 causes vsync issues, so scale
814 our 200-1023 to 500-4095 */
Hans de Goede9153ac32012-05-15 04:23:55 -0300815 framerate_ctrl = (gspca_dev->exposure->val - 200)
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300816 * 1000 / 229 + 500;
Hans de Goede82e839c2010-02-03 14:37:30 -0300817 }
818
819 i2cpframerate[3] = framerate_ctrl >> 6;
820 i2cpframerate[4] = framerate_ctrl & 0x3f;
Hans de Goede4848ea72012-05-14 15:21:25 -0300821 i2c_w(gspca_dev, i2cpframerate);
822 i2c_w(gspca_dev, i2cpexpo);
823 i2c_w(gspca_dev, i2cpdoit);
Andoni Zubimendi794af522008-07-16 08:33:14 -0300824 break;
Hans de Goede4848ea72012-05-14 15:21:25 -0300825 }
Hans de Goede421763e2010-02-10 18:57:40 -0300826 case SENSOR_PAS106: {
827 __u8 i2cpframerate[] =
828 {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
829 __u8 i2cpexpo[] =
830 {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
831 const __u8 i2cpdoit[] =
832 {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
833 int framerate_ctrl;
834
835 /* For values below 150 use partial frame exposure, above
836 that use framerate ctrl */
Hans de Goede9153ac32012-05-15 04:23:55 -0300837 if (gspca_dev->exposure->val < 150) {
838 i2cpexpo[3] = 150 - gspca_dev->exposure->val;
Hans de Goede421763e2010-02-10 18:57:40 -0300839 framerate_ctrl = 300;
840 } else {
841 /* The PAS106's exposure control goes from 0 - 4095,
842 but anything below 300 causes vsync issues, so scale
843 our 150-1023 to 300-4095 */
Hans de Goede9153ac32012-05-15 04:23:55 -0300844 framerate_ctrl = (gspca_dev->exposure->val - 150)
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300845 * 1000 / 230 + 300;
Hans de Goede421763e2010-02-10 18:57:40 -0300846 }
847
848 i2cpframerate[3] = framerate_ctrl >> 4;
849 i2cpframerate[4] = framerate_ctrl & 0x0f;
Hans de Goede4848ea72012-05-14 15:21:25 -0300850 i2c_w(gspca_dev, i2cpframerate);
851 i2c_w(gspca_dev, i2cpexpo);
852 i2c_w(gspca_dev, i2cpdoit);
Hans de Goede421763e2010-02-10 18:57:40 -0300853 break;
Hans de Goededcef3232008-07-10 10:40:53 -0300854 }
Hans de Goede4848ea72012-05-14 15:21:25 -0300855 default:
856 break;
857 }
Hans de Goededcef3232008-07-10 10:40:53 -0300858}
859
Hans de Goede66f35822008-07-16 10:16:28 -0300860static void setfreq(struct gspca_dev *gspca_dev)
861{
862 struct sd *sd = (struct sd *) gspca_dev;
863
Hans de Goede4848ea72012-05-14 15:21:25 -0300864 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) {
Hans de Goede66f35822008-07-16 10:16:28 -0300865 /* Framerate adjust register for artificial light 50 hz flicker
Hans de Goede6af492e2008-07-22 07:09:33 -0300866 compensation, for the ov6650 this is identical to ov6630
867 0x2b register, see ov6630 datasheet.
868 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
Andoni Zubimendid87616f2008-07-17 05:35:52 -0300869 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
Hans de Goede9153ac32012-05-15 04:23:55 -0300870 switch (sd->plfreq->val) {
Hans de Goede66f35822008-07-16 10:16:28 -0300871 default:
872/* case 0: * no filter*/
873/* case 2: * 60 hz */
874 i2c[3] = 0;
875 break;
876 case 1: /* 50 hz */
Hans de Goede722103e2008-07-17 10:24:47 -0300877 i2c[3] = (sd->sensor == SENSOR_OV6650)
878 ? 0x4f : 0x8a;
Hans de Goede66f35822008-07-16 10:16:28 -0300879 break;
880 }
Hans de Goedef45f06b2008-09-03 17:12:21 -0300881 i2c[1] = sensor_data[sd->sensor].sensor_addr;
Hans de Goede4848ea72012-05-14 15:21:25 -0300882 i2c_w(gspca_dev, i2c);
Hans de Goede66f35822008-07-16 10:16:28 -0300883 }
884}
885
Hans de Goededcef3232008-07-10 10:40:53 -0300886static void do_autogain(struct gspca_dev *gspca_dev)
887{
888 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede9153ac32012-05-15 04:23:55 -0300889 int deadzone, desired_avg_lum, avg_lum;
Hans de Goededcef3232008-07-10 10:40:53 -0300890
Hans de Goede9153ac32012-05-15 04:23:55 -0300891 avg_lum = atomic_read(&sd->avg_lum);
892 if (avg_lum == -1)
Hans de Goededcef3232008-07-10 10:40:53 -0300893 return;
894
Hans de Goede26984b02010-02-01 13:18:37 -0300895 if (sd->autogain_ignore_frames > 0) {
896 sd->autogain_ignore_frames--;
897 return;
898 }
899
Hans de Goede5017c7b2008-10-22 04:59:29 -0300900 /* SIF / VGA sensors have a different autoexposure area and thus
901 different avg_lum values for the same picture brightness */
902 if (sensor_data[sd->sensor].flags & F_SIF) {
Hans de Goede26984b02010-02-01 13:18:37 -0300903 deadzone = 500;
904 /* SIF sensors tend to overexpose, so keep this small */
905 desired_avg_lum = 5000;
Hans de Goede5017c7b2008-10-22 04:59:29 -0300906 } else {
Hans de Goede26984b02010-02-01 13:18:37 -0300907 deadzone = 1500;
Hans de Goedef913c002011-01-05 16:01:16 -0300908 desired_avg_lum = 13000;
Hans de Goede5017c7b2008-10-22 04:59:29 -0300909 }
910
Hans de Goede9153ac32012-05-15 04:23:55 -0300911 if (sd->brightness)
912 desired_avg_lum = sd->brightness->val * desired_avg_lum / 127;
Hans de Goede26984b02010-02-01 13:18:37 -0300913
Hans de Goede9153ac32012-05-15 04:23:55 -0300914 if (gspca_dev->exposure->maximum < 500) {
915 if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
916 desired_avg_lum, deadzone))
917 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
918 } else {
919 int gain_knee = gspca_dev->gain->maximum * 9 / 10;
920 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum,
921 deadzone, gain_knee, sd->exposure_knee))
922 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
Hans de Goedea975a522008-07-16 15:29:11 -0300923 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300924}
925
926/* this function is called at probe time */
927static int sd_config(struct gspca_dev *gspca_dev,
928 const struct usb_device_id *id)
929{
930 struct sd *sd = (struct sd *) gspca_dev;
931 struct cam *cam;
Hans de Goede65f33392008-09-03 17:12:15 -0300932
933 reg_r(gspca_dev, 0x00);
934 if (gspca_dev->usb_buf[0] != 0x10)
935 return -ENODEV;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936
Jean-Francois Moine5da162e2008-07-26 14:17:23 -0300937 /* copy the webcam info from the device id */
Hans de Goedef45f06b2008-09-03 17:12:21 -0300938 sd->sensor = id->driver_info >> 8;
939 sd->bridge = id->driver_info & 0xff;
Jean-François Moinef51a8ca2011-03-13 15:04:11 -0300940
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300941 cam = &gspca_dev->cam;
Hans de Goedef45f06b2008-09-03 17:12:21 -0300942 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300943 cam->cam_mode = vga_mode;
Andoni Zubimendi51fc8e32008-07-10 11:12:24 -0300944 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300945 } else {
946 cam->cam_mode = sif_mode;
Andoni Zubimendi51fc8e32008-07-10 11:12:24 -0300947 cam->nmodes = ARRAY_SIZE(sif_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300948 }
Jean-Francois Moine49cb6b02009-04-25 13:29:01 -0300949 cam->npkt = 36; /* 36 packets per ISOC message */
950
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300951 return 0;
952}
953
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300954/* this function is called at probe and resume time */
955static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300956{
Hans de Goede271315a2008-09-03 17:12:19 -0300957 const __u8 stop = 0x09; /* Disable stream turn of LED */
958
959 reg_w(gspca_dev, 0x01, &stop, 1);
960
Hans de Goede4848ea72012-05-14 15:21:25 -0300961 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300962}
963
Hans de Goede9153ac32012-05-15 04:23:55 -0300964static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
965{
966 struct gspca_dev *gspca_dev =
967 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
968 struct sd *sd = (struct sd *)gspca_dev;
969
970 gspca_dev->usb_err = 0;
971
972 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
973 /* when switching to autogain set defaults to make sure
974 we are on a valid point of the autogain gain /
975 exposure knee graph, and give this change time to
976 take effect before doing autogain. */
977 gspca_dev->gain->val = gspca_dev->gain->default_value;
978 gspca_dev->exposure->val = gspca_dev->exposure->default_value;
979 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
980 }
981
982 if (!gspca_dev->streaming)
983 return 0;
984
985 switch (ctrl->id) {
986 case V4L2_CID_BRIGHTNESS:
987 setbrightness(gspca_dev);
988 break;
989 case V4L2_CID_AUTOGAIN:
990 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
991 setexposure(gspca_dev);
992 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
993 setgain(gspca_dev);
994 break;
995 case V4L2_CID_POWER_LINE_FREQUENCY:
996 setfreq(gspca_dev);
997 break;
998 default:
999 return -EINVAL;
1000 }
1001 return gspca_dev->usb_err;
1002}
1003
1004static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1005 .s_ctrl = sd_s_ctrl,
1006};
1007
1008/* this function is called at probe time */
1009static int sd_init_controls(struct gspca_dev *gspca_dev)
1010{
1011 struct sd *sd = (struct sd *) gspca_dev;
1012 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1013
1014 gspca_dev->vdev.ctrl_handler = hdl;
1015 v4l2_ctrl_handler_init(hdl, 5);
1016
1017 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630 ||
1018 sd->sensor == SENSOR_PAS106 || sd->sensor == SENSOR_PAS202)
1019 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1020 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1021
1022 /* Gain range is sensor dependent */
1023 switch (sd->sensor) {
1024 case SENSOR_OV6650:
1025 case SENSOR_PAS106:
1026 case SENSOR_PAS202:
1027 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1028 V4L2_CID_GAIN, 0, 31, 1, 15);
1029 break;
Hans de Goede9153ac32012-05-15 04:23:55 -03001030 case SENSOR_OV7630:
1031 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
Hans de Goede8b3a19b2012-05-16 07:14:54 -03001032 V4L2_CID_GAIN, 0, 47, 1, 31);
1033 break;
1034 case SENSOR_HV7131D:
1035 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
Hans de Goede9153ac32012-05-15 04:23:55 -03001036 V4L2_CID_GAIN, 0, 63, 1, 31);
1037 break;
1038 case SENSOR_TAS5110C:
1039 case SENSOR_TAS5110D:
1040 case SENSOR_TAS5130CXX:
1041 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1042 V4L2_CID_GAIN, 0, 255, 1, 127);
1043 break;
1044 default:
1045 if (sd->bridge == BRIDGE_103) {
1046 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1047 V4L2_CID_GAIN, 0, 127, 1, 63);
1048 } else {
1049 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1050 V4L2_CID_GAIN, 0, 15, 1, 7);
1051 }
1052 }
1053
1054 /* Exposure range is sensor dependent, and not all have exposure */
1055 switch (sd->sensor) {
1056 case SENSOR_HV7131D:
1057 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1058 V4L2_CID_EXPOSURE, 0, 8191, 1, 482);
1059 sd->exposure_knee = 964;
1060 break;
1061 case SENSOR_OV6650:
1062 case SENSOR_OV7630:
1063 case SENSOR_PAS106:
1064 case SENSOR_PAS202:
1065 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1066 V4L2_CID_EXPOSURE, 0, 1023, 1, 66);
1067 sd->exposure_knee = 200;
1068 break;
1069 case SENSOR_TAS5110C:
1070 case SENSOR_TAS5110D:
1071 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1072 V4L2_CID_EXPOSURE, 2, 15, 1, 2);
1073 break;
1074 }
1075
1076 if (gspca_dev->exposure) {
1077 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1078 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1079 }
1080
1081 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630)
1082 sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1083 V4L2_CID_POWER_LINE_FREQUENCY,
1084 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1085 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
1086
1087 if (hdl->error) {
1088 pr_err("Could not initialize controls\n");
1089 return hdl->error;
1090 }
1091
1092 if (gspca_dev->autogain)
1093 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
1094
1095 return 0;
1096}
1097
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001098/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001099static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001100{
1101 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede93627732008-09-04 16:20:12 -03001102 struct cam *cam = &gspca_dev->cam;
Hans de Goede0a76cb82011-01-05 13:55:43 -03001103 int i, mode;
1104 __u8 regs[0x31];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001105
Hans de Goede93627732008-09-04 16:20:12 -03001106 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
Hans de Goede0a76cb82011-01-05 13:55:43 -03001107 /* Copy registers 0x01 - 0x19 from the template */
1108 memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
1109 /* Set the mode */
1110 regs[0x18] |= mode << 4;
1111
1112 /* Set bridge gain to 1.0 */
1113 if (sd->bridge == BRIDGE_103) {
1114 regs[0x05] = 0x20; /* Red */
1115 regs[0x06] = 0x20; /* Green */
1116 regs[0x07] = 0x20; /* Blue */
1117 } else {
1118 regs[0x10] = 0x00; /* Red and blue */
1119 regs[0x11] = 0x00; /* Green */
1120 }
1121
1122 /* Setup pixel numbers and auto exposure window */
1123 if (sensor_data[sd->sensor].flags & F_SIF) {
1124 regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
1125 regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
1126 regs[0x1c] = 0x02; /* AE H-start 64 */
1127 regs[0x1d] = 0x02; /* AE V-start 64 */
1128 regs[0x1e] = 0x09; /* AE H-end 288 */
1129 regs[0x1f] = 0x07; /* AE V-end 224 */
1130 } else {
1131 regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
1132 regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
Hans de Goedef913c002011-01-05 16:01:16 -03001133 regs[0x1c] = 0x05; /* AE H-start 160 */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001134 regs[0x1d] = 0x03; /* AE V-start 96 */
1135 regs[0x1e] = 0x0f; /* AE H-end 480 */
1136 regs[0x1f] = 0x0c; /* AE V-end 384 */
1137 }
1138
1139 /* Setup the gamma table (only used with the sn9c103 bridge) */
1140 for (i = 0; i < 16; i++)
1141 regs[0x20 + i] = i * 16;
1142 regs[0x20 + i] = 255;
1143
1144 /* Special cases where some regs depend on mode or bridge */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001145 switch (sd->sensor) {
Hans de Goedef45f06b2008-09-03 17:12:21 -03001146 case SENSOR_TAS5130CXX:
Hans de Goede0a76cb82011-01-05 13:55:43 -03001147 /* FIXME / TESTME
1148 probably not mode specific at all most likely the upper
Hans de Goedef45f06b2008-09-03 17:12:21 -03001149 nibble of 0x19 is exposure (clock divider) just as with
1150 the tas5110, we need someone to test this. */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001151 regs[0x19] = mode ? 0x23 : 0x43;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001152 break;
Hans de Goede0a76cb82011-01-05 13:55:43 -03001153 case SENSOR_OV7630:
1154 /* FIXME / TESTME for some reason with the 101/102 bridge the
1155 clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
1156 Also the hstart needs to go from 1 to 2 when using a 103,
1157 which is likely related. This does not seem right. */
1158 if (sd->bridge == BRIDGE_103) {
1159 regs[0x01] = 0x44; /* Select 24 Mhz clock */
1160 regs[0x12] = 0x02; /* Set hstart to 2 */
1161 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001162 }
Hans de Goedec437d652008-09-03 17:12:22 -03001163 /* Disable compression when the raw bayer format has been selected */
Hans de Goede93627732008-09-04 16:20:12 -03001164 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
Hans de Goede0a76cb82011-01-05 13:55:43 -03001165 regs[0x18] &= ~0x80;
Hans de Goede93627732008-09-04 16:20:12 -03001166
1167 /* Vga mode emulation on SIF sensor? */
1168 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
Hans de Goede0a76cb82011-01-05 13:55:43 -03001169 regs[0x12] += 16; /* hstart adjust */
1170 regs[0x13] += 24; /* vstart adjust */
1171 regs[0x15] = 320 / 16; /* hsize */
1172 regs[0x16] = 240 / 16; /* vsize */
Hans de Goede93627732008-09-04 16:20:12 -03001173 }
Hans de Goede6af492e2008-07-22 07:09:33 -03001174
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001175 /* reg 0x01 bit 2 video transfert on */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001176 reg_w(gspca_dev, 0x01, &regs[0x01], 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001177 /* reg 0x17 SensorClk enable inv Clk 0x60 */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001178 reg_w(gspca_dev, 0x17, &regs[0x17], 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001179 /* Set the registers from the template */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001180 reg_w(gspca_dev, 0x01, &regs[0x01],
1181 (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
Hans de Goedef45f06b2008-09-03 17:12:21 -03001182
1183 /* Init the sensor */
1184 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1185 sensor_data[sd->sensor].sensor_init_size);
Hans de Goedef45f06b2008-09-03 17:12:21 -03001186
Hans de Goede0a76cb82011-01-05 13:55:43 -03001187 /* Mode / bridge specific sensor setup */
Hans de Goede82e839c2010-02-03 14:37:30 -03001188 switch (sd->sensor) {
1189 case SENSOR_PAS202: {
1190 const __u8 i2cpclockdiv[] =
1191 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1192 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1193 if (mode)
1194 i2c_w(gspca_dev, i2cpclockdiv);
Hans de Goede0a76cb82011-01-05 13:55:43 -03001195 break;
Hans de Goede82e839c2010-02-03 14:37:30 -03001196 }
Hans de Goede0a76cb82011-01-05 13:55:43 -03001197 case SENSOR_OV7630:
1198 /* FIXME / TESTME We should be able to handle this identical
1199 for the 101/102 and the 103 case */
1200 if (sd->bridge == BRIDGE_103) {
1201 const __u8 i2c[] = { 0xa0, 0x21, 0x13,
1202 0x80, 0x00, 0x00, 0x00, 0x10 };
1203 i2c_w(gspca_dev, i2c);
1204 }
1205 break;
Hans de Goede82e839c2010-02-03 14:37:30 -03001206 }
Hans de Goede3647fea2008-07-15 05:36:30 -03001207 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001208 reg_w(gspca_dev, 0x15, &regs[0x15], 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001209 /* compression register */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001210 reg_w(gspca_dev, 0x18, &regs[0x18], 1);
Andoni Zubimendi794af522008-07-16 08:33:14 -03001211 /* H_start */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001212 reg_w(gspca_dev, 0x12, &regs[0x12], 1);
Andoni Zubimendi794af522008-07-16 08:33:14 -03001213 /* V_START */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001214 reg_w(gspca_dev, 0x13, &regs[0x13], 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001215 /* reset 0x17 SensorClk enable inv Clk 0x60 */
1216 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
Hans de Goede0a76cb82011-01-05 13:55:43 -03001217 reg_w(gspca_dev, 0x17, &regs[0x17], 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001218 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
Hans de Goede0a76cb82011-01-05 13:55:43 -03001219 reg_w(gspca_dev, 0x19, &regs[0x19], 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001220 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001221 reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001222 /* Enable video transfert */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001223 reg_w(gspca_dev, 0x01, &regs[0x01], 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001224 /* Compression */
Hans de Goede0a76cb82011-01-05 13:55:43 -03001225 reg_w(gspca_dev, 0x18, &regs[0x18], 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001226 msleep(20);
1227
Hans de Goede6af492e2008-07-22 07:09:33 -03001228 sd->reg11 = -1;
1229
Hans de Goededcef3232008-07-10 10:40:53 -03001230 setgain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001231 setbrightness(gspca_dev);
Hans de Goededcef3232008-07-10 10:40:53 -03001232 setexposure(gspca_dev);
Hans de Goede66f35822008-07-16 10:16:28 -03001233 setfreq(gspca_dev);
Hans de Goededcef3232008-07-10 10:40:53 -03001234
Hans de Goede6af492e2008-07-22 07:09:33 -03001235 sd->frames_to_drop = 0;
Hans de Goededcef3232008-07-10 10:40:53 -03001236 sd->autogain_ignore_frames = 0;
Hans de Goede9153ac32012-05-15 04:23:55 -03001237 gspca_dev->exp_too_high_cnt = 0;
1238 gspca_dev->exp_too_low_cnt = 0;
Hans de Goededcef3232008-07-10 10:40:53 -03001239 atomic_set(&sd->avg_lum, -1);
Hans de Goede4848ea72012-05-14 15:21:25 -03001240 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001241}
1242
1243static void sd_stopN(struct gspca_dev *gspca_dev)
1244{
Hans de Goedef45f06b2008-09-03 17:12:21 -03001245 sd_init(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001246}
1247
Hans de Goede2b3e2842010-12-12 08:55:04 -03001248static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001249{
Hans de Goededcef3232008-07-10 10:40:53 -03001250 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede2b3e2842010-12-12 08:55:04 -03001251 int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001252
Hans de Goedec36260ee2008-07-16 09:56:07 -03001253 /* frames start with:
1254 * ff ff 00 c4 c4 96 synchro
1255 * 00 (unknown)
1256 * xx (frame sequence / size / compression)
1257 * (xx) (idem - extra byte for sn9c103)
1258 * ll mm brightness sum inside auto exposure
1259 * ll mm brightness sum outside auto exposure
1260 * (xx xx xx xx xx) audio values for snc103
1261 */
Hans de Goede2b3e2842010-12-12 08:55:04 -03001262 for (i = 0; i < len; i++) {
1263 switch (sd->header_read) {
1264 case 0:
1265 if (data[i] == 0xff)
1266 sd->header_read++;
1267 break;
1268 case 1:
1269 if (data[i] == 0xff)
1270 sd->header_read++;
1271 else
1272 sd->header_read = 0;
1273 break;
1274 case 2:
1275 if (data[i] == 0x00)
1276 sd->header_read++;
1277 else if (data[i] != 0xff)
1278 sd->header_read = 0;
1279 break;
1280 case 3:
1281 if (data[i] == 0xc4)
1282 sd->header_read++;
1283 else if (data[i] == 0xff)
1284 sd->header_read = 1;
1285 else
1286 sd->header_read = 0;
1287 break;
1288 case 4:
1289 if (data[i] == 0xc4)
1290 sd->header_read++;
1291 else if (data[i] == 0xff)
1292 sd->header_read = 1;
1293 else
1294 sd->header_read = 0;
1295 break;
1296 case 5:
1297 if (data[i] == 0x96)
1298 sd->header_read++;
1299 else if (data[i] == 0xff)
1300 sd->header_read = 1;
1301 else
1302 sd->header_read = 0;
1303 break;
1304 default:
1305 sd->header[sd->header_read - 6] = data[i];
1306 sd->header_read++;
1307 if (sd->header_read == header_size) {
1308 sd->header_read = 0;
1309 return data + i + 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001310 }
1311 }
1312 }
Hans de Goede2b3e2842010-12-12 08:55:04 -03001313 return NULL;
1314}
1315
1316static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1317 u8 *data, /* isoc packet */
1318 int len) /* iso packet length */
1319{
1320 int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
1321 struct sd *sd = (struct sd *) gspca_dev;
1322 struct cam *cam = &gspca_dev->cam;
1323 u8 *sof;
1324
1325 sof = find_sof(gspca_dev, data, len);
1326 if (sof) {
1327 if (sd->bridge == BRIDGE_103) {
1328 fr_h_sz = 18;
1329 lum_offset = 3;
1330 } else {
1331 fr_h_sz = 12;
1332 lum_offset = 2;
1333 }
1334
1335 len_after_sof = len - (sof - data);
1336 len = (sof - data) - fr_h_sz;
1337 if (len < 0)
1338 len = 0;
1339 }
Hans de Goedec437d652008-09-03 17:12:22 -03001340
1341 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1342 /* In raw mode we sometimes get some garbage after the frame
1343 ignore this */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001344 int used;
Hans de Goedec437d652008-09-03 17:12:22 -03001345 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1346
Jean-François Moineb192ca92010-06-27 03:08:19 -03001347 used = gspca_dev->image_len;
Hans de Goedec437d652008-09-03 17:12:22 -03001348 if (used + len > size)
1349 len = size - used;
1350 }
1351
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001352 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede2b3e2842010-12-12 08:55:04 -03001353
1354 if (sof) {
1355 int lum = sd->header[lum_offset] +
1356 (sd->header[lum_offset + 1] << 8);
1357
1358 /* When exposure changes midway a frame we
1359 get a lum of 0 in this case drop 2 frames
1360 as the frames directly after an exposure
1361 change have an unstable image. Sometimes lum
1362 *really* is 0 (cam used in low light with
1363 low exposure setting), so do not drop frames
1364 if the previous lum was 0 too. */
1365 if (lum == 0 && sd->prev_avg_lum != 0) {
1366 lum = -1;
1367 sd->frames_to_drop = 2;
1368 sd->prev_avg_lum = 0;
1369 } else
1370 sd->prev_avg_lum = lum;
1371 atomic_set(&sd->avg_lum, lum);
1372
1373 if (sd->frames_to_drop)
1374 sd->frames_to_drop--;
1375 else
1376 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1377
1378 gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
1379 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001380}
1381
Hans de Goede66f35822008-07-16 10:16:28 -03001382static int sd_querymenu(struct gspca_dev *gspca_dev,
1383 struct v4l2_querymenu *menu)
1384{
1385 switch (menu->id) {
1386 case V4L2_CID_POWER_LINE_FREQUENCY:
1387 switch (menu->index) {
1388 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1389 strcpy((char *) menu->name, "NoFliker");
1390 return 0;
1391 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1392 strcpy((char *) menu->name, "50 Hz");
1393 return 0;
1394 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1395 strcpy((char *) menu->name, "60 Hz");
1396 return 0;
1397 }
1398 break;
1399 }
1400 return -EINVAL;
1401}
1402
Jean-François Moine28566432010-10-01 07:33:26 -03001403#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goedef65e93d2010-01-31 10:35:15 -03001404static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1405 u8 *data, /* interrupt packet data */
1406 int len) /* interrupt packet length */
1407{
1408 int ret = -EINVAL;
1409
1410 if (len == 1 && data[0] == 1) {
1411 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1412 input_sync(gspca_dev->input_dev);
1413 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1414 input_sync(gspca_dev->input_dev);
1415 ret = 0;
1416 }
1417
1418 return ret;
1419}
1420#endif
1421
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001422/* sub-driver description */
Hans de Goededcef3232008-07-10 10:40:53 -03001423static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001424 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001425 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001426 .init = sd_init,
Hans de Goede9153ac32012-05-15 04:23:55 -03001427 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001428 .start = sd_start,
1429 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001430 .pkt_scan = sd_pkt_scan,
Hans de Goede66f35822008-07-16 10:16:28 -03001431 .querymenu = sd_querymenu,
Hans de Goedee2ad2a52008-09-03 17:12:15 -03001432 .dq_callback = do_autogain,
Jean-François Moine28566432010-10-01 07:33:26 -03001433#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goedef65e93d2010-01-31 10:35:15 -03001434 .int_pkt_scan = sd_int_pkt_scan,
1435#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001436};
1437
1438/* -- module initialisation -- */
Hans de Goedef45f06b2008-09-03 17:12:21 -03001439#define SB(sensor, bridge) \
1440 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1441
Hans de Goedee2ad2a52008-09-03 17:12:15 -03001442
Jean-François Moine95c967c2011-01-13 05:20:29 -03001443static const struct usb_device_id device_table[] = {
Hans de Goedeb10af3f2010-01-10 19:31:34 -03001444 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1445 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
Hans de Goedeb10af3f2010-01-10 19:31:34 -03001446 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
Hans de Goedef45f06b2008-09-03 17:12:21 -03001447 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1448 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
Hans de Goedef45f06b2008-09-03 17:12:21 -03001449 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
Hans de Goedef45f06b2008-09-03 17:12:21 -03001450 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
Hans de Goede69ffd252011-01-06 11:56:30 -03001451#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Hans de Goedef45f06b2008-09-03 17:12:21 -03001452 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1453 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
Hans de Goede0e4b91c2010-02-10 20:29:43 -03001454#endif
Hans de Goedef72c77a2012-11-04 17:12:10 -03001455 {USB_DEVICE(0x0c45, 0x6027), SB(OV7630, 101)}, /* Genius Eye 310 */
Hans de Goedef45f06b2008-09-03 17:12:21 -03001456 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1457 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
Hans de Goede00765f12010-12-12 15:55:03 -03001458 {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
1459 /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */
Jean-Francois Moine29fbdf32008-11-07 04:53:28 -03001460 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
Hans de Goedef45f06b2008-09-03 17:12:21 -03001461 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
Hans de Goedef45f06b2008-09-03 17:12:21 -03001462 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
Hans de Goede69ffd252011-01-06 11:56:30 -03001463 /* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
1464 /* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */
1465 {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
1466 {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
1467 /* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */
Hans de Goede4cce1652008-09-04 16:22:57 -03001468 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
Hans de Goede69ffd252011-01-06 11:56:30 -03001469 {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
1470 {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
Hans de Goede4cce1652008-09-04 16:22:57 -03001471 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
Hans de Goede4cce1652008-09-04 16:22:57 -03001472 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001473 {}
1474};
1475MODULE_DEVICE_TABLE(usb, device_table);
1476
1477/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03001478static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001479 const struct usb_device_id *id)
1480{
1481 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1482 THIS_MODULE);
1483}
1484
1485static struct usb_driver sd_driver = {
1486 .name = MODULE_NAME,
1487 .id_table = device_table,
1488 .probe = sd_probe,
1489 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001490#ifdef CONFIG_PM
1491 .suspend = gspca_suspend,
1492 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -03001493 .reset_resume = gspca_resume,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001494#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001495};
1496
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001497module_usb_driver(sd_driver);