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