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