blob: f006e29ca0197b66ec62dfd821dcb520e24635bf [file] [log] [blame]
Kyle Guinnd661e622009-01-16 05:36:14 -03001/*
2 * Mars MR97310A library
3 *
Theodore Kilgore930bf782009-10-05 05:11:35 -03004 * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
Kyle Guinnd661e622009-01-16 05:36:14 -03005 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
6 *
Theodore Kilgore89f08632009-08-14 06:51:52 -03007 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
8 * and for the routines for detecting and classifying these various cameras,
Theodore Kilgore930bf782009-10-05 05:11:35 -03009 * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
Theodore Kilgore89f08632009-08-14 06:51:52 -030010 *
Theodore Kilgore930bf782009-10-05 05:11:35 -030011 * Support for the control settings for the CIF cameras is
Hans de Goede1fddcf02010-09-05 07:06:04 -030012 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and
Theodore Kilgore930bf782009-10-05 05:11:35 -030013 * Thomas Kaiser <thomas@kaiser-linux.li>
14 *
15 * Support for the control settings for the VGA cameras is
Theodore Kilgore89f08632009-08-14 06:51:52 -030016 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
17 *
Theodore Kilgore930bf782009-10-05 05:11:35 -030018 * Several previously unsupported cameras are owned and have been tested by
Hans de Goede1fddcf02010-09-05 07:06:04 -030019 * Hans de Goede <hdegoede@redhat.com> and
Theodore Kilgore930bf782009-10-05 05:11:35 -030020 * Thomas Kaiser <thomas@kaiser-linux.li> and
Theodore Kilgore1160a382009-10-30 04:29:56 -030021 * Theodore Kilgore <kilgota@auburn.edu> and
22 * Edmond Rodriguez <erodrig_97@yahoo.com> and
23 * Aurelien Jacobs <aurel@gnuage.org>
Theodore Kilgore89f08632009-08-14 06:51:52 -030024 *
25 * The MR97311A support in gspca/mars.c has been helpful in understanding some
26 * of the registers in these cameras.
27 *
Kyle Guinnd661e622009-01-16 05:36:14 -030028 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation; either version 2 of the License, or
31 * any later version.
32 *
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
37 *
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 */
42
Joe Perches133a9fe2011-08-21 19:56:57 -030043#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
44
Kyle Guinnd661e622009-01-16 05:36:14 -030045#define MODULE_NAME "mr97310a"
46
47#include "gspca.h"
48
Theodore Kilgore89f08632009-08-14 06:51:52 -030049#define CAM_TYPE_CIF 0
50#define CAM_TYPE_VGA 1
51
Theodore Kilgore89f08632009-08-14 06:51:52 -030052#define MR97310A_BRIGHTNESS_DEFAULT 0
53
Theodore Kilgore930bf782009-10-05 05:11:35 -030054#define MR97310A_EXPOSURE_MIN 0
Theodore Kilgore89f08632009-08-14 06:51:52 -030055#define MR97310A_EXPOSURE_MAX 4095
56#define MR97310A_EXPOSURE_DEFAULT 1000
57
58#define MR97310A_GAIN_MIN 0
59#define MR97310A_GAIN_MAX 31
60#define MR97310A_GAIN_DEFAULT 25
61
Theodore Kilgore9d3103d2010-02-09 18:05:25 -030062#define MR97310A_CONTRAST_MIN 0
63#define MR97310A_CONTRAST_MAX 31
64#define MR97310A_CONTRAST_DEFAULT 23
65
66#define MR97310A_CS_GAIN_MIN 0
67#define MR97310A_CS_GAIN_MAX 0x7ff
68#define MR97310A_CS_GAIN_DEFAULT 0x110
69
Hans Verkuil3e0ed002012-05-14 09:45:06 -030070#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000)
Hans de Goede065b6f72009-10-29 07:42:30 -030071#define MR97310A_MIN_CLOCKDIV_MIN 3
72#define MR97310A_MIN_CLOCKDIV_MAX 8
73#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
74
Theodore Kilgore89f08632009-08-14 06:51:52 -030075MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
76 "Theodore Kilgore <kilgota@auburn.edu>");
Kyle Guinnd661e622009-01-16 05:36:14 -030077MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
78MODULE_LICENSE("GPL");
79
Hans de Goede78028702009-09-02 09:55:16 -030080/* global parameters */
Jean-Francois Moine83955552009-12-12 06:58:01 -030081static int force_sensor_type = -1;
Hans de Goede78028702009-09-02 09:55:16 -030082module_param(force_sensor_type, int, 0644);
83MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
84
Kyle Guinnd661e622009-01-16 05:36:14 -030085/* specific webcam descriptor */
86struct sd {
87 struct gspca_dev gspca_dev; /* !! must be the first item */
Hans Verkuil3e0ed002012-05-14 09:45:06 -030088 struct { /* exposure/min_clockdiv control cluster */
89 struct v4l2_ctrl *exposure;
90 struct v4l2_ctrl *min_clockdiv;
91 };
Kyle Guinnd661e622009-01-16 05:36:14 -030092 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030093 u8 cam_type; /* 0 is CIF and 1 is VGA */
94 u8 sensor_type; /* We use 0 and 1 here, too. */
95 u8 do_lcd_stop;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -030096 u8 adj_colors;
Kyle Guinnd661e622009-01-16 05:36:14 -030097};
98
Theodore Kilgore89f08632009-08-14 06:51:52 -030099struct sensor_w_data {
100 u8 reg;
101 u8 flags;
102 u8 data[16];
103 int len;
104};
105
Theodore Kilgore930bf782009-10-05 05:11:35 -0300106static void sd_stopN(struct gspca_dev *gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300107
108static const struct v4l2_pix_format vga_mode[] = {
109 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
110 .bytesperline = 160,
111 .sizeimage = 160 * 120,
112 .colorspace = V4L2_COLORSPACE_SRGB,
113 .priv = 4},
114 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
115 .bytesperline = 176,
116 .sizeimage = 176 * 144,
117 .colorspace = V4L2_COLORSPACE_SRGB,
118 .priv = 3},
119 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
120 .bytesperline = 320,
121 .sizeimage = 320 * 240,
122 .colorspace = V4L2_COLORSPACE_SRGB,
123 .priv = 2},
124 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
125 .bytesperline = 352,
126 .sizeimage = 352 * 288,
127 .colorspace = V4L2_COLORSPACE_SRGB,
128 .priv = 1},
129 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
130 .bytesperline = 640,
131 .sizeimage = 640 * 480,
132 .colorspace = V4L2_COLORSPACE_SRGB,
133 .priv = 0},
134};
135
136/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300137static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300138{
139 int rc;
140
141 rc = usb_bulk_msg(gspca_dev->dev,
142 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300143 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300144 if (rc < 0)
Joe Perches133a9fe2011-08-21 19:56:57 -0300145 pr_err("reg write [%02x] error %d\n",
Kyle Guinnd661e622009-01-16 05:36:14 -0300146 gspca_dev->usb_buf[0], rc);
147 return rc;
148}
149
Theodore Kilgore89f08632009-08-14 06:51:52 -0300150/* the bytes are read into gspca_dev->usb_buf */
151static int mr_read(struct gspca_dev *gspca_dev, int len)
152{
153 int rc;
154
155 rc = usb_bulk_msg(gspca_dev->dev,
156 usb_rcvbulkpipe(gspca_dev->dev, 3),
157 gspca_dev->usb_buf, len, NULL, 500);
158 if (rc < 0)
Joe Perches133a9fe2011-08-21 19:56:57 -0300159 pr_err("reg read [%02x] error %d\n",
Theodore Kilgore89f08632009-08-14 06:51:52 -0300160 gspca_dev->usb_buf[0], rc);
161 return rc;
162}
163
164static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
165 const u8 *data, int len)
166{
167 gspca_dev->usb_buf[0] = 0x1f;
168 gspca_dev->usb_buf[1] = flags;
169 gspca_dev->usb_buf[2] = reg;
170 memcpy(gspca_dev->usb_buf + 3, data, len);
171
172 return mr_write(gspca_dev, len + 3);
173}
174
175static int sensor_write_regs(struct gspca_dev *gspca_dev,
176 const struct sensor_w_data *data, int len)
177{
178 int i, rc;
179
180 for (i = 0; i < len; i++) {
181 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
182 data[i].data, data[i].len);
183 if (rc < 0)
184 return rc;
185 }
186
187 return 0;
188}
189
190static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
191{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300192 struct sd *sd = (struct sd *) gspca_dev;
193 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300194 int rc;
195
196 buf = data;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300197 if (sd->cam_type == CAM_TYPE_CIF) {
198 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
199 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
200 } else {
201 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
202 confirm_reg = 0x11;
203 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300204 if (rc < 0)
205 return rc;
206
207 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300208 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300209 if (rc < 0)
210 return rc;
211
212 return 0;
213}
214
Theodore Kilgore930bf782009-10-05 05:11:35 -0300215static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300216{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300217 int err_code;
218
Theodore Kilgore930bf782009-10-05 05:11:35 -0300219 gspca_dev->usb_buf[0] = reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300220 err_code = mr_write(gspca_dev, 1);
221 if (err_code < 0)
222 return err_code;
223
224 err_code = mr_read(gspca_dev, 16);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300225 if (err_code < 0)
226 return err_code;
227
228 if (verbose)
229 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
230 gspca_dev->usb_buf[0],
231 gspca_dev->usb_buf[1],
232 gspca_dev->usb_buf[2]);
233
234 return 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300235}
236
237static int zero_the_pointer(struct gspca_dev *gspca_dev)
238{
239 __u8 *data = gspca_dev->usb_buf;
240 int err_code;
241 u8 status = 0;
242 int tries = 0;
243
Theodore Kilgore930bf782009-10-05 05:11:35 -0300244 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300245 if (err_code < 0)
246 return err_code;
247
Theodore Kilgore89f08632009-08-14 06:51:52 -0300248 data[0] = 0x19;
249 data[1] = 0x51;
250 err_code = mr_write(gspca_dev, 2);
251 if (err_code < 0)
252 return err_code;
253
Theodore Kilgore930bf782009-10-05 05:11:35 -0300254 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300255 if (err_code < 0)
256 return err_code;
257
258 data[0] = 0x19;
259 data[1] = 0xba;
260 err_code = mr_write(gspca_dev, 2);
261 if (err_code < 0)
262 return err_code;
263
Theodore Kilgore930bf782009-10-05 05:11:35 -0300264 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300265 if (err_code < 0)
266 return err_code;
267
268 data[0] = 0x19;
269 data[1] = 0x00;
270 err_code = mr_write(gspca_dev, 2);
271 if (err_code < 0)
272 return err_code;
273
Theodore Kilgore930bf782009-10-05 05:11:35 -0300274 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300275 if (err_code < 0)
276 return err_code;
277
278 data[0] = 0x19;
279 data[1] = 0x00;
280 err_code = mr_write(gspca_dev, 2);
281 if (err_code < 0)
282 return err_code;
283
284 while (status != 0x0a && tries < 256) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300285 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300286 status = data[0];
287 tries++;
288 if (err_code < 0)
289 return err_code;
290 }
Hans de Goede54943782009-08-14 11:05:38 -0300291 if (status != 0x0a)
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300292 PERR("status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300293
294 tries = 0;
295 while (tries < 4) {
296 data[0] = 0x19;
297 data[1] = 0x00;
298 err_code = mr_write(gspca_dev, 2);
299 if (err_code < 0)
300 return err_code;
301
Theodore Kilgore930bf782009-10-05 05:11:35 -0300302 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300303 status = data[0];
304 tries++;
305 if (err_code < 0)
306 return err_code;
307 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300308
309 data[0] = 0x19;
310 err_code = mr_write(gspca_dev, 1);
311 if (err_code < 0)
312 return err_code;
313
314 err_code = mr_read(gspca_dev, 16);
315 if (err_code < 0)
316 return err_code;
317
318 return 0;
319}
320
Theodore Kilgore930bf782009-10-05 05:11:35 -0300321static int stream_start(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300322{
Theodore Kilgore930bf782009-10-05 05:11:35 -0300323 gspca_dev->usb_buf[0] = 0x01;
324 gspca_dev->usb_buf[1] = 0x01;
325 return mr_write(gspca_dev, 2);
326}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300327
Theodore Kilgore930bf782009-10-05 05:11:35 -0300328static void stream_stop(struct gspca_dev *gspca_dev)
329{
330 gspca_dev->usb_buf[0] = 0x01;
331 gspca_dev->usb_buf[1] = 0x00;
332 if (mr_write(gspca_dev, 2) < 0)
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300333 PERR("Stream Stop failed");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300334}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300335
Theodore Kilgore930bf782009-10-05 05:11:35 -0300336static void lcd_stop(struct gspca_dev *gspca_dev)
337{
338 gspca_dev->usb_buf[0] = 0x19;
339 gspca_dev->usb_buf[1] = 0x54;
340 if (mr_write(gspca_dev, 2) < 0)
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300341 PERR("LCD Stop failed");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300342}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300343
Theodore Kilgore930bf782009-10-05 05:11:35 -0300344static int isoc_enable(struct gspca_dev *gspca_dev)
345{
346 gspca_dev->usb_buf[0] = 0x00;
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300347 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300348 return mr_write(gspca_dev, 2);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300349}
350
Theodore Kilgore1160a382009-10-30 04:29:56 -0300351/* This function is called at probe time */
Kyle Guinnd661e622009-01-16 05:36:14 -0300352static int sd_config(struct gspca_dev *gspca_dev,
353 const struct usb_device_id *id)
354{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300355 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300356 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300357 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300358
359 cam = &gspca_dev->cam;
360 cam->cam_mode = vga_mode;
361 cam->nmodes = ARRAY_SIZE(vga_mode);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300362 sd->do_lcd_stop = 0;
363
Theodore Kilgore1160a382009-10-30 04:29:56 -0300364 /* Several of the supported CIF cameras share the same USB ID but
365 * require different initializations and different control settings.
366 * The same is true of the VGA cameras. Therefore, we are forced
367 * to start the initialization process in order to determine which
368 * camera is present. Some of the supported cameras require the
Theodore Kilgore930bf782009-10-05 05:11:35 -0300369 * memory pointer to be set to 0 as the very first item of business
370 * or else they will not stream. So we do that immediately.
371 */
372 err_code = zero_the_pointer(gspca_dev);
373 if (err_code < 0)
374 return err_code;
Hans de Goede9ac69782009-08-14 10:15:52 -0300375
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300376 err_code = stream_start(gspca_dev);
377 if (err_code < 0)
378 return err_code;
379
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300380 /* Now, the query for sensor type. */
381 err_code = cam_get_response16(gspca_dev, 0x07, 1);
382 if (err_code < 0)
383 return err_code;
384
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -0300385 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300386 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300387 cam->nmodes--;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300388 /*
Theodore Kilgore1160a382009-10-30 04:29:56 -0300389 * All but one of the known CIF cameras share the same USB ID,
390 * but two different init routines are in use, and the control
391 * settings are different, too. We need to detect which camera
392 * of the two known varieties is connected!
Theodore Kilgore930bf782009-10-05 05:11:35 -0300393 *
394 * A list of known CIF cameras follows. They all report either
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300395 * 0200 for type 0 or 0300 for type 1.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300396 * If you have another to report, please do
397 *
398 * Name sd->sensor_type reported by
399 *
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300400 * Sakar 56379 Spy-shot 0 T. Kilgore
Theodore Kilgore930bf782009-10-05 05:11:35 -0300401 * Innovage 0 T. Kilgore
402 * Vivitar Mini 0 H. De Goede
403 * Vivitar Mini 0 E. Rodriguez
404 * Vivitar Mini 1 T. Kilgore
405 * Elta-Media 8212dc 1 T. Kaiser
406 * Philips dig. keych. 1 T. Kilgore
Theodore Kilgore1160a382009-10-30 04:29:56 -0300407 * Trust Spyc@m 100 1 A. Jacobs
Theodore Kilgore930bf782009-10-05 05:11:35 -0300408 */
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300409 switch (gspca_dev->usb_buf[0]) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300410 case 2:
411 sd->sensor_type = 0;
412 break;
413 case 3:
414 sd->sensor_type = 1;
415 break;
416 default:
Joe Perches133a9fe2011-08-21 19:56:57 -0300417 pr_err("Unknown CIF Sensor id : %02x\n",
Theodore Kilgore930bf782009-10-05 05:11:35 -0300418 gspca_dev->usb_buf[1]);
419 return -ENODEV;
420 }
421 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
422 sd->sensor_type);
423 } else {
424 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300425
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300426 /*
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300427 * Here is a table of the responses to the query for sensor
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300428 * type, from the known MR97310A VGA cameras. Six different
429 * cameras of which five share the same USB ID.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300430 *
431 * Name gspca_dev->usb_buf[] sd->sensor_type
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300432 * sd->do_lcd_stop
433 * Aiptek Pencam VGA+ 0300 0 1
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300434 * ION digital 0300 0 1
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300435 * Argus DC-1620 0450 1 0
436 * Argus QuickClix 0420 1 1
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300437 * Sakar 77379 Digital 0350 0 1
438 * Sakar 1638x CyberPix 0120 0 2
Theodore Kilgore930bf782009-10-05 05:11:35 -0300439 *
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300440 * Based upon these results, we assume default settings
441 * and then correct as necessary, as follows.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300442 *
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300443 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300444
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300445 sd->sensor_type = 1;
446 sd->do_lcd_stop = 0;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300447 sd->adj_colors = 0;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300448 if (gspca_dev->usb_buf[0] == 0x01) {
449 sd->sensor_type = 2;
450 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300451 (gspca_dev->usb_buf[0] != 0x04)) {
Joe Perches133a9fe2011-08-21 19:56:57 -0300452 pr_err("Unknown VGA Sensor id Byte 0: %02x\n",
453 gspca_dev->usb_buf[0]);
454 pr_err("Defaults assumed, may not work\n");
455 pr_err("Please report this\n");
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300456 }
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300457 /* Sakar Digital color needs to be adjusted. */
458 if ((gspca_dev->usb_buf[0] == 0x03) &&
459 (gspca_dev->usb_buf[1] == 0x50))
460 sd->adj_colors = 1;
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300461 if (gspca_dev->usb_buf[0] == 0x04) {
462 sd->do_lcd_stop = 1;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300463 switch (gspca_dev->usb_buf[1]) {
464 case 0x50:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300465 sd->sensor_type = 0;
466 PDEBUG(D_PROBE, "sensor_type corrected to 0");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300467 break;
468 case 0x20:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300469 /* Nothing to do here. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300470 break;
471 default:
Joe Perches133a9fe2011-08-21 19:56:57 -0300472 pr_err("Unknown VGA Sensor id Byte 1: %02x\n",
473 gspca_dev->usb_buf[1]);
474 pr_err("Defaults assumed, may not work\n");
475 pr_err("Please report this\n");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300476 }
Hans de Goede78028702009-09-02 09:55:16 -0300477 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300478 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
479 sd->sensor_type);
480 }
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300481 /* Stop streaming as we've started it only to probe the sensor type. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300482 sd_stopN(gspca_dev);
Hans de Goede78028702009-09-02 09:55:16 -0300483
Theodore Kilgore930bf782009-10-05 05:11:35 -0300484 if (force_sensor_type != -1) {
485 sd->sensor_type = !!force_sensor_type;
486 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
487 sd->sensor_type);
488 }
489
Kyle Guinnd661e622009-01-16 05:36:14 -0300490 return 0;
491}
492
493/* this function is called at probe and resume time */
494static int sd_init(struct gspca_dev *gspca_dev)
495{
496 return 0;
497}
498
Theodore Kilgore89f08632009-08-14 06:51:52 -0300499static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300500{
501 struct sd *sd = (struct sd *) gspca_dev;
502 __u8 *data = gspca_dev->usb_buf;
503 int err_code;
Jean-François Moine294d8b42010-10-01 07:37:15 -0300504 static const __u8 startup_string[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300505 0x00,
506 0x0d,
507 0x01,
508 0x00, /* Hsize/8 for 352 or 320 */
509 0x00, /* Vsize/4 for 288 or 240 */
510 0x13, /* or 0xbb, depends on sensor */
511 0x00, /* Hstart, depends on res. */
512 0x00, /* reserved ? */
513 0x00, /* Vstart, depends on res. and sensor */
514 0x50, /* 0x54 to get 176 or 160 */
515 0xc0
516 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300517
Theodore Kilgore89f08632009-08-14 06:51:52 -0300518 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300519
Theodore Kilgore89f08632009-08-14 06:51:52 -0300520 memcpy(data, startup_string, 11);
521 if (sd->sensor_type)
522 data[5] = 0xbb;
523
Ondrej Zary1966bc22013-08-30 17:54:23 -0300524 switch (gspca_dev->pixfmt.width) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300525 case 160:
526 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
527 /* fall thru */
528 case 320:
529 default:
530 data[3] = 0x28; /* reg 2, H size/8 */
531 data[4] = 0x3c; /* reg 3, V size/4 */
532 data[6] = 0x14; /* reg 5, H start */
533 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
534 break;
535 case 176:
536 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
537 /* fall thru */
538 case 352:
539 data[3] = 0x2c; /* reg 2, H size/8 */
540 data[4] = 0x48; /* reg 3, V size/4 */
541 data[6] = 0x06; /* reg 5, H start */
Theodore Kilgore32345b02009-11-01 12:59:42 -0300542 data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300543 break;
544 }
545 err_code = mr_write(gspca_dev, 11);
546 if (err_code < 0)
547 return err_code;
548
549 if (!sd->sensor_type) {
Jean-François Moine294d8b42010-10-01 07:37:15 -0300550 static const struct sensor_w_data cif_sensor0_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300551 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
552 0x0f, 0x14, 0x0f, 0x10}, 8},
553 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
554 {0x12, 0x00, {0x07}, 1},
555 {0x1f, 0x00, {0x06}, 1},
556 {0x27, 0x00, {0x04}, 1},
557 {0x29, 0x00, {0x0c}, 1},
558 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
559 {0x50, 0x00, {0x60}, 1},
560 {0x60, 0x00, {0x06}, 1},
561 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
562 {0x72, 0x00, {0x1e, 0x56}, 2},
563 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
564 0x31, 0x80, 0x00}, 9},
565 {0x11, 0x00, {0x01}, 1},
566 {0, 0, {0}, 0}
567 };
568 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
569 ARRAY_SIZE(cif_sensor0_init_data));
570 } else { /* sd->sensor_type = 1 */
Jean-François Moine294d8b42010-10-01 07:37:15 -0300571 static const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300572 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300573 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300574 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
575 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300576 {0x09, 0x02, {0x0e}, 1},
577 {0x0a, 0x02, {0x05}, 1},
578 {0x0b, 0x02, {0x05}, 1},
579 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300580 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300581 {0x0e, 0x02, {0x0c}, 1},
582 {0x0f, 0x00, {0x00}, 1},
583 {0x10, 0x00, {0x06}, 1},
584 {0x11, 0x00, {0x07}, 1},
585 {0x12, 0x00, {0x00}, 1},
586 {0x13, 0x00, {0x01}, 1},
587 {0, 0, {0}, 0}
588 };
Theodore Kilgore70136082009-12-25 05:15:10 -0300589 /* Without this command the cam won't work with USB-UHCI */
590 gspca_dev->usb_buf[0] = 0x0a;
591 gspca_dev->usb_buf[1] = 0x00;
592 err_code = mr_write(gspca_dev, 2);
593 if (err_code < 0)
594 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300595 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
596 ARRAY_SIZE(cif_sensor1_init_data));
597 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300598 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300599}
600
601static int start_vga_cam(struct gspca_dev *gspca_dev)
602{
603 struct sd *sd = (struct sd *) gspca_dev;
604 __u8 *data = gspca_dev->usb_buf;
605 int err_code;
Jean-François Moine294d8b42010-10-01 07:37:15 -0300606 static const __u8 startup_string[] =
607 {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00,
608 0x00, 0x50, 0xc0};
Theodore Kilgore89f08632009-08-14 06:51:52 -0300609 /* What some of these mean is explained in start_cif_cam(), above */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300610
Theodore Kilgore89f08632009-08-14 06:51:52 -0300611 memcpy(data, startup_string, 11);
612 if (!sd->sensor_type) {
613 data[5] = 0x00;
614 data[10] = 0x91;
615 }
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300616 if (sd->sensor_type == 2) {
617 data[5] = 0x00;
618 data[10] = 0x18;
619 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300620
Ondrej Zary1966bc22013-08-30 17:54:23 -0300621 switch (gspca_dev->pixfmt.width) {
Kyle Guinnd661e622009-01-16 05:36:14 -0300622 case 160:
623 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
624 /* fall thru */
625 case 320:
626 data[9] |= 0x04; /* reg 8, 2:1 scale down */
627 /* fall thru */
628 case 640:
629 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300630 data[3] = 0x50; /* reg 2, H size/8 */
631 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300632 data[6] = 0x04; /* reg 5, H start */
633 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300634 if (sd->sensor_type == 2) {
635 data[6] = 2;
636 data[8] = 1;
637 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300638 if (sd->do_lcd_stop)
639 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300640 break;
641
642 case 176:
643 data[9] |= 0x04; /* reg 8, 2:1 scale down */
644 /* fall thru */
645 case 352:
646 data[3] = 0x2c; /* reg 2, H size */
647 data[4] = 0x48; /* reg 3, V size */
648 data[6] = 0x94; /* reg 5, H start */
649 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300650 if (sd->do_lcd_stop)
651 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300652 break;
653 }
654
Theodore Kilgore89f08632009-08-14 06:51:52 -0300655 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300656 if (err_code < 0)
657 return err_code;
658
Theodore Kilgore89f08632009-08-14 06:51:52 -0300659 if (!sd->sensor_type) {
Jean-François Moine294d8b42010-10-01 07:37:15 -0300660 static const struct sensor_w_data vga_sensor0_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300661 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
662 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
663 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
664 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
665 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
666 {0, 0, {0}, 0}
667 };
668 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
669 ARRAY_SIZE(vga_sensor0_init_data));
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300670 } else if (sd->sensor_type == 1) {
Jean-François Moine294d8b42010-10-01 07:37:15 -0300671 static const struct sensor_w_data color_adj[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300672 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300673 /* adjusted blue, green, red gain correct
674 too much blue from the Sakar Digital */
Theodore Kilgoreb31210d2009-11-01 13:02:59 -0300675 0x05, 0x01, 0x04}, 8}
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300676 };
677
Jean-François Moine294d8b42010-10-01 07:37:15 -0300678 static const struct sensor_w_data color_no_adj[] = {
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300679 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
680 /* default blue, green, red gain settings */
681 0x07, 0x00, 0x01}, 8}
682 };
683
Jean-François Moine294d8b42010-10-01 07:37:15 -0300684 static const struct sensor_w_data vga_sensor1_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300685 {0x11, 0x04, {0x01}, 1},
Theodore Kilgore542821d2009-11-01 13:09:15 -0300686 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
687 /* These settings may be better for some cameras */
688 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300689 0x00, 0x0a}, 7},
690 {0x11, 0x04, {0x01}, 1},
691 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
692 {0x11, 0x04, {0x01}, 1},
693 {0, 0, {0}, 0}
694 };
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300695
696 if (sd->adj_colors)
697 err_code = sensor_write_regs(gspca_dev, color_adj,
698 ARRAY_SIZE(color_adj));
699 else
700 err_code = sensor_write_regs(gspca_dev, color_no_adj,
701 ARRAY_SIZE(color_no_adj));
702
703 if (err_code < 0)
704 return err_code;
705
Theodore Kilgore89f08632009-08-14 06:51:52 -0300706 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
707 ARRAY_SIZE(vga_sensor1_init_data));
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300708 } else { /* sensor type == 2 */
Jean-François Moine294d8b42010-10-01 07:37:15 -0300709 static const struct sensor_w_data vga_sensor2_init_data[] = {
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300710
711 {0x01, 0x00, {0x48}, 1},
712 {0x02, 0x00, {0x22}, 1},
713 /* Reg 3 msb and 4 is lsb of the exposure setting*/
714 {0x05, 0x00, {0x10}, 1},
715 {0x06, 0x00, {0x00}, 1},
716 {0x07, 0x00, {0x00}, 1},
717 {0x08, 0x00, {0x00}, 1},
718 {0x09, 0x00, {0x00}, 1},
719 /* The following are used in the gain control
720 * which is BTW completely borked in the OEM driver
721 * The values for each color go from 0 to 0x7ff
722 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
723 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
724 *{0x0c, 0x00, {0x01}, 1}, red gain msb
725 *{0x0d, 0x00, {0x10}, 1}, red gain lsb
726 *{0x0e, 0x00, {0x01}, 1}, blue gain msb
727 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
728 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
729 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
730 */
731 {0x12, 0x00, {0x00}, 1},
732 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
733 {0x14, 0x00, {0x00}, 1},
734 {0x15, 0x00, {0x06}, 1},
735 {0x16, 0x00, {0x01}, 1},
736 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
737 {0x18, 0x00, {0x02}, 1},
738 {0x19, 0x00, {0x82}, 1}, /* don't mess with */
739 {0x1a, 0x00, {0x00}, 1},
740 {0x1b, 0x00, {0x20}, 1},
741 /* {0x1c, 0x00, {0x17}, 1}, contrast control */
742 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
743 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
744 {0x1f, 0x00, {0x0c}, 1},
745 {0x20, 0x00, {0x00}, 1},
746 {0, 0, {0}, 0}
747 };
748 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
749 ARRAY_SIZE(vga_sensor2_init_data));
Theodore Kilgore89f08632009-08-14 06:51:52 -0300750 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300751 return err_code;
752}
753
754static int sd_start(struct gspca_dev *gspca_dev)
755{
756 struct sd *sd = (struct sd *) gspca_dev;
757 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300758
Theodore Kilgore89f08632009-08-14 06:51:52 -0300759 sd->sof_read = 0;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300760
761 /* Some of the VGA cameras require the memory pointer
762 * to be set to 0 again. We have been forced to start the
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300763 * stream in sd_config() to detect the hardware, and closed it.
764 * Thus, we need here to do a completely fresh and clean start. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300765 err_code = zero_the_pointer(gspca_dev);
766 if (err_code < 0)
767 return err_code;
768
769 err_code = stream_start(gspca_dev);
770 if (err_code < 0)
771 return err_code;
772
Theodore Kilgore89f08632009-08-14 06:51:52 -0300773 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300774 err_code = start_cif_cam(gspca_dev);
775 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300776 err_code = start_vga_cam(gspca_dev);
777 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300778 if (err_code < 0)
779 return err_code;
780
Theodore Kilgore930bf782009-10-05 05:11:35 -0300781 return isoc_enable(gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300782}
783
784static void sd_stopN(struct gspca_dev *gspca_dev)
785{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300786 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300787
Theodore Kilgore930bf782009-10-05 05:11:35 -0300788 stream_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300789 /* Not all the cams need this, but even if not, probably a good idea */
790 zero_the_pointer(gspca_dev);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300791 if (sd->do_lcd_stop)
792 lcd_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300793}
794
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300795static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300796{
797 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300798 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
799 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
Jean-François Moine294d8b42010-10-01 07:37:15 -0300800 static const u8 quick_clix_table[] =
Theodore Kilgore930bf782009-10-05 05:11:35 -0300801 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
802 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
Theodore Kilgore930bf782009-10-05 05:11:35 -0300803 if (sd->cam_type == CAM_TYPE_VGA) {
804 sign_reg += 4;
805 value_reg += 4;
806 }
807
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300808 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300809 if (val > 0) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300810 sensor_write1(gspca_dev, sign_reg, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300811 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300812 sensor_write1(gspca_dev, sign_reg, 0x01);
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300813 val = 257 - val;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300814 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300815 /* Use lookup table for funky Argus QuickClix brightness */
816 if (sd->do_lcd_stop)
817 val = quick_clix_table[val];
818
819 sensor_write1(gspca_dev, value_reg, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300820}
821
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300822static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300823{
824 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300825 int exposure = MR97310A_EXPOSURE_DEFAULT;
Hans de Goede065b6f72009-10-29 07:42:30 -0300826 u8 buf[2];
Theodore Kilgore89f08632009-08-14 06:51:52 -0300827
Theodore Kilgore930bf782009-10-05 05:11:35 -0300828 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300829 /* This cam does not like exposure settings < 300,
Hans de Goeded76f9752009-10-11 05:22:29 -0300830 so scale 0 - 4095 to 300 - 4095 */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300831 exposure = (expo * 9267) / 10000 + 300;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300832 sensor_write1(gspca_dev, 3, exposure >> 4);
833 sensor_write1(gspca_dev, 4, exposure & 0x0f);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300834 } else if (sd->sensor_type == 2) {
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300835 exposure = expo;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300836 exposure >>= 3;
837 sensor_write1(gspca_dev, 3, exposure >> 8);
838 sensor_write1(gspca_dev, 4, exposure & 0xff);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300839 } else {
Hans de Goedea2e081b2009-08-14 17:11:36 -0300840 /* We have both a clock divider and an exposure register.
841 We first calculate the clock divider, as that determines
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300842 the maximum exposure and then we calculate the exposure
Hans de Goedea2e081b2009-08-14 17:11:36 -0300843 register setting (which goes from 0 - 511).
844
845 Note our 0 - 4095 exposure is mapped to 0 - 511
846 milliseconds exposure time */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300847 u8 clockdiv = (60 * expo + 7999) / 8000;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300848
849 /* Limit framerate to not exceed usb bandwidth */
Ondrej Zary1966bc22013-08-30 17:54:23 -0300850 if (clockdiv < min_clockdiv && gspca_dev->pixfmt.width >= 320)
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300851 clockdiv = min_clockdiv;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300852 else if (clockdiv < 2)
853 clockdiv = 2;
854
Theodore Kilgore930bf782009-10-05 05:11:35 -0300855 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
856 clockdiv = 4;
857
Hans de Goedea2e081b2009-08-14 17:11:36 -0300858 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
859 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300860 exposure = (60 * 511 * expo) / (8000 * clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300861 if (exposure > 511)
862 exposure = 511;
863
864 /* exposure register value is reversed! */
865 exposure = 511 - exposure;
866
Hans de Goede065b6f72009-10-29 07:42:30 -0300867 buf[0] = exposure & 0xff;
868 buf[1] = exposure >> 8;
869 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300870 sensor_write1(gspca_dev, 0x02, clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300871 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300872}
873
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300874static void setgain(struct gspca_dev *gspca_dev, s32 val)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300875{
876 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300877 u8 gainreg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300878
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300879 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300880 sensor_write1(gspca_dev, 0x0e, val);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300881 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
882 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300883 sensor_write1(gspca_dev, gainreg, val >> 8);
884 sensor_write1(gspca_dev, gainreg + 1, val & 0xff);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300885 }
886 else
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300887 sensor_write1(gspca_dev, 0x10, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300888}
889
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300890static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300891{
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300892 sensor_write1(gspca_dev, 0x1c, val);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300893}
894
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300895static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300896{
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300897 struct gspca_dev *gspca_dev =
898 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
899 struct sd *sd = (struct sd *)gspca_dev;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300900
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300901 gspca_dev->usb_err = 0;
902
903 if (!gspca_dev->streaming)
904 return 0;
905
906 switch (ctrl->id) {
907 case V4L2_CID_BRIGHTNESS:
908 setbrightness(gspca_dev, ctrl->val);
909 break;
910 case V4L2_CID_CONTRAST:
911 setcontrast(gspca_dev, ctrl->val);
912 break;
913 case V4L2_CID_EXPOSURE:
914 setexposure(gspca_dev, sd->exposure->val,
915 sd->min_clockdiv ? sd->min_clockdiv->val : 0);
916 break;
917 case V4L2_CID_GAIN:
918 setgain(gspca_dev, ctrl->val);
919 break;
920 }
921 return gspca_dev->usb_err;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300922}
923
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300924static const struct v4l2_ctrl_ops sd_ctrl_ops = {
925 .s_ctrl = sd_s_ctrl,
926};
927
928static int sd_init_controls(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300929{
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300930 struct sd *sd = (struct sd *)gspca_dev;
931 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
932 static const struct v4l2_ctrl_config clockdiv = {
933 .ops = &sd_ctrl_ops,
934 .id = MR97310A_CID_CLOCKDIV,
935 .type = V4L2_CTRL_TYPE_INTEGER,
936 .name = "Minimum Clock Divider",
937 .min = MR97310A_MIN_CLOCKDIV_MIN,
938 .max = MR97310A_MIN_CLOCKDIV_MAX,
939 .step = 1,
940 .def = MR97310A_MIN_CLOCKDIV_DEFAULT,
941 };
942 bool has_brightness = false;
943 bool has_argus_brightness = false;
944 bool has_contrast = false;
945 bool has_gain = false;
946 bool has_cs_gain = false;
947 bool has_exposure = false;
948 bool has_clockdiv = false;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300949
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300950 gspca_dev->vdev.ctrl_handler = hdl;
951 v4l2_ctrl_handler_init(hdl, 4);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300952
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300953 /* Setup controls depending on camera type */
954 if (sd->cam_type == CAM_TYPE_CIF) {
955 /* No brightness for sensor_type 0 */
956 if (sd->sensor_type == 0)
957 has_exposure = has_gain = has_clockdiv = true;
958 else
959 has_exposure = has_gain = has_brightness = true;
960 } else {
961 /* All controls need to be disabled if VGA sensor_type is 0 */
962 if (sd->sensor_type == 0)
963 ; /* no controls! */
964 else if (sd->sensor_type == 2)
965 has_exposure = has_cs_gain = has_contrast = true;
966 else if (sd->do_lcd_stop)
967 has_exposure = has_gain = has_argus_brightness =
968 has_clockdiv = true;
969 else
970 has_exposure = has_gain = has_brightness =
971 has_clockdiv = true;
972 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300973
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300974 /* Separate brightness control description for Argus QuickClix as it has
975 * different limits from the other mr97310a cameras, and separate gain
976 * control for Sakar CyberPix camera. */
977 /*
978 * This control is disabled for CIF type 1 and VGA type 0 cameras.
979 * It does not quite act linearly for the Argus QuickClix camera,
980 * but it does control brightness. The values are 0 - 15 only, and
981 * the table above makes them act consecutively.
982 */
983 if (has_brightness)
984 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
985 V4L2_CID_BRIGHTNESS, -254, 255, 1,
986 MR97310A_BRIGHTNESS_DEFAULT);
987 else if (has_argus_brightness)
988 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
989 V4L2_CID_BRIGHTNESS, 0, 15, 1,
990 MR97310A_BRIGHTNESS_DEFAULT);
991 if (has_contrast)
992 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
993 V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN,
994 MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT);
995 if (has_gain)
996 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
997 V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX,
998 1, MR97310A_GAIN_DEFAULT);
999 else if (has_cs_gain)
1000 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN,
1001 MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX,
1002 1, MR97310A_CS_GAIN_DEFAULT);
1003 if (has_exposure)
1004 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1005 V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN,
1006 MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT);
1007 if (has_clockdiv)
1008 sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL);
Theodore Kilgore89f08632009-08-14 06:51:52 -03001009
Hans Verkuil3e0ed002012-05-14 09:45:06 -03001010 if (hdl->error) {
1011 pr_err("Could not initialize controls\n");
1012 return hdl->error;
1013 }
1014 if (has_exposure && has_clockdiv)
1015 v4l2_ctrl_cluster(2, &sd->exposure);
Hans de Goede065b6f72009-10-29 07:42:30 -03001016 return 0;
1017}
1018
Kyle Guinnd661e622009-01-16 05:36:14 -03001019/* Include pac common sof detection functions */
1020#include "pac_common.h"
1021
1022static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001023 u8 *data, /* isoc packet */
1024 int len) /* iso packet length */
Kyle Guinnd661e622009-01-16 05:36:14 -03001025{
Marton Nemetha6b69e42009-11-02 08:05:51 -03001026 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -03001027 unsigned char *sof;
1028
Theodore Kilgorec93396e2013-02-04 13:17:55 -03001029 sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001030 if (sof) {
1031 int n;
1032
1033 /* finish decoding current frame */
1034 n = sof - data;
1035 if (n > sizeof pac_sof_marker)
1036 n -= sizeof pac_sof_marker;
1037 else
1038 n = 0;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001039 gspca_frame_add(gspca_dev, LAST_PACKET,
Kyle Guinnd661e622009-01-16 05:36:14 -03001040 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -03001041 /* Start next frame. */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001042 gspca_frame_add(gspca_dev, FIRST_PACKET,
Theodore Kilgore9832d762009-03-13 13:04:31 -03001043 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -03001044 len -= sof - data;
1045 data = sof;
1046 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001047 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001048}
1049
1050/* sub-driver description */
1051static const struct sd_desc sd_desc = {
1052 .name = MODULE_NAME,
Kyle Guinnd661e622009-01-16 05:36:14 -03001053 .config = sd_config,
1054 .init = sd_init,
Hans Verkuil3e0ed002012-05-14 09:45:06 -03001055 .init_controls = sd_init_controls,
Kyle Guinnd661e622009-01-16 05:36:14 -03001056 .start = sd_start,
1057 .stopN = sd_stopN,
1058 .pkt_scan = sd_pkt_scan,
1059};
1060
1061/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03001062static const struct usb_device_id device_table[] = {
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -03001063 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
Theodore Kilgore89f08632009-08-14 06:51:52 -03001064 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
1065 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
1066 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -03001067 {}
1068};
1069MODULE_DEVICE_TABLE(usb, device_table);
1070
1071/* -- device connect -- */
1072static int sd_probe(struct usb_interface *intf,
1073 const struct usb_device_id *id)
1074{
1075 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1076 THIS_MODULE);
1077}
1078
1079static struct usb_driver sd_driver = {
1080 .name = MODULE_NAME,
1081 .id_table = device_table,
1082 .probe = sd_probe,
1083 .disconnect = gspca_disconnect,
1084#ifdef CONFIG_PM
1085 .suspend = gspca_suspend,
1086 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -03001087 .reset_resume = gspca_resume,
Kyle Guinnd661e622009-01-16 05:36:14 -03001088#endif
1089};
1090
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001091module_usb_driver(sd_driver);