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