1/* 2 * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher 3 * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland 4 * Copyright (c) 2002, 2003 Tuukka Toivonen 5 * Copyright (c) 2008 Erik Andrén 6 * Copyright (c) 2008 Chia-I Wu 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 * P/N 861037: Sensor HDCS1000 ASIC STV0600 23 * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 24 * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express 25 * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam 26 * P/N 861075-0040: Sensor HDCS1000 ASIC 27 * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB 28 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web 29 */ 30 31#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 32 33#include "stv06xx_hdcs.h" 34 35static const struct ctrl hdcs1x00_ctrl[] = { 36 { 37 { 38 .id = V4L2_CID_EXPOSURE, 39 .type = V4L2_CTRL_TYPE_INTEGER, 40 .name = "exposure", 41 .minimum = 0x00, 42 .maximum = 0xff, 43 .step = 0x1, 44 .default_value = HDCS_DEFAULT_EXPOSURE, 45 .flags = V4L2_CTRL_FLAG_SLIDER 46 }, 47 .set = hdcs_set_exposure, 48 .get = hdcs_get_exposure 49 }, { 50 { 51 .id = V4L2_CID_GAIN, 52 .type = V4L2_CTRL_TYPE_INTEGER, 53 .name = "gain", 54 .minimum = 0x00, 55 .maximum = 0xff, 56 .step = 0x1, 57 .default_value = HDCS_DEFAULT_GAIN, 58 .flags = V4L2_CTRL_FLAG_SLIDER 59 }, 60 .set = hdcs_set_gain, 61 .get = hdcs_get_gain 62 } 63}; 64 65static struct v4l2_pix_format hdcs1x00_mode[] = { 66 { 67 HDCS_1X00_DEF_WIDTH, 68 HDCS_1X00_DEF_HEIGHT, 69 V4L2_PIX_FMT_SGRBG8, 70 V4L2_FIELD_NONE, 71 .sizeimage = 72 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, 73 .bytesperline = HDCS_1X00_DEF_WIDTH, 74 .colorspace = V4L2_COLORSPACE_SRGB, 75 .priv = 1 76 } 77}; 78 79static const struct ctrl hdcs1020_ctrl[] = { 80 { 81 { 82 .id = V4L2_CID_EXPOSURE, 83 .type = V4L2_CTRL_TYPE_INTEGER, 84 .name = "exposure", 85 .minimum = 0x00, 86 .maximum = 0xffff, 87 .step = 0x1, 88 .default_value = HDCS_DEFAULT_EXPOSURE, 89 .flags = V4L2_CTRL_FLAG_SLIDER 90 }, 91 .set = hdcs_set_exposure, 92 .get = hdcs_get_exposure 93 }, { 94 { 95 .id = V4L2_CID_GAIN, 96 .type = V4L2_CTRL_TYPE_INTEGER, 97 .name = "gain", 98 .minimum = 0x00, 99 .maximum = 0xff, 100 .step = 0x1, 101 .default_value = HDCS_DEFAULT_GAIN, 102 .flags = V4L2_CTRL_FLAG_SLIDER 103 }, 104 .set = hdcs_set_gain, 105 .get = hdcs_get_gain 106 } 107}; 108 109static struct v4l2_pix_format hdcs1020_mode[] = { 110 { 111 HDCS_1020_DEF_WIDTH, 112 HDCS_1020_DEF_HEIGHT, 113 V4L2_PIX_FMT_SGRBG8, 114 V4L2_FIELD_NONE, 115 .sizeimage = 116 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, 117 .bytesperline = HDCS_1020_DEF_WIDTH, 118 .colorspace = V4L2_COLORSPACE_SRGB, 119 .priv = 1 120 } 121}; 122 123enum hdcs_power_state { 124 HDCS_STATE_SLEEP, 125 HDCS_STATE_IDLE, 126 HDCS_STATE_RUN 127}; 128 129/* no lock? */ 130struct hdcs { 131 enum hdcs_power_state state; 132 int w, h; 133 134 /* visible area of the sensor array */ 135 struct { 136 int left, top; 137 int width, height; 138 int border; 139 } array; 140 141 struct { 142 /* Column timing overhead */ 143 u8 cto; 144 /* Column processing overhead */ 145 u8 cpo; 146 /* Row sample period constant */ 147 u16 rs; 148 /* Exposure reset duration */ 149 u16 er; 150 } exp; 151 152 int psmp; 153 u8 exp_cache, gain_cache; 154}; 155 156static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) 157{ 158 u8 regs[I2C_MAX_BYTES * 2]; 159 int i; 160 161 if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) || 162 (reg + len > 0xff))) 163 return -EINVAL; 164 165 for (i = 0; i < len; i++) { 166 regs[2 * i] = reg; 167 regs[2 * i + 1] = vals[i]; 168 /* All addresses are shifted left one bit 169 * as bit 0 toggles r/w */ 170 reg += 2; 171 } 172 173 return stv06xx_write_sensor_bytes(sd, regs, len); 174} 175 176static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state) 177{ 178 struct hdcs *hdcs = sd->sensor_priv; 179 u8 val; 180 int ret; 181 182 if (hdcs->state == state) 183 return 0; 184 185 /* we need to go idle before running or sleeping */ 186 if (hdcs->state != HDCS_STATE_IDLE) { 187 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); 188 if (ret) 189 return ret; 190 } 191 192 hdcs->state = HDCS_STATE_IDLE; 193 194 if (state == HDCS_STATE_IDLE) 195 return 0; 196 197 switch (state) { 198 case HDCS_STATE_SLEEP: 199 val = HDCS_SLEEP_MODE; 200 break; 201 202 case HDCS_STATE_RUN: 203 val = HDCS_RUN_ENABLE; 204 break; 205 206 default: 207 return -EINVAL; 208 } 209 210 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); 211 212 /* Update the state if the write succeeded */ 213 if (!ret) 214 hdcs->state = state; 215 216 return ret; 217} 218 219static int hdcs_reset(struct sd *sd) 220{ 221 struct hdcs *hdcs = sd->sensor_priv; 222 int err; 223 224 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1); 225 if (err < 0) 226 return err; 227 228 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); 229 if (err < 0) 230 hdcs->state = HDCS_STATE_IDLE; 231 232 return err; 233} 234 235static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 236{ 237 struct sd *sd = (struct sd *) gspca_dev; 238 struct hdcs *hdcs = sd->sensor_priv; 239 240 *val = hdcs->exp_cache; 241 242 return 0; 243} 244 245static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 246{ 247 struct sd *sd = (struct sd *) gspca_dev; 248 struct hdcs *hdcs = sd->sensor_priv; 249 int rowexp, srowexp; 250 int max_srowexp; 251 /* Column time period */ 252 int ct; 253 /* Column processing period */ 254 int cp; 255 /* Row processing period */ 256 int rp; 257 /* Minimum number of column timing periods 258 within the column processing period */ 259 int mnct; 260 int cycles, err; 261 u8 exp[14]; 262 263 val &= 0xff; 264 hdcs->exp_cache = val; 265 266 cycles = val * HDCS_CLK_FREQ_MHZ * 257; 267 268 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); 269 cp = hdcs->exp.cto + (hdcs->w * ct / 2); 270 271 /* the cycles one row takes */ 272 rp = hdcs->exp.rs + cp; 273 274 rowexp = cycles / rp; 275 276 /* the remaining cycles */ 277 cycles -= rowexp * rp; 278 279 /* calculate sub-row exposure */ 280 if (IS_1020(sd)) { 281 /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */ 282 srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct; 283 284 mnct = (hdcs->exp.er + 12 + ct - 1) / ct; 285 max_srowexp = hdcs->w - mnct; 286 } else { 287 /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */ 288 srowexp = cp - hdcs->exp.er - 6 - cycles; 289 290 mnct = (hdcs->exp.er + 5 + ct - 1) / ct; 291 max_srowexp = cp - mnct * ct - 1; 292 } 293 294 if (srowexp < 0) 295 srowexp = 0; 296 else if (srowexp > max_srowexp) 297 srowexp = max_srowexp; 298 299 if (IS_1020(sd)) { 300 exp[0] = HDCS20_CONTROL; 301 exp[1] = 0x00; /* Stop streaming */ 302 exp[2] = HDCS_ROWEXPL; 303 exp[3] = rowexp & 0xff; 304 exp[4] = HDCS_ROWEXPH; 305 exp[5] = rowexp >> 8; 306 exp[6] = HDCS20_SROWEXP; 307 exp[7] = (srowexp >> 2) & 0xff; 308 exp[8] = HDCS20_ERROR; 309 exp[9] = 0x10; /* Clear exposure error flag*/ 310 exp[10] = HDCS20_CONTROL; 311 exp[11] = 0x04; /* Restart streaming */ 312 err = stv06xx_write_sensor_bytes(sd, exp, 6); 313 } else { 314 exp[0] = HDCS00_CONTROL; 315 exp[1] = 0x00; /* Stop streaming */ 316 exp[2] = HDCS_ROWEXPL; 317 exp[3] = rowexp & 0xff; 318 exp[4] = HDCS_ROWEXPH; 319 exp[5] = rowexp >> 8; 320 exp[6] = HDCS00_SROWEXPL; 321 exp[7] = srowexp & 0xff; 322 exp[8] = HDCS00_SROWEXPH; 323 exp[9] = srowexp >> 8; 324 exp[10] = HDCS_STATUS; 325 exp[11] = 0x10; /* Clear exposure error flag*/ 326 exp[12] = HDCS00_CONTROL; 327 exp[13] = 0x04; /* Restart streaming */ 328 err = stv06xx_write_sensor_bytes(sd, exp, 7); 329 if (err < 0) 330 return err; 331 } 332 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d", 333 val, rowexp, srowexp); 334 return err; 335} 336 337static int hdcs_set_gains(struct sd *sd, u8 g) 338{ 339 struct hdcs *hdcs = sd->sensor_priv; 340 int err; 341 u8 gains[4]; 342 343 hdcs->gain_cache = g; 344 345 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ 346 if (g > 127) 347 g = 0x80 | (g / 2); 348 349 gains[0] = g; 350 gains[1] = g; 351 gains[2] = g; 352 gains[3] = g; 353 354 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); 355 return err; 356} 357 358static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 359{ 360 struct sd *sd = (struct sd *) gspca_dev; 361 struct hdcs *hdcs = sd->sensor_priv; 362 363 *val = hdcs->gain_cache; 364 365 return 0; 366} 367 368static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) 369{ 370 PDEBUG(D_V4L2, "Writing gain %d", val); 371 return hdcs_set_gains((struct sd *) gspca_dev, 372 val & 0xff); 373} 374 375static int hdcs_set_size(struct sd *sd, 376 unsigned int width, unsigned int height) 377{ 378 struct hdcs *hdcs = sd->sensor_priv; 379 u8 win[4]; 380 unsigned int x, y; 381 int err; 382 383 /* must be multiple of 4 */ 384 width = (width + 3) & ~0x3; 385 height = (height + 3) & ~0x3; 386 387 if (width > hdcs->array.width) 388 width = hdcs->array.width; 389 390 if (IS_1020(sd)) { 391 /* the borders are also invalid */ 392 if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP 393 > hdcs->array.height) 394 height = hdcs->array.height - 2 * hdcs->array.border - 395 HDCS_1020_BOTTOM_Y_SKIP; 396 397 y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2 398 + hdcs->array.top; 399 } else { 400 if (height > hdcs->array.height) 401 height = hdcs->array.height; 402 403 y = hdcs->array.top + (hdcs->array.height - height) / 2; 404 } 405 406 x = hdcs->array.left + (hdcs->array.width - width) / 2; 407 408 win[0] = y / 4; 409 win[1] = x / 4; 410 win[2] = (y + height) / 4 - 1; 411 win[3] = (x + width) / 4 - 1; 412 413 err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4); 414 if (err < 0) 415 return err; 416 417 /* Update the current width and height */ 418 hdcs->w = width; 419 hdcs->h = height; 420 return err; 421} 422 423static int hdcs_probe_1x00(struct sd *sd) 424{ 425 struct hdcs *hdcs; 426 u16 sensor; 427 int ret; 428 429 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); 430 if (ret < 0 || sensor != 0x08) 431 return -ENODEV; 432 433 pr_info("HDCS-1000/1100 sensor detected\n"); 434 435 sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; 436 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); 437 sd->desc.ctrls = hdcs1x00_ctrl; 438 sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl); 439 440 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); 441 if (!hdcs) 442 return -ENOMEM; 443 444 hdcs->array.left = 8; 445 hdcs->array.top = 8; 446 hdcs->array.width = HDCS_1X00_DEF_WIDTH; 447 hdcs->array.height = HDCS_1X00_DEF_HEIGHT; 448 hdcs->array.border = 4; 449 450 hdcs->exp.cto = 4; 451 hdcs->exp.cpo = 2; 452 hdcs->exp.rs = 186; 453 hdcs->exp.er = 100; 454 455 /* 456 * Frame rate on HDCS-1000 with STV600 depends on PSMP: 457 * 4 = doesn't work at all 458 * 5 = 7.8 fps, 459 * 6 = 6.9 fps, 460 * 8 = 6.3 fps, 461 * 10 = 5.5 fps, 462 * 15 = 4.4 fps, 463 * 31 = 2.8 fps 464 * 465 * Frame rate on HDCS-1000 with STV602 depends on PSMP: 466 * 15 = doesn't work at all 467 * 18 = doesn't work at all 468 * 19 = 7.3 fps 469 * 20 = 7.4 fps 470 * 21 = 7.4 fps 471 * 22 = 7.4 fps 472 * 24 = 6.3 fps 473 * 30 = 5.4 fps 474 */ 475 hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5; 476 477 sd->sensor_priv = hdcs; 478 479 return 0; 480} 481 482static int hdcs_probe_1020(struct sd *sd) 483{ 484 struct hdcs *hdcs; 485 u16 sensor; 486 int ret; 487 488 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); 489 if (ret < 0 || sensor != 0x10) 490 return -ENODEV; 491 492 pr_info("HDCS-1020 sensor detected\n"); 493 494 sd->gspca_dev.cam.cam_mode = hdcs1020_mode; 495 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); 496 sd->desc.ctrls = hdcs1020_ctrl; 497 sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl); 498 499 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); 500 if (!hdcs) 501 return -ENOMEM; 502 503 /* 504 * From Andrey's test image: looks like HDCS-1020 upper-left 505 * visible pixel is at 24,8 (y maybe even smaller?) and lower-right 506 * visible pixel at 375,299 (x maybe even larger?) 507 */ 508 hdcs->array.left = 24; 509 hdcs->array.top = 4; 510 hdcs->array.width = HDCS_1020_DEF_WIDTH; 511 hdcs->array.height = 304; 512 hdcs->array.border = 4; 513 514 hdcs->psmp = 6; 515 516 hdcs->exp.cto = 3; 517 hdcs->exp.cpo = 3; 518 hdcs->exp.rs = 155; 519 hdcs->exp.er = 96; 520 521 sd->sensor_priv = hdcs; 522 523 return 0; 524} 525 526static int hdcs_start(struct sd *sd) 527{ 528 PDEBUG(D_STREAM, "Starting stream"); 529 530 return hdcs_set_state(sd, HDCS_STATE_RUN); 531} 532 533static int hdcs_stop(struct sd *sd) 534{ 535 PDEBUG(D_STREAM, "Halting stream"); 536 537 return hdcs_set_state(sd, HDCS_STATE_SLEEP); 538} 539 540static void hdcs_disconnect(struct sd *sd) 541{ 542 PDEBUG(D_PROBE, "Disconnecting the sensor"); 543 kfree(sd->sensor_priv); 544} 545 546static int hdcs_init(struct sd *sd) 547{ 548 struct hdcs *hdcs = sd->sensor_priv; 549 int i, err = 0; 550 551 /* Set the STV0602AA in STV0600 emulation mode */ 552 if (sd->bridge == BRIDGE_STV602) 553 stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1); 554 555 /* Execute the bridge init */ 556 for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) { 557 err = stv06xx_write_bridge(sd, stv_bridge_init[i][0], 558 stv_bridge_init[i][1]); 559 } 560 if (err < 0) 561 return err; 562 563 /* sensor soft reset */ 564 hdcs_reset(sd); 565 566 /* Execute the sensor init */ 567 for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) { 568 err = stv06xx_write_sensor(sd, stv_sensor_init[i][0], 569 stv_sensor_init[i][1]); 570 } 571 if (err < 0) 572 return err; 573 574 /* Enable continuous frame capture, bit 2: stop when frame complete */ 575 err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3)); 576 if (err < 0) 577 return err; 578 579 /* Set PGA sample duration 580 (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */ 581 if (IS_1020(sd)) 582 err = stv06xx_write_sensor(sd, HDCS_TCTRL, 583 (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp); 584 else 585 err = stv06xx_write_sensor(sd, HDCS_TCTRL, 586 (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp); 587 if (err < 0) 588 return err; 589 590 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN); 591 if (err < 0) 592 return err; 593 594 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height); 595 if (err < 0) 596 return err; 597 598 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE); 599 return err; 600} 601 602static int hdcs_dump(struct sd *sd) 603{ 604 u16 reg, val; 605 606 pr_info("Dumping sensor registers:\n"); 607 608 for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) { 609 stv06xx_read_sensor(sd, reg, &val); 610 pr_info("reg 0x%02x = 0x%02x\n", reg, val); 611 } 612 return 0; 613} 614