pac7302.c 25.3 KB
Newer Older
1
/*
2
 * Pixart PAC7302 driver
3
 *
4 5
 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6
 *
7
 * Separated from Pixart PAC7311 library by Márton Németh
8 9
 * Camera button input handling by Márton Németh <nm127@freemail.hu>
 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
/*
 * Some documentation about various registers as determined by trial and error.
 *
 * Register page 1:
 *
 * Address	Description
 * 0x78		Global control, bit 6 controls the LED (inverted)
 *
 * Register page 3:
 *
 * Address	Description
 * 0x02		Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
 *		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
 * 0x03		Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
 * 0x04		Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
 *		63 -> ~27 fps, the 2 msb's must always be 1 !!
 * 0x05		Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
 *		1 -> ~30 fps, 2 -> ~20 fps
 * 0x0e		Exposure bits 0-7, 0-448, 0 = use full frame time
 * 0x0f		Exposure bit 8, 0-448, 448 = no exposure at all
 * 0x10		Master gain 0-31
 * 0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
 *
 * The registers are accessed in the following functions:
 *
 * Page | Register   | Function
 * -----+------------+---------------------------------------------------
 *  0   | 0x0f..0x20 | setcolors()
 *  0   | 0xa2..0xab | setbrightcont()
 *  0   | 0xc5       | setredbalance()
 *  0   | 0xc6       | setwhitebalance()
 *  0   | 0xc7       | setbluebalance()
 *  0   | 0xdc       | setbrightcont(), setcolors()
 *  3   | 0x02       | setexposure()
 *  3   | 0x10       | setgain()
 *  3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
 *  3   | 0x21       | sethvflip()
 */
64

65 66
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

67
#include <linux/input.h>
68
#include <media/v4l2-chip-ident.h>
69
#include "gspca.h"
70 71
/* Include pac common sof detection functions */
#include "pac_common.h"
72

73 74
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
		"Thomas Kaiser thomas@kaiser-linux.li");
75 76 77
MODULE_DESCRIPTION("Pixart PAC7302");
MODULE_LICENSE("GPL");

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
enum e_ctrl {
	BRIGHTNESS,
	CONTRAST,
	COLORS,
	WHITE_BALANCE,
	RED_BALANCE,
	BLUE_BALANCE,
	GAIN,
	AUTOGAIN,
	EXPOSURE,
	VFLIP,
	HFLIP,
	NCTRLS		/* number of controls */
};

93 94 95
struct sd {
	struct gspca_dev gspca_dev;		/* !! must be the first item */

96 97
	struct gspca_ctrl ctrls[NCTRLS];

98 99 100
	u8 flags;
#define FL_HFLIP 0x01		/* mirrored by default */
#define FL_VFLIP 0x02		/* vertical flipped by default */
101 102

	u8 sof_read;
103
	s8 autogain_ignore_frames;
104 105 106 107 108

	atomic_t avg_lum;
};

/* V4L2 controls supported by the driver */
109 110 111 112 113 114 115
static void setbrightcont(struct gspca_dev *gspca_dev);
static void setcolors(struct gspca_dev *gspca_dev);
static void setwhitebalance(struct gspca_dev *gspca_dev);
static void setredbalance(struct gspca_dev *gspca_dev);
static void setbluebalance(struct gspca_dev *gspca_dev);
static void setgain(struct gspca_dev *gspca_dev);
static void setexposure(struct gspca_dev *gspca_dev);
116
static void setautogain(struct gspca_dev *gspca_dev);
117
static void sethvflip(struct gspca_dev *gspca_dev);
118

