xref: /linux/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c (revision e9f0878c4b2004ac19581274c1ae4c61ae3ca70e)
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