blob: a9178d9d6745460e5dd35c61c08442b51f6f33df [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
Theodore Kilgore1160a382009-10-30 04:29:56 -030021 * Theodore Kilgore <kilgota@auburn.edu> and
22 * Edmond Rodriguez <erodrig_97@yahoo.com> and
23 * Aurelien Jacobs <aurel@gnuage.org>
Theodore Kilgore89f08632009-08-14 06:51:52 -030024 *
25 * The MR97311A support in gspca/mars.c has been helpful in understanding some
26 * of the registers in these cameras.
27 *
Kyle Guinnd661e622009-01-16 05:36:14 -030028 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation; either version 2 of the License, or
31 * any later version.
32 *
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
37 *
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 */
42
43#define MODULE_NAME "mr97310a"
44
45#include "gspca.h"
46
Theodore Kilgore89f08632009-08-14 06:51:52 -030047#define CAM_TYPE_CIF 0
48#define CAM_TYPE_VGA 1
49
Theodore Kilgore89f08632009-08-14 06:51:52 -030050#define MR97310A_BRIGHTNESS_DEFAULT 0
51
Theodore Kilgore930bf782009-10-05 05:11:35 -030052#define MR97310A_EXPOSURE_MIN 0
Theodore Kilgore89f08632009-08-14 06:51:52 -030053#define MR97310A_EXPOSURE_MAX 4095
54#define MR97310A_EXPOSURE_DEFAULT 1000
55
56#define MR97310A_GAIN_MIN 0
57#define MR97310A_GAIN_MAX 31
58#define MR97310A_GAIN_DEFAULT 25
59
Hans de Goede065b6f72009-10-29 07:42:30 -030060#define MR97310A_MIN_CLOCKDIV_MIN 3
61#define MR97310A_MIN_CLOCKDIV_MAX 8
62#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
63
Theodore Kilgore89f08632009-08-14 06:51:52 -030064MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
65 "Theodore Kilgore <kilgota@auburn.edu>");
Kyle Guinnd661e622009-01-16 05:36:14 -030066MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
67MODULE_LICENSE("GPL");
68
Hans de Goede78028702009-09-02 09:55:16 -030069/* global parameters */
Jean-Francois Moine83955552009-12-12 06:58:01 -030070static int force_sensor_type = -1;
Hans de Goede78028702009-09-02 09:55:16 -030071module_param(force_sensor_type, int, 0644);
72MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
73
Kyle Guinnd661e622009-01-16 05:36:14 -030074/* specific webcam descriptor */
75struct sd {
76 struct gspca_dev gspca_dev; /* !! must be the first item */
Kyle Guinnd661e622009-01-16 05:36:14 -030077 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030078 u8 cam_type; /* 0 is CIF and 1 is VGA */
79 u8 sensor_type; /* We use 0 and 1 here, too. */
80 u8 do_lcd_stop;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -030081 u8 adj_colors;
Theodore Kilgore89f08632009-08-14 06:51:52 -030082
83 int brightness;
84 u16 exposure;
Theodore Kilgore89f08632009-08-14 06:51:52 -030085 u8 gain;
Hans de Goede065b6f72009-10-29 07:42:30 -030086 u8 min_clockdiv;
Kyle Guinnd661e622009-01-16 05:36:14 -030087};
88
Theodore Kilgore89f08632009-08-14 06:51:52 -030089struct sensor_w_data {
90 u8 reg;
91 u8 flags;
92 u8 data[16];
93 int len;
94};
95
Theodore Kilgore930bf782009-10-05 05:11:35 -030096static void sd_stopN(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -030097static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede065b6f72009-10-29 07:42:30 -0300103static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede9ac69782009-08-14 10:15:52 -0300105static void setbrightness(struct gspca_dev *gspca_dev);
106static void setexposure(struct gspca_dev *gspca_dev);
107static void setgain(struct gspca_dev *gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300108
Kyle Guinnd661e622009-01-16 05:36:14 -0300109/* V4L2 controls supported by the driver */
Marton Nemeth7e64dc42009-12-30 09:12:41 -0300110static const struct ctrl sd_ctrls[] = {
Theodore Kilgore1160a382009-10-30 04:29:56 -0300111/* Separate brightness control description for Argus QuickClix as it has
112 different limits from the other mr97310a cameras */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300113 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300114#define NORM_BRIGHTNESS_IDX 0
Theodore Kilgore89f08632009-08-14 06:51:52 -0300115 {
116 .id = V4L2_CID_BRIGHTNESS,
117 .type = V4L2_CTRL_TYPE_INTEGER,
118 .name = "Brightness",
Theodore Kilgore930bf782009-10-05 05:11:35 -0300119 .minimum = -254,
120 .maximum = 255,
Theodore Kilgore89f08632009-08-14 06:51:52 -0300121 .step = 1,
122 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
123 .flags = 0,
124 },
125 .set = sd_setbrightness,
126 .get = sd_getbrightness,
127 },
128 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300129#define ARGUS_QC_BRIGHTNESS_IDX 1
130 {
131 .id = V4L2_CID_BRIGHTNESS,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Brightness",
134 .minimum = 0,
135 .maximum = 15,
136 .step = 1,
137 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
138 .flags = 0,
139 },
140 .set = sd_setbrightness,
141 .get = sd_getbrightness,
142 },
143 {
144#define EXPOSURE_IDX 2
Theodore Kilgore89f08632009-08-14 06:51:52 -0300145 {
146 .id = V4L2_CID_EXPOSURE,
147 .type = V4L2_CTRL_TYPE_INTEGER,
148 .name = "Exposure",
149 .minimum = MR97310A_EXPOSURE_MIN,
150 .maximum = MR97310A_EXPOSURE_MAX,
151 .step = 1,
152 .default_value = MR97310A_EXPOSURE_DEFAULT,
153 .flags = 0,
154 },
155 .set = sd_setexposure,
156 .get = sd_getexposure,
157 },
158 {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300159#define GAIN_IDX 3
Theodore Kilgore89f08632009-08-14 06:51:52 -0300160 {
161 .id = V4L2_CID_GAIN,
162 .type = V4L2_CTRL_TYPE_INTEGER,
163 .name = "Gain",
164 .minimum = MR97310A_GAIN_MIN,
165 .maximum = MR97310A_GAIN_MAX,
166 .step = 1,
167 .default_value = MR97310A_GAIN_DEFAULT,
168 .flags = 0,
169 },
170 .set = sd_setgain,
171 .get = sd_getgain,
172 },
Hans de Goede065b6f72009-10-29 07:42:30 -0300173 {
174#define MIN_CLOCKDIV_IDX 4
175 {
176 .id = V4L2_CID_PRIVATE_BASE,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "Minimum Clock Divider",
179 .minimum = MR97310A_MIN_CLOCKDIV_MIN,
180 .maximum = MR97310A_MIN_CLOCKDIV_MAX,
181 .step = 1,
182 .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
183 .flags = 0,
184 },
185 .set = sd_setmin_clockdiv,
186 .get = sd_getmin_clockdiv,
187 },
Kyle Guinnd661e622009-01-16 05:36:14 -0300188};
189
190static const struct v4l2_pix_format vga_mode[] = {
191 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
192 .bytesperline = 160,
193 .sizeimage = 160 * 120,
194 .colorspace = V4L2_COLORSPACE_SRGB,
195 .priv = 4},
196 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
197 .bytesperline = 176,
198 .sizeimage = 176 * 144,
199 .colorspace = V4L2_COLORSPACE_SRGB,
200 .priv = 3},
201 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
202 .bytesperline = 320,
203 .sizeimage = 320 * 240,
204 .colorspace = V4L2_COLORSPACE_SRGB,
205 .priv = 2},
206 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
207 .bytesperline = 352,
208 .sizeimage = 352 * 288,
209 .colorspace = V4L2_COLORSPACE_SRGB,
210 .priv = 1},
211 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
212 .bytesperline = 640,
213 .sizeimage = 640 * 480,
214 .colorspace = V4L2_COLORSPACE_SRGB,
215 .priv = 0},
216};
217
218/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300219static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300220{
221 int rc;
222
223 rc = usb_bulk_msg(gspca_dev->dev,
224 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300225 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300226 if (rc < 0)
227 PDEBUG(D_ERR, "reg write [%02x] error %d",
228 gspca_dev->usb_buf[0], rc);
229 return rc;
230}
231
Theodore Kilgore89f08632009-08-14 06:51:52 -0300232/* the bytes are read into gspca_dev->usb_buf */
233static int mr_read(struct gspca_dev *gspca_dev, int len)
234{
235 int rc;
236
237 rc = usb_bulk_msg(gspca_dev->dev,
238 usb_rcvbulkpipe(gspca_dev->dev, 3),
239 gspca_dev->usb_buf, len, NULL, 500);
240 if (rc < 0)
241 PDEBUG(D_ERR, "reg read [%02x] error %d",
242 gspca_dev->usb_buf[0], rc);
243 return rc;
244}
245
246static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
247 const u8 *data, int len)
248{
249 gspca_dev->usb_buf[0] = 0x1f;
250 gspca_dev->usb_buf[1] = flags;
251 gspca_dev->usb_buf[2] = reg;
252 memcpy(gspca_dev->usb_buf + 3, data, len);
253
254 return mr_write(gspca_dev, len + 3);
255}
256
257static int sensor_write_regs(struct gspca_dev *gspca_dev,
258 const struct sensor_w_data *data, int len)
259{
260 int i, rc;
261
262 for (i = 0; i < len; i++) {
263 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
264 data[i].data, data[i].len);
265 if (rc < 0)
266 return rc;
267 }
268
269 return 0;
270}
271
272static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
273{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300274 struct sd *sd = (struct sd *) gspca_dev;
275 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300276 int rc;
277
278 buf = data;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300279 if (sd->cam_type == CAM_TYPE_CIF) {
280 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
281 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
282 } else {
283 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
284 confirm_reg = 0x11;
285 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300286 if (rc < 0)
287 return rc;
288
289 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300290 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300291 if (rc < 0)
292 return rc;
293
294 return 0;
295}
296
Theodore Kilgore930bf782009-10-05 05:11:35 -0300297static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300298{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300299 int err_code;
300
Theodore Kilgore930bf782009-10-05 05:11:35 -0300301 gspca_dev->usb_buf[0] = reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300302 err_code = mr_write(gspca_dev, 1);
303 if (err_code < 0)
304 return err_code;
305
306 err_code = mr_read(gspca_dev, 16);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300307 if (err_code < 0)
308 return err_code;
309
310 if (verbose)
311 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
312 gspca_dev->usb_buf[0],
313 gspca_dev->usb_buf[1],
314 gspca_dev->usb_buf[2]);
315
316 return 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300317}
318
319static int zero_the_pointer(struct gspca_dev *gspca_dev)
320{
321 __u8 *data = gspca_dev->usb_buf;
322 int err_code;
323 u8 status = 0;
324 int tries = 0;
325
Theodore Kilgore930bf782009-10-05 05:11:35 -0300326 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300327 if (err_code < 0)
328 return err_code;
329
330 err_code = mr_write(gspca_dev, 1);
331 data[0] = 0x19;
332 data[1] = 0x51;
333 err_code = mr_write(gspca_dev, 2);
334 if (err_code < 0)
335 return err_code;
336
Theodore Kilgore930bf782009-10-05 05:11:35 -0300337 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300338 if (err_code < 0)
339 return err_code;
340
341 data[0] = 0x19;
342 data[1] = 0xba;
343 err_code = mr_write(gspca_dev, 2);
344 if (err_code < 0)
345 return err_code;
346
Theodore Kilgore930bf782009-10-05 05:11:35 -0300347 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300348 if (err_code < 0)
349 return err_code;
350
351 data[0] = 0x19;
352 data[1] = 0x00;
353 err_code = mr_write(gspca_dev, 2);
354 if (err_code < 0)
355 return err_code;
356
Theodore Kilgore930bf782009-10-05 05:11:35 -0300357 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300358 if (err_code < 0)
359 return err_code;
360
361 data[0] = 0x19;
362 data[1] = 0x00;
363 err_code = mr_write(gspca_dev, 2);
364 if (err_code < 0)
365 return err_code;
366
367 while (status != 0x0a && tries < 256) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300368 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300369 status = data[0];
370 tries++;
371 if (err_code < 0)
372 return err_code;
373 }
Hans de Goede54943782009-08-14 11:05:38 -0300374 if (status != 0x0a)
375 PDEBUG(D_ERR, "status is %02x", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300376
377 tries = 0;
378 while (tries < 4) {
379 data[0] = 0x19;
380 data[1] = 0x00;
381 err_code = mr_write(gspca_dev, 2);
382 if (err_code < 0)
383 return err_code;
384
Theodore Kilgore930bf782009-10-05 05:11:35 -0300385 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300386 status = data[0];
387 tries++;
388 if (err_code < 0)
389 return err_code;
390 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300391
392 data[0] = 0x19;
393 err_code = mr_write(gspca_dev, 1);
394 if (err_code < 0)
395 return err_code;
396
397 err_code = mr_read(gspca_dev, 16);
398 if (err_code < 0)
399 return err_code;
400
401 return 0;
402}
403
Theodore Kilgore930bf782009-10-05 05:11:35 -0300404static int stream_start(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300405{
Theodore Kilgore930bf782009-10-05 05:11:35 -0300406 gspca_dev->usb_buf[0] = 0x01;
407 gspca_dev->usb_buf[1] = 0x01;
408 return mr_write(gspca_dev, 2);
409}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300410
Theodore Kilgore930bf782009-10-05 05:11:35 -0300411static void stream_stop(struct gspca_dev *gspca_dev)
412{
413 gspca_dev->usb_buf[0] = 0x01;
414 gspca_dev->usb_buf[1] = 0x00;
415 if (mr_write(gspca_dev, 2) < 0)
416 PDEBUG(D_ERR, "Stream Stop failed");
417}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300418
Theodore Kilgore930bf782009-10-05 05:11:35 -0300419static void lcd_stop(struct gspca_dev *gspca_dev)
420{
421 gspca_dev->usb_buf[0] = 0x19;
422 gspca_dev->usb_buf[1] = 0x54;
423 if (mr_write(gspca_dev, 2) < 0)
424 PDEBUG(D_ERR, "LCD Stop failed");
425}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300426
Theodore Kilgore930bf782009-10-05 05:11:35 -0300427static int isoc_enable(struct gspca_dev *gspca_dev)
428{
429 gspca_dev->usb_buf[0] = 0x00;
430 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */
431 return mr_write(gspca_dev, 2);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300432}
433
Theodore Kilgore1160a382009-10-30 04:29:56 -0300434/* This function is called at probe time */
Kyle Guinnd661e622009-01-16 05:36:14 -0300435static int sd_config(struct gspca_dev *gspca_dev,
436 const struct usb_device_id *id)
437{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300438 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300439 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300440 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300441
442 cam = &gspca_dev->cam;
443 cam->cam_mode = vga_mode;
444 cam->nmodes = ARRAY_SIZE(vga_mode);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300445 sd->do_lcd_stop = 0;
446
Theodore Kilgore1160a382009-10-30 04:29:56 -0300447 /* Several of the supported CIF cameras share the same USB ID but
448 * require different initializations and different control settings.
449 * The same is true of the VGA cameras. Therefore, we are forced
450 * to start the initialization process in order to determine which
451 * camera is present. Some of the supported cameras require the
Theodore Kilgore930bf782009-10-05 05:11:35 -0300452 * memory pointer to be set to 0 as the very first item of business
453 * or else they will not stream. So we do that immediately.
454 */
455 err_code = zero_the_pointer(gspca_dev);
456 if (err_code < 0)
457 return err_code;
Hans de Goede9ac69782009-08-14 10:15:52 -0300458
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300459 err_code = stream_start(gspca_dev);
460 if (err_code < 0)
461 return err_code;
462
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -0300463 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300464 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300465 cam->nmodes--;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300466 err_code = cam_get_response16(gspca_dev, 0x06, 1);
467 if (err_code < 0)
468 return err_code;
469 /*
Theodore Kilgore1160a382009-10-30 04:29:56 -0300470 * All but one of the known CIF cameras share the same USB ID,
471 * but two different init routines are in use, and the control
472 * settings are different, too. We need to detect which camera
473 * of the two known varieties is connected!
Theodore Kilgore930bf782009-10-05 05:11:35 -0300474 *
475 * A list of known CIF cameras follows. They all report either
476 * 0002 for type 0 or 0003 for type 1.
477 * If you have another to report, please do
478 *
479 * Name sd->sensor_type reported by
480 *
481 * Sakar Spy-shot 0 T. Kilgore
482 * Innovage 0 T. Kilgore
483 * Vivitar Mini 0 H. De Goede
484 * Vivitar Mini 0 E. Rodriguez
485 * Vivitar Mini 1 T. Kilgore
486 * Elta-Media 8212dc 1 T. Kaiser
487 * Philips dig. keych. 1 T. Kilgore
Theodore Kilgore1160a382009-10-30 04:29:56 -0300488 * Trust Spyc@m 100 1 A. Jacobs
Theodore Kilgore930bf782009-10-05 05:11:35 -0300489 */
490 switch (gspca_dev->usb_buf[1]) {
491 case 2:
492 sd->sensor_type = 0;
493 break;
494 case 3:
495 sd->sensor_type = 1;
496 break;
497 default:
498 PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
499 gspca_dev->usb_buf[1]);
500 return -ENODEV;
501 }
502 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
503 sd->sensor_type);
504 } else {
505 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300506
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300508 if (err_code < 0)
509 return err_code;
510
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300511 /*
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300512 * Here is a table of the responses to the previous command
513 * from the known MR97310A VGA cameras.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300514 *
515 * Name gspca_dev->usb_buf[] sd->sensor_type
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300516 * sd->do_lcd_stop
517 * Aiptek Pencam VGA+ 0300 0 1
518 * ION digital 0350 0 1
519 * Argus DC-1620 0450 1 0
520 * Argus QuickClix 0420 1 1
Theodore Kilgore930bf782009-10-05 05:11:35 -0300521 *
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300522 * Based upon these results, we assume default settings
523 * and then correct as necessary, as follows.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300524 *
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300525 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300526
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300527 sd->sensor_type = 1;
528 sd->do_lcd_stop = 0;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300529 sd->adj_colors = 0;
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300530 if ((gspca_dev->usb_buf[0] != 0x03) &&
531 (gspca_dev->usb_buf[0] != 0x04)) {
532 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
533 gspca_dev->usb_buf[1]);
534 PDEBUG(D_ERR, "Defaults assumed, may not work");
535 PDEBUG(D_ERR, "Please report this");
536 }
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300537 /* Sakar Digital color needs to be adjusted. */
538 if ((gspca_dev->usb_buf[0] == 0x03) &&
539 (gspca_dev->usb_buf[1] == 0x50))
540 sd->adj_colors = 1;
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300541 if (gspca_dev->usb_buf[0] == 0x04) {
542 sd->do_lcd_stop = 1;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300543 switch (gspca_dev->usb_buf[1]) {
544 case 0x50:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300545 sd->sensor_type = 0;
546 PDEBUG(D_PROBE, "sensor_type corrected to 0");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300547 break;
548 case 0x20:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300549 /* Nothing to do here. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300550 break;
551 default:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300552 PDEBUG(D_ERR,
553 "Unknown VGA Sensor id Byte 1: %02x",
554 gspca_dev->usb_buf[1]);
555 PDEBUG(D_ERR,
556 "Defaults assumed, may not work");
557 PDEBUG(D_ERR, "Please report this");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300558 }
Hans de Goede78028702009-09-02 09:55:16 -0300559 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300560 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
561 sd->sensor_type);
562 }
563 /* Stop streaming as we've started it to probe the sensor type. */
564 sd_stopN(gspca_dev);
Hans de Goede78028702009-09-02 09:55:16 -0300565
Theodore Kilgore930bf782009-10-05 05:11:35 -0300566 if (force_sensor_type != -1) {
567 sd->sensor_type = !!force_sensor_type;
568 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
569 sd->sensor_type);
570 }
571
572 /* Setup controls depending on camera type */
573 if (sd->cam_type == CAM_TYPE_CIF) {
574 /* No brightness for sensor_type 0 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300575 if (sd->sensor_type == 0)
Theodore Kilgore930bf782009-10-05 05:11:35 -0300576 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
577 (1 << ARGUS_QC_BRIGHTNESS_IDX);
578 else
Hans de Goede065b6f72009-10-29 07:42:30 -0300579 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
580 (1 << MIN_CLOCKDIV_IDX);
Hans de Goede9ac69782009-08-14 10:15:52 -0300581 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300582 /* All controls need to be disabled if VGA sensor_type is 0 */
583 if (sd->sensor_type == 0)
584 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
585 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
586 (1 << EXPOSURE_IDX) |
Hans de Goede065b6f72009-10-29 07:42:30 -0300587 (1 << GAIN_IDX) |
588 (1 << MIN_CLOCKDIV_IDX);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300589 else if (sd->do_lcd_stop)
590 /* Argus QuickClix has different brightness limits */
591 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
592 else
593 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300594 }
Hans de Goede9ac69782009-08-14 10:15:52 -0300595
596 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
597 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
598 sd->gain = MR97310A_GAIN_DEFAULT;
Hans de Goede065b6f72009-10-29 07:42:30 -0300599 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
Hans de Goede9ac69782009-08-14 10:15:52 -0300600
Kyle Guinnd661e622009-01-16 05:36:14 -0300601 return 0;
602}
603
604/* this function is called at probe and resume time */
605static int sd_init(struct gspca_dev *gspca_dev)
606{
607 return 0;
608}
609
Theodore Kilgore89f08632009-08-14 06:51:52 -0300610static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300611{
612 struct sd *sd = (struct sd *) gspca_dev;
613 __u8 *data = gspca_dev->usb_buf;
614 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300615 const __u8 startup_string[] = {
616 0x00,
617 0x0d,
618 0x01,
619 0x00, /* Hsize/8 for 352 or 320 */
620 0x00, /* Vsize/4 for 288 or 240 */
621 0x13, /* or 0xbb, depends on sensor */
622 0x00, /* Hstart, depends on res. */
623 0x00, /* reserved ? */
624 0x00, /* Vstart, depends on res. and sensor */
625 0x50, /* 0x54 to get 176 or 160 */
626 0xc0
627 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300628
Theodore Kilgore89f08632009-08-14 06:51:52 -0300629 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300630
Theodore Kilgore89f08632009-08-14 06:51:52 -0300631 memcpy(data, startup_string, 11);
632 if (sd->sensor_type)
633 data[5] = 0xbb;
634
635 switch (gspca_dev->width) {
636 case 160:
637 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
638 /* fall thru */
639 case 320:
640 default:
641 data[3] = 0x28; /* reg 2, H size/8 */
642 data[4] = 0x3c; /* reg 3, V size/4 */
643 data[6] = 0x14; /* reg 5, H start */
644 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
645 break;
646 case 176:
647 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
648 /* fall thru */
649 case 352:
650 data[3] = 0x2c; /* reg 2, H size/8 */
651 data[4] = 0x48; /* reg 3, V size/4 */
652 data[6] = 0x06; /* reg 5, H start */
Theodore Kilgore32345b02009-11-01 12:59:42 -0300653 data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300654 break;
655 }
656 err_code = mr_write(gspca_dev, 11);
657 if (err_code < 0)
658 return err_code;
659
660 if (!sd->sensor_type) {
661 const struct sensor_w_data cif_sensor0_init_data[] = {
662 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
663 0x0f, 0x14, 0x0f, 0x10}, 8},
664 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
665 {0x12, 0x00, {0x07}, 1},
666 {0x1f, 0x00, {0x06}, 1},
667 {0x27, 0x00, {0x04}, 1},
668 {0x29, 0x00, {0x0c}, 1},
669 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
670 {0x50, 0x00, {0x60}, 1},
671 {0x60, 0x00, {0x06}, 1},
672 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
673 {0x72, 0x00, {0x1e, 0x56}, 2},
674 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
675 0x31, 0x80, 0x00}, 9},
676 {0x11, 0x00, {0x01}, 1},
677 {0, 0, {0}, 0}
678 };
679 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
680 ARRAY_SIZE(cif_sensor0_init_data));
681 } else { /* sd->sensor_type = 1 */
682 const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300683 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300684 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300685 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
686 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300687 {0x09, 0x02, {0x0e}, 1},
688 {0x0a, 0x02, {0x05}, 1},
689 {0x0b, 0x02, {0x05}, 1},
690 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300691 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300692 {0x0e, 0x02, {0x0c}, 1},
693 {0x0f, 0x00, {0x00}, 1},
694 {0x10, 0x00, {0x06}, 1},
695 {0x11, 0x00, {0x07}, 1},
696 {0x12, 0x00, {0x00}, 1},
697 {0x13, 0x00, {0x01}, 1},
698 {0, 0, {0}, 0}
699 };
700 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
701 ARRAY_SIZE(cif_sensor1_init_data));
702 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300703 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300704}
705
706static int start_vga_cam(struct gspca_dev *gspca_dev)
707{
708 struct sd *sd = (struct sd *) gspca_dev;
709 __u8 *data = gspca_dev->usb_buf;
710 int err_code;
711 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
712 0x00, 0x00, 0x00, 0x50, 0xc0};
Theodore Kilgore89f08632009-08-14 06:51:52 -0300713 /* What some of these mean is explained in start_cif_cam(), above */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300714
Theodore Kilgore89f08632009-08-14 06:51:52 -0300715 memcpy(data, startup_string, 11);
716 if (!sd->sensor_type) {
717 data[5] = 0x00;
718 data[10] = 0x91;
719 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300720
721 switch (gspca_dev->width) {
722 case 160:
723 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
724 /* fall thru */
725 case 320:
726 data[9] |= 0x04; /* reg 8, 2:1 scale down */
727 /* fall thru */
728 case 640:
729 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300730 data[3] = 0x50; /* reg 2, H size/8 */
731 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300732 data[6] = 0x04; /* reg 5, H start */
733 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300734 if (sd->do_lcd_stop)
735 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300736 break;
737
738 case 176:
739 data[9] |= 0x04; /* reg 8, 2:1 scale down */
740 /* fall thru */
741 case 352:
742 data[3] = 0x2c; /* reg 2, H size */
743 data[4] = 0x48; /* reg 3, V size */
744 data[6] = 0x94; /* reg 5, H start */
745 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300746 if (sd->do_lcd_stop)
747 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300748 break;
749 }
750
Theodore Kilgore89f08632009-08-14 06:51:52 -0300751 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300752 if (err_code < 0)
753 return err_code;
754
Theodore Kilgore89f08632009-08-14 06:51:52 -0300755 if (!sd->sensor_type) {
756 /* The only known sensor_type 0 cam is the Argus DC-1620 */
757 const struct sensor_w_data vga_sensor0_init_data[] = {
758 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
759 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
760 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
761 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
762 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
763 {0, 0, {0}, 0}
764 };
765 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
766 ARRAY_SIZE(vga_sensor0_init_data));
767 } else { /* sd->sensor_type = 1 */
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300768 const struct sensor_w_data color_adj[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300769 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300770 /* adjusted blue, green, red gain correct
771 too much blue from the Sakar Digital */
Theodore Kilgoreb31210d2009-11-01 13:02:59 -0300772 0x05, 0x01, 0x04}, 8}
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300773 };
774
775 const struct sensor_w_data color_no_adj[] = {
776 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
777 /* default blue, green, red gain settings */
778 0x07, 0x00, 0x01}, 8}
779 };
780
781 const struct sensor_w_data vga_sensor1_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300782 {0x11, 0x04, {0x01}, 1},
Theodore Kilgore542821d2009-11-01 13:09:15 -0300783 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
784 /* These settings may be better for some cameras */
785 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300786 0x00, 0x0a}, 7},
787 {0x11, 0x04, {0x01}, 1},
788 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
789 {0x11, 0x04, {0x01}, 1},
790 {0, 0, {0}, 0}
791 };
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300792
793 if (sd->adj_colors)
794 err_code = sensor_write_regs(gspca_dev, color_adj,
795 ARRAY_SIZE(color_adj));
796 else
797 err_code = sensor_write_regs(gspca_dev, color_no_adj,
798 ARRAY_SIZE(color_no_adj));
799
800 if (err_code < 0)
801 return err_code;
802
Theodore Kilgore89f08632009-08-14 06:51:52 -0300803 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
804 ARRAY_SIZE(vga_sensor1_init_data));
805 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300806 return err_code;
807}
808
809static int sd_start(struct gspca_dev *gspca_dev)
810{
811 struct sd *sd = (struct sd *) gspca_dev;
812 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300813
Theodore Kilgore89f08632009-08-14 06:51:52 -0300814 sd->sof_read = 0;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300815
816 /* Some of the VGA cameras require the memory pointer
817 * to be set to 0 again. We have been forced to start the
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300818 * stream in sd_config() to detect the hardware, and closed it.
819 * Thus, we need here to do a completely fresh and clean start. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300820 err_code = zero_the_pointer(gspca_dev);
821 if (err_code < 0)
822 return err_code;
823
824 err_code = stream_start(gspca_dev);
825 if (err_code < 0)
826 return err_code;
827
Theodore Kilgore89f08632009-08-14 06:51:52 -0300828 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300829 err_code = start_cif_cam(gspca_dev);
830 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300831 err_code = start_vga_cam(gspca_dev);
832 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300833 if (err_code < 0)
834 return err_code;
835
836 setbrightness(gspca_dev);
837 setexposure(gspca_dev);
838 setgain(gspca_dev);
839
840 return isoc_enable(gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300841}
842
843static void sd_stopN(struct gspca_dev *gspca_dev)
844{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300845 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300846
Theodore Kilgore930bf782009-10-05 05:11:35 -0300847 stream_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300848 /* Not all the cams need this, but even if not, probably a good idea */
849 zero_the_pointer(gspca_dev);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300850 if (sd->do_lcd_stop)
851 lcd_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300852}
853
854static void setbrightness(struct gspca_dev *gspca_dev)
855{
856 struct sd *sd = (struct sd *) gspca_dev;
857 u8 val;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300858 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
859 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
860 const u8 quick_clix_table[] =
861 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
862 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
863 /*
864 * This control is disabled for CIF type 1 and VGA type 0 cameras.
865 * It does not quite act linearly for the Argus QuickClix camera,
866 * but it does control brightness. The values are 0 - 15 only, and
867 * the table above makes them act consecutively.
868 */
869 if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
870 (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
Hans de Goede9ac69782009-08-14 10:15:52 -0300871 return;
872
Theodore Kilgore930bf782009-10-05 05:11:35 -0300873 if (sd->cam_type == CAM_TYPE_VGA) {
874 sign_reg += 4;
875 value_reg += 4;
876 }
877
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300878 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300879 if (sd->brightness > 0) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300880 sensor_write1(gspca_dev, sign_reg, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300881 val = sd->brightness;
882 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300883 sensor_write1(gspca_dev, sign_reg, 0x01);
884 val = (257 - sd->brightness);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300885 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300886 /* Use lookup table for funky Argus QuickClix brightness */
887 if (sd->do_lcd_stop)
888 val = quick_clix_table[val];
889
890 sensor_write1(gspca_dev, value_reg, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300891}
892
893static void setexposure(struct gspca_dev *gspca_dev)
894{
895 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300896 int exposure;
Hans de Goede065b6f72009-10-29 07:42:30 -0300897 u8 buf[2];
Theodore Kilgore89f08632009-08-14 06:51:52 -0300898
Hans de Goede9ac69782009-08-14 10:15:52 -0300899 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
900 return;
901
Theodore Kilgore930bf782009-10-05 05:11:35 -0300902 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300903 /* This cam does not like exposure settings < 300,
Hans de Goeded76f9752009-10-11 05:22:29 -0300904 so scale 0 - 4095 to 300 - 4095 */
905 exposure = (sd->exposure * 9267) / 10000 + 300;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300906 sensor_write1(gspca_dev, 3, exposure >> 4);
907 sensor_write1(gspca_dev, 4, exposure & 0x0f);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300908 } else {
Hans de Goedea2e081b2009-08-14 17:11:36 -0300909 /* We have both a clock divider and an exposure register.
910 We first calculate the clock divider, as that determines
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300911 the maximum exposure and then we calculate the exposure
Hans de Goedea2e081b2009-08-14 17:11:36 -0300912 register setting (which goes from 0 - 511).
913
914 Note our 0 - 4095 exposure is mapped to 0 - 511
915 milliseconds exposure time */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300916 u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300917
918 /* Limit framerate to not exceed usb bandwidth */
Hans de Goede065b6f72009-10-29 07:42:30 -0300919 if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
920 clockdiv = sd->min_clockdiv;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300921 else if (clockdiv < 2)
922 clockdiv = 2;
923
Theodore Kilgore930bf782009-10-05 05:11:35 -0300924 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
925 clockdiv = 4;
926
Hans de Goedea2e081b2009-08-14 17:11:36 -0300927 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
928 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
929 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
930 if (exposure > 511)
931 exposure = 511;
932
933 /* exposure register value is reversed! */
934 exposure = 511 - exposure;
935
Hans de Goede065b6f72009-10-29 07:42:30 -0300936 buf[0] = exposure & 0xff;
937 buf[1] = exposure >> 8;
938 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300939 sensor_write1(gspca_dev, 0x02, clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300940 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300941}
942
943static void setgain(struct gspca_dev *gspca_dev)
944{
945 struct sd *sd = (struct sd *) gspca_dev;
946
Hans de Goede9ac69782009-08-14 10:15:52 -0300947 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
948 return;
949
Theodore Kilgore930bf782009-10-05 05:11:35 -0300950 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Hans de Goede823902de2009-08-17 12:25:17 -0300951 sensor_write1(gspca_dev, 0x0e, sd->gain);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300952 } else {
953 sensor_write1(gspca_dev, 0x10, sd->gain);
954 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300955}
956
957static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
958{
959 struct sd *sd = (struct sd *) gspca_dev;
960
961 sd->brightness = val;
962 if (gspca_dev->streaming)
963 setbrightness(gspca_dev);
964 return 0;
965}
966
967static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
968{
969 struct sd *sd = (struct sd *) gspca_dev;
970
971 *val = sd->brightness;
972 return 0;
973}
974
975static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
976{
977 struct sd *sd = (struct sd *) gspca_dev;
978
979 sd->exposure = val;
980 if (gspca_dev->streaming)
981 setexposure(gspca_dev);
982 return 0;
983}
984
985static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
986{
987 struct sd *sd = (struct sd *) gspca_dev;
988
989 *val = sd->exposure;
990 return 0;
991}
992
993static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
994{
995 struct sd *sd = (struct sd *) gspca_dev;
996
997 sd->gain = val;
998 if (gspca_dev->streaming)
999 setgain(gspca_dev);
1000 return 0;
1001}
1002
1003static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1004{
1005 struct sd *sd = (struct sd *) gspca_dev;
1006
1007 *val = sd->gain;
1008 return 0;
Kyle Guinnd661e622009-01-16 05:36:14 -03001009}
1010
Hans de Goede065b6f72009-10-29 07:42:30 -03001011static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1012{
1013 struct sd *sd = (struct sd *) gspca_dev;
1014
1015 sd->min_clockdiv = val;
1016 if (gspca_dev->streaming)
1017 setexposure(gspca_dev);
1018 return 0;
1019}
1020
1021static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 *val = sd->min_clockdiv;
1026 return 0;
1027}
1028
Kyle Guinnd661e622009-01-16 05:36:14 -03001029/* Include pac common sof detection functions */
1030#include "pac_common.h"
1031
1032static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001033 u8 *data, /* isoc packet */
1034 int len) /* iso packet length */
Kyle Guinnd661e622009-01-16 05:36:14 -03001035{
Marton Nemetha6b69e42009-11-02 08:05:51 -03001036 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -03001037 unsigned char *sof;
1038
Marton Nemetha6b69e42009-11-02 08:05:51 -03001039 sof = pac_find_sof(&sd->sof_read, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001040 if (sof) {
1041 int n;
1042
1043 /* finish decoding current frame */
1044 n = sof - data;
1045 if (n > sizeof pac_sof_marker)
1046 n -= sizeof pac_sof_marker;
1047 else
1048 n = 0;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001049 gspca_frame_add(gspca_dev, LAST_PACKET,
Kyle Guinnd661e622009-01-16 05:36:14 -03001050 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -03001051 /* Start next frame. */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001052 gspca_frame_add(gspca_dev, FIRST_PACKET,
Theodore Kilgore9832d762009-03-13 13:04:31 -03001053 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -03001054 len -= sof - data;
1055 data = sof;
1056 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001057 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001058}
1059
1060/* sub-driver description */
1061static const struct sd_desc sd_desc = {
1062 .name = MODULE_NAME,
1063 .ctrls = sd_ctrls,
1064 .nctrls = ARRAY_SIZE(sd_ctrls),
1065 .config = sd_config,
1066 .init = sd_init,
1067 .start = sd_start,
1068 .stopN = sd_stopN,
1069 .pkt_scan = sd_pkt_scan,
1070};
1071
1072/* -- module initialisation -- */
1073static const __devinitdata struct usb_device_id device_table[] = {
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -03001074 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
Theodore Kilgore89f08632009-08-14 06:51:52 -03001075 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
1076 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
1077 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -03001078 {}
1079};
1080MODULE_DEVICE_TABLE(usb, device_table);
1081
1082/* -- device connect -- */
1083static int sd_probe(struct usb_interface *intf,
1084 const struct usb_device_id *id)
1085{
1086 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1087 THIS_MODULE);
1088}
1089
1090static struct usb_driver sd_driver = {
1091 .name = MODULE_NAME,
1092 .id_table = device_table,
1093 .probe = sd_probe,
1094 .disconnect = gspca_disconnect,
1095#ifdef CONFIG_PM
1096 .suspend = gspca_suspend,
1097 .resume = gspca_resume,
1098#endif
1099};
1100
1101/* -- module insert / remove -- */
1102static int __init sd_mod_init(void)
1103{
Alexey Klimov5d3fa302009-03-27 15:57:46 -03001104 int ret;
1105
1106 ret = usb_register(&sd_driver);
1107 if (ret < 0)
1108 return ret;
Kyle Guinnd661e622009-01-16 05:36:14 -03001109 PDEBUG(D_PROBE, "registered");
1110 return 0;
1111}
1112static void __exit sd_mod_exit(void)
1113{
1114 usb_deregister(&sd_driver);
1115 PDEBUG(D_PROBE, "deregistered");
1116}
1117
1118module_init(sd_mod_init);
1119module_exit(sd_mod_exit);