119
static const struct ctrl sd_ctrls[] = {
120
[BRIGHTNESS] = {
121 122 123 124 125 126 127 128
	    {
		.id      = V4L2_CID_BRIGHTNESS,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Brightness",
		.minimum = 0,
#define BRIGHTNESS_MAX 0x20
		.maximum = BRIGHTNESS_MAX,
		.step    = 1,
129
		.default_value = 0x10,
130
	    },
131
	    .set_control = setbrightcont
132
	},
133
[CONTRAST] = {
134 135 136 137 138 139 140 141
	    {
		.id      = V4L2_CID_CONTRAST,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Contrast",
		.minimum = 0,
#define CONTRAST_MAX 255
		.maximum = CONTRAST_MAX,
		.step    = 1,
142
		.default_value = 127,
143
	    },
144
	    .set_control = setbrightcont
145
	},
146
[COLORS] = {
147 148 149 150 151 152 153 154
	    {
		.id      = V4L2_CID_SATURATION,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Saturation",
		.minimum = 0,
#define COLOR_MAX 255
		.maximum = COLOR_MAX,
		.step    = 1,
155
		.default_value = 127
156
	    },
157
	    .set_control = setcolors
158
	},
159
[WHITE_BALANCE] = {
160 161 162 163 164 165 166
	    {
		.id      = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "White Balance",
		.minimum = 0,
		.maximum = 255,
		.step    = 1,
167
		.default_value = 4,
168
	    },
169
	    .set_control = setwhitebalance
170
	},
171
[RED_BALANCE] = {
172 173 174 175 176 177 178
	    {
		.id      = V4L2_CID_RED_BALANCE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Red",
		.minimum = 0,
		.maximum = 3,
		.step    = 1,
179
		.default_value = 1,
180
	    },
181
	    .set_control = setredbalance
182
	},
183
[BLUE_BALANCE] = {
184 185 186 187 188 189 190
	    {
		.id      = V4L2_CID_BLUE_BALANCE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Blue",
		.minimum = 0,
		.maximum = 3,
		.step    = 1,
191
		.default_value = 1,
192
	    },
193
	    .set_control = setbluebalance
194
	},
195
[GAIN] = {
196 197 198 199 200
	    {
		.id      = V4L2_CID_GAIN,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Gain",
		.minimum = 0,
201
		.maximum = 255,
202 203 204 205 206
		.step    = 1,
#define GAIN_DEF 127
#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
		.default_value = GAIN_DEF,
	    },
207
	    .set_control = setgain
208
	},
209
[EXPOSURE] = {
210 211 212 213 214
	    {
		.id      = V4L2_CID_EXPOSURE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Exposure",
		.minimum = 0,
215
		.maximum = 1023,
216
		.step    = 1,
217 218
#define EXPOSURE_DEF  66  /*  33 ms / 30 fps */
#define EXPOSURE_KNEE 133 /*  66 ms / 15 fps */
219 220
		.default_value = EXPOSURE_DEF,
	    },
221
	    .set_control = setexposure
222
	},
223
[AUTOGAIN] = {
224 225 226 227 228 229 230 231 232 233
	    {
		.id      = V4L2_CID_AUTOGAIN,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Auto Gain",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
#define AUTOGAIN_DEF 1
		.default_value = AUTOGAIN_DEF,
	    },
234
	    .set_control = setautogain,
235
	},
236
[HFLIP] = {
237 238 239 240 241 242 243
	    {
		.id      = V4L2_CID_HFLIP,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Mirror",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
244
		.default_value = 0,
245
	    },
246
	    .set_control = sethvflip,
247
	},
248
[VFLIP] = {
249 250 251 252 253 254 255
	    {
		.id      = V4L2_CID_VFLIP,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Vflip",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
256
		.default_value = 0,
257
	    },
258
	    .set_control = sethvflip
259 260 261 262 263 264 265 266
	},
};

static const struct v4l2_pix_format vga_mode[] = {
	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
		.bytesperline = 640,
		.sizeimage = 640 * 480 * 3 / 8 + 590,
		.colorspace = V4L2_COLORSPACE_JPEG,
267
	},
268 269 270 271 272
};

#define LOAD_PAGE3		255
#define END_OF_SEQUENCE		0

