📄 qc-hdcs.c
字号:
I2C_SET_CHECK(HDCS_ROWEXPL, 0x7B); /* Row Exposure Low Register */ I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ if (IS_1020(qc)) { I2C_SET_CHECK(HDCS20_SROWEXP, 0x01); /* Sub-Row Exposure Register */ } else { I2C_SET_CHECK(HDCS00_SROWEXPL, 0x01<<2); I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); } if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1501, 0xC2); /* ? */ STV_SET_CHECK(0x1502, 0xB0); /* ? */ I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; /* Start isochronous streaming */ I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); /* Stop isochronous streaming */ STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ STV_SET_CHECK(0x1500, 0x1D); /* ? */ I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ STV_SETW_CHECK(0x15C1, 0x027B); /* Max. ISO packet size */ I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ I2C_SET_CHECK(HDCS_FWCOL, 0x0B); /* First Window Column Register */ I2C_SET_CHECK(HDCS_LWROW, 0x3D); /* Last Window Row Register */ I2C_SET_CHECK(HDCS_LWCOL, 0x5A); /* Last Window Column Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCB : 0x6B); /* Timing Control Register */ I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xD6); /* Horizontal Blank Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1446, 0x00); /* ? */ if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); STV_SET_CHECK(0x1446, 0x00); /* ? */ I2C_SET_CHECK(HDCS_ROWEXPL, 0x7B); /* Row Exposure Low Register */ I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ if (IS_1020(qc)) { I2C_SET_CHECK(HDCS20_SROWEXP, 0x01); /* Sub-Row Exposure Register */ } else { I2C_SET_CHECK(HDCS00_SROWEXPL, 0x01<<2); I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); } if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1501, 0xC2); /* ? */ STV_SET_CHECK(0x1502, 0xB0); /* ? */ I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; /* Start isochronous streaming */ I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ /* Stop isochronous streaming */ STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ STV_SET_CHECK(0x1500, 0x1D); /* ? */ I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ STV_SETW_CHECK(0x15C1, 0x0230); /* Max. ISO packet size */ I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ I2C_SET_CHECK(HDCS_FWCOL, 0x07); /* First Window Column Register */ I2C_SET_CHECK(HDCS_LWROW, 0x49); /* Last Window Row Register */ I2C_SET_CHECK(HDCS_LWCOL, 0x5E); /* Last Window Column Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCE : 0x6E); /* Timing Control Register */ I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xCF); /* Horizontal Blank Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1446, 0x00); /* ? */ if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); STV_SET_CHECK(0x1446, 0x00); /* ? */ I2C_SET_CHECK(HDCS_ROWEXPL, 0x62); /* Row Exposure Low Register */ I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ if (IS_1020(qc)) { I2C_SET_CHECK(HDCS20_SROWEXP, 0x1A); /* Sub-Row Exposure Register */ } else { I2C_SET_CHECK(HDCS00_SROWEXPL, 0x1A<<2); I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); } if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1501, 0xB6); /* ? */ STV_SET_CHECK(0x1502, 0xA8); /* ? */ I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; /* Start isochronous streaming */ I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); } return 0;fail: return r;}/* }}} */#endif/* {{{ [fold] hdcs_init: Initialise parameters (from Georg Acher's user module for hdcs sensor) */static int hdcs_init(struct quickcam *qc){ struct qc_sensor_data *sd = &qc->sensor_data; unsigned char control = GET_CONTROL; unsigned char config = GET_CONFIG; int r,tctrl,astrt,psmp; if (sd->compress) return -EINVAL; sd->maxwidth = IS_1020(qc) ? 352 : 360; /* CIF */ sd->maxheight = IS_1020(qc) ? 292 : 296; if (sd->subsample) { sd->maxwidth /= 2; /* QCIF */ sd->maxheight /= 2; } if ((r = qc_i2c_break(qc))<0) goto fail; /* The following setting must go into same I2C packet */#if HDCS_COMPRESSr = hdcs_compress_init(qc, 3);qc_i2c_wait(qc);qc_i2c_break(qc);qc_stv_set(qc, 0x1440, 0x00); /* Turn on/off isochronous stream */qc_i2c_set(qc, GET_CONTROL, BIT(1)); /* Stop and enter sleep mode */qc_i2c_wait(qc);if (r) PDEBUG("hdcs_compress_init(1) = %i", r);return 0;#endif STV_SET_CHECK(STV_REG23, 0); /* Set the STV0602AA in STV0600 emulation mode */ if (IS_870(qc)) STV_SET_CHECK(0x1446, 1); /* Reset the image sensor (keeping it to 1 is a problem) */ I2C_SET_CHECK(control, 1); if ((r = qc_i2c_wait(qc))<0) goto fail; I2C_SET_CHECK(control, 0); if ((r = qc_i2c_wait(qc))<0) goto fail; I2C_SET_CHECK(HDCS_STATUS, BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)); /* Clear status (writing 1 will clear the corresponding status bit) */ I2C_SET_CHECK(HDCS_IMASK, 0x00); /* Disable all interrupts */ if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(STV_REG00, 0x1D); STV_SET_CHECK(STV_REG04, 0x07); STV_SET_CHECK(STV_REG03, 0x95); STV_SET_CHECK(STV_REG23, 0); STV_SET_CHECK(STV_SCAN_RATE, 0x20); /* Larger -> slower */ STV_SETW_CHECK(STV_ISO_SIZE, 847); /* ISO-Size, 0x34F = 847 .. 0x284 = 644 */ /* Set mode */ STV_SET_CHECK(STV_Y_CTRL, 0x01); /* 0x02: half, 0x01: full */ STV_SET_CHECK(STV_X_CTRL, 0x0A); /* 0x06: half, 0x0A: full */ /* These are not good final values, which will be set in set_size */ /* However, it looks like it's best to set some values at this point nevertheless */ I2C_SET_CHECK(HDCS_FWROW, 0); /* Start at row 0 */ I2C_SET_CHECK(HDCS_FWCOL, 0); /* Start at column 0 */ I2C_SET_CHECK(HDCS_LWROW, 0x47); /* End at row 288 */ I2C_SET_CHECK(HDCS_LWCOL, 0x57); /* End at column 352 */ /* 0x07 - 0x50 */ astrt = 3; /* 0..3, doesn't seem to have any effect... hmm.. smaller is slower with subsampling */ if (!IS_1020(qc)) { /* HDCS-1000 (tctrl was 0x09, but caused some HDCS-1000 not to work) */ /* Frame rate on HDCS-1000 0x46D:0x840 depending on PSMP: * 4 = doesn't work at all * 5 = 7.8 fps, * 6 = 6.9 fps, * 8 = 6.3 fps, * 10 = 5.5 fps, * 15 = 4.4 fps, * 31 = 2.8 fps */ /* Frame rate on HDCS-1000 0x46D:0x870 depending on PSMP: * 15 = doesn't work at all * 18 = doesn't work at all * 19 = 7.3 fps * 20 = 7.4 fps * 21 = 7.4 fps * 22 = 7.4 fps * 24 = 6.3 fps * 30 = 5.4 fps */ psmp = IS_870(qc) ? 20 : 5; /* 4..31 (was 30, changed to 20) */ tctrl = (astrt<<5) | psmp; } else { /* HDCS-1020 (tctrl was 0x7E, but causes slow frame rate on HDCS-1020) */ /* Changed to 6 which should give 8.1 fps */ psmp = 6; /* 4..31 (was 9, changed to 6 to improve fps */ tctrl = (astrt<<6) | psmp; } I2C_SET_CHECK(HDCS_TCTRL, tctrl); /* Set PGA sample duration (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */ I2C_SET_CHECK(control, 0); /* FIXME:should not be anymore necessary (already done) */ I2C_SET_CHECK(HDCS_ROWEXPL, 0); I2C_SET_CHECK(HDCS_ROWEXPH, 0); if (IS_1020(qc)) { I2C_SET_CHECK(HDCS20_SROWEXP, 0); I2C_SET_CHECK(HDCS20_ERROR, BIT(0)|BIT(2)); /* Clear error conditions by writing 1 */ } else { I2C_SET_CHECK(HDCS00_SROWEXPL, 0); I2C_SET_CHECK(HDCS00_SROWEXPH, 0); } if ((r = qc_i2c_wait(qc))<0) goto fail; STV_SET_CHECK(STV_REG01, 0xB5); STV_SET_CHECK(STV_REG02, 0xA8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -