pac7311.c 22.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 *		Pixart PAC7311 library
 *		Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
 *
 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
 *
 * 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
 */

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/* Some documentation about various registers as determined by trial and error.
   When the register addresses differ between the 7202 and the 7311 the 2
   different addresses are written as 7302addr/7311addr, when one of the 2
   addresses is a - sign that register description is not valid for the
   matching IC.

   Register page 1:

   Address	Description
   -/0x08	Unknown compressor related, must always be 8 except when not
		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
   -/0x1b	Auto white balance related, bit 0 is AWB enable (inverted)
		bits 345 seem to toggle per color gains on/off (inverted)
   0x78		Global control, bit 6 controls the LED (inverted)
   -/0x80	JPEG compression ratio ? Best not touched

   Register page 3/4:

   Address	Description
   0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42
		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
43 44 45 46
   -/0x0f	Master gain 1-245, low value = high gain
   0x10/-	Master gain 0-31
   -/0x10	Another gain 0-15, limited influence (1-2x gain I guess)
   0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47 48 49
   -/0x27	Seems to toggle various gains on / off, Setting bit 7 seems to
		completely disable the analog amplification block. Set to 0x68
		for max gain, 0x14 for minimal gain.
50 51
*/

52 53
#define MODULE_NAME "pac7311"

54
#include <linux/input.h>
55 56 57 58 59 60
#include "gspca.h"

MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
MODULE_DESCRIPTION("Pixart PAC7311");
MODULE_LICENSE("GPL");

61
/* specific webcam descriptor for pac7311 */
62 63 64 65
struct sd {
	struct gspca_dev gspca_dev;		/* !! must be the first item */

	unsigned char contrast;
66 67
	unsigned char gain;
	unsigned char exposure;
68
	unsigned char autogain;
69 70
	__u8 hflip;
	__u8 vflip;
71

72 73 74 75
	u8 sof_read;
	u8 autogain_ignore_frames;

	atomic_t avg_lum;
76 77 78 79 80 81 82
};

/* V4L2 controls supported by the driver */
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
83 84 85 86
static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
87 88 89 90
static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
91

92
static const struct ctrl sd_ctrls[] = {
93
/* This control is for both the 7302 and the 7311 */
94 95 96 97 98 99
	{
	    {
		.id      = V4L2_CID_CONTRAST,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Contrast",
		.minimum = 0,
100 101
#define CONTRAST_MAX 255
		.maximum = CONTRAST_MAX,
102
		.step    = 1,
103
#define CONTRAST_DEF 127
104
		.default_value = CONTRAST_DEF,
105 106 107 108
	    },
	    .set = sd_setcontrast,
	    .get = sd_getcontrast,
	},
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
/* All controls below are for both the 7302 and the 7311 */
	{
	    {
		.id      = V4L2_CID_GAIN,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Gain",
		.minimum = 0,
#define GAIN_MAX 255
		.maximum = GAIN_MAX,
		.step    = 1,
#define GAIN_DEF 127
#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
		.default_value = GAIN_DEF,
	    },
	    .set = sd_setgain,
	    .get = sd_getgain,
	},
	{
	    {
		.id      = V4L2_CID_EXPOSURE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Exposure",
		.minimum = 0,
#define EXPOSURE_MAX 255
		.maximum = EXPOSURE_MAX,
		.step    = 1,
#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
		.default_value = EXPOSURE_DEF,
	    },
	    .set = sd_setexposure,
	    .get = sd_getexposure,
	},
142 143 144 145 146 147 148 149
	{
	    {
		.id      = V4L2_CID_AUTOGAIN,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Auto Gain",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
150 151
#define AUTOGAIN_DEF 1
		.default_value = AUTOGAIN_DEF,
152 153 154 155
	    },
	    .set = sd_setautogain,
	    .get = sd_getautogain,
	},
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
	{
	    {
		.id      = V4L2_CID_HFLIP,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Mirror",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
#define HFLIP_DEF 0
		.default_value = HFLIP_DEF,
	    },
	    .set = sd_sethflip,
	    .get = sd_gethflip,
	},
	{
	    {
		.id      = V4L2_CID_VFLIP,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Vflip",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
#define VFLIP_DEF 0
		.default_value = VFLIP_DEF,
	    },
	    .set = sd_setvflip,
	    .get = sd_getvflip,
	},
184 185
};

