blob: af454663e2958d36010ff03f8b722d81fdcfa5a1 [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
Hans de Goede1fddcf02010-09-05 07:06:04 -030012 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and
Theodore Kilgore930bf782009-10-05 05:11:35 -030013 * 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
Hans de Goede1fddcf02010-09-05 07:06:04 -030019 * Hans de Goede <hdegoede@redhat.com> and
Theodore Kilgore930bf782009-10-05 05:11:35 -030020 * 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.
Kyle Guinnd661e622009-01-16 05:36:14 -030037 */
38
Joe Perches133a9fe2011-08-21 19:56:57 -030039#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
40
Kyle Guinnd661e622009-01-16 05:36:14 -030041#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
Theodore Kilgore9d3103d2010-02-09 18:05:25 -030058#define MR97310A_CONTRAST_MIN 0
59#define MR97310A_CONTRAST_MAX 31
60#define MR97310A_CONTRAST_DEFAULT 23
61
62#define MR97310A_CS_GAIN_MIN 0
63#define MR97310A_CS_GAIN_MAX 0x7ff
64#define MR97310A_CS_GAIN_DEFAULT 0x110
65
Hans Verkuil3e0ed002012-05-14 09:45:06 -030066#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000)
Hans de Goede065b6f72009-10-29 07:42:30 -030067#define MR97310A_MIN_CLOCKDIV_MIN 3
68#define MR97310A_MIN_CLOCKDIV_MAX 8
69#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
70
Mauro Carvalho Chehab1ddc9f72016-10-18 17:44:16 -020071MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,Theodore Kilgore <kilgota@auburn.edu>");
Kyle Guinnd661e622009-01-16 05:36:14 -030072MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
73MODULE_LICENSE("GPL");
74
Hans de Goede78028702009-09-02 09:55:16 -030075/* global parameters */
Jean-Francois Moine83955552009-12-12 06:58:01 -030076static int force_sensor_type = -1;
Hans de Goede78028702009-09-02 09:55:16 -030077module_param(force_sensor_type, int, 0644);
78MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
79
Kyle Guinnd661e622009-01-16 05:36:14 -030080/* specific webcam descriptor */
81struct sd {
82 struct gspca_dev gspca_dev; /* !! must be the first item */
Hans Verkuil3e0ed002012-05-14 09:45:06 -030083 struct { /* exposure/min_clockdiv control cluster */
84 struct v4l2_ctrl *exposure;
85 struct v4l2_ctrl *min_clockdiv;
86 };
Kyle Guinnd661e622009-01-16 05:36:14 -030087 u8 sof_read;
Theodore Kilgore89f08632009-08-14 06:51:52 -030088 u8 cam_type; /* 0 is CIF and 1 is VGA */
89 u8 sensor_type; /* We use 0 and 1 here, too. */
90 u8 do_lcd_stop;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -030091 u8 adj_colors;
Kyle Guinnd661e622009-01-16 05:36:14 -030092};
93
Theodore Kilgore89f08632009-08-14 06:51:52 -030094struct sensor_w_data {
95 u8 reg;
96 u8 flags;
97 u8 data[16];
98 int len;
99};
100
Theodore Kilgore930bf782009-10-05 05:11:35 -0300101static void sd_stopN(struct gspca_dev *gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300102
103static const struct v4l2_pix_format vga_mode[] = {
104 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
105 .bytesperline = 160,
106 .sizeimage = 160 * 120,
107 .colorspace = V4L2_COLORSPACE_SRGB,
108 .priv = 4},
109 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
110 .bytesperline = 176,
111 .sizeimage = 176 * 144,
112 .colorspace = V4L2_COLORSPACE_SRGB,
113 .priv = 3},
114 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
115 .bytesperline = 320,
116 .sizeimage = 320 * 240,
117 .colorspace = V4L2_COLORSPACE_SRGB,
118 .priv = 2},
119 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
120 .bytesperline = 352,
121 .sizeimage = 352 * 288,
122 .colorspace = V4L2_COLORSPACE_SRGB,
123 .priv = 1},
124 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
125 .bytesperline = 640,
126 .sizeimage = 640 * 480,
127 .colorspace = V4L2_COLORSPACE_SRGB,
128 .priv = 0},
129};
130
131/* the bytes to write are in gspca_dev->usb_buf */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300132static int mr_write(struct gspca_dev *gspca_dev, int len)
Kyle Guinnd661e622009-01-16 05:36:14 -0300133{
134 int rc;
135
136 rc = usb_bulk_msg(gspca_dev->dev,
137 usb_sndbulkpipe(gspca_dev->dev, 4),
Jean-Francois Moine92e8c912009-02-02 16:25:38 -0300138 gspca_dev->usb_buf, len, NULL, 500);
Kyle Guinnd661e622009-01-16 05:36:14 -0300139 if (rc < 0)
Joe Perches133a9fe2011-08-21 19:56:57 -0300140 pr_err("reg write [%02x] error %d\n",
Kyle Guinnd661e622009-01-16 05:36:14 -0300141 gspca_dev->usb_buf[0], rc);
142 return rc;
143}
144
Theodore Kilgore89f08632009-08-14 06:51:52 -0300145/* the bytes are read into gspca_dev->usb_buf */
146static int mr_read(struct gspca_dev *gspca_dev, int len)
147{
148 int rc;
149
150 rc = usb_bulk_msg(gspca_dev->dev,
151 usb_rcvbulkpipe(gspca_dev->dev, 3),
152 gspca_dev->usb_buf, len, NULL, 500);
153 if (rc < 0)
Joe Perches133a9fe2011-08-21 19:56:57 -0300154 pr_err("reg read [%02x] error %d\n",
Theodore Kilgore89f08632009-08-14 06:51:52 -0300155 gspca_dev->usb_buf[0], rc);
156 return rc;
157}
158
159static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
160 const u8 *data, int len)
161{
162 gspca_dev->usb_buf[0] = 0x1f;
163 gspca_dev->usb_buf[1] = flags;
164 gspca_dev->usb_buf[2] = reg;
165 memcpy(gspca_dev->usb_buf + 3, data, len);
166
167 return mr_write(gspca_dev, len + 3);
168}
169
170static int sensor_write_regs(struct gspca_dev *gspca_dev,
171 const struct sensor_w_data *data, int len)
172{
173 int i, rc;
174
175 for (i = 0; i < len; i++) {
176 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
177 data[i].data, data[i].len);
178 if (rc < 0)
179 return rc;
180 }
181
182 return 0;
183}
184
185static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
186{
Hans de Goedea2e081b2009-08-14 17:11:36 -0300187 struct sd *sd = (struct sd *) gspca_dev;
188 u8 buf, confirm_reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300189 int rc;
190
191 buf = data;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300192 if (sd->cam_type == CAM_TYPE_CIF) {
193 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
194 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
195 } else {
196 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
197 confirm_reg = 0x11;
198 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300199 if (rc < 0)
200 return rc;
201
202 buf = 0x01;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300203 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300204 if (rc < 0)
205 return rc;
206
207 return 0;
208}
209
Theodore Kilgore930bf782009-10-05 05:11:35 -0300210static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300211{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300212 int err_code;
213
Theodore Kilgore930bf782009-10-05 05:11:35 -0300214 gspca_dev->usb_buf[0] = reg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300215 err_code = mr_write(gspca_dev, 1);
216 if (err_code < 0)
217 return err_code;
218
219 err_code = mr_read(gspca_dev, 16);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300220 if (err_code < 0)
221 return err_code;
222
223 if (verbose)
Joe Perches37d5efb2017-09-22 15:20:33 -0400224 gspca_dbg(gspca_dev, D_PROBE, "Register: %02x reads %02x%02x%02x\n",
225 reg,
226 gspca_dev->usb_buf[0],
227 gspca_dev->usb_buf[1],
228 gspca_dev->usb_buf[2]);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300229
230 return 0;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300231}
232
233static int zero_the_pointer(struct gspca_dev *gspca_dev)
234{
235 __u8 *data = gspca_dev->usb_buf;
236 int err_code;
237 u8 status = 0;
238 int tries = 0;
239
Theodore Kilgore930bf782009-10-05 05:11:35 -0300240 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300241 if (err_code < 0)
242 return err_code;
243
Theodore Kilgore89f08632009-08-14 06:51:52 -0300244 data[0] = 0x19;
245 data[1] = 0x51;
246 err_code = mr_write(gspca_dev, 2);
247 if (err_code < 0)
248 return err_code;
249
Theodore Kilgore930bf782009-10-05 05:11:35 -0300250 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300251 if (err_code < 0)
252 return err_code;
253
254 data[0] = 0x19;
255 data[1] = 0xba;
256 err_code = mr_write(gspca_dev, 2);
257 if (err_code < 0)
258 return err_code;
259
Theodore Kilgore930bf782009-10-05 05:11:35 -0300260 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300261 if (err_code < 0)
262 return err_code;
263
264 data[0] = 0x19;
265 data[1] = 0x00;
266 err_code = mr_write(gspca_dev, 2);
267 if (err_code < 0)
268 return err_code;
269
Theodore Kilgore930bf782009-10-05 05:11:35 -0300270 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300271 if (err_code < 0)
272 return err_code;
273
274 data[0] = 0x19;
275 data[1] = 0x00;
276 err_code = mr_write(gspca_dev, 2);
277 if (err_code < 0)
278 return err_code;
279
280 while (status != 0x0a && tries < 256) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300281 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300282 status = data[0];
283 tries++;
284 if (err_code < 0)
285 return err_code;
286 }
Hans de Goede54943782009-08-14 11:05:38 -0300287 if (status != 0x0a)
Joe Perches52173c5f2017-09-22 14:33:35 -0400288 gspca_err(gspca_dev, "status is %02x\n", status);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300289
290 tries = 0;
291 while (tries < 4) {
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
Theodore Kilgore930bf782009-10-05 05:11:35 -0300298 err_code = cam_get_response16(gspca_dev, 0x21, 0);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300299 status = data[0];
300 tries++;
301 if (err_code < 0)
302 return err_code;
303 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300304
305 data[0] = 0x19;
306 err_code = mr_write(gspca_dev, 1);
307 if (err_code < 0)
308 return err_code;
309
310 err_code = mr_read(gspca_dev, 16);
311 if (err_code < 0)
312 return err_code;
313
314 return 0;
315}
316
Theodore Kilgore930bf782009-10-05 05:11:35 -0300317static int stream_start(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300318{
Theodore Kilgore930bf782009-10-05 05:11:35 -0300319 gspca_dev->usb_buf[0] = 0x01;
320 gspca_dev->usb_buf[1] = 0x01;
321 return mr_write(gspca_dev, 2);
322}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300323
Theodore Kilgore930bf782009-10-05 05:11:35 -0300324static void stream_stop(struct gspca_dev *gspca_dev)
325{
326 gspca_dev->usb_buf[0] = 0x01;
327 gspca_dev->usb_buf[1] = 0x00;
328 if (mr_write(gspca_dev, 2) < 0)
Joe Perches52173c5f2017-09-22 14:33:35 -0400329 gspca_err(gspca_dev, "Stream Stop failed\n");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300330}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300331
Theodore Kilgore930bf782009-10-05 05:11:35 -0300332static void lcd_stop(struct gspca_dev *gspca_dev)
333{
334 gspca_dev->usb_buf[0] = 0x19;
335 gspca_dev->usb_buf[1] = 0x54;
336 if (mr_write(gspca_dev, 2) < 0)
Joe Perches52173c5f2017-09-22 14:33:35 -0400337 gspca_err(gspca_dev, "LCD Stop failed\n");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300338}
Theodore Kilgore89f08632009-08-14 06:51:52 -0300339
Theodore Kilgore930bf782009-10-05 05:11:35 -0300340static int isoc_enable(struct gspca_dev *gspca_dev)
341{
342 gspca_dev->usb_buf[0] = 0x00;
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300343 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300344 return mr_write(gspca_dev, 2);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300345}
346
Theodore Kilgore1160a382009-10-30 04:29:56 -0300347/* This function is called at probe time */
Kyle Guinnd661e622009-01-16 05:36:14 -0300348static int sd_config(struct gspca_dev *gspca_dev,
349 const struct usb_device_id *id)
350{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300351 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300352 struct cam *cam;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300353 int err_code;
Kyle Guinnd661e622009-01-16 05:36:14 -0300354
355 cam = &gspca_dev->cam;
356 cam->cam_mode = vga_mode;
357 cam->nmodes = ARRAY_SIZE(vga_mode);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300358 sd->do_lcd_stop = 0;
359
Theodore Kilgore1160a382009-10-30 04:29:56 -0300360 /* Several of the supported CIF cameras share the same USB ID but
361 * require different initializations and different control settings.
362 * The same is true of the VGA cameras. Therefore, we are forced
363 * to start the initialization process in order to determine which
364 * camera is present. Some of the supported cameras require the
Theodore Kilgore930bf782009-10-05 05:11:35 -0300365 * memory pointer to be set to 0 as the very first item of business
366 * or else they will not stream. So we do that immediately.
367 */
368 err_code = zero_the_pointer(gspca_dev);
369 if (err_code < 0)
370 return err_code;
Hans de Goede9ac69782009-08-14 10:15:52 -0300371
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300372 err_code = stream_start(gspca_dev);
373 if (err_code < 0)
374 return err_code;
375
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300376 /* Now, the query for sensor type. */
377 err_code = cam_get_response16(gspca_dev, 0x07, 1);
378 if (err_code < 0)
379 return err_code;
380
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -0300381 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300382 sd->cam_type = CAM_TYPE_CIF;
Hans de Goede9ac69782009-08-14 10:15:52 -0300383 cam->nmodes--;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300384 /*
Theodore Kilgore1160a382009-10-30 04:29:56 -0300385 * All but one of the known CIF cameras share the same USB ID,
386 * but two different init routines are in use, and the control
387 * settings are different, too. We need to detect which camera
388 * of the two known varieties is connected!
Theodore Kilgore930bf782009-10-05 05:11:35 -0300389 *
390 * A list of known CIF cameras follows. They all report either
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300391 * 0200 for type 0 or 0300 for type 1.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300392 * If you have another to report, please do
393 *
394 * Name sd->sensor_type reported by
395 *
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300396 * Sakar 56379 Spy-shot 0 T. Kilgore
Theodore Kilgore930bf782009-10-05 05:11:35 -0300397 * Innovage 0 T. Kilgore
398 * Vivitar Mini 0 H. De Goede
399 * Vivitar Mini 0 E. Rodriguez
400 * Vivitar Mini 1 T. Kilgore
401 * Elta-Media 8212dc 1 T. Kaiser
402 * Philips dig. keych. 1 T. Kilgore
Theodore Kilgore1160a382009-10-30 04:29:56 -0300403 * Trust Spyc@m 100 1 A. Jacobs
Theodore Kilgore930bf782009-10-05 05:11:35 -0300404 */
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300405 switch (gspca_dev->usb_buf[0]) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300406 case 2:
407 sd->sensor_type = 0;
408 break;
409 case 3:
410 sd->sensor_type = 1;
411 break;
412 default:
Joe Perches133a9fe2011-08-21 19:56:57 -0300413 pr_err("Unknown CIF Sensor id : %02x\n",
Theodore Kilgore930bf782009-10-05 05:11:35 -0300414 gspca_dev->usb_buf[1]);
415 return -ENODEV;
416 }
Joe Perches37d5efb2017-09-22 15:20:33 -0400417 gspca_dbg(gspca_dev, D_PROBE, "MR97310A CIF camera detected, sensor: %d\n",
418 sd->sensor_type);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300419 } else {
420 sd->cam_type = CAM_TYPE_VGA;
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300421
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300422 /*
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300423 * Here is a table of the responses to the query for sensor
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300424 * type, from the known MR97310A VGA cameras. Six different
425 * cameras of which five share the same USB ID.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300426 *
427 * Name gspca_dev->usb_buf[] sd->sensor_type
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300428 * sd->do_lcd_stop
429 * Aiptek Pencam VGA+ 0300 0 1
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300430 * ION digital 0300 0 1
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300431 * Argus DC-1620 0450 1 0
432 * Argus QuickClix 0420 1 1
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300433 * Sakar 77379 Digital 0350 0 1
434 * Sakar 1638x CyberPix 0120 0 2
Theodore Kilgore930bf782009-10-05 05:11:35 -0300435 *
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300436 * Based upon these results, we assume default settings
437 * and then correct as necessary, as follows.
Theodore Kilgore930bf782009-10-05 05:11:35 -0300438 *
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300439 */
Hans de Goede5f5e26b2009-08-14 10:40:26 -0300440
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300441 sd->sensor_type = 1;
442 sd->do_lcd_stop = 0;
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300443 sd->adj_colors = 0;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300444 if (gspca_dev->usb_buf[0] == 0x01) {
445 sd->sensor_type = 2;
446 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300447 (gspca_dev->usb_buf[0] != 0x04)) {
Joe Perches133a9fe2011-08-21 19:56:57 -0300448 pr_err("Unknown VGA Sensor id Byte 0: %02x\n",
449 gspca_dev->usb_buf[0]);
450 pr_err("Defaults assumed, may not work\n");
451 pr_err("Please report this\n");
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300452 }
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300453 /* Sakar Digital color needs to be adjusted. */
454 if ((gspca_dev->usb_buf[0] == 0x03) &&
455 (gspca_dev->usb_buf[1] == 0x50))
456 sd->adj_colors = 1;
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300457 if (gspca_dev->usb_buf[0] == 0x04) {
458 sd->do_lcd_stop = 1;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300459 switch (gspca_dev->usb_buf[1]) {
460 case 0x50:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300461 sd->sensor_type = 0;
Joe Perches37d5efb2017-09-22 15:20:33 -0400462 gspca_dbg(gspca_dev, D_PROBE, "sensor_type corrected to 0\n");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300463 break;
464 case 0x20:
Theodore Kilgoreb3e440e2009-10-09 03:54:49 -0300465 /* Nothing to do here. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300466 break;
467 default:
Joe Perches133a9fe2011-08-21 19:56:57 -0300468 pr_err("Unknown VGA Sensor id Byte 1: %02x\n",
469 gspca_dev->usb_buf[1]);
470 pr_err("Defaults assumed, may not work\n");
471 pr_err("Please report this\n");
Theodore Kilgore930bf782009-10-05 05:11:35 -0300472 }
Hans de Goede78028702009-09-02 09:55:16 -0300473 }
Joe Perches37d5efb2017-09-22 15:20:33 -0400474 gspca_dbg(gspca_dev, D_PROBE, "MR97310A VGA camera detected, sensor: %d\n",
475 sd->sensor_type);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300476 }
Theodore Kilgorec260fe92010-01-15 05:54:36 -0300477 /* Stop streaming as we've started it only to probe the sensor type. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300478 sd_stopN(gspca_dev);
Hans de Goede78028702009-09-02 09:55:16 -0300479
Theodore Kilgore930bf782009-10-05 05:11:35 -0300480 if (force_sensor_type != -1) {
481 sd->sensor_type = !!force_sensor_type;
Joe Perches37d5efb2017-09-22 15:20:33 -0400482 gspca_dbg(gspca_dev, D_PROBE, "Forcing sensor type to: %d\n",
483 sd->sensor_type);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300484 }
485
Kyle Guinnd661e622009-01-16 05:36:14 -0300486 return 0;
487}
488
489/* this function is called at probe and resume time */
490static int sd_init(struct gspca_dev *gspca_dev)
491{
492 return 0;
493}
494
Theodore Kilgore89f08632009-08-14 06:51:52 -0300495static int start_cif_cam(struct gspca_dev *gspca_dev)
Kyle Guinnd661e622009-01-16 05:36:14 -0300496{
497 struct sd *sd = (struct sd *) gspca_dev;
498 __u8 *data = gspca_dev->usb_buf;
499 int err_code;
Jean-François Moine294d8b42010-10-01 07:37:15 -0300500 static const __u8 startup_string[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300501 0x00,
502 0x0d,
503 0x01,
504 0x00, /* Hsize/8 for 352 or 320 */
505 0x00, /* Vsize/4 for 288 or 240 */
506 0x13, /* or 0xbb, depends on sensor */
507 0x00, /* Hstart, depends on res. */
508 0x00, /* reserved ? */
509 0x00, /* Vstart, depends on res. and sensor */
510 0x50, /* 0x54 to get 176 or 160 */
511 0xc0
512 };
Kyle Guinnd661e622009-01-16 05:36:14 -0300513
Theodore Kilgore89f08632009-08-14 06:51:52 -0300514 /* Note: Some of the above descriptions guessed from MR97113A driver */
Kyle Guinnd661e622009-01-16 05:36:14 -0300515
Theodore Kilgore89f08632009-08-14 06:51:52 -0300516 memcpy(data, startup_string, 11);
517 if (sd->sensor_type)
518 data[5] = 0xbb;
519
Ondrej Zary1966bc22013-08-30 17:54:23 -0300520 switch (gspca_dev->pixfmt.width) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300521 case 160:
522 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500523 /* fall through */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300524 case 320:
525 default:
526 data[3] = 0x28; /* reg 2, H size/8 */
527 data[4] = 0x3c; /* reg 3, V size/4 */
528 data[6] = 0x14; /* reg 5, H start */
529 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
530 break;
531 case 176:
532 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500533 /* fall through */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300534 case 352:
535 data[3] = 0x2c; /* reg 2, H size/8 */
536 data[4] = 0x48; /* reg 3, V size/4 */
537 data[6] = 0x06; /* reg 5, H start */
Theodore Kilgore32345b02009-11-01 12:59:42 -0300538 data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300539 break;
540 }
541 err_code = mr_write(gspca_dev, 11);
542 if (err_code < 0)
543 return err_code;
544
545 if (!sd->sensor_type) {
Jean-François Moine294d8b42010-10-01 07:37:15 -0300546 static const struct sensor_w_data cif_sensor0_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300547 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
548 0x0f, 0x14, 0x0f, 0x10}, 8},
549 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
550 {0x12, 0x00, {0x07}, 1},
551 {0x1f, 0x00, {0x06}, 1},
552 {0x27, 0x00, {0x04}, 1},
553 {0x29, 0x00, {0x0c}, 1},
554 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
555 {0x50, 0x00, {0x60}, 1},
556 {0x60, 0x00, {0x06}, 1},
557 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
558 {0x72, 0x00, {0x1e, 0x56}, 2},
559 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
560 0x31, 0x80, 0x00}, 9},
561 {0x11, 0x00, {0x01}, 1},
562 {0, 0, {0}, 0}
563 };
564 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
565 ARRAY_SIZE(cif_sensor0_init_data));
566 } else { /* sd->sensor_type = 1 */
Jean-François Moine294d8b42010-10-01 07:37:15 -0300567 static const struct sensor_w_data cif_sensor1_init_data[] = {
Hans de Goede9ac69782009-08-14 10:15:52 -0300568 /* Reg 3,4, 7,8 get set by the controls */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300569 {0x02, 0x00, {0x10}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300570 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
571 {0x06, 0x01, {0x00}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300572 {0x09, 0x02, {0x0e}, 1},
573 {0x0a, 0x02, {0x05}, 1},
574 {0x0b, 0x02, {0x05}, 1},
575 {0x0c, 0x02, {0x0f}, 1},
Hans de Goede9ac69782009-08-14 10:15:52 -0300576 {0x0d, 0x02, {0x07}, 1},
Theodore Kilgore89f08632009-08-14 06:51:52 -0300577 {0x0e, 0x02, {0x0c}, 1},
578 {0x0f, 0x00, {0x00}, 1},
579 {0x10, 0x00, {0x06}, 1},
580 {0x11, 0x00, {0x07}, 1},
581 {0x12, 0x00, {0x00}, 1},
582 {0x13, 0x00, {0x01}, 1},
583 {0, 0, {0}, 0}
584 };
Theodore Kilgore70136082009-12-25 05:15:10 -0300585 /* Without this command the cam won't work with USB-UHCI */
586 gspca_dev->usb_buf[0] = 0x0a;
587 gspca_dev->usb_buf[1] = 0x00;
588 err_code = mr_write(gspca_dev, 2);
589 if (err_code < 0)
590 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300591 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
592 ARRAY_SIZE(cif_sensor1_init_data));
593 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300594 return err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300595}
596
597static int start_vga_cam(struct gspca_dev *gspca_dev)
598{
599 struct sd *sd = (struct sd *) gspca_dev;
600 __u8 *data = gspca_dev->usb_buf;
601 int err_code;
Jean-François Moine294d8b42010-10-01 07:37:15 -0300602 static const __u8 startup_string[] =
603 {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00,
604 0x00, 0x50, 0xc0};
Theodore Kilgore89f08632009-08-14 06:51:52 -0300605 /* What some of these mean is explained in start_cif_cam(), above */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300606
Theodore Kilgore89f08632009-08-14 06:51:52 -0300607 memcpy(data, startup_string, 11);
608 if (!sd->sensor_type) {
609 data[5] = 0x00;
610 data[10] = 0x91;
611 }
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300612 if (sd->sensor_type == 2) {
613 data[5] = 0x00;
614 data[10] = 0x18;
615 }
Kyle Guinnd661e622009-01-16 05:36:14 -0300616
Ondrej Zary1966bc22013-08-30 17:54:23 -0300617 switch (gspca_dev->pixfmt.width) {
Kyle Guinnd661e622009-01-16 05:36:14 -0300618 case 160:
619 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500620 /* fall through */
Kyle Guinnd661e622009-01-16 05:36:14 -0300621 case 320:
622 data[9] |= 0x04; /* reg 8, 2:1 scale down */
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500623 /* fall through */
Kyle Guinnd661e622009-01-16 05:36:14 -0300624 case 640:
625 default:
Theodore Kilgore89f08632009-08-14 06:51:52 -0300626 data[3] = 0x50; /* reg 2, H size/8 */
627 data[4] = 0x78; /* reg 3, V size/4 */
Kyle Guinnd661e622009-01-16 05:36:14 -0300628 data[6] = 0x04; /* reg 5, H start */
629 data[8] = 0x03; /* reg 7, V start */
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300630 if (sd->sensor_type == 2) {
631 data[6] = 2;
632 data[8] = 1;
633 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300634 if (sd->do_lcd_stop)
635 data[8] = 0x04; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300636 break;
637
638 case 176:
639 data[9] |= 0x04; /* reg 8, 2:1 scale down */
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500640 /* fall through */
Kyle Guinnd661e622009-01-16 05:36:14 -0300641 case 352:
642 data[3] = 0x2c; /* reg 2, H size */
643 data[4] = 0x48; /* reg 3, V size */
644 data[6] = 0x94; /* reg 5, H start */
645 data[8] = 0x63; /* reg 7, V start */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300646 if (sd->do_lcd_stop)
647 data[8] = 0x64; /* Bayer tile shifted */
Kyle Guinnd661e622009-01-16 05:36:14 -0300648 break;
649 }
650
Theodore Kilgore89f08632009-08-14 06:51:52 -0300651 err_code = mr_write(gspca_dev, 11);
Kyle Guinnd661e622009-01-16 05:36:14 -0300652 if (err_code < 0)
653 return err_code;
654
Theodore Kilgore89f08632009-08-14 06:51:52 -0300655 if (!sd->sensor_type) {
Jean-François Moine294d8b42010-10-01 07:37:15 -0300656 static const struct sensor_w_data vga_sensor0_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300657 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
658 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
659 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
660 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
661 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
662 {0, 0, {0}, 0}
663 };
664 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
665 ARRAY_SIZE(vga_sensor0_init_data));
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300666 } else if (sd->sensor_type == 1) {
Jean-François Moine294d8b42010-10-01 07:37:15 -0300667 static const struct sensor_w_data color_adj[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300668 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300669 /* adjusted blue, green, red gain correct
670 too much blue from the Sakar Digital */
Theodore Kilgoreb31210d2009-11-01 13:02:59 -0300671 0x05, 0x01, 0x04}, 8}
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300672 };
673
Jean-François Moine294d8b42010-10-01 07:37:15 -0300674 static const struct sensor_w_data color_no_adj[] = {
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300675 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
676 /* default blue, green, red gain settings */
677 0x07, 0x00, 0x01}, 8}
678 };
679
Jean-François Moine294d8b42010-10-01 07:37:15 -0300680 static const struct sensor_w_data vga_sensor1_init_data[] = {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300681 {0x11, 0x04, {0x01}, 1},
Theodore Kilgore542821d2009-11-01 13:09:15 -0300682 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
683 /* These settings may be better for some cameras */
684 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
Theodore Kilgore89f08632009-08-14 06:51:52 -0300685 0x00, 0x0a}, 7},
686 {0x11, 0x04, {0x01}, 1},
687 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
688 {0x11, 0x04, {0x01}, 1},
689 {0, 0, {0}, 0}
690 };
Theodore Kilgore64f4d9a2009-10-30 04:43:39 -0300691
692 if (sd->adj_colors)
693 err_code = sensor_write_regs(gspca_dev, color_adj,
694 ARRAY_SIZE(color_adj));
695 else
696 err_code = sensor_write_regs(gspca_dev, color_no_adj,
697 ARRAY_SIZE(color_no_adj));
698
699 if (err_code < 0)
700 return err_code;
701
Theodore Kilgore89f08632009-08-14 06:51:52 -0300702 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
703 ARRAY_SIZE(vga_sensor1_init_data));
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300704 } else { /* sensor type == 2 */
Jean-François Moine294d8b42010-10-01 07:37:15 -0300705 static const struct sensor_w_data vga_sensor2_init_data[] = {
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300706
707 {0x01, 0x00, {0x48}, 1},
708 {0x02, 0x00, {0x22}, 1},
709 /* Reg 3 msb and 4 is lsb of the exposure setting*/
710 {0x05, 0x00, {0x10}, 1},
711 {0x06, 0x00, {0x00}, 1},
712 {0x07, 0x00, {0x00}, 1},
713 {0x08, 0x00, {0x00}, 1},
714 {0x09, 0x00, {0x00}, 1},
715 /* The following are used in the gain control
716 * which is BTW completely borked in the OEM driver
717 * The values for each color go from 0 to 0x7ff
718 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
719 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
720 *{0x0c, 0x00, {0x01}, 1}, red gain msb
721 *{0x0d, 0x00, {0x10}, 1}, red gain lsb
722 *{0x0e, 0x00, {0x01}, 1}, blue gain msb
723 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
724 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
725 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
726 */
727 {0x12, 0x00, {0x00}, 1},
728 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
729 {0x14, 0x00, {0x00}, 1},
730 {0x15, 0x00, {0x06}, 1},
731 {0x16, 0x00, {0x01}, 1},
732 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
733 {0x18, 0x00, {0x02}, 1},
734 {0x19, 0x00, {0x82}, 1}, /* don't mess with */
735 {0x1a, 0x00, {0x00}, 1},
736 {0x1b, 0x00, {0x20}, 1},
737 /* {0x1c, 0x00, {0x17}, 1}, contrast control */
738 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
739 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
740 {0x1f, 0x00, {0x0c}, 1},
741 {0x20, 0x00, {0x00}, 1},
742 {0, 0, {0}, 0}
743 };
744 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
745 ARRAY_SIZE(vga_sensor2_init_data));
Theodore Kilgore89f08632009-08-14 06:51:52 -0300746 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300747 return err_code;
748}
749
750static int sd_start(struct gspca_dev *gspca_dev)
751{
752 struct sd *sd = (struct sd *) gspca_dev;
753 int err_code;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300754
Theodore Kilgore89f08632009-08-14 06:51:52 -0300755 sd->sof_read = 0;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300756
757 /* Some of the VGA cameras require the memory pointer
758 * to be set to 0 again. We have been forced to start the
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300759 * stream in sd_config() to detect the hardware, and closed it.
760 * Thus, we need here to do a completely fresh and clean start. */
Theodore Kilgore930bf782009-10-05 05:11:35 -0300761 err_code = zero_the_pointer(gspca_dev);
762 if (err_code < 0)
763 return err_code;
764
765 err_code = stream_start(gspca_dev);
766 if (err_code < 0)
767 return err_code;
768
Theodore Kilgore89f08632009-08-14 06:51:52 -0300769 if (sd->cam_type == CAM_TYPE_CIF) {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300770 err_code = start_cif_cam(gspca_dev);
771 } else {
Theodore Kilgore89f08632009-08-14 06:51:52 -0300772 err_code = start_vga_cam(gspca_dev);
773 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300774 if (err_code < 0)
775 return err_code;
776
Theodore Kilgore930bf782009-10-05 05:11:35 -0300777 return isoc_enable(gspca_dev);
Kyle Guinnd661e622009-01-16 05:36:14 -0300778}
779
780static void sd_stopN(struct gspca_dev *gspca_dev)
781{
Theodore Kilgore89f08632009-08-14 06:51:52 -0300782 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -0300783
Theodore Kilgore930bf782009-10-05 05:11:35 -0300784 stream_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300785 /* Not all the cams need this, but even if not, probably a good idea */
786 zero_the_pointer(gspca_dev);
Theodore Kilgore930bf782009-10-05 05:11:35 -0300787 if (sd->do_lcd_stop)
788 lcd_stop(gspca_dev);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300789}
790
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300791static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300792{
793 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300794 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
795 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
Jean-François Moine294d8b42010-10-01 07:37:15 -0300796 static const u8 quick_clix_table[] =
Theodore Kilgore930bf782009-10-05 05:11:35 -0300797 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
798 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
Theodore Kilgore930bf782009-10-05 05:11:35 -0300799 if (sd->cam_type == CAM_TYPE_VGA) {
800 sign_reg += 4;
801 value_reg += 4;
802 }
803
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300804 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300805 if (val > 0) {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300806 sensor_write1(gspca_dev, sign_reg, 0x00);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300807 } else {
Theodore Kilgore930bf782009-10-05 05:11:35 -0300808 sensor_write1(gspca_dev, sign_reg, 0x01);
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300809 val = 257 - val;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300810 }
Theodore Kilgore930bf782009-10-05 05:11:35 -0300811 /* Use lookup table for funky Argus QuickClix brightness */
812 if (sd->do_lcd_stop)
813 val = quick_clix_table[val];
814
815 sensor_write1(gspca_dev, value_reg, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300816}
817
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300818static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300819{
820 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300821 int exposure = MR97310A_EXPOSURE_DEFAULT;
Hans de Goede065b6f72009-10-29 07:42:30 -0300822 u8 buf[2];
Theodore Kilgore89f08632009-08-14 06:51:52 -0300823
Theodore Kilgore930bf782009-10-05 05:11:35 -0300824 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300825 /* This cam does not like exposure settings < 300,
Hans de Goeded76f9752009-10-11 05:22:29 -0300826 so scale 0 - 4095 to 300 - 4095 */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300827 exposure = (expo * 9267) / 10000 + 300;
Theodore Kilgore930bf782009-10-05 05:11:35 -0300828 sensor_write1(gspca_dev, 3, exposure >> 4);
829 sensor_write1(gspca_dev, 4, exposure & 0x0f);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300830 } else if (sd->sensor_type == 2) {
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300831 exposure = expo;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300832 exposure >>= 3;
833 sensor_write1(gspca_dev, 3, exposure >> 8);
834 sensor_write1(gspca_dev, 4, exposure & 0xff);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300835 } else {
Hans de Goedea2e081b2009-08-14 17:11:36 -0300836 /* We have both a clock divider and an exposure register.
837 We first calculate the clock divider, as that determines
Theodore Kilgoreb4b84de2009-11-01 13:07:08 -0300838 the maximum exposure and then we calculate the exposure
Hans de Goedea2e081b2009-08-14 17:11:36 -0300839 register setting (which goes from 0 - 511).
840
841 Note our 0 - 4095 exposure is mapped to 0 - 511
842 milliseconds exposure time */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300843 u8 clockdiv = (60 * expo + 7999) / 8000;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300844
845 /* Limit framerate to not exceed usb bandwidth */
Ondrej Zary1966bc22013-08-30 17:54:23 -0300846 if (clockdiv < min_clockdiv && gspca_dev->pixfmt.width >= 320)
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300847 clockdiv = min_clockdiv;
Hans de Goedea2e081b2009-08-14 17:11:36 -0300848 else if (clockdiv < 2)
849 clockdiv = 2;
850
Theodore Kilgore930bf782009-10-05 05:11:35 -0300851 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
852 clockdiv = 4;
853
Hans de Goedea2e081b2009-08-14 17:11:36 -0300854 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
855 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300856 exposure = (60 * 511 * expo) / (8000 * clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300857 if (exposure > 511)
858 exposure = 511;
859
860 /* exposure register value is reversed! */
861 exposure = 511 - exposure;
862
Hans de Goede065b6f72009-10-29 07:42:30 -0300863 buf[0] = exposure & 0xff;
864 buf[1] = exposure >> 8;
865 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300866 sensor_write1(gspca_dev, 0x02, clockdiv);
Hans de Goedea2e081b2009-08-14 17:11:36 -0300867 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300868}
869
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300870static void setgain(struct gspca_dev *gspca_dev, s32 val)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300871{
872 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300873 u8 gainreg;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300874
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300875 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300876 sensor_write1(gspca_dev, 0x0e, val);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300877 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
878 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300879 sensor_write1(gspca_dev, gainreg, val >> 8);
880 sensor_write1(gspca_dev, gainreg + 1, val & 0xff);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300881 }
882 else
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300883 sensor_write1(gspca_dev, 0x10, val);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300884}
885
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300886static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300887{
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300888 sensor_write1(gspca_dev, 0x1c, val);
Theodore Kilgore9d3103d2010-02-09 18:05:25 -0300889}
890
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300891static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300892{
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300893 struct gspca_dev *gspca_dev =
894 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
895 struct sd *sd = (struct sd *)gspca_dev;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300896
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300897 gspca_dev->usb_err = 0;
898
899 if (!gspca_dev->streaming)
900 return 0;
901
902 switch (ctrl->id) {
903 case V4L2_CID_BRIGHTNESS:
904 setbrightness(gspca_dev, ctrl->val);
905 break;
906 case V4L2_CID_CONTRAST:
907 setcontrast(gspca_dev, ctrl->val);
908 break;
909 case V4L2_CID_EXPOSURE:
910 setexposure(gspca_dev, sd->exposure->val,
911 sd->min_clockdiv ? sd->min_clockdiv->val : 0);
912 break;
913 case V4L2_CID_GAIN:
914 setgain(gspca_dev, ctrl->val);
915 break;
916 }
917 return gspca_dev->usb_err;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300918}
919
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300920static const struct v4l2_ctrl_ops sd_ctrl_ops = {
921 .s_ctrl = sd_s_ctrl,
922};
923
924static int sd_init_controls(struct gspca_dev *gspca_dev)
Theodore Kilgore89f08632009-08-14 06:51:52 -0300925{
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300926 struct sd *sd = (struct sd *)gspca_dev;
927 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
928 static const struct v4l2_ctrl_config clockdiv = {
929 .ops = &sd_ctrl_ops,
930 .id = MR97310A_CID_CLOCKDIV,
931 .type = V4L2_CTRL_TYPE_INTEGER,
932 .name = "Minimum Clock Divider",
933 .min = MR97310A_MIN_CLOCKDIV_MIN,
934 .max = MR97310A_MIN_CLOCKDIV_MAX,
935 .step = 1,
936 .def = MR97310A_MIN_CLOCKDIV_DEFAULT,
937 };
938 bool has_brightness = false;
939 bool has_argus_brightness = false;
940 bool has_contrast = false;
941 bool has_gain = false;
942 bool has_cs_gain = false;
943 bool has_exposure = false;
944 bool has_clockdiv = false;
Theodore Kilgore89f08632009-08-14 06:51:52 -0300945
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300946 gspca_dev->vdev.ctrl_handler = hdl;
947 v4l2_ctrl_handler_init(hdl, 4);
Theodore Kilgore89f08632009-08-14 06:51:52 -0300948
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300949 /* Setup controls depending on camera type */
950 if (sd->cam_type == CAM_TYPE_CIF) {
951 /* No brightness for sensor_type 0 */
952 if (sd->sensor_type == 0)
953 has_exposure = has_gain = has_clockdiv = true;
954 else
955 has_exposure = has_gain = has_brightness = true;
956 } else {
957 /* All controls need to be disabled if VGA sensor_type is 0 */
958 if (sd->sensor_type == 0)
959 ; /* no controls! */
960 else if (sd->sensor_type == 2)
961 has_exposure = has_cs_gain = has_contrast = true;
962 else if (sd->do_lcd_stop)
963 has_exposure = has_gain = has_argus_brightness =
964 has_clockdiv = true;
965 else
966 has_exposure = has_gain = has_brightness =
967 has_clockdiv = true;
968 }
Theodore Kilgore89f08632009-08-14 06:51:52 -0300969
Hans Verkuil3e0ed002012-05-14 09:45:06 -0300970 /* Separate brightness control description for Argus QuickClix as it has
971 * different limits from the other mr97310a cameras, and separate gain
972 * control for Sakar CyberPix camera. */
973 /*
974 * This control is disabled for CIF type 1 and VGA type 0 cameras.
975 * It does not quite act linearly for the Argus QuickClix camera,
976 * but it does control brightness. The values are 0 - 15 only, and
977 * the table above makes them act consecutively.
978 */
979 if (has_brightness)
980 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
981 V4L2_CID_BRIGHTNESS, -254, 255, 1,
982 MR97310A_BRIGHTNESS_DEFAULT);
983 else if (has_argus_brightness)
984 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
985 V4L2_CID_BRIGHTNESS, 0, 15, 1,
986 MR97310A_BRIGHTNESS_DEFAULT);
987 if (has_contrast)
988 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
989 V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN,
990 MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT);
991 if (has_gain)
992 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
993 V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX,
994 1, MR97310A_GAIN_DEFAULT);
995 else if (has_cs_gain)
996 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN,
997 MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX,
998 1, MR97310A_CS_GAIN_DEFAULT);
999 if (has_exposure)
1000 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1001 V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN,
1002 MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT);
1003 if (has_clockdiv)
1004 sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL);
Theodore Kilgore89f08632009-08-14 06:51:52 -03001005
Hans Verkuil3e0ed002012-05-14 09:45:06 -03001006 if (hdl->error) {
1007 pr_err("Could not initialize controls\n");
1008 return hdl->error;
1009 }
1010 if (has_exposure && has_clockdiv)
1011 v4l2_ctrl_cluster(2, &sd->exposure);
Hans de Goede065b6f72009-10-29 07:42:30 -03001012 return 0;
1013}
1014
Kyle Guinnd661e622009-01-16 05:36:14 -03001015/* Include pac common sof detection functions */
1016#include "pac_common.h"
1017
1018static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001019 u8 *data, /* isoc packet */
1020 int len) /* iso packet length */
Kyle Guinnd661e622009-01-16 05:36:14 -03001021{
Marton Nemetha6b69e42009-11-02 08:05:51 -03001022 struct sd *sd = (struct sd *) gspca_dev;
Kyle Guinnd661e622009-01-16 05:36:14 -03001023 unsigned char *sof;
1024
Theodore Kilgorec93396e2013-02-04 13:17:55 -03001025 sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001026 if (sof) {
1027 int n;
1028
1029 /* finish decoding current frame */
1030 n = sof - data;
1031 if (n > sizeof pac_sof_marker)
1032 n -= sizeof pac_sof_marker;
1033 else
1034 n = 0;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001035 gspca_frame_add(gspca_dev, LAST_PACKET,
Kyle Guinnd661e622009-01-16 05:36:14 -03001036 data, n);
Theodore Kilgore9832d762009-03-13 13:04:31 -03001037 /* Start next frame. */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001038 gspca_frame_add(gspca_dev, FIRST_PACKET,
Theodore Kilgore9832d762009-03-13 13:04:31 -03001039 pac_sof_marker, sizeof pac_sof_marker);
Kyle Guinnd661e622009-01-16 05:36:14 -03001040 len -= sof - data;
1041 data = sof;
1042 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03001043 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Kyle Guinnd661e622009-01-16 05:36:14 -03001044}
1045
1046/* sub-driver description */
1047static const struct sd_desc sd_desc = {
1048 .name = MODULE_NAME,
Kyle Guinnd661e622009-01-16 05:36:14 -03001049 .config = sd_config,
1050 .init = sd_init,
Hans Verkuil3e0ed002012-05-14 09:45:06 -03001051 .init_controls = sd_init_controls,
Kyle Guinnd661e622009-01-16 05:36:14 -03001052 .start = sd_start,
1053 .stopN = sd_stopN,
1054 .pkt_scan = sd_pkt_scan,
1055};
1056
1057/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03001058static const struct usb_device_id device_table[] = {
Aurelien Jacobs8ac246c2009-10-29 07:45:24 -03001059 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
Theodore Kilgore89f08632009-08-14 06:51:52 -03001060 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
1061 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
1062 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
Kyle Guinnd661e622009-01-16 05:36:14 -03001063 {}
1064};
1065MODULE_DEVICE_TABLE(usb, device_table);
1066
1067/* -- device connect -- */
1068static int sd_probe(struct usb_interface *intf,
1069 const struct usb_device_id *id)
1070{
1071 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1072 THIS_MODULE);
1073}
1074
1075static struct usb_driver sd_driver = {
1076 .name = MODULE_NAME,
1077 .id_table = device_table,
1078 .probe = sd_probe,
1079 .disconnect = gspca_disconnect,
1080#ifdef CONFIG_PM
1081 .suspend = gspca_suspend,
1082 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -03001083 .reset_resume = gspca_resume,
Kyle Guinnd661e622009-01-16 05:36:14 -03001084#endif
1085};
1086
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001087module_usb_driver(sd_driver);