blob: 140c8f320e4782b83b39342b064c877d26eb85d6 [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
Hans de Goedef9089b02009-09-03 04:14:36 -0300396 * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300397 * Vivitar Mini 0x08 T. Kilgore 1
398 * Elta-Media 8212dc 0x23 T. Kaiser 1
399 * Philips dig. keych. 0x37 T. Kilgore 1
400 */
401 if ((data[0] & 0x78) == 8 ||
402 ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
403 sd->sensor_type = 1;
404 else
405 sd->sensor_type = 0;
406
Hans de Goede54943782009-08-14 11:05:38 -0300407 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
408 sd->sensor_type);
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300409
Hans de Goede78028702009-09-02 09:55:16 -0300410 if (force_sensor_type != -1) {
411 sd->sensor_type = !! force_sensor_type;
412 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
413 sd->sensor_type);
414 }
415
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300416 if (sd->sensor_type == 0)
Hans de Goedea2e081b2009-08-14 17:11:36 -0300417 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300418 } else {
419 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede54943782009-08-14 11:05:38 -0300420 PDEBUG(D_PROBE, "MR97310A VGA camera detected");
Hans de Goede9ac69782009-08-14 10:15:52 -0300421 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
422 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300423 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300424
425 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
426 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
427 sd->gain = MR97310A_GAIN_DEFAULT;
428
Kyle Guinnd661e622009-01-16 05:36:14 -0300429 return 0;
430}
431
432/* this function is called at probe and resume time */
433static int sd_init(struct gspca_dev *gspca_dev)
434{
435 return 0;
436}
437
Theodore Kilgore89f08632009-08-14 06:51:52 -0300438static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300439{
440 struct sd *sd = (struct sd *) gspca_dev;
441 __u8 *data = gspca_dev->usb_buf;
442 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300443 const __u8 startup_string[] = {
444 0x00,
445 0x0d,
446 0x01,
447 0x00, /* Hsize/8 for 352 or 320 */
448 0x00, /* Vsize/4 for 288 or 240 */
449 0x13, /* or 0xbb, depends on sensor */
450 0x00, /* Hstart, depends on res. */
451 0x00, /* reserved ? */
452 0x00, /* Vstart, depends on res. and sensor */
453 0x50, /* 0x54 to get 176 or 160 */
454 0xc0
455 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300456
Theodore Kilgore89f08632009-08-14 06:51:52 -0300457 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300458 data[0] = 0x01;
459 data[1] = 0x01;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300460 err_code = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300461 if (err_code < 0)
462 return err_code;
463
Theodore Kilgore89f08632009-08-14 06:51:52 -0300464 memcpy(data, startup_string, 11);
465 if (sd->sensor_type)
466 data[5] = 0xbb;
467
468 switch (gspca_dev->width) {
469 case 160:
470 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
471 /* fall thru */
472 case 320:
473 default:
474 data[3] = 0x28; /* reg 2, H size/8 */
475 data[4] = 0x3c; /* reg 3, V size/4 */
476 data[6] = 0x14; /* reg 5, H start */
477 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
478 break;
479 case 176:
480 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
481 /* fall thru */
482 case 352:
483 data[3] = 0x2c; /* reg 2, H size/8 */
484 data[4] = 0x48; /* reg 3, V size/4 */
485 data[6] = 0x06; /* reg 5, H start */
486 data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
487 break;
488 }
489 err_code = mr_write(gspca_dev, 11);
490 if (err_code < 0)
491 return err_code;
492
493 if (!sd->sensor_type) {
494 const struct sensor_w_data cif_sensor0_init_data[] = {
495 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
496 0x0f, 0x14, 0x0f, 0x10}, 8},
497 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
498 {0x12, 0x00, {0x07}, 1},
499 {0x1f, 0x00, {0x06}, 1},
500 {0x27, 0x00, {0x04}, 1},
501 {0x29, 0x00, {0x0c}, 1},
502 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
503 {0x50, 0x00, {0x60}, 1},
504 {0x60, 0x00, {0x06}, 1},
505 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
506 {0x72, 0x00, {0x1e, 0x56}, 2},
507 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
508 0x31, 0x80, 0x00}, 9},
509 {0x11, 0x00, {0x01}, 1},
510 {0, 0, {0}, 0}
511 };
512 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
513 ARRAY_SIZE(cif_sensor0_init_data));
514 } else { /* sd->sensor_type = 1 */
515 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300516 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300517 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300518 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
519 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300520 {0x09, 0x02, {0x0e}, 1},
521 {0x0a, 0x02, {0x05}, 1},
522 {0x0b, 0x02, {0x05}, 1},
523 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300524 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300525 {0x0e, 0x02, {0x0c}, 1},
526 {0x0f, 0x00, {0x00}, 1},
527 {0x10, 0x00, {0x06}, 1},
528 {0x11, 0x00, {0x07}, 1},
529 {0x12, 0x00, {0x00}, 1},
530 {0x13, 0x00, {0x01}, 1},
531 {0, 0, {0}, 0}
532 };
533 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
534 ARRAY_SIZE(cif_sensor1_init_data));
535 }
536 if (err_code < 0)
537 return err_code;
538
Hans de Goede9ac69782009-08-14 10:15:52 -0300539 setbrightness(gspca_dev);
540 setexposure(gspca_dev);
541 setgain(gspca_dev);
542
Theodore Kilgore89f08632009-08-14 06:51:52 -0300543 msleep(200);
Hans de Goede9ac69782009-08-14 10:15:52 -0300544
Kyle Guinnd661e622009-01-16 05:36:14 -0300545 data[0] = 0x00;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300546 data[1] = 0x4d; /* ISOC transfering enable... */
547 err_code = mr_write(gspca_dev, 2);
548 if (err_code < 0)
549 return err_code;
550
Theodore Kilgore89f08632009-08-14 06:51:52 -0300551 return 0;
552}
553
554static int start_vga_cam(struct gspca_dev *gspca_dev)
555{
556 struct sd *sd = (struct sd *) gspca_dev;
557 __u8 *data = gspca_dev->usb_buf;
558 int err_code;
559 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
560 0x00, 0x00, 0x00, 0x50, 0xc0};
561
562 /* What some of these mean is explained in start_cif_cam(), above */
563 sd->sof_read = 0;
564
565 /*
566 * We have to know which camera we have, because the register writes
567 * depend upon the camera. This test, run before we actually enter
568 * the initialization routine, distinguishes most of the cameras, If
569 * needed, another routine is done later, too.
570 */
571 memset(data, 0, 16);
572 data[0] = 0x20;
573 err_code = mr_write(gspca_dev, 1);
574 if (err_code < 0)
575 return err_code;
576
577 err_code = mr_read(gspca_dev, 16);
578 if (err_code < 0)
579 return err_code;
580
Hans de Goede54943782009-08-14 11:05:38 -0300581 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300582
583 msleep(200);
584 /*
585 * Known VGA cameras. If you have another to report, please do
586 *
587 * Name byte just read sd->sensor_type
588 * sd->do_lcd_stop
589 * Aiptek Pencam VGA+ 0x31 0 1
590 * ION digital 0x31 0 1
591 * Argus DC-1620 0x30 1 0
592 * Argus QuickClix 0x30 1 1 (not caught here)
593 */
594 sd->sensor_type = data[0] & 1;
595 sd->do_lcd_stop = (~data[0]) & 1;
596
597
598
599 /* Streaming setup begins here. */
600
601
602 data[0] = 0x01;
603 data[1] = 0x01;
604 err_code = mr_write(gspca_dev, 2);
605 if (err_code < 0)
606 return err_code;
607
608 /*
609 * A second test can now resolve any remaining ambiguity in the
610 * identification of the camera type,
611 */
612 if (!sd->sensor_type) {
613 data[0] = get_sensor_id(gspca_dev);
614 if (data[0] == 0x7f) {
615 sd->sensor_type = 1;
Hans de Goede54943782009-08-14 11:05:38 -0300616 PDEBUG(D_PROBE, "sensor_type corrected to 1");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300617 }
618 msleep(200);
619 }
620
Hans de Goede78028702009-09-02 09:55:16 -0300621 if (force_sensor_type != -1) {
622 sd->sensor_type = !! force_sensor_type;
623 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
624 sd->sensor_type);
625 }
626
Theodore Kilgore89f08632009-08-14 06:51:52 -0300627 /*
628 * Known VGA cameras.
629 * This test is only run if the previous test returned 0x30, but
630 * here is the information for all others, too, just for reference.
631 *
632 * Name byte just read sd->sensor_type
633 *
634 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
635 * ION digital 0xbd (this test not run) 1
636 * Argus DC-1620 0xe5 (no change) 0
637 * Argus QuickClix 0x7f (reclassified) 1
638 */
639 memcpy(data, startup_string, 11);
640 if (!sd->sensor_type) {
641 data[5] = 0x00;
642 data[10] = 0x91;
643 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300644
645 switch (gspca_dev->width) {
646 case 160:
647 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
648 /* fall thru */
649 case 320:
650 data[9] |= 0x04; /* reg 8, 2:1 scale down */
651 /* fall thru */
652 case 640:
653 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300654 data[3] = 0x50; /* reg 2, H size/8 */
655 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300656 data[6] = 0x04; /* reg 5, H start */
657 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300658 if (sd->do_lcd_stop)
659 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300660 break;
661
662 case 176:
663 data[9] |= 0x04; /* reg 8, 2:1 scale down */
664 /* fall thru */
665 case 352:
666 data[3] = 0x2c; /* reg 2, H size */
667 data[4] = 0x48; /* reg 3, V size */
668 data[6] = 0x94; /* reg 5, H start */
669 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300670 if (sd->do_lcd_stop)
671 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300672 break;
673 }
674
Theodore Kilgore89f08632009-08-14 06:51:52 -0300675 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300676 if (err_code < 0)
677 return err_code;
678
Theodore Kilgore89f08632009-08-14 06:51:52 -0300679 if (!sd->sensor_type) {
680 /* The only known sensor_type 0 cam is the Argus DC-1620 */
681 const struct sensor_w_data vga_sensor0_init_data[] = {
682 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
683 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
684 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
685 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
686 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
687 {0, 0, {0}, 0}
688 };
689 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
690 ARRAY_SIZE(vga_sensor0_init_data));
691 } else { /* sd->sensor_type = 1 */
692 const struct sensor_w_data vga_sensor1_init_data[] = {
693 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
694 0x07, 0x00, 0x01}, 8},
695 {0x11, 0x04, {0x01}, 1},
696 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
697 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
698 0x00, 0x0a}, 7},
699 {0x11, 0x04, {0x01}, 1},
700 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
701 {0x11, 0x04, {0x01}, 1},
702 {0, 0, {0}, 0}
703 };
704 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
705 ARRAY_SIZE(vga_sensor1_init_data));
706 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300707 if (err_code < 0)
708 return err_code;
709
Theodore Kilgore89f08632009-08-14 06:51:52 -0300710 msleep(200);
Kyle Guinnd661e622009-01-16 05:36:14 -0300711 data[0] = 0x00;
712 data[1] = 0x4d; /* ISOC transfering enable... */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300713 err_code = mr_write(gspca_dev, 2);
714
715 return err_code;
716}
717
718static int sd_start(struct gspca_dev *gspca_dev)
719{
720 struct sd *sd = (struct sd *) gspca_dev;
721 int err_code;
722 struct cam *cam;
723
Theodore Kilgore89f08632009-08-14 06:51:52 -0300724 cam = &gspca_dev->cam;
725 sd->sof_read = 0;
726 /*
727 * Some of the supported cameras require the memory pointer to be
728 * set to 0, or else they will not stream.
729 */
730 zero_the_pointer(gspca_dev);
731 msleep(200);
732 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300733 err_code = start_cif_cam(gspca_dev);
734 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300735 err_code = start_vga_cam(gspca_dev);
736 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300737 return err_code;
738}
739
740static void sd_stopN(struct gspca_dev *gspca_dev)
741{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300742 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300743 int result;
744
745 gspca_dev->usb_buf[0] = 1;
746 gspca_dev->usb_buf[1] = 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300747 result = mr_write(gspca_dev, 2);
Kyle Guinnd661e622009-01-16 05:36:14 -0300748 if (result < 0)
749 PDEBUG(D_ERR, "Camera Stop failed");
Theodore Kilgore89f08632009-08-14 06:51:52 -0300750
751 /* Not all the cams need this, but even if not, probably a good idea */
752 zero_the_pointer(gspca_dev);
753 if (sd->do_lcd_stop) {
754 gspca_dev->usb_buf[0] = 0x19;
755 gspca_dev->usb_buf[1] = 0x54;
756 result = mr_write(gspca_dev, 2);
757 if (result < 0)
758 PDEBUG(D_ERR, "Camera Stop failed");
759 }
760}
761
762static void setbrightness(struct gspca_dev *gspca_dev)
763{
764 struct sd *sd = (struct sd *) gspca_dev;
765 u8 val;
Hans de Goede9ac69782009-08-14 10:15:52 -0300766
767 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
768 return;
769
770 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300771 if (sd->brightness > 0) {
Hans de Goede9ac69782009-08-14 10:15:52 -0300772 sensor_write1(gspca_dev, 7, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300773 val = sd->brightness;
774 } else {
Hans de Goede9ac69782009-08-14 10:15:52 -0300775 sensor_write1(gspca_dev, 7, 0x01);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300776 val = 257 - sd->brightness;
777 }
778 sensor_write1(gspca_dev, 8, val);
779}
780
781static void setexposure(struct gspca_dev *gspca_dev)
782{
783 struct sd *sd = (struct sd *) gspca_dev;
784 u8 val;
785
Hans de Goede9ac69782009-08-14 10:15:52 -0300786 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
787 return;
788
Hans de Goedea2e081b2009-08-14 17:11:36 -0300789 if (sd->sensor_type) {
790 val = sd->exposure >> 4;
791 sensor_write1(gspca_dev, 3, val);
792 val = sd->exposure & 0xf;
793 sensor_write1(gspca_dev, 4, val);
794 } else {
795 u8 clockdiv;
796 int exposure;
797
798 /* We have both a clock divider and an exposure register.
799 We first calculate the clock divider, as that determines
800 the maximum exposure and then we calculayte the exposure
801 register setting (which goes from 0 - 511).
802
803 Note our 0 - 4095 exposure is mapped to 0 - 511
804 milliseconds exposure time */
805 clockdiv = (60 * sd->exposure + 7999) / 8000;
806
807 /* Limit framerate to not exceed usb bandwidth */
808 if (clockdiv < 3 && gspca_dev->width >= 320)
809 clockdiv = 3;
810 else if (clockdiv < 2)
811 clockdiv = 2;
812
813 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
814 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
815 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
816 if (exposure > 511)
817 exposure = 511;
818
819 /* exposure register value is reversed! */
820 exposure = 511 - exposure;
821
822 sensor_write1(gspca_dev, 0x02, clockdiv);
823 sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
824 sensor_write1(gspca_dev, 0x0f, exposure >> 8);
825 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300826}
827
828static void setgain(struct gspca_dev *gspca_dev)
829{
830 struct sd *sd = (struct sd *) gspca_dev;
831
Hans de Goede9ac69782009-08-14 10:15:52 -0300832 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
833 return;
834
Hans de Goedea2e081b2009-08-14 17:11:36 -0300835 if (sd->sensor_type) {
Hans de Goede823902de2009-08-17 12:25:17 -0300836 sensor_write1(gspca_dev, 0x0e, sd->gain);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300837 } else {
838 sensor_write1(gspca_dev, 0x10, sd->gain);
839 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300840}
841
842static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
843{
844 struct sd *sd = (struct sd *) gspca_dev;
845
846 sd->brightness = val;
847 if (gspca_dev->streaming)
848 setbrightness(gspca_dev);
849 return 0;
850}
851
852static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
853{
854 struct sd *sd = (struct sd *) gspca_dev;
855
856 *val = sd->brightness;
857 return 0;
858}
859
860static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
861{
862 struct sd *sd = (struct sd *) gspca_dev;
863
864 sd->exposure = val;
865 if (gspca_dev->streaming)
866 setexposure(gspca_dev);
867 return 0;
868}
869
870static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
871{
872 struct sd *sd = (struct sd *) gspca_dev;
873
874 *val = sd->exposure;
875 return 0;
876}
877
878static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
879{
880 struct sd *sd = (struct sd *) gspca_dev;
881
882 sd->gain = val;
883 if (gspca_dev->streaming)
884 setgain(gspca_dev);
885 return 0;
886}
887
888static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
889{
890 struct sd *sd = (struct sd *) gspca_dev;
891
892 *val = sd->gain;
893 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -0300894}
895
896/* Include pac common sof detection functions */
897#include "pac_common.h"
898
899static void sd_pkt_scan(struct gspca_dev *gspca_dev,
900 struct gspca_frame *frame, /* target */
901 __u8 *data, /* isoc packet */
902 int len) /* iso packet length */
903{
Kyle Guinnd661e622009-01-16 05:36:14 -0300904 unsigned char *sof;
905
906 sof = pac_find_sof(gspca_dev, data, len);
907 if (sof) {
908 int n;
909
910 /* finish decoding current frame */
911 n = sof - data;
912 if (n > sizeof pac_sof_marker)
913 n -= sizeof pac_sof_marker;
914 else
915 n = 0;
916 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
917 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -0300918 /* Start next frame. */
919 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
920 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -0300921 len -= sof - data;
922 data = sof;
923 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300924 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
925}
926
927/* sub-driver description */
928static const struct sd_desc sd_desc = {
929 .name = MODULE_NAME,
930 .ctrls = sd_ctrls,
931 .nctrls = ARRAY_SIZE(sd_ctrls),
932 .config = sd_config,
933 .init = sd_init,
934 .start = sd_start,
935 .stopN = sd_stopN,
936 .pkt_scan = sd_pkt_scan,
937};
938
939/* -- module initialisation -- */
940static const __devinitdata struct usb_device_id device_table[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300941 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
942 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
943 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -0300944 {}
945};
946MODULE_DEVICE_TABLE(usb, device_table);
947
948/* -- device connect -- */
949static int sd_probe(struct usb_interface *intf,
950 const struct usb_device_id *id)
951{
952 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
953 THIS_MODULE);
954}
955
956static struct usb_driver sd_driver = {
957 .name = MODULE_NAME,
958 .id_table = device_table,
959 .probe = sd_probe,
960 .disconnect = gspca_disconnect,
961#ifdef CONFIG_PM
962 .suspend = gspca_suspend,
963 .resume = gspca_resume,
964#endif
965};
966
967/* -- module insert / remove -- */
968static int __init sd_mod_init(void)
969{
Alexey Klimov5d3fa302009-03-27 15:57:46 -0300970 int ret;
971
972 ret = usb_register(&sd_driver);
973 if (ret < 0)
974 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -0300975 PDEBUG(D_PROBE, "registered");
976 return 0;
977}
978static void __exit sd_mod_exit(void)
979{
980 usb_deregister(&sd_driver);
981 PDEBUG(D_PROBE, "deregistered");
982}
983
984module_init(sd_mod_init);
985module_exit(sd_mod_exit);