186
static const struct v4l2_pix_format vga_mode[] = {
187
	{160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
188 189 190 191
		.bytesperline = 160,
		.sizeimage = 160 * 120 * 3 / 8 + 590,
		.colorspace = V4L2_COLORSPACE_JPEG,
		.priv = 2},
192
	{320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
193 194 195 196
		.bytesperline = 320,
		.sizeimage = 320 * 240 * 3 / 8 + 590,
		.colorspace = V4L2_COLORSPACE_JPEG,
		.priv = 1},
197
	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
198 199 200 201
		.bytesperline = 640,
		.sizeimage = 640 * 480 * 3 / 8 + 590,
		.colorspace = V4L2_COLORSPACE_JPEG,
		.priv = 0},
202 203
};

204 205 206
#define LOAD_PAGE4		254
#define END_OF_SEQUENCE		0

207
/* pac 7311 */
208
static const __u8 init_7311[] = {
209 210 211
	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
	0x78, 0x44,	/* Bit_0=start stream, Bit_6=LED */
212 213 214 215 216 217 218 219 220 221 222
	0xff, 0x04,
	0x27, 0x80,
	0x28, 0xca,
	0x29, 0x53,
	0x2a, 0x0e,
	0xff, 0x01,
	0x3e, 0x20,
};

static const __u8 start_7311[] = {
/*	index, len, [value]* */
223 224
	0xff, 1,	0x01,		/* page 1 */
	0x02, 43,	0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
225 226 227 228 229
			0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
			0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
			0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00,
230
	0x3e, 42,	0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
231 232 233 234 235 236 237 238 239 240 241 242 243
			0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
			0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
			0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
			0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
			0xd0, 0xff,
	0x78, 6,	0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
	0x7f, 18,	0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
			0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
			0x18, 0x20,
	0x96, 3,	0x01, 0x08, 0x04,
	0xa0, 4,	0x44, 0x44, 0x44, 0x04,
	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
			0x3f, 0x00, 0x0a, 0x01, 0x00,
244
	0xff, 1,	0x04,		/* page 4 */
245
	0, LOAD_PAGE4,			/* load the page 4 */
246
	0x11, 1,	0x01,
247
	0, END_OF_SEQUENCE		/* end of sequence */
248 249
};

250
#define SKIP		0xaa
251
/* page 4 - the value SKIP says skip the index - see reg_w_page() */
252
static const __u8 page4_7311[] = {
253 254 255 256 257
	SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
	0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
	0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
	SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
258 259 260 261
	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
};

262
static void reg_w_buf(struct gspca_dev *gspca_dev,
263 264
		  __u8 index,
		  const char *buffer, int len)
265
{
266 267
	int ret;

268 269
	if (gspca_dev->usb_err < 0)
		return;
270
	memcpy(gspca_dev->usb_buf, buffer, len);
271
	ret = usb_control_msg(gspca_dev->dev,
272
			usb_sndctrlpipe(gspca_dev->dev, 0),
273
			0,		/* request */
274
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
275
			0,		/* value */
276
			index, gspca_dev->usb_buf, len,
277
			500);
278
	if (ret < 0) {
279 280 281
		PDEBUG(D_ERR, "reg_w_buf(): "
		"Failed to write registers to index 0x%x, error %i",
		index, ret);
282 283
		gspca_dev->usb_err = ret;
	}
284 285 286
}


287
static void reg_w(struct gspca_dev *gspca_dev,
288
		  __u8 index,
289
		  __u8 value)
