1/* 2 * SPCA506 chip based cameras function 3 * M Xhaard 15/04/2004 based on different work Mark Taylor and others 4 * and my own snoopy file on a pv-321c donate by a german compagny 5 * "Firma Frank Gmbh" from Saarbruecken 6 * 7 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24#define MODULE_NAME "spca506" 25 26#include "gspca.h" 27 28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 29MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); 30MODULE_LICENSE("GPL"); 31 32/* specific webcam descriptor */ 33struct sd { 34 struct gspca_dev gspca_dev; /* !! must be the first item */ 35 36 unsigned char brightness; 37 unsigned char contrast; 38 unsigned char colors; 39 unsigned char hue; 40 char norme; 41 char channel; 42}; 43 44/* V4L2 controls supported by the driver */ 45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 47static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 48static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 49static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 50static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); 52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); 53 54static const struct ctrl sd_ctrls[] = { 55#define SD_BRIGHTNESS 0 56 { 57 { 58 .id = V4L2_CID_BRIGHTNESS, 59 .type = V4L2_CTRL_TYPE_INTEGER, 60 .name = "Brightness", 61 .minimum = 0, 62 .maximum = 0xff, 63 .step = 1, 64 .default_value = 0x80, 65 }, 66 .set = sd_setbrightness, 67 .get = sd_getbrightness, 68 }, 69#define SD_CONTRAST 1 70 { 71 { 72 .id = V4L2_CID_CONTRAST, 73 .type = V4L2_CTRL_TYPE_INTEGER, 74 .name = "Contrast", 75 .minimum = 0, 76 .maximum = 0xff, 77 .step = 1, 78 .default_value = 0x47, 79 }, 80 .set = sd_setcontrast, 81 .get = sd_getcontrast, 82 }, 83#define SD_COLOR 2 84 { 85 { 86 .id = V4L2_CID_SATURATION, 87 .type = V4L2_CTRL_TYPE_INTEGER, 88 .name = "Saturation", 89 .minimum = 0, 90 .maximum = 0xff, 91 .step = 1, 92 .default_value = 0x40, 93 }, 94 .set = sd_setcolors, 95 .get = sd_getcolors, 96 }, 97#define SD_HUE 3 98 { 99 { 100 .id = V4L2_CID_HUE, 101 .type = V4L2_CTRL_TYPE_INTEGER, 102 .name = "Hue", 103 .minimum = 0, 104 .maximum = 0xff, 105 .step = 1, 106 .default_value = 0, 107 }, 108 .set = sd_sethue, 109 .get = sd_gethue, 110 }, 111}; 112 113static const struct v4l2_pix_format vga_mode[] = { 114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 115 .bytesperline = 160, 116 .sizeimage = 160 * 120 * 3 / 2, 117 .colorspace = V4L2_COLORSPACE_SRGB, 118 .priv = 5}, 119 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 120 .bytesperline = 176, 121 .sizeimage = 176 * 144 * 3 / 2, 122 .colorspace = V4L2_COLORSPACE_SRGB, 123 .priv = 4}, 124 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 125 .bytesperline = 320, 126 .sizeimage = 320 * 240 * 3 / 2, 127 .colorspace = V4L2_COLORSPACE_SRGB, 128 .priv = 2}, 129 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 130 .bytesperline = 352, 131 .sizeimage = 352 * 288 * 3 / 2, 132 .colorspace = V4L2_COLORSPACE_SRGB, 133 .priv = 1}, 134 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 135 .bytesperline = 640, 136 .sizeimage = 640 * 480 * 3 / 2, 137 .colorspace = V4L2_COLORSPACE_SRGB, 138 .priv = 0}, 139}; 140 141#define SPCA50X_OFFSET_DATA 10 142 143#define SAA7113_bright 0x0a /* defaults 0x80 */ 144#define SAA7113_contrast 0x0b /* defaults 0x47 */ 145#define SAA7113_saturation 0x0c /* defaults 0x40 */ 146#define SAA7113_hue 0x0d /* defaults 0x00 */ 147#define SAA7113_I2C_BASE_WRITE 0x4a 148 149/* read 'len' bytes to gspca_dev->usb_buf */ 150static void reg_r(struct gspca_dev *gspca_dev, 151 __u16 req, 152 __u16 index, 153 __u16 length) 154{ 155 usb_control_msg(gspca_dev->dev, 156 usb_rcvctrlpipe(gspca_dev->dev, 0), 157 req, 158 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 159 0, /* value */ 160 index, gspca_dev->usb_buf, length, 161 500); 162} 163 164static void reg_w(struct usb_device *dev, 165 __u16 req, 166 __u16 value, 167 __u16 index) 168{ 169 usb_control_msg(dev, 170 usb_sndctrlpipe(dev, 0), 171 req, 172 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 173 value, index, 174 NULL, 0, 500); 175} 176 177static void spca506_Initi2c(struct gspca_dev *gspca_dev) 178{ 179 reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); 180} 181 182static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, 183 __u16 reg) 184{ 185 int retry = 60; 186 187 reg_w(gspca_dev->dev, 0x07, reg, 0x0001); 188 reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); 189 while (retry--) { 190 reg_r(gspca_dev, 0x07, 0x0003, 2); 191 if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) 192 break; 193 } 194} 195 196static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, 197 __u16 norme, 198 __u16 channel) 199{ 200 struct sd *sd = (struct sd *) gspca_dev; 201 __u8 setbit0 = 0x00; 202 __u8 setbit1 = 0x00; 203 __u8 videomask = 0x00; 204 205 PDEBUG(D_STREAM, "** Open Set Norme **"); 206 spca506_Initi2c(gspca_dev); 207 /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */ 208 /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */ 209 /* and exclude SAA7113 reserved channel set default 0 otherwise */ 210 if (norme & V4L2_STD_NTSC) 211 setbit0 = 0x01; 212 if (channel == 4 || channel == 5 || channel > 9) 213 channel = 0; 214 if (channel < 4) 215 setbit1 = 0x02; 216 videomask = (0x48 | setbit0 | setbit1); 217 reg_w(gspca_dev->dev, 0x08, videomask, 0x0000); 218 spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02); 219 220 if (norme & V4L2_STD_NTSC) 221 spca506_WriteI2c(gspca_dev, 0x33, 0x0e); 222 /* Chrominance Control NTSC N */ 223 else if (norme & V4L2_STD_SECAM) 224 spca506_WriteI2c(gspca_dev, 0x53, 0x0e); 225 /* Chrominance Control SECAM */ 226 else 227 spca506_WriteI2c(gspca_dev, 0x03, 0x0e); 228 /* Chrominance Control PAL BGHIV */ 229 230 sd->norme = norme; 231 sd->channel = channel; 232 PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask); 233 PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel); 234} 235 236static void spca506_GetNormeInput(struct gspca_dev *gspca_dev, 237 __u16 *norme, __u16 *channel) 238{ 239 struct sd *sd = (struct sd *) gspca_dev; 240 241 /* Read the register is not so good value change so 242 we use your own copy in spca50x struct */ 243 *norme = sd->norme; 244 *channel = sd->channel; 245 PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel); 246} 247 248static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code, 249 __u16 xmult, __u16 ymult) 250{ 251 struct usb_device *dev = gspca_dev->dev; 252 253 PDEBUG(D_STREAM, "** SetSize **"); 254 reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000); 255 /* Soft snap 0x40 Hard 0x41 */ 256 reg_w(dev, 0x04, 0x41, 0x0001); 257 reg_w(dev, 0x04, 0x00, 0x0002); 258 /* reserved */ 259 reg_w(dev, 0x04, 0x00, 0x0003); 260 261 /* reserved */ 262 reg_w(dev, 0x04, 0x00, 0x0004); 263 /* reserved */ 264 reg_w(dev, 0x04, 0x01, 0x0005); 265 /* reserced */ 266 reg_w(dev, 0x04, xmult, 0x0006); 267 /* reserved */ 268 reg_w(dev, 0x04, ymult, 0x0007); 269 /* compression 1 */ 270 reg_w(dev, 0x04, 0x00, 0x0008); 271 /* T=64 -> 2 */ 272 reg_w(dev, 0x04, 0x00, 0x0009); 273 /* threshold2D */ 274 reg_w(dev, 0x04, 0x21, 0x000a); 275 /* quantization */ 276 reg_w(dev, 0x04, 0x00, 0x000b); 277} 278 279/* this function is called at probe time */ 280static int sd_config(struct gspca_dev *gspca_dev, 281 const struct usb_device_id *id) 282{ 283 struct sd *sd = (struct sd *) gspca_dev; 284 struct cam *cam; 285 286 cam = &gspca_dev->cam; 287 cam->cam_mode = vga_mode; 288 cam->nmodes = ARRAY_SIZE(vga_mode); 289 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 290 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 291 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 292 sd->hue = sd_ctrls[SD_HUE].qctrl.default_value; 293 return 0; 294} 295 296/* this function is called at probe and resume time */ 297static int sd_init(struct gspca_dev *gspca_dev) 298{ 299 struct usb_device *dev = gspca_dev->dev; 300 301 reg_w(dev, 0x03, 0x00, 0x0004); 302 reg_w(dev, 0x03, 0xFF, 0x0003); 303 reg_w(dev, 0x03, 0x00, 0x0000); 304 reg_w(dev, 0x03, 0x1c, 0x0001); 305 reg_w(dev, 0x03, 0x18, 0x0001); 306 /* Init on PAL and composite input0 */ 307 spca506_SetNormeInput(gspca_dev, 0, 0); 308 reg_w(dev, 0x03, 0x1c, 0x0001); 309 reg_w(dev, 0x03, 0x18, 0x0001); 310 reg_w(dev, 0x05, 0x00, 0x0000); 311 reg_w(dev, 0x05, 0xef, 0x0001); 312 reg_w(dev, 0x05, 0x00, 0x00c1); 313 reg_w(dev, 0x05, 0x00, 0x00c2); 314 reg_w(dev, 0x06, 0x18, 0x0002); 315 reg_w(dev, 0x06, 0xf5, 0x0011); 316 reg_w(dev, 0x06, 0x02, 0x0012); 317 reg_w(dev, 0x06, 0xfb, 0x0013); 318 reg_w(dev, 0x06, 0x00, 0x0014); 319 reg_w(dev, 0x06, 0xa4, 0x0051); 320 reg_w(dev, 0x06, 0x40, 0x0052); 321 reg_w(dev, 0x06, 0x71, 0x0053); 322 reg_w(dev, 0x06, 0x40, 0x0054); 323 /************************************************/ 324 reg_w(dev, 0x03, 0x00, 0x0004); 325 reg_w(dev, 0x03, 0x00, 0x0003); 326 reg_w(dev, 0x03, 0x00, 0x0004); 327 reg_w(dev, 0x03, 0xFF, 0x0003); 328 reg_w(dev, 0x02, 0x00, 0x0000); 329 reg_w(dev, 0x03, 0x60, 0x0000); 330 reg_w(dev, 0x03, 0x18, 0x0001); 331 /* for a better reading mx :) */ 332 /*sdca506_WriteI2c(value,register) */ 333 spca506_Initi2c(gspca_dev); 334 spca506_WriteI2c(gspca_dev, 0x08, 0x01); 335 spca506_WriteI2c(gspca_dev, 0xc0, 0x02); 336 /* input composite video */ 337 spca506_WriteI2c(gspca_dev, 0x33, 0x03); 338 spca506_WriteI2c(gspca_dev, 0x00, 0x04); 339 spca506_WriteI2c(gspca_dev, 0x00, 0x05); 340 spca506_WriteI2c(gspca_dev, 0x0d, 0x06); 341 spca506_WriteI2c(gspca_dev, 0xf0, 0x07); 342 spca506_WriteI2c(gspca_dev, 0x98, 0x08); 343 spca506_WriteI2c(gspca_dev, 0x03, 0x09); 344 spca506_WriteI2c(gspca_dev, 0x80, 0x0a); 345 spca506_WriteI2c(gspca_dev, 0x47, 0x0b); 346 spca506_WriteI2c(gspca_dev, 0x48, 0x0c); 347 spca506_WriteI2c(gspca_dev, 0x00, 0x0d); 348 spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */ 349 spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); 350 spca506_WriteI2c(gspca_dev, 0x00, 0x10); 351 spca506_WriteI2c(gspca_dev, 0x0c, 0x11); 352 spca506_WriteI2c(gspca_dev, 0xb8, 0x12); 353 spca506_WriteI2c(gspca_dev, 0x01, 0x13); 354 spca506_WriteI2c(gspca_dev, 0x00, 0x14); 355 spca506_WriteI2c(gspca_dev, 0x00, 0x15); 356 spca506_WriteI2c(gspca_dev, 0x00, 0x16); 357 spca506_WriteI2c(gspca_dev, 0x00, 0x17); 358 spca506_WriteI2c(gspca_dev, 0x00, 0x18); 359 spca506_WriteI2c(gspca_dev, 0x00, 0x19); 360 spca506_WriteI2c(gspca_dev, 0x00, 0x1a); 361 spca506_WriteI2c(gspca_dev, 0x00, 0x1b); 362 spca506_WriteI2c(gspca_dev, 0x00, 0x1c); 363 spca506_WriteI2c(gspca_dev, 0x00, 0x1d); 364 spca506_WriteI2c(gspca_dev, 0x00, 0x1e); 365 spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); 366 spca506_WriteI2c(gspca_dev, 0x02, 0x40); 367 spca506_WriteI2c(gspca_dev, 0xff, 0x41); 368 spca506_WriteI2c(gspca_dev, 0xff, 0x42); 369 spca506_WriteI2c(gspca_dev, 0xff, 0x43); 370 spca506_WriteI2c(gspca_dev, 0xff, 0x44); 371 spca506_WriteI2c(gspca_dev, 0xff, 0x45); 372 spca506_WriteI2c(gspca_dev, 0xff, 0x46); 373 spca506_WriteI2c(gspca_dev, 0xff, 0x47); 374 spca506_WriteI2c(gspca_dev, 0xff, 0x48); 375 spca506_WriteI2c(gspca_dev, 0xff, 0x49); 376 spca506_WriteI2c(gspca_dev, 0xff, 0x4a); 377 spca506_WriteI2c(gspca_dev, 0xff, 0x4b); 378 spca506_WriteI2c(gspca_dev, 0xff, 0x4c); 379 spca506_WriteI2c(gspca_dev, 0xff, 0x4d); 380 spca506_WriteI2c(gspca_dev, 0xff, 0x4e); 381 spca506_WriteI2c(gspca_dev, 0xff, 0x4f); 382 spca506_WriteI2c(gspca_dev, 0xff, 0x50); 383 spca506_WriteI2c(gspca_dev, 0xff, 0x51); 384 spca506_WriteI2c(gspca_dev, 0xff, 0x52); 385 spca506_WriteI2c(gspca_dev, 0xff, 0x53); 386 spca506_WriteI2c(gspca_dev, 0xff, 0x54); 387 spca506_WriteI2c(gspca_dev, 0xff, 0x55); 388 spca506_WriteI2c(gspca_dev, 0xff, 0x56); 389 spca506_WriteI2c(gspca_dev, 0xff, 0x57); 390 spca506_WriteI2c(gspca_dev, 0x00, 0x58); 391 spca506_WriteI2c(gspca_dev, 0x54, 0x59); 392 spca506_WriteI2c(gspca_dev, 0x07, 0x5a); 393 spca506_WriteI2c(gspca_dev, 0x83, 0x5b); 394 spca506_WriteI2c(gspca_dev, 0x00, 0x5c); 395 spca506_WriteI2c(gspca_dev, 0x00, 0x5d); 396 spca506_WriteI2c(gspca_dev, 0x00, 0x5e); 397 spca506_WriteI2c(gspca_dev, 0x00, 0x5f); 398 spca506_WriteI2c(gspca_dev, 0x00, 0x60); 399 spca506_WriteI2c(gspca_dev, 0x05, 0x61); 400 spca506_WriteI2c(gspca_dev, 0x9f, 0x62); 401 PDEBUG(D_STREAM, "** Close Init *"); 402 return 0; 403} 404 405static int sd_start(struct gspca_dev *gspca_dev) 406{ 407 struct usb_device *dev = gspca_dev->dev; 408 __u16 norme; 409 __u16 channel; 410 411 /**************************************/ 412 reg_w(dev, 0x03, 0x00, 0x0004); 413 reg_w(dev, 0x03, 0x00, 0x0003); 414 reg_w(dev, 0x03, 0x00, 0x0004); 415 reg_w(dev, 0x03, 0xFF, 0x0003); 416 reg_w(dev, 0x02, 0x00, 0x0000); 417 reg_w(dev, 0x03, 0x60, 0x0000); 418 reg_w(dev, 0x03, 0x18, 0x0001); 419 420 /*sdca506_WriteI2c(value,register) */ 421 spca506_Initi2c(gspca_dev); 422 spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */ 423/* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */ 424 spca506_WriteI2c(gspca_dev, 0x33, 0x03); 425 /* Analog Input Control 2 */ 426 spca506_WriteI2c(gspca_dev, 0x00, 0x04); 427 /* Analog Input Control 3 */ 428 spca506_WriteI2c(gspca_dev, 0x00, 0x05); 429 /* Analog Input Control 4 */ 430 spca506_WriteI2c(gspca_dev, 0x0d, 0x06); 431 /* Horizontal Sync Start 0xe9-0x0d */ 432 spca506_WriteI2c(gspca_dev, 0xf0, 0x07); 433 /* Horizontal Sync Stop 0x0d-0xf0 */ 434 435 spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */ 436/* Defaults value */ 437 spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */ 438 spca506_WriteI2c(gspca_dev, 0x80, 0x0a); 439 /* Luminance Brightness */ 440 spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */ 441 spca506_WriteI2c(gspca_dev, 0x48, 0x0c); 442 /* Chrominance Saturation */ 443 spca506_WriteI2c(gspca_dev, 0x00, 0x0d); 444 /* Chrominance Hue Control */ 445 spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); 446 /* Chrominance Gain Control */ 447 /**************************************/ 448 spca506_WriteI2c(gspca_dev, 0x00, 0x10); 449 /* Format/Delay Control */ 450 spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */ 451 spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */ 452 spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */ 453 spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */ 454 spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */ 455 spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */ 456 spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */ 457 spca506_WriteI2c(gspca_dev, 0x00, 0x18); 458 spca506_WriteI2c(gspca_dev, 0x00, 0x19); 459 spca506_WriteI2c(gspca_dev, 0x00, 0x1a); 460 spca506_WriteI2c(gspca_dev, 0x00, 0x1b); 461 spca506_WriteI2c(gspca_dev, 0x00, 0x1c); 462 spca506_WriteI2c(gspca_dev, 0x00, 0x1d); 463 spca506_WriteI2c(gspca_dev, 0x00, 0x1e); 464 spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); 465 spca506_WriteI2c(gspca_dev, 0x02, 0x40); 466 spca506_WriteI2c(gspca_dev, 0xff, 0x41); 467 spca506_WriteI2c(gspca_dev, 0xff, 0x42); 468 spca506_WriteI2c(gspca_dev, 0xff, 0x43); 469 spca506_WriteI2c(gspca_dev, 0xff, 0x44); 470 spca506_WriteI2c(gspca_dev, 0xff, 0x45); 471 spca506_WriteI2c(gspca_dev, 0xff, 0x46); 472 spca506_WriteI2c(gspca_dev, 0xff, 0x47); 473 spca506_WriteI2c(gspca_dev, 0xff, 0x48); 474 spca506_WriteI2c(gspca_dev, 0xff, 0x49); 475 spca506_WriteI2c(gspca_dev, 0xff, 0x4a); 476 spca506_WriteI2c(gspca_dev, 0xff, 0x4b); 477 spca506_WriteI2c(gspca_dev, 0xff, 0x4c); 478 spca506_WriteI2c(gspca_dev, 0xff, 0x4d); 479 spca506_WriteI2c(gspca_dev, 0xff, 0x4e); 480 spca506_WriteI2c(gspca_dev, 0xff, 0x4f); 481 spca506_WriteI2c(gspca_dev, 0xff, 0x50); 482 spca506_WriteI2c(gspca_dev, 0xff, 0x51); 483 spca506_WriteI2c(gspca_dev, 0xff, 0x52); 484 spca506_WriteI2c(gspca_dev, 0xff, 0x53); 485 spca506_WriteI2c(gspca_dev, 0xff, 0x54); 486 spca506_WriteI2c(gspca_dev, 0xff, 0x55); 487 spca506_WriteI2c(gspca_dev, 0xff, 0x56); 488 spca506_WriteI2c(gspca_dev, 0xff, 0x57); 489 spca506_WriteI2c(gspca_dev, 0x00, 0x58); 490 spca506_WriteI2c(gspca_dev, 0x54, 0x59); 491 spca506_WriteI2c(gspca_dev, 0x07, 0x5a); 492 spca506_WriteI2c(gspca_dev, 0x83, 0x5b); 493 spca506_WriteI2c(gspca_dev, 0x00, 0x5c); 494 spca506_WriteI2c(gspca_dev, 0x00, 0x5d); 495 spca506_WriteI2c(gspca_dev, 0x00, 0x5e); 496 spca506_WriteI2c(gspca_dev, 0x00, 0x5f); 497 spca506_WriteI2c(gspca_dev, 0x00, 0x60); 498 spca506_WriteI2c(gspca_dev, 0x05, 0x61); 499 spca506_WriteI2c(gspca_dev, 0x9f, 0x62); 500 /**************************************/ 501 reg_w(dev, 0x05, 0x00, 0x0003); 502 reg_w(dev, 0x05, 0x00, 0x0004); 503 reg_w(dev, 0x03, 0x10, 0x0001); 504 reg_w(dev, 0x03, 0x78, 0x0000); 505 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 506 case 0: 507 spca506_Setsize(gspca_dev, 0, 0x10, 0x10); 508 break; 509 case 1: 510 spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a); 511 break; 512 case 2: 513 spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c); 514 break; 515 case 4: 516 spca506_Setsize(gspca_dev, 4, 0x34, 0x34); 517 break; 518 default: 519/* case 5: */ 520 spca506_Setsize(gspca_dev, 5, 0x40, 0x40); 521 break; 522 } 523 524 /* compress setting and size */ 525 /* set i2c luma */ 526 reg_w(dev, 0x02, 0x01, 0x0000); 527 reg_w(dev, 0x03, 0x12, 0x0000); 528 reg_r(gspca_dev, 0x04, 0x0001, 2); 529 PDEBUG(D_STREAM, "webcam started"); 530 spca506_GetNormeInput(gspca_dev, &norme, &channel); 531 spca506_SetNormeInput(gspca_dev, norme, channel); 532 return 0; 533} 534 535static void sd_stopN(struct gspca_dev *gspca_dev) 536{ 537 struct usb_device *dev = gspca_dev->dev; 538 539 reg_w(dev, 0x02, 0x00, 0x0000); 540 reg_w(dev, 0x03, 0x00, 0x0004); 541 reg_w(dev, 0x03, 0x00, 0x0003); 542} 543 544static void sd_pkt_scan(struct gspca_dev *gspca_dev, 545 u8 *data, /* isoc packet */ 546 int len) /* iso packet length */ 547{ 548 switch (data[0]) { 549 case 0: /* start of frame */ 550 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 551 data += SPCA50X_OFFSET_DATA; 552 len -= SPCA50X_OFFSET_DATA; 553 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 554 break; 555 case 0xff: /* drop */ 556/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 557 break; 558 default: 559 data += 1; 560 len -= 1; 561 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 562 break; 563 } 564} 565 566static void setbrightness(struct gspca_dev *gspca_dev) 567{ 568 struct sd *sd = (struct sd *) gspca_dev; 569 570 spca506_Initi2c(gspca_dev); 571 spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright); 572 spca506_WriteI2c(gspca_dev, 0x01, 0x09); 573} 574 575static void setcontrast(struct gspca_dev *gspca_dev) 576{ 577 struct sd *sd = (struct sd *) gspca_dev; 578 579 spca506_Initi2c(gspca_dev); 580 spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast); 581 spca506_WriteI2c(gspca_dev, 0x01, 0x09); 582} 583 584static void setcolors(struct gspca_dev *gspca_dev) 585{ 586 struct sd *sd = (struct sd *) gspca_dev; 587 588 spca506_Initi2c(gspca_dev); 589 spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation); 590 spca506_WriteI2c(gspca_dev, 0x01, 0x09); 591} 592 593static void sethue(struct gspca_dev *gspca_dev) 594{ 595 struct sd *sd = (struct sd *) gspca_dev; 596 597 spca506_Initi2c(gspca_dev); 598 spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue); 599 spca506_WriteI2c(gspca_dev, 0x01, 0x09); 600} 601 602static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 603{ 604 struct sd *sd = (struct sd *) gspca_dev; 605 606 sd->brightness = val; 607 if (gspca_dev->streaming) 608 setbrightness(gspca_dev); 609 return 0; 610} 611 612static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 613{ 614 struct sd *sd = (struct sd *) gspca_dev; 615 616 *val = sd->brightness; 617 return 0; 618} 619 620static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 621{ 622 struct sd *sd = (struct sd *) gspca_dev; 623 624 sd->contrast = val; 625 if (gspca_dev->streaming) 626 setcontrast(gspca_dev); 627 return 0; 628} 629 630static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 631{ 632 struct sd *sd = (struct sd *) gspca_dev; 633 634 *val = sd->contrast; 635 return 0; 636} 637 638static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) 639{ 640 struct sd *sd = (struct sd *) gspca_dev; 641 642 sd->colors = val; 643 if (gspca_dev->streaming) 644 setcolors(gspca_dev); 645 return 0; 646} 647 648static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 649{ 650 struct sd *sd = (struct sd *) gspca_dev; 651 652 *val = sd->colors; 653 return 0; 654} 655 656static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) 657{ 658 struct sd *sd = (struct sd *) gspca_dev; 659 660 sd->hue = val; 661 if (gspca_dev->streaming) 662 sethue(gspca_dev); 663 return 0; 664} 665 666static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) 667{ 668 struct sd *sd = (struct sd *) gspca_dev; 669 670 *val = sd->hue; 671 return 0; 672} 673 674/* sub-driver description */ 675static const struct sd_desc sd_desc = { 676 .name = MODULE_NAME, 677 .ctrls = sd_ctrls, 678 .nctrls = ARRAY_SIZE(sd_ctrls), 679 .config = sd_config, 680 .init = sd_init, 681 .start = sd_start, 682 .stopN = sd_stopN, 683 .pkt_scan = sd_pkt_scan, 684}; 685 686/* -- module initialisation -- */ 687static const struct usb_device_id device_table[] __devinitconst = { 688 {USB_DEVICE(0x06e1, 0xa190)}, 689 {USB_DEVICE(0x0734, 0x043b)}, 690 {USB_DEVICE(0x99fa, 0x8988)}, 691 {} 692}; 693MODULE_DEVICE_TABLE(usb, device_table); 694 695/* -- device connect -- */ 696static int __devinit sd_probe(struct usb_interface *intf, 697 const struct usb_device_id *id) 698{ 699 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 700 THIS_MODULE); 701} 702 703static struct usb_driver sd_driver = { 704 .name = MODULE_NAME, 705 .id_table = device_table, 706 .probe = sd_probe, 707 .disconnect = gspca_disconnect, 708#ifdef CONFIG_PM 709 .suspend = gspca_suspend, 710 .resume = gspca_resume, 711#endif 712}; 713 714/* -- module insert / remove -- */ 715static int __init sd_mod_init(void) 716{ 717 int ret; 718 ret = usb_register(&sd_driver); 719 if (ret < 0) 720 return ret; 721 PDEBUG(D_PROBE, "registered"); 722 return 0; 723} 724static void __exit sd_mod_exit(void) 725{ 726 usb_deregister(&sd_driver); 727 PDEBUG(D_PROBE, "deregistered"); 728} 729 730module_init(sd_mod_init); 731module_exit(sd_mod_exit); 732