root/drivers/media/usb/gspca/conex.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reg_r
  2. reg_w_val
  3. reg_w
  4. cx11646_fw
  5. cx_sensor
  6. cx11646_initsize
  7. cx11646_jpegInit
  8. cx11646_jpeg
  9. cx11646_init1
  10. sd_config
  11. sd_init
  12. sd_start
  13. sd_stop0
  14. sd_pkt_scan
  15. setbrightness
  16. setcontrast
  17. sd_s_ctrl
  18. sd_init_controls
  19. sd_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *              Connexant Cx11646 library
   4  *              Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
   5  *
   6  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   7  */
   8 
   9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10 
  11 #define MODULE_NAME "conex"
  12 
  13 #include "gspca.h"
  14 #define CONEX_CAM 1             /* special JPEG header */
  15 #include "jpeg.h"
  16 
  17 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  18 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
  19 MODULE_LICENSE("GPL");
  20 
  21 #define QUALITY 50
  22 
  23 /* specific webcam descriptor */
  24 struct sd {
  25         struct gspca_dev gspca_dev;     /* !! must be the first item */
  26         struct v4l2_ctrl *brightness;
  27         struct v4l2_ctrl *contrast;
  28         struct v4l2_ctrl *sat;
  29 
  30         u8 jpeg_hdr[JPEG_HDR_SZ];
  31 };
  32 
  33 static const struct v4l2_pix_format vga_mode[] = {
  34         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  35                 .bytesperline = 176,
  36                 .sizeimage = 176 * 144 * 3 / 8 + 590,
  37                 .colorspace = V4L2_COLORSPACE_JPEG,
  38                 .priv = 3},
  39         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  40                 .bytesperline = 320,
  41                 .sizeimage = 320 * 240 * 3 / 8 + 590,
  42                 .colorspace = V4L2_COLORSPACE_JPEG,
  43                 .priv = 2},
  44         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  45                 .bytesperline = 352,
  46                 .sizeimage = 352 * 288 * 3 / 8 + 590,
  47                 .colorspace = V4L2_COLORSPACE_JPEG,
  48                 .priv = 1},
  49         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  50                 .bytesperline = 640,
  51                 .sizeimage = 640 * 480 * 3 / 8 + 590,
  52                 .colorspace = V4L2_COLORSPACE_JPEG,
  53                 .priv = 0},
  54 };
  55 
  56 /* the read bytes are found in gspca_dev->usb_buf */
  57 static void reg_r(struct gspca_dev *gspca_dev,
  58                   __u16 index,
  59                   __u16 len)
  60 {
  61         struct usb_device *dev = gspca_dev->dev;
  62 
  63         if (len > USB_BUF_SZ) {
  64                 gspca_err(gspca_dev, "reg_r: buffer overflow\n");
  65                 return;
  66         }
  67 
  68         usb_control_msg(dev,
  69                         usb_rcvctrlpipe(dev, 0),
  70                         0,
  71                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  72                         0,
  73                         index, gspca_dev->usb_buf, len,
  74                         500);
  75         gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
  76                   index, gspca_dev->usb_buf[0]);
  77 }
  78 
  79 /* the bytes to write are in gspca_dev->usb_buf */
  80 static void reg_w_val(struct gspca_dev *gspca_dev,
  81                         __u16 index,
  82                         __u8 val)
  83 {
  84         struct usb_device *dev = gspca_dev->dev;
  85 
  86         gspca_dev->usb_buf[0] = val;
  87         usb_control_msg(dev,
  88                         usb_sndctrlpipe(dev, 0),
  89                         0,
  90                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  91                         0,
  92                         index, gspca_dev->usb_buf, 1, 500);
  93 }
  94 
  95 static void reg_w(struct gspca_dev *gspca_dev,
  96                   __u16 index,
  97                   const __u8 *buffer,
  98                   __u16 len)
  99 {
 100         struct usb_device *dev = gspca_dev->dev;
 101 
 102         if (len > USB_BUF_SZ) {
 103                 gspca_err(gspca_dev, "reg_w: buffer overflow\n");
 104                 return;
 105         }
 106         gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
 107                   index, *buffer);
 108 
 109         memcpy(gspca_dev->usb_buf, buffer, len);
 110         usb_control_msg(dev,
 111                         usb_sndctrlpipe(dev, 0),
 112                         0,
 113                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 114                         0,
 115                         index, gspca_dev->usb_buf, len, 500);
 116 }
 117 
 118 static const __u8 cx_sensor_init[][4] = {
 119         {0x88, 0x11, 0x01, 0x01},
 120         {0x88, 0x12, 0x70, 0x01},
 121         {0x88, 0x0f, 0x00, 0x01},
 122         {0x88, 0x05, 0x01, 0x01},
 123         {}
 124 };
 125 
 126 static const __u8 cx11646_fw1[][3] = {
 127         {0x00, 0x02, 0x00},
 128         {0x01, 0x43, 0x00},
 129         {0x02, 0xA7, 0x00},
 130         {0x03, 0x8B, 0x01},
 131         {0x04, 0xE9, 0x02},
 132         {0x05, 0x08, 0x04},
 133         {0x06, 0x08, 0x05},
 134         {0x07, 0x07, 0x06},
 135         {0x08, 0xE7, 0x06},
 136         {0x09, 0xC6, 0x07},
 137         {0x0A, 0x86, 0x08},
 138         {0x0B, 0x46, 0x09},
 139         {0x0C, 0x05, 0x0A},
 140         {0x0D, 0xA5, 0x0A},
 141         {0x0E, 0x45, 0x0B},
 142         {0x0F, 0xE5, 0x0B},
 143         {0x10, 0x85, 0x0C},
 144         {0x11, 0x25, 0x0D},
 145         {0x12, 0xC4, 0x0D},
 146         {0x13, 0x45, 0x0E},
 147         {0x14, 0xE4, 0x0E},
 148         {0x15, 0x64, 0x0F},
 149         {0x16, 0xE4, 0x0F},
 150         {0x17, 0x64, 0x10},
 151         {0x18, 0xE4, 0x10},
 152         {0x19, 0x64, 0x11},
 153         {0x1A, 0xE4, 0x11},
 154         {0x1B, 0x64, 0x12},
 155         {0x1C, 0xE3, 0x12},
 156         {0x1D, 0x44, 0x13},
 157         {0x1E, 0xC3, 0x13},
 158         {0x1F, 0x24, 0x14},
 159         {0x20, 0xA3, 0x14},
 160         {0x21, 0x04, 0x15},
 161         {0x22, 0x83, 0x15},
 162         {0x23, 0xE3, 0x15},
 163         {0x24, 0x43, 0x16},
 164         {0x25, 0xA4, 0x16},
 165         {0x26, 0x23, 0x17},
 166         {0x27, 0x83, 0x17},
 167         {0x28, 0xE3, 0x17},
 168         {0x29, 0x43, 0x18},
 169         {0x2A, 0xA3, 0x18},
 170         {0x2B, 0x03, 0x19},
 171         {0x2C, 0x63, 0x19},
 172         {0x2D, 0xC3, 0x19},
 173         {0x2E, 0x22, 0x1A},
 174         {0x2F, 0x63, 0x1A},
 175         {0x30, 0xC3, 0x1A},
 176         {0x31, 0x23, 0x1B},
 177         {0x32, 0x83, 0x1B},
 178         {0x33, 0xE2, 0x1B},
 179         {0x34, 0x23, 0x1C},
 180         {0x35, 0x83, 0x1C},
 181         {0x36, 0xE2, 0x1C},
 182         {0x37, 0x23, 0x1D},
 183         {0x38, 0x83, 0x1D},
 184         {0x39, 0xE2, 0x1D},
 185         {0x3A, 0x23, 0x1E},
 186         {0x3B, 0x82, 0x1E},
 187         {0x3C, 0xC3, 0x1E},
 188         {0x3D, 0x22, 0x1F},
 189         {0x3E, 0x63, 0x1F},
 190         {0x3F, 0xC1, 0x1F},
 191         {}
 192 };
 193 static void cx11646_fw(struct gspca_dev*gspca_dev)
 194 {
 195         int i = 0;
 196 
 197         reg_w_val(gspca_dev, 0x006a, 0x02);
 198         while (cx11646_fw1[i][1]) {
 199                 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
 200                 i++;
 201         }
 202         reg_w_val(gspca_dev, 0x006a, 0x00);
 203 }
 204 
 205 static const __u8 cxsensor[] = {
 206         0x88, 0x12, 0x70, 0x01,
 207         0x88, 0x0d, 0x02, 0x01,
 208         0x88, 0x0f, 0x00, 0x01,
 209         0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
 210         0x88, 0x02, 0x10, 0x01,
 211         0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
 212         0x88, 0x0B, 0x00, 0x01,
 213         0x88, 0x0A, 0x0A, 0x01,
 214         0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
 215         0x88, 0x05, 0x01, 0x01,
 216         0xA1, 0x18, 0x00, 0x01,
 217         0x00
 218 };
 219 
 220 static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
 221 static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
 222 static const __u8 reg10[] = { 0xb1, 0xb1 };
 223 static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e };        /* 640 */
 224 static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
 225         /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
 226 static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
 227                                         /* 320{0x04,0x0c,0x05,0x0f}; //320 */
 228 static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 };        /* 176 */
 229 static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
 230 
 231 static void cx_sensor(struct gspca_dev*gspca_dev)
 232 {
 233         int i = 0;
 234         int length;
 235         const __u8 *ptsensor = cxsensor;
 236 
 237         reg_w(gspca_dev, 0x0020, reg20, 8);
 238         reg_w(gspca_dev, 0x0028, reg28, 8);
 239         reg_w(gspca_dev, 0x0010, reg10, 2);
 240         reg_w_val(gspca_dev, 0x0092, 0x03);
 241 
 242         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 243         case 0:
 244                 reg_w(gspca_dev, 0x0071, reg71a, 4);
 245                 break;
 246         case 1:
 247                 reg_w(gspca_dev, 0x0071, reg71b, 4);
 248                 break;
 249         default:
 250 /*      case 2: */
 251                 reg_w(gspca_dev, 0x0071, reg71c, 4);
 252                 break;
 253         case 3:
 254                 reg_w(gspca_dev, 0x0071, reg71d, 4);
 255                 break;
 256         }
 257         reg_w(gspca_dev, 0x007b, reg7b, 6);
 258         reg_w_val(gspca_dev, 0x00f8, 0x00);
 259         reg_w(gspca_dev, 0x0010, reg10, 2);
 260         reg_w_val(gspca_dev, 0x0098, 0x41);
 261         for (i = 0; i < 11; i++) {
 262                 if (i == 3 || i == 5 || i == 8)
 263                         length = 8;
 264                 else
 265                         length = 4;
 266                 reg_w(gspca_dev, 0x00e5, ptsensor, length);
 267                 if (length == 4)
 268                         reg_r(gspca_dev, 0x00e8, 1);
 269                 else
 270                         reg_r(gspca_dev, 0x00e8, length);
 271                 ptsensor += length;
 272         }
 273         reg_r(gspca_dev, 0x00e7, 8);
 274 }
 275 
 276 static const __u8 cx_inits_176[] = {
 277         0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
 278         0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
 279         0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
 280         0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
 281         0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
 282         0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
 283         0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 284 };
 285 static const __u8 cx_inits_320[] = {
 286         0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
 287         0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
 288         0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
 289         0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
 290         0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
 291         0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
 292         0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 293 };
 294 static const __u8 cx_inits_352[] = {
 295         0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
 296         0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
 297         0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
 298         0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
 299         0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
 300         0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
 301         0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 302 };
 303 static const __u8 cx_inits_640[] = {
 304         0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
 305         0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
 306         0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
 307         0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
 308         0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
 309         0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
 310         0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 311 };
 312 
 313 static void cx11646_initsize(struct gspca_dev *gspca_dev)
 314 {
 315         const __u8 *cxinit;
 316         static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
 317         static const __u8 reg17[] =
 318                         { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
 319 
 320         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 321         case 0:
 322                 cxinit = cx_inits_640;
 323                 break;
 324         case 1:
 325                 cxinit = cx_inits_352;
 326                 break;
 327         default:
 328 /*      case 2: */
 329                 cxinit = cx_inits_320;
 330                 break;
 331         case 3:
 332                 cxinit = cx_inits_176;
 333                 break;
 334         }
 335         reg_w_val(gspca_dev, 0x009a, 0x01);
 336         reg_w_val(gspca_dev, 0x0010, 0x10);
 337         reg_w(gspca_dev, 0x0012, reg12, 5);
 338         reg_w(gspca_dev, 0x0017, reg17, 8);
 339         reg_w_val(gspca_dev, 0x00c0, 0x00);
 340         reg_w_val(gspca_dev, 0x00c1, 0x04);
 341         reg_w_val(gspca_dev, 0x00c2, 0x04);
 342 
 343         reg_w(gspca_dev, 0x0061, cxinit, 8);
 344         cxinit += 8;
 345         reg_w(gspca_dev, 0x00ca, cxinit, 8);
 346         cxinit += 8;
 347         reg_w(gspca_dev, 0x00d2, cxinit, 8);
 348         cxinit += 8;
 349         reg_w(gspca_dev, 0x00da, cxinit, 6);
 350         cxinit += 8;
 351         reg_w(gspca_dev, 0x0041, cxinit, 8);
 352         cxinit += 8;
 353         reg_w(gspca_dev, 0x0049, cxinit, 8);
 354         cxinit += 8;
 355         reg_w(gspca_dev, 0x0051, cxinit, 2);
 356 
 357         reg_r(gspca_dev, 0x0010, 1);
 358 }
 359 
 360 static const __u8 cx_jpeg_init[][8] = {
 361         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15},       /* 1 */
 362         {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
 363         {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
 364         {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
 365         {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
 366         {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
 367         {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
 368         {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
 369         {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
 370         {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
 371         {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
 372         {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
 373         {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
 374         {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
 375         {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
 376         {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
 377         {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
 378         {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
 379         {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
 380         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
 381         {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
 382         {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
 383         {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
 384         {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
 385         {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
 386         {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
 387         {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
 388         {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
 389         {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
 390         {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
 391         {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
 392         {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
 393         {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
 394         {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
 395         {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
 396         {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
 397         {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
 398         {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
 399         {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
 400         {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
 401         {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
 402         {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
 403         {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
 404         {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
 405         {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
 406         {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
 407         {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
 408         {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
 409         {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
 410         {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
 411         {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
 412         {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
 413         {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
 414         {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
 415         {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
 416         {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
 417         {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
 418         {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
 419         {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
 420         {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
 421         {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
 422         {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
 423         {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
 424         {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
 425         {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
 426         {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
 427         {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
 428         {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
 429         {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
 430         {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
 431         {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
 432         {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
 433         {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
 434         {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
 435         {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
 436         {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
 437         {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
 438         {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
 439         {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00}        /* 79 */
 440 };
 441 
 442 
 443 static const __u8 cxjpeg_640[][8] = {
 444         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10},       /* 1 */
 445         {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
 446         {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
 447         {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
 448         {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
 449         {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
 450         {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
 451         {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
 452         {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
 453         {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
 454         {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
 455         {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
 456         {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
 457         {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
 458         {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
 459         {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
 460         {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
 461         {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
 462         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
 463         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
 464         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
 465         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
 466         {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
 467         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
 468         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
 469         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
 470         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}        /* 27 */
 471 };
 472 static const __u8 cxjpeg_352[][8] = {
 473         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
 474         {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
 475         {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
 476         {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
 477         {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
 478         {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
 479         {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
 480         {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
 481         {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
 482         {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
 483         {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
 484         {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
 485         {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
 486         {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
 487         {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
 488         {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
 489         {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
 490         {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
 491         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
 492         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
 493         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
 494         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
 495         {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
 496         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
 497         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
 498         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
 499         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 500 };
 501 static const __u8 cxjpeg_320[][8] = {
 502         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
 503         {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
 504         {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
 505         {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
 506         {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
 507         {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
 508         {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
 509         {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
 510         {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
 511         {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
 512         {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
 513         {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
 514         {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
 515         {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
 516         {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
 517         {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
 518         {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
 519         {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
 520         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
 521         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
 522         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
 523         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
 524         {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
 525         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
 526         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
 527         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
 528         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}        /* 27 */
 529 };
 530 static const __u8 cxjpeg_176[][8] = {
 531         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
 532         {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
 533         {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
 534         {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
 535         {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
 536         {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
 537         {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
 538         {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
 539         {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
 540         {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
 541         {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
 542         {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
 543         {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
 544         {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
 545         {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
 546         {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
 547         {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
 548         {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
 549         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
 550         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
 551         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
 552         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
 553         {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
 554         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
 555         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
 556         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
 557         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 558 };
 559 /* 640 take with the zcx30x part */
 560 static const __u8 cxjpeg_qtable[][8] = {
 561         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
 562         {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
 563         {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
 564         {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
 565         {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
 566         {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
 567         {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
 568         {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
 569         {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
 570         {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
 571         {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
 572         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
 573         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
 574         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
 575         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
 576         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
 577         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
 578         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}        /* 18 */
 579 };
 580 
 581 
 582 static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
 583 {
 584         int i;
 585         int length;
 586 
 587         reg_w_val(gspca_dev, 0x00c0, 0x01);
 588         reg_w_val(gspca_dev, 0x00c3, 0x00);
 589         reg_w_val(gspca_dev, 0x00c0, 0x00);
 590         reg_r(gspca_dev, 0x0001, 1);
 591         length = 8;
 592         for (i = 0; i < 79; i++) {
 593                 if (i == 78)
 594                         length = 6;
 595                 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
 596         }
 597         reg_r(gspca_dev, 0x0002, 1);
 598         reg_w_val(gspca_dev, 0x0055, 0x14);
 599 }
 600 
 601 static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
 602 static const __u8 regE5_8[] =
 603                 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
 604 static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
 605 static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
 606 static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
 607 static const __u8 reg51[] = { 0x77, 0x03 };
 608 #define reg70 0x03
 609 
 610 static void cx11646_jpeg(struct gspca_dev*gspca_dev)
 611 {
 612         int i;
 613         int length;
 614         __u8 Reg55;
 615         int retry;
 616 
 617         reg_w_val(gspca_dev, 0x00c0, 0x01);
 618         reg_w_val(gspca_dev, 0x00c3, 0x00);
 619         reg_w_val(gspca_dev, 0x00c0, 0x00);
 620         reg_r(gspca_dev, 0x0001, 1);
 621         length = 8;
 622         switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
 623         case 0:
 624                 for (i = 0; i < 27; i++) {
 625                         if (i == 26)
 626                                 length = 2;
 627                         reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
 628                 }
 629                 Reg55 = 0x28;
 630                 break;
 631         case 1:
 632                 for (i = 0; i < 27; i++) {
 633                         if (i == 26)
 634                                 length = 2;
 635                         reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
 636                 }
 637                 Reg55 = 0x16;
 638                 break;
 639         default:
 640 /*      case 2: */
 641                 for (i = 0; i < 27; i++) {
 642                         if (i == 26)
 643                                 length = 2;
 644                         reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
 645                 }
 646                 Reg55 = 0x14;
 647                 break;
 648         case 3:
 649                 for (i = 0; i < 27; i++) {
 650                         if (i == 26)
 651                                 length = 2;
 652                         reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
 653                 }
 654                 Reg55 = 0x0B;
 655                 break;
 656         }
 657 
 658         reg_r(gspca_dev, 0x0002, 1);
 659         reg_w_val(gspca_dev, 0x0055, Reg55);
 660         reg_r(gspca_dev, 0x0002, 1);
 661         reg_w(gspca_dev, 0x0010, reg10, 2);
 662         reg_w_val(gspca_dev, 0x0054, 0x02);
 663         reg_w_val(gspca_dev, 0x0054, 0x01);
 664         reg_w_val(gspca_dev, 0x0000, 0x94);
 665         reg_w_val(gspca_dev, 0x0053, 0xc0);
 666         reg_w_val(gspca_dev, 0x00fc, 0xe1);
 667         reg_w_val(gspca_dev, 0x0000, 0x00);
 668         /* wait for completion */
 669         retry = 50;
 670         do {
 671                 reg_r(gspca_dev, 0x0002, 1);
 672                                                         /* 0x07 until 0x00 */
 673                 if (gspca_dev->usb_buf[0] == 0x00)
 674                         break;
 675                 reg_w_val(gspca_dev, 0x0053, 0x00);
 676         } while (--retry);
 677         if (retry == 0)
 678                 gspca_err(gspca_dev, "Damned Errors sending jpeg Table\n");
 679         /* send the qtable now */
 680         reg_r(gspca_dev, 0x0001, 1);            /* -> 0x18 */
 681         length = 8;
 682         for (i = 0; i < 18; i++) {
 683                 if (i == 17)
 684                         length = 2;
 685                 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
 686 
 687         }
 688         reg_r(gspca_dev, 0x0002, 1);    /* 0x00 */
 689         reg_r(gspca_dev, 0x0053, 1);    /* 0x00 */
 690         reg_w_val(gspca_dev, 0x0054, 0x02);
 691         reg_w_val(gspca_dev, 0x0054, 0x01);
 692         reg_w_val(gspca_dev, 0x0000, 0x94);
 693         reg_w_val(gspca_dev, 0x0053, 0xc0);
 694 
 695         reg_r(gspca_dev, 0x0038, 1);            /* 0x40 */
 696         reg_r(gspca_dev, 0x0038, 1);            /* 0x40 */
 697         reg_r(gspca_dev, 0x001f, 1);            /* 0x38 */
 698         reg_w(gspca_dev, 0x0012, reg12, 5);
 699         reg_w(gspca_dev, 0x00e5, regE5_8, 8);
 700         reg_r(gspca_dev, 0x00e8, 8);
 701         reg_w(gspca_dev, 0x00e5, regE5a, 4);
 702         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
 703         reg_w_val(gspca_dev, 0x009a, 0x01);
 704         reg_w(gspca_dev, 0x00e5, regE5b, 4);
 705         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
 706         reg_w(gspca_dev, 0x00e5, regE5c, 4);
 707         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
 708 
 709         reg_w(gspca_dev, 0x0051, reg51, 2);
 710         reg_w(gspca_dev, 0x0010, reg10, 2);
 711         reg_w_val(gspca_dev, 0x0070, reg70);
 712 }
 713 
 714 static void cx11646_init1(struct gspca_dev *gspca_dev)
 715 {
 716         int i = 0;
 717 
 718         reg_w_val(gspca_dev, 0x0010, 0x00);
 719         reg_w_val(gspca_dev, 0x0053, 0x00);
 720         reg_w_val(gspca_dev, 0x0052, 0x00);
 721         reg_w_val(gspca_dev, 0x009b, 0x2f);
 722         reg_w_val(gspca_dev, 0x009c, 0x10);
 723         reg_r(gspca_dev, 0x0098, 1);
 724         reg_w_val(gspca_dev, 0x0098, 0x40);
 725         reg_r(gspca_dev, 0x0099, 1);
 726         reg_w_val(gspca_dev, 0x0099, 0x07);
 727         reg_w_val(gspca_dev, 0x0039, 0x40);
 728         reg_w_val(gspca_dev, 0x003c, 0xff);
 729         reg_w_val(gspca_dev, 0x003f, 0x1f);
 730         reg_w_val(gspca_dev, 0x003d, 0x40);
 731 /*      reg_w_val(gspca_dev, 0x003d, 0x60); */
 732         reg_r(gspca_dev, 0x0099, 1);                    /* ->0x07 */
 733 
 734         while (cx_sensor_init[i][0]) {
 735                 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
 736                 reg_r(gspca_dev, 0x00e8, 1);            /* -> 0x00 */
 737                 if (i == 1) {
 738                         reg_w_val(gspca_dev, 0x00ed, 0x01);
 739                         reg_r(gspca_dev, 0x00ed, 1);    /* -> 0x01 */
 740                 }
 741                 i++;
 742         }
 743         reg_w_val(gspca_dev, 0x00c3, 0x00);
 744 }
 745 
 746 /* this function is called at probe time */
 747 static int sd_config(struct gspca_dev *gspca_dev,
 748                         const struct usb_device_id *id)
 749 {
 750         struct cam *cam;
 751 
 752         cam = &gspca_dev->cam;
 753         cam->cam_mode = vga_mode;
 754         cam->nmodes = ARRAY_SIZE(vga_mode);
 755         return 0;
 756 }
 757 
 758 /* this function is called at probe and resume time */
 759 static int sd_init(struct gspca_dev *gspca_dev)
 760 {
 761         cx11646_init1(gspca_dev);
 762         cx11646_initsize(gspca_dev);
 763         cx11646_fw(gspca_dev);
 764         cx_sensor(gspca_dev);
 765         cx11646_jpegInit(gspca_dev);
 766         return 0;
 767 }
 768 
 769 static int sd_start(struct gspca_dev *gspca_dev)
 770 {
 771         struct sd *sd = (struct sd *) gspca_dev;
 772 
 773         /* create the JPEG header */
 774         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
 775                         gspca_dev->pixfmt.width,
 776                         0x22);          /* JPEG 411 */
 777         jpeg_set_qual(sd->jpeg_hdr, QUALITY);
 778 
 779         cx11646_initsize(gspca_dev);
 780         cx11646_fw(gspca_dev);
 781         cx_sensor(gspca_dev);
 782         cx11646_jpeg(gspca_dev);
 783         return 0;
 784 }
 785 
 786 /* called on streamoff with alt 0 and on disconnect */
 787 static void sd_stop0(struct gspca_dev *gspca_dev)
 788 {
 789         int retry = 50;
 790 
 791         if (!gspca_dev->present)
 792                 return;
 793         reg_w_val(gspca_dev, 0x0000, 0x00);
 794         reg_r(gspca_dev, 0x0002, 1);
 795         reg_w_val(gspca_dev, 0x0053, 0x00);
 796 
 797         while (retry--) {
 798 /*              reg_r(gspca_dev, 0x0002, 1);*/
 799                 reg_r(gspca_dev, 0x0053, 1);
 800                 if (gspca_dev->usb_buf[0] == 0)
 801                         break;
 802         }
 803         reg_w_val(gspca_dev, 0x0000, 0x00);
 804         reg_r(gspca_dev, 0x0002, 1);
 805 
 806         reg_w_val(gspca_dev, 0x0010, 0x00);
 807         reg_r(gspca_dev, 0x0033, 1);
 808         reg_w_val(gspca_dev, 0x00fc, 0xe0);
 809 }
 810 
 811 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 812                         u8 *data,                       /* isoc packet */
 813                         int len)                        /* iso packet length */
 814 {
 815         struct sd *sd = (struct sd *) gspca_dev;
 816 
 817         if (data[0] == 0xff && data[1] == 0xd8) {
 818 
 819                 /* start of frame */
 820                 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 821 
 822                 /* put the JPEG header in the new frame */
 823                 gspca_frame_add(gspca_dev, FIRST_PACKET,
 824                                 sd->jpeg_hdr, JPEG_HDR_SZ);
 825                 data += 2;
 826                 len -= 2;
 827         }
 828         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 829 }
 830 
 831 static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
 832 {
 833         __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
 834         __u8 reg51c[2];
 835 
 836         regE5cbx[2] = val;
 837         reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
 838         reg_r(gspca_dev, 0x00e8, 8);
 839         reg_w(gspca_dev, 0x00e5, regE5c, 4);
 840         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
 841 
 842         reg51c[0] = 0x77;
 843         reg51c[1] = sat;
 844         reg_w(gspca_dev, 0x0051, reg51c, 2);
 845         reg_w(gspca_dev, 0x0010, reg10, 2);
 846         reg_w_val(gspca_dev, 0x0070, reg70);
 847 }
 848 
 849 static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
 850 {
 851         __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 };   /* seem MSB */
 852 /*      __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01};     * LSB */
 853         __u8 reg51c[2];
 854 
 855         regE5acx[2] = val;
 856         reg_w(gspca_dev, 0x00e5, regE5acx, 4);
 857         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
 858         reg51c[0] = 0x77;
 859         reg51c[1] = sat;
 860         reg_w(gspca_dev, 0x0051, reg51c, 2);
 861         reg_w(gspca_dev, 0x0010, reg10, 2);
 862         reg_w_val(gspca_dev, 0x0070, reg70);
 863 }
 864 
 865 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 866 {
 867         struct gspca_dev *gspca_dev =
 868                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 869         struct sd *sd = (struct sd *)gspca_dev;
 870 
 871         gspca_dev->usb_err = 0;
 872 
 873         if (!gspca_dev->streaming)
 874                 return 0;
 875 
 876         switch (ctrl->id) {
 877         case V4L2_CID_BRIGHTNESS:
 878                 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
 879                 break;
 880         case V4L2_CID_CONTRAST:
 881                 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
 882                 break;
 883         case V4L2_CID_SATURATION:
 884                 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
 885                 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
 886                 break;
 887         }
 888         return gspca_dev->usb_err;
 889 }
 890 
 891 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 892         .s_ctrl = sd_s_ctrl,
 893 };
 894 
 895 static int sd_init_controls(struct gspca_dev *gspca_dev)
 896 {
 897         struct sd *sd = (struct sd *)gspca_dev;
 898         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 899 
 900         gspca_dev->vdev.ctrl_handler = hdl;
 901         v4l2_ctrl_handler_init(hdl, 3);
 902         sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 903                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
 904         sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 905                         V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
 906         sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 907                         V4L2_CID_SATURATION, 0, 7, 1, 3);
 908         if (hdl->error) {
 909                 pr_err("Could not initialize controls\n");
 910                 return hdl->error;
 911         }
 912         return 0;
 913 }
 914 
 915 /* sub-driver description */
 916 static const struct sd_desc sd_desc = {
 917         .name = MODULE_NAME,
 918         .config = sd_config,
 919         .init = sd_init,
 920         .init_controls = sd_init_controls,
 921         .start = sd_start,
 922         .stop0 = sd_stop0,
 923         .pkt_scan = sd_pkt_scan,
 924 };
 925 
 926 /* -- module initialisation -- */
 927 static const struct usb_device_id device_table[] = {
 928         {USB_DEVICE(0x0572, 0x0041)},
 929         {}
 930 };
 931 MODULE_DEVICE_TABLE(usb, device_table);
 932 
 933 /* -- device connect -- */
 934 static int sd_probe(struct usb_interface *intf,
 935                         const struct usb_device_id *id)
 936 {
 937         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 938                                 THIS_MODULE);
 939 }
 940 
 941 static struct usb_driver sd_driver = {
 942         .name = MODULE_NAME,
 943         .id_table = device_table,
 944         .probe = sd_probe,
 945         .disconnect = gspca_disconnect,
 946 #ifdef CONFIG_PM
 947         .suspend = gspca_suspend,
 948         .resume = gspca_resume,
 949         .reset_resume = gspca_resume,
 950 #endif
 951 };
 952 
 953 module_usb_driver(sd_driver);

/* [<][>][^][v][top][bottom][index][help] */