Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sunplus.c
Go to the documentation of this file.
1 /*
2  * Sunplus spca504(abc) spca533 spca536 library
3  * Copyright (C) 2005 Michel Xhaard [email protected]
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 
24 #define MODULE_NAME "sunplus"
25 
26 #include "gspca.h"
27 #include "jpeg.h"
28 
29 MODULE_AUTHOR("Michel Xhaard <[email protected]>");
30 MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
31 MODULE_LICENSE("GPL");
32 
33 #define QUALITY 85
34 
35 /* specific webcam descriptor */
36 struct sd {
37  struct gspca_dev gspca_dev; /* !! must be the first item */
38 
39  bool autogain;
40 
41  u8 bridge;
42 #define BRIDGE_SPCA504 0
43 #define BRIDGE_SPCA504B 1
44 #define BRIDGE_SPCA504C 2
45 #define BRIDGE_SPCA533 3
46 #define BRIDGE_SPCA536 4
47  u8 subtype;
48 #define AiptekMiniPenCam13 1
49 #define LogitechClickSmart420 2
50 #define LogitechClickSmart820 3
51 #define MegapixV4 4
52 #define MegaImageVI 5
53 
55 };
56 
57 static const struct v4l2_pix_format vga_mode[] = {
59  .bytesperline = 320,
60  .sizeimage = 320 * 240 * 3 / 8 + 590,
61  .colorspace = V4L2_COLORSPACE_JPEG,
62  .priv = 2},
64  .bytesperline = 640,
65  .sizeimage = 640 * 480 * 3 / 8 + 590,
66  .colorspace = V4L2_COLORSPACE_JPEG,
67  .priv = 1},
68 };
69 
70 static const struct v4l2_pix_format custom_mode[] = {
72  .bytesperline = 320,
73  .sizeimage = 320 * 240 * 3 / 8 + 590,
74  .colorspace = V4L2_COLORSPACE_JPEG,
75  .priv = 2},
77  .bytesperline = 464,
78  .sizeimage = 464 * 480 * 3 / 8 + 590,
79  .colorspace = V4L2_COLORSPACE_JPEG,
80  .priv = 1},
81 };
82 
83 static const struct v4l2_pix_format vga_mode2[] = {
85  .bytesperline = 176,
86  .sizeimage = 176 * 144 * 3 / 8 + 590,
87  .colorspace = V4L2_COLORSPACE_JPEG,
88  .priv = 4},
90  .bytesperline = 320,
91  .sizeimage = 320 * 240 * 3 / 8 + 590,
92  .colorspace = V4L2_COLORSPACE_JPEG,
93  .priv = 3},
95  .bytesperline = 352,
96  .sizeimage = 352 * 288 * 3 / 8 + 590,
97  .colorspace = V4L2_COLORSPACE_JPEG,
98  .priv = 2},
100  .bytesperline = 640,
101  .sizeimage = 640 * 480 * 3 / 8 + 590,
102  .colorspace = V4L2_COLORSPACE_JPEG,
103  .priv = 1},
104 };
105 
106 #define SPCA50X_OFFSET_DATA 10
107 #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
108 #define SPCA504_PCCAM600_OFFSET_COMPRESS 4
109 #define SPCA504_PCCAM600_OFFSET_MODE 5
110 #define SPCA504_PCCAM600_OFFSET_DATA 14
111  /* Frame packet header offsets for the spca533 */
112 #define SPCA533_OFFSET_DATA 16
113 #define SPCA533_OFFSET_FRAMSEQ 15
114 /* Frame packet header offsets for the spca536 */
115 #define SPCA536_OFFSET_DATA 4
116 #define SPCA536_OFFSET_FRAMSEQ 1
117 
118 struct cmd {
122 };
123 
124 /* Initialisation data for the Creative PC-CAM 600 */
125 static const struct cmd spca504_pccam600_init_data[] = {
126 /* {0xa0, 0x0000, 0x0503}, * capture mode */
127  {0x00, 0x0000, 0x2000},
128  {0x00, 0x0013, 0x2301},
129  {0x00, 0x0003, 0x2000},
130  {0x00, 0x0001, 0x21ac},
131  {0x00, 0x0001, 0x21a6},
132  {0x00, 0x0000, 0x21a7}, /* brightness */
133  {0x00, 0x0020, 0x21a8}, /* contrast */
134  {0x00, 0x0001, 0x21ac}, /* sat/hue */
135  {0x00, 0x0000, 0x21ad}, /* hue */
136  {0x00, 0x001a, 0x21ae}, /* saturation */
137  {0x00, 0x0002, 0x21a3}, /* gamma */
138  {0x30, 0x0154, 0x0008},
139  {0x30, 0x0004, 0x0006},
140  {0x30, 0x0258, 0x0009},
141  {0x30, 0x0004, 0x0000},
142  {0x30, 0x0093, 0x0004},
143  {0x30, 0x0066, 0x0005},
144  {0x00, 0x0000, 0x2000},
145  {0x00, 0x0013, 0x2301},
146  {0x00, 0x0003, 0x2000},
147  {0x00, 0x0013, 0x2301},
148  {0x00, 0x0003, 0x2000},
149 };
150 
151 /* Creative PC-CAM 600 specific open data, sent before using the
152  * generic initialisation data from spca504_open_data.
153  */
154 static const struct cmd spca504_pccam600_open_data[] = {
155  {0x00, 0x0001, 0x2501},
156  {0x20, 0x0500, 0x0001}, /* snapshot mode */
157  {0x00, 0x0003, 0x2880},
158  {0x00, 0x0001, 0x2881},
159 };
160 
161 /* Initialisation data for the logitech clicksmart 420 */
162 static const struct cmd spca504A_clicksmart420_init_data[] = {
163 /* {0xa0, 0x0000, 0x0503}, * capture mode */
164  {0x00, 0x0000, 0x2000},
165  {0x00, 0x0013, 0x2301},
166  {0x00, 0x0003, 0x2000},
167  {0x00, 0x0001, 0x21ac},
168  {0x00, 0x0001, 0x21a6},
169  {0x00, 0x0000, 0x21a7}, /* brightness */
170  {0x00, 0x0020, 0x21a8}, /* contrast */
171  {0x00, 0x0001, 0x21ac}, /* sat/hue */
172  {0x00, 0x0000, 0x21ad}, /* hue */
173  {0x00, 0x001a, 0x21ae}, /* saturation */
174  {0x00, 0x0002, 0x21a3}, /* gamma */
175  {0x30, 0x0004, 0x000a},
176  {0xb0, 0x0001, 0x0000},
177 
178  {0xa1, 0x0080, 0x0001},
179  {0x30, 0x0049, 0x0000},
180  {0x30, 0x0060, 0x0005},
181  {0x0c, 0x0004, 0x0000},
182  {0x00, 0x0000, 0x0000},
183  {0x00, 0x0000, 0x2000},
184  {0x00, 0x0013, 0x2301},
185  {0x00, 0x0003, 0x2000},
186 };
187 
188 /* clicksmart 420 open data ? */
189 static const struct cmd spca504A_clicksmart420_open_data[] = {
190  {0x00, 0x0001, 0x2501},
191  {0x20, 0x0502, 0x0000},
192  {0x06, 0x0000, 0x0000},
193  {0x00, 0x0004, 0x2880},
194  {0x00, 0x0001, 0x2881},
195 
196  {0xa0, 0x0000, 0x0503},
197 };
198 
199 static const u8 qtable_creative_pccam[2][64] = {
200  { /* Q-table Y-components */
201  0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
202  0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
203  0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
204  0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
205  0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
206  0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
207  0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
208  0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
209  { /* Q-table C-components */
210  0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
211  0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
212  0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
213  0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
214  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
215  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
216  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
217  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
218 };
219 
220 /* FIXME: This Q-table is identical to the Creative PC-CAM one,
221  * except for one byte. Possibly a typo?
222  * NWG: 18/05/2003.
223  */
224 static const u8 qtable_spca504_default[2][64] = {
225  { /* Q-table Y-components */
226  0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
227  0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
228  0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
229  0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
230  0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
231  0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
232  0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
233  0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
234  },
235  { /* Q-table C-components */
236  0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
237  0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
238  0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
239  0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
240  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
241  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
242  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
243  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
244 };
245 
246 /* read <len> bytes to gspca_dev->usb_buf */
247 static void reg_r(struct gspca_dev *gspca_dev,
248  u8 req,
249  u16 index,
250  u16 len)
251 {
252  int ret;
253 
254 #ifdef GSPCA_DEBUG
255  if (len > USB_BUF_SZ) {
256  pr_err("reg_r: buffer overflow\n");
257  return;
258  }
259 #endif
260  if (gspca_dev->usb_err < 0)
261  return;
262  ret = usb_control_msg(gspca_dev->dev,
263  usb_rcvctrlpipe(gspca_dev->dev, 0),
264  req,
266  0, /* value */
267  index,
268  len ? gspca_dev->usb_buf : NULL, len,
269  500);
270  if (ret < 0) {
271  pr_err("reg_r err %d\n", ret);
272  gspca_dev->usb_err = ret;
273  }
274 }
275 
276 /* write one byte */
277 static void reg_w_1(struct gspca_dev *gspca_dev,
278  u8 req,
279  u16 value,
280  u16 index,
281  u16 byte)
282 {
283  int ret;
284 
285  if (gspca_dev->usb_err < 0)
286  return;
287  gspca_dev->usb_buf[0] = byte;
288  ret = usb_control_msg(gspca_dev->dev,
289  usb_sndctrlpipe(gspca_dev->dev, 0),
290  req,
292  value, index,
293  gspca_dev->usb_buf, 1,
294  500);
295  if (ret < 0) {
296  pr_err("reg_w_1 err %d\n", ret);
297  gspca_dev->usb_err = ret;
298  }
299 }
300 
301 /* write req / index / value */
302 static void reg_w_riv(struct gspca_dev *gspca_dev,
303  u8 req, u16 index, u16 value)
304 {
305  struct usb_device *dev = gspca_dev->dev;
306  int ret;
307 
308  if (gspca_dev->usb_err < 0)
309  return;
310  ret = usb_control_msg(dev,
311  usb_sndctrlpipe(dev, 0),
312  req,
314  value, index, NULL, 0, 500);
315  if (ret < 0) {
316  pr_err("reg_w_riv err %d\n", ret);
317  gspca_dev->usb_err = ret;
318  return;
319  }
320  PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
321  req, index, value);
322 }
323 
324 static void write_vector(struct gspca_dev *gspca_dev,
325  const struct cmd *data, int ncmds)
326 {
327  while (--ncmds >= 0) {
328  reg_w_riv(gspca_dev, data->req, data->idx, data->val);
329  data++;
330  }
331 }
332 
333 static void setup_qtable(struct gspca_dev *gspca_dev,
334  const u8 qtable[2][64])
335 {
336  int i;
337 
338  /* loop over y components */
339  for (i = 0; i < 64; i++)
340  reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
341 
342  /* loop over c components */
343  for (i = 0; i < 64; i++)
344  reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
345 }
346 
347 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
348  u8 req, u16 idx, u16 val)
349 {
350  reg_w_riv(gspca_dev, req, idx, val);
351  reg_r(gspca_dev, 0x01, 0x0001, 1);
352  PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
353  reg_w_riv(gspca_dev, req, idx, val);
354 
355  msleep(200);
356  reg_r(gspca_dev, 0x01, 0x0001, 1);
357  PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
358 }
359 
360 #ifdef GSPCA_DEBUG
361 static void spca504_read_info(struct gspca_dev *gspca_dev)
362 {
363  int i;
364  u8 info[6];
365 
366  for (i = 0; i < 6; i++) {
367  reg_r(gspca_dev, 0, i, 1);
368  info[i] = gspca_dev->usb_buf[0];
369  }
370  PDEBUG(D_STREAM,
371  "Read info: %d %d %d %d %d %d."
372  " Should be 1,0,2,2,0,0",
373  info[0], info[1], info[2],
374  info[3], info[4], info[5]);
375 }
376 #endif
377 
378 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
379  u8 req,
380  u16 idx, u16 val, u8 endcode, u8 count)
381 {
382  u16 status;
383 
384  reg_w_riv(gspca_dev, req, idx, val);
385  reg_r(gspca_dev, 0x01, 0x0001, 1);
386  if (gspca_dev->usb_err < 0)
387  return;
388  PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
389  gspca_dev->usb_buf[0], endcode);
390  if (!count)
391  return;
392  count = 200;
393  while (--count > 0) {
394  msleep(10);
395  /* gsmart mini2 write a each wait setting 1 ms is enough */
396 /* reg_w_riv(gspca_dev, req, idx, val); */
397  reg_r(gspca_dev, 0x01, 0x0001, 1);
398  status = gspca_dev->usb_buf[0];
399  if (status == endcode) {
400  PDEBUG(D_FRAM, "status 0x%04x after wait %d",
401  status, 200 - count);
402  break;
403  }
404  }
405 }
406 
407 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
408 {
409  int count = 10;
410 
411  while (--count > 0) {
412  reg_r(gspca_dev, 0x21, 0, 1);
413  if ((gspca_dev->usb_buf[0] & 0x01) == 0)
414  break;
415  msleep(10);
416  }
417 }
418 
419 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
420 {
421  int count = 50;
422 
423  while (--count > 0) {
424  reg_r(gspca_dev, 0x21, 1, 1);
425  if (gspca_dev->usb_buf[0] != 0) {
426  reg_w_1(gspca_dev, 0x21, 0, 1, 0);
427  reg_r(gspca_dev, 0x21, 1, 1);
428  spca504B_PollingDataReady(gspca_dev);
429  break;
430  }
431  msleep(10);
432  }
433 }
434 
435 #ifdef GSPCA_DEBUG
436 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
437 {
438  u8 *data;
439 
440  data = gspca_dev->usb_buf;
441  reg_r(gspca_dev, 0x20, 0, 5);
442  PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
443  data[0], data[1], data[2], data[3], data[4]);
444  reg_r(gspca_dev, 0x23, 0, 64);
445  reg_r(gspca_dev, 0x23, 1, 64);
446 }
447 #endif
448 
449 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
450 {
451  struct sd *sd = (struct sd *) gspca_dev;
452  u8 Size;
453 
454  Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
455  switch (sd->bridge) {
456  case BRIDGE_SPCA533:
457  reg_w_riv(gspca_dev, 0x31, 0, 0);
458  spca504B_WaitCmdStatus(gspca_dev);
459  spca504B_PollingDataReady(gspca_dev);
460 #ifdef GSPCA_DEBUG
461  spca50x_GetFirmware(gspca_dev);
462 #endif
463  reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
464  reg_r(gspca_dev, 0x24, 8, 1);
465 
466  reg_w_1(gspca_dev, 0x25, 0, 4, Size);
467  reg_r(gspca_dev, 0x25, 4, 1); /* size */
468  spca504B_PollingDataReady(gspca_dev);
469 
470  /* Init the cam width height with some values get on init ? */
471  reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
472  spca504B_WaitCmdStatus(gspca_dev);
473  spca504B_PollingDataReady(gspca_dev);
474  break;
475  default:
476 /* case BRIDGE_SPCA504B: */
477 /* case BRIDGE_SPCA536: */
478  reg_w_1(gspca_dev, 0x25, 0, 4, Size);
479  reg_r(gspca_dev, 0x25, 4, 1); /* size */
480  reg_w_1(gspca_dev, 0x27, 0, 0, 6);
481  reg_r(gspca_dev, 0x27, 0, 1); /* type */
482  spca504B_PollingDataReady(gspca_dev);
483  break;
484  case BRIDGE_SPCA504:
485  Size += 3;
486  if (sd->subtype == AiptekMiniPenCam13) {
487  /* spca504a aiptek */
488  spca504A_acknowledged_command(gspca_dev,
489  0x08, Size, 0,
490  0x80 | (Size & 0x0f), 1);
491  spca504A_acknowledged_command(gspca_dev,
492  1, 3, 0, 0x9f, 0);
493  } else {
494  spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
495  }
496  break;
497  case BRIDGE_SPCA504C:
498  /* capture mode */
499  reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
500  reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
501  break;
502  }
503 }
504 
505 static void spca504_wait_status(struct gspca_dev *gspca_dev)
506 {
507  int cnt;
508 
509  cnt = 256;
510  while (--cnt > 0) {
511  /* With this we get the status, when return 0 it's all ok */
512  reg_r(gspca_dev, 0x06, 0x00, 1);
513  if (gspca_dev->usb_buf[0] == 0)
514  return;
515  msleep(10);
516  }
517 }
518 
519 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
520 {
521  reg_w_1(gspca_dev, 0x26, 0, 0, 3);
522  reg_r(gspca_dev, 0x26, 0, 1);
523  spca504B_PollingDataReady(gspca_dev);
524 }
525 
526 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
527 {
528  struct sd *sd = (struct sd *) gspca_dev;
529  u16 reg;
530 
531  reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
532  reg_w_riv(gspca_dev, 0x00, reg, val);
533 }
534 
535 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
536 {
537  struct sd *sd = (struct sd *) gspca_dev;
538  u16 reg;
539 
540  reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
541  reg_w_riv(gspca_dev, 0x00, reg, val);
542 }
543 
544 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
545 {
546  struct sd *sd = (struct sd *) gspca_dev;
547  u16 reg;
548 
549  reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
550  reg_w_riv(gspca_dev, 0x00, reg, val);
551 }
552 
553 static void init_ctl_reg(struct gspca_dev *gspca_dev)
554 {
555  struct sd *sd = (struct sd *) gspca_dev;
556  int pollreg = 1;
557 
558  switch (sd->bridge) {
559  case BRIDGE_SPCA504:
560  case BRIDGE_SPCA504C:
561  pollreg = 0;
562  /* fall thru */
563  default:
564 /* case BRIDGE_SPCA533: */
565 /* case BRIDGE_SPCA504B: */
566  reg_w_riv(gspca_dev, 0, 0x21ad, 0x00); /* hue */
567  reg_w_riv(gspca_dev, 0, 0x21ac, 0x01); /* sat/hue */
568  reg_w_riv(gspca_dev, 0, 0x21a3, 0x00); /* gamma */
569  break;
570  case BRIDGE_SPCA536:
571  reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
572  reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
573  reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
574  break;
575  }
576  if (pollreg)
577  spca504B_PollingDataReady(gspca_dev);
578 }
579 
580 /* this function is called at probe time */
581 static int sd_config(struct gspca_dev *gspca_dev,
582  const struct usb_device_id *id)
583 {
584  struct sd *sd = (struct sd *) gspca_dev;
585  struct cam *cam;
586 
587  cam = &gspca_dev->cam;
588 
589  sd->bridge = id->driver_info >> 8;
590  sd->subtype = id->driver_info;
591 
592  if (sd->subtype == AiptekMiniPenCam13) {
593 
594  /* try to get the firmware as some cam answer 2.0.1.2.2
595  * and should be a spca504b then overwrite that setting */
596  reg_r(gspca_dev, 0x20, 0, 1);
597  switch (gspca_dev->usb_buf[0]) {
598  case 1:
599  break; /* (right bridge/subtype) */
600  case 2:
601  sd->bridge = BRIDGE_SPCA504B;
602  sd->subtype = 0;
603  break;
604  default:
605  return -ENODEV;
606  }
607  }
608 
609  switch (sd->bridge) {
610  default:
611 /* case BRIDGE_SPCA504B: */
612 /* case BRIDGE_SPCA504: */
613 /* case BRIDGE_SPCA536: */
614  cam->cam_mode = vga_mode;
615  cam->nmodes = ARRAY_SIZE(vga_mode);
616  break;
617  case BRIDGE_SPCA533:
618  cam->cam_mode = custom_mode;
619  if (sd->subtype == MegaImageVI) /* 320x240 only */
620  cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
621  else
622  cam->nmodes = ARRAY_SIZE(custom_mode);
623  break;
624  case BRIDGE_SPCA504C:
625  cam->cam_mode = vga_mode2;
626  cam->nmodes = ARRAY_SIZE(vga_mode2);
627  break;
628  }
629  return 0;
630 }
631 
632 /* this function is called at probe and resume time */
633 static int sd_init(struct gspca_dev *gspca_dev)
634 {
635  struct sd *sd = (struct sd *) gspca_dev;
636 
637  switch (sd->bridge) {
638  case BRIDGE_SPCA504B:
639  reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
640  reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
641  reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
642  reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
643  reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
644  reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
645  /* fall thru */
646  case BRIDGE_SPCA533:
647  spca504B_PollingDataReady(gspca_dev);
648 #ifdef GSPCA_DEBUG
649  spca50x_GetFirmware(gspca_dev);
650 #endif
651  break;
652  case BRIDGE_SPCA536:
653 #ifdef GSPCA_DEBUG
654  spca50x_GetFirmware(gspca_dev);
655 #endif
656  reg_r(gspca_dev, 0x00, 0x5002, 1);
657  reg_w_1(gspca_dev, 0x24, 0, 0, 0);
658  reg_r(gspca_dev, 0x24, 0, 1);
659  spca504B_PollingDataReady(gspca_dev);
660  reg_w_riv(gspca_dev, 0x34, 0, 0);
661  spca504B_WaitCmdStatus(gspca_dev);
662  break;
663  case BRIDGE_SPCA504C: /* pccam600 */
664  PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
665  reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
666  reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */
667  spca504_wait_status(gspca_dev);
668  if (sd->subtype == LogitechClickSmart420)
669  write_vector(gspca_dev,
670  spca504A_clicksmart420_open_data,
671  ARRAY_SIZE(spca504A_clicksmart420_open_data));
672  else
673  write_vector(gspca_dev, spca504_pccam600_open_data,
674  ARRAY_SIZE(spca504_pccam600_open_data));
675  setup_qtable(gspca_dev, qtable_creative_pccam);
676  break;
677  default:
678 /* case BRIDGE_SPCA504: */
679  PDEBUG(D_STREAM, "Opening SPCA504");
680  if (sd->subtype == AiptekMiniPenCam13) {
681 #ifdef GSPCA_DEBUG
682  spca504_read_info(gspca_dev);
683 #endif
684 
685  /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
686  spca504A_acknowledged_command(gspca_dev, 0x24,
687  8, 3, 0x9e, 1);
688  /* Twice sequential need status 0xff->0x9e->0x9d */
689  spca504A_acknowledged_command(gspca_dev, 0x24,
690  8, 3, 0x9e, 0);
691 
692  spca504A_acknowledged_command(gspca_dev, 0x24,
693  0, 0, 0x9d, 1);
694  /******************************/
695  /* spca504a aiptek */
696  spca504A_acknowledged_command(gspca_dev, 0x08,
697  6, 0, 0x86, 1);
698 /* reg_write (dev, 0, 0x2000, 0); */
699 /* reg_write (dev, 0, 0x2883, 1); */
700 /* spca504A_acknowledged_command (gspca_dev, 0x08,
701  6, 0, 0x86, 1); */
702 /* spca504A_acknowledged_command (gspca_dev, 0x24,
703  0, 0, 0x9D, 1); */
704  reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
705  /* L92 sno1t.txt */
706  reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
707  spca504A_acknowledged_command(gspca_dev, 0x01,
708  0x0f, 0, 0xff, 0);
709  }
710  /* setup qtable */
711  reg_w_riv(gspca_dev, 0, 0x2000, 0);
712  reg_w_riv(gspca_dev, 0, 0x2883, 1);
713  setup_qtable(gspca_dev, qtable_spca504_default);
714  break;
715  }
716  return gspca_dev->usb_err;
717 }
718 
719 static int sd_start(struct gspca_dev *gspca_dev)
720 {
721  struct sd *sd = (struct sd *) gspca_dev;
722  int enable;
723 
724  /* create the JPEG header */
725  jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
726  0x22); /* JPEG 411 */
727  jpeg_set_qual(sd->jpeg_hdr, QUALITY);
728 
729  if (sd->bridge == BRIDGE_SPCA504B)
730  spca504B_setQtable(gspca_dev);
731  spca504B_SetSizeType(gspca_dev);
732  switch (sd->bridge) {
733  default:
734 /* case BRIDGE_SPCA504B: */
735 /* case BRIDGE_SPCA533: */
736 /* case BRIDGE_SPCA536: */
737  switch (sd->subtype) {
738  case MegapixV4:
740  case MegaImageVI:
741  reg_w_riv(gspca_dev, 0xf0, 0, 0);
742  spca504B_WaitCmdStatus(gspca_dev);
743  reg_r(gspca_dev, 0xf0, 4, 0);
744  spca504B_WaitCmdStatus(gspca_dev);
745  break;
746  default:
747  reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
748  spca504B_WaitCmdStatus(gspca_dev);
749  spca504B_PollingDataReady(gspca_dev);
750  break;
751  }
752  break;
753  case BRIDGE_SPCA504:
754  if (sd->subtype == AiptekMiniPenCam13) {
755 #ifdef GSPCA_DEBUG
756  spca504_read_info(gspca_dev);
757 #endif
758 
759  /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
760  spca504A_acknowledged_command(gspca_dev, 0x24,
761  8, 3, 0x9e, 1);
762  /* Twice sequential need status 0xff->0x9e->0x9d */
763  spca504A_acknowledged_command(gspca_dev, 0x24,
764  8, 3, 0x9e, 0);
765  spca504A_acknowledged_command(gspca_dev, 0x24,
766  0, 0, 0x9d, 1);
767  } else {
768  spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
769 #ifdef GSPCA_DEBUG
770  spca504_read_info(gspca_dev);
771 #endif
772  spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
773  spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
774  }
775  spca504B_SetSizeType(gspca_dev);
776  reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
777  /* L92 sno1t.txt */
778  reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
779  break;
780  case BRIDGE_SPCA504C:
781  if (sd->subtype == LogitechClickSmart420) {
782  write_vector(gspca_dev,
783  spca504A_clicksmart420_init_data,
784  ARRAY_SIZE(spca504A_clicksmart420_init_data));
785  } else {
786  write_vector(gspca_dev, spca504_pccam600_init_data,
787  ARRAY_SIZE(spca504_pccam600_init_data));
788  }
789  enable = (sd->autogain ? 0x04 : 0x01);
790  reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
791  /* auto exposure */
792  reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
793  /* auto whiteness */
794 
795  /* set default exposure compensation and whiteness balance */
796  reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */
797  reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
798  spca504B_SetSizeType(gspca_dev);
799  break;
800  }
801  init_ctl_reg(gspca_dev);
802  return gspca_dev->usb_err;
803 }
804 
805 static void sd_stopN(struct gspca_dev *gspca_dev)
806 {
807  struct sd *sd = (struct sd *) gspca_dev;
808 
809  switch (sd->bridge) {
810  default:
811 /* case BRIDGE_SPCA533: */
812 /* case BRIDGE_SPCA536: */
813 /* case BRIDGE_SPCA504B: */
814  reg_w_riv(gspca_dev, 0x31, 0, 0);
815  spca504B_WaitCmdStatus(gspca_dev);
816  spca504B_PollingDataReady(gspca_dev);
817  break;
818  case BRIDGE_SPCA504:
819  case BRIDGE_SPCA504C:
820  reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
821 
822  if (sd->subtype == AiptekMiniPenCam13) {
823  /* spca504a aiptek */
824 /* spca504A_acknowledged_command(gspca_dev, 0x08,
825  6, 0, 0x86, 1); */
826  spca504A_acknowledged_command(gspca_dev, 0x24,
827  0x00, 0x00, 0x9d, 1);
828  spca504A_acknowledged_command(gspca_dev, 0x01,
829  0x0f, 0x00, 0xff, 1);
830  } else {
831  spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
832  reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
833  }
834  break;
835  }
836 }
837 
838 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
839  u8 *data, /* isoc packet */
840  int len) /* iso packet length */
841 {
842  struct sd *sd = (struct sd *) gspca_dev;
843  int i, sof = 0;
844  static u8 ffd9[] = {0xff, 0xd9};
845 
846 /* frames are jpeg 4.1.1 without 0xff escape */
847  switch (sd->bridge) {
848  case BRIDGE_SPCA533:
849  if (data[0] == 0xff) {
850  if (data[1] != 0x01) { /* drop packet */
851 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
852  return;
853  }
854  sof = 1;
855  data += SPCA533_OFFSET_DATA;
856  len -= SPCA533_OFFSET_DATA;
857  } else {
858  data += 1;
859  len -= 1;
860  }
861  break;
862  case BRIDGE_SPCA536:
863  if (data[0] == 0xff) {
864  sof = 1;
865  data += SPCA536_OFFSET_DATA;
866  len -= SPCA536_OFFSET_DATA;
867  } else {
868  data += 2;
869  len -= 2;
870  }
871  break;
872  default:
873 /* case BRIDGE_SPCA504: */
874 /* case BRIDGE_SPCA504B: */
875  switch (data[0]) {
876  case 0xfe: /* start of frame */
877  sof = 1;
878  data += SPCA50X_OFFSET_DATA;
879  len -= SPCA50X_OFFSET_DATA;
880  break;
881  case 0xff: /* drop packet */
882 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
883  return;
884  default:
885  data += 1;
886  len -= 1;
887  break;
888  }
889  break;
890  case BRIDGE_SPCA504C:
891  switch (data[0]) {
892  case 0xfe: /* start of frame */
893  sof = 1;
896  break;
897  case 0xff: /* drop packet */
898 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
899  return;
900  default:
901  data += 1;
902  len -= 1;
903  break;
904  }
905  break;
906  }
907  if (sof) { /* start of frame */
908  gspca_frame_add(gspca_dev, LAST_PACKET,
909  ffd9, 2);
910 
911  /* put the JPEG header in the new frame */
912  gspca_frame_add(gspca_dev, FIRST_PACKET,
913  sd->jpeg_hdr, JPEG_HDR_SZ);
914  }
915 
916  /* add 0x00 after 0xff */
917  i = 0;
918  do {
919  if (data[i] == 0xff) {
920  gspca_frame_add(gspca_dev, INTER_PACKET,
921  data, i + 1);
922  len -= i;
923  data += i;
924  *data = 0x00;
925  i = 0;
926  }
927  i++;
928  } while (i < len);
929  gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
930 }
931 
932 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
933 {
934  struct gspca_dev *gspca_dev =
935  container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
936  struct sd *sd = (struct sd *)gspca_dev;
937 
938  gspca_dev->usb_err = 0;
939 
940  if (!gspca_dev->streaming)
941  return 0;
942 
943  switch (ctrl->id) {
944  case V4L2_CID_BRIGHTNESS:
945  setbrightness(gspca_dev, ctrl->val);
946  break;
947  case V4L2_CID_CONTRAST:
948  setcontrast(gspca_dev, ctrl->val);
949  break;
950  case V4L2_CID_SATURATION:
951  setcolors(gspca_dev, ctrl->val);
952  break;
953  case V4L2_CID_AUTOGAIN:
954  sd->autogain = ctrl->val;
955  break;
956  }
957  return gspca_dev->usb_err;
958 }
959 
960 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
961  .s_ctrl = sd_s_ctrl,
962 };
963 
964 static int sd_init_controls(struct gspca_dev *gspca_dev)
965 {
966  struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
967 
968  gspca_dev->vdev.ctrl_handler = hdl;
969  v4l2_ctrl_handler_init(hdl, 4);
970  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
971  V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
972  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
973  V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
974  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
975  V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
976  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
977  V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
978 
979  if (hdl->error) {
980  pr_err("Could not initialize controls\n");
981  return hdl->error;
982  }
983  return 0;
984 }
985 
986 /* sub-driver description */
987 static const struct sd_desc sd_desc = {
988  .name = MODULE_NAME,
989  .config = sd_config,
990  .init = sd_init,
991  .init_controls = sd_init_controls,
992  .start = sd_start,
993  .stopN = sd_stopN,
994  .pkt_scan = sd_pkt_scan,
995 };
996 
997 /* -- module initialisation -- */
998 #define BS(bridge, subtype) \
999  .driver_info = (BRIDGE_ ## bridge << 8) \
1000  | (subtype)
1001 static const struct usb_device_id device_table[] = {
1002  {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
1003  {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
1004  {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
1005  {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
1006  {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
1007  {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
1008  {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
1009  {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
1010  {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1011  {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1012  {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1013  {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1014  {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1015  {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1016  {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1017  {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1018  {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1019  {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1020  {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1021  {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1022  {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1023  {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1024  {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1025  {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1026  {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1027  {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1028  {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1029  {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1030  {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1031  {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1032  {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1033  {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1034  {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1035  {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1036  {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1037  {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1038  {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1039  {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1040  {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1041  {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1042  {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1043  {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1044  {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1045  {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1046  {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1047  {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1048  {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1049  {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1050  {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1051  {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1052  {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1053  {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1054  {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1055  {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1056  {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1057  {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1058  {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1059  {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1060  {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1061  {}
1062 };
1063 MODULE_DEVICE_TABLE(usb, device_table);
1064 
1065 /* -- device connect -- */
1066 static int sd_probe(struct usb_interface *intf,
1067  const struct usb_device_id *id)
1068 {
1069  return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1070  THIS_MODULE);
1071 }
1072 
1073 static struct usb_driver sd_driver = {
1074  .name = MODULE_NAME,
1075  .id_table = device_table,
1076  .probe = sd_probe,
1077  .disconnect = gspca_disconnect,
1078 #ifdef CONFIG_PM
1079  .suspend = gspca_suspend,
1080  .resume = gspca_resume,
1081  .reset_resume = gspca_resume,
1082 #endif
1083 };
1084 
1085 module_usb_driver(sd_driver);