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