0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0019
0020 #include "stv06xx_hdcs.h"
0021
0022 static struct v4l2_pix_format hdcs1x00_mode[] = {
0023 {
0024 HDCS_1X00_DEF_WIDTH,
0025 HDCS_1X00_DEF_HEIGHT,
0026 V4L2_PIX_FMT_SGRBG8,
0027 V4L2_FIELD_NONE,
0028 .sizeimage =
0029 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
0030 .bytesperline = HDCS_1X00_DEF_WIDTH,
0031 .colorspace = V4L2_COLORSPACE_SRGB,
0032 .priv = 1
0033 }
0034 };
0035
0036 static struct v4l2_pix_format hdcs1020_mode[] = {
0037 {
0038 HDCS_1020_DEF_WIDTH,
0039 HDCS_1020_DEF_HEIGHT,
0040 V4L2_PIX_FMT_SGRBG8,
0041 V4L2_FIELD_NONE,
0042 .sizeimage =
0043 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
0044 .bytesperline = HDCS_1020_DEF_WIDTH,
0045 .colorspace = V4L2_COLORSPACE_SRGB,
0046 .priv = 1
0047 }
0048 };
0049
0050 enum hdcs_power_state {
0051 HDCS_STATE_SLEEP,
0052 HDCS_STATE_IDLE,
0053 HDCS_STATE_RUN
0054 };
0055
0056
0057 struct hdcs {
0058 enum hdcs_power_state state;
0059 int w, h;
0060
0061
0062 struct {
0063 int left, top;
0064 int width, height;
0065 int border;
0066 } array;
0067
0068 struct {
0069
0070 u8 cto;
0071
0072 u8 cpo;
0073
0074 u16 rs;
0075
0076 u16 er;
0077 } exp;
0078
0079 int psmp;
0080 };
0081
0082 static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
0083 {
0084 u8 regs[I2C_MAX_BYTES * 2];
0085 int i;
0086
0087 if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) ||
0088 (reg + len > 0xff)))
0089 return -EINVAL;
0090
0091 for (i = 0; i < len; i++) {
0092 regs[2 * i] = reg;
0093 regs[2 * i + 1] = vals[i];
0094
0095
0096 reg += 2;
0097 }
0098
0099 return stv06xx_write_sensor_bytes(sd, regs, len);
0100 }
0101
0102 static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
0103 {
0104 struct hdcs *hdcs = sd->sensor_priv;
0105 u8 val;
0106 int ret;
0107
0108 if (hdcs->state == state)
0109 return 0;
0110
0111
0112 if (hdcs->state != HDCS_STATE_IDLE) {
0113 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
0114 if (ret)
0115 return ret;
0116 }
0117
0118 hdcs->state = HDCS_STATE_IDLE;
0119
0120 if (state == HDCS_STATE_IDLE)
0121 return 0;
0122
0123 switch (state) {
0124 case HDCS_STATE_SLEEP:
0125 val = HDCS_SLEEP_MODE;
0126 break;
0127
0128 case HDCS_STATE_RUN:
0129 val = HDCS_RUN_ENABLE;
0130 break;
0131
0132 default:
0133 return -EINVAL;
0134 }
0135
0136 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
0137
0138
0139 if (!ret)
0140 hdcs->state = state;
0141
0142 return ret;
0143 }
0144
0145 static int hdcs_reset(struct sd *sd)
0146 {
0147 struct hdcs *hdcs = sd->sensor_priv;
0148 int err;
0149
0150 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1);
0151 if (err < 0)
0152 return err;
0153
0154 err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
0155 if (err < 0)
0156 hdcs->state = HDCS_STATE_IDLE;
0157
0158 return err;
0159 }
0160
0161 static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
0162 {
0163 struct sd *sd = (struct sd *) gspca_dev;
0164 struct hdcs *hdcs = sd->sensor_priv;
0165 int rowexp, srowexp;
0166 int max_srowexp;
0167
0168 int ct;
0169
0170 int cp;
0171
0172 int rp;
0173
0174
0175 int mnct;
0176 int cycles, err;
0177 u8 exp[14];
0178
0179 cycles = val * HDCS_CLK_FREQ_MHZ * 257;
0180
0181 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
0182 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
0183
0184
0185 rp = hdcs->exp.rs + cp;
0186
0187 rowexp = cycles / rp;
0188
0189
0190 cycles -= rowexp * rp;
0191
0192
0193 if (IS_1020(sd)) {
0194
0195 srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct;
0196
0197 mnct = (hdcs->exp.er + 12 + ct - 1) / ct;
0198 max_srowexp = hdcs->w - mnct;
0199 } else {
0200
0201 srowexp = cp - hdcs->exp.er - 6 - cycles;
0202
0203 mnct = (hdcs->exp.er + 5 + ct - 1) / ct;
0204 max_srowexp = cp - mnct * ct - 1;
0205 }
0206
0207 if (srowexp < 0)
0208 srowexp = 0;
0209 else if (srowexp > max_srowexp)
0210 srowexp = max_srowexp;
0211
0212 if (IS_1020(sd)) {
0213 exp[0] = HDCS20_CONTROL;
0214 exp[1] = 0x00;
0215 exp[2] = HDCS_ROWEXPL;
0216 exp[3] = rowexp & 0xff;
0217 exp[4] = HDCS_ROWEXPH;
0218 exp[5] = rowexp >> 8;
0219 exp[6] = HDCS20_SROWEXP;
0220 exp[7] = (srowexp >> 2) & 0xff;
0221 exp[8] = HDCS20_ERROR;
0222 exp[9] = 0x10;
0223 exp[10] = HDCS20_CONTROL;
0224 exp[11] = 0x04;
0225 err = stv06xx_write_sensor_bytes(sd, exp, 6);
0226 } else {
0227 exp[0] = HDCS00_CONTROL;
0228 exp[1] = 0x00;
0229 exp[2] = HDCS_ROWEXPL;
0230 exp[3] = rowexp & 0xff;
0231 exp[4] = HDCS_ROWEXPH;
0232 exp[5] = rowexp >> 8;
0233 exp[6] = HDCS00_SROWEXPL;
0234 exp[7] = srowexp & 0xff;
0235 exp[8] = HDCS00_SROWEXPH;
0236 exp[9] = srowexp >> 8;
0237 exp[10] = HDCS_STATUS;
0238 exp[11] = 0x10;
0239 exp[12] = HDCS00_CONTROL;
0240 exp[13] = 0x04;
0241 err = stv06xx_write_sensor_bytes(sd, exp, 7);
0242 if (err < 0)
0243 return err;
0244 }
0245 gspca_dbg(gspca_dev, D_CONF, "Writing exposure %d, rowexp %d, srowexp %d\n",
0246 val, rowexp, srowexp);
0247 return err;
0248 }
0249
0250 static int hdcs_set_gains(struct sd *sd, u8 g)
0251 {
0252 int err;
0253 u8 gains[4];
0254
0255
0256 if (g > 127)
0257 g = 0x80 | (g / 2);
0258
0259 gains[0] = g;
0260 gains[1] = g;
0261 gains[2] = g;
0262 gains[3] = g;
0263
0264 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
0265 return err;
0266 }
0267
0268 static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
0269 {
0270 gspca_dbg(gspca_dev, D_CONF, "Writing gain %d\n", val);
0271 return hdcs_set_gains((struct sd *) gspca_dev,
0272 val & 0xff);
0273 }
0274
0275 static int hdcs_set_size(struct sd *sd,
0276 unsigned int width, unsigned int height)
0277 {
0278 struct hdcs *hdcs = sd->sensor_priv;
0279 u8 win[4];
0280 unsigned int x, y;
0281 int err;
0282
0283
0284 width = (width + 3) & ~0x3;
0285 height = (height + 3) & ~0x3;
0286
0287 if (width > hdcs->array.width)
0288 width = hdcs->array.width;
0289
0290 if (IS_1020(sd)) {
0291
0292 if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP
0293 > hdcs->array.height)
0294 height = hdcs->array.height - 2 * hdcs->array.border -
0295 HDCS_1020_BOTTOM_Y_SKIP;
0296
0297 y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2
0298 + hdcs->array.top;
0299 } else {
0300 if (height > hdcs->array.height)
0301 height = hdcs->array.height;
0302
0303 y = hdcs->array.top + (hdcs->array.height - height) / 2;
0304 }
0305
0306 x = hdcs->array.left + (hdcs->array.width - width) / 2;
0307
0308 win[0] = y / 4;
0309 win[1] = x / 4;
0310 win[2] = (y + height) / 4 - 1;
0311 win[3] = (x + width) / 4 - 1;
0312
0313 err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4);
0314 if (err < 0)
0315 return err;
0316
0317
0318 hdcs->w = width;
0319 hdcs->h = height;
0320 return err;
0321 }
0322
0323 static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl)
0324 {
0325 struct gspca_dev *gspca_dev =
0326 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0327 int err = -EINVAL;
0328
0329 switch (ctrl->id) {
0330 case V4L2_CID_GAIN:
0331 err = hdcs_set_gain(gspca_dev, ctrl->val);
0332 break;
0333 case V4L2_CID_EXPOSURE:
0334 err = hdcs_set_exposure(gspca_dev, ctrl->val);
0335 break;
0336 }
0337 return err;
0338 }
0339
0340 static const struct v4l2_ctrl_ops hdcs_ctrl_ops = {
0341 .s_ctrl = hdcs_s_ctrl,
0342 };
0343
0344 static int hdcs_init_controls(struct sd *sd)
0345 {
0346 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
0347
0348 v4l2_ctrl_handler_init(hdl, 2);
0349 v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
0350 V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE);
0351 v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
0352 V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN);
0353 return hdl->error;
0354 }
0355
0356 static int hdcs_probe_1x00(struct sd *sd)
0357 {
0358 struct hdcs *hdcs;
0359 u16 sensor;
0360 int ret;
0361
0362 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
0363 if (ret < 0 || sensor != 0x08)
0364 return -ENODEV;
0365
0366 pr_info("HDCS-1000/1100 sensor detected\n");
0367
0368 sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
0369 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
0370
0371 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
0372 if (!hdcs)
0373 return -ENOMEM;
0374
0375 hdcs->array.left = 8;
0376 hdcs->array.top = 8;
0377 hdcs->array.width = HDCS_1X00_DEF_WIDTH;
0378 hdcs->array.height = HDCS_1X00_DEF_HEIGHT;
0379 hdcs->array.border = 4;
0380
0381 hdcs->exp.cto = 4;
0382 hdcs->exp.cpo = 2;
0383 hdcs->exp.rs = 186;
0384 hdcs->exp.er = 100;
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5;
0407
0408 sd->sensor_priv = hdcs;
0409
0410 return 0;
0411 }
0412
0413 static int hdcs_probe_1020(struct sd *sd)
0414 {
0415 struct hdcs *hdcs;
0416 u16 sensor;
0417 int ret;
0418
0419 ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
0420 if (ret < 0 || sensor != 0x10)
0421 return -ENODEV;
0422
0423 pr_info("HDCS-1020 sensor detected\n");
0424
0425 sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
0426 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
0427
0428 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
0429 if (!hdcs)
0430 return -ENOMEM;
0431
0432
0433
0434
0435
0436
0437 hdcs->array.left = 24;
0438 hdcs->array.top = 4;
0439 hdcs->array.width = HDCS_1020_DEF_WIDTH;
0440 hdcs->array.height = 304;
0441 hdcs->array.border = 4;
0442
0443 hdcs->psmp = 6;
0444
0445 hdcs->exp.cto = 3;
0446 hdcs->exp.cpo = 3;
0447 hdcs->exp.rs = 155;
0448 hdcs->exp.er = 96;
0449
0450 sd->sensor_priv = hdcs;
0451
0452 return 0;
0453 }
0454
0455 static int hdcs_start(struct sd *sd)
0456 {
0457 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
0458
0459 gspca_dbg(gspca_dev, D_STREAM, "Starting stream\n");
0460
0461 return hdcs_set_state(sd, HDCS_STATE_RUN);
0462 }
0463
0464 static int hdcs_stop(struct sd *sd)
0465 {
0466 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
0467
0468 gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
0469
0470 return hdcs_set_state(sd, HDCS_STATE_SLEEP);
0471 }
0472
0473 static int hdcs_init(struct sd *sd)
0474 {
0475 struct hdcs *hdcs = sd->sensor_priv;
0476 int i, err = 0;
0477
0478
0479 if (sd->bridge == BRIDGE_STV602)
0480 stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
0481
0482
0483 for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) {
0484 err = stv06xx_write_bridge(sd, stv_bridge_init[i][0],
0485 stv_bridge_init[i][1]);
0486 }
0487 if (err < 0)
0488 return err;
0489
0490
0491 hdcs_reset(sd);
0492
0493
0494 for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) {
0495 err = stv06xx_write_sensor(sd, stv_sensor_init[i][0],
0496 stv_sensor_init[i][1]);
0497 }
0498 if (err < 0)
0499 return err;
0500
0501
0502 err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3));
0503 if (err < 0)
0504 return err;
0505
0506
0507
0508 if (IS_1020(sd))
0509 err = stv06xx_write_sensor(sd, HDCS_TCTRL,
0510 (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
0511 else
0512 err = stv06xx_write_sensor(sd, HDCS_TCTRL,
0513 (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp);
0514 if (err < 0)
0515 return err;
0516
0517 return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
0518 }
0519
0520 static int hdcs_dump(struct sd *sd)
0521 {
0522 u16 reg, val;
0523
0524 pr_info("Dumping sensor registers:\n");
0525
0526 for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) {
0527 stv06xx_read_sensor(sd, reg, &val);
0528 pr_info("reg 0x%02x = 0x%02x\n", reg, val);
0529 }
0530 return 0;
0531 }