273
static const u8 init_7302[] = {
274 275 276 277 278 279
/*	index,value */
	0xff, 0x01,		/* page 1 */
	0x78, 0x00,		/* deactivate */
	0xff, 0x01,
	0x78, 0x40,		/* led off */
};
280
static const u8 start_7302[] = {
281 282 283 284 285 286 287 288 289 290 291 292 293 294
/*	index, len, [value]* */
	0xff, 1,	0x00,		/* page 0 */
	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
			0x00, 0x00, 0x00, 0x00,
	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
	0x26, 2,	0xaa, 0xaa,
	0x2e, 1,	0x31,
	0x38, 1,	0x01,
	0x3a, 3,	0x14, 0xff, 0x5a,
	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
			0x00, 0x54, 0x11,
	0x55, 1,	0x00,
295
	0x62, 4,	0x10, 0x1e, 0x1e, 0x18,
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
	0x6b, 1,	0x00,
	0x6e, 3,	0x08, 0x06, 0x00,
	0x72, 3,	0x00, 0xff, 0x00,
	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
			0xd2, 0xeb,
	0xaf, 1,	0x02,
	0xb5, 2,	0x08, 0x08,
	0xb8, 2,	0x08, 0x88,
	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
	0xcc, 1,	0x00,
	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
			0xc1, 0xd7, 0xec,
	0xdc, 1,	0x01,
	0xff, 1,	0x01,		/* page 1 */
	0x12, 3,	0x02, 0x00, 0x01,
	0x3e, 2,	0x00, 0x00,
	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
	0x7c, 1,	0x00,
	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
			0x02, 0x00,
	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
	0xd8, 1,	0x01,
	0xdb, 2,	0x00, 0x01,
	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
	0xeb, 1,	0x00,
	0xff, 1,	0x02,		/* page 2 */
	0x22, 1,	0x00,
	0xff, 1,	0x03,		/* page 3 */
	0, LOAD_PAGE3,			/* load the page 3 */
	0x11, 1,	0x01,
	0xff, 1,	0x02,		/* page 2 */
	0x13, 1,	0x00,
	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
	0x27, 2,	0x14, 0x0c,
	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
	0x6e, 1,	0x08,
	0xff, 1,	0x01,		/* page 1 */
	0x78, 1,	0x00,
	0, END_OF_SEQUENCE		/* end of sequence */
};

#define SKIP		0xaa
/* page 3 - the value SKIP says skip the index - see reg_w_page() */
346
static const u8 page3_7302[] = {
347
	0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
348 349 350 351 352 353 354 355
	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
356
	SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
357 358 359 360 361 362 363 364 365 366 367 368
	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
	0x00
};

369
static void reg_w_buf(struct gspca_dev *gspca_dev,
370
		u8 index,
371
		  const u8 *buffer, int len)
372
{
373 374
	int ret;

375 376
	if (gspca_dev->usb_err < 0)
		return;
377
	memcpy(gspca_dev->usb_buf, buffer, len);
378
	ret = usb_control_msg(gspca_dev->dev,
379
			usb_sndctrlpipe(gspca_dev->dev, 0),
380
			0,		/* request */
381 382 383 384
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			0,		/* value */
			index, gspca_dev->usb_buf, len,
			500);
385
	if (ret < 0) {
386
		pr_err("reg_w_buf failed i: %02x error %d\n",
387
		       index, ret);
388 389
		gspca_dev->usb_err = ret;
	}
390 391 392
}


393
static void reg_w(struct gspca_dev *gspca_dev,
394 395
		u8 index,
		u8 value)
396
{
397 398
	int ret;

399 400
	if (gspca_dev->usb_err < 0)
		return;
401
	gspca_dev->usb_buf[0] = value;
402
	ret = usb_control_msg(gspca_dev->dev,
403 404 405 406 407
			usb_sndctrlpipe(gspca_dev->dev, 0),
			0,			/* request */
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			0, index, gspca_dev->usb_buf, 1,
			500);
408
	if (ret < 0) {
409
		pr_err("reg_w() failed i: %02x v: %02x error %d\n",
410
		       index, value, ret);
411 412
		gspca_dev->usb_err = ret;
	}
413 414
}

415
static void reg_w_seq(struct gspca_dev *gspca_dev,
416
		const u8 *seq, int len)
417 418
{
	while (--len >= 0) {
419
		reg_w(gspca_dev, seq[0], seq[1]);
420 421 422 423 424
		seq += 2;
	}
}

/* load the beginning of a page */
425
static void reg_w_page(struct gspca_dev *gspca_dev,
426
			const u8 *page, int len)
427 428
{
	int index;
429
	int ret = 0;
430

431 432
	if (gspca_dev->usb_err < 0)
		return;
433 434 435 436
	for (index = 0; index < len; index++) {
		if (page[index] == SKIP)		/* skip this index */
			continue;
		gspca_dev->usb_buf[0] = page[index];
437
		ret = usb_control_msg(gspca_dev->dev,
438 439 440 441 442
				usb_sndctrlpipe(gspca_dev->dev, 0),
				0,			/* request */
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
				0, index, gspca_dev->usb_buf, 1,
				500);
443
		if (ret < 0) {
444
			pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
445
			       index, page[index], ret);
446
			gspca_dev->usb_err = ret;
447 448
			break;
		}
449 450 451 452
	}
}

