blob: 1ee3d1ee5a406054883417cf0a8a7d9c132a0742 [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
60/* specific webcam descriptor */
61struct sd {
62 struct gspca_dev gspca_dev; /* !! must be the first item */
Kyle Guinnd661e622009-01-16 05:36:14 -030063 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030064 u8 cam_type; /* 0 is CIF and 1 is VGA */
65 u8 sensor_type; /* We use 0 and 1 here, too. */
66 u8 do_lcd_stop;
Theodore Kilgore89f08632009-08-14 06:51:52 -030067
68 int brightness;
69 u16 exposure;
Theodore Kilgore89f08632009-08-14 06:51:52 -030070 u8 gain;
Kyle Guinnd661e622009-01-16 05:36:14 -030071};
72
Theodore Kilgore89f08632009-08-14 06:51:52 -030073struct sensor_w_data {
74 u8 reg;
75 u8 flags;
76 u8 data[16];
77 int len;
78};
79
80static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede9ac69782009-08-14 10:15:52 -030086static void setbrightness(struct gspca_dev *gspca_dev);
87static void setexposure(struct gspca_dev *gspca_dev);
88static void setgain(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -030089
Kyle Guinnd661e622009-01-16 05:36:14 -030090/* V4L2 controls supported by the driver */
91static struct ctrl sd_ctrls[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -030092 {
Hans de Goede9ac69782009-08-14 10:15:52 -030093#define BRIGHTNESS_IDX 0
Theodore Kilgore89f08632009-08-14 06:51:52 -030094 {
95 .id = V4L2_CID_BRIGHTNESS,
96 .type = V4L2_CTRL_TYPE_INTEGER,
97 .name = "Brightness",
98 .minimum = MR97310A_BRIGHTNESS_MIN,
99 .maximum = MR97310A_BRIGHTNESS_MAX,
100 .step = 1,
101 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
102 .flags = 0,
103 },
104 .set = sd_setbrightness,
105 .get = sd_getbrightness,
106 },
107 {
Hans de Goede9ac69782009-08-14 10:15:52 -0300108#define EXPOSURE_IDX 1
Theodore Kilgore89f08632009-08-14 06:51:52 -0300109 {
110 .id = V4L2_CID_EXPOSURE,
111 .type = V4L2_CTRL_TYPE_INTEGER,
112 .name = "Exposure",
113 .minimum = MR97310A_EXPOSURE_MIN,
114 .maximum = MR97310A_EXPOSURE_MAX,
115 .step = 1,
116 .default_value = MR97310A_EXPOSURE_DEFAULT,
117 .flags = 0,
118 },
119 .set = sd_setexposure,
120 .get = sd_getexposure,
121 },
122 {
Hans de Goede9ac69782009-08-14 10:15:52 -0300123#define GAIN_IDX 2
Theodore Kilgore89f08632009-08-14 06:51:52 -0300124 {
125 .id = V4L2_CID_GAIN,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Gain",
128 .minimum = MR97310A_GAIN_MIN,
129 .maximum = MR97310A_GAIN_MAX,
130 .step = 1,
131 .default_value = MR97310A_GAIN_DEFAULT,
132 .flags = 0,
133 },
134 .set = sd_setgain,
135 .get = sd_getgain,
136 },
Kyle Guinnd661e622009-01-16 05:36:14 -0300137};
138
139static const struct v4l2_pix_format vga_mode[] = {
140 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
141 .bytesperline = 160,
142 .sizeimage = 160 * 120,
143 .colorspace = V4L2_COLORSPACE_SRGB,
144 .priv = 4},
145 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
146 .bytesperline = 176,
147 .sizeimage = 176 * 144,
148 .colorspace = V4L2_COLORSPACE_SRGB,
149 .priv = 3},
150 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
151 .bytesperline = 320,
152 .sizeimage = 320 * 240,
153 .colorspace = V4L2_COLORSPACE_SRGB,
154 .priv = 2},
155 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
156 .bytesperline = 352,
157 .sizeimage = 352 * 288,
158 .colorspace = V4L2_COLORSPACE_SRGB,
159 .priv = 1},
160 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
161 .bytesperline = 640,
162 .sizeimage = 640 * 480,
163 .colorspace = V4L2_COLORSPACE_SRGB,
164 .priv = 0},
165};
166
167/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300168static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300169{
170 int rc;
171
172 rc = usb_bulk_msg(gspca_dev->dev,
173 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300174 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300175 if (rc < 0)
176 PDEBUG(D_ERR, "reg write [%02x] error %d",
177 gspca_dev->usb_buf[0], rc);
178 return rc;
179}
180
Theodore Kilgore89f08632009-08-14 06:51:52 -0300181/* the bytes are read into gspca_dev->usb_buf */
182static int mr_read(struct gspca_dev *gspca_dev, int len)
183{
184 int rc;
185
186 rc = usb_bulk_msg(gspca_dev->dev,
187 usb_rcvbulkpipe(gspca_dev->dev, 3),
188 gspca_dev->usb_buf, len, NULL, 500);
189 if (rc < 0)
190 PDEBUG(D_ERR, "reg read [%02x] error %d",
191 gspca_dev->usb_buf[0], rc);
192 return rc;
193}
194
195static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
196 const u8 *data, int len)
197{
198 gspca_dev->usb_buf[0] = 0x1f;
199 gspca_dev->usb_buf[1] = flags;
200 gspca_dev->usb_buf[2] = reg;
201 memcpy(gspca_dev->usb_buf + 3, data, len);
202
203 return mr_write(gspca_dev, len + 3);
204}
205
206static int sensor_write_regs(struct gspca_dev *gspca_dev,
207 const struct sensor_w_data *data, int len)
208{
209 int i, rc;
210
211 for (i = 0; i < len; i++) {
212 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
213 data[i].data, data[i].len);
214 if (rc < 0)
215 return rc;
216 }
217
218 return 0;
219}
220
221static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
222{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300223 struct sd *sd = (struct sd *) gspca_dev;
224 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300225 int rc;
226
227 buf = data;
228 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
229 if (rc < 0)
230 return rc;
231
232 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300233 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
234 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300235 if (rc < 0)
236 return rc;
237
238 return 0;
239}
240
241static int cam_get_response16(struct gspca_dev *gspca_dev)
242{
243 __u8 *data = gspca_dev->usb_buf;
244 int err_code;
245
246 data[0] = 0x21;
247 err_code = mr_write(gspca_dev, 1);
248 if (err_code < 0)
249 return err_code;
250
251 err_code = mr_read(gspca_dev, 16);
252 return err_code;
253}
254
255static int zero_the_pointer(struct gspca_dev *gspca_dev)
256{
257 __u8 *data = gspca_dev->usb_buf;
258 int err_code;
259 u8 status = 0;
260 int tries = 0;
261
262 err_code = cam_get_response16(gspca_dev);
263 if (err_code < 0)
264 return err_code;
265
266 err_code = mr_write(gspca_dev, 1);
267 data[0] = 0x19;
268 data[1] = 0x51;
269 err_code = mr_write(gspca_dev, 2);
270 if (err_code < 0)
271 return err_code;
272
273 err_code = cam_get_response16(gspca_dev);
274 if (err_code < 0)
275 return err_code;
276
277 data[0] = 0x19;
278 data[1] = 0xba;
279 err_code = mr_write(gspca_dev, 2);
280 if (err_code < 0)
281 return err_code;
282
283 err_code = cam_get_response16(gspca_dev);
284 if (err_code < 0)
285 return err_code;
286
287 data[0] = 0x19;
288 data[1] = 0x00;
289 err_code = mr_write(gspca_dev, 2);
290 if (err_code < 0)
291 return err_code;
292
293 err_code = cam_get_response16(gspca_dev);
294 if (err_code < 0)
295 return err_code;
296
297 data[0] = 0x19;
298 data[1] = 0x00;
299 err_code = mr_write(gspca_dev, 2);
300 if (err_code < 0)
301 return err_code;
302
303 while (status != 0x0a && tries < 256) {
304 err_code = cam_get_response16(gspca_dev);
305 status = data[0];
306 tries++;
307 if (err_code < 0)
308 return err_code;
309 }
Hans de Goede54943782009-08-14 11:05:38 -0300310 if (status != 0x0a)
311 PDEBUG(D_ERR, "status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300312
313 tries = 0;
314 while (tries < 4) {
315 data[0] = 0x19;
316 data[1] = 0x00;
317 err_code = mr_write(gspca_dev, 2);
318 if (err_code < 0)
319 return err_code;
320
321 err_code = cam_get_response16(gspca_dev);
322 status = data[0];
323 tries++;
324 if (err_code < 0)
325 return err_code;
326 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300327
328 data[0] = 0x19;
329 err_code = mr_write(gspca_dev, 1);
330 if (err_code < 0)
331 return err_code;
332
333 err_code = mr_read(gspca_dev, 16);
334 if (err_code < 0)
335 return err_code;
336
337 return 0;
338}
339
340static u8 get_sensor_id(struct gspca_dev *gspca_dev)
341{
342 int err_code;
343
344 gspca_dev->usb_buf[0] = 0x1e;
345 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);
350 if (err_code < 0)
351 return err_code;
352
Hans de Goede54943782009-08-14 11:05:38 -0300353 PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300354
355 return gspca_dev->usb_buf[0];
356}
357
Kyle Guinnd661e622009-01-16 05:36:14 -0300358/* this function is called at probe time */
359static int sd_config(struct gspca_dev *gspca_dev,
360 const struct usb_device_id *id)
361{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300362 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300363 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300364 __u8 *data = gspca_dev->usb_buf;
365 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300366
367 cam = &gspca_dev->cam;
368 cam->cam_mode = vga_mode;
369 cam->nmodes = ARRAY_SIZE(vga_mode);
Hans de Goede9ac69782009-08-14 10:15:52 -0300370
Theodore Kilgore89f08632009-08-14 06:51:52 -0300371 if (id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300372 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300373 cam->nmodes--;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300374
375 data[0] = 0x01;
376 data[1] = 0x01;
377 err_code = mr_write(gspca_dev, 2);
378 if (err_code < 0)
379 return err_code;
380
381 msleep(200);
382 data[0] = get_sensor_id(gspca_dev);
383 /*
384 * Known CIF cameras. If you have another to report, please do
385 *
386 * Name byte just read sd->sensor_type
387 * reported by
388 * Sakar Spy-shot 0x28 T. Kilgore 0
389 * Innovage 0xf5 (unstable) T. Kilgore 0
390 * Vivitar Mini 0x53 H. De Goede 0
391 * Vivitar Mini 0x08 T. Kilgore 1
392 * Elta-Media 8212dc 0x23 T. Kaiser 1
393 * Philips dig. keych. 0x37 T. Kilgore 1
394 */
395 if ((data[0] & 0x78) == 8 ||
396 ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
397 sd->sensor_type = 1;
398 else
399 sd->sensor_type = 0;
400
Hans de Goede54943782009-08-14 11:05:38 -0300401 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
402 sd->sensor_type);
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300403
404 if (sd->sensor_type == 0)
Hans de Goedea2e081b2009-08-14 17:11:36 -0300405 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300406 } else {
407 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede54943782009-08-14 11:05:38 -0300408 PDEBUG(D_PROBE, "MR97310A VGA camera detected");
Hans de Goede9ac69782009-08-14 10:15:52 -0300409 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
410 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300411 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300412
413 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
414 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
415 sd->gain = MR97310A_GAIN_DEFAULT;
416
Kyle Guinnd661e622009-01-16 05:36:14 -0300417 return 0;
418}
419
420/* this function is called at probe and resume time */
421static int sd_init(struct gspca_dev *gspca_dev)
422{
423 return 0;
424}
425
Theodore Kilgore89f08632009-08-14 06:51:52 -0300426static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300427{
428 struct sd *sd = (struct sd *) gspca_dev;
429 __u8 *data = gspca_dev->usb_buf;
430 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300431 const __u8 startup_string[] = {
432 0x00,
433 0x0d,
434 0x01,
435 0x00, /* Hsize/8 for 352 or 320 */
436 0x00, /* Vsize/4 for 288 or 240 */
437 0x13, /* or 0xbb, depends on sensor */
438 0x00, /* Hstart, depends on res. */
439 0x00, /* reserved ? */
440 0x00, /* Vstart, depends on res. and sensor */
441 0x50, /* 0x54 to get 176 or 160 */
442 0xc0
443 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300444
Theodore Kilgore89f08632009-08-14 06:51:52 -0300445 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300446 data[0] = 0x01;
447 data[1] = 0x01;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300448 err_code = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300449 if (err_code < 0)
450 return err_code;
451
Theodore Kilgore89f08632009-08-14 06:51:52 -0300452 memcpy(data, startup_string, 11);
453 if (sd->sensor_type)
454 data[5] = 0xbb;
455
456 switch (gspca_dev->width) {
457 case 160:
458 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
459 /* fall thru */
460 case 320:
461 default:
462 data[3] = 0x28; /* reg 2, H size/8 */
463 data[4] = 0x3c; /* reg 3, V size/4 */
464 data[6] = 0x14; /* reg 5, H start */
465 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
466 break;
467 case 176:
468 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
469 /* fall thru */
470 case 352:
471 data[3] = 0x2c; /* reg 2, H size/8 */
472 data[4] = 0x48; /* reg 3, V size/4 */
473 data[6] = 0x06; /* reg 5, H start */
474 data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
475 break;
476 }
477 err_code = mr_write(gspca_dev, 11);
478 if (err_code < 0)
479 return err_code;
480
481 if (!sd->sensor_type) {
482 const struct sensor_w_data cif_sensor0_init_data[] = {
483 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
484 0x0f, 0x14, 0x0f, 0x10}, 8},
485 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
486 {0x12, 0x00, {0x07}, 1},
487 {0x1f, 0x00, {0x06}, 1},
488 {0x27, 0x00, {0x04}, 1},
489 {0x29, 0x00, {0x0c}, 1},
490 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
491 {0x50, 0x00, {0x60}, 1},
492 {0x60, 0x00, {0x06}, 1},
493 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
494 {0x72, 0x00, {0x1e, 0x56}, 2},
495 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
496 0x31, 0x80, 0x00}, 9},
497 {0x11, 0x00, {0x01}, 1},
498 {0, 0, {0}, 0}
499 };
500 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
501 ARRAY_SIZE(cif_sensor0_init_data));
502 } else { /* sd->sensor_type = 1 */
503 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300504 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300505 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300506 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
507 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300508 {0x09, 0x02, {0x0e}, 1},
509 {0x0a, 0x02, {0x05}, 1},
510 {0x0b, 0x02, {0x05}, 1},
511 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300512 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300513 {0x0e, 0x02, {0x0c}, 1},
514 {0x0f, 0x00, {0x00}, 1},
515 {0x10, 0x00, {0x06}, 1},
516 {0x11, 0x00, {0x07}, 1},
517 {0x12, 0x00, {0x00}, 1},
518 {0x13, 0x00, {0x01}, 1},
519 {0, 0, {0}, 0}
520 };
521 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
522 ARRAY_SIZE(cif_sensor1_init_data));
523 }
524 if (err_code < 0)
525 return err_code;
526
Hans de Goede9ac69782009-08-14 10:15:52 -0300527 setbrightness(gspca_dev);
528 setexposure(gspca_dev);
529 setgain(gspca_dev);
530
Theodore Kilgore89f08632009-08-14 06:51:52 -0300531 msleep(200);
Hans de Goede9ac69782009-08-14 10:15:52 -0300532
Kyle Guinnd661e622009-01-16 05:36:14 -0300533 data[0] = 0x00;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300534 data[1] = 0x4d; /* ISOC transfering enable... */
535 err_code = mr_write(gspca_dev, 2);
536 if (err_code < 0)
537 return err_code;
538
Theodore Kilgore89f08632009-08-14 06:51:52 -0300539 return 0;
540}
541
542static int start_vga_cam(struct gspca_dev *gspca_dev)
543{
544 struct sd *sd = (struct sd *) gspca_dev;
545 __u8 *data = gspca_dev->usb_buf;
546 int err_code;
547 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
548 0x00, 0x00, 0x00, 0x50, 0xc0};
549
550 /* What some of these mean is explained in start_cif_cam(), above */
551 sd->sof_read = 0;
552
553 /*
554 * We have to know which camera we have, because the register writes
555 * depend upon the camera. This test, run before we actually enter
556 * the initialization routine, distinguishes most of the cameras, If
557 * needed, another routine is done later, too.
558 */
559 memset(data, 0, 16);
560 data[0] = 0x20;
561 err_code = mr_write(gspca_dev, 1);
562 if (err_code < 0)
563 return err_code;
564
565 err_code = mr_read(gspca_dev, 16);
566 if (err_code < 0)
567 return err_code;
568
Hans de Goede54943782009-08-14 11:05:38 -0300569 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300570
571 msleep(200);
572 /*
573 * Known VGA cameras. If you have another to report, please do
574 *
575 * Name byte just read sd->sensor_type
576 * sd->do_lcd_stop
577 * Aiptek Pencam VGA+ 0x31 0 1
578 * ION digital 0x31 0 1
579 * Argus DC-1620 0x30 1 0
580 * Argus QuickClix 0x30 1 1 (not caught here)
581 */
582 sd->sensor_type = data[0] & 1;
583 sd->do_lcd_stop = (~data[0]) & 1;
584
585
586
587 /* Streaming setup begins here. */
588
589
590 data[0] = 0x01;
591 data[1] = 0x01;
592 err_code = mr_write(gspca_dev, 2);
593 if (err_code < 0)
594 return err_code;
595
596 /*
597 * A second test can now resolve any remaining ambiguity in the
598 * identification of the camera type,
599 */
600 if (!sd->sensor_type) {
601 data[0] = get_sensor_id(gspca_dev);
602 if (data[0] == 0x7f) {
603 sd->sensor_type = 1;
Hans de Goede54943782009-08-14 11:05:38 -0300604 PDEBUG(D_PROBE, "sensor_type corrected to 1");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300605 }
606 msleep(200);
607 }
608
609 /*
610 * Known VGA cameras.
611 * This test is only run if the previous test returned 0x30, but
612 * here is the information for all others, too, just for reference.
613 *
614 * Name byte just read sd->sensor_type
615 *
616 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
617 * ION digital 0xbd (this test not run) 1
618 * Argus DC-1620 0xe5 (no change) 0
619 * Argus QuickClix 0x7f (reclassified) 1
620 */
621 memcpy(data, startup_string, 11);
622 if (!sd->sensor_type) {
623 data[5] = 0x00;
624 data[10] = 0x91;
625 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300626
627 switch (gspca_dev->width) {
628 case 160:
629 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
630 /* fall thru */
631 case 320:
632 data[9] |= 0x04; /* reg 8, 2:1 scale down */
633 /* fall thru */
634 case 640:
635 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300636 data[3] = 0x50; /* reg 2, H size/8 */
637 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300638 data[6] = 0x04; /* reg 5, H start */
639 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300640 if (sd->do_lcd_stop)
641 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300642 break;
643
644 case 176:
645 data[9] |= 0x04; /* reg 8, 2:1 scale down */
646 /* fall thru */
647 case 352:
648 data[3] = 0x2c; /* reg 2, H size */
649 data[4] = 0x48; /* reg 3, V size */
650 data[6] = 0x94; /* reg 5, H start */
651 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300652 if (sd->do_lcd_stop)
653 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300654 break;
655 }
656
Theodore Kilgore89f08632009-08-14 06:51:52 -0300657 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300658 if (err_code < 0)
659 return err_code;
660
Theodore Kilgore89f08632009-08-14 06:51:52 -0300661 if (!sd->sensor_type) {
662 /* The only known sensor_type 0 cam is the Argus DC-1620 */
663 const struct sensor_w_data vga_sensor0_init_data[] = {
664 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
665 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
666 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
667 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
668 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
669 {0, 0, {0}, 0}
670 };
671 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
672 ARRAY_SIZE(vga_sensor0_init_data));
673 } else { /* sd->sensor_type = 1 */
674 const struct sensor_w_data vga_sensor1_init_data[] = {
675 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
676 0x07, 0x00, 0x01}, 8},
677 {0x11, 0x04, {0x01}, 1},
678 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
679 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
680 0x00, 0x0a}, 7},
681 {0x11, 0x04, {0x01}, 1},
682 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
683 {0x11, 0x04, {0x01}, 1},
684 {0, 0, {0}, 0}
685 };
686 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
687 ARRAY_SIZE(vga_sensor1_init_data));
688 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300689 if (err_code < 0)
690 return err_code;
691
Theodore Kilgore89f08632009-08-14 06:51:52 -0300692 msleep(200);
Kyle Guinnd661e622009-01-16 05:36:14 -0300693 data[0] = 0x00;
694 data[1] = 0x4d; /* ISOC transfering enable... */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300695 err_code = mr_write(gspca_dev, 2);
696
697 return err_code;
698}
699
700static int sd_start(struct gspca_dev *gspca_dev)
701{
702 struct sd *sd = (struct sd *) gspca_dev;
703 int err_code;
704 struct cam *cam;
705
Theodore Kilgore89f08632009-08-14 06:51:52 -0300706 cam = &gspca_dev->cam;
707 sd->sof_read = 0;
708 /*
709 * Some of the supported cameras require the memory pointer to be
710 * set to 0, or else they will not stream.
711 */
712 zero_the_pointer(gspca_dev);
713 msleep(200);
714 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300715 err_code = start_cif_cam(gspca_dev);
716 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300717 err_code = start_vga_cam(gspca_dev);
718 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300719 return err_code;
720}
721
722static void sd_stopN(struct gspca_dev *gspca_dev)
723{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300724 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300725 int result;
726
727 gspca_dev->usb_buf[0] = 1;
728 gspca_dev->usb_buf[1] = 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300729 result = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300730 if (result < 0)
731 PDEBUG(D_ERR, "Camera Stop failed");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300732
733 /* Not all the cams need this, but even if not, probably a good idea */
734 zero_the_pointer(gspca_dev);
735 if (sd->do_lcd_stop) {
736 gspca_dev->usb_buf[0] = 0x19;
737 gspca_dev->usb_buf[1] = 0x54;
738 result = mr_write(gspca_dev, 2);
739 if (result < 0)
740 PDEBUG(D_ERR, "Camera Stop failed");
741 }
742}
743
744static void setbrightness(struct gspca_dev *gspca_dev)
745{
746 struct sd *sd = (struct sd *) gspca_dev;
747 u8 val;
Hans de Goede9ac69782009-08-14 10:15:52 -0300748
749 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
750 return;
751
752 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300753 if (sd->brightness > 0) {
Hans de Goede9ac69782009-08-14 10:15:52 -0300754 sensor_write1(gspca_dev, 7, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300755 val = sd->brightness;
756 } else {
Hans de Goede9ac69782009-08-14 10:15:52 -0300757 sensor_write1(gspca_dev, 7, 0x01);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300758 val = 257 - sd->brightness;
759 }
760 sensor_write1(gspca_dev, 8, val);
761}
762
763static void setexposure(struct gspca_dev *gspca_dev)
764{
765 struct sd *sd = (struct sd *) gspca_dev;
766 u8 val;
767
Hans de Goede9ac69782009-08-14 10:15:52 -0300768 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
769 return;
770
Hans de Goedea2e081b2009-08-14 17:11:36 -0300771 if (sd->sensor_type) {
772 val = sd->exposure >> 4;
773 sensor_write1(gspca_dev, 3, val);
774 val = sd->exposure & 0xf;
775 sensor_write1(gspca_dev, 4, val);
776 } else {
777 u8 clockdiv;
778 int exposure;
779
780 /* We have both a clock divider and an exposure register.
781 We first calculate the clock divider, as that determines
782 the maximum exposure and then we calculayte the exposure
783 register setting (which goes from 0 - 511).
784
785 Note our 0 - 4095 exposure is mapped to 0 - 511
786 milliseconds exposure time */
787 clockdiv = (60 * sd->exposure + 7999) / 8000;
788
789 /* Limit framerate to not exceed usb bandwidth */
790 if (clockdiv < 3 && gspca_dev->width >= 320)
791 clockdiv = 3;
792 else if (clockdiv < 2)
793 clockdiv = 2;
794
795 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
796 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
797 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
798 if (exposure > 511)
799 exposure = 511;
800
801 /* exposure register value is reversed! */
802 exposure = 511 - exposure;
803
804 sensor_write1(gspca_dev, 0x02, clockdiv);
805 sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
806 sensor_write1(gspca_dev, 0x0f, exposure >> 8);
807 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300808}
809
810static void setgain(struct gspca_dev *gspca_dev)
811{
812 struct sd *sd = (struct sd *) gspca_dev;
813
Hans de Goede9ac69782009-08-14 10:15:52 -0300814 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
815 return;
816
Hans de Goedea2e081b2009-08-14 17:11:36 -0300817 if (sd->sensor_type) {
818 sensor_write1(gspca_dev, 3, sd->gain);
819 } else {
820 sensor_write1(gspca_dev, 0x10, sd->gain);
821 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300822}
823
824static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
825{
826 struct sd *sd = (struct sd *) gspca_dev;
827
828 sd->brightness = val;
829 if (gspca_dev->streaming)
830 setbrightness(gspca_dev);
831 return 0;
832}
833
834static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
835{
836 struct sd *sd = (struct sd *) gspca_dev;
837
838 *val = sd->brightness;
839 return 0;
840}
841
842static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
843{
844 struct sd *sd = (struct sd *) gspca_dev;
845
846 sd->exposure = val;
847 if (gspca_dev->streaming)
848 setexposure(gspca_dev);
849 return 0;
850}
851
852static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
853{
854 struct sd *sd = (struct sd *) gspca_dev;
855
856 *val = sd->exposure;
857 return 0;
858}
859
860static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
861{
862 struct sd *sd = (struct sd *) gspca_dev;
863
864 sd->gain = val;
865 if (gspca_dev->streaming)
866 setgain(gspca_dev);
867 return 0;
868}
869
870static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
871{
872 struct sd *sd = (struct sd *) gspca_dev;
873
874 *val = sd->gain;
875 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -0300876}
877
878/* Include pac common sof detection functions */
879#include "pac_common.h"
880
881static void sd_pkt_scan(struct gspca_dev *gspca_dev,
882 struct gspca_frame *frame, /* target */
883 __u8 *data, /* isoc packet */
884 int len) /* iso packet length */
885{
Kyle Guinnd661e622009-01-16 05:36:14 -0300886 unsigned char *sof;
887
888 sof = pac_find_sof(gspca_dev, data, len);
889 if (sof) {
890 int n;
891
892 /* finish decoding current frame */
893 n = sof - data;
894 if (n > sizeof pac_sof_marker)
895 n -= sizeof pac_sof_marker;
896 else
897 n = 0;
898 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
899 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -0300900 /* Start next frame. */
901 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
902 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -0300903 len -= sof - data;
904 data = sof;
905 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300906 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
907}
908
909/* sub-driver description */
910static const struct sd_desc sd_desc = {
911 .name = MODULE_NAME,
912 .ctrls = sd_ctrls,
913 .nctrls = ARRAY_SIZE(sd_ctrls),
914 .config = sd_config,
915 .init = sd_init,
916 .start = sd_start,
917 .stopN = sd_stopN,
918 .pkt_scan = sd_pkt_scan,
919};
920
921/* -- module initialisation -- */
922static const __devinitdata struct usb_device_id device_table[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300923 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
924 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
925 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -0300926 {}
927};
928MODULE_DEVICE_TABLE(usb, device_table);
929
930/* -- device connect -- */
931static int sd_probe(struct usb_interface *intf,
932 const struct usb_device_id *id)
933{
934 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
935 THIS_MODULE);
936}
937
938static struct usb_driver sd_driver = {
939 .name = MODULE_NAME,
940 .id_table = device_table,
941 .probe = sd_probe,
942 .disconnect = gspca_disconnect,
943#ifdef CONFIG_PM
944 .suspend = gspca_suspend,
945 .resume = gspca_resume,
946#endif
947};
948
949/* -- module insert / remove -- */
950static int __init sd_mod_init(void)
951{
Alexey Klimov5d3fa302009-03-27 15:57:46 -0300952 int ret;
953
954 ret = usb_register(&sd_driver);
955 if (ret < 0)
956 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -0300957 PDEBUG(D_PROBE, "registered");
958 return 0;
959}
960static void __exit sd_mod_exit(void)
961{
962 usb_deregister(&sd_driver);
963 PDEBUG(D_PROBE, "deregistered");
964}
965
966module_init(sd_mod_init);
967module_exit(sd_mod_exit);