blob: 33744e724eaa8b41251bff7d0a4bd512b0de97a3 [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
12 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
13 * 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
19 * Hans de Goede <hdgoede@redhat.com> and
20 * 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
43#define MODULE_NAME "mr97310a"
44
45#include "gspca.h"
46
Theodore Kilgore89f08632009-08-14 06:51:52 -030047#define CAM_TYPE_CIF 0
48#define CAM_TYPE_VGA 1
49
Theodore Kilgore89f08632009-08-14 06:51:52 -030050#define MR97310A_BRIGHTNESS_DEFAULT 0
51
Theodore Kilgore930bf782009-10-05 05:11:35 -030052#define MR97310A_EXPOSURE_MIN 0
Theodore Kilgore89f08632009-08-14 06:51:52 -030053#define MR97310A_EXPOSURE_MAX 4095
54#define MR97310A_EXPOSURE_DEFAULT 1000
55
56#define MR97310A_GAIN_MIN 0
57#define MR97310A_GAIN_MAX 31
58#define MR97310A_GAIN_DEFAULT 25
59
Theodore Kilgore9d3103d2010-02-09 18:05:25 -030060#define MR97310A_CONTRAST_MIN 0
61#define MR97310A_CONTRAST_MAX 31
62#define MR97310A_CONTRAST_DEFAULT 23
63
64#define MR97310A_CS_GAIN_MIN 0
65#define MR97310A_CS_GAIN_MAX 0x7ff
66#define MR97310A_CS_GAIN_DEFAULT 0x110
67
Hans de Goede065b6f72009-10-29 07:42:30 -030068#define MR97310A_MIN_CLOCKDIV_MIN 3
69#define MR97310A_MIN_CLOCKDIV_MAX 8
70#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
71
Theodore Kilgore89f08632009-08-14 06:51:52 -030072MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
73 "Theodore Kilgore <kilgota@auburn.edu>");
Kyle Guinnd661e622009-01-16 05:36:14 -030074MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
75MODULE_LICENSE("GPL");
76
Hans de Goede78028702009-09-02 09:55:16 -030077/* global parameters */
Jean-Francois Moine83955552009-12-12 06:58:01 -030078static int force_sensor_type = -1;
Hans de Goede78028702009-09-02 09:55:16 -030079module_param(force_sensor_type, int, 0644);
80MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
81
Kyle Guinnd661e622009-01-16 05:36:14 -030082/* specific webcam descriptor */
83struct sd {
84 struct gspca_dev gspca_dev; /* !! must be the first item */
Kyle Guinnd661e622009-01-16 05:36:14 -030085 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030086 u8 cam_type; /* 0 is CIF and 1 is VGA */
87 u8 sensor_type; /* We use 0 and 1 here, too. */
88 u8 do_lcd_stop;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -030089 u8 adj_colors;
Theodore Kilgore89f08632009-08-14 06:51:52 -030090
91 int brightness;
92 u16 exposure;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -030093 u32 gain;
94 u8 contrast;
Hans de Goede065b6f72009-10-29 07:42:30 -030095 u8 min_clockdiv;
Kyle Guinnd661e622009-01-16 05:36:14 -030096};
97
Theodore Kilgore89f08632009-08-14 06:51:52 -030098struct sensor_w_data {
99 u8 reg;
100 u8 flags;
101 u8 data[16];
102 int len;
103};
104
Theodore Kilgore930bf782009-10-05 05:11:35 -0300105static void sd_stopN(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300106static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
108static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
109static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300110static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300112static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
113static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede065b6f72009-10-29 07:42:30 -0300114static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
115static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede9ac69782009-08-14 10:15:52 -0300116static void setbrightness(struct gspca_dev *gspca_dev);
117static void setexposure(struct gspca_dev *gspca_dev);
118static void setgain(struct gspca_dev *gspca_dev);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300119static void setcontrast(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300120
Kyle Guinnd661e622009-01-16 05:36:14 -0300121/* V4L2 controls supported by the driver */
Marton Nemeth7e64dc42009-12-30 09:12:41 -0300122static const struct ctrl sd_ctrls[] = {
Theodore Kilgore1160a382009-10-30 04:29:56 -0300123/* Separate brightness control description for Argus QuickClix as it has
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300124 * different limits from the other mr97310a cameras, and separate gain
125 * control for Sakar CyberPix camera. */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300126 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300127#define NORM_BRIGHTNESS_IDX 0
Theodore Kilgore89f08632009-08-14 06:51:52 -0300128 {
129 .id = V4L2_CID_BRIGHTNESS,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Brightness",
Theodore Kilgore930bf782009-10-05 05:11:35 -0300132 .minimum = -254,
133 .maximum = 255,
Theodore Kilgore89f08632009-08-14 06:51:52 -0300134 .step = 1,
135 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
136 .flags = 0,
137 },
138 .set = sd_setbrightness,
139 .get = sd_getbrightness,
140 },
141 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300142#define ARGUS_QC_BRIGHTNESS_IDX 1
143 {
144 .id = V4L2_CID_BRIGHTNESS,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Brightness",
147 .minimum = 0,
148 .maximum = 15,
149 .step = 1,
150 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
151 .flags = 0,
152 },
153 .set = sd_setbrightness,
154 .get = sd_getbrightness,
155 },
156 {
157#define EXPOSURE_IDX 2
Theodore Kilgore89f08632009-08-14 06:51:52 -0300158 {
159 .id = V4L2_CID_EXPOSURE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Exposure",
162 .minimum = MR97310A_EXPOSURE_MIN,
163 .maximum = MR97310A_EXPOSURE_MAX,
164 .step = 1,
165 .default_value = MR97310A_EXPOSURE_DEFAULT,
166 .flags = 0,
167 },
168 .set = sd_setexposure,
169 .get = sd_getexposure,
170 },
171 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300172#define GAIN_IDX 3
Theodore Kilgore89f08632009-08-14 06:51:52 -0300173 {
174 .id = V4L2_CID_GAIN,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Gain",
177 .minimum = MR97310A_GAIN_MIN,
178 .maximum = MR97310A_GAIN_MAX,
179 .step = 1,
180 .default_value = MR97310A_GAIN_DEFAULT,
181 .flags = 0,
182 },
183 .set = sd_setgain,
184 .get = sd_getgain,
185 },
Hans de Goede065b6f72009-10-29 07:42:30 -0300186 {
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300187#define SAKAR_CS_GAIN_IDX 4
188 {
189 .id = V4L2_CID_GAIN,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Gain",
192 .minimum = MR97310A_CS_GAIN_MIN,
193 .maximum = MR97310A_CS_GAIN_MAX,
194 .step = 1,
195 .default_value = MR97310A_CS_GAIN_DEFAULT,
196 .flags = 0,
197 },
198 .set = sd_setgain,
199 .get = sd_getgain,
200 },
201 {
202#define CONTRAST_IDX 5
203 {
204 .id = V4L2_CID_CONTRAST,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Contrast",
207 .minimum = MR97310A_CONTRAST_MIN,
208 .maximum = MR97310A_CONTRAST_MAX,
209 .step = 1,
210 .default_value = MR97310A_CONTRAST_DEFAULT,
211 .flags = 0,
212 },
213 .set = sd_setcontrast,
214 .get = sd_getcontrast,
215 },
216 {
217#define MIN_CLOCKDIV_IDX 6
Hans de Goede065b6f72009-10-29 07:42:30 -0300218 {
219 .id = V4L2_CID_PRIVATE_BASE,
220 .type = V4L2_CTRL_TYPE_INTEGER,
221 .name = "Minimum Clock Divider",
222 .minimum = MR97310A_MIN_CLOCKDIV_MIN,
223 .maximum = MR97310A_MIN_CLOCKDIV_MAX,
224 .step = 1,
225 .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
226 .flags = 0,
227 },
228 .set = sd_setmin_clockdiv,
229 .get = sd_getmin_clockdiv,
230 },
Kyle Guinnd661e622009-01-16 05:36:14 -0300231};
232
233static const struct v4l2_pix_format vga_mode[] = {
234 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
235 .bytesperline = 160,
236 .sizeimage = 160 * 120,
237 .colorspace = V4L2_COLORSPACE_SRGB,
238 .priv = 4},
239 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
240 .bytesperline = 176,
241 .sizeimage = 176 * 144,
242 .colorspace = V4L2_COLORSPACE_SRGB,
243 .priv = 3},
244 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
245 .bytesperline = 320,
246 .sizeimage = 320 * 240,
247 .colorspace = V4L2_COLORSPACE_SRGB,
248 .priv = 2},
249 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
250 .bytesperline = 352,
251 .sizeimage = 352 * 288,
252 .colorspace = V4L2_COLORSPACE_SRGB,
253 .priv = 1},
254 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
255 .bytesperline = 640,
256 .sizeimage = 640 * 480,
257 .colorspace = V4L2_COLORSPACE_SRGB,
258 .priv = 0},
259};
260
261/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300262static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300263{
264 int rc;
265
266 rc = usb_bulk_msg(gspca_dev->dev,
267 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300268 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300269 if (rc < 0)
270 PDEBUG(D_ERR, "reg write [%02x] error %d",
271 gspca_dev->usb_buf[0], rc);
272 return rc;
273}
274
Theodore Kilgore89f08632009-08-14 06:51:52 -0300275/* the bytes are read into gspca_dev->usb_buf */
276static int mr_read(struct gspca_dev *gspca_dev, int len)
277{
278 int rc;
279
280 rc = usb_bulk_msg(gspca_dev->dev,
281 usb_rcvbulkpipe(gspca_dev->dev, 3),
282 gspca_dev->usb_buf, len, NULL, 500);
283 if (rc < 0)
284 PDEBUG(D_ERR, "reg read [%02x] error %d",
285 gspca_dev->usb_buf[0], rc);
286 return rc;
287}
288
289static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
290 const u8 *data, int len)
291{
292 gspca_dev->usb_buf[0] = 0x1f;
293 gspca_dev->usb_buf[1] = flags;
294 gspca_dev->usb_buf[2] = reg;
295 memcpy(gspca_dev->usb_buf + 3, data, len);
296
297 return mr_write(gspca_dev, len + 3);
298}
299
300static int sensor_write_regs(struct gspca_dev *gspca_dev,
301 const struct sensor_w_data *data, int len)
302{
303 int i, rc;
304
305 for (i = 0; i < len; i++) {
306 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
307 data[i].data, data[i].len);
308 if (rc < 0)
309 return rc;
310 }
311
312 return 0;
313}
314
315static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
316{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300317 struct sd *sd = (struct sd *) gspca_dev;
318 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300319 int rc;
320
321 buf = data;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300322 if (sd->cam_type == CAM_TYPE_CIF) {
323 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
324 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
325 } else {
326 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
327 confirm_reg = 0x11;
328 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300329 if (rc < 0)
330 return rc;
331
332 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300333 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300334 if (rc < 0)
335 return rc;
336
337 return 0;
338}
339
Theodore Kilgore930bf782009-10-05 05:11:35 -0300340static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300341{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300342 int err_code;
343
Theodore Kilgore930bf782009-10-05 05:11:35 -0300344 gspca_dev->usb_buf[0] = reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300345 err_code = mr_write(gspca_dev, 1);
346 if (err_code < 0)
347 return err_code;
348
349 err_code = mr_read(gspca_dev, 16);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300350 if (err_code < 0)
351 return err_code;
352
353 if (verbose)
354 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
355 gspca_dev->usb_buf[0],
356 gspca_dev->usb_buf[1],
357 gspca_dev->usb_buf[2]);
358
359 return 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300360}
361
362static int zero_the_pointer(struct gspca_dev *gspca_dev)
363{
364 __u8 *data = gspca_dev->usb_buf;
365 int err_code;
366 u8 status = 0;
367 int tries = 0;
368
Theodore Kilgore930bf782009-10-05 05:11:35 -0300369 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300370 if (err_code < 0)
371 return err_code;
372
Theodore Kilgore89f08632009-08-14 06:51:52 -0300373 data[0] = 0x19;
374 data[1] = 0x51;
375 err_code = mr_write(gspca_dev, 2);
376 if (err_code < 0)
377 return err_code;
378
Theodore Kilgore930bf782009-10-05 05:11:35 -0300379 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300380 if (err_code < 0)
381 return err_code;
382
383 data[0] = 0x19;
384 data[1] = 0xba;
385 err_code = mr_write(gspca_dev, 2);
386 if (err_code < 0)
387 return err_code;
388
Theodore Kilgore930bf782009-10-05 05:11:35 -0300389 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300390 if (err_code < 0)
391 return err_code;
392
393 data[0] = 0x19;
394 data[1] = 0x00;
395 err_code = mr_write(gspca_dev, 2);
396 if (err_code < 0)
397 return err_code;
398
Theodore Kilgore930bf782009-10-05 05:11:35 -0300399 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300400 if (err_code < 0)
401 return err_code;
402
403 data[0] = 0x19;
404 data[1] = 0x00;
405 err_code = mr_write(gspca_dev, 2);
406 if (err_code < 0)
407 return err_code;
408
409 while (status != 0x0a && tries < 256) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300410 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300411 status = data[0];
412 tries++;
413 if (err_code < 0)
414 return err_code;
415 }
Hans de Goede54943782009-08-14 11:05:38 -0300416 if (status != 0x0a)
417 PDEBUG(D_ERR, "status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300418
419 tries = 0;
420 while (tries < 4) {
421 data[0] = 0x19;
422 data[1] = 0x00;
423 err_code = mr_write(gspca_dev, 2);
424 if (err_code < 0)
425 return err_code;
426
Theodore Kilgore930bf782009-10-05 05:11:35 -0300427 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300428 status = data[0];
429 tries++;
430 if (err_code < 0)
431 return err_code;
432 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300433
434 data[0] = 0x19;
435 err_code = mr_write(gspca_dev, 1);
436 if (err_code < 0)
437 return err_code;
438
439 err_code = mr_read(gspca_dev, 16);
440 if (err_code < 0)
441 return err_code;
442
443 return 0;
444}
445
Theodore Kilgore930bf782009-10-05 05:11:35 -0300446static int stream_start(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300447{
Theodore Kilgore930bf782009-10-05 05:11:35 -0300448 gspca_dev->usb_buf[0] = 0x01;
449 gspca_dev->usb_buf[1] = 0x01;
450 return mr_write(gspca_dev, 2);
451}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300452
Theodore Kilgore930bf782009-10-05 05:11:35 -0300453static void stream_stop(struct gspca_dev *gspca_dev)
454{
455 gspca_dev->usb_buf[0] = 0x01;
456 gspca_dev->usb_buf[1] = 0x00;
457 if (mr_write(gspca_dev, 2) < 0)
458 PDEBUG(D_ERR, "Stream Stop failed");
459}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300460
Theodore Kilgore930bf782009-10-05 05:11:35 -0300461static void lcd_stop(struct gspca_dev *gspca_dev)
462{
463 gspca_dev->usb_buf[0] = 0x19;
464 gspca_dev->usb_buf[1] = 0x54;
465 if (mr_write(gspca_dev, 2) < 0)
466 PDEBUG(D_ERR, "LCD Stop failed");
467}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300468
Theodore Kilgore930bf782009-10-05 05:11:35 -0300469static int isoc_enable(struct gspca_dev *gspca_dev)
470{
471 gspca_dev->usb_buf[0] = 0x00;
472 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */
473 return mr_write(gspca_dev, 2);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300474}
475
Theodore Kilgore1160a382009-10-30 04:29:56 -0300476/* This function is called at probe time */
Kyle Guinnd661e622009-01-16 05:36:14 -0300477static int sd_config(struct gspca_dev *gspca_dev,
478 const struct usb_device_id *id)
479{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300480 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300481 struct cam *cam;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300482 int gain_default = MR97310A_GAIN_DEFAULT;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300483 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300484
485 cam = &gspca_dev->cam;
486 cam->cam_mode = vga_mode;
487 cam->nmodes = ARRAY_SIZE(vga_mode);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300488 sd->do_lcd_stop = 0;
489
Theodore Kilgore1160a382009-10-30 04:29:56 -0300490 /* Several of the supported CIF cameras share the same USB ID but
491 * require different initializations and different control settings.
492 * The same is true of the VGA cameras. Therefore, we are forced
493 * to start the initialization process in order to determine which
494 * camera is present. Some of the supported cameras require the
Theodore Kilgore930bf782009-10-05 05:11:35 -0300495 * memory pointer to be set to 0 as the very first item of business
496 * or else they will not stream. So we do that immediately.
497 */
498 err_code = zero_the_pointer(gspca_dev);
499 if (err_code < 0)
500 return err_code;
Hans de Goede9ac69782009-08-14 10:15:52 -0300501
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300502 err_code = stream_start(gspca_dev);
503 if (err_code < 0)
504 return err_code;
505
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300506 /* Now, the query for sensor type. */
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -0300511 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300512 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300513 cam->nmodes--;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300514 /*
Theodore Kilgore1160a382009-10-30 04:29:56 -0300515 * All but one of the known CIF cameras share the same USB ID,
516 * but two different init routines are in use, and the control
517 * settings are different, too. We need to detect which camera
518 * of the two known varieties is connected!
Theodore Kilgore930bf782009-10-05 05:11:35 -0300519 *
520 * A list of known CIF cameras follows. They all report either
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300521 * 0200 for type 0 or 0300 for type 1.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300522 * If you have another to report, please do
523 *
524 * Name sd->sensor_type reported by
525 *
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300526 * Sakar 56379 Spy-shot 0 T. Kilgore
Theodore Kilgore930bf782009-10-05 05:11:35 -0300527 * Innovage 0 T. Kilgore
528 * Vivitar Mini 0 H. De Goede
529 * Vivitar Mini 0 E. Rodriguez
530 * Vivitar Mini 1 T. Kilgore
531 * Elta-Media 8212dc 1 T. Kaiser
532 * Philips dig. keych. 1 T. Kilgore
Theodore Kilgore1160a382009-10-30 04:29:56 -0300533 * Trust Spyc@m 100 1 A. Jacobs
Theodore Kilgore930bf782009-10-05 05:11:35 -0300534 */
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300535 switch (gspca_dev->usb_buf[0]) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300536 case 2:
537 sd->sensor_type = 0;
538 break;
539 case 3:
540 sd->sensor_type = 1;
541 break;
542 default:
543 PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
544 gspca_dev->usb_buf[1]);
545 return -ENODEV;
546 }
547 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
548 sd->sensor_type);
549 } else {
550 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300551
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300552 /*
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300553 * Here is a table of the responses to the query for sensor
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300554 * type, from the known MR97310A VGA cameras. Six different
555 * cameras of which five share the same USB ID.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300556 *
557 * Name gspca_dev->usb_buf[] sd->sensor_type
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300558 * sd->do_lcd_stop
559 * Aiptek Pencam VGA+ 0300 0 1
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300560 * ION digital 0300 0 1
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300561 * Argus DC-1620 0450 1 0
562 * Argus QuickClix 0420 1 1
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300563 * Sakar 77379 Digital 0350 0 1
564 * Sakar 1638x CyberPix 0120 0 2
Theodore Kilgore930bf782009-10-05 05:11:35 -0300565 *
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300566 * Based upon these results, we assume default settings
567 * and then correct as necessary, as follows.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300568 *
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300569 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300570
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300571 sd->sensor_type = 1;
572 sd->do_lcd_stop = 0;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300573 sd->adj_colors = 0;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300574 if (gspca_dev->usb_buf[0] == 0x01) {
575 sd->sensor_type = 2;
576 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300577 (gspca_dev->usb_buf[0] != 0x04)) {
578 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300579 gspca_dev->usb_buf[0]);
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300580 PDEBUG(D_ERR, "Defaults assumed, may not work");
581 PDEBUG(D_ERR, "Please report this");
582 }
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300583 /* Sakar Digital color needs to be adjusted. */
584 if ((gspca_dev->usb_buf[0] == 0x03) &&
585 (gspca_dev->usb_buf[1] == 0x50))
586 sd->adj_colors = 1;
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300587 if (gspca_dev->usb_buf[0] == 0x04) {
588 sd->do_lcd_stop = 1;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300589 switch (gspca_dev->usb_buf[1]) {
590 case 0x50:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300591 sd->sensor_type = 0;
592 PDEBUG(D_PROBE, "sensor_type corrected to 0");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300593 break;
594 case 0x20:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300595 /* Nothing to do here. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300596 break;
597 default:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300598 PDEBUG(D_ERR,
599 "Unknown VGA Sensor id Byte 1: %02x",
600 gspca_dev->usb_buf[1]);
601 PDEBUG(D_ERR,
602 "Defaults assumed, may not work");
603 PDEBUG(D_ERR, "Please report this");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300604 }
Hans de Goede78028702009-09-02 09:55:16 -0300605 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300606 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
607 sd->sensor_type);
608 }
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300609 /* Stop streaming as we've started it only to probe the sensor type. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300610 sd_stopN(gspca_dev);
Hans de Goede78028702009-09-02 09:55:16 -0300611
Theodore Kilgore930bf782009-10-05 05:11:35 -0300612 if (force_sensor_type != -1) {
613 sd->sensor_type = !!force_sensor_type;
614 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
615 sd->sensor_type);
616 }
617
618 /* Setup controls depending on camera type */
619 if (sd->cam_type == CAM_TYPE_CIF) {
620 /* No brightness for sensor_type 0 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300621 if (sd->sensor_type == 0)
Theodore Kilgore930bf782009-10-05 05:11:35 -0300622 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300623 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
624 (1 << CONTRAST_IDX) |
625 (1 << SAKAR_CS_GAIN_IDX);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300626 else
Hans de Goede065b6f72009-10-29 07:42:30 -0300627 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300628 (1 << CONTRAST_IDX) |
629 (1 << SAKAR_CS_GAIN_IDX) |
Hans de Goede065b6f72009-10-29 07:42:30 -0300630 (1 << MIN_CLOCKDIV_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300631 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300632 /* All controls need to be disabled if VGA sensor_type is 0 */
633 if (sd->sensor_type == 0)
634 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
635 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
636 (1 << EXPOSURE_IDX) |
Hans de Goede065b6f72009-10-29 07:42:30 -0300637 (1 << GAIN_IDX) |
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300638 (1 << CONTRAST_IDX) |
639 (1 << SAKAR_CS_GAIN_IDX) |
Hans de Goede065b6f72009-10-29 07:42:30 -0300640 (1 << MIN_CLOCKDIV_IDX);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300641 else if (sd->sensor_type == 2) {
642 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
643 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
644 (1 << GAIN_IDX) |
645 (1 << MIN_CLOCKDIV_IDX);
646 gain_default = MR97310A_CS_GAIN_DEFAULT;
647 } else if (sd->do_lcd_stop)
Theodore Kilgore930bf782009-10-05 05:11:35 -0300648 /* Argus QuickClix has different brightness limits */
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300649 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
650 (1 << CONTRAST_IDX) |
651 (1 << SAKAR_CS_GAIN_IDX);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300652 else
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300653 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
654 (1 << CONTRAST_IDX) |
655 (1 << SAKAR_CS_GAIN_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300656 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300657
658 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
659 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300660 sd->gain = gain_default;
661 sd->contrast = MR97310A_CONTRAST_DEFAULT;
Hans de Goede065b6f72009-10-29 07:42:30 -0300662 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
Hans de Goede9ac69782009-08-14 10:15:52 -0300663
Kyle Guinnd661e622009-01-16 05:36:14 -0300664 return 0;
665}
666
667/* this function is called at probe and resume time */
668static int sd_init(struct gspca_dev *gspca_dev)
669{
670 return 0;
671}
672
Theodore Kilgore89f08632009-08-14 06:51:52 -0300673static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300674{
675 struct sd *sd = (struct sd *) gspca_dev;
676 __u8 *data = gspca_dev->usb_buf;
677 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300678 const __u8 startup_string[] = {
679 0x00,
680 0x0d,
681 0x01,
682 0x00, /* Hsize/8 for 352 or 320 */
683 0x00, /* Vsize/4 for 288 or 240 */
684 0x13, /* or 0xbb, depends on sensor */
685 0x00, /* Hstart, depends on res. */
686 0x00, /* reserved ? */
687 0x00, /* Vstart, depends on res. and sensor */
688 0x50, /* 0x54 to get 176 or 160 */
689 0xc0
690 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300691
Theodore Kilgore89f08632009-08-14 06:51:52 -0300692 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300693
Theodore Kilgore89f08632009-08-14 06:51:52 -0300694 memcpy(data, startup_string, 11);
695 if (sd->sensor_type)
696 data[5] = 0xbb;
697
698 switch (gspca_dev->width) {
699 case 160:
700 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
701 /* fall thru */
702 case 320:
703 default:
704 data[3] = 0x28; /* reg 2, H size/8 */
705 data[4] = 0x3c; /* reg 3, V size/4 */
706 data[6] = 0x14; /* reg 5, H start */
707 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
708 break;
709 case 176:
710 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
711 /* fall thru */
712 case 352:
713 data[3] = 0x2c; /* reg 2, H size/8 */
714 data[4] = 0x48; /* reg 3, V size/4 */
715 data[6] = 0x06; /* reg 5, H start */
Theodore Kilgore32345b02009-11-01 12:59:42 -0300716 data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300717 break;
718 }
719 err_code = mr_write(gspca_dev, 11);
720 if (err_code < 0)
721 return err_code;
722
723 if (!sd->sensor_type) {
724 const struct sensor_w_data cif_sensor0_init_data[] = {
725 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
726 0x0f, 0x14, 0x0f, 0x10}, 8},
727 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
728 {0x12, 0x00, {0x07}, 1},
729 {0x1f, 0x00, {0x06}, 1},
730 {0x27, 0x00, {0x04}, 1},
731 {0x29, 0x00, {0x0c}, 1},
732 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
733 {0x50, 0x00, {0x60}, 1},
734 {0x60, 0x00, {0x06}, 1},
735 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
736 {0x72, 0x00, {0x1e, 0x56}, 2},
737 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
738 0x31, 0x80, 0x00}, 9},
739 {0x11, 0x00, {0x01}, 1},
740 {0, 0, {0}, 0}
741 };
742 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
743 ARRAY_SIZE(cif_sensor0_init_data));
744 } else { /* sd->sensor_type = 1 */
745 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300746 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300747 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300748 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
749 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300750 {0x09, 0x02, {0x0e}, 1},
751 {0x0a, 0x02, {0x05}, 1},
752 {0x0b, 0x02, {0x05}, 1},
753 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300754 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300755 {0x0e, 0x02, {0x0c}, 1},
756 {0x0f, 0x00, {0x00}, 1},
757 {0x10, 0x00, {0x06}, 1},
758 {0x11, 0x00, {0x07}, 1},
759 {0x12, 0x00, {0x00}, 1},
760 {0x13, 0x00, {0x01}, 1},
761 {0, 0, {0}, 0}
762 };
Theodore Kilgore70136082009-12-25 05:15:10 -0300763 /* Without this command the cam won't work with USB-UHCI */
764 gspca_dev->usb_buf[0] = 0x0a;
765 gspca_dev->usb_buf[1] = 0x00;
766 err_code = mr_write(gspca_dev, 2);
767 if (err_code < 0)
768 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300769 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
770 ARRAY_SIZE(cif_sensor1_init_data));
771 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300772 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300773}
774
775static int start_vga_cam(struct gspca_dev *gspca_dev)
776{
777 struct sd *sd = (struct sd *) gspca_dev;
778 __u8 *data = gspca_dev->usb_buf;
779 int err_code;
780 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
781 0x00, 0x00, 0x00, 0x50, 0xc0};
Theodore Kilgore89f08632009-08-14 06:51:52 -0300782 /* What some of these mean is explained in start_cif_cam(), above */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300783
Theodore Kilgore89f08632009-08-14 06:51:52 -0300784 memcpy(data, startup_string, 11);
785 if (!sd->sensor_type) {
786 data[5] = 0x00;
787 data[10] = 0x91;
788 }
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300789 if (sd->sensor_type == 2) {
790 data[5] = 0x00;
791 data[10] = 0x18;
792 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300793
794 switch (gspca_dev->width) {
795 case 160:
796 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
797 /* fall thru */
798 case 320:
799 data[9] |= 0x04; /* reg 8, 2:1 scale down */
800 /* fall thru */
801 case 640:
802 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300803 data[3] = 0x50; /* reg 2, H size/8 */
804 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300805 data[6] = 0x04; /* reg 5, H start */
806 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300807 if (sd->sensor_type == 2) {
808 data[6] = 2;
809 data[8] = 1;
810 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300811 if (sd->do_lcd_stop)
812 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300813 break;
814
815 case 176:
816 data[9] |= 0x04; /* reg 8, 2:1 scale down */
817 /* fall thru */
818 case 352:
819 data[3] = 0x2c; /* reg 2, H size */
820 data[4] = 0x48; /* reg 3, V size */
821 data[6] = 0x94; /* reg 5, H start */
822 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300823 if (sd->do_lcd_stop)
824 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300825 break;
826 }
827
Theodore Kilgore89f08632009-08-14 06:51:52 -0300828 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300829 if (err_code < 0)
830 return err_code;
831
Theodore Kilgore89f08632009-08-14 06:51:52 -0300832 if (!sd->sensor_type) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300833 const struct sensor_w_data vga_sensor0_init_data[] = {
834 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
835 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
836 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
837 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
838 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
839 {0, 0, {0}, 0}
840 };
841 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
842 ARRAY_SIZE(vga_sensor0_init_data));
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300843 } else if (sd->sensor_type == 1) {
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300844 const struct sensor_w_data color_adj[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300845 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300846 /* adjusted blue, green, red gain correct
847 too much blue from the Sakar Digital */
Theodore Kilgoreb31210d2009-11-01 13:02:59 -0300848 0x05, 0x01, 0x04}, 8}
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300849 };
850
851 const struct sensor_w_data color_no_adj[] = {
852 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
853 /* default blue, green, red gain settings */
854 0x07, 0x00, 0x01}, 8}
855 };
856
857 const struct sensor_w_data vga_sensor1_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300858 {0x11, 0x04, {0x01}, 1},
Theodore Kilgore542821d2009-11-01 13:09:15 -0300859 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
860 /* These settings may be better for some cameras */
861 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300862 0x00, 0x0a}, 7},
863 {0x11, 0x04, {0x01}, 1},
864 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
865 {0x11, 0x04, {0x01}, 1},
866 {0, 0, {0}, 0}
867 };
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300868
869 if (sd->adj_colors)
870 err_code = sensor_write_regs(gspca_dev, color_adj,
871 ARRAY_SIZE(color_adj));
872 else
873 err_code = sensor_write_regs(gspca_dev, color_no_adj,
874 ARRAY_SIZE(color_no_adj));
875
876 if (err_code < 0)
877 return err_code;
878
Theodore Kilgore89f08632009-08-14 06:51:52 -0300879 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
880 ARRAY_SIZE(vga_sensor1_init_data));
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300881 } else { /* sensor type == 2 */
882 const struct sensor_w_data vga_sensor2_init_data[] = {
883
884 {0x01, 0x00, {0x48}, 1},
885 {0x02, 0x00, {0x22}, 1},
886 /* Reg 3 msb and 4 is lsb of the exposure setting*/
887 {0x05, 0x00, {0x10}, 1},
888 {0x06, 0x00, {0x00}, 1},
889 {0x07, 0x00, {0x00}, 1},
890 {0x08, 0x00, {0x00}, 1},
891 {0x09, 0x00, {0x00}, 1},
892 /* The following are used in the gain control
893 * which is BTW completely borked in the OEM driver
894 * The values for each color go from 0 to 0x7ff
895 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
896 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
897 *{0x0c, 0x00, {0x01}, 1}, red gain msb
898 *{0x0d, 0x00, {0x10}, 1}, red gain lsb
899 *{0x0e, 0x00, {0x01}, 1}, blue gain msb
900 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
901 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
902 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
903 */
904 {0x12, 0x00, {0x00}, 1},
905 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
906 {0x14, 0x00, {0x00}, 1},
907 {0x15, 0x00, {0x06}, 1},
908 {0x16, 0x00, {0x01}, 1},
909 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
910 {0x18, 0x00, {0x02}, 1},
911 {0x19, 0x00, {0x82}, 1}, /* don't mess with */
912 {0x1a, 0x00, {0x00}, 1},
913 {0x1b, 0x00, {0x20}, 1},
914 /* {0x1c, 0x00, {0x17}, 1}, contrast control */
915 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
916 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
917 {0x1f, 0x00, {0x0c}, 1},
918 {0x20, 0x00, {0x00}, 1},
919 {0, 0, {0}, 0}
920 };
921 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
922 ARRAY_SIZE(vga_sensor2_init_data));
Theodore Kilgore89f08632009-08-14 06:51:52 -0300923 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300924 return err_code;
925}
926
927static int sd_start(struct gspca_dev *gspca_dev)
928{
929 struct sd *sd = (struct sd *) gspca_dev;
930 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300931
Theodore Kilgore89f08632009-08-14 06:51:52 -0300932 sd->sof_read = 0;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300933
934 /* Some of the VGA cameras require the memory pointer
935 * to be set to 0 again. We have been forced to start the
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300936 * stream in sd_config() to detect the hardware, and closed it.
937 * Thus, we need here to do a completely fresh and clean start. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300938 err_code = zero_the_pointer(gspca_dev);
939 if (err_code < 0)
940 return err_code;
941
942 err_code = stream_start(gspca_dev);
943 if (err_code < 0)
944 return err_code;
945
Theodore Kilgore89f08632009-08-14 06:51:52 -0300946 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300947 err_code = start_cif_cam(gspca_dev);
948 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300949 err_code = start_vga_cam(gspca_dev);
950 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300951 if (err_code < 0)
952 return err_code;
953
954 setbrightness(gspca_dev);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300955 setcontrast(gspca_dev);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300956 setexposure(gspca_dev);
957 setgain(gspca_dev);
958
959 return isoc_enable(gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300960}
961
962static void sd_stopN(struct gspca_dev *gspca_dev)
963{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300964 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300965
Theodore Kilgore930bf782009-10-05 05:11:35 -0300966 stream_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300967 /* Not all the cams need this, but even if not, probably a good idea */
968 zero_the_pointer(gspca_dev);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300969 if (sd->do_lcd_stop)
970 lcd_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300971}
972
973static void setbrightness(struct gspca_dev *gspca_dev)
974{
975 struct sd *sd = (struct sd *) gspca_dev;
976 u8 val;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300977 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
978 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
979 const u8 quick_clix_table[] =
980 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
981 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
982 /*
983 * This control is disabled for CIF type 1 and VGA type 0 cameras.
984 * It does not quite act linearly for the Argus QuickClix camera,
985 * but it does control brightness. The values are 0 - 15 only, and
986 * the table above makes them act consecutively.
987 */
988 if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
989 (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
Hans de Goede9ac69782009-08-14 10:15:52 -0300990 return;
991
Theodore Kilgore930bf782009-10-05 05:11:35 -0300992 if (sd->cam_type == CAM_TYPE_VGA) {
993 sign_reg += 4;
994 value_reg += 4;
995 }
996
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300997 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300998 if (sd->brightness > 0) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300999 sensor_write1(gspca_dev, sign_reg, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -03001000 val = sd->brightness;
1001 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -03001002 sensor_write1(gspca_dev, sign_reg, 0x01);
1003 val = (257 - sd->brightness);
Theodore Kilgore89f08632009-08-14 06:51:52 -03001004 }
Theodore Kilgore930bf782009-10-05 05:11:35 -03001005 /* Use lookup table for funky Argus QuickClix brightness */
1006 if (sd->do_lcd_stop)
1007 val = quick_clix_table[val];
1008
1009 sensor_write1(gspca_dev, value_reg, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -03001010}
1011
1012static void setexposure(struct gspca_dev *gspca_dev)
1013{
1014 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001015 int exposure = MR97310A_EXPOSURE_DEFAULT;
Hans de Goede065b6f72009-10-29 07:42:30 -03001016 u8 buf[2];
Theodore Kilgore89f08632009-08-14 06:51:52 -03001017
Hans de Goede9ac69782009-08-14 10:15:52 -03001018 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
1019 return;
1020
Theodore Kilgore930bf782009-10-05 05:11:35 -03001021 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -03001022 /* This cam does not like exposure settings < 300,
Hans de Goeded76f9752009-10-11 05:22:29 -03001023 so scale 0 - 4095 to 300 - 4095 */
1024 exposure = (sd->exposure * 9267) / 10000 + 300;
Theodore Kilgore930bf782009-10-05 05:11:35 -03001025 sensor_write1(gspca_dev, 3, exposure >> 4);
1026 sensor_write1(gspca_dev, 4, exposure & 0x0f);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001027 } else if (sd->sensor_type == 2) {
1028 exposure = sd->exposure;
1029 exposure >>= 3;
1030 sensor_write1(gspca_dev, 3, exposure >> 8);
1031 sensor_write1(gspca_dev, 4, exposure & 0xff);
Hans de Goedea2e081b2009-08-14 17:11:36 -03001032 } else {
Hans de Goedea2e081b2009-08-14 17:11:36 -03001033 /* We have both a clock divider and an exposure register.
1034 We first calculate the clock divider, as that determines
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -03001035 the maximum exposure and then we calculate the exposure
Hans de Goedea2e081b2009-08-14 17:11:36 -03001036 register setting (which goes from 0 - 511).
1037
1038 Note our 0 - 4095 exposure is mapped to 0 - 511
1039 milliseconds exposure time */
Theodore Kilgore930bf782009-10-05 05:11:35 -03001040 u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
Hans de Goedea2e081b2009-08-14 17:11:36 -03001041
1042 /* Limit framerate to not exceed usb bandwidth */
Hans de Goede065b6f72009-10-29 07:42:30 -03001043 if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
1044 clockdiv = sd->min_clockdiv;
Hans de Goedea2e081b2009-08-14 17:11:36 -03001045 else if (clockdiv < 2)
1046 clockdiv = 2;
1047
Theodore Kilgore930bf782009-10-05 05:11:35 -03001048 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
1049 clockdiv = 4;
1050
Hans de Goedea2e081b2009-08-14 17:11:36 -03001051 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
1052 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
1053 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
1054 if (exposure > 511)
1055 exposure = 511;
1056
1057 /* exposure register value is reversed! */
1058 exposure = 511 - exposure;
1059
Hans de Goede065b6f72009-10-29 07:42:30 -03001060 buf[0] = exposure & 0xff;
1061 buf[1] = exposure >> 8;
1062 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
Hans de Goedea2e081b2009-08-14 17:11:36 -03001063 sensor_write1(gspca_dev, 0x02, clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -03001064 }
Theodore Kilgore89f08632009-08-14 06:51:52 -03001065}
1066
1067static void setgain(struct gspca_dev *gspca_dev)
1068{
1069 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001070 u8 gainreg;
Theodore Kilgore89f08632009-08-14 06:51:52 -03001071
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001072 if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) &&
1073 (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX)))
Hans de Goede9ac69782009-08-14 10:15:52 -03001074 return;
1075
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001076 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
Hans de Goede823902de2009-08-17 12:25:17 -03001077 sensor_write1(gspca_dev, 0x0e, sd->gain);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001078 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
1079 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
1080 sensor_write1(gspca_dev, gainreg, sd->gain >> 8);
1081 sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff);
1082 }
1083 else
Hans de Goedea2e081b2009-08-14 17:11:36 -03001084 sensor_write1(gspca_dev, 0x10, sd->gain);
Theodore Kilgore89f08632009-08-14 06:51:52 -03001085}
1086
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001087static void setcontrast(struct gspca_dev *gspca_dev)
1088{
1089 struct sd *sd = (struct sd *) gspca_dev;
1090
1091 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
1092 return;
1093
1094 sensor_write1(gspca_dev, 0x1c, sd->contrast);
1095}
1096
1097
Theodore Kilgore89f08632009-08-14 06:51:52 -03001098static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1099{
1100 struct sd *sd = (struct sd *) gspca_dev;
1101
1102 sd->brightness = val;
1103 if (gspca_dev->streaming)
1104 setbrightness(gspca_dev);
1105 return 0;
1106}
1107
1108static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1109{
1110 struct sd *sd = (struct sd *) gspca_dev;
1111
1112 *val = sd->brightness;
1113 return 0;
1114}
1115
1116static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1117{
1118 struct sd *sd = (struct sd *) gspca_dev;
1119
1120 sd->exposure = val;
1121 if (gspca_dev->streaming)
1122 setexposure(gspca_dev);
1123 return 0;
1124}
1125
1126static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1127{
1128 struct sd *sd = (struct sd *) gspca_dev;
1129
1130 *val = sd->exposure;
1131 return 0;
1132}
1133
1134static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1135{
1136 struct sd *sd = (struct sd *) gspca_dev;
1137
1138 sd->gain = val;
1139 if (gspca_dev->streaming)
1140 setgain(gspca_dev);
1141 return 0;
1142}
1143
1144static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1145{
1146 struct sd *sd = (struct sd *) gspca_dev;
1147
1148 *val = sd->gain;
1149 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -03001150}
1151
Theodore Kilgore9d3103d2010-02-09 18:05:25 -03001152static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1153{
1154 struct sd *sd = (struct sd *) gspca_dev;
1155
1156 sd->contrast = val;
1157 if (gspca_dev->streaming)
1158 setcontrast(gspca_dev);
1159 return 0;
1160}
1161
1162
1163static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1164{
1165 struct sd *sd = (struct sd *) gspca_dev;
1166
1167 *val = sd->contrast;
1168 return 0;
1169}
1170
Hans de Goede065b6f72009-10-29 07:42:30 -03001171static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1172{
1173 struct sd *sd = (struct sd *) gspca_dev;
1174
1175 sd->min_clockdiv = val;
1176 if (gspca_dev->streaming)
1177 setexposure(gspca_dev);
1178 return 0;
1179}
1180
1181static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
1182{
1183 struct sd *sd = (struct sd *) gspca_dev;
1184
1185 *val = sd->min_clockdiv;
1186 return 0;
1187}
1188
Kyle Guinnd661e622009-01-16 05:36:14 -03001189/* Include pac common sof detection functions */
1190#include "pac_common.h"
1191
1192static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001193 u8 *data, /* isoc packet */
1194 int len) /* iso packet length */
Kyle Guinnd661e622009-01-16 05:36:14 -03001195{
Marton Nemetha6b69e42009-11-02 08:05:51 -03001196 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -03001197 unsigned char *sof;
1198
Marton Nemetha6b69e42009-11-02 08:05:51 -03001199 sof = pac_find_sof(&sd->sof_read, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001200 if (sof) {
1201 int n;
1202
1203 /* finish decoding current frame */
1204 n = sof - data;
1205 if (n > sizeof pac_sof_marker)
1206 n -= sizeof pac_sof_marker;
1207 else
1208 n = 0;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001209 gspca_frame_add(gspca_dev, LAST_PACKET,
Kyle Guinnd661e622009-01-16 05:36:14 -03001210 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -03001211 /* Start next frame. */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001212 gspca_frame_add(gspca_dev, FIRST_PACKET,
Theodore Kilgore9832d762009-03-13 13:04:31 -03001213 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -03001214 len -= sof - data;
1215 data = sof;
1216 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001217 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001218}
1219
1220/* sub-driver description */
1221static const struct sd_desc sd_desc = {
1222 .name = MODULE_NAME,
1223 .ctrls = sd_ctrls,
1224 .nctrls = ARRAY_SIZE(sd_ctrls),
1225 .config = sd_config,
1226 .init = sd_init,
1227 .start = sd_start,
1228 .stopN = sd_stopN,
1229 .pkt_scan = sd_pkt_scan,
1230};
1231
1232/* -- module initialisation -- */
1233static const __devinitdata struct usb_device_id device_table[] = {
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -03001234 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
Theodore Kilgore89f08632009-08-14 06:51:52 -03001235 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
1236 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
1237 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -03001238 {}
1239};
1240MODULE_DEVICE_TABLE(usb, device_table);
1241
1242/* -- device connect -- */
1243static int sd_probe(struct usb_interface *intf,
1244 const struct usb_device_id *id)
1245{
1246 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1247 THIS_MODULE);
1248}
1249
1250static struct usb_driver sd_driver = {
1251 .name = MODULE_NAME,
1252 .id_table = device_table,
1253 .probe = sd_probe,
1254 .disconnect = gspca_disconnect,
1255#ifdef CONFIG_PM
1256 .suspend = gspca_suspend,
1257 .resume = gspca_resume,
1258#endif
1259};
1260
1261/* -- module insert / remove -- */
1262static int __init sd_mod_init(void)
1263{
Alexey Klimov5d3fa302009-03-27 15:57:46 -03001264 int ret;
1265
1266 ret = usb_register(&sd_driver);
1267 if (ret < 0)
1268 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -03001269 PDEBUG(D_PROBE, "registered");
1270 return 0;
1271}
1272static void __exit sd_mod_exit(void)
1273{
1274 usb_deregister(&sd_driver);
1275 PDEBUG(D_PROBE, "deregistered");
1276}
1277
1278module_init(sd_mod_init);
1279module_exit(sd_mod_exit);