/* output a variable sequence */
453
static void reg_w_var(struct gspca_dev *gspca_dev,
454 455
			const u8 *seq,
			const u8 *page3, unsigned int page3_len)
456 457 458 459 460 461 462 463
{
	int index, len;

	for (;;) {
		index = *seq++;
		len = *seq++;
		switch (len) {
		case END_OF_SEQUENCE:
464
			return;
465
		case LOAD_PAGE3:
466
			reg_w_page(gspca_dev, page3, page3_len);
467 468
			break;
		default:
469
#ifdef GSPCA_DEBUG
470 471 472
			if (len > USB_BUF_SZ) {
				PDEBUG(D_ERR|D_STREAM,
					"Incorrect variable sequence");
473
				return;
474
			}
475
#endif
476 477
			while (len > 0) {
				if (len < 8) {
478
					reg_w_buf(gspca_dev,
479
						index, seq, len);
480 481 482
					seq += len;
					break;
				}
483
				reg_w_buf(gspca_dev, index, seq, 8);
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
				seq += 8;
				index += 8;
				len -= 8;
			}
		}
	}
	/* not reached */
}

/* this function is called at probe time for pac7302 */
static int sd_config(struct gspca_dev *gspca_dev,
			const struct usb_device_id *id)
{
	struct sd *sd = (struct sd *) gspca_dev;
	struct cam *cam;

	cam = &gspca_dev->cam;

	cam->cam_mode = vga_mode;	/* only 640x480 */
	cam->nmodes = ARRAY_SIZE(vga_mode);

505 506
	gspca_dev->cam.ctrls = sd->ctrls;

507
	sd->flags = id->driver_info;
508 509 510
	return 0;
}

511
static void setbrightcont(struct gspca_dev *gspca_dev)
512 513 514
{
	struct sd *sd = (struct sd *) gspca_dev;
	int i, v;
515
	static const u8 max[10] =
516 517
		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
		 0xd4, 0xec};
518
	static const u8 delta[10] =
519 520 521
		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
		 0x11, 0x0b};

522
	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
523 524
	for (i = 0; i < 10; i++) {
		v = max[i];
525
		v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX)
526
			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
527
		v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX;
528 529 530 531
		if (v < 0)
			v = 0;
		else if (v > 0xff)
			v = 0xff;
532
		reg_w(gspca_dev, 0xa2 + i, v);
533
	}
534
	reg_w(gspca_dev, 0xdc, 0x01);
535 536
}

537
static void setcolors(struct gspca_dev *gspca_dev)
538 539 540 541 542 543 544 545
{
	struct sd *sd = (struct sd *) gspca_dev;
	int i, v;
	static const int a[9] =
		{217, -212, 0, -101, 170, -67, -38, -315, 355};
	static const int b[9] =
		{19, 106, 0, 19, 106, 1, 19, 106, 1};

546 547 548
	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
	reg_w(gspca_dev, 0x11, 0x01);
	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
549
	for (i = 0; i < 9; i++) {
550
		v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i];
551 552
		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
553
	}
554
	reg_w(gspca_dev, 0xdc, 0x01);
555 556
}

557
static void setwhitebalance(struct gspca_dev *gspca_dev)
558 559 560
{
	struct sd *sd = (struct sd *) gspca_dev;

561
	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
562
	reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val);
563

564
	reg_w(gspca_dev, 0xdc, 0x01);
565 566
}

567
static void setredbalance(struct gspca_dev *gspca_dev)
568 569 570
{
	struct sd *sd = (struct sd *) gspca_dev;

571
	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
572
	reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val);
573

574
	reg_w(gspca_dev, 0xdc, 0x01);
575 576
}

577
static void setbluebalance(struct gspca_dev *gspca_dev)
578 579 580
{
	struct sd *sd = (struct sd *) gspca_dev;

581
	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
582
	reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val);
583

584
	reg_w(gspca_dev, 0xdc, 0x01);
585 586
}

587
static void setgain(struct gspca_dev *gspca_dev)
588 589 590
{
	struct sd *sd = (struct sd *) gspca_dev;

591
	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
592
	reg_w(gspca_dev, 0x10, sd->ctrls[GAIN].val >> 3);
593 594

	/* load registers to sensor (Bit 0, auto clear) */
595
	reg_w(gspca_dev, 0x11, 0x01);
596 597
}

