blob: 63050f0ebfad442eee82e2c8e7f9de2f57bdc659 [file] [log] [blame]
Kyle Guinnd661e622009-01-16 05:36:14 -03001/*
2 * Mars MR97310A library
3 *
Theodore Kilgore930bf782009-10-05 05:11:35 -03004 * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
Kyle Guinnd661e622009-01-16 05:36:14 -03005 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
6 *
Theodore Kilgore89f08632009-08-14 06:51:52 -03007 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
8 * and for the routines for detecting and classifying these various cameras,
Theodore Kilgore930bf782009-10-05 05:11:35 -03009 * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
Theodore Kilgore89f08632009-08-14 06:51:52 -030010 *
Theodore Kilgore930bf782009-10-05 05:11:35 -030011 * Support for the control settings for the CIF cameras is
12 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
13 * Thomas Kaiser <thomas@kaiser-linux.li>
14 *
15 * Support for the control settings for the VGA cameras is
Theodore Kilgore89f08632009-08-14 06:51:52 -030016 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
17 *
Theodore Kilgore930bf782009-10-05 05:11:35 -030018 * Several previously unsupported cameras are owned and have been tested by
19 * Hans de Goede <hdgoede@redhat.com> and
20 * Thomas Kaiser <thomas@kaiser-linux.li> and
21 * Theodore Kilgore <kilgota@auburn.edu>
Theodore Kilgore89f08632009-08-14 06:51:52 -030022 *
23 * The MR97311A support in gspca/mars.c has been helpful in understanding some
24 * of the registers in these cameras.
25 *
Kyle Guinnd661e622009-01-16 05:36:14 -030026 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * any later version.
30 *
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
35 *
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 */
40
41#define MODULE_NAME "mr97310a"
42
43#include "gspca.h"
44
Theodore Kilgore89f08632009-08-14 06:51:52 -030045#define CAM_TYPE_CIF 0
46#define CAM_TYPE_VGA 1
47
Theodore Kilgore89f08632009-08-14 06:51:52 -030048#define MR97310A_BRIGHTNESS_DEFAULT 0
49
Theodore Kilgore930bf782009-10-05 05:11:35 -030050#define MR97310A_EXPOSURE_MIN 0
Theodore Kilgore89f08632009-08-14 06:51:52 -030051#define MR97310A_EXPOSURE_MAX 4095
52#define MR97310A_EXPOSURE_DEFAULT 1000
53
54#define MR97310A_GAIN_MIN 0
55#define MR97310A_GAIN_MAX 31
56#define MR97310A_GAIN_DEFAULT 25
57
Hans de Goede065b6f72009-10-29 07:42:30 -030058#define MR97310A_MIN_CLOCKDIV_MIN 3
59#define MR97310A_MIN_CLOCKDIV_MAX 8
60#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
61
Theodore Kilgore89f08632009-08-14 06:51:52 -030062MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
63 "Theodore Kilgore <kilgota@auburn.edu>");
Kyle Guinnd661e622009-01-16 05:36:14 -030064MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
65MODULE_LICENSE("GPL");
66
Hans de Goede78028702009-09-02 09:55:16 -030067/* global parameters */
68int force_sensor_type = -1;
69module_param(force_sensor_type, int, 0644);
70MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
71
Kyle Guinnd661e622009-01-16 05:36:14 -030072/* specific webcam descriptor */
73struct sd {
74 struct gspca_dev gspca_dev; /* !! must be the first item */
Kyle Guinnd661e622009-01-16 05:36:14 -030075 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030076 u8 cam_type; /* 0 is CIF and 1 is VGA */
77 u8 sensor_type; /* We use 0 and 1 here, too. */
78 u8 do_lcd_stop;
Theodore Kilgore89f08632009-08-14 06:51:52 -030079
80 int brightness;
81 u16 exposure;
Theodore Kilgore89f08632009-08-14 06:51:52 -030082 u8 gain;
Hans de Goede065b6f72009-10-29 07:42:30 -030083 u8 min_clockdiv;
Kyle Guinnd661e622009-01-16 05:36:14 -030084};
85
Theodore Kilgore89f08632009-08-14 06:51:52 -030086struct sensor_w_data {
87 u8 reg;
88 u8 flags;
89 u8 data[16];
90 int len;
91};
92
Theodore Kilgore930bf782009-10-05 05:11:35 -030093static void sd_stopN(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -030094static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
98static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede065b6f72009-10-29 07:42:30 -0300100static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede9ac69782009-08-14 10:15:52 -0300102static void setbrightness(struct gspca_dev *gspca_dev);
103static void setexposure(struct gspca_dev *gspca_dev);
104static void setgain(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300105
Kyle Guinnd661e622009-01-16 05:36:14 -0300106/* V4L2 controls supported by the driver */
107static struct ctrl sd_ctrls[] = {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300108/* Seprate brightness control description for Argus QuickClix as it has
109 different limits from to other mr97310a camera's */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300110 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300111#define NORM_BRIGHTNESS_IDX 0
Theodore Kilgore89f08632009-08-14 06:51:52 -0300112 {
113 .id = V4L2_CID_BRIGHTNESS,
114 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Brightness",
Theodore Kilgore930bf782009-10-05 05:11:35 -0300116 .minimum = -254,
117 .maximum = 255,
Theodore Kilgore89f08632009-08-14 06:51:52 -0300118 .step = 1,
119 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
120 .flags = 0,
121 },
122 .set = sd_setbrightness,
123 .get = sd_getbrightness,
124 },
125 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300126#define ARGUS_QC_BRIGHTNESS_IDX 1
127 {
128 .id = V4L2_CID_BRIGHTNESS,
129 .type = V4L2_CTRL_TYPE_INTEGER,
130 .name = "Brightness",
131 .minimum = 0,
132 .maximum = 15,
133 .step = 1,
134 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
135 .flags = 0,
136 },
137 .set = sd_setbrightness,
138 .get = sd_getbrightness,
139 },
140 {
141#define EXPOSURE_IDX 2
Theodore Kilgore89f08632009-08-14 06:51:52 -0300142 {
143 .id = V4L2_CID_EXPOSURE,
144 .type = V4L2_CTRL_TYPE_INTEGER,
145 .name = "Exposure",
146 .minimum = MR97310A_EXPOSURE_MIN,
147 .maximum = MR97310A_EXPOSURE_MAX,
148 .step = 1,
149 .default_value = MR97310A_EXPOSURE_DEFAULT,
150 .flags = 0,
151 },
152 .set = sd_setexposure,
153 .get = sd_getexposure,
154 },
155 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300156#define GAIN_IDX 3
Theodore Kilgore89f08632009-08-14 06:51:52 -0300157 {
158 .id = V4L2_CID_GAIN,
159 .type = V4L2_CTRL_TYPE_INTEGER,
160 .name = "Gain",
161 .minimum = MR97310A_GAIN_MIN,
162 .maximum = MR97310A_GAIN_MAX,
163 .step = 1,
164 .default_value = MR97310A_GAIN_DEFAULT,
165 .flags = 0,
166 },
167 .set = sd_setgain,
168 .get = sd_getgain,
169 },
Hans de Goede065b6f72009-10-29 07:42:30 -0300170 {
171#define MIN_CLOCKDIV_IDX 4
172 {
173 .id = V4L2_CID_PRIVATE_BASE,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "Minimum Clock Divider",
176 .minimum = MR97310A_MIN_CLOCKDIV_MIN,
177 .maximum = MR97310A_MIN_CLOCKDIV_MAX,
178 .step = 1,
179 .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
180 .flags = 0,
181 },
182 .set = sd_setmin_clockdiv,
183 .get = sd_getmin_clockdiv,
184 },
Kyle Guinnd661e622009-01-16 05:36:14 -0300185};
186
187static const struct v4l2_pix_format vga_mode[] = {
188 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
189 .bytesperline = 160,
190 .sizeimage = 160 * 120,
191 .colorspace = V4L2_COLORSPACE_SRGB,
192 .priv = 4},
193 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
194 .bytesperline = 176,
195 .sizeimage = 176 * 144,
196 .colorspace = V4L2_COLORSPACE_SRGB,
197 .priv = 3},
198 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
199 .bytesperline = 320,
200 .sizeimage = 320 * 240,
201 .colorspace = V4L2_COLORSPACE_SRGB,
202 .priv = 2},
203 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
204 .bytesperline = 352,
205 .sizeimage = 352 * 288,
206 .colorspace = V4L2_COLORSPACE_SRGB,
207 .priv = 1},
208 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
209 .bytesperline = 640,
210 .sizeimage = 640 * 480,
211 .colorspace = V4L2_COLORSPACE_SRGB,
212 .priv = 0},
213};
214
215/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300216static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300217{
218 int rc;
219
220 rc = usb_bulk_msg(gspca_dev->dev,
221 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300222 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300223 if (rc < 0)
224 PDEBUG(D_ERR, "reg write [%02x] error %d",
225 gspca_dev->usb_buf[0], rc);
226 return rc;
227}
228
Theodore Kilgore89f08632009-08-14 06:51:52 -0300229/* the bytes are read into gspca_dev->usb_buf */
230static int mr_read(struct gspca_dev *gspca_dev, int len)
231{
232 int rc;
233
234 rc = usb_bulk_msg(gspca_dev->dev,
235 usb_rcvbulkpipe(gspca_dev->dev, 3),
236 gspca_dev->usb_buf, len, NULL, 500);
237 if (rc < 0)
238 PDEBUG(D_ERR, "reg read [%02x] error %d",
239 gspca_dev->usb_buf[0], rc);
240 return rc;
241}
242
243static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
244 const u8 *data, int len)
245{
246 gspca_dev->usb_buf[0] = 0x1f;
247 gspca_dev->usb_buf[1] = flags;
248 gspca_dev->usb_buf[2] = reg;
249 memcpy(gspca_dev->usb_buf + 3, data, len);
250
251 return mr_write(gspca_dev, len + 3);
252}
253
254static int sensor_write_regs(struct gspca_dev *gspca_dev,
255 const struct sensor_w_data *data, int len)
256{
257 int i, rc;
258
259 for (i = 0; i < len; i++) {
260 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
261 data[i].data, data[i].len);
262 if (rc < 0)
263 return rc;
264 }
265
266 return 0;
267}
268
269static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
270{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300271 struct sd *sd = (struct sd *) gspca_dev;
272 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300273 int rc;
274
275 buf = data;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300276 if (sd->cam_type == CAM_TYPE_CIF) {
277 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
278 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
279 } else {
280 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
281 confirm_reg = 0x11;
282 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300283 if (rc < 0)
284 return rc;
285
286 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300287 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300288 if (rc < 0)
289 return rc;
290
291 return 0;
292}
293
Theodore Kilgore930bf782009-10-05 05:11:35 -0300294static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300295{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300296 int err_code;
297
Theodore Kilgore930bf782009-10-05 05:11:35 -0300298 gspca_dev->usb_buf[0] = reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300299 err_code = mr_write(gspca_dev, 1);
300 if (err_code < 0)
301 return err_code;
302
303 err_code = mr_read(gspca_dev, 16);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300304 if (err_code < 0)
305 return err_code;
306
307 if (verbose)
308 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
309 gspca_dev->usb_buf[0],
310 gspca_dev->usb_buf[1],
311 gspca_dev->usb_buf[2]);
312
313 return 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300314}
315
316static int zero_the_pointer(struct gspca_dev *gspca_dev)
317{
318 __u8 *data = gspca_dev->usb_buf;
319 int err_code;
320 u8 status = 0;
321 int tries = 0;
322
Theodore Kilgore930bf782009-10-05 05:11:35 -0300323 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300324 if (err_code < 0)
325 return err_code;
326
327 err_code = mr_write(gspca_dev, 1);
328 data[0] = 0x19;
329 data[1] = 0x51;
330 err_code = mr_write(gspca_dev, 2);
331 if (err_code < 0)
332 return err_code;
333
Theodore Kilgore930bf782009-10-05 05:11:35 -0300334 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300335 if (err_code < 0)
336 return err_code;
337
338 data[0] = 0x19;
339 data[1] = 0xba;
340 err_code = mr_write(gspca_dev, 2);
341 if (err_code < 0)
342 return err_code;
343
Theodore Kilgore930bf782009-10-05 05:11:35 -0300344 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300345 if (err_code < 0)
346 return err_code;
347
348 data[0] = 0x19;
349 data[1] = 0x00;
350 err_code = mr_write(gspca_dev, 2);
351 if (err_code < 0)
352 return err_code;
353
Theodore Kilgore930bf782009-10-05 05:11:35 -0300354 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300355 if (err_code < 0)
356 return err_code;
357
358 data[0] = 0x19;
359 data[1] = 0x00;
360 err_code = mr_write(gspca_dev, 2);
361 if (err_code < 0)
362 return err_code;
363
364 while (status != 0x0a && tries < 256) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300365 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300366 status = data[0];
367 tries++;
368 if (err_code < 0)
369 return err_code;
370 }
Hans de Goede54943782009-08-14 11:05:38 -0300371 if (status != 0x0a)
372 PDEBUG(D_ERR, "status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300373
374 tries = 0;
375 while (tries < 4) {
376 data[0] = 0x19;
377 data[1] = 0x00;
378 err_code = mr_write(gspca_dev, 2);
379 if (err_code < 0)
380 return err_code;
381
Theodore Kilgore930bf782009-10-05 05:11:35 -0300382 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300383 status = data[0];
384 tries++;
385 if (err_code < 0)
386 return err_code;
387 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300388
389 data[0] = 0x19;
390 err_code = mr_write(gspca_dev, 1);
391 if (err_code < 0)
392 return err_code;
393
394 err_code = mr_read(gspca_dev, 16);
395 if (err_code < 0)
396 return err_code;
397
398 return 0;
399}
400
Theodore Kilgore930bf782009-10-05 05:11:35 -0300401static int stream_start(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300402{
Theodore Kilgore930bf782009-10-05 05:11:35 -0300403 gspca_dev->usb_buf[0] = 0x01;
404 gspca_dev->usb_buf[1] = 0x01;
405 return mr_write(gspca_dev, 2);
406}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300407
Theodore Kilgore930bf782009-10-05 05:11:35 -0300408static void stream_stop(struct gspca_dev *gspca_dev)
409{
410 gspca_dev->usb_buf[0] = 0x01;
411 gspca_dev->usb_buf[1] = 0x00;
412 if (mr_write(gspca_dev, 2) < 0)
413 PDEBUG(D_ERR, "Stream Stop failed");
414}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300415
Theodore Kilgore930bf782009-10-05 05:11:35 -0300416static void lcd_stop(struct gspca_dev *gspca_dev)
417{
418 gspca_dev->usb_buf[0] = 0x19;
419 gspca_dev->usb_buf[1] = 0x54;
420 if (mr_write(gspca_dev, 2) < 0)
421 PDEBUG(D_ERR, "LCD Stop failed");
422}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300423
Theodore Kilgore930bf782009-10-05 05:11:35 -0300424static int isoc_enable(struct gspca_dev *gspca_dev)
425{
426 gspca_dev->usb_buf[0] = 0x00;
427 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */
428 return mr_write(gspca_dev, 2);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300429}
430
Kyle Guinnd661e622009-01-16 05:36:14 -0300431/* this function is called at probe time */
432static int sd_config(struct gspca_dev *gspca_dev,
433 const struct usb_device_id *id)
434{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300435 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300436 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300437 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300438
439 cam = &gspca_dev->cam;
440 cam->cam_mode = vga_mode;
441 cam->nmodes = ARRAY_SIZE(vga_mode);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300442 sd->do_lcd_stop = 0;
443
444 /* Now, logical layout of the driver must fall sacrifice to the
445 * realities of the hardware supported. We have to sort out several
446 * cameras which share the USB ID but are in fact different inside.
447 * We need to start the initialization process for the cameras in
448 * order to classify them. Some of the supported cameras require the
449 * memory pointer to be set to 0 as the very first item of business
450 * or else they will not stream. So we do that immediately.
451 */
452 err_code = zero_the_pointer(gspca_dev);
453 if (err_code < 0)
454 return err_code;
Hans de Goede9ac69782009-08-14 10:15:52 -0300455
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300456 err_code = stream_start(gspca_dev);
457 if (err_code < 0)
458 return err_code;
459
Theodore Kilgore89f08632009-08-14 06:51:52 -0300460 if (id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300461 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300462 cam->nmodes--;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300463 err_code = cam_get_response16(gspca_dev, 0x06, 1);
464 if (err_code < 0)
465 return err_code;
466 /*
467 * The various CIF cameras share the same USB ID but use
468 * different init routines and different controls. We need to
469 * detect which one is connected!
470 *
471 * A list of known CIF cameras follows. They all report either
472 * 0002 for type 0 or 0003 for type 1.
473 * If you have another to report, please do
474 *
475 * Name sd->sensor_type reported by
476 *
477 * Sakar Spy-shot 0 T. Kilgore
478 * Innovage 0 T. Kilgore
479 * Vivitar Mini 0 H. De Goede
480 * Vivitar Mini 0 E. Rodriguez
481 * Vivitar Mini 1 T. Kilgore
482 * Elta-Media 8212dc 1 T. Kaiser
483 * Philips dig. keych. 1 T. Kilgore
484 */
485 switch (gspca_dev->usb_buf[1]) {
486 case 2:
487 sd->sensor_type = 0;
488 break;
489 case 3:
490 sd->sensor_type = 1;
491 break;
492 default:
493 PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
494 gspca_dev->usb_buf[1]);
495 return -ENODEV;
496 }
497 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
498 sd->sensor_type);
499 } else {
500 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300501
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300502 err_code = cam_get_response16(gspca_dev, 0x07, 1);
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300503 if (err_code < 0)
504 return err_code;
505
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300506 /*
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300507 * Here is a table of the responses to the previous command
508 * from the known MR97310A VGA cameras.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300509 *
510 * Name gspca_dev->usb_buf[] sd->sensor_type
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300511 * sd->do_lcd_stop
512 * Aiptek Pencam VGA+ 0300 0 1
513 * ION digital 0350 0 1
514 * Argus DC-1620 0450 1 0
515 * Argus QuickClix 0420 1 1
Theodore Kilgore930bf782009-10-05 05:11:35 -0300516 *
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300517 * Based upon these results, we assume default settings
518 * and then correct as necessary, as follows.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300519 *
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300520 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300521
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300522 sd->sensor_type = 1;
523 sd->do_lcd_stop = 0;
524 if ((gspca_dev->usb_buf[0] != 0x03) &&
525 (gspca_dev->usb_buf[0] != 0x04)) {
526 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
527 gspca_dev->usb_buf[1]);
528 PDEBUG(D_ERR, "Defaults assumed, may not work");
529 PDEBUG(D_ERR, "Please report this");
530 }
531 if (gspca_dev->usb_buf[0] == 0x04) {
532 sd->do_lcd_stop = 1;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300533 switch (gspca_dev->usb_buf[1]) {
534 case 0x50:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300535 sd->sensor_type = 0;
536 PDEBUG(D_PROBE, "sensor_type corrected to 0");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300537 break;
538 case 0x20:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300539 /* Nothing to do here. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300540 break;
541 default:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300542 PDEBUG(D_ERR,
543 "Unknown VGA Sensor id Byte 1: %02x",
544 gspca_dev->usb_buf[1]);
545 PDEBUG(D_ERR,
546 "Defaults assumed, may not work");
547 PDEBUG(D_ERR, "Please report this");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300548 }
Hans de Goede78028702009-09-02 09:55:16 -0300549 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300550 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
551 sd->sensor_type);
552 }
553 /* Stop streaming as we've started it to probe the sensor type. */
554 sd_stopN(gspca_dev);
Hans de Goede78028702009-09-02 09:55:16 -0300555
Theodore Kilgore930bf782009-10-05 05:11:35 -0300556 if (force_sensor_type != -1) {
557 sd->sensor_type = !!force_sensor_type;
558 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
559 sd->sensor_type);
560 }
561
562 /* Setup controls depending on camera type */
563 if (sd->cam_type == CAM_TYPE_CIF) {
564 /* No brightness for sensor_type 0 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300565 if (sd->sensor_type == 0)
Theodore Kilgore930bf782009-10-05 05:11:35 -0300566 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
567 (1 << ARGUS_QC_BRIGHTNESS_IDX);
568 else
Hans de Goede065b6f72009-10-29 07:42:30 -0300569 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
570 (1 << MIN_CLOCKDIV_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300571 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300572 /* All controls need to be disabled if VGA sensor_type is 0 */
573 if (sd->sensor_type == 0)
574 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
575 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
576 (1 << EXPOSURE_IDX) |
Hans de Goede065b6f72009-10-29 07:42:30 -0300577 (1 << GAIN_IDX) |
578 (1 << MIN_CLOCKDIV_IDX);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300579 else if (sd->do_lcd_stop)
580 /* Argus QuickClix has different brightness limits */
581 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
582 else
583 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300584 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300585
586 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
587 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
588 sd->gain = MR97310A_GAIN_DEFAULT;
Hans de Goede065b6f72009-10-29 07:42:30 -0300589 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
Hans de Goede9ac69782009-08-14 10:15:52 -0300590
Kyle Guinnd661e622009-01-16 05:36:14 -0300591 return 0;
592}
593
594/* this function is called at probe and resume time */
595static int sd_init(struct gspca_dev *gspca_dev)
596{
597 return 0;
598}
599
Theodore Kilgore89f08632009-08-14 06:51:52 -0300600static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300601{
602 struct sd *sd = (struct sd *) gspca_dev;
603 __u8 *data = gspca_dev->usb_buf;
604 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300605 const __u8 startup_string[] = {
606 0x00,
607 0x0d,
608 0x01,
609 0x00, /* Hsize/8 for 352 or 320 */
610 0x00, /* Vsize/4 for 288 or 240 */
611 0x13, /* or 0xbb, depends on sensor */
612 0x00, /* Hstart, depends on res. */
613 0x00, /* reserved ? */
614 0x00, /* Vstart, depends on res. and sensor */
615 0x50, /* 0x54 to get 176 or 160 */
616 0xc0
617 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300618
Theodore Kilgore89f08632009-08-14 06:51:52 -0300619 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300620
Theodore Kilgore89f08632009-08-14 06:51:52 -0300621 memcpy(data, startup_string, 11);
622 if (sd->sensor_type)
623 data[5] = 0xbb;
624
625 switch (gspca_dev->width) {
626 case 160:
627 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
628 /* fall thru */
629 case 320:
630 default:
631 data[3] = 0x28; /* reg 2, H size/8 */
632 data[4] = 0x3c; /* reg 3, V size/4 */
633 data[6] = 0x14; /* reg 5, H start */
634 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
635 break;
636 case 176:
637 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
638 /* fall thru */
639 case 352:
640 data[3] = 0x2c; /* reg 2, H size/8 */
641 data[4] = 0x48; /* reg 3, V size/4 */
642 data[6] = 0x06; /* reg 5, H start */
Theodore Kilgore32345b02009-11-01 12:59:42 -0300643 data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300644 break;
645 }
646 err_code = mr_write(gspca_dev, 11);
647 if (err_code < 0)
648 return err_code;
649
650 if (!sd->sensor_type) {
651 const struct sensor_w_data cif_sensor0_init_data[] = {
652 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
653 0x0f, 0x14, 0x0f, 0x10}, 8},
654 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
655 {0x12, 0x00, {0x07}, 1},
656 {0x1f, 0x00, {0x06}, 1},
657 {0x27, 0x00, {0x04}, 1},
658 {0x29, 0x00, {0x0c}, 1},
659 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
660 {0x50, 0x00, {0x60}, 1},
661 {0x60, 0x00, {0x06}, 1},
662 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
663 {0x72, 0x00, {0x1e, 0x56}, 2},
664 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
665 0x31, 0x80, 0x00}, 9},
666 {0x11, 0x00, {0x01}, 1},
667 {0, 0, {0}, 0}
668 };
669 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
670 ARRAY_SIZE(cif_sensor0_init_data));
671 } else { /* sd->sensor_type = 1 */
672 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300673 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300674 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300675 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
676 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300677 {0x09, 0x02, {0x0e}, 1},
678 {0x0a, 0x02, {0x05}, 1},
679 {0x0b, 0x02, {0x05}, 1},
680 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300681 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300682 {0x0e, 0x02, {0x0c}, 1},
683 {0x0f, 0x00, {0x00}, 1},
684 {0x10, 0x00, {0x06}, 1},
685 {0x11, 0x00, {0x07}, 1},
686 {0x12, 0x00, {0x00}, 1},
687 {0x13, 0x00, {0x01}, 1},
688 {0, 0, {0}, 0}
689 };
690 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
691 ARRAY_SIZE(cif_sensor1_init_data));
692 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300693 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300694}
695
696static int start_vga_cam(struct gspca_dev *gspca_dev)
697{
698 struct sd *sd = (struct sd *) gspca_dev;
699 __u8 *data = gspca_dev->usb_buf;
700 int err_code;
701 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
702 0x00, 0x00, 0x00, 0x50, 0xc0};
Theodore Kilgore89f08632009-08-14 06:51:52 -0300703 /* What some of these mean is explained in start_cif_cam(), above */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300704
Theodore Kilgore89f08632009-08-14 06:51:52 -0300705 memcpy(data, startup_string, 11);
706 if (!sd->sensor_type) {
707 data[5] = 0x00;
708 data[10] = 0x91;
709 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300710
711 switch (gspca_dev->width) {
712 case 160:
713 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
714 /* fall thru */
715 case 320:
716 data[9] |= 0x04; /* reg 8, 2:1 scale down */
717 /* fall thru */
718 case 640:
719 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300720 data[3] = 0x50; /* reg 2, H size/8 */
721 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300722 data[6] = 0x04; /* reg 5, H start */
723 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300724 if (sd->do_lcd_stop)
725 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300726 break;
727
728 case 176:
729 data[9] |= 0x04; /* reg 8, 2:1 scale down */
730 /* fall thru */
731 case 352:
732 data[3] = 0x2c; /* reg 2, H size */
733 data[4] = 0x48; /* reg 3, V size */
734 data[6] = 0x94; /* reg 5, H start */
735 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300736 if (sd->do_lcd_stop)
737 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300738 break;
739 }
740
Theodore Kilgore89f08632009-08-14 06:51:52 -0300741 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300742 if (err_code < 0)
743 return err_code;
744
Theodore Kilgore89f08632009-08-14 06:51:52 -0300745 if (!sd->sensor_type) {
746 /* The only known sensor_type 0 cam is the Argus DC-1620 */
747 const struct sensor_w_data vga_sensor0_init_data[] = {
748 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
749 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
750 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
751 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
752 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
753 {0, 0, {0}, 0}
754 };
755 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
756 ARRAY_SIZE(vga_sensor0_init_data));
757 } else { /* sd->sensor_type = 1 */
758 const struct sensor_w_data vga_sensor1_init_data[] = {
759 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
760 0x07, 0x00, 0x01}, 8},
761 {0x11, 0x04, {0x01}, 1},
762 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
763 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
764 0x00, 0x0a}, 7},
765 {0x11, 0x04, {0x01}, 1},
766 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
767 {0x11, 0x04, {0x01}, 1},
768 {0, 0, {0}, 0}
769 };
770 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
771 ARRAY_SIZE(vga_sensor1_init_data));
772 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300773 return err_code;
774}
775
776static int sd_start(struct gspca_dev *gspca_dev)
777{
778 struct sd *sd = (struct sd *) gspca_dev;
779 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300780
Theodore Kilgore89f08632009-08-14 06:51:52 -0300781 sd->sof_read = 0;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300782
783 /* Some of the VGA cameras require the memory pointer
784 * to be set to 0 again. We have been forced to start the
785 * stream somewhere else to detect the hardware, and closed it,
786 * and now since we are restarting the stream we need to do a
787 * completely fresh and clean start. */
788 err_code = zero_the_pointer(gspca_dev);
789 if (err_code < 0)
790 return err_code;
791
792 err_code = stream_start(gspca_dev);
793 if (err_code < 0)
794 return err_code;
795
Theodore Kilgore89f08632009-08-14 06:51:52 -0300796 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300797 err_code = start_cif_cam(gspca_dev);
798 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300799 err_code = start_vga_cam(gspca_dev);
800 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300801 if (err_code < 0)
802 return err_code;
803
804 setbrightness(gspca_dev);
805 setexposure(gspca_dev);
806 setgain(gspca_dev);
807
808 return isoc_enable(gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300809}
810
811static void sd_stopN(struct gspca_dev *gspca_dev)
812{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300813 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300814
Theodore Kilgore930bf782009-10-05 05:11:35 -0300815 stream_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300816 /* Not all the cams need this, but even if not, probably a good idea */
817 zero_the_pointer(gspca_dev);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300818 if (sd->do_lcd_stop)
819 lcd_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300820}
821
822static void setbrightness(struct gspca_dev *gspca_dev)
823{
824 struct sd *sd = (struct sd *) gspca_dev;
825 u8 val;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300826 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
827 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
828 const u8 quick_clix_table[] =
829 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
830 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
831 /*
832 * This control is disabled for CIF type 1 and VGA type 0 cameras.
833 * It does not quite act linearly for the Argus QuickClix camera,
834 * but it does control brightness. The values are 0 - 15 only, and
835 * the table above makes them act consecutively.
836 */
837 if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
838 (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
Hans de Goede9ac69782009-08-14 10:15:52 -0300839 return;
840
Theodore Kilgore930bf782009-10-05 05:11:35 -0300841 if (sd->cam_type == CAM_TYPE_VGA) {
842 sign_reg += 4;
843 value_reg += 4;
844 }
845
Hans de Goede9ac69782009-08-14 10:15:52 -0300846 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300847 if (sd->brightness > 0) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300848 sensor_write1(gspca_dev, sign_reg, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300849 val = sd->brightness;
850 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300851 sensor_write1(gspca_dev, sign_reg, 0x01);
852 val = (257 - sd->brightness);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300853 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300854 /* Use lookup table for funky Argus QuickClix brightness */
855 if (sd->do_lcd_stop)
856 val = quick_clix_table[val];
857
858 sensor_write1(gspca_dev, value_reg, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300859}
860
861static void setexposure(struct gspca_dev *gspca_dev)
862{
863 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300864 int exposure;
Hans de Goede065b6f72009-10-29 07:42:30 -0300865 u8 buf[2];
Theodore Kilgore89f08632009-08-14 06:51:52 -0300866
Hans de Goede9ac69782009-08-14 10:15:52 -0300867 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
868 return;
869
Theodore Kilgore930bf782009-10-05 05:11:35 -0300870 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Hans de Goeded76f9752009-10-11 05:22:29 -0300871 /* This cam does not like exposure settings > 300,
872 so scale 0 - 4095 to 300 - 4095 */
873 exposure = (sd->exposure * 9267) / 10000 + 300;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300874 sensor_write1(gspca_dev, 3, exposure >> 4);
875 sensor_write1(gspca_dev, 4, exposure & 0x0f);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300876 } else {
Hans de Goedea2e081b2009-08-14 17:11:36 -0300877 /* We have both a clock divider and an exposure register.
878 We first calculate the clock divider, as that determines
879 the maximum exposure and then we calculayte the exposure
880 register setting (which goes from 0 - 511).
881
882 Note our 0 - 4095 exposure is mapped to 0 - 511
883 milliseconds exposure time */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300884 u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300885
886 /* Limit framerate to not exceed usb bandwidth */
Hans de Goede065b6f72009-10-29 07:42:30 -0300887 if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
888 clockdiv = sd->min_clockdiv;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300889 else if (clockdiv < 2)
890 clockdiv = 2;
891
Theodore Kilgore930bf782009-10-05 05:11:35 -0300892 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
893 clockdiv = 4;
894
Hans de Goedea2e081b2009-08-14 17:11:36 -0300895 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
896 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
897 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
898 if (exposure > 511)
899 exposure = 511;
900
901 /* exposure register value is reversed! */
902 exposure = 511 - exposure;
903
Hans de Goede065b6f72009-10-29 07:42:30 -0300904 buf[0] = exposure & 0xff;
905 buf[1] = exposure >> 8;
906 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300907 sensor_write1(gspca_dev, 0x02, clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300908 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300909}
910
911static void setgain(struct gspca_dev *gspca_dev)
912{
913 struct sd *sd = (struct sd *) gspca_dev;
914
Hans de Goede9ac69782009-08-14 10:15:52 -0300915 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
916 return;
917
Theodore Kilgore930bf782009-10-05 05:11:35 -0300918 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Hans de Goede823902d2009-08-17 12:25:17 -0300919 sensor_write1(gspca_dev, 0x0e, sd->gain);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300920 } else {
921 sensor_write1(gspca_dev, 0x10, sd->gain);
922 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300923}
924
925static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
926{
927 struct sd *sd = (struct sd *) gspca_dev;
928
929 sd->brightness = val;
930 if (gspca_dev->streaming)
931 setbrightness(gspca_dev);
932 return 0;
933}
934
935static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
936{
937 struct sd *sd = (struct sd *) gspca_dev;
938
939 *val = sd->brightness;
940 return 0;
941}
942
943static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
944{
945 struct sd *sd = (struct sd *) gspca_dev;
946
947 sd->exposure = val;
948 if (gspca_dev->streaming)
949 setexposure(gspca_dev);
950 return 0;
951}
952
953static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
954{
955 struct sd *sd = (struct sd *) gspca_dev;
956
957 *val = sd->exposure;
958 return 0;
959}
960
961static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
962{
963 struct sd *sd = (struct sd *) gspca_dev;
964
965 sd->gain = val;
966 if (gspca_dev->streaming)
967 setgain(gspca_dev);
968 return 0;
969}
970
971static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
972{
973 struct sd *sd = (struct sd *) gspca_dev;
974
975 *val = sd->gain;
976 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -0300977}
978
Hans de Goede065b6f72009-10-29 07:42:30 -0300979static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
980{
981 struct sd *sd = (struct sd *) gspca_dev;
982
983 sd->min_clockdiv = val;
984 if (gspca_dev->streaming)
985 setexposure(gspca_dev);
986 return 0;
987}
988
989static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
990{
991 struct sd *sd = (struct sd *) gspca_dev;
992
993 *val = sd->min_clockdiv;
994 return 0;
995}
996
Kyle Guinnd661e622009-01-16 05:36:14 -0300997/* Include pac common sof detection functions */
998#include "pac_common.h"
999
1000static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1001 struct gspca_frame *frame, /* target */
1002 __u8 *data, /* isoc packet */
1003 int len) /* iso packet length */
1004{
Kyle Guinnd661e622009-01-16 05:36:14 -03001005 unsigned char *sof;
1006
1007 sof = pac_find_sof(gspca_dev, data, len);
1008 if (sof) {
1009 int n;
1010
1011 /* finish decoding current frame */
1012 n = sof - data;
1013 if (n > sizeof pac_sof_marker)
1014 n -= sizeof pac_sof_marker;
1015 else
1016 n = 0;
1017 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1018 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -03001019 /* Start next frame. */
1020 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
1021 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -03001022 len -= sof - data;
1023 data = sof;
1024 }
Kyle Guinnd661e622009-01-16 05:36:14 -03001025 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1026}
1027
1028/* sub-driver description */
1029static const struct sd_desc sd_desc = {
1030 .name = MODULE_NAME,
1031 .ctrls = sd_ctrls,
1032 .nctrls = ARRAY_SIZE(sd_ctrls),
1033 .config = sd_config,
1034 .init = sd_init,
1035 .start = sd_start,
1036 .stopN = sd_stopN,
1037 .pkt_scan = sd_pkt_scan,
1038};
1039
1040/* -- module initialisation -- */
1041static const __devinitdata struct usb_device_id device_table[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -03001042 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
1043 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
1044 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -03001045 {}
1046};
1047MODULE_DEVICE_TABLE(usb, device_table);
1048
1049/* -- device connect -- */
1050static int sd_probe(struct usb_interface *intf,
1051 const struct usb_device_id *id)
1052{
1053 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1054 THIS_MODULE);
1055}
1056
1057static struct usb_driver sd_driver = {
1058 .name = MODULE_NAME,
1059 .id_table = device_table,
1060 .probe = sd_probe,
1061 .disconnect = gspca_disconnect,
1062#ifdef CONFIG_PM
1063 .suspend = gspca_suspend,
1064 .resume = gspca_resume,
1065#endif
1066};
1067
1068/* -- module insert / remove -- */
1069static int __init sd_mod_init(void)
1070{
Alexey Klimov5d3fa302009-03-27 15:57:46 -03001071 int ret;
1072
1073 ret = usb_register(&sd_driver);
1074 if (ret < 0)
1075 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -03001076 PDEBUG(D_PROBE, "registered");
1077 return 0;
1078}
1079static void __exit sd_mod_exit(void)
1080{
1081 usb_deregister(&sd_driver);
1082 PDEBUG(D_PROBE, "deregistered");
1083}
1084
1085module_init(sd_mod_init);
1086module_exit(sd_mod_exit);