290
{
291 292
	int ret;

293 294
	if (gspca_dev->usb_err < 0)
		return;
295
	gspca_dev->usb_buf[0] = value;
296
	ret = usb_control_msg(gspca_dev->dev,
297
			usb_sndctrlpipe(gspca_dev->dev, 0),
298 299
			0,			/* request */
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
300
			0, index, gspca_dev->usb_buf, 1,
301
			500);
302
	if (ret < 0) {
303 304 305
		PDEBUG(D_ERR, "reg_w(): "
		"Failed to write register to index 0x%x, value 0x%x, error %i",
		index, value, ret);
306 307
		gspca_dev->usb_err = ret;
	}
308 309
}

310
static void reg_w_seq(struct gspca_dev *gspca_dev,
311 312 313
		const __u8 *seq, int len)
{
	while (--len >= 0) {
314
		reg_w(gspca_dev, seq[0], seq[1]);
315 316 317 318 319
		seq += 2;
	}
}

/* load the beginning of a page */
320
static void reg_w_page(struct gspca_dev *gspca_dev,
321 322 323
			const __u8 *page, int len)
{
	int index;
324
	int ret = 0;
325

326 327
	if (gspca_dev->usb_err < 0)
		return;
328
	for (index = 0; index < len; index++) {
329
		if (page[index] == SKIP)		/* skip this index */
330 331
			continue;
		gspca_dev->usb_buf[0] = page[index];
332
		ret = usb_control_msg(gspca_dev->dev,
333 334 335 336 337
				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);
338
		if (ret < 0) {
339 340 341 342
			PDEBUG(D_ERR, "reg_w_page(): "
			"Failed to write register to index 0x%x, "
			"value 0x%x, error %i",
			index, page[index], ret);
343
			gspca_dev->usb_err = ret;
344 345
			break;
		}
346 347 348 349
	}
}

/* output a variable sequence */
350
static void reg_w_var(struct gspca_dev *gspca_dev,
351 352
			const __u8 *seq,
			const __u8 *page4, unsigned int page4_len)
353 354 355 356 357 358 359
{
	int index, len;

	for (;;) {
		index = *seq++;
		len = *seq++;
		switch (len) {
360
		case END_OF_SEQUENCE:
361
			return;
362
		case LOAD_PAGE4:
363
			reg_w_page(gspca_dev, page4, page4_len);
364 365
			break;
		default:
366
			if (len > USB_BUF_SZ) {
367 368
				PDEBUG(D_ERR|D_STREAM,
					"Incorrect variable sequence");
369
				return;
370 371 372
			}
			while (len > 0) {
				if (len < 8) {
373
					reg_w_buf(gspca_dev,
374
						index, seq, len);
375 376 377
					seq += len;
					break;
				}
378
				reg_w_buf(gspca_dev, index, seq, 8);
379 380 381 382 383 384 385 386 387
				seq += 8;
				index += 8;
				len -= 8;
			}
		}
	}
	/* not reached */
}

388
/* this function is called at probe time for pac7311 */
389 390 391 392 393 394 395
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;
396

397 398 399
	PDEBUG(D_CONF, "Find Sensor PAC7311");
	cam->cam_mode = vga_mode;
	cam->nmodes = ARRAY_SIZE(vga_mode);
400

401
	sd->contrast = CONTRAST_DEF;
402 403
	sd->gain = GAIN_DEF;
	sd->exposure = EXPOSURE_DEF;
404
	sd->autogain = AUTOGAIN_DEF;
405 406
	sd->hflip = HFLIP_DEF;
	sd->vflip = VFLIP_DEF;
407 408 409
	return 0;
}

410
/* This function is used by pac7311 only */
411
static void setcontrast(struct gspca_dev *gspca_dev)
412 413
{
	struct sd *sd = (struct sd *) gspca_dev;
414

415 416
	reg_w(gspca_dev, 0xff, 0x04);
	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
417
	/* load registers to sensor (Bit 0, auto clear) */
418
	reg_w(gspca_dev, 0x11, 0x01);
419 420
}

