Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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