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