598
static void setexposure(struct gspca_dev *gspca_dev)
599 600
{
	struct sd *sd = (struct sd *) gspca_dev;
601 602
	u8 clockdiv;
	u16 exposure;
603

604 605 606 607 608
	/*
	 * Register 2 of frame 3 contains the clock divider configuring the
	 * no fps according to the formula: 90 / reg. sd->exposure is the
	 * desired exposure time in 0.5 ms.
	 */
609
	clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000;
610

611 612 613 614 615 616
	/*
	 * Note clockdiv = 3 also works, but when running at 30 fps, depending
	 * on the scene being recorded, the camera switches to another
	 * quantization table for certain JPEG blocks, and we don't know how
	 * to decompress these blocks. So we cap the framerate at 15 fps.
	 */
617 618 619 620 621
	if (clockdiv < 6)
		clockdiv = 6;
	else if (clockdiv > 63)
		clockdiv = 63;

622 623 624 625 626
	/*
	 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
	 * Always round up, otherwise we cannot get the desired frametime
	 * using the partial frame time exposure control.
	 */
627 628 629
	if (clockdiv < 6 || clockdiv > 12)
		clockdiv = ((clockdiv + 2) / 3) * 3;

630 631 632 633
	/*
	 * frame exposure time in ms = 1000 * clockdiv / 90    ->
	 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
	 */
634
	exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv);
635 636 637
	/* 0 = use full frametime, 448 = no exposure, reverse it */
	exposure = 448 - exposure;

638
	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
639 640 641
	reg_w(gspca_dev, 0x02, clockdiv);
	reg_w(gspca_dev, 0x0e, exposure & 0xff);
	reg_w(gspca_dev, 0x0f, exposure >> 8);
642 643

	/* load registers to sensor (Bit 0, auto clear) */
644
	reg_w(gspca_dev, 0x11, 0x01);
645 646
}

647 648 649 650
static void setautogain(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;

651 652 653 654 655 656
	/*
	 * When switching to autogain set defaults to make sure
	 * we are on a valid point of the autogain gain /
	 * exposure knee graph, and give this change time to
	 * take effect before doing autogain.
	 */
657 658 659 660 661 662 663 664 665 666 667 668
	if (sd->ctrls[AUTOGAIN].val) {
		sd->ctrls[EXPOSURE].val = EXPOSURE_DEF;
		sd->ctrls[GAIN].val = GAIN_DEF;
		sd->autogain_ignore_frames =
				PAC_AUTOGAIN_IGNORE_FRAMES;
	} else {
		sd->autogain_ignore_frames = -1;
	}
	setexposure(gspca_dev);
	setgain(gspca_dev);
}

669
static void sethvflip(struct gspca_dev *gspca_dev)
670 671
{
	struct sd *sd = (struct sd *) gspca_dev;
672 673
	u8 data, hflip, vflip;

674
	hflip = sd->ctrls[HFLIP].val;
675 676
	if (sd->flags & FL_HFLIP)
		hflip = !hflip;
677
	vflip = sd->ctrls[VFLIP].val;
678 679
	if (sd->flags & FL_VFLIP)
		vflip = !vflip;
680

681
	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
682
	data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
683 684
	reg_w(gspca_dev, 0x21, data);

685
	/* load registers to sensor (Bit 0, auto clear) */
686
	reg_w(gspca_dev, 0x11, 0x01);
687 688 689 690 691
}

/* this function is called at probe and resume time for pac7302 */
static int sd_init(struct gspca_dev *gspca_dev)
{
692 693
	reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
	return gspca_dev->usb_err;
694 695 696 697 698 699
}

static int sd_start(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;

700
	reg_w_var(gspca_dev, start_7302,
701
		page3_7302, sizeof(page3_7302));
702 703 704 705 706
	setbrightcont(gspca_dev);
	setcolors(gspca_dev);
	setwhitebalance(gspca_dev);
	setredbalance(gspca_dev);
	setbluebalance(gspca_dev);
707
	setautogain(gspca_dev);
708
	sethvflip(gspca_dev);
709 710

	sd->sof_read = 0;
711
	atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val);
712 713

	/* start stream */
