1 /* 2 * SPCA500 chip based cameras initialization data 3 * 4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 */ 17 18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19 20 #define MODULE_NAME "spca500" 21 22 #include "gspca.h" 23 #include "jpeg.h" 24 25 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 26 MODULE_DESCRIPTION("GSPCA/SPCA500 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 char subtype; 36 #define AgfaCl20 0 37 #define AiptekPocketDV 1 38 #define BenqDC1016 2 39 #define CreativePCCam300 3 40 #define DLinkDSC350 4 41 #define Gsmartmini 5 42 #define IntelPocketPCCamera 6 43 #define KodakEZ200 7 44 #define LogitechClickSmart310 8 45 #define LogitechClickSmart510 9 46 #define LogitechTraveler 10 47 #define MustekGsmart300 11 48 #define Optimedia 12 49 #define PalmPixDC85 13 50 #define ToptroIndus 14 51 52 u8 jpeg_hdr[JPEG_HDR_SZ]; 53 }; 54 55 static const struct v4l2_pix_format vga_mode[] = { 56 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 57 .bytesperline = 320, 58 .sizeimage = 320 * 240 * 3 / 8 + 590, 59 .colorspace = V4L2_COLORSPACE_JPEG, 60 .priv = 1}, 61 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 62 .bytesperline = 640, 63 .sizeimage = 640 * 480 * 3 / 8 + 590, 64 .colorspace = V4L2_COLORSPACE_JPEG, 65 .priv = 0}, 66 }; 67 68 static const struct v4l2_pix_format sif_mode[] = { 69 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 70 .bytesperline = 176, 71 .sizeimage = 176 * 144 * 3 / 8 + 590, 72 .colorspace = V4L2_COLORSPACE_JPEG, 73 .priv = 1}, 74 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 75 .bytesperline = 352, 76 .sizeimage = 352 * 288 * 3 / 8 + 590, 77 .colorspace = V4L2_COLORSPACE_JPEG, 78 .priv = 0}, 79 }; 80 81 /* Frame packet header offsets for the spca500 */ 82 #define SPCA500_OFFSET_PADDINGLB 2 83 #define SPCA500_OFFSET_PADDINGHB 3 84 #define SPCA500_OFFSET_MODE 4 85 #define SPCA500_OFFSET_IMGWIDTH 5 86 #define SPCA500_OFFSET_IMGHEIGHT 6 87 #define SPCA500_OFFSET_IMGMODE 7 88 #define SPCA500_OFFSET_QTBLINDEX 8 89 #define SPCA500_OFFSET_FRAMSEQ 9 90 #define SPCA500_OFFSET_CDSPINFO 10 91 #define SPCA500_OFFSET_GPIO 11 92 #define SPCA500_OFFSET_AUGPIO 12 93 #define SPCA500_OFFSET_DATA 16 94 95 96 static const __u16 spca500_visual_defaults[][3] = { 97 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, 98 * hue (H byte) = 0, 99 * saturation/hue enable, 100 * brightness/contrast enable. 101 */ 102 {0x00, 0x0000, 0x8167}, /* brightness = 0 */ 103 {0x00, 0x0020, 0x8168}, /* contrast = 0 */ 104 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, 105 * hue (H byte) = 0, saturation/hue enable, 106 * brightness/contrast enable. 107 * was 0x0003, now 0x0000. 108 */ 109 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */ 110 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */ 111 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */ 112 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */ 113 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */ 114 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */ 115 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */ 116 {0x0c, 0x0004, 0x0000}, 117 /* set interface */ 118 {} 119 }; 120 static const __u16 Clicksmart510_defaults[][3] = { 121 {0x00, 0x00, 0x8211}, 122 {0x00, 0x01, 0x82c0}, 123 {0x00, 0x10, 0x82cb}, 124 {0x00, 0x0f, 0x800d}, 125 {0x00, 0x82, 0x8225}, 126 {0x00, 0x21, 0x8228}, 127 {0x00, 0x00, 0x8203}, 128 {0x00, 0x00, 0x8204}, 129 {0x00, 0x08, 0x8205}, 130 {0x00, 0xf8, 0x8206}, 131 {0x00, 0x28, 0x8207}, 132 {0x00, 0xa0, 0x8208}, 133 {0x00, 0x08, 0x824a}, 134 {0x00, 0x08, 0x8214}, 135 {0x00, 0x80, 0x82c1}, 136 {0x00, 0x00, 0x82c2}, 137 {0x00, 0x00, 0x82ca}, 138 {0x00, 0x80, 0x82c1}, 139 {0x00, 0x04, 0x82c2}, 140 {0x00, 0x00, 0x82ca}, 141 {0x00, 0xfc, 0x8100}, 142 {0x00, 0xfc, 0x8105}, 143 {0x00, 0x30, 0x8101}, 144 {0x00, 0x00, 0x8102}, 145 {0x00, 0x00, 0x8103}, 146 {0x00, 0x66, 0x8107}, 147 {0x00, 0x00, 0x816b}, 148 {0x00, 0x00, 0x8155}, 149 {0x00, 0x01, 0x8156}, 150 {0x00, 0x60, 0x8157}, 151 {0x00, 0x40, 0x8158}, 152 {0x00, 0x0a, 0x8159}, 153 {0x00, 0x06, 0x815a}, 154 {0x00, 0x00, 0x813f}, 155 {0x00, 0x00, 0x8200}, 156 {0x00, 0x19, 0x8201}, 157 {0x00, 0x00, 0x82c1}, 158 {0x00, 0xa0, 0x82c2}, 159 {0x00, 0x00, 0x82ca}, 160 {0x00, 0x00, 0x8117}, 161 {0x00, 0x00, 0x8118}, 162 {0x00, 0x65, 0x8119}, 163 {0x00, 0x00, 0x811a}, 164 {0x00, 0x00, 0x811b}, 165 {0x00, 0x55, 0x811c}, 166 {0x00, 0x65, 0x811d}, 167 {0x00, 0x55, 0x811e}, 168 {0x00, 0x16, 0x811f}, 169 {0x00, 0x19, 0x8120}, 170 {0x00, 0x80, 0x8103}, 171 {0x00, 0x83, 0x816b}, 172 {0x00, 0x25, 0x8168}, 173 {0x00, 0x01, 0x820f}, 174 {0x00, 0xff, 0x8115}, 175 {0x00, 0x48, 0x8116}, 176 {0x00, 0x50, 0x8151}, 177 {0x00, 0x40, 0x8152}, 178 {0x00, 0x78, 0x8153}, 179 {0x00, 0x40, 0x8154}, 180 {0x00, 0x00, 0x8167}, 181 {0x00, 0x20, 0x8168}, 182 {0x00, 0x00, 0x816a}, 183 {0x00, 0x03, 0x816b}, 184 {0x00, 0x20, 0x8169}, 185 {0x00, 0x60, 0x8157}, 186 {0x00, 0x00, 0x8190}, 187 {0x00, 0x00, 0x81a1}, 188 {0x00, 0x00, 0x81b2}, 189 {0x00, 0x27, 0x8191}, 190 {0x00, 0x27, 0x81a2}, 191 {0x00, 0x27, 0x81b3}, 192 {0x00, 0x4b, 0x8192}, 193 {0x00, 0x4b, 0x81a3}, 194 {0x00, 0x4b, 0x81b4}, 195 {0x00, 0x66, 0x8193}, 196 {0x00, 0x66, 0x81a4}, 197 {0x00, 0x66, 0x81b5}, 198 {0x00, 0x79, 0x8194}, 199 {0x00, 0x79, 0x81a5}, 200 {0x00, 0x79, 0x81b6}, 201 {0x00, 0x8a, 0x8195}, 202 {0x00, 0x8a, 0x81a6}, 203 {0x00, 0x8a, 0x81b7}, 204 {0x00, 0x9b, 0x8196}, 205 {0x00, 0x9b, 0x81a7}, 206 {0x00, 0x9b, 0x81b8}, 207 {0x00, 0xa6, 0x8197}, 208 {0x00, 0xa6, 0x81a8}, 209 {0x00, 0xa6, 0x81b9}, 210 {0x00, 0xb2, 0x8198}, 211 {0x00, 0xb2, 0x81a9}, 212 {0x00, 0xb2, 0x81ba}, 213 {0x00, 0xbe, 0x8199}, 214 {0x00, 0xbe, 0x81aa}, 215 {0x00, 0xbe, 0x81bb}, 216 {0x00, 0xc8, 0x819a}, 217 {0x00, 0xc8, 0x81ab}, 218 {0x00, 0xc8, 0x81bc}, 219 {0x00, 0xd2, 0x819b}, 220 {0x00, 0xd2, 0x81ac}, 221 {0x00, 0xd2, 0x81bd}, 222 {0x00, 0xdb, 0x819c}, 223 {0x00, 0xdb, 0x81ad}, 224 {0x00, 0xdb, 0x81be}, 225 {0x00, 0xe4, 0x819d}, 226 {0x00, 0xe4, 0x81ae}, 227 {0x00, 0xe4, 0x81bf}, 228 {0x00, 0xed, 0x819e}, 229 {0x00, 0xed, 0x81af}, 230 {0x00, 0xed, 0x81c0}, 231 {0x00, 0xf7, 0x819f}, 232 {0x00, 0xf7, 0x81b0}, 233 {0x00, 0xf7, 0x81c1}, 234 {0x00, 0xff, 0x81a0}, 235 {0x00, 0xff, 0x81b1}, 236 {0x00, 0xff, 0x81c2}, 237 {0x00, 0x03, 0x8156}, 238 {0x00, 0x00, 0x8211}, 239 {0x00, 0x20, 0x8168}, 240 {0x00, 0x01, 0x8202}, 241 {0x00, 0x30, 0x8101}, 242 {0x00, 0x00, 0x8111}, 243 {0x00, 0x00, 0x8112}, 244 {0x00, 0x00, 0x8113}, 245 {0x00, 0x00, 0x8114}, 246 {} 247 }; 248 249 static const __u8 qtable_creative_pccam[2][64] = { 250 { /* Q-table Y-components */ 251 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 252 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, 253 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, 254 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, 255 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, 256 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, 257 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, 258 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, 259 { /* Q-table C-components */ 260 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, 261 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 262 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 263 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 264 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 265 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 266 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 267 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} 268 }; 269 270 static const __u8 qtable_kodak_ez200[2][64] = { 271 { /* Q-table Y-components */ 272 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, 273 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06, 274 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06, 275 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06, 276 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08, 277 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09, 278 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a, 279 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a}, 280 { /* Q-table C-components */ 281 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a, 282 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 283 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 284 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 285 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 286 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 287 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 288 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a} 289 }; 290 291 static const __u8 qtable_pocketdv[2][64] = { 292 { /* Q-table Y-components start registers 0x8800 */ 293 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, 294 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, 295 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16, 296 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19, 297 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f, 298 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25, 299 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28, 300 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28, 301 }, 302 { /* Q-table C-components start registers 0x8840 */ 303 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28, 304 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28, 305 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28, 306 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 307 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 308 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 309 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 310 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} 311 }; 312 313 /* read 'len' bytes to gspca_dev->usb_buf */ 314 static void reg_r(struct gspca_dev *gspca_dev, 315 __u16 index, 316 __u16 length) 317 { 318 usb_control_msg(gspca_dev->dev, 319 usb_rcvctrlpipe(gspca_dev->dev, 0), 320 0, 321 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 322 0, /* value */ 323 index, gspca_dev->usb_buf, length, 500); 324 } 325 326 static int reg_w(struct gspca_dev *gspca_dev, 327 __u16 req, __u16 index, __u16 value) 328 { 329 int ret; 330 331 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value); 332 ret = usb_control_msg(gspca_dev->dev, 333 usb_sndctrlpipe(gspca_dev->dev, 0), 334 req, 335 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 336 value, index, NULL, 0, 500); 337 if (ret < 0) 338 pr_err("reg write: error %d\n", ret); 339 return ret; 340 } 341 342 /* returns: negative is error, pos or zero is data */ 343 static int reg_r_12(struct gspca_dev *gspca_dev, 344 __u16 req, /* bRequest */ 345 __u16 index, /* wIndex */ 346 __u16 length) /* wLength (1 or 2 only) */ 347 { 348 int ret; 349 350 gspca_dev->usb_buf[1] = 0; 351 ret = usb_control_msg(gspca_dev->dev, 352 usb_rcvctrlpipe(gspca_dev->dev, 0), 353 req, 354 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 355 0, /* value */ 356 index, 357 gspca_dev->usb_buf, length, 358 500); /* timeout */ 359 if (ret < 0) { 360 pr_err("reg_r_12 err %d\n", ret); 361 return ret; 362 } 363 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; 364 } 365 366 /* 367 * Simple function to wait for a given 8-bit value to be returned from 368 * a reg_read call. 369 * Returns: negative is error or timeout, zero is success. 370 */ 371 static int reg_r_wait(struct gspca_dev *gspca_dev, 372 __u16 reg, __u16 index, __u16 value) 373 { 374 int ret, cnt = 20; 375 376 while (--cnt > 0) { 377 ret = reg_r_12(gspca_dev, reg, index, 1); 378 if (ret == value) 379 return 0; 380 msleep(50); 381 } 382 return -EIO; 383 } 384 385 static int write_vector(struct gspca_dev *gspca_dev, 386 const __u16 data[][3]) 387 { 388 int ret, i = 0; 389 390 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { 391 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]); 392 if (ret < 0) 393 return ret; 394 i++; 395 } 396 return 0; 397 } 398 399 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, 400 unsigned int request, 401 unsigned int ybase, 402 unsigned int cbase, 403 const __u8 qtable[2][64]) 404 { 405 int i, err; 406 407 /* loop over y components */ 408 for (i = 0; i < 64; i++) { 409 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]); 410 if (err < 0) 411 return err; 412 } 413 414 /* loop over c components */ 415 for (i = 0; i < 64; i++) { 416 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]); 417 if (err < 0) 418 return err; 419 } 420 return 0; 421 } 422 423 static void spca500_ping310(struct gspca_dev *gspca_dev) 424 { 425 reg_r(gspca_dev, 0x0d04, 2); 426 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", 427 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); 428 } 429 430 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) 431 { 432 reg_r(gspca_dev, 0x0d05, 2); 433 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", 434 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); 435 reg_w(gspca_dev, 0x00, 0x8167, 0x5a); 436 spca500_ping310(gspca_dev); 437 438 reg_w(gspca_dev, 0x00, 0x8168, 0x22); 439 reg_w(gspca_dev, 0x00, 0x816a, 0xc0); 440 reg_w(gspca_dev, 0x00, 0x816b, 0x0b); 441 reg_w(gspca_dev, 0x00, 0x8169, 0x25); 442 reg_w(gspca_dev, 0x00, 0x8157, 0x5b); 443 reg_w(gspca_dev, 0x00, 0x8158, 0x5b); 444 reg_w(gspca_dev, 0x00, 0x813f, 0x03); 445 reg_w(gspca_dev, 0x00, 0x8151, 0x4a); 446 reg_w(gspca_dev, 0x00, 0x8153, 0x78); 447 reg_w(gspca_dev, 0x00, 0x0d01, 0x04); 448 /* 00 for adjust shutter */ 449 reg_w(gspca_dev, 0x00, 0x0d02, 0x01); 450 reg_w(gspca_dev, 0x00, 0x8169, 0x25); 451 reg_w(gspca_dev, 0x00, 0x0d01, 0x02); 452 } 453 454 static void spca500_setmode(struct gspca_dev *gspca_dev, 455 __u8 xmult, __u8 ymult) 456 { 457 int mode; 458 459 /* set x multiplier */ 460 reg_w(gspca_dev, 0, 0x8001, xmult); 461 462 /* set y multiplier */ 463 reg_w(gspca_dev, 0, 0x8002, ymult); 464 465 /* use compressed mode, VGA, with mode specific subsample */ 466 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 467 reg_w(gspca_dev, 0, 0x8003, mode << 4); 468 } 469 470 static int spca500_full_reset(struct gspca_dev *gspca_dev) 471 { 472 int err; 473 474 /* send the reset command */ 475 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000); 476 if (err < 0) 477 return err; 478 479 /* wait for the reset to complete */ 480 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000); 481 if (err < 0) 482 return err; 483 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000); 484 if (err < 0) 485 return err; 486 err = reg_r_wait(gspca_dev, 0x06, 0, 0); 487 if (err < 0) { 488 PERR("reg_r_wait() failed"); 489 return err; 490 } 491 /* all ok */ 492 return 0; 493 } 494 495 /* Synchro the Bridge with sensor */ 496 /* Maybe that will work on all spca500 chip */ 497 /* because i only own a clicksmart310 try for that chip */ 498 /* using spca50x_set_packet_size() cause an Ooops here */ 499 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */ 500 /* up-port the same feature as in 2.4.x kernel */ 501 static int spca500_synch310(struct gspca_dev *gspca_dev) 502 { 503 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { 504 PERR("Set packet size: set interface error"); 505 goto error; 506 } 507 spca500_ping310(gspca_dev); 508 509 reg_r(gspca_dev, 0x0d00, 1); 510 511 /* need alt setting here */ 512 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); 513 514 /* Windoze use pipe with altsetting 6 why 7 here */ 515 if (usb_set_interface(gspca_dev->dev, 516 gspca_dev->iface, 517 gspca_dev->alt) < 0) { 518 PERR("Set packet size: set interface error"); 519 goto error; 520 } 521 return 0; 522 error: 523 return -EBUSY; 524 } 525 526 static void spca500_reinit(struct gspca_dev *gspca_dev) 527 { 528 int err; 529 __u8 Data; 530 531 /* some unknown command from Aiptek pocket dv and family300 */ 532 533 reg_w(gspca_dev, 0x00, 0x0d01, 0x01); 534 reg_w(gspca_dev, 0x00, 0x0d03, 0x00); 535 reg_w(gspca_dev, 0x00, 0x0d02, 0x01); 536 537 /* enable drop packet */ 538 reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 539 540 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, 541 qtable_pocketdv); 542 if (err < 0) 543 PERR("spca50x_setup_qtable failed on init"); 544 545 /* set qtable index */ 546 reg_w(gspca_dev, 0x00, 0x8880, 2); 547 /* family cam Quicksmart stuff */ 548 reg_w(gspca_dev, 0x00, 0x800a, 0x00); 549 /* Set agc transfer: synced between frames */ 550 reg_w(gspca_dev, 0x00, 0x820f, 0x01); 551 /* Init SDRAM - needed for SDRAM access */ 552 reg_w(gspca_dev, 0x00, 0x870a, 0x04); 553 /*Start init sequence or stream */ 554 reg_w(gspca_dev, 0, 0x8003, 0x00); 555 /* switch to video camera mode */ 556 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 557 msleep(2000); 558 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) { 559 reg_r(gspca_dev, 0x816b, 1); 560 Data = gspca_dev->usb_buf[0]; 561 reg_w(gspca_dev, 0x00, 0x816b, Data); 562 } 563 } 564 565 /* this function is called at probe time */ 566 static int sd_config(struct gspca_dev *gspca_dev, 567 const struct usb_device_id *id) 568 { 569 struct sd *sd = (struct sd *) gspca_dev; 570 struct cam *cam; 571 572 cam = &gspca_dev->cam; 573 sd->subtype = id->driver_info; 574 if (sd->subtype != LogitechClickSmart310) { 575 cam->cam_mode = vga_mode; 576 cam->nmodes = ARRAY_SIZE(vga_mode); 577 } else { 578 cam->cam_mode = sif_mode; 579 cam->nmodes = ARRAY_SIZE(sif_mode); 580 } 581 return 0; 582 } 583 584 /* this function is called at probe and resume time */ 585 static int sd_init(struct gspca_dev *gspca_dev) 586 { 587 struct sd *sd = (struct sd *) gspca_dev; 588 589 /* initialisation of spca500 based cameras is deferred */ 590 PDEBUG(D_STREAM, "SPCA500 init"); 591 if (sd->subtype == LogitechClickSmart310) 592 spca500_clksmart310_init(gspca_dev); 593 /* else 594 spca500_initialise(gspca_dev); */ 595 PDEBUG(D_STREAM, "SPCA500 init done"); 596 return 0; 597 } 598 599 static int sd_start(struct gspca_dev *gspca_dev) 600 { 601 struct sd *sd = (struct sd *) gspca_dev; 602 int err; 603 __u8 Data; 604 __u8 xmult, ymult; 605 606 /* create the JPEG header */ 607 jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, 608 gspca_dev->pixfmt.width, 609 0x22); /* JPEG 411 */ 610 jpeg_set_qual(sd->jpeg_hdr, QUALITY); 611 612 if (sd->subtype == LogitechClickSmart310) { 613 xmult = 0x16; 614 ymult = 0x12; 615 } else { 616 xmult = 0x28; 617 ymult = 0x1e; 618 } 619 620 /* is there a sensor here ? */ 621 reg_r(gspca_dev, 0x8a04, 1); 622 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x", 623 gspca_dev->usb_buf[0]); 624 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x", 625 gspca_dev->curr_mode, xmult, ymult); 626 627 /* setup qtable */ 628 switch (sd->subtype) { 629 case LogitechClickSmart310: 630 spca500_setmode(gspca_dev, xmult, ymult); 631 632 /* enable drop packet */ 633 reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 634 reg_w(gspca_dev, 0x00, 0x8880, 3); 635 err = spca50x_setup_qtable(gspca_dev, 636 0x00, 0x8800, 0x8840, 637 qtable_creative_pccam); 638 if (err < 0) 639 PERR("spca50x_setup_qtable failed"); 640 /* Init SDRAM - needed for SDRAM access */ 641 reg_w(gspca_dev, 0x00, 0x870a, 0x04); 642 643 /* switch to video camera mode */ 644 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 645 msleep(500); 646 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) 647 PERR("reg_r_wait() failed"); 648 649 reg_r(gspca_dev, 0x816b, 1); 650 Data = gspca_dev->usb_buf[0]; 651 reg_w(gspca_dev, 0x00, 0x816b, Data); 652 653 spca500_synch310(gspca_dev); 654 655 write_vector(gspca_dev, spca500_visual_defaults); 656 spca500_setmode(gspca_dev, xmult, ymult); 657 /* enable drop packet */ 658 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 659 if (err < 0) 660 PERR("failed to enable drop packet"); 661 reg_w(gspca_dev, 0x00, 0x8880, 3); 662 err = spca50x_setup_qtable(gspca_dev, 663 0x00, 0x8800, 0x8840, 664 qtable_creative_pccam); 665 if (err < 0) 666 PERR("spca50x_setup_qtable failed"); 667 668 /* Init SDRAM - needed for SDRAM access */ 669 reg_w(gspca_dev, 0x00, 0x870a, 0x04); 670 671 /* switch to video camera mode */ 672 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 673 674 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) 675 PERR("reg_r_wait() failed"); 676 677 reg_r(gspca_dev, 0x816b, 1); 678 Data = gspca_dev->usb_buf[0]; 679 reg_w(gspca_dev, 0x00, 0x816b, Data); 680 break; 681 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ 682 case IntelPocketPCCamera: /* FIXME: Temporary fix for 683 * Intel Pocket PC Camera 684 * - NWG (Sat 29th March 2003) */ 685 686 /* do a full reset */ 687 err = spca500_full_reset(gspca_dev); 688 if (err < 0) 689 PERR("spca500_full_reset failed"); 690 691 /* enable drop packet */ 692 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 693 if (err < 0) 694 PERR("failed to enable drop packet"); 695 reg_w(gspca_dev, 0x00, 0x8880, 3); 696 err = spca50x_setup_qtable(gspca_dev, 697 0x00, 0x8800, 0x8840, 698 qtable_creative_pccam); 699 if (err < 0) 700 PERR("spca50x_setup_qtable failed"); 701 702 spca500_setmode(gspca_dev, xmult, ymult); 703 reg_w(gspca_dev, 0x20, 0x0001, 0x0004); 704 705 /* switch to video camera mode */ 706 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 707 708 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) 709 PERR("reg_r_wait() failed"); 710 711 reg_r(gspca_dev, 0x816b, 1); 712 Data = gspca_dev->usb_buf[0]; 713 reg_w(gspca_dev, 0x00, 0x816b, Data); 714 715 /* write_vector(gspca_dev, spca500_visual_defaults); */ 716 break; 717 case KodakEZ200: /* Kodak EZ200 */ 718 719 /* do a full reset */ 720 err = spca500_full_reset(gspca_dev); 721 if (err < 0) 722 PERR("spca500_full_reset failed"); 723 /* enable drop packet */ 724 reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 725 reg_w(gspca_dev, 0x00, 0x8880, 0); 726 err = spca50x_setup_qtable(gspca_dev, 727 0x00, 0x8800, 0x8840, 728 qtable_kodak_ez200); 729 if (err < 0) 730 PERR("spca50x_setup_qtable failed"); 731 spca500_setmode(gspca_dev, xmult, ymult); 732 733 reg_w(gspca_dev, 0x20, 0x0001, 0x0004); 734 735 /* switch to video camera mode */ 736 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 737 738 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) 739 PERR("reg_r_wait() failed"); 740 741 reg_r(gspca_dev, 0x816b, 1); 742 Data = gspca_dev->usb_buf[0]; 743 reg_w(gspca_dev, 0x00, 0x816b, Data); 744 745 /* write_vector(gspca_dev, spca500_visual_defaults); */ 746 break; 747 748 case BenqDC1016: 749 case DLinkDSC350: /* FamilyCam 300 */ 750 case AiptekPocketDV: /* Aiptek PocketDV */ 751 case Gsmartmini: /*Mustek Gsmart Mini */ 752 case MustekGsmart300: /* Mustek Gsmart 300 */ 753 case PalmPixDC85: 754 case Optimedia: 755 case ToptroIndus: 756 case AgfaCl20: 757 spca500_reinit(gspca_dev); 758 reg_w(gspca_dev, 0x00, 0x0d01, 0x01); 759 /* enable drop packet */ 760 reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 761 762 err = spca50x_setup_qtable(gspca_dev, 763 0x00, 0x8800, 0x8840, qtable_pocketdv); 764 if (err < 0) 765 PERR("spca50x_setup_qtable failed"); 766 reg_w(gspca_dev, 0x00, 0x8880, 2); 767 768 /* familycam Quicksmart pocketDV stuff */ 769 reg_w(gspca_dev, 0x00, 0x800a, 0x00); 770 /* Set agc transfer: synced between frames */ 771 reg_w(gspca_dev, 0x00, 0x820f, 0x01); 772 /* Init SDRAM - needed for SDRAM access */ 773 reg_w(gspca_dev, 0x00, 0x870a, 0x04); 774 775 spca500_setmode(gspca_dev, xmult, ymult); 776 /* switch to video camera mode */ 777 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 778 779 reg_r_wait(gspca_dev, 0, 0x8000, 0x44); 780 781 reg_r(gspca_dev, 0x816b, 1); 782 Data = gspca_dev->usb_buf[0]; 783 reg_w(gspca_dev, 0x00, 0x816b, Data); 784 break; 785 case LogitechTraveler: 786 case LogitechClickSmart510: 787 reg_w(gspca_dev, 0x02, 0x00, 0x00); 788 /* enable drop packet */ 789 reg_w(gspca_dev, 0x00, 0x850a, 0x0001); 790 791 err = spca50x_setup_qtable(gspca_dev, 792 0x00, 0x8800, 793 0x8840, qtable_creative_pccam); 794 if (err < 0) 795 PERR("spca50x_setup_qtable failed"); 796 reg_w(gspca_dev, 0x00, 0x8880, 3); 797 reg_w(gspca_dev, 0x00, 0x800a, 0x00); 798 /* Init SDRAM - needed for SDRAM access */ 799 reg_w(gspca_dev, 0x00, 0x870a, 0x04); 800 801 spca500_setmode(gspca_dev, xmult, ymult); 802 803 /* switch to video camera mode */ 804 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 805 reg_r_wait(gspca_dev, 0, 0x8000, 0x44); 806 807 reg_r(gspca_dev, 0x816b, 1); 808 Data = gspca_dev->usb_buf[0]; 809 reg_w(gspca_dev, 0x00, 0x816b, Data); 810 write_vector(gspca_dev, Clicksmart510_defaults); 811 break; 812 } 813 return 0; 814 } 815 816 static void sd_stopN(struct gspca_dev *gspca_dev) 817 { 818 reg_w(gspca_dev, 0, 0x8003, 0x00); 819 820 /* switch to video camera mode */ 821 reg_w(gspca_dev, 0x00, 0x8000, 0x0004); 822 reg_r(gspca_dev, 0x8000, 1); 823 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", 824 gspca_dev->usb_buf[0]); 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; 833 static __u8 ffd9[] = {0xff, 0xd9}; 834 835 /* frames are jpeg 4.1.1 without 0xff escape */ 836 if (data[0] == 0xff) { 837 if (data[1] != 0x01) { /* drop packet */ 838 /* gspca_dev->last_packet_type = DISCARD_PACKET; */ 839 return; 840 } 841 gspca_frame_add(gspca_dev, LAST_PACKET, 842 ffd9, 2); 843 844 /* put the JPEG header in the new frame */ 845 gspca_frame_add(gspca_dev, FIRST_PACKET, 846 sd->jpeg_hdr, JPEG_HDR_SZ); 847 848 data += SPCA500_OFFSET_DATA; 849 len -= SPCA500_OFFSET_DATA; 850 } else { 851 data += 1; 852 len -= 1; 853 } 854 855 /* add 0x00 after 0xff */ 856 i = 0; 857 do { 858 if (data[i] == 0xff) { 859 gspca_frame_add(gspca_dev, INTER_PACKET, 860 data, i + 1); 861 len -= i; 862 data += i; 863 *data = 0x00; 864 i = 0; 865 } 866 i++; 867 } while (i < len); 868 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 869 } 870 871 static void setbrightness(struct gspca_dev *gspca_dev, s32 val) 872 { 873 reg_w(gspca_dev, 0x00, 0x8167, 874 (__u8) (val - 128)); 875 } 876 877 static void setcontrast(struct gspca_dev *gspca_dev, s32 val) 878 { 879 reg_w(gspca_dev, 0x00, 0x8168, val); 880 } 881 882 static void setcolors(struct gspca_dev *gspca_dev, s32 val) 883 { 884 reg_w(gspca_dev, 0x00, 0x8169, val); 885 } 886 887 static int sd_s_ctrl(struct v4l2_ctrl *ctrl) 888 { 889 struct gspca_dev *gspca_dev = 890 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 891 892 gspca_dev->usb_err = 0; 893 894 if (!gspca_dev->streaming) 895 return 0; 896 897 switch (ctrl->id) { 898 case V4L2_CID_BRIGHTNESS: 899 setbrightness(gspca_dev, ctrl->val); 900 break; 901 case V4L2_CID_CONTRAST: 902 setcontrast(gspca_dev, ctrl->val); 903 break; 904 case V4L2_CID_SATURATION: 905 setcolors(gspca_dev, ctrl->val); 906 break; 907 } 908 return gspca_dev->usb_err; 909 } 910 911 static const struct v4l2_ctrl_ops sd_ctrl_ops = { 912 .s_ctrl = sd_s_ctrl, 913 }; 914 915 static int sd_init_controls(struct gspca_dev *gspca_dev) 916 { 917 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 918 919 gspca_dev->vdev.ctrl_handler = hdl; 920 v4l2_ctrl_handler_init(hdl, 3); 921 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 922 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); 923 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 924 V4L2_CID_CONTRAST, 0, 63, 1, 31); 925 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 926 V4L2_CID_SATURATION, 0, 63, 1, 31); 927 928 if (hdl->error) { 929 pr_err("Could not initialize controls\n"); 930 return hdl->error; 931 } 932 return 0; 933 } 934 935 /* sub-driver description */ 936 static const struct sd_desc sd_desc = { 937 .name = MODULE_NAME, 938 .config = sd_config, 939 .init = sd_init, 940 .init_controls = sd_init_controls, 941 .start = sd_start, 942 .stopN = sd_stopN, 943 .pkt_scan = sd_pkt_scan, 944 }; 945 946 /* -- module initialisation -- */ 947 static const struct usb_device_id device_table[] = { 948 {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200}, 949 {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300}, 950 {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler}, 951 {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310}, 952 {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510}, 953 {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016}, 954 {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85}, 955 {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300}, 956 {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini}, 957 {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20}, 958 {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia}, 959 {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350}, 960 {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV}, 961 {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus}, 962 {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera}, 963 {} 964 }; 965 MODULE_DEVICE_TABLE(usb, device_table); 966 967 /* -- device connect -- */ 968 static int sd_probe(struct usb_interface *intf, 969 const struct usb_device_id *id) 970 { 971 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 972 THIS_MODULE); 973 } 974 975 static struct usb_driver sd_driver = { 976 .name = MODULE_NAME, 977 .id_table = device_table, 978 .probe = sd_probe, 979 .disconnect = gspca_disconnect, 980 #ifdef CONFIG_PM 981 .suspend = gspca_suspend, 982 .resume = gspca_resume, 983 .reset_resume = gspca_resume, 984 #endif 985 }; 986 987 module_usb_driver(sd_driver); 988