421
static void setgain(struct gspca_dev *gspca_dev)
422 423
{
	struct sd *sd = (struct sd *) gspca_dev;
424 425 426 427 428 429
	int gain = GAIN_MAX - sd->gain;

	if (gain < 1)
		gain = 1;
	else if (gain > 245)
		gain = 245;
430 431 432
	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
	reg_w(gspca_dev, 0x0e, 0x00);
	reg_w(gspca_dev, 0x0f, gain);
433 434

	/* load registers to sensor (Bit 0, auto clear) */
435
	reg_w(gspca_dev, 0x11, 0x01);
436 437
}

438
static void setexposure(struct gspca_dev *gspca_dev)
439 440
{
	struct sd *sd = (struct sd *) gspca_dev;
441 442 443 444 445 446 447 448 449 450
	__u8 reg;

	/* register 2 of frame 3/4 contains the clock divider configuring the
	   no fps according to the formula: 60 / reg. sd->exposure is the
	   desired exposure time in ms. */
	reg = 120 * sd->exposure / 1000;
	if (reg < 2)
		reg = 2;
	else if (reg > 63)
		reg = 63;
451

452 453 454
	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
	reg_w(gspca_dev, 0x02, reg);

455 456
	/* Page 1 register 8 must always be 0x08 except when not in
	   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
457
	reg_w(gspca_dev, 0xff, 0x01);
458
	if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
459
			reg <= 3) {
460
		reg_w(gspca_dev, 0x08, 0x09);
461
	} else {
462
		reg_w(gspca_dev, 0x08, 0x08);
463
	}
464

465
	/* load registers to sensor (Bit 0, auto clear) */
466
	reg_w(gspca_dev, 0x11, 0x01);
467 468
}

469
static void sethvflip(struct gspca_dev *gspca_dev)
470 471 472 473
{
	struct sd *sd = (struct sd *) gspca_dev;
	__u8 data;

474
	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
475
	data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
476 477
	reg_w(gspca_dev, 0x21, data);

478
	/* load registers to sensor (Bit 0, auto clear) */
479
	reg_w(gspca_dev, 0x11, 0x01);
480 481
}

482
/* this function is called at probe and resume time for pac7311 */
483
static int sd_init(struct gspca_dev *gspca_dev)
484
{
485 486
	reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
	return gspca_dev->usb_err;
487 488
}

489
static int sd_start(struct gspca_dev *gspca_dev)
490
{
491 492
	struct sd *sd = (struct sd *) gspca_dev;

493
	sd->sof_read = 0;
494

495
	reg_w_var(gspca_dev, start_7311,
496
		page4_7311, sizeof(page4_7311));
497 498 499 500
	setcontrast(gspca_dev);
	setgain(gspca_dev);
	setexposure(gspca_dev);
	sethvflip(gspca_dev);
501 502

	/* set correct resolution */
503
	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
504
	case 2:					/* 160x120 pac7311 */
505 506 507
		reg_w(gspca_dev, 0xff, 0x01);
		reg_w(gspca_dev, 0x17, 0x20);
		reg_w(gspca_dev, 0x87, 0x10);
508
		break;
509
	case 1:					/* 320x240 pac7311 */
510 511 512
		reg_w(gspca_dev, 0xff, 0x01);
		reg_w(gspca_dev, 0x17, 0x30);
		reg_w(gspca_dev, 0x87, 0x11);
513 514
		break;
	case 0:					/* 640x480 */
515 516 517
		reg_w(gspca_dev, 0xff, 0x01);
		reg_w(gspca_dev, 0x17, 0x00);
		reg_w(gspca_dev, 0x87, 0x12);
518 519 520
		break;
	}

521 522 523
	sd->sof_read = 0;
	sd->autogain_ignore_frames = 0;
	atomic_set(&sd->avg_lum, -1);
524 525

	/* start stream */
526 527
	reg_w(gspca_dev, 0xff, 0x01);
	reg_w(gspca_dev, 0x78, 0x05);
528

529
	return gspca_dev->usb_err;
530 531 532 533
}