714 715
	reg_w(gspca_dev, 0xff, 0x01);
	reg_w(gspca_dev, 0x78, 0x01);
716

717
	return gspca_dev->usb_err;
718 719 720 721
}

static void sd_stopN(struct gspca_dev *gspca_dev)
{
722

723
	/* stop stream */
724 725
	reg_w(gspca_dev, 0xff, 0x01);
	reg_w(gspca_dev, 0x78, 0x00);
726 727 728 729 730 731 732
}

/* called on streamoff with alt 0 and on disconnect for pac7302 */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
	if (!gspca_dev->present)
		return;
733 734
	reg_w(gspca_dev, 0xff, 0x01);
	reg_w(gspca_dev, 0x78, 0x40);
735 736
}

737
#define WANT_REGULAR_AUTOGAIN
738 739
#include "autogain_functions.h"

740 741 742 743
static void do_autogain(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int avg_lum = atomic_read(&sd->avg_lum);
744 745
	int desired_lum;
	const int deadzone = 30;
746

747
	if (sd->autogain_ignore_frames < 0)
748 749
		return;

750
	if (sd->autogain_ignore_frames > 0) {
751
		sd->autogain_ignore_frames--;
752 753 754 755 756
	} else {
		desired_lum = 270 + sd->ctrls[BRIGHTNESS].val;

		auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
				deadzone, GAIN_KNEE, EXPOSURE_KNEE);
757
		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
758
	}
759 760
}

761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
/* JPEG header */
static const u8 jpeg_header[] = {
	0xff, 0xd8,	/* SOI: Start of Image */

	0xff, 0xc0,	/* SOF0: Start of Frame (Baseline DCT) */
	0x00, 0x11,	/* length = 17 bytes (including this length field) */
	0x08,		/* Precision: 8 */
	0x02, 0x80,	/* height = 640 (image rotated) */
	0x01, 0xe0,	/* width = 480 */
	0x03,		/* Number of image components: 3 */
	0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
	0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
	0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */

	0xff, 0xda,	/* SOS: Start Of Scan */
	0x00, 0x0c,	/* length = 12 bytes (including this length field) */
	0x03,		/* number of components: 3 */
	0x01, 0x00,	/* selector 1, table 0x00 */
	0x02, 0x11,	/* selector 2, table 0x11 */
	0x03, 0x11,	/* selector 3, table 0x11 */
	0x00, 0x3f,	/* Spectral selection: 0 .. 63 */
	0x00		/* Successive approximation: 0 */
783 784 785 786
};

/* this function is run at interrupt level */
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
787
			u8 *data,			/* isoc packet */
788 789 790
			int len)			/* iso packet length */
{
	struct sd *sd = (struct sd *) gspca_dev;
791
	u8 *image;
792
	u8 *sof;
793 794 795 796 797

	sof = pac_find_sof(&sd->sof_read, data, len);
	if (sof) {
		int n, lum_offset, footer_length;

798 799 800 801 802 803
		/*
		 * 6 bytes after the FF D9 EOF marker a number of lumination
		 * bytes are send corresponding to different parts of the
		 * image, the 14th and 15th byte after the EOF seem to
		 * correspond to the center of the image.
		 */
804 805 806 807 808 809
		lum_offset = 61 + sizeof pac_sof_marker;
		footer_length = 74;

		/* Finish decoding current frame */
		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
		if (n < 0) {
810
			gspca_dev->image_len += n;
811
			n = 0;
812 813
		} else {
			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
814
		}
815 816 817

		image = gspca_dev->image;
		if (image != NULL
818 819 820
		 && image[gspca_dev->image_len - 2] == 0xff
		 && image[gspca_dev->image_len - 1] == 0xd9)
			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
821 822 823 824 825 826 827 828 829 830 831 832 833

		n = sof - data;
		len -= n;
		data = sof;

		/* Get average lumination */
		if (gspca_dev->last_packet_type == LAST_PACKET &&
				n >= lum_offset)
			atomic_set(&sd->avg_lum, data[-lum_offset] +
						data[-lum_offset + 1]);

		/* Start the new frame with the jpeg header */
		/* The PAC7302 has the image rotated 90 degrees */
834 835
		gspca_frame_add(gspca_dev, FIRST_PACKET,
				jpeg_header, sizeof jpeg_header);
836
	}
837
	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
838 839
}

