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 35 static struct v4l2_pix_format hdcs1x00_mode[] = { 36 { 37 HDCS_1X00_DEF_WIDTH, 38 HDCS_1X00_DEF_HEIGHT, 39 V4L2_PIX_FMT_SGRBG8, 40 V4L2_FIELD_NONE, 41 .sizeimage = 42 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, 43 .bytesperline = HDCS_1X00_DEF_WIDTH, 44 .colorspace = V4L2_COLORSPACE_SRGB, 45 .priv = 1 46 } 47 }; 48 49 static struct v4l2_pix_format hdcs1020_mode[] = { 50 { 51 HDCS_1020_DEF_WIDTH, 52 HDCS_1020_DEF_HEIGHT, 53 V4L2_PIX_FMT_SGRBG8, 54 V4L2_FIELD_NONE, 55 .sizeimage = 56 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, 57 .bytesperline = HDCS_1020_DEF_WIDTH, 58 .colorspace = V4L2_COLORSPACE_SRGB, 59 .priv = 1 60 } 61 }; 62 63 enum hdcs_power_state { 64 HDCS_STATE_SLEEP, 65 HDCS_STATE_IDLE, 66 HDCS_STATE_RUN 67 }; 68 69 /* no lock? */ 70 struct hdcs { 71 enum hdcs_power_state state; 72 int w, h; 73 74 /* visible area of the sensor array */ 75 struct { 76 int left, top; 77 int width, height; 78 int border; 79 } array; 80 81 struct { 82 /* Column timing overhead */ 83 u8 cto; 84 /* Column processing overhead */ 85 u8 cpo; 86 /* Row sample period constant */ 87 u16 rs; 88 /* Exposure reset duration */ 89 u16 er; 90 } exp; 91 92 int psmp; 93 }; 94 95 static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) 96 { 97 u8 regs[I2C_MAX_BYTES * 2]; 98 int i; 99 100 if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) || 101 (reg + len > 0xff))) 102 return -EINVAL; 103 104 for (i = 0; i < len; i++) { 105 regs[2 * i] = reg; 106 regs[2 * i + 1] = vals[i]; 107 /* All addresses are shifted left one bit 108 * as bit 0 toggles r/w */ 109 reg += 2; 110 } 111 112 return stv06xx_write_sensor_bytes(sd, regs, len); 113 } 114 115 static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state) 116 { 117 struct hdcs *hdcs = sd->sensor_priv; 118 u8 val; 119 int ret; 120 121 if (hdcs->state == state) 122 return 0; 123 124 /* we need to go idle before running or sleeping */ 125 if (hdcs->state != HDCS_STATE_IDLE) { 126 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); 127 if (ret) 128 return ret; 129 } 130 131 hdcs->state = HDCS_STATE_IDLE; 132 133 if (state == HDCS_STATE_IDLE) 134 return 0; 135 136 switch (state) { 137 case HDCS_STATE_SLEEP: 138 val = HDCS_SLEEP_MODE; 139 break; 140 141 case HDCS_STATE_RUN: 142 val = HDCS_RUN_ENABLE; 143 break; 144 145 default: 146 return -EINVAL; 147 } 148 149 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); 150 151 /* Update the state if the write succeeded */ 152 if (!ret) 153 hdcs->state = state; 154 155 return ret; 156 } 157 158 static int hdcs_reset(struct sd *sd) 159 { 160 struct hdcs *hdcs = sd->sensor_priv; 161 int err; 162 163 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1); 164 if (err < 0) 165 return err; 166 167 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); 168 if (err < 0) 169 hdcs->state = HDCS_STATE_IDLE; 170 171 return err; 172 } 173 174 static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 175 { 176 struct sd *sd = (struct sd *) gspca_dev; 177 struct hdcs *hdcs = sd->sensor_priv; 178 int rowexp, srowexp; 179 int max_srowexp; 180 /* Column time period */ 181 int ct; 182 /* Column processing period */ 183 int cp; 184 /* Row processing period */ 185 int rp; 186 /* Minimum number of column timing periods 187 within the column processing period */ 188 int mnct; 189 int cycles, err; 190 u8 exp[14]; 191 192 cycles = val * HDCS_CLK_FREQ_MHZ * 257; 193 194 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); 195 cp = hdcs->exp.cto + (hdcs->w * ct / 2); 196 197 /* the cycles one row takes */ 198 rp = hdcs->exp.rs + cp; 199 200 rowexp = cycles / rp; 201 202 /* the remaining cycles */ 203 cycles -= rowexp * rp; 204 205 /* calculate sub-row exposure */ 206 if (IS_1020(sd)) { 207 /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */ 208 srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct; 209 210 mnct = (hdcs->exp.er + 12 + ct - 1) / ct; 211 max_srowexp = hdcs->w - mnct; 212 } else { 213 /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */ 214 srowexp = cp - hdcs->exp.er - 6 - cycles; 215 216 mnct = (hdcs->exp.er + 5 + ct - 1) / ct; 217 max_srowexp = cp - mnct * ct - 1; 218 } 219 220 if (srowexp < 0) 221 srowexp = 0; 222 else if (srowexp > max_srowexp) 223 srowexp = max_srowexp; 224 225 if (IS_1020(sd)) { 226 exp[0] = HDCS20_CONTROL; 227 exp[1] = 0x00; /* Stop streaming */ 228 exp[2] = HDCS_ROWEXPL; 229 exp[3] = rowexp & 0xff; 230 exp[4] = HDCS_ROWEXPH; 231 exp[5] = rowexp >> 8; 232 exp[6] = HDCS20_SROWEXP; 233 exp[7] = (srowexp >> 2) & 0xff; 234 exp[8] = HDCS20_ERROR; 235 exp[9] = 0x10; /* Clear exposure error flag*/ 236 exp[10] = HDCS20_CONTROL; 237 exp[11] = 0x04; /* Restart streaming */ 238 err = stv06xx_write_sensor_bytes(sd, exp, 6); 239 } else { 240 exp[0] = HDCS00_CONTROL; 241 exp[1] = 0x00; /* Stop streaming */ 242 exp[2] = HDCS_ROWEXPL; 243 exp[3] = rowexp & 0xff; 244 exp[4] = HDCS_ROWEXPH; 245 exp[5] = rowexp >> 8; 246 exp[6] = HDCS00_SROWEXPL; 247 exp[7] = srowexp & 0xff; 248 exp[8] = HDCS00_SROWEXPH; 249 exp[9] = srowexp >> 8; 250 exp[10] = HDCS_STATUS; 251 exp[11] = 0x10; /* Clear exposure error flag*/ 252 exp[12] = HDCS00_CONTROL; 253 exp[13] = 0x04; /* Restart streaming */ 254 err = stv06xx_write_sensor_bytes(sd, exp, 7); 255 if (err < 0) 256 return err; 257 } 258 PDEBUG(D_CONF, "Writing exposure %d, rowexp %d, srowexp %d", 259 val, rowexp, srowexp); 260 return err; 261 } 262 263 static int hdcs_set_gains(struct sd *sd, u8 g) 264 { 265 int err; 266 u8 gains[4]; 267 268 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ 269 if (g > 127) 270 g = 0x80 | (g / 2); 271 272 gains[0] = g; 273 gains[1] = g; 274 gains[2] = g; 275 gains[3] = g; 276 277 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); 278 return err; 279 } 280 281 static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) 282 { 283 PDEBUG(D_CONF, "Writing gain %d", val); 284 return hdcs_set_gains((struct sd *) gspca_dev, 285 val & 0xff); 286 } 287 288 static int hdcs_set_size(struct sd *sd, 289 unsigned int width, unsigned int height) 290 { 291 struct hdcs *hdcs = sd->sensor_priv; 292 u8 win[4]; 293 unsigned int x, y; 294 int err; 295 296 /* must be multiple of 4 */ 297 width = (width + 3) & ~0x3; 298 height = (height + 3) & ~0x3; 299 300 if (width > hdcs->array.width) 301 width = hdcs->array.width; 302 303 if (IS_1020(sd)) { 304 /* the borders are also invalid */ 305 if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP 306 > hdcs->array.height) 307 height = hdcs->array.height - 2 * hdcs->array.border - 308 HDCS_1020_BOTTOM_Y_SKIP; 309 310 y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2 311 + hdcs->array.top; 312 } else { 313 if (height > hdcs->array.height) 314 height = hdcs->array.height; 315 316 y = hdcs->array.top + (hdcs->array.height - height) / 2; 317 } 318 319 x = hdcs->array.left + (hdcs->array.width - width) / 2; 320 321 win[0] = y / 4; 322 win[1] = x / 4; 323 win[2] = (y + height) / 4 - 1; 324 win[3] = (x + width) / 4 - 1; 325 326 err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4); 327 if (err < 0) 328 return err; 329 330 /* Update the current width and height */ 331 hdcs->w = width; 332 hdcs->h = height; 333 return err; 334 } 335 336 static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl) 337 { 338 struct gspca_dev *gspca_dev = 339 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 340 int err = -EINVAL; 341 342 switch (ctrl->id) { 343 case V4L2_CID_GAIN: 344 err = hdcs_set_gain(gspca_dev, ctrl->val); 345 break; 346 case V4L2_CID_EXPOSURE: 347 err = hdcs_set_exposure(gspca_dev, ctrl->val); 348 break; 349 } 350 return err; 351 } 352 353 static const struct v4l2_ctrl_ops hdcs_ctrl_ops = { 354 .s_ctrl = hdcs_s_ctrl, 355 }; 356 357 static int hdcs_init_controls(struct sd *sd) 358 { 359 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; 360 361 v4l2_ctrl_handler_init(hdl, 2); 362 v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops, 363 V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE); 364 v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops, 365 V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN); 366 return hdl->error; 367 } 368 369 static int hdcs_probe_1x00(struct sd *sd) 370 { 371 struct hdcs *hdcs; 372 u16 sensor; 373 int ret; 374 375 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); 376 if (ret < 0 || sensor != 0x08) 377 return -ENODEV; 378 379 pr_info("HDCS-1000/1100 sensor detected\n"); 380 381 sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; 382 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); 383 384 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); 385 if (!hdcs) 386 return -ENOMEM; 387 388 hdcs->array.left = 8; 389 hdcs->array.top = 8; 390 hdcs->array.width = HDCS_1X00_DEF_WIDTH; 391 hdcs->array.height = HDCS_1X00_DEF_HEIGHT; 392 hdcs->array.border = 4; 393 394 hdcs->exp.cto = 4; 395 hdcs->exp.cpo = 2; 396 hdcs->exp.rs = 186; 397 hdcs->exp.er = 100; 398 399 /* 400 * Frame rate on HDCS-1000 with STV600 depends on PSMP: 401 * 4 = doesn't work at all 402 * 5 = 7.8 fps, 403 * 6 = 6.9 fps, 404 * 8 = 6.3 fps, 405 * 10 = 5.5 fps, 406 * 15 = 4.4 fps, 407 * 31 = 2.8 fps 408 * 409 * Frame rate on HDCS-1000 with STV602 depends on PSMP: 410 * 15 = doesn't work at all 411 * 18 = doesn't work at all 412 * 19 = 7.3 fps 413 * 20 = 7.4 fps 414 * 21 = 7.4 fps 415 * 22 = 7.4 fps 416 * 24 = 6.3 fps 417 * 30 = 5.4 fps 418 */ 419 hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5; 420 421 sd->sensor_priv = hdcs; 422 423 return 0; 424 } 425 426 static int hdcs_probe_1020(struct sd *sd) 427 { 428 struct hdcs *hdcs; 429 u16 sensor; 430 int ret; 431 432 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); 433 if (ret < 0 || sensor != 0x10) 434 return -ENODEV; 435 436 pr_info("HDCS-1020 sensor detected\n"); 437 438 sd->gspca_dev.cam.cam_mode = hdcs1020_mode; 439 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); 440 441 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); 442 if (!hdcs) 443 return -ENOMEM; 444 445 /* 446 * From Andrey's test image: looks like HDCS-1020 upper-left 447 * visible pixel is at 24,8 (y maybe even smaller?) and lower-right 448 * visible pixel at 375,299 (x maybe even larger?) 449 */ 450 hdcs->array.left = 24; 451 hdcs->array.top = 4; 452 hdcs->array.width = HDCS_1020_DEF_WIDTH; 453 hdcs->array.height = 304; 454 hdcs->array.border = 4; 455 456 hdcs->psmp = 6; 457 458 hdcs->exp.cto = 3; 459 hdcs->exp.cpo = 3; 460 hdcs->exp.rs = 155; 461 hdcs->exp.er = 96; 462 463 sd->sensor_priv = hdcs; 464 465 return 0; 466 } 467 468 static int hdcs_start(struct sd *sd) 469 { 470 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 471 472 PDEBUG(D_STREAM, "Starting stream"); 473 474 return hdcs_set_state(sd, HDCS_STATE_RUN); 475 } 476 477 static int hdcs_stop(struct sd *sd) 478 { 479 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 480 481 PDEBUG(D_STREAM, "Halting stream"); 482 483 return hdcs_set_state(sd, HDCS_STATE_SLEEP); 484 } 485 486 static int hdcs_init(struct sd *sd) 487 { 488 struct hdcs *hdcs = sd->sensor_priv; 489 int i, err = 0; 490 491 /* Set the STV0602AA in STV0600 emulation mode */ 492 if (sd->bridge == BRIDGE_STV602) 493 stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1); 494 495 /* Execute the bridge init */ 496 for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) { 497 err = stv06xx_write_bridge(sd, stv_bridge_init[i][0], 498 stv_bridge_init[i][1]); 499 } 500 if (err < 0) 501 return err; 502 503 /* sensor soft reset */ 504 hdcs_reset(sd); 505 506 /* Execute the sensor init */ 507 for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) { 508 err = stv06xx_write_sensor(sd, stv_sensor_init[i][0], 509 stv_sensor_init[i][1]); 510 } 511 if (err < 0) 512 return err; 513 514 /* Enable continuous frame capture, bit 2: stop when frame complete */ 515 err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3)); 516 if (err < 0) 517 return err; 518 519 /* Set PGA sample duration 520 (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */ 521 if (IS_1020(sd)) 522 err = stv06xx_write_sensor(sd, HDCS_TCTRL, 523 (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp); 524 else 525 err = stv06xx_write_sensor(sd, HDCS_TCTRL, 526 (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp); 527 if (err < 0) 528 return err; 529 530 return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height); 531 } 532 533 static int hdcs_dump(struct sd *sd) 534 { 535 u16 reg, val; 536 537 pr_info("Dumping sensor registers:\n"); 538 539 for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) { 540 stv06xx_read_sensor(sd, reg, &val); 541 pr_info("reg 0x%02x = 0x%02x\n", reg, val); 542 } 543 return 0; 544 } 545