static void sd_stopN(struct gspca_dev *gspca_dev)
{
534 535 536 537 538 539 540 541 542 543
	reg_w(gspca_dev, 0xff, 0x04);
	reg_w(gspca_dev, 0x27, 0x80);
	reg_w(gspca_dev, 0x28, 0xca);
	reg_w(gspca_dev, 0x29, 0x53);
	reg_w(gspca_dev, 0x2a, 0x0e);
	reg_w(gspca_dev, 0xff, 0x01);
	reg_w(gspca_dev, 0x3e, 0x20);
	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
544 545
}

546
/* called on streamoff with alt 0 and on disconnect for 7311 */
547 548 549 550
static void sd_stop0(struct gspca_dev *gspca_dev)
{
}

551 552 553
/* Include pac common sof detection functions */
#include "pac_common.h"

554
static void do_autogain(struct gspca_dev *gspca_dev)
555
{
556 557
	struct sd *sd = (struct sd *) gspca_dev;
	int avg_lum = atomic_read(&sd->avg_lum);
558
	int desired_lum, deadzone;
559 560 561 562

	if (avg_lum == -1)
		return;

563 564
	desired_lum = 200;
	deadzone = 20;
565 566 567 568

	if (sd->autogain_ignore_frames > 0)
		sd->autogain_ignore_frames--;
	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
569
			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
570
		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
571 572
}

573
/* JPEG header, part 1 */
574
static const unsigned char pac_jpeg_header1[] = {
575 576 577 578 579 580 581
  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 */
  /* 2 bytes is placed here: number of image lines */
  /* 2 bytes is placed here: samples per line */
582 583
};

584
/* JPEG header, continued */
585
static const unsigned char pac_jpeg_header2[] = {
586 587 588 589 590 591 592 593 594 595 596 597 598
  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 */
599 600
};

601 602 603 604 605
static void pac_start_frame(struct gspca_dev *gspca_dev,
		__u16 lines, __u16 samples_per_line)
{
	unsigned char tmpbuf[4];

606
	gspca_frame_add(gspca_dev, FIRST_PACKET,
607 608 609 610 611 612 613
		pac_jpeg_header1, sizeof(pac_jpeg_header1));

	tmpbuf[0] = lines >> 8;
	tmpbuf[1] = lines & 0xff;
	tmpbuf[2] = samples_per_line >> 8;
	tmpbuf[3] = samples_per_line & 0xff;

614
	gspca_frame_add(gspca_dev, INTER_PACKET,
615
		tmpbuf, sizeof(tmpbuf));
616
	gspca_frame_add(gspca_dev, INTER_PACKET,
617 618 619
		pac_jpeg_header2, sizeof(pac_jpeg_header2));
}

620
/* this function is run at interrupt level */
621
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
622
			u8 *data,			/* isoc packet */
623 624 625
			int len)			/* iso packet length */
{
	struct sd *sd = (struct sd *) gspca_dev;
626
	u8 *image;
627 628
	unsigned char *sof;

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

633 634 635 636 637 638
		/* 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 */
		lum_offset = 24 + sizeof pac_sof_marker;
		footer_length = 26;
639 640 641 642

		/* Finish decoding current frame */
		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
		if (n < 0) {
643
			gspca_dev->image_len += n;
644
			n = 0;
645 646
		} else {
			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
647
		}
648 649
		image = gspca_dev->image;
		if (image != NULL
650 651 652
		 && image[gspca_dev->image_len - 2] == 0xff
		 && image[gspca_dev->image_len - 1] == 0xd9)
			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
653 654 655 656 657 658 659

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

		/* Get average lumination */
		if (gspca_dev->last_packet_type == LAST_PACKET &&
660 661
				n >= lum_offset)
			atomic_set(&sd->avg_lum, data[-lum_offset] +
662
						data[-lum_offset + 1]);
663
		else
664 665 666
			atomic_set(&sd->avg_lum, -1);

		/* Start the new frame with the jpeg header */
667
		pac_start_frame(gspca_dev,
668
			gspca_dev->height, gspca_dev->width);
669
	}
670
	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
671 672 673 674 675 676 677
}