840 841 842 843
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
			struct v4l2_dbg_register *reg)
{
844 845
	u8 index;
	u8 value;
846

847 848 849 850
	/*
	 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
	 *		       long on the USB bus)
	 */
851 852 853 854 855 856 857
	if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
	    reg->match.addr == 0 &&
	    (reg->reg < 0x000000ff) &&
	    (reg->val <= 0x000000ff)
	) {
		/* Currently writing to page 0 is only supported. */
		/* reg_w() only supports 8bit index */
858 859
		index = reg->reg;
		value = reg->val;
860

861 862 863 864 865
		/*
		 * Note that there shall be no access to other page
		 * by any other function between the page switch and
		 * the actual register write.
		 */
866 867
		reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
		reg_w(gspca_dev, index, value);
868

869
		reg_w(gspca_dev, 0xdc, 0x01);
870
	}
871
	return gspca_dev->usb_err;
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
}

static int sd_chip_ident(struct gspca_dev *gspca_dev,
			struct v4l2_dbg_chip_ident *chip)
{
	int ret = -EINVAL;

	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
	    chip->match.addr == 0) {
		chip->revision = 0;
		chip->ident = V4L2_IDENT_UNKNOWN;
		ret = 0;
	}
	return ret;
}
#endif

889
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,		/* interrupt packet data */
			int len)		/* interrput packet length */
{
	int ret = -EINVAL;
	u8 data0, data1;

	if (len == 2) {
		data0 = data[0];
		data1 = data[1];
		if ((data0 == 0x00 && data1 == 0x11) ||
		    (data0 == 0x22 && data1 == 0x33) ||
		    (data0 == 0x44 && data1 == 0x55) ||
		    (data0 == 0x66 && data1 == 0x77) ||
		    (data0 == 0x88 && data1 == 0x99) ||
		    (data0 == 0xaa && data1 == 0xbb) ||
		    (data0 == 0xcc && data1 == 0xdd) ||
		    (data0 == 0xee && data1 == 0xff)) {
			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
			input_sync(gspca_dev->input_dev);
			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
			input_sync(gspca_dev->input_dev);
			ret = 0;
		}
	}

	return ret;
}
#endif

920
/* sub-driver description for pac7302 */
921
static const struct sd_desc sd_desc = {
922
	.name = KBUILD_MODNAME,
923 924 925 926 927 928 929 930 931
	.ctrls = sd_ctrls,
	.nctrls = ARRAY_SIZE(sd_ctrls),
	.config = sd_config,
	.init = sd_init,
	.start = sd_start,
	.stopN = sd_stopN,
	.stop0 = sd_stop0,
	.pkt_scan = sd_pkt_scan,
	.dq_callback = do_autogain,
932 933 934 935
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.set_register = sd_dbg_s_register,
	.get_chip_ident = sd_chip_ident,
#endif
936
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
937 938
	.int_pkt_scan = sd_int_pkt_scan,
#endif
939 940 941
};

/* -- module initialisation -- */
942
static const struct usb_device_id device_table[] = {
943
	{USB_DEVICE(0x06f8, 0x3009)},
944
	{USB_DEVICE(0x06f8, 0x301b)},
945 946
	{USB_DEVICE(0x093a, 0x2620)},
	{USB_DEVICE(0x093a, 0x2621)},
947 948
	{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
	{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
949
	{USB_DEVICE(0x093a, 0x2625)},
950 951
	{USB_DEVICE(0x093a, 0x2626)},
	{USB_DEVICE(0x093a, 0x2628)},
952
	{USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
953 954
	{USB_DEVICE(0x093a, 0x262a)},
	{USB_DEVICE(0x093a, 0x262c)},
955
	{USB_DEVICE(0x145f, 0x013c)},
956 957 958 959 960
	{}
};
MODULE_DEVICE_TABLE(usb, device_table);

/* -- device connect -- */
961
static int sd_probe(struct usb_interface *intf,
962 963 964 965 966 967 968
			const struct usb_device_id *id)
{
	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
				THIS_MODULE);
}

static struct usb_driver sd_driver = {
969
	.name = KBUILD_MODNAME,
970 971 972 973 974 975 976 977 978
	.id_table = device_table,
	.probe = sd_probe,
	.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume = gspca_resume,
#endif
};

979
module_usb_driver(sd_driver);