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