static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->contrast = val;
678
	if (gspca_dev->streaming) {
679
		setcontrast(gspca_dev);
680
	}
681
	return gspca_dev->usb_err;
682 683 684 685 686 687 688 689 690 691
}

static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->contrast;
	return 0;
}

692 693 694 695 696 697 698
static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->gain = val;
	if (gspca_dev->streaming)
		setgain(gspca_dev);
699
	return gspca_dev->usb_err;
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
}

static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->gain;
	return 0;
}

static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->exposure = val;
	if (gspca_dev->streaming)
		setexposure(gspca_dev);
717
	return gspca_dev->usb_err;
718 719 720 721 722 723 724 725 726 727
}

static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->exposure;
	return 0;
}

728 729 730 731 732
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->autogain = val;
733 734 735 736 737 738 739 740 741 742 743 744 745 746
	/* 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. */
	if (sd->autogain) {
		sd->exposure = EXPOSURE_DEF;
		sd->gain = GAIN_DEF;
		if (gspca_dev->streaming) {
			sd->autogain_ignore_frames =
				PAC_AUTOGAIN_IGNORE_FRAMES;
			setexposure(gspca_dev);
			setgain(gspca_dev);
		}
	}
747

748
	return gspca_dev->usb_err;
749 750 751 752 753 754 755 756 757 758
}

static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->autogain;
	return 0;
}

759 760 761 762 763 764 765
static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->hflip = val;
	if (gspca_dev->streaming)
		sethvflip(gspca_dev);
766
	return gspca_dev->usb_err;
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
}

static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->hflip;
	return 0;
}

static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->vflip = val;
	if (gspca_dev->streaming)
		sethvflip(gspca_dev);
784
	return gspca_dev->usb_err;
785 786 787 788 789 790 791 792 793 794
}

static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->vflip;
	return 0;
}

795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
#ifdef CONFIG_INPUT
static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,		/* interrupt packet data */
			int len)		/* interrupt 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

826
/* sub-driver description for pac7311 */
827
static const struct sd_desc sd_desc = {
828 829 830 831
	.name = MODULE_NAME,
	.ctrls = sd_ctrls,
	.nctrls = ARRAY_SIZE(sd_ctrls),
	.config = sd_config,
832
	.init = sd_init,
833 834 835 836
	.start = sd_start,
	.stopN = sd_stopN,
	.stop0 = sd_stop0,
	.pkt_scan = sd_pkt_scan,
837
	.dq_callback = do_autogain,
838 839 840
#ifdef CONFIG_INPUT
	.int_pkt_scan = sd_int_pkt_scan,
#endif
841 842 843
};

/* -- module initialisation -- */
844
static const struct usb_device_id device_table[] __devinitconst = {
845 846 847 848 849 850
	{USB_DEVICE(0x093a, 0x2600)},
	{USB_DEVICE(0x093a, 0x2601)},
	{USB_DEVICE(0x093a, 0x2603)},
	{USB_DEVICE(0x093a, 0x2608)},
	{USB_DEVICE(0x093a, 0x260e)},
	{USB_DEVICE(0x093a, 0x260f)},
851 852 853 854 855
	{}
};
MODULE_DEVICE_TABLE(usb, device_table);

/* -- device connect -- */
856
static int __devinit sd_probe(struct usb_interface *intf,
857 858 859 860 861 862 863 864 865 866 867
			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 = {
	.name = MODULE_NAME,
	.id_table = device_table,
	.probe = sd_probe,
	.disconnect = gspca_disconnect,
868 869 870 871
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume = gspca_resume,
#endif
872 873 874 875 876
};

/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
877 878 879
	int ret;
	ret = usb_register(&sd_driver);
	if (ret < 0)
880
		return ret;
881
	PDEBUG(D_PROBE, "registered");
882 883 884 885 886 887 888 889 890 891
	return 0;
}
static void __exit sd_mod_exit(void)
{
	usb_deregister(&sd_driver);
	PDEBUG(D_PROBE, "deregistered");
}

module_init(sd_mod_init);
module_exit(sd_mod_exit);