blob: 7540ea94e1a9aee5504e98606b93f2f5beeed25f [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{
223 u8 buf;
224 int rc;
225
226 buf = data;
227 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
228 if (rc < 0)
229 return rc;
230
231 buf = 0x01;
232 rc = sensor_write_reg(gspca_dev, 0x13, 0x00, &buf, 1);
233 if (rc < 0)
234 return rc;
235
236 return 0;
237}
238
239static int cam_get_response16(struct gspca_dev *gspca_dev)
240{
241 __u8 *data = gspca_dev->usb_buf;
242 int err_code;
243
244 data[0] = 0x21;
245 err_code = mr_write(gspca_dev, 1);
246 if (err_code < 0)
247 return err_code;
248
249 err_code = mr_read(gspca_dev, 16);
250 return err_code;
251}
252
253static int zero_the_pointer(struct gspca_dev *gspca_dev)
254{
255 __u8 *data = gspca_dev->usb_buf;
256 int err_code;
257 u8 status = 0;
258 int tries = 0;
259
260 err_code = cam_get_response16(gspca_dev);
261 if (err_code < 0)
262 return err_code;
263
264 err_code = mr_write(gspca_dev, 1);
265 data[0] = 0x19;
266 data[1] = 0x51;
267 err_code = mr_write(gspca_dev, 2);
268 if (err_code < 0)
269 return err_code;
270
271 err_code = cam_get_response16(gspca_dev);
272 if (err_code < 0)
273 return err_code;
274
275 data[0] = 0x19;
276 data[1] = 0xba;
277 err_code = mr_write(gspca_dev, 2);
278 if (err_code < 0)
279 return err_code;
280
281 err_code = cam_get_response16(gspca_dev);
282 if (err_code < 0)
283 return err_code;
284
285 data[0] = 0x19;
286 data[1] = 0x00;
287 err_code = mr_write(gspca_dev, 2);
288 if (err_code < 0)
289 return err_code;
290
291 err_code = cam_get_response16(gspca_dev);
292 if (err_code < 0)
293 return err_code;
294
295 data[0] = 0x19;
296 data[1] = 0x00;
297 err_code = mr_write(gspca_dev, 2);
298 if (err_code < 0)
299 return err_code;
300
301 while (status != 0x0a && tries < 256) {
302 err_code = cam_get_response16(gspca_dev);
303 status = data[0];
304 tries++;
305 if (err_code < 0)
306 return err_code;
307 }
Hans de Goede54943782009-08-14 11:05:38 -0300308 if (status != 0x0a)
309 PDEBUG(D_ERR, "status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300310
311 tries = 0;
312 while (tries < 4) {
313 data[0] = 0x19;
314 data[1] = 0x00;
315 err_code = mr_write(gspca_dev, 2);
316 if (err_code < 0)
317 return err_code;
318
319 err_code = cam_get_response16(gspca_dev);
320 status = data[0];
321 tries++;
322 if (err_code < 0)
323 return err_code;
324 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300325
326 data[0] = 0x19;
327 err_code = mr_write(gspca_dev, 1);
328 if (err_code < 0)
329 return err_code;
330
331 err_code = mr_read(gspca_dev, 16);
332 if (err_code < 0)
333 return err_code;
334
335 return 0;
336}
337
338static u8 get_sensor_id(struct gspca_dev *gspca_dev)
339{
340 int err_code;
341
342 gspca_dev->usb_buf[0] = 0x1e;
343 err_code = mr_write(gspca_dev, 1);
344 if (err_code < 0)
345 return err_code;
346
347 err_code = mr_read(gspca_dev, 16);
348 if (err_code < 0)
349 return err_code;
350
Hans de Goede54943782009-08-14 11:05:38 -0300351 PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300352
353 return gspca_dev->usb_buf[0];
354}
355
Kyle Guinnd661e622009-01-16 05:36:14 -0300356/* this function is called at probe time */
357static int sd_config(struct gspca_dev *gspca_dev,
358 const struct usb_device_id *id)
359{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300360 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300361 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300362 __u8 *data = gspca_dev->usb_buf;
363 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300364
365 cam = &gspca_dev->cam;
366 cam->cam_mode = vga_mode;
367 cam->nmodes = ARRAY_SIZE(vga_mode);
Hans de Goede9ac69782009-08-14 10:15:52 -0300368
Theodore Kilgore89f08632009-08-14 06:51:52 -0300369 if (id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300370 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300371 cam->nmodes--;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300372
373 data[0] = 0x01;
374 data[1] = 0x01;
375 err_code = mr_write(gspca_dev, 2);
376 if (err_code < 0)
377 return err_code;
378
379 msleep(200);
380 data[0] = get_sensor_id(gspca_dev);
381 /*
382 * Known CIF cameras. If you have another to report, please do
383 *
384 * Name byte just read sd->sensor_type
385 * reported by
386 * Sakar Spy-shot 0x28 T. Kilgore 0
387 * Innovage 0xf5 (unstable) T. Kilgore 0
388 * Vivitar Mini 0x53 H. De Goede 0
389 * Vivitar Mini 0x08 T. Kilgore 1
390 * Elta-Media 8212dc 0x23 T. Kaiser 1
391 * Philips dig. keych. 0x37 T. Kilgore 1
392 */
393 if ((data[0] & 0x78) == 8 ||
394 ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
395 sd->sensor_type = 1;
396 else
397 sd->sensor_type = 0;
398
Hans de Goede54943782009-08-14 11:05:38 -0300399 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
400 sd->sensor_type);
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300401
402 if (sd->sensor_type == 0)
403 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
404 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300405 } else {
406 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede54943782009-08-14 11:05:38 -0300407 PDEBUG(D_PROBE, "MR97310A VGA camera detected");
Hans de Goede9ac69782009-08-14 10:15:52 -0300408 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
409 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300410 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300411
412 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
413 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
414 sd->gain = MR97310A_GAIN_DEFAULT;
415
Kyle Guinnd661e622009-01-16 05:36:14 -0300416 return 0;
417}
418
419/* this function is called at probe and resume time */
420static int sd_init(struct gspca_dev *gspca_dev)
421{
422 return 0;
423}
424
Theodore Kilgore89f08632009-08-14 06:51:52 -0300425static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300426{
427 struct sd *sd = (struct sd *) gspca_dev;
428 __u8 *data = gspca_dev->usb_buf;
429 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300430 const __u8 startup_string[] = {
431 0x00,
432 0x0d,
433 0x01,
434 0x00, /* Hsize/8 for 352 or 320 */
435 0x00, /* Vsize/4 for 288 or 240 */
436 0x13, /* or 0xbb, depends on sensor */
437 0x00, /* Hstart, depends on res. */
438 0x00, /* reserved ? */
439 0x00, /* Vstart, depends on res. and sensor */
440 0x50, /* 0x54 to get 176 or 160 */
441 0xc0
442 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300443
Theodore Kilgore89f08632009-08-14 06:51:52 -0300444 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300445 data[0] = 0x01;
446 data[1] = 0x01;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300447 err_code = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300448 if (err_code < 0)
449 return err_code;
450
Theodore Kilgore89f08632009-08-14 06:51:52 -0300451 memcpy(data, startup_string, 11);
452 if (sd->sensor_type)
453 data[5] = 0xbb;
454
455 switch (gspca_dev->width) {
456 case 160:
457 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
458 /* fall thru */
459 case 320:
460 default:
461 data[3] = 0x28; /* reg 2, H size/8 */
462 data[4] = 0x3c; /* reg 3, V size/4 */
463 data[6] = 0x14; /* reg 5, H start */
464 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
465 break;
466 case 176:
467 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
468 /* fall thru */
469 case 352:
470 data[3] = 0x2c; /* reg 2, H size/8 */
471 data[4] = 0x48; /* reg 3, V size/4 */
472 data[6] = 0x06; /* reg 5, H start */
473 data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
474 break;
475 }
476 err_code = mr_write(gspca_dev, 11);
477 if (err_code < 0)
478 return err_code;
479
480 if (!sd->sensor_type) {
481 const struct sensor_w_data cif_sensor0_init_data[] = {
482 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
483 0x0f, 0x14, 0x0f, 0x10}, 8},
484 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
485 {0x12, 0x00, {0x07}, 1},
486 {0x1f, 0x00, {0x06}, 1},
487 {0x27, 0x00, {0x04}, 1},
488 {0x29, 0x00, {0x0c}, 1},
489 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
490 {0x50, 0x00, {0x60}, 1},
491 {0x60, 0x00, {0x06}, 1},
492 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
493 {0x72, 0x00, {0x1e, 0x56}, 2},
494 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
495 0x31, 0x80, 0x00}, 9},
496 {0x11, 0x00, {0x01}, 1},
497 {0, 0, {0}, 0}
498 };
499 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
500 ARRAY_SIZE(cif_sensor0_init_data));
501 } else { /* sd->sensor_type = 1 */
502 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300503 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300504 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300505 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
506 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300507 {0x09, 0x02, {0x0e}, 1},
508 {0x0a, 0x02, {0x05}, 1},
509 {0x0b, 0x02, {0x05}, 1},
510 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300511 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300512 {0x0e, 0x02, {0x0c}, 1},
513 {0x0f, 0x00, {0x00}, 1},
514 {0x10, 0x00, {0x06}, 1},
515 {0x11, 0x00, {0x07}, 1},
516 {0x12, 0x00, {0x00}, 1},
517 {0x13, 0x00, {0x01}, 1},
518 {0, 0, {0}, 0}
519 };
520 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
521 ARRAY_SIZE(cif_sensor1_init_data));
522 }
523 if (err_code < 0)
524 return err_code;
525
Hans de Goede9ac69782009-08-14 10:15:52 -0300526 setbrightness(gspca_dev);
527 setexposure(gspca_dev);
528 setgain(gspca_dev);
529
Theodore Kilgore89f08632009-08-14 06:51:52 -0300530 msleep(200);
Hans de Goede9ac69782009-08-14 10:15:52 -0300531
Kyle Guinnd661e622009-01-16 05:36:14 -0300532 data[0] = 0x00;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300533 data[1] = 0x4d; /* ISOC transfering enable... */
534 err_code = mr_write(gspca_dev, 2);
535 if (err_code < 0)
536 return err_code;
537
Theodore Kilgore89f08632009-08-14 06:51:52 -0300538 return 0;
539}
540
541static int start_vga_cam(struct gspca_dev *gspca_dev)
542{
543 struct sd *sd = (struct sd *) gspca_dev;
544 __u8 *data = gspca_dev->usb_buf;
545 int err_code;
546 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
547 0x00, 0x00, 0x00, 0x50, 0xc0};
548
549 /* What some of these mean is explained in start_cif_cam(), above */
550 sd->sof_read = 0;
551
552 /*
553 * We have to know which camera we have, because the register writes
554 * depend upon the camera. This test, run before we actually enter
555 * the initialization routine, distinguishes most of the cameras, If
556 * needed, another routine is done later, too.
557 */
558 memset(data, 0, 16);
559 data[0] = 0x20;
560 err_code = mr_write(gspca_dev, 1);
561 if (err_code < 0)
562 return err_code;
563
564 err_code = mr_read(gspca_dev, 16);
565 if (err_code < 0)
566 return err_code;
567
Hans de Goede54943782009-08-14 11:05:38 -0300568 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300569
570 msleep(200);
571 /*
572 * Known VGA cameras. If you have another to report, please do
573 *
574 * Name byte just read sd->sensor_type
575 * sd->do_lcd_stop
576 * Aiptek Pencam VGA+ 0x31 0 1
577 * ION digital 0x31 0 1
578 * Argus DC-1620 0x30 1 0
579 * Argus QuickClix 0x30 1 1 (not caught here)
580 */
581 sd->sensor_type = data[0] & 1;
582 sd->do_lcd_stop = (~data[0]) & 1;
583
584
585
586 /* Streaming setup begins here. */
587
588
589 data[0] = 0x01;
590 data[1] = 0x01;
591 err_code = mr_write(gspca_dev, 2);
592 if (err_code < 0)
593 return err_code;
594
595 /*
596 * A second test can now resolve any remaining ambiguity in the
597 * identification of the camera type,
598 */
599 if (!sd->sensor_type) {
600 data[0] = get_sensor_id(gspca_dev);
601 if (data[0] == 0x7f) {
602 sd->sensor_type = 1;
Hans de Goede54943782009-08-14 11:05:38 -0300603 PDEBUG(D_PROBE, "sensor_type corrected to 1");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300604 }
605 msleep(200);
606 }
607
608 /*
609 * Known VGA cameras.
610 * This test is only run if the previous test returned 0x30, but
611 * here is the information for all others, too, just for reference.
612 *
613 * Name byte just read sd->sensor_type
614 *
615 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
616 * ION digital 0xbd (this test not run) 1
617 * Argus DC-1620 0xe5 (no change) 0
618 * Argus QuickClix 0x7f (reclassified) 1
619 */
620 memcpy(data, startup_string, 11);
621 if (!sd->sensor_type) {
622 data[5] = 0x00;
623 data[10] = 0x91;
624 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300625
626 switch (gspca_dev->width) {
627 case 160:
628 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
629 /* fall thru */
630 case 320:
631 data[9] |= 0x04; /* reg 8, 2:1 scale down */
632 /* fall thru */
633 case 640:
634 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300635 data[3] = 0x50; /* reg 2, H size/8 */
636 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300637 data[6] = 0x04; /* reg 5, H start */
638 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300639 if (sd->do_lcd_stop)
640 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300641 break;
642
643 case 176:
644 data[9] |= 0x04; /* reg 8, 2:1 scale down */
645 /* fall thru */
646 case 352:
647 data[3] = 0x2c; /* reg 2, H size */
648 data[4] = 0x48; /* reg 3, V size */
649 data[6] = 0x94; /* reg 5, H start */
650 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300651 if (sd->do_lcd_stop)
652 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300653 break;
654 }
655
Theodore Kilgore89f08632009-08-14 06:51:52 -0300656 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300657 if (err_code < 0)
658 return err_code;
659
Theodore Kilgore89f08632009-08-14 06:51:52 -0300660 if (!sd->sensor_type) {
661 /* The only known sensor_type 0 cam is the Argus DC-1620 */
662 const struct sensor_w_data vga_sensor0_init_data[] = {
663 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
664 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
665 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
666 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
667 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
668 {0, 0, {0}, 0}
669 };
670 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
671 ARRAY_SIZE(vga_sensor0_init_data));
672 } else { /* sd->sensor_type = 1 */
673 const struct sensor_w_data vga_sensor1_init_data[] = {
674 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
675 0x07, 0x00, 0x01}, 8},
676 {0x11, 0x04, {0x01}, 1},
677 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
678 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
679 0x00, 0x0a}, 7},
680 {0x11, 0x04, {0x01}, 1},
681 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
682 {0x11, 0x04, {0x01}, 1},
683 {0, 0, {0}, 0}
684 };
685 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
686 ARRAY_SIZE(vga_sensor1_init_data));
687 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300688 if (err_code < 0)
689 return err_code;
690
Theodore Kilgore89f08632009-08-14 06:51:52 -0300691 msleep(200);
Kyle Guinnd661e622009-01-16 05:36:14 -0300692 data[0] = 0x00;
693 data[1] = 0x4d; /* ISOC transfering enable... */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300694 err_code = mr_write(gspca_dev, 2);
695
696 return err_code;
697}
698
699static int sd_start(struct gspca_dev *gspca_dev)
700{
701 struct sd *sd = (struct sd *) gspca_dev;
702 int err_code;
703 struct cam *cam;
704
Theodore Kilgore89f08632009-08-14 06:51:52 -0300705 cam = &gspca_dev->cam;
706 sd->sof_read = 0;
707 /*
708 * Some of the supported cameras require the memory pointer to be
709 * set to 0, or else they will not stream.
710 */
711 zero_the_pointer(gspca_dev);
712 msleep(200);
713 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300714 err_code = start_cif_cam(gspca_dev);
715 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300716 err_code = start_vga_cam(gspca_dev);
717 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300718 return err_code;
719}
720
721static void sd_stopN(struct gspca_dev *gspca_dev)
722{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300723 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300724 int result;
725
726 gspca_dev->usb_buf[0] = 1;
727 gspca_dev->usb_buf[1] = 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300728 result = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300729 if (result < 0)
730 PDEBUG(D_ERR, "Camera Stop failed");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300731
732 /* Not all the cams need this, but even if not, probably a good idea */
733 zero_the_pointer(gspca_dev);
734 if (sd->do_lcd_stop) {
735 gspca_dev->usb_buf[0] = 0x19;
736 gspca_dev->usb_buf[1] = 0x54;
737 result = mr_write(gspca_dev, 2);
738 if (result < 0)
739 PDEBUG(D_ERR, "Camera Stop failed");
740 }
741}
742
743static void setbrightness(struct gspca_dev *gspca_dev)
744{
745 struct sd *sd = (struct sd *) gspca_dev;
746 u8 val;
Hans de Goede9ac69782009-08-14 10:15:52 -0300747
748 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
749 return;
750
751 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300752 if (sd->brightness > 0) {
Hans de Goede9ac69782009-08-14 10:15:52 -0300753 sensor_write1(gspca_dev, 7, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300754 val = sd->brightness;
755 } else {
Hans de Goede9ac69782009-08-14 10:15:52 -0300756 sensor_write1(gspca_dev, 7, 0x01);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300757 val = 257 - sd->brightness;
758 }
759 sensor_write1(gspca_dev, 8, val);
760}
761
762static void setexposure(struct gspca_dev *gspca_dev)
763{
764 struct sd *sd = (struct sd *) gspca_dev;
765 u8 val;
766
Hans de Goede9ac69782009-08-14 10:15:52 -0300767 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
768 return;
769
Theodore Kilgore89f08632009-08-14 06:51:52 -0300770 val = sd->exposure >> 4;
771 sensor_write1(gspca_dev, 3, val);
772 val = sd->exposure & 0xf;
773 sensor_write1(gspca_dev, 4, val);
774}
775
776static void setgain(struct gspca_dev *gspca_dev)
777{
778 struct sd *sd = (struct sd *) gspca_dev;
779
Hans de Goede9ac69782009-08-14 10:15:52 -0300780 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
781 return;
782
Theodore Kilgore89f08632009-08-14 06:51:52 -0300783 sensor_write1(gspca_dev, 3, sd->gain);
784}
785
786static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
787{
788 struct sd *sd = (struct sd *) gspca_dev;
789
790 sd->brightness = val;
791 if (gspca_dev->streaming)
792 setbrightness(gspca_dev);
793 return 0;
794}
795
796static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
797{
798 struct sd *sd = (struct sd *) gspca_dev;
799
800 *val = sd->brightness;
801 return 0;
802}
803
804static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
805{
806 struct sd *sd = (struct sd *) gspca_dev;
807
808 sd->exposure = val;
809 if (gspca_dev->streaming)
810 setexposure(gspca_dev);
811 return 0;
812}
813
814static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
815{
816 struct sd *sd = (struct sd *) gspca_dev;
817
818 *val = sd->exposure;
819 return 0;
820}
821
822static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
823{
824 struct sd *sd = (struct sd *) gspca_dev;
825
826 sd->gain = val;
827 if (gspca_dev->streaming)
828 setgain(gspca_dev);
829 return 0;
830}
831
832static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
833{
834 struct sd *sd = (struct sd *) gspca_dev;
835
836 *val = sd->gain;
837 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -0300838}
839
840/* Include pac common sof detection functions */
841#include "pac_common.h"
842
843static void sd_pkt_scan(struct gspca_dev *gspca_dev,
844 struct gspca_frame *frame, /* target */
845 __u8 *data, /* isoc packet */
846 int len) /* iso packet length */
847{
Kyle Guinnd661e622009-01-16 05:36:14 -0300848 unsigned char *sof;
849
850 sof = pac_find_sof(gspca_dev, data, len);
851 if (sof) {
852 int n;
853
854 /* finish decoding current frame */
855 n = sof - data;
856 if (n > sizeof pac_sof_marker)
857 n -= sizeof pac_sof_marker;
858 else
859 n = 0;
860 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
861 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -0300862 /* Start next frame. */
863 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
864 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -0300865 len -= sof - data;
866 data = sof;
867 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300868 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
869}
870
871/* sub-driver description */
872static const struct sd_desc sd_desc = {
873 .name = MODULE_NAME,
874 .ctrls = sd_ctrls,
875 .nctrls = ARRAY_SIZE(sd_ctrls),
876 .config = sd_config,
877 .init = sd_init,
878 .start = sd_start,
879 .stopN = sd_stopN,
880 .pkt_scan = sd_pkt_scan,
881};
882
883/* -- module initialisation -- */
884static const __devinitdata struct usb_device_id device_table[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300885 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
886 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
887 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -0300888 {}
889};
890MODULE_DEVICE_TABLE(usb, device_table);
891
892/* -- device connect -- */
893static int sd_probe(struct usb_interface *intf,
894 const struct usb_device_id *id)
895{
896 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
897 THIS_MODULE);
898}
899
900static struct usb_driver sd_driver = {
901 .name = MODULE_NAME,
902 .id_table = device_table,
903 .probe = sd_probe,
904 .disconnect = gspca_disconnect,
905#ifdef CONFIG_PM
906 .suspend = gspca_suspend,
907 .resume = gspca_resume,
908#endif
909};
910
911/* -- module insert / remove -- */
912static int __init sd_mod_init(void)
913{
Alexey Klimov5d3fa302009-03-27 15:57:46 -0300914 int ret;
915
916 ret = usb_register(&sd_driver);
917 if (ret < 0)
918 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -0300919 PDEBUG(D_PROBE, "registered");
920 return 0;
921}
922static void __exit sd_mod_exit(void)
923{
924 usb_deregister(&sd_driver);
925 PDEBUG(D_PROBE, "deregistered");
926}
927
928module_init(sd_mod_init);
929module_exit(sd_mod_exit);