blob: 169cdb65c14a67d93f66b7faeb1a4ba25ef456eb [file] [log] [blame]
Kyle Guinnd661e622009-01-16 05:36:14 -03001/*
2 * Mars MR97310A library
3 *
4 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
5 *
Theodore Kilgore89f08632009-08-14 06:51:52 -03006 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
7 * and for the routines for detecting and classifying these various cameras,
8 *
9 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
10 *
11 * Acknowledgements:
12 *
13 * The MR97311A support in gspca/mars.c has been helpful in understanding some
14 * of the registers in these cameras.
15 *
16 * Hans de Goede <hdgoede@redhat.com> and
17 * Thomas Kaiser <thomas@kaiser-linux.li>
18 * have assisted with their experience. Each of them has also helped by
19 * testing a previously unsupported camera.
20 *
Kyle Guinnd661e622009-01-16 05:36:14 -030021 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 */
35
36#define MODULE_NAME "mr97310a"
37
38#include "gspca.h"
39
Theodore Kilgore89f08632009-08-14 06:51:52 -030040#define CAM_TYPE_CIF 0
41#define CAM_TYPE_VGA 1
42
43#define MR97310A_BRIGHTNESS_MIN -254
44#define MR97310A_BRIGHTNESS_MAX 255
45#define MR97310A_BRIGHTNESS_DEFAULT 0
46
47#define MR97310A_EXPOSURE_MIN 300
48#define MR97310A_EXPOSURE_MAX 4095
49#define MR97310A_EXPOSURE_DEFAULT 1000
50
51#define MR97310A_GAIN_MIN 0
52#define MR97310A_GAIN_MAX 31
53#define MR97310A_GAIN_DEFAULT 25
54
55MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
56 "Theodore Kilgore <kilgota@auburn.edu>");
Kyle Guinnd661e622009-01-16 05:36:14 -030057MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
58MODULE_LICENSE("GPL");
59
Hans de Goede78028702009-09-02 09:55:16 -030060/* global parameters */
61int force_sensor_type = -1;
62module_param(force_sensor_type, int, 0644);
63MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
64
Kyle Guinnd661e622009-01-16 05:36:14 -030065/* specific webcam descriptor */
66struct sd {
67 struct gspca_dev gspca_dev; /* !! must be the first item */
Kyle Guinnd661e622009-01-16 05:36:14 -030068 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030069 u8 cam_type; /* 0 is CIF and 1 is VGA */
70 u8 sensor_type; /* We use 0 and 1 here, too. */
71 u8 do_lcd_stop;
Theodore Kilgore89f08632009-08-14 06:51:52 -030072
73 int brightness;
74 u16 exposure;
Theodore Kilgore89f08632009-08-14 06:51:52 -030075 u8 gain;
Kyle Guinnd661e622009-01-16 05:36:14 -030076};
77
Theodore Kilgore89f08632009-08-14 06:51:52 -030078struct sensor_w_data {
79 u8 reg;
80 u8 flags;
81 u8 data[16];
82 int len;
83};
84
85static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede9ac69782009-08-14 10:15:52 -030091static void setbrightness(struct gspca_dev *gspca_dev);
92static void setexposure(struct gspca_dev *gspca_dev);
93static void setgain(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -030094
Kyle Guinnd661e622009-01-16 05:36:14 -030095/* V4L2 controls supported by the driver */
96static struct ctrl sd_ctrls[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -030097 {
Hans de Goede9ac69782009-08-14 10:15:52 -030098#define BRIGHTNESS_IDX 0
Theodore Kilgore89f08632009-08-14 06:51:52 -030099 {
100 .id = V4L2_CID_BRIGHTNESS,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Brightness",
103 .minimum = MR97310A_BRIGHTNESS_MIN,
104 .maximum = MR97310A_BRIGHTNESS_MAX,
105 .step = 1,
106 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
107 .flags = 0,
108 },
109 .set = sd_setbrightness,
110 .get = sd_getbrightness,
111 },
112 {
Hans de Goede9ac69782009-08-14 10:15:52 -0300113#define EXPOSURE_IDX 1
Theodore Kilgore89f08632009-08-14 06:51:52 -0300114 {
115 .id = V4L2_CID_EXPOSURE,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Exposure",
118 .minimum = MR97310A_EXPOSURE_MIN,
119 .maximum = MR97310A_EXPOSURE_MAX,
120 .step = 1,
121 .default_value = MR97310A_EXPOSURE_DEFAULT,
122 .flags = 0,
123 },
124 .set = sd_setexposure,
125 .get = sd_getexposure,
126 },
127 {
Hans de Goede9ac69782009-08-14 10:15:52 -0300128#define GAIN_IDX 2
Theodore Kilgore89f08632009-08-14 06:51:52 -0300129 {
130 .id = V4L2_CID_GAIN,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "Gain",
133 .minimum = MR97310A_GAIN_MIN,
134 .maximum = MR97310A_GAIN_MAX,
135 .step = 1,
136 .default_value = MR97310A_GAIN_DEFAULT,
137 .flags = 0,
138 },
139 .set = sd_setgain,
140 .get = sd_getgain,
141 },
Kyle Guinnd661e622009-01-16 05:36:14 -0300142};
143
144static const struct v4l2_pix_format vga_mode[] = {
145 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
146 .bytesperline = 160,
147 .sizeimage = 160 * 120,
148 .colorspace = V4L2_COLORSPACE_SRGB,
149 .priv = 4},
150 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
151 .bytesperline = 176,
152 .sizeimage = 176 * 144,
153 .colorspace = V4L2_COLORSPACE_SRGB,
154 .priv = 3},
155 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
156 .bytesperline = 320,
157 .sizeimage = 320 * 240,
158 .colorspace = V4L2_COLORSPACE_SRGB,
159 .priv = 2},
160 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
161 .bytesperline = 352,
162 .sizeimage = 352 * 288,
163 .colorspace = V4L2_COLORSPACE_SRGB,
164 .priv = 1},
165 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
166 .bytesperline = 640,
167 .sizeimage = 640 * 480,
168 .colorspace = V4L2_COLORSPACE_SRGB,
169 .priv = 0},
170};
171
172/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300173static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300174{
175 int rc;
176
177 rc = usb_bulk_msg(gspca_dev->dev,
178 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300179 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300180 if (rc < 0)
181 PDEBUG(D_ERR, "reg write [%02x] error %d",
182 gspca_dev->usb_buf[0], rc);
183 return rc;
184}
185
Theodore Kilgore89f08632009-08-14 06:51:52 -0300186/* the bytes are read into gspca_dev->usb_buf */
187static int mr_read(struct gspca_dev *gspca_dev, int len)
188{
189 int rc;
190
191 rc = usb_bulk_msg(gspca_dev->dev,
192 usb_rcvbulkpipe(gspca_dev->dev, 3),
193 gspca_dev->usb_buf, len, NULL, 500);
194 if (rc < 0)
195 PDEBUG(D_ERR, "reg read [%02x] error %d",
196 gspca_dev->usb_buf[0], rc);
197 return rc;
198}
199
200static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
201 const u8 *data, int len)
202{
203 gspca_dev->usb_buf[0] = 0x1f;
204 gspca_dev->usb_buf[1] = flags;
205 gspca_dev->usb_buf[2] = reg;
206 memcpy(gspca_dev->usb_buf + 3, data, len);
207
208 return mr_write(gspca_dev, len + 3);
209}
210
211static int sensor_write_regs(struct gspca_dev *gspca_dev,
212 const struct sensor_w_data *data, int len)
213{
214 int i, rc;
215
216 for (i = 0; i < len; i++) {
217 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
218 data[i].data, data[i].len);
219 if (rc < 0)
220 return rc;
221 }
222
223 return 0;
224}
225
226static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
227{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300228 struct sd *sd = (struct sd *) gspca_dev;
229 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300230 int rc;
231
232 buf = data;
233 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
234 if (rc < 0)
235 return rc;
236
237 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300238 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
239 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300240 if (rc < 0)
241 return rc;
242
243 return 0;
244}
245
246static int cam_get_response16(struct gspca_dev *gspca_dev)
247{
248 __u8 *data = gspca_dev->usb_buf;
249 int err_code;
250
251 data[0] = 0x21;
252 err_code = mr_write(gspca_dev, 1);
253 if (err_code < 0)
254 return err_code;
255
256 err_code = mr_read(gspca_dev, 16);
257 return err_code;
258}
259
260static int zero_the_pointer(struct gspca_dev *gspca_dev)
261{
262 __u8 *data = gspca_dev->usb_buf;
263 int err_code;
264 u8 status = 0;
265 int tries = 0;
266
267 err_code = cam_get_response16(gspca_dev);
268 if (err_code < 0)
269 return err_code;
270
271 err_code = mr_write(gspca_dev, 1);
272 data[0] = 0x19;
273 data[1] = 0x51;
274 err_code = mr_write(gspca_dev, 2);
275 if (err_code < 0)
276 return err_code;
277
278 err_code = cam_get_response16(gspca_dev);
279 if (err_code < 0)
280 return err_code;
281
282 data[0] = 0x19;
283 data[1] = 0xba;
284 err_code = mr_write(gspca_dev, 2);
285 if (err_code < 0)
286 return err_code;
287
288 err_code = cam_get_response16(gspca_dev);
289 if (err_code < 0)
290 return err_code;
291
292 data[0] = 0x19;
293 data[1] = 0x00;
294 err_code = mr_write(gspca_dev, 2);
295 if (err_code < 0)
296 return err_code;
297
298 err_code = cam_get_response16(gspca_dev);
299 if (err_code < 0)
300 return err_code;
301
302 data[0] = 0x19;
303 data[1] = 0x00;
304 err_code = mr_write(gspca_dev, 2);
305 if (err_code < 0)
306 return err_code;
307
308 while (status != 0x0a && tries < 256) {
309 err_code = cam_get_response16(gspca_dev);
310 status = data[0];
311 tries++;
312 if (err_code < 0)
313 return err_code;
314 }
Hans de Goede54943782009-08-14 11:05:38 -0300315 if (status != 0x0a)
316 PDEBUG(D_ERR, "status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300317
318 tries = 0;
319 while (tries < 4) {
320 data[0] = 0x19;
321 data[1] = 0x00;
322 err_code = mr_write(gspca_dev, 2);
323 if (err_code < 0)
324 return err_code;
325
326 err_code = cam_get_response16(gspca_dev);
327 status = data[0];
328 tries++;
329 if (err_code < 0)
330 return err_code;
331 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300332
333 data[0] = 0x19;
334 err_code = mr_write(gspca_dev, 1);
335 if (err_code < 0)
336 return err_code;
337
338 err_code = mr_read(gspca_dev, 16);
339 if (err_code < 0)
340 return err_code;
341
342 return 0;
343}
344
345static u8 get_sensor_id(struct gspca_dev *gspca_dev)
346{
347 int err_code;
348
349 gspca_dev->usb_buf[0] = 0x1e;
350 err_code = mr_write(gspca_dev, 1);
351 if (err_code < 0)
352 return err_code;
353
354 err_code = mr_read(gspca_dev, 16);
355 if (err_code < 0)
356 return err_code;
357
Hans de Goede54943782009-08-14 11:05:38 -0300358 PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300359
360 return gspca_dev->usb_buf[0];
361}
362
Kyle Guinnd661e622009-01-16 05:36:14 -0300363/* this function is called at probe time */
364static int sd_config(struct gspca_dev *gspca_dev,
365 const struct usb_device_id *id)
366{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300367 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300368 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300369 __u8 *data = gspca_dev->usb_buf;
370 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300371
372 cam = &gspca_dev->cam;
373 cam->cam_mode = vga_mode;
374 cam->nmodes = ARRAY_SIZE(vga_mode);
Hans de Goede9ac69782009-08-14 10:15:52 -0300375
Theodore Kilgore89f08632009-08-14 06:51:52 -0300376 if (id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300377 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300378 cam->nmodes--;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300379
380 data[0] = 0x01;
381 data[1] = 0x01;
382 err_code = mr_write(gspca_dev, 2);
383 if (err_code < 0)
384 return err_code;
385
386 msleep(200);
387 data[0] = get_sensor_id(gspca_dev);
388 /*
389 * Known CIF cameras. If you have another to report, please do
390 *
391 * Name byte just read sd->sensor_type
392 * reported by
393 * Sakar Spy-shot 0x28 T. Kilgore 0
394 * Innovage 0xf5 (unstable) T. Kilgore 0
395 * Vivitar Mini 0x53 H. De Goede 0
396 * Vivitar Mini 0x08 T. Kilgore 1
397 * Elta-Media 8212dc 0x23 T. Kaiser 1
398 * Philips dig. keych. 0x37 T. Kilgore 1
399 */
400 if ((data[0] & 0x78) == 8 ||
401 ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
402 sd->sensor_type = 1;
403 else
404 sd->sensor_type = 0;
405
Hans de Goede54943782009-08-14 11:05:38 -0300406 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
407 sd->sensor_type);
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300408
Hans de Goede78028702009-09-02 09:55:16 -0300409 if (force_sensor_type != -1) {
410 sd->sensor_type = !! force_sensor_type;
411 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
412 sd->sensor_type);
413 }
414
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300415 if (sd->sensor_type == 0)
Hans de Goedea2e081b2009-08-14 17:11:36 -0300416 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300417 } else {
418 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede54943782009-08-14 11:05:38 -0300419 PDEBUG(D_PROBE, "MR97310A VGA camera detected");
Hans de Goede9ac69782009-08-14 10:15:52 -0300420 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
421 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300422 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300423
424 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
425 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
426 sd->gain = MR97310A_GAIN_DEFAULT;
427
Kyle Guinnd661e622009-01-16 05:36:14 -0300428 return 0;
429}
430
431/* this function is called at probe and resume time */
432static int sd_init(struct gspca_dev *gspca_dev)
433{
434 return 0;
435}
436
Theodore Kilgore89f08632009-08-14 06:51:52 -0300437static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300438{
439 struct sd *sd = (struct sd *) gspca_dev;
440 __u8 *data = gspca_dev->usb_buf;
441 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300442 const __u8 startup_string[] = {
443 0x00,
444 0x0d,
445 0x01,
446 0x00, /* Hsize/8 for 352 or 320 */
447 0x00, /* Vsize/4 for 288 or 240 */
448 0x13, /* or 0xbb, depends on sensor */
449 0x00, /* Hstart, depends on res. */
450 0x00, /* reserved ? */
451 0x00, /* Vstart, depends on res. and sensor */
452 0x50, /* 0x54 to get 176 or 160 */
453 0xc0
454 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300455
Theodore Kilgore89f08632009-08-14 06:51:52 -0300456 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300457 data[0] = 0x01;
458 data[1] = 0x01;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300459 err_code = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300460 if (err_code < 0)
461 return err_code;
462
Theodore Kilgore89f08632009-08-14 06:51:52 -0300463 memcpy(data, startup_string, 11);
464 if (sd->sensor_type)
465 data[5] = 0xbb;
466
467 switch (gspca_dev->width) {
468 case 160:
469 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
470 /* fall thru */
471 case 320:
472 default:
473 data[3] = 0x28; /* reg 2, H size/8 */
474 data[4] = 0x3c; /* reg 3, V size/4 */
475 data[6] = 0x14; /* reg 5, H start */
476 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
477 break;
478 case 176:
479 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
480 /* fall thru */
481 case 352:
482 data[3] = 0x2c; /* reg 2, H size/8 */
483 data[4] = 0x48; /* reg 3, V size/4 */
484 data[6] = 0x06; /* reg 5, H start */
485 data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
486 break;
487 }
488 err_code = mr_write(gspca_dev, 11);
489 if (err_code < 0)
490 return err_code;
491
492 if (!sd->sensor_type) {
493 const struct sensor_w_data cif_sensor0_init_data[] = {
494 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
495 0x0f, 0x14, 0x0f, 0x10}, 8},
496 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
497 {0x12, 0x00, {0x07}, 1},
498 {0x1f, 0x00, {0x06}, 1},
499 {0x27, 0x00, {0x04}, 1},
500 {0x29, 0x00, {0x0c}, 1},
501 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
502 {0x50, 0x00, {0x60}, 1},
503 {0x60, 0x00, {0x06}, 1},
504 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
505 {0x72, 0x00, {0x1e, 0x56}, 2},
506 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
507 0x31, 0x80, 0x00}, 9},
508 {0x11, 0x00, {0x01}, 1},
509 {0, 0, {0}, 0}
510 };
511 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
512 ARRAY_SIZE(cif_sensor0_init_data));
513 } else { /* sd->sensor_type = 1 */
514 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300515 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300516 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300517 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
518 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300519 {0x09, 0x02, {0x0e}, 1},
520 {0x0a, 0x02, {0x05}, 1},
521 {0x0b, 0x02, {0x05}, 1},
522 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300523 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300524 {0x0e, 0x02, {0x0c}, 1},
525 {0x0f, 0x00, {0x00}, 1},
526 {0x10, 0x00, {0x06}, 1},
527 {0x11, 0x00, {0x07}, 1},
528 {0x12, 0x00, {0x00}, 1},
529 {0x13, 0x00, {0x01}, 1},
530 {0, 0, {0}, 0}
531 };
532 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
533 ARRAY_SIZE(cif_sensor1_init_data));
534 }
535 if (err_code < 0)
536 return err_code;
537
Hans de Goede9ac69782009-08-14 10:15:52 -0300538 setbrightness(gspca_dev);
539 setexposure(gspca_dev);
540 setgain(gspca_dev);
541
Theodore Kilgore89f08632009-08-14 06:51:52 -0300542 msleep(200);
Hans de Goede9ac69782009-08-14 10:15:52 -0300543
Kyle Guinnd661e622009-01-16 05:36:14 -0300544 data[0] = 0x00;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300545 data[1] = 0x4d; /* ISOC transfering enable... */
546 err_code = mr_write(gspca_dev, 2);
547 if (err_code < 0)
548 return err_code;
549
Theodore Kilgore89f08632009-08-14 06:51:52 -0300550 return 0;
551}
552
553static int start_vga_cam(struct gspca_dev *gspca_dev)
554{
555 struct sd *sd = (struct sd *) gspca_dev;
556 __u8 *data = gspca_dev->usb_buf;
557 int err_code;
558 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
559 0x00, 0x00, 0x00, 0x50, 0xc0};
560
561 /* What some of these mean is explained in start_cif_cam(), above */
562 sd->sof_read = 0;
563
564 /*
565 * We have to know which camera we have, because the register writes
566 * depend upon the camera. This test, run before we actually enter
567 * the initialization routine, distinguishes most of the cameras, If
568 * needed, another routine is done later, too.
569 */
570 memset(data, 0, 16);
571 data[0] = 0x20;
572 err_code = mr_write(gspca_dev, 1);
573 if (err_code < 0)
574 return err_code;
575
576 err_code = mr_read(gspca_dev, 16);
577 if (err_code < 0)
578 return err_code;
579
Hans de Goede54943782009-08-14 11:05:38 -0300580 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300581
582 msleep(200);
583 /*
584 * Known VGA cameras. If you have another to report, please do
585 *
586 * Name byte just read sd->sensor_type
587 * sd->do_lcd_stop
588 * Aiptek Pencam VGA+ 0x31 0 1
589 * ION digital 0x31 0 1
590 * Argus DC-1620 0x30 1 0
591 * Argus QuickClix 0x30 1 1 (not caught here)
592 */
593 sd->sensor_type = data[0] & 1;
594 sd->do_lcd_stop = (~data[0]) & 1;
595
596
597
598 /* Streaming setup begins here. */
599
600
601 data[0] = 0x01;
602 data[1] = 0x01;
603 err_code = mr_write(gspca_dev, 2);
604 if (err_code < 0)
605 return err_code;
606
607 /*
608 * A second test can now resolve any remaining ambiguity in the
609 * identification of the camera type,
610 */
611 if (!sd->sensor_type) {
612 data[0] = get_sensor_id(gspca_dev);
613 if (data[0] == 0x7f) {
614 sd->sensor_type = 1;
Hans de Goede54943782009-08-14 11:05:38 -0300615 PDEBUG(D_PROBE, "sensor_type corrected to 1");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300616 }
617 msleep(200);
618 }
619
Hans de Goede78028702009-09-02 09:55:16 -0300620 if (force_sensor_type != -1) {
621 sd->sensor_type = !! force_sensor_type;
622 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
623 sd->sensor_type);
624 }
625
Theodore Kilgore89f08632009-08-14 06:51:52 -0300626 /*
627 * Known VGA cameras.
628 * This test is only run if the previous test returned 0x30, but
629 * here is the information for all others, too, just for reference.
630 *
631 * Name byte just read sd->sensor_type
632 *
633 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
634 * ION digital 0xbd (this test not run) 1
635 * Argus DC-1620 0xe5 (no change) 0
636 * Argus QuickClix 0x7f (reclassified) 1
637 */
638 memcpy(data, startup_string, 11);
639 if (!sd->sensor_type) {
640 data[5] = 0x00;
641 data[10] = 0x91;
642 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300643
644 switch (gspca_dev->width) {
645 case 160:
646 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
647 /* fall thru */
648 case 320:
649 data[9] |= 0x04; /* reg 8, 2:1 scale down */
650 /* fall thru */
651 case 640:
652 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300653 data[3] = 0x50; /* reg 2, H size/8 */
654 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300655 data[6] = 0x04; /* reg 5, H start */
656 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300657 if (sd->do_lcd_stop)
658 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300659 break;
660
661 case 176:
662 data[9] |= 0x04; /* reg 8, 2:1 scale down */
663 /* fall thru */
664 case 352:
665 data[3] = 0x2c; /* reg 2, H size */
666 data[4] = 0x48; /* reg 3, V size */
667 data[6] = 0x94; /* reg 5, H start */
668 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300669 if (sd->do_lcd_stop)
670 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300671 break;
672 }
673
Theodore Kilgore89f08632009-08-14 06:51:52 -0300674 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300675 if (err_code < 0)
676 return err_code;
677
Theodore Kilgore89f08632009-08-14 06:51:52 -0300678 if (!sd->sensor_type) {
679 /* The only known sensor_type 0 cam is the Argus DC-1620 */
680 const struct sensor_w_data vga_sensor0_init_data[] = {
681 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
682 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
683 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
684 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
685 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
686 {0, 0, {0}, 0}
687 };
688 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
689 ARRAY_SIZE(vga_sensor0_init_data));
690 } else { /* sd->sensor_type = 1 */
691 const struct sensor_w_data vga_sensor1_init_data[] = {
692 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
693 0x07, 0x00, 0x01}, 8},
694 {0x11, 0x04, {0x01}, 1},
695 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
696 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
697 0x00, 0x0a}, 7},
698 {0x11, 0x04, {0x01}, 1},
699 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
700 {0x11, 0x04, {0x01}, 1},
701 {0, 0, {0}, 0}
702 };
703 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
704 ARRAY_SIZE(vga_sensor1_init_data));
705 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300706 if (err_code < 0)
707 return err_code;
708
Theodore Kilgore89f08632009-08-14 06:51:52 -0300709 msleep(200);
Kyle Guinnd661e622009-01-16 05:36:14 -0300710 data[0] = 0x00;
711 data[1] = 0x4d; /* ISOC transfering enable... */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300712 err_code = mr_write(gspca_dev, 2);
713
714 return err_code;
715}
716
717static int sd_start(struct gspca_dev *gspca_dev)
718{
719 struct sd *sd = (struct sd *) gspca_dev;
720 int err_code;
721 struct cam *cam;
722
Theodore Kilgore89f08632009-08-14 06:51:52 -0300723 cam = &gspca_dev->cam;
724 sd->sof_read = 0;
725 /*
726 * Some of the supported cameras require the memory pointer to be
727 * set to 0, or else they will not stream.
728 */
729 zero_the_pointer(gspca_dev);
730 msleep(200);
731 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300732 err_code = start_cif_cam(gspca_dev);
733 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300734 err_code = start_vga_cam(gspca_dev);
735 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300736 return err_code;
737}
738
739static void sd_stopN(struct gspca_dev *gspca_dev)
740{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300741 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300742 int result;
743
744 gspca_dev->usb_buf[0] = 1;
745 gspca_dev->usb_buf[1] = 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300746 result = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300747 if (result < 0)
748 PDEBUG(D_ERR, "Camera Stop failed");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300749
750 /* Not all the cams need this, but even if not, probably a good idea */
751 zero_the_pointer(gspca_dev);
752 if (sd->do_lcd_stop) {
753 gspca_dev->usb_buf[0] = 0x19;
754 gspca_dev->usb_buf[1] = 0x54;
755 result = mr_write(gspca_dev, 2);
756 if (result < 0)
757 PDEBUG(D_ERR, "Camera Stop failed");
758 }
759}
760
761static void setbrightness(struct gspca_dev *gspca_dev)
762{
763 struct sd *sd = (struct sd *) gspca_dev;
764 u8 val;
Hans de Goede9ac69782009-08-14 10:15:52 -0300765
766 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
767 return;
768
769 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300770 if (sd->brightness > 0) {
Hans de Goede9ac69782009-08-14 10:15:52 -0300771 sensor_write1(gspca_dev, 7, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300772 val = sd->brightness;
773 } else {
Hans de Goede9ac69782009-08-14 10:15:52 -0300774 sensor_write1(gspca_dev, 7, 0x01);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300775 val = 257 - sd->brightness;
776 }
777 sensor_write1(gspca_dev, 8, val);
778}
779
780static void setexposure(struct gspca_dev *gspca_dev)
781{
782 struct sd *sd = (struct sd *) gspca_dev;
783 u8 val;
784
Hans de Goede9ac69782009-08-14 10:15:52 -0300785 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
786 return;
787
Hans de Goedea2e081b2009-08-14 17:11:36 -0300788 if (sd->sensor_type) {
789 val = sd->exposure >> 4;
790 sensor_write1(gspca_dev, 3, val);
791 val = sd->exposure & 0xf;
792 sensor_write1(gspca_dev, 4, val);
793 } else {
794 u8 clockdiv;
795 int exposure;
796
797 /* We have both a clock divider and an exposure register.
798 We first calculate the clock divider, as that determines
799 the maximum exposure and then we calculayte the exposure
800 register setting (which goes from 0 - 511).
801
802 Note our 0 - 4095 exposure is mapped to 0 - 511
803 milliseconds exposure time */
804 clockdiv = (60 * sd->exposure + 7999) / 8000;
805
806 /* Limit framerate to not exceed usb bandwidth */
807 if (clockdiv < 3 && gspca_dev->width >= 320)
808 clockdiv = 3;
809 else if (clockdiv < 2)
810 clockdiv = 2;
811
812 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
813 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
814 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
815 if (exposure > 511)
816 exposure = 511;
817
818 /* exposure register value is reversed! */
819 exposure = 511 - exposure;
820
821 sensor_write1(gspca_dev, 0x02, clockdiv);
822 sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
823 sensor_write1(gspca_dev, 0x0f, exposure >> 8);
824 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300825}
826
827static void setgain(struct gspca_dev *gspca_dev)
828{
829 struct sd *sd = (struct sd *) gspca_dev;
830
Hans de Goede9ac69782009-08-14 10:15:52 -0300831 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
832 return;
833
Hans de Goedea2e081b2009-08-14 17:11:36 -0300834 if (sd->sensor_type) {
Hans de Goede823902d2009-08-17 12:25:17 -0300835 sensor_write1(gspca_dev, 0x0e, sd->gain);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300836 } else {
837 sensor_write1(gspca_dev, 0x10, sd->gain);
838 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300839}
840
841static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
842{
843 struct sd *sd = (struct sd *) gspca_dev;
844
845 sd->brightness = val;
846 if (gspca_dev->streaming)
847 setbrightness(gspca_dev);
848 return 0;
849}
850
851static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
852{
853 struct sd *sd = (struct sd *) gspca_dev;
854
855 *val = sd->brightness;
856 return 0;
857}
858
859static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
860{
861 struct sd *sd = (struct sd *) gspca_dev;
862
863 sd->exposure = val;
864 if (gspca_dev->streaming)
865 setexposure(gspca_dev);
866 return 0;
867}
868
869static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
870{
871 struct sd *sd = (struct sd *) gspca_dev;
872
873 *val = sd->exposure;
874 return 0;
875}
876
877static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
878{
879 struct sd *sd = (struct sd *) gspca_dev;
880
881 sd->gain = val;
882 if (gspca_dev->streaming)
883 setgain(gspca_dev);
884 return 0;
885}
886
887static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
888{
889 struct sd *sd = (struct sd *) gspca_dev;
890
891 *val = sd->gain;
892 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -0300893}
894
895/* Include pac common sof detection functions */
896#include "pac_common.h"
897
898static void sd_pkt_scan(struct gspca_dev *gspca_dev,
899 struct gspca_frame *frame, /* target */
900 __u8 *data, /* isoc packet */
901 int len) /* iso packet length */
902{
Kyle Guinnd661e622009-01-16 05:36:14 -0300903 unsigned char *sof;
904
905 sof = pac_find_sof(gspca_dev, data, len);
906 if (sof) {
907 int n;
908
909 /* finish decoding current frame */
910 n = sof - data;
911 if (n > sizeof pac_sof_marker)
912 n -= sizeof pac_sof_marker;
913 else
914 n = 0;
915 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
916 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -0300917 /* Start next frame. */
918 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
919 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -0300920 len -= sof - data;
921 data = sof;
922 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300923 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
924}
925
926/* sub-driver description */
927static const struct sd_desc sd_desc = {
928 .name = MODULE_NAME,
929 .ctrls = sd_ctrls,
930 .nctrls = ARRAY_SIZE(sd_ctrls),
931 .config = sd_config,
932 .init = sd_init,
933 .start = sd_start,
934 .stopN = sd_stopN,
935 .pkt_scan = sd_pkt_scan,
936};
937
938/* -- module initialisation -- */
939static const __devinitdata struct usb_device_id device_table[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300940 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
941 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
942 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -0300943 {}
944};
945MODULE_DEVICE_TABLE(usb, device_table);
946
947/* -- device connect -- */
948static int sd_probe(struct usb_interface *intf,
949 const struct usb_device_id *id)
950{
951 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
952 THIS_MODULE);
953}
954
955static struct usb_driver sd_driver = {
956 .name = MODULE_NAME,
957 .id_table = device_table,
958 .probe = sd_probe,
959 .disconnect = gspca_disconnect,
960#ifdef CONFIG_PM
961 .suspend = gspca_suspend,
962 .resume = gspca_resume,
963#endif
964};
965
966/* -- module insert / remove -- */
967static int __init sd_mod_init(void)
968{
Alexey Klimov5d3fa302009-03-27 15:57:46 -0300969 int ret;
970
971 ret = usb_register(&sd_driver);
972 if (ret < 0)
973 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -0300974 PDEBUG(D_PROBE, "registered");
975 return 0;
976}
977static void __exit sd_mod_exit(void)
978{
979 usb_deregister(&sd_driver);
980 PDEBUG(D_PROBE, "deregistered");
981}
982
983module_init(sd_mod_init);
984module_exit(sd_mod_exit);