1/* 2 * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004) 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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 23#define MODULE_NAME "etoms" 24 25#include "gspca.h" 26 27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 28MODULE_DESCRIPTION("Etoms 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 unsigned char autogain; 39 40 char sensor; 41#define SENSOR_PAS106 0 42#define SENSOR_TAS5130CXX 1 43 signed char ag_cnt; 44#define AG_CNT_START 13 45}; 46 47/* V4L2 controls supported by the driver */ 48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 54static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 55static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 56 57static const struct ctrl sd_ctrls[] = { 58 { 59 { 60 .id = V4L2_CID_BRIGHTNESS, 61 .type = V4L2_CTRL_TYPE_INTEGER, 62 .name = "Brightness", 63 .minimum = 1, 64 .maximum = 127, 65 .step = 1, 66#define BRIGHTNESS_DEF 63 67 .default_value = BRIGHTNESS_DEF, 68 }, 69 .set = sd_setbrightness, 70 .get = sd_getbrightness, 71 }, 72 { 73 { 74 .id = V4L2_CID_CONTRAST, 75 .type = V4L2_CTRL_TYPE_INTEGER, 76 .name = "Contrast", 77 .minimum = 0, 78 .maximum = 255, 79 .step = 1, 80#define CONTRAST_DEF 127 81 .default_value = CONTRAST_DEF, 82 }, 83 .set = sd_setcontrast, 84 .get = sd_getcontrast, 85 }, 86#define COLOR_IDX 2 87 { 88 { 89 .id = V4L2_CID_SATURATION, 90 .type = V4L2_CTRL_TYPE_INTEGER, 91 .name = "Color", 92 .minimum = 0, 93 .maximum = 15, 94 .step = 1, 95#define COLOR_DEF 7 96 .default_value = COLOR_DEF, 97 }, 98 .set = sd_setcolors, 99 .get = sd_getcolors, 100 }, 101 { 102 { 103 .id = V4L2_CID_AUTOGAIN, 104 .type = V4L2_CTRL_TYPE_BOOLEAN, 105 .name = "Auto Gain", 106 .minimum = 0, 107 .maximum = 1, 108 .step = 1, 109#define AUTOGAIN_DEF 1 110 .default_value = AUTOGAIN_DEF, 111 }, 112 .set = sd_setautogain, 113 .get = sd_getautogain, 114 }, 115}; 116 117static const struct v4l2_pix_format vga_mode[] = { 118 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 119 .bytesperline = 320, 120 .sizeimage = 320 * 240, 121 .colorspace = V4L2_COLORSPACE_SRGB, 122 .priv = 1}, 123/* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 124 .bytesperline = 640, 125 .sizeimage = 640 * 480, 126 .colorspace = V4L2_COLORSPACE_SRGB, 127 .priv = 0}, */ 128}; 129 130static const struct v4l2_pix_format sif_mode[] = { 131 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 132 .bytesperline = 176, 133 .sizeimage = 176 * 144, 134 .colorspace = V4L2_COLORSPACE_SRGB, 135 .priv = 1}, 136 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 137 .bytesperline = 352, 138 .sizeimage = 352 * 288, 139 .colorspace = V4L2_COLORSPACE_SRGB, 140 .priv = 0}, 141}; 142 143#define ETOMS_ALT_SIZE_1000 12 144 145#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */ 146#define ET_GPIO_OUT 0x05 /* Only IO data */ 147#define ET_GPIO_IN 0x06 /* Read Only IO data */ 148#define ET_RESET_ALL 0x03 149#define ET_ClCK 0x01 150#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */ 151 152#define ET_COMP 0x12 /* Compression register */ 153#define ET_MAXQt 0x13 154#define ET_MINQt 0x14 155#define ET_COMP_VAL0 0x02 156#define ET_COMP_VAL1 0x03 157 158#define ET_REG1d 0x1d 159#define ET_REG1e 0x1e 160#define ET_REG1f 0x1f 161#define ET_REG20 0x20 162#define ET_REG21 0x21 163#define ET_REG22 0x22 164#define ET_REG23 0x23 165#define ET_REG24 0x24 166#define ET_REG25 0x25 167/* base registers for luma calculation */ 168#define ET_LUMA_CENTER 0x39 169 170#define ET_G_RED 0x4d 171#define ET_G_GREEN1 0x4e 172#define ET_G_BLUE 0x4f 173#define ET_G_GREEN2 0x50 174#define ET_G_GR_H 0x51 175#define ET_G_GB_H 0x52 176 177#define ET_O_RED 0x34 178#define ET_O_GREEN1 0x35 179#define ET_O_BLUE 0x36 180#define ET_O_GREEN2 0x37 181 182#define ET_SYNCHRO 0x68 183#define ET_STARTX 0x69 184#define ET_STARTY 0x6a 185#define ET_WIDTH_LOW 0x6b 186#define ET_HEIGTH_LOW 0x6c 187#define ET_W_H_HEIGTH 0x6d 188 189#define ET_REG6e 0x6e /* OBW */ 190#define ET_REG6f 0x6f /* OBW */ 191#define ET_REG70 0x70 /* OBW_AWB */ 192#define ET_REG71 0x71 /* OBW_AWB */ 193#define ET_REG72 0x72 /* OBW_AWB */ 194#define ET_REG73 0x73 /* Clkdelay ns */ 195#define ET_REG74 0x74 /* test pattern */ 196#define ET_REG75 0x75 /* test pattern */ 197 198#define ET_I2C_CLK 0x8c 199#define ET_PXL_CLK 0x60 200 201#define ET_I2C_BASE 0x89 202#define ET_I2C_COUNT 0x8a 203#define ET_I2C_PREFETCH 0x8b 204#define ET_I2C_REG 0x88 205#define ET_I2C_DATA7 0x87 206#define ET_I2C_DATA6 0x86 207#define ET_I2C_DATA5 0x85 208#define ET_I2C_DATA4 0x84 209#define ET_I2C_DATA3 0x83 210#define ET_I2C_DATA2 0x82 211#define ET_I2C_DATA1 0x81 212#define ET_I2C_DATA0 0x80 213 214#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */ 215#define PAS106_REG3 0x03 /* line/frame H [11..4] */ 216#define PAS106_REG4 0x04 /* line/frame L [3..0] */ 217#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */ 218#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */ 219#define PAS106_REG7 0x07 /* signbit Dac (default 0) */ 220#define PAS106_REG9 0x09 221#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */ 222#define PAS106_REG13 0x13 /* end i2c write */ 223 224static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; 225 226static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; 227 228static const __u8 I2c3[] = { 0x12, 0x05 }; 229 230static const __u8 I2c4[] = { 0x41, 0x08 }; 231 232/* read 'len' bytes to gspca_dev->usb_buf */ 233static void reg_r(struct gspca_dev *gspca_dev, 234 __u16 index, 235 __u16 len) 236{ 237 struct usb_device *dev = gspca_dev->dev; 238 239#ifdef GSPCA_DEBUG 240 if (len > USB_BUF_SZ) { 241 pr_err("reg_r: buffer overflow\n"); 242 return; 243 } 244#endif 245 usb_control_msg(dev, 246 usb_rcvctrlpipe(dev, 0), 247 0, 248 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 249 0, 250 index, gspca_dev->usb_buf, len, 500); 251 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", 252 index, gspca_dev->usb_buf[0]); 253} 254 255static void reg_w_val(struct gspca_dev *gspca_dev, 256 __u16 index, 257 __u8 val) 258{ 259 struct usb_device *dev = gspca_dev->dev; 260 261 gspca_dev->usb_buf[0] = val; 262 usb_control_msg(dev, 263 usb_sndctrlpipe(dev, 0), 264 0, 265 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 266 0, 267 index, gspca_dev->usb_buf, 1, 500); 268} 269 270static void reg_w(struct gspca_dev *gspca_dev, 271 __u16 index, 272 const __u8 *buffer, 273 __u16 len) 274{ 275 struct usb_device *dev = gspca_dev->dev; 276 277#ifdef GSPCA_DEBUG 278 if (len > USB_BUF_SZ) { 279 pr_err("reg_w: buffer overflow\n"); 280 return; 281 } 282 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); 283#endif 284 memcpy(gspca_dev->usb_buf, buffer, len); 285 usb_control_msg(dev, 286 usb_sndctrlpipe(dev, 0), 287 0, 288 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 289 0, index, gspca_dev->usb_buf, len, 500); 290} 291 292static int i2c_w(struct gspca_dev *gspca_dev, 293 __u8 reg, 294 const __u8 *buffer, 295 int len, __u8 mode) 296{ 297 /* buffer should be [D0..D7] */ 298 __u8 ptchcount; 299 300 /* set the base address */ 301 reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); 302 /* sensor base for the pas106 */ 303 /* set count and prefetch */ 304 ptchcount = ((len & 0x07) << 4) | (mode & 0x03); 305 reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount); 306 /* set the register base */ 307 reg_w_val(gspca_dev, ET_I2C_REG, reg); 308 while (--len >= 0) 309 reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]); 310 return 0; 311} 312 313static int i2c_r(struct gspca_dev *gspca_dev, 314 __u8 reg) 315{ 316 /* set the base address */ 317 reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); 318 /* sensor base for the pas106 */ 319 /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */ 320 reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11); 321 reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */ 322 reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ 323 reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00); 324 reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */ 325 return 0; 326} 327 328static int Et_WaitStatus(struct gspca_dev *gspca_dev) 329{ 330 int retry = 10; 331 332 while (retry--) { 333 reg_r(gspca_dev, ET_ClCK, 1); 334 if (gspca_dev->usb_buf[0] != 0) 335 return 1; 336 } 337 return 0; 338} 339 340static int et_video(struct gspca_dev *gspca_dev, 341 int on) 342{ 343 int ret; 344 345 reg_w_val(gspca_dev, ET_GPIO_OUT, 346 on ? 0x10 /* startvideo - set Bit5 */ 347 : 0); /* stopvideo */ 348 ret = Et_WaitStatus(gspca_dev); 349 if (ret != 0) 350 PDEBUG(D_ERR, "timeout video on/off"); 351 return ret; 352} 353 354static void Et_init2(struct gspca_dev *gspca_dev) 355{ 356 __u8 value; 357 static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; 358 359 PDEBUG(D_STREAM, "Open Init2 ET"); 360 reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f); 361 reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10); 362 reg_r(gspca_dev, ET_GPIO_IN, 1); 363 reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ 364 reg_w_val(gspca_dev, ET_CTRL, 0x1b); 365 366 /* compression et subsampling */ 367 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) 368 value = ET_COMP_VAL1; /* 320 */ 369 else 370 value = ET_COMP_VAL0; /* 640 */ 371 reg_w_val(gspca_dev, ET_COMP, value); 372 reg_w_val(gspca_dev, ET_MAXQt, 0x1f); 373 reg_w_val(gspca_dev, ET_MINQt, 0x04); 374 /* undocumented registers */ 375 reg_w_val(gspca_dev, ET_REG1d, 0xff); 376 reg_w_val(gspca_dev, ET_REG1e, 0xff); 377 reg_w_val(gspca_dev, ET_REG1f, 0xff); 378 reg_w_val(gspca_dev, ET_REG20, 0x35); 379 reg_w_val(gspca_dev, ET_REG21, 0x01); 380 reg_w_val(gspca_dev, ET_REG22, 0x00); 381 reg_w_val(gspca_dev, ET_REG23, 0xff); 382 reg_w_val(gspca_dev, ET_REG24, 0xff); 383 reg_w_val(gspca_dev, ET_REG25, 0x0f); 384 /* colors setting */ 385 reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */ 386 reg_w_val(gspca_dev, 0x31, 0x40); 387 reg_w_val(gspca_dev, 0x32, 0x00); 388 reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */ 389 reg_w_val(gspca_dev, ET_O_GREEN1, 0x00); 390 reg_w_val(gspca_dev, ET_O_BLUE, 0x00); 391 reg_w_val(gspca_dev, ET_O_GREEN2, 0x00); 392 /*************/ 393 reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */ 394 reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); 395 reg_w_val(gspca_dev, ET_G_BLUE, 0x80); 396 reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); 397 reg_w_val(gspca_dev, ET_G_GR_H, 0x00); 398 reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */ 399 /* Window control registers */ 400 reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */ 401 reg_w_val(gspca_dev, 0x62, 0x02); 402 reg_w_val(gspca_dev, 0x63, 0x03); 403 reg_w_val(gspca_dev, 0x64, 0x14); 404 reg_w_val(gspca_dev, 0x65, 0x0e); 405 reg_w_val(gspca_dev, 0x66, 0x02); 406 reg_w_val(gspca_dev, 0x67, 0x02); 407 408 /**************************************/ 409 reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */ 410 reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ 411 reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ 412 reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80); 413 reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0); 414 reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */ 415 reg_w_val(gspca_dev, ET_REG6e, 0x86); 416 reg_w_val(gspca_dev, ET_REG6f, 0x01); 417 reg_w_val(gspca_dev, ET_REG70, 0x26); 418 reg_w_val(gspca_dev, ET_REG71, 0x7a); 419 reg_w_val(gspca_dev, ET_REG72, 0x01); 420 /* Clock Pattern registers ***************** */ 421 reg_w_val(gspca_dev, ET_REG73, 0x00); 422 reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */ 423 reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */ 424 /**********************************************/ 425 reg_w_val(gspca_dev, 0x8a, 0x20); 426 reg_w_val(gspca_dev, 0x8d, 0x0f); 427 reg_w_val(gspca_dev, 0x8e, 0x08); 428 /**************************************/ 429 reg_w_val(gspca_dev, 0x03, 0x08); 430 reg_w_val(gspca_dev, ET_PXL_CLK, 0x03); 431 reg_w_val(gspca_dev, 0x81, 0xff); 432 reg_w_val(gspca_dev, 0x80, 0x00); 433 reg_w_val(gspca_dev, 0x81, 0xff); 434 reg_w_val(gspca_dev, 0x80, 0x20); 435 reg_w_val(gspca_dev, 0x03, 0x01); 436 reg_w_val(gspca_dev, 0x03, 0x00); 437 reg_w_val(gspca_dev, 0x03, 0x08); 438 /********************************************/ 439 440/* reg_r(gspca_dev, ET_I2C_BASE, 1); 441 always 0x40 as the pas106 ??? */ 442 /* set the sensor */ 443 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) 444 value = 0x04; /* 320 */ 445 else /* 640 */ 446 value = 0x1e; /* 0x17 * setting PixelClock 447 * 0x03 mean 24/(3+1) = 6 Mhz 448 * 0x05 -> 24/(5+1) = 4 Mhz 449 * 0x0b -> 24/(11+1) = 2 Mhz 450 * 0x17 -> 24/(23+1) = 1 Mhz 451 */ 452 reg_w_val(gspca_dev, ET_PXL_CLK, value); 453 /* now set by fifo the FormatLine setting */ 454 reg_w(gspca_dev, 0x62, FormLine, 6); 455 456 /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ 457 reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */ 458 reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */ 459 /* Pedro change */ 460 /* Brightness change Brith+ decrease value */ 461 /* Brigth- increase value */ 462 /* original value = 0x70; */ 463 reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */ 464 reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ 465} 466 467static void setbrightness(struct gspca_dev *gspca_dev) 468{ 469 struct sd *sd = (struct sd *) gspca_dev; 470 int i; 471 __u8 brightness = sd->brightness; 472 473 for (i = 0; i < 4; i++) 474 reg_w_val(gspca_dev, ET_O_RED + i, brightness); 475} 476 477static void setcontrast(struct gspca_dev *gspca_dev) 478{ 479 struct sd *sd = (struct sd *) gspca_dev; 480 __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; 481 __u8 contrast = sd->contrast; 482 483 memset(RGBG, contrast, sizeof(RGBG) - 2); 484 reg_w(gspca_dev, ET_G_RED, RGBG, 6); 485} 486 487static void setcolors(struct gspca_dev *gspca_dev) 488{ 489 struct sd *sd = (struct sd *) gspca_dev; 490 __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; 491 __u8 i2cflags = 0x01; 492 /* __u8 green = 0; */ 493 __u8 colors = sd->colors; 494 495 I2cc[3] = colors; /* red */ 496 I2cc[0] = 15 - colors; /* blue */ 497 /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ 498 /* I2cc[1] = I2cc[2] = green; */ 499 if (sd->sensor == SENSOR_PAS106) { 500 i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); 501 i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1); 502 } 503/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", 504 I2cc[3], I2cc[0], green); */ 505} 506 507static void getcolors(struct gspca_dev *gspca_dev) 508{ 509 struct sd *sd = (struct sd *) gspca_dev; 510 511 if (sd->sensor == SENSOR_PAS106) { 512/* i2c_r(gspca_dev, PAS106_REG9); * blue */ 513 i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */ 514 sd->colors = gspca_dev->usb_buf[0] & 0x0f; 515 } 516} 517 518static void setautogain(struct gspca_dev *gspca_dev) 519{ 520 struct sd *sd = (struct sd *) gspca_dev; 521 522 if (sd->autogain) 523 sd->ag_cnt = AG_CNT_START; 524 else 525 sd->ag_cnt = -1; 526} 527 528static void Et_init1(struct gspca_dev *gspca_dev) 529{ 530 __u8 value; 531/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */ 532 __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; 533 /* try 1/120 0x6d 0xcd 0x40 */ 534/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00}; 535 * 1/60000 hmm ?? */ 536 537 PDEBUG(D_STREAM, "Open Init1 ET"); 538 reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7); 539 reg_r(gspca_dev, ET_GPIO_IN, 1); 540 reg_w_val(gspca_dev, ET_RESET_ALL, 1); 541 reg_w_val(gspca_dev, ET_RESET_ALL, 0); 542 reg_w_val(gspca_dev, ET_ClCK, 0x10); 543 reg_w_val(gspca_dev, ET_CTRL, 0x19); 544 /* compression et subsampling */ 545 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) 546 value = ET_COMP_VAL1; 547 else 548 value = ET_COMP_VAL0; 549 PDEBUG(D_STREAM, "Open mode %d Compression %d", 550 gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv, 551 value); 552 reg_w_val(gspca_dev, ET_COMP, value); 553 reg_w_val(gspca_dev, ET_MAXQt, 0x1d); 554 reg_w_val(gspca_dev, ET_MINQt, 0x02); 555 /* undocumented registers */ 556 reg_w_val(gspca_dev, ET_REG1d, 0xff); 557 reg_w_val(gspca_dev, ET_REG1e, 0xff); 558 reg_w_val(gspca_dev, ET_REG1f, 0xff); 559 reg_w_val(gspca_dev, ET_REG20, 0x35); 560 reg_w_val(gspca_dev, ET_REG21, 0x01); 561 reg_w_val(gspca_dev, ET_REG22, 0x00); 562 reg_w_val(gspca_dev, ET_REG23, 0xf7); 563 reg_w_val(gspca_dev, ET_REG24, 0xff); 564 reg_w_val(gspca_dev, ET_REG25, 0x07); 565 /* colors setting */ 566 reg_w_val(gspca_dev, ET_G_RED, 0x80); 567 reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); 568 reg_w_val(gspca_dev, ET_G_BLUE, 0x80); 569 reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); 570 reg_w_val(gspca_dev, ET_G_GR_H, 0x00); 571 reg_w_val(gspca_dev, ET_G_GB_H, 0x00); 572 /* Window control registers */ 573 reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0); 574 reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */ 575 reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */ 576 reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60); 577 reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20); 578 reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50); 579 reg_w_val(gspca_dev, ET_REG6e, 0x86); 580 reg_w_val(gspca_dev, ET_REG6f, 0x01); 581 reg_w_val(gspca_dev, ET_REG70, 0x86); 582 reg_w_val(gspca_dev, ET_REG71, 0x14); 583 reg_w_val(gspca_dev, ET_REG72, 0x00); 584 /* Clock Pattern registers */ 585 reg_w_val(gspca_dev, ET_REG73, 0x00); 586 reg_w_val(gspca_dev, ET_REG74, 0x00); 587 reg_w_val(gspca_dev, ET_REG75, 0x0a); 588 reg_w_val(gspca_dev, ET_I2C_CLK, 0x04); 589 reg_w_val(gspca_dev, ET_PXL_CLK, 0x01); 590 /* set the sensor */ 591 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 592 I2c0[0] = 0x06; 593 i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); 594 i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); 595 value = 0x06; 596 i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); 597 i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); 598 /* value = 0x1f; */ 599 value = 0x04; 600 i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); 601 } else { 602 I2c0[0] = 0x0a; 603 604 i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); 605 i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); 606 value = 0x0a; 607 i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); 608 i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); 609 value = 0x04; 610 /* value = 0x10; */ 611 i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); 612 /* bit 2 enable bit 1:2 select 0 1 2 3 613 value = 0x07; * curve 0 * 614 i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1); 615 */ 616 } 617 618/* value = 0x01; */ 619/* value = 0x22; */ 620/* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */ 621 /* magnetude and sign bit for DAC */ 622 i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1); 623 /* now set by fifo the whole colors setting */ 624 reg_w(gspca_dev, ET_G_RED, GainRGBG, 6); 625 getcolors(gspca_dev); 626 setcolors(gspca_dev); 627} 628 629/* this function is called at probe time */ 630static int sd_config(struct gspca_dev *gspca_dev, 631 const struct usb_device_id *id) 632{ 633 struct sd *sd = (struct sd *) gspca_dev; 634 struct cam *cam; 635 636 cam = &gspca_dev->cam; 637 sd->sensor = id->driver_info; 638 if (sd->sensor == SENSOR_PAS106) { 639 cam->cam_mode = sif_mode; 640 cam->nmodes = ARRAY_SIZE(sif_mode); 641 } else { 642 cam->cam_mode = vga_mode; 643 cam->nmodes = ARRAY_SIZE(vga_mode); 644 gspca_dev->ctrl_dis = (1 << COLOR_IDX); 645 } 646 sd->brightness = BRIGHTNESS_DEF; 647 sd->contrast = CONTRAST_DEF; 648 sd->colors = COLOR_DEF; 649 sd->autogain = AUTOGAIN_DEF; 650 sd->ag_cnt = -1; 651 return 0; 652} 653 654/* this function is called at probe and resume time */ 655static int sd_init(struct gspca_dev *gspca_dev) 656{ 657 struct sd *sd = (struct sd *) gspca_dev; 658 659 if (sd->sensor == SENSOR_PAS106) 660 Et_init1(gspca_dev); 661 else 662 Et_init2(gspca_dev); 663 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); 664 et_video(gspca_dev, 0); /* video off */ 665 return 0; 666} 667 668/* -- start the camera -- */ 669static int sd_start(struct gspca_dev *gspca_dev) 670{ 671 struct sd *sd = (struct sd *) gspca_dev; 672 673 if (sd->sensor == SENSOR_PAS106) 674 Et_init1(gspca_dev); 675 else 676 Et_init2(gspca_dev); 677 678 setautogain(gspca_dev); 679 680 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); 681 et_video(gspca_dev, 1); /* video on */ 682 return 0; 683} 684 685static void sd_stopN(struct gspca_dev *gspca_dev) 686{ 687 et_video(gspca_dev, 0); /* video off */ 688} 689 690static __u8 Et_getgainG(struct gspca_dev *gspca_dev) 691{ 692 struct sd *sd = (struct sd *) gspca_dev; 693 694 if (sd->sensor == SENSOR_PAS106) { 695 i2c_r(gspca_dev, PAS106_REG0e); 696 PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]); 697 return gspca_dev->usb_buf[0]; 698 } 699 return 0x1f; 700} 701 702static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) 703{ 704 struct sd *sd = (struct sd *) gspca_dev; 705 706 if (sd->sensor == SENSOR_PAS106) { 707 __u8 i2cflags = 0x01; 708 709 i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); 710 i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1); 711 } 712} 713 714#define BLIMIT(bright) \ 715 (u8)((bright > 0x1f) ? 0x1f : ((bright < 4) ? 3 : bright)) 716#define LIMIT(color) \ 717 (u8)((color > 0xff) ? 0xff : ((color < 0) ? 0 : color)) 718 719static void do_autogain(struct gspca_dev *gspca_dev) 720{ 721 struct sd *sd = (struct sd *) gspca_dev; 722 __u8 luma; 723 __u8 luma_mean = 128; 724 __u8 luma_delta = 20; 725 __u8 spring = 4; 726 int Gbright; 727 __u8 r, g, b; 728 729 if (sd->ag_cnt < 0) 730 return; 731 if (--sd->ag_cnt >= 0) 732 return; 733 sd->ag_cnt = AG_CNT_START; 734 735 Gbright = Et_getgainG(gspca_dev); 736 reg_r(gspca_dev, ET_LUMA_CENTER, 4); 737 g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; 738 r = gspca_dev->usb_buf[1]; 739 b = gspca_dev->usb_buf[2]; 740 r = ((r << 8) - (r << 4) - (r << 3)) >> 10; 741 b = ((b << 7) >> 10); 742 g = ((g << 9) + (g << 7) + (g << 5)) >> 10; 743 luma = LIMIT(r + g + b); 744 PDEBUG(D_FRAM, "Etoms luma G %d", luma); 745 if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) { 746 Gbright += (luma_mean - luma) >> spring; 747 Gbright = BLIMIT(Gbright); 748 PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright); 749 Et_setgainG(gspca_dev, (__u8) Gbright); 750 } 751} 752 753#undef BLIMIT 754#undef LIMIT 755 756static void sd_pkt_scan(struct gspca_dev *gspca_dev, 757 u8 *data, /* isoc packet */ 758 int len) /* iso packet length */ 759{ 760 int seqframe; 761 762 seqframe = data[0] & 0x3f; 763 len = (int) (((data[0] & 0xc0) << 2) | data[1]); 764 if (seqframe == 0x3f) { 765 PDEBUG(D_FRAM, 766 "header packet found datalength %d !!", len); 767 PDEBUG(D_FRAM, "G %d R %d G %d B %d", 768 data[2], data[3], data[4], data[5]); 769 data += 30; 770 /* don't change datalength as the chips provided it */ 771 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 772 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 773 return; 774 } 775 if (len) { 776 data += 8; 777 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 778 } else { /* Drop Packet */ 779 gspca_dev->last_packet_type = DISCARD_PACKET; 780 } 781} 782 783static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 784{ 785 struct sd *sd = (struct sd *) gspca_dev; 786 787 sd->brightness = val; 788 if (gspca_dev->streaming) 789 setbrightness(gspca_dev); 790 return 0; 791} 792 793static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 794{ 795 struct sd *sd = (struct sd *) gspca_dev; 796 797 *val = sd->brightness; 798 return 0; 799} 800 801static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 802{ 803 struct sd *sd = (struct sd *) gspca_dev; 804 805 sd->contrast = val; 806 if (gspca_dev->streaming) 807 setcontrast(gspca_dev); 808 return 0; 809} 810 811static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 812{ 813 struct sd *sd = (struct sd *) gspca_dev; 814 815 *val = sd->contrast; 816 return 0; 817} 818 819static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) 820{ 821 struct sd *sd = (struct sd *) gspca_dev; 822 823 sd->colors = val; 824 if (gspca_dev->streaming) 825 setcolors(gspca_dev); 826 return 0; 827} 828 829static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 830{ 831 struct sd *sd = (struct sd *) gspca_dev; 832 833 *val = sd->colors; 834 return 0; 835} 836 837static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 838{ 839 struct sd *sd = (struct sd *) gspca_dev; 840 841 sd->autogain = val; 842 if (gspca_dev->streaming) 843 setautogain(gspca_dev); 844 return 0; 845} 846 847static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 848{ 849 struct sd *sd = (struct sd *) gspca_dev; 850 851 *val = sd->autogain; 852 return 0; 853} 854 855/* sub-driver description */ 856static const struct sd_desc sd_desc = { 857 .name = MODULE_NAME, 858 .ctrls = sd_ctrls, 859 .nctrls = ARRAY_SIZE(sd_ctrls), 860 .config = sd_config, 861 .init = sd_init, 862 .start = sd_start, 863 .stopN = sd_stopN, 864 .pkt_scan = sd_pkt_scan, 865 .dq_callback = do_autogain, 866}; 867 868/* -- module initialisation -- */ 869static const struct usb_device_id device_table[] = { 870 {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, 871#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE 872 {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, 873#endif 874 {} 875}; 876 877MODULE_DEVICE_TABLE(usb, device_table); 878 879/* -- device connect -- */ 880static int sd_probe(struct usb_interface *intf, 881 const struct usb_device_id *id) 882{ 883 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 884 THIS_MODULE); 885} 886 887static struct usb_driver sd_driver = { 888 .name = MODULE_NAME, 889 .id_table = device_table, 890 .probe = sd_probe, 891 .disconnect = gspca_disconnect, 892#ifdef CONFIG_PM 893 .suspend = gspca_suspend, 894 .resume = gspca_resume, 895#endif 896}; 897 898module_usb_driver(sd_driver); 899