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