Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/drivers/media/usb/gspca/sunplus.c

  1 /*
  2  *              Sunplus spca504(abc) spca533 spca536 library
  3  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
  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 <mxhaard@users.sourceforge.net>");
 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 
 54         u8 jpeg_hdr[JPEG_HDR_SZ];
 55 };
 56 
 57 static const struct v4l2_pix_format vga_mode[] = {
 58         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 59                 .bytesperline = 320,
 60                 .sizeimage = 320 * 240 * 3 / 8 + 590,
 61                 .colorspace = V4L2_COLORSPACE_JPEG,
 62                 .priv = 2},
 63         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 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[] = {
 71         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 72                 .bytesperline = 320,
 73                 .sizeimage = 320 * 240 * 3 / 8 + 590,
 74                 .colorspace = V4L2_COLORSPACE_JPEG,
 75                 .priv = 2},
 76         {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 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[] = {
 84         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 85                 .bytesperline = 176,
 86                 .sizeimage = 176 * 144 * 3 / 8 + 590,
 87                 .colorspace = V4L2_COLORSPACE_JPEG,
 88                 .priv = 4},
 89         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 90                 .bytesperline = 320,
 91                 .sizeimage = 320 * 240 * 3 / 8 + 590,
 92                 .colorspace = V4L2_COLORSPACE_JPEG,
 93                 .priv = 3},
 94         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 95                 .bytesperline = 352,
 96                 .sizeimage = 352 * 288 * 3 / 8 + 590,
 97                 .colorspace = V4L2_COLORSPACE_JPEG,
 98                 .priv = 2},
 99         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
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 {
119         u8 req;
120         u16 val;
121         u16 idx;
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         if (len > USB_BUF_SZ) {
255                 PERR("reg_r: buffer overflow\n");
256                 return;
257         }
258         if (gspca_dev->usb_err < 0)
259                 return;
260         ret = usb_control_msg(gspca_dev->dev,
261                         usb_rcvctrlpipe(gspca_dev->dev, 0),
262                         req,
263                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
264                         0,              /* value */
265                         index,
266                         len ? gspca_dev->usb_buf : NULL, len,
267                         500);
268         if (ret < 0) {
269                 pr_err("reg_r err %d\n", ret);
270                 gspca_dev->usb_err = ret;
271         }
272 }
273 
274 /* write one byte */
275 static void reg_w_1(struct gspca_dev *gspca_dev,
276                    u8 req,
277                    u16 value,
278                    u16 index,
279                    u16 byte)
280 {
281         int ret;
282 
283         if (gspca_dev->usb_err < 0)
284                 return;
285         gspca_dev->usb_buf[0] = byte;
286         ret = usb_control_msg(gspca_dev->dev,
287                         usb_sndctrlpipe(gspca_dev->dev, 0),
288                         req,
289                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
290                         value, index,
291                         gspca_dev->usb_buf, 1,
292                         500);
293         if (ret < 0) {
294                 pr_err("reg_w_1 err %d\n", ret);
295                 gspca_dev->usb_err = ret;
296         }
297 }
298 
299 /* write req / index / value */
300 static void reg_w_riv(struct gspca_dev *gspca_dev,
301                      u8 req, u16 index, u16 value)
302 {
303         struct usb_device *dev = gspca_dev->dev;
304         int ret;
305 
306         if (gspca_dev->usb_err < 0)
307                 return;
308         ret = usb_control_msg(dev,
309                         usb_sndctrlpipe(dev, 0),
310                         req,
311                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
312                         value, index, NULL, 0, 500);
313         if (ret < 0) {
314                 pr_err("reg_w_riv err %d\n", ret);
315                 gspca_dev->usb_err = ret;
316                 return;
317         }
318         PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
319                 req, index, value);
320 }
321 
322 static void write_vector(struct gspca_dev *gspca_dev,
323                         const struct cmd *data, int ncmds)
324 {
325         while (--ncmds >= 0) {
326                 reg_w_riv(gspca_dev, data->req, data->idx, data->val);
327                 data++;
328         }
329 }
330 
331 static void setup_qtable(struct gspca_dev *gspca_dev,
332                         const u8 qtable[2][64])
333 {
334         int i;
335 
336         /* loop over y components */
337         for (i = 0; i < 64; i++)
338                 reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
339 
340         /* loop over c components */
341         for (i = 0; i < 64; i++)
342                 reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
343 }
344 
345 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
346                              u8 req, u16 idx, u16 val)
347 {
348         reg_w_riv(gspca_dev, req, idx, val);
349         reg_r(gspca_dev, 0x01, 0x0001, 1);
350         PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
351         reg_w_riv(gspca_dev, req, idx, val);
352 
353         msleep(200);
354         reg_r(gspca_dev, 0x01, 0x0001, 1);
355         PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
356 }
357 
358 static void spca504_read_info(struct gspca_dev *gspca_dev)
359 {
360         int i;
361         u8 info[6];
362 
363         if (gspca_debug < D_STREAM)
364                 return;
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. Should be 1,0,2,2,0,0",
372                 info[0], info[1], info[2],
373                 info[3], info[4], info[5]);
374 }
375 
376 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
377                         u8 req,
378                         u16 idx, u16 val, u8 endcode, u8 count)
379 {
380         u16 status;
381 
382         reg_w_riv(gspca_dev, req, idx, val);
383         reg_r(gspca_dev, 0x01, 0x0001, 1);
384         if (gspca_dev->usb_err < 0)
385                 return;
386         PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
387                         gspca_dev->usb_buf[0], endcode);
388         if (!count)
389                 return;
390         count = 200;
391         while (--count > 0) {
392                 msleep(10);
393                 /* gsmart mini2 write a each wait setting 1 ms is enough */
394 /*              reg_w_riv(gspca_dev, req, idx, val); */
395                 reg_r(gspca_dev, 0x01, 0x0001, 1);
396                 status = gspca_dev->usb_buf[0];
397                 if (status == endcode) {
398                         PDEBUG(D_FRAM, "status 0x%04x after wait %d",
399                                 status, 200 - count);
400                                 break;
401                 }
402         }
403 }
404 
405 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
406 {
407         int count = 10;
408 
409         while (--count > 0) {
410                 reg_r(gspca_dev, 0x21, 0, 1);
411                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
412                         break;
413                 msleep(10);
414         }
415 }
416 
417 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
418 {
419         int count = 50;
420 
421         while (--count > 0) {
422                 reg_r(gspca_dev, 0x21, 1, 1);
423                 if (gspca_dev->usb_buf[0] != 0) {
424                         reg_w_1(gspca_dev, 0x21, 0, 1, 0);
425                         reg_r(gspca_dev, 0x21, 1, 1);
426                         spca504B_PollingDataReady(gspca_dev);
427                         break;
428                 }
429                 msleep(10);
430         }
431 }
432 
433 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
434 {
435         u8 *data;
436 
437         if (gspca_debug < D_STREAM)
438                 return;
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 
448 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
449 {
450         struct sd *sd = (struct sd *) gspca_dev;
451         u8 Size;
452 
453         Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
454         switch (sd->bridge) {
455         case BRIDGE_SPCA533:
456                 reg_w_riv(gspca_dev, 0x31, 0, 0);
457                 spca504B_WaitCmdStatus(gspca_dev);
458                 spca504B_PollingDataReady(gspca_dev);
459                 spca50x_GetFirmware(gspca_dev);
460 
461                 reg_w_1(gspca_dev, 0x24, 0, 8, 2);              /* type */
462                 reg_r(gspca_dev, 0x24, 8, 1);
463 
464                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
465                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
466                 spca504B_PollingDataReady(gspca_dev);
467 
468                 /* Init the cam width height with some values get on init ? */
469                 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
470                 spca504B_WaitCmdStatus(gspca_dev);
471                 spca504B_PollingDataReady(gspca_dev);
472                 break;
473         default:
474 /* case BRIDGE_SPCA504B: */
475 /* case BRIDGE_SPCA536: */
476                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
477                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
478                 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
479                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
480                 spca504B_PollingDataReady(gspca_dev);
481                 break;
482         case BRIDGE_SPCA504:
483                 Size += 3;
484                 if (sd->subtype == AiptekMiniPenCam13) {
485                         /* spca504a aiptek */
486                         spca504A_acknowledged_command(gspca_dev,
487                                                 0x08, Size, 0,
488                                                 0x80 | (Size & 0x0f), 1);
489                         spca504A_acknowledged_command(gspca_dev,
490                                                         1, 3, 0, 0x9f, 0);
491                 } else {
492                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
493                 }
494                 break;
495         case BRIDGE_SPCA504C:
496                 /* capture mode */
497                 reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
498                 reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
499                 break;
500         }
501 }
502 
503 static void spca504_wait_status(struct gspca_dev *gspca_dev)
504 {
505         int cnt;
506 
507         cnt = 256;
508         while (--cnt > 0) {
509                 /* With this we get the status, when return 0 it's all ok */
510                 reg_r(gspca_dev, 0x06, 0x00, 1);
511                 if (gspca_dev->usb_buf[0] == 0)
512                         return;
513                 msleep(10);
514         }
515 }
516 
517 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
518 {
519         reg_w_1(gspca_dev, 0x26, 0, 0, 3);
520         reg_r(gspca_dev, 0x26, 0, 1);
521         spca504B_PollingDataReady(gspca_dev);
522 }
523 
524 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
525 {
526         struct sd *sd = (struct sd *) gspca_dev;
527         u16 reg;
528 
529         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
530         reg_w_riv(gspca_dev, 0x00, reg, val);
531 }
532 
533 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
534 {
535         struct sd *sd = (struct sd *) gspca_dev;
536         u16 reg;
537 
538         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
539         reg_w_riv(gspca_dev, 0x00, reg, val);
540 }
541 
542 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
543 {
544         struct sd *sd = (struct sd *) gspca_dev;
545         u16 reg;
546 
547         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
548         reg_w_riv(gspca_dev, 0x00, reg, val);
549 }
550 
551 static void init_ctl_reg(struct gspca_dev *gspca_dev)
552 {
553         struct sd *sd = (struct sd *) gspca_dev;
554         int pollreg = 1;
555 
556         switch (sd->bridge) {
557         case BRIDGE_SPCA504:
558         case BRIDGE_SPCA504C:
559                 pollreg = 0;
560                 /* fall thru */
561         default:
562 /*      case BRIDGE_SPCA533: */
563 /*      case BRIDGE_SPCA504B: */
564                 reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);  /* hue */
565                 reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);  /* sat/hue */
566                 reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);  /* gamma */
567                 break;
568         case BRIDGE_SPCA536:
569                 reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
570                 reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
571                 reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
572                 break;
573         }
574         if (pollreg)
575                 spca504B_PollingDataReady(gspca_dev);
576 }
577 
578 /* this function is called at probe time */
579 static int sd_config(struct gspca_dev *gspca_dev,
580                         const struct usb_device_id *id)
581 {
582         struct sd *sd = (struct sd *) gspca_dev;
583         struct cam *cam;
584 
585         cam = &gspca_dev->cam;
586 
587         sd->bridge = id->driver_info >> 8;
588         sd->subtype = id->driver_info;
589 
590         if (sd->subtype == AiptekMiniPenCam13) {
591 
592                 /* try to get the firmware as some cam answer 2.0.1.2.2
593                  * and should be a spca504b then overwrite that setting */
594                 reg_r(gspca_dev, 0x20, 0, 1);
595                 switch (gspca_dev->usb_buf[0]) {
596                 case 1:
597                         break;          /* (right bridge/subtype) */
598                 case 2:
599                         sd->bridge = BRIDGE_SPCA504B;
600                         sd->subtype = 0;
601                         break;
602                 default:
603                         return -ENODEV;
604                 }
605         }
606 
607         switch (sd->bridge) {
608         default:
609 /*      case BRIDGE_SPCA504B: */
610 /*      case BRIDGE_SPCA504: */
611 /*      case BRIDGE_SPCA536: */
612                 cam->cam_mode = vga_mode;
613                 cam->nmodes = ARRAY_SIZE(vga_mode);
614                 break;
615         case BRIDGE_SPCA533:
616                 cam->cam_mode = custom_mode;
617                 if (sd->subtype == MegaImageVI)         /* 320x240 only */
618                         cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
619                 else
620                         cam->nmodes = ARRAY_SIZE(custom_mode);
621                 break;
622         case BRIDGE_SPCA504C:
623                 cam->cam_mode = vga_mode2;
624                 cam->nmodes = ARRAY_SIZE(vga_mode2);
625                 break;
626         }
627         return 0;
628 }
629 
630 /* this function is called at probe and resume time */
631 static int sd_init(struct gspca_dev *gspca_dev)
632 {
633         struct sd *sd = (struct sd *) gspca_dev;
634 
635         switch (sd->bridge) {
636         case BRIDGE_SPCA504B:
637                 reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
638                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
639                 reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
640                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
641                 reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
642                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
643                 /* fall thru */
644         case BRIDGE_SPCA533:
645                 spca504B_PollingDataReady(gspca_dev);
646                 spca50x_GetFirmware(gspca_dev);
647                 break;
648         case BRIDGE_SPCA536:
649                 spca50x_GetFirmware(gspca_dev);
650                 reg_r(gspca_dev, 0x00, 0x5002, 1);
651                 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
652                 reg_r(gspca_dev, 0x24, 0, 1);
653                 spca504B_PollingDataReady(gspca_dev);
654                 reg_w_riv(gspca_dev, 0x34, 0, 0);
655                 spca504B_WaitCmdStatus(gspca_dev);
656                 break;
657         case BRIDGE_SPCA504C:   /* pccam600 */
658                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
659                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
660                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);     /* reset */
661                 spca504_wait_status(gspca_dev);
662                 if (sd->subtype == LogitechClickSmart420)
663                         write_vector(gspca_dev,
664                                 spca504A_clicksmart420_open_data,
665                                 ARRAY_SIZE(spca504A_clicksmart420_open_data));
666                 else
667                         write_vector(gspca_dev, spca504_pccam600_open_data,
668                                 ARRAY_SIZE(spca504_pccam600_open_data));
669                 setup_qtable(gspca_dev, qtable_creative_pccam);
670                 break;
671         default:
672 /*      case BRIDGE_SPCA504: */
673                 PDEBUG(D_STREAM, "Opening SPCA504");
674                 if (sd->subtype == AiptekMiniPenCam13) {
675                         spca504_read_info(gspca_dev);
676 
677                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
678                         spca504A_acknowledged_command(gspca_dev, 0x24,
679                                                         8, 3, 0x9e, 1);
680                         /* Twice sequential need status 0xff->0x9e->0x9d */
681                         spca504A_acknowledged_command(gspca_dev, 0x24,
682                                                         8, 3, 0x9e, 0);
683 
684                         spca504A_acknowledged_command(gspca_dev, 0x24,
685                                                         0, 0, 0x9d, 1);
686                         /******************************/
687                         /* spca504a aiptek */
688                         spca504A_acknowledged_command(gspca_dev, 0x08,
689                                                         6, 0, 0x86, 1);
690 /*                      reg_write (dev, 0, 0x2000, 0); */
691 /*                      reg_write (dev, 0, 0x2883, 1); */
692 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
693                                                         6, 0, 0x86, 1); */
694 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
695                                                         0, 0, 0x9D, 1); */
696                         reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
697                                                         /* L92 sno1t.txt */
698                         reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
699                         spca504A_acknowledged_command(gspca_dev, 0x01,
700                                                         0x0f, 0, 0xff, 0);
701                 }
702                 /* setup qtable */
703                 reg_w_riv(gspca_dev, 0, 0x2000, 0);
704                 reg_w_riv(gspca_dev, 0, 0x2883, 1);
705                 setup_qtable(gspca_dev, qtable_spca504_default);
706                 break;
707         }
708         return gspca_dev->usb_err;
709 }
710 
711 static int sd_start(struct gspca_dev *gspca_dev)
712 {
713         struct sd *sd = (struct sd *) gspca_dev;
714         int enable;
715 
716         /* create the JPEG header */
717         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
718                         gspca_dev->pixfmt.width,
719                         0x22);          /* JPEG 411 */
720         jpeg_set_qual(sd->jpeg_hdr, QUALITY);
721 
722         if (sd->bridge == BRIDGE_SPCA504B)
723                 spca504B_setQtable(gspca_dev);
724         spca504B_SetSizeType(gspca_dev);
725         switch (sd->bridge) {
726         default:
727 /*      case BRIDGE_SPCA504B: */
728 /*      case BRIDGE_SPCA533: */
729 /*      case BRIDGE_SPCA536: */
730                 switch (sd->subtype) {
731                 case MegapixV4:
732                 case LogitechClickSmart820:
733                 case MegaImageVI:
734                         reg_w_riv(gspca_dev, 0xf0, 0, 0);
735                         spca504B_WaitCmdStatus(gspca_dev);
736                         reg_r(gspca_dev, 0xf0, 4, 0);
737                         spca504B_WaitCmdStatus(gspca_dev);
738                         break;
739                 default:
740                         reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
741                         spca504B_WaitCmdStatus(gspca_dev);
742                         spca504B_PollingDataReady(gspca_dev);
743                         break;
744                 }
745                 break;
746         case BRIDGE_SPCA504:
747                 if (sd->subtype == AiptekMiniPenCam13) {
748                         spca504_read_info(gspca_dev);
749 
750                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
751                         spca504A_acknowledged_command(gspca_dev, 0x24,
752                                                         8, 3, 0x9e, 1);
753                         /* Twice sequential need status 0xff->0x9e->0x9d */
754                         spca504A_acknowledged_command(gspca_dev, 0x24,
755                                                         8, 3, 0x9e, 0);
756                         spca504A_acknowledged_command(gspca_dev, 0x24,
757                                                         0, 0, 0x9d, 1);
758                 } else {
759                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
760                         spca504_read_info(gspca_dev);
761                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
762                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
763                 }
764                 spca504B_SetSizeType(gspca_dev);
765                 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
766                                                         /* L92 sno1t.txt */
767                 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
768                 break;
769         case BRIDGE_SPCA504C:
770                 if (sd->subtype == LogitechClickSmart420) {
771                         write_vector(gspca_dev,
772                                 spca504A_clicksmart420_init_data,
773                                 ARRAY_SIZE(spca504A_clicksmart420_init_data));
774                 } else {
775                         write_vector(gspca_dev, spca504_pccam600_init_data,
776                                 ARRAY_SIZE(spca504_pccam600_init_data));
777                 }
778                 enable = (sd->autogain ? 0x04 : 0x01);
779                 reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
780                                                         /* auto exposure */
781                 reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
782                                                         /* auto whiteness */
783 
784                 /* set default exposure compensation and whiteness balance */
785                 reg_w_riv(gspca_dev, 0x30, 0x0001, 800);        /* ~ 20 fps */
786                 reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
787                 spca504B_SetSizeType(gspca_dev);
788                 break;
789         }
790         init_ctl_reg(gspca_dev);
791         return gspca_dev->usb_err;
792 }
793 
794 static void sd_stopN(struct gspca_dev *gspca_dev)
795 {
796         struct sd *sd = (struct sd *) gspca_dev;
797 
798         switch (sd->bridge) {
799         default:
800 /*      case BRIDGE_SPCA533: */
801 /*      case BRIDGE_SPCA536: */
802 /*      case BRIDGE_SPCA504B: */
803                 reg_w_riv(gspca_dev, 0x31, 0, 0);
804                 spca504B_WaitCmdStatus(gspca_dev);
805                 spca504B_PollingDataReady(gspca_dev);
806                 break;
807         case BRIDGE_SPCA504:
808         case BRIDGE_SPCA504C:
809                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
810 
811                 if (sd->subtype == AiptekMiniPenCam13) {
812                         /* spca504a aiptek */
813 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
814                                                          6, 0, 0x86, 1); */
815                         spca504A_acknowledged_command(gspca_dev, 0x24,
816                                                         0x00, 0x00, 0x9d, 1);
817                         spca504A_acknowledged_command(gspca_dev, 0x01,
818                                                         0x0f, 0x00, 0xff, 1);
819                 } else {
820                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
821                         reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
822                 }
823                 break;
824         }
825 }
826 
827 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
828                         u8 *data,                       /* isoc packet */
829                         int len)                        /* iso packet length */
830 {
831         struct sd *sd = (struct sd *) gspca_dev;
832         int i, sof = 0;
833         static u8 ffd9[] = {0xff, 0xd9};
834 
835 /* frames are jpeg 4.1.1 without 0xff escape */
836         switch (sd->bridge) {
837         case BRIDGE_SPCA533:
838                 if (data[0] == 0xff) {
839                         if (data[1] != 0x01) {  /* drop packet */
840 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
841                                 return;
842                         }
843                         sof = 1;
844                         data += SPCA533_OFFSET_DATA;
845                         len -= SPCA533_OFFSET_DATA;
846                 } else {
847                         data += 1;
848                         len -= 1;
849                 }
850                 break;
851         case BRIDGE_SPCA536:
852                 if (data[0] == 0xff) {
853                         sof = 1;
854                         data += SPCA536_OFFSET_DATA;
855                         len -= SPCA536_OFFSET_DATA;
856                 } else {
857                         data += 2;
858                         len -= 2;
859                 }
860                 break;
861         default:
862 /*      case BRIDGE_SPCA504: */
863 /*      case BRIDGE_SPCA504B: */
864                 switch (data[0]) {
865                 case 0xfe:                      /* start of frame */
866                         sof = 1;
867                         data += SPCA50X_OFFSET_DATA;
868                         len -= SPCA50X_OFFSET_DATA;
869                         break;
870                 case 0xff:                      /* drop packet */
871 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
872                         return;
873                 default:
874                         data += 1;
875                         len -= 1;
876                         break;
877                 }
878                 break;
879         case BRIDGE_SPCA504C:
880                 switch (data[0]) {
881                 case 0xfe:                      /* start of frame */
882                         sof = 1;
883                         data += SPCA504_PCCAM600_OFFSET_DATA;
884                         len -= SPCA504_PCCAM600_OFFSET_DATA;
885                         break;
886                 case 0xff:                      /* drop packet */
887 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
888                         return;
889                 default:
890                         data += 1;
891                         len -= 1;
892                         break;
893                 }
894                 break;
895         }
896         if (sof) {              /* start of frame */
897                 gspca_frame_add(gspca_dev, LAST_PACKET,
898                                 ffd9, 2);
899 
900                 /* put the JPEG header in the new frame */
901                 gspca_frame_add(gspca_dev, FIRST_PACKET,
902                         sd->jpeg_hdr, JPEG_HDR_SZ);
903         }
904 
905         /* add 0x00 after 0xff */
906         i = 0;
907         do {
908                 if (data[i] == 0xff) {
909                         gspca_frame_add(gspca_dev, INTER_PACKET,
910                                         data, i + 1);
911                         len -= i;
912                         data += i;
913                         *data = 0x00;
914                         i = 0;
915                 }
916                 i++;
917         } while (i < len);
918         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
919 }
920 
921 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
922 {
923         struct gspca_dev *gspca_dev =
924                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
925         struct sd *sd = (struct sd *)gspca_dev;
926 
927         gspca_dev->usb_err = 0;
928 
929         if (!gspca_dev->streaming)
930                 return 0;
931 
932         switch (ctrl->id) {
933         case V4L2_CID_BRIGHTNESS:
934                 setbrightness(gspca_dev, ctrl->val);
935                 break;
936         case V4L2_CID_CONTRAST:
937                 setcontrast(gspca_dev, ctrl->val);
938                 break;
939         case V4L2_CID_SATURATION:
940                 setcolors(gspca_dev, ctrl->val);
941                 break;
942         case V4L2_CID_AUTOGAIN:
943                 sd->autogain = ctrl->val;
944                 break;
945         }
946         return gspca_dev->usb_err;
947 }
948 
949 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
950         .s_ctrl = sd_s_ctrl,
951 };
952 
953 static int sd_init_controls(struct gspca_dev *gspca_dev)
954 {
955         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
956 
957         gspca_dev->vdev.ctrl_handler = hdl;
958         v4l2_ctrl_handler_init(hdl, 4);
959         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
960                         V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
961         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
962                         V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
963         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
964                         V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
965         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
966                         V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
967 
968         if (hdl->error) {
969                 pr_err("Could not initialize controls\n");
970                 return hdl->error;
971         }
972         return 0;
973 }
974 
975 /* sub-driver description */
976 static const struct sd_desc sd_desc = {
977         .name = MODULE_NAME,
978         .config = sd_config,
979         .init = sd_init,
980         .init_controls = sd_init_controls,
981         .start = sd_start,
982         .stopN = sd_stopN,
983         .pkt_scan = sd_pkt_scan,
984 };
985 
986 /* -- module initialisation -- */
987 #define BS(bridge, subtype) \
988         .driver_info = (BRIDGE_ ## bridge << 8) \
989                         | (subtype)
990 static const struct usb_device_id device_table[] = {
991         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
992         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
993         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
994         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
995         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
996         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
997         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
998         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
999         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1000         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1001         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1002         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1003         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1004         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1005         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1006         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1007         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1008         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1009         {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1010         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1011         {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1012         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1013         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1014         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1015         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1016         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1017         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1018         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1019         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1020         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1021         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1022         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1023         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1024         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1025         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1026         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1027         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1028         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1029         {USB_DEVICE(0x06d6, 0x0041), BS(SPCA504B, 0)},
1030         {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1031         {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1032         {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1033         {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1034         {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1035         {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1036         {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1037         {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1038         {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1039         {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1040         {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1041         {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1042         {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1043         {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1044         {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1045         {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1046         {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1047         {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1048         {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1049         {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1050         {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1051         {}
1052 };
1053 MODULE_DEVICE_TABLE(usb, device_table);
1054 
1055 /* -- device connect -- */
1056 static int sd_probe(struct usb_interface *intf,
1057                         const struct usb_device_id *id)
1058 {
1059         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1060                                 THIS_MODULE);
1061 }
1062 
1063 static struct usb_driver sd_driver = {
1064         .name = MODULE_NAME,
1065         .id_table = device_table,
1066         .probe = sd_probe,
1067         .disconnect = gspca_disconnect,
1068 #ifdef CONFIG_PM
1069         .suspend = gspca_suspend,
1070         .resume = gspca_resume,
1071         .reset_resume = gspca_resume,
1072 #endif
1073 };
1074 
1075 module_usb_driver(sd_driver);
1076 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us