pac7311.c 21.7 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 54 55 56 57 58 59
#define MODULE_NAME "pac7311"

#include "gspca.h"

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

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

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

71 72 73 74
	u8 sof_read;
	u8 autogain_ignore_frames;

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

/* 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);
82 83 84 85
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);
86 87 88 89
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);
90 91

static struct ctrl sd_ctrls[] = {
92
/* This control is for both the 7302 and the 7311 */
93 94 95 96 97 98
	{
	    {
		.id      = V4L2_CID_CONTRAST,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Contrast",
		.minimum = 0,
99 100
#define CONTRAST_MAX 255
		.maximum = CONTRAST_MAX,
101
		.step    = 1,
102
#define CONTRAST_DEF 127
103
		.default_value = CONTRAST_DEF,
104 105 106 107
	    },
	    .set = sd_setcontrast,
	    .get = sd_getcontrast,
	},
108 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
/* 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,
	},
141 142 143 144 145 146 147 148
	{
	    {
		.id      = V4L2_CID_AUTOGAIN,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Auto Gain",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
149 150
#define AUTOGAIN_DEF 1
		.default_value = AUTOGAIN_DEF,
151 152 153 154
	    },
	    .set = sd_setautogain,
	    .get = sd_getautogain,
	},
155 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
	{
	    {
		.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,
	},
183 184
};

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

203 204 205 206
#define LOAD_PAGE3		255
#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
	memcpy(gspca_dev->usb_buf, buffer, len);
269
	ret = usb_control_msg(gspca_dev->dev,
270
			usb_sndctrlpipe(gspca_dev->dev, 0),
271
			1,		/* request */
272
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
273
			0,		/* value */
274
			index, gspca_dev->usb_buf, len,
275
			500);
276 277 278 279
	if (ret < 0)
		PDEBUG(D_ERR, "reg_w_buf(): "
		"Failed to write registers to index 0x%x, error %i",
		index, ret);
280 281 282
}


283
static void reg_w(struct gspca_dev *gspca_dev,
284
		  __u8 index,
285
		  __u8 value)
286
{
287 288
	int ret;

289
	gspca_dev->usb_buf[0] = value;
290
	ret = usb_control_msg(gspca_dev->dev,
291
			usb_sndctrlpipe(gspca_dev->dev, 0),
292 293
			0,			/* request */
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
294
			0, index, gspca_dev->usb_buf, 1,
295
			500);
296 297 298 299
	if (ret < 0)
		PDEBUG(D_ERR, "reg_w(): "
		"Failed to write register to index 0x%x, value 0x%x, error %i",
		index, value, ret);
300 301
}

302 303 304 305 306 307 308 309 310 311 312 313 314 315
static void reg_w_seq(struct gspca_dev *gspca_dev,
		const __u8 *seq, int len)
{
	while (--len >= 0) {
		reg_w(gspca_dev, seq[0], seq[1]);
		seq += 2;
	}
}

/* load the beginning of a page */
static void reg_w_page(struct gspca_dev *gspca_dev,
			const __u8 *page, int len)
{
	int index;
316
	int ret;
317 318

	for (index = 0; index < len; index++) {
319
		if (page[index] == SKIP)		/* skip this index */
320 321
			continue;
		gspca_dev->usb_buf[0] = page[index];
322
		ret = usb_control_msg(gspca_dev->dev,
323 324 325 326 327
				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);
328 329 330 331 332
		if (ret < 0)
			PDEBUG(D_ERR, "reg_w_page(): "
			"Failed to write register to index 0x%x, "
			"value 0x%x, error %i",
			index, page[index], ret);
333 334 335 336 337
	}
}

/* output a variable sequence */
static void reg_w_var(struct gspca_dev *gspca_dev,
338 339 340
			const __u8 *seq,
			const __u8 *page3, unsigned int page3_len,
			const __u8 *page4, unsigned int page4_len)
341 342 343 344 345 346 347
{
	int index, len;

	for (;;) {
		index = *seq++;
		len = *seq++;
		switch (len) {
348
		case END_OF_SEQUENCE:
349
			return;
350
		case LOAD_PAGE4:
351
			reg_w_page(gspca_dev, page4, page4_len);
352
			break;
353
		case LOAD_PAGE3:
354
			reg_w_page(gspca_dev, page3, page3_len);
355 356
			break;
		default:
357
			if (len > USB_BUF_SZ) {
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
				PDEBUG(D_ERR|D_STREAM,
					"Incorrect variable sequence");
				return;
			}
			while (len > 0) {
				if (len < 8) {
					reg_w_buf(gspca_dev, index, seq, len);
					seq += len;
					break;
				}
				reg_w_buf(gspca_dev, index, seq, 8);
				seq += 8;
				index += 8;
				len -= 8;
			}
		}
	}
	/* not reached */
}

378
/* this function is called at probe time for pac7311 */
379 380 381 382 383 384 385
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;
386

387 388 389
	PDEBUG(D_CONF, "Find Sensor PAC7311");
	cam->cam_mode = vga_mode;
	cam->nmodes = ARRAY_SIZE(vga_mode);
390

391
	sd->contrast = CONTRAST_DEF;
392 393
	sd->gain = GAIN_DEF;
	sd->exposure = EXPOSURE_DEF;
394
	sd->autogain = AUTOGAIN_DEF;
395 396
	sd->hflip = HFLIP_DEF;
	sd->vflip = VFLIP_DEF;
397 398 399
	return 0;
}

400 401
/* This function is used by pac7311 only */
static void setcontrast(struct gspca_dev *gspca_dev)
402 403
{
	struct sd *sd = (struct sd *) gspca_dev;
404

405
	reg_w(gspca_dev, 0xff, 0x04);
406
	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
407
	/* load registers to sensor (Bit 0, auto clear) */
408
	reg_w(gspca_dev, 0x11, 0x01);
409 410
}

411
static void setgain(struct gspca_dev *gspca_dev)
412 413
{
	struct sd *sd = (struct sd *) gspca_dev;
414 415 416 417 418 419 420 421 422
	int gain = GAIN_MAX - sd->gain;

	if (gain < 1)
		gain = 1;
	else if (gain > 245)
		gain = 245;
	reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
	reg_w(gspca_dev, 0x0e, 0x00);
	reg_w(gspca_dev, 0x0f, gain);
423 424

	/* load registers to sensor (Bit 0, auto clear) */
425
	reg_w(gspca_dev, 0x11, 0x01);
426 427
}

428
static void setexposure(struct gspca_dev *gspca_dev)
429 430
{
	struct sd *sd = (struct sd *) gspca_dev;
431 432 433 434 435 436 437 438 439 440
	__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;
441

442 443 444 445 446 447 448 449 450 451 452
	reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
	reg_w(gspca_dev, 0x02, reg);
	/* 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 */
	reg_w(gspca_dev, 0xff, 0x01);
	if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
			reg <= 3)
		reg_w(gspca_dev, 0x08, 0x09);
	else
		reg_w(gspca_dev, 0x08, 0x08);

453 454
	/* load registers to sensor (Bit 0, auto clear) */
	reg_w(gspca_dev, 0x11, 0x01);
455 456
}

457 458 459 460 461
static void sethvflip(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	__u8 data;

462 463
	reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
	data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
464
	reg_w(gspca_dev, 0x21, data);
465
	/* load registers to sensor (Bit 0, auto clear) */
466 467 468
	reg_w(gspca_dev, 0x11, 0x01);
}

469
/* this function is called at probe and resume time for pac7311 */
470
static int sd_init(struct gspca_dev *gspca_dev)
471
{
472
	reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
473

474 475 476
	return 0;
}

477
static int sd_start(struct gspca_dev *gspca_dev)
478
{
479 480
	struct sd *sd = (struct sd *) gspca_dev;

481
	sd->sof_read = 0;
482

483 484 485 486
	reg_w_var(gspca_dev, start_7311,
		NULL, 0,
		page4_7311, sizeof(page4_7311));
	setcontrast(gspca_dev);
487 488 489
	setgain(gspca_dev);
	setexposure(gspca_dev);
	sethvflip(gspca_dev);
490 491

	/* set correct resolution */
492
	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
493
	case 2:					/* 160x120 pac7311 */
494 495 496
		reg_w(gspca_dev, 0xff, 0x01);
		reg_w(gspca_dev, 0x17, 0x20);
		reg_w(gspca_dev, 0x87, 0x10);
497
		break;
498
	case 1:					/* 320x240 pac7311 */
499 500 501
		reg_w(gspca_dev, 0xff, 0x01);
		reg_w(gspca_dev, 0x17, 0x30);
		reg_w(gspca_dev, 0x87, 0x11);
502 503
		break;
	case 0:					/* 640x480 */
504 505 506
		reg_w(gspca_dev, 0xff, 0x01);
		reg_w(gspca_dev, 0x17, 0x00);
		reg_w(gspca_dev, 0x87, 0x12);
507 508 509
		break;
	}

510 511 512
	sd->sof_read = 0;
	sd->autogain_ignore_frames = 0;
	atomic_set(&sd->avg_lum, -1);
513 514 515

	/* start stream */
	reg_w(gspca_dev, 0xff, 0x01);
516 517
	reg_w(gspca_dev, 0x78, 0x05);

518
	return 0;
519 520 521 522
}

static void sd_stopN(struct gspca_dev *gspca_dev)
{
523 524 525 526 527 528 529
	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);
530 531 532
	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 */
533 534
}

535
/* called on streamoff with alt 0 and on disconnect for 7311 */
536 537 538 539
static void sd_stop0(struct gspca_dev *gspca_dev)
{
}

540 541 542
/* Include pac common sof detection functions */
#include "pac_common.h"

543
static void do_autogain(struct gspca_dev *gspca_dev)
544
{
545 546
	struct sd *sd = (struct sd *) gspca_dev;
	int avg_lum = atomic_read(&sd->avg_lum);
547
	int desired_lum, deadzone;
548 549 550 551

	if (avg_lum == -1)
		return;

552 553
	desired_lum = 200;
	deadzone = 20;
554 555 556 557

	if (sd->autogain_ignore_frames > 0)
		sd->autogain_ignore_frames--;
	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
558
			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
559
		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
560 561
}

562
/* JPEG header, part 1 */
563
static const unsigned char pac_jpeg_header1[] = {
564 565 566 567 568 569 570
  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 */
571 572
};

573
/* JPEG header, continued */
574
static const unsigned char pac_jpeg_header2[] = {
575 576 577 578 579 580 581 582 583 584 585 586 587
  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 */
588 589
};

590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
static void pac_start_frame(struct gspca_dev *gspca_dev,
		struct gspca_frame *frame,
		__u16 lines, __u16 samples_per_line)
{
	unsigned char tmpbuf[4];

	gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
		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;

	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
		tmpbuf, sizeof(tmpbuf));
	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
		pac_jpeg_header2, sizeof(pac_jpeg_header2));
}

610
/* this function is run at interrupt level */
611 612
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
			struct gspca_frame *frame,	/* target */
613
			__u8 *data,			/* isoc packet */
614 615 616
			int len)			/* iso packet length */
{
	struct sd *sd = (struct sd *) gspca_dev;
617 618
	unsigned char *sof;

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

623 624 625 626 627 628
		/* 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;
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649

		/* Finish decoding current frame */
		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
		if (n < 0) {
			frame->data_end += n;
			n = 0;
		}
		frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
					data, n);
		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
				frame->data_end[-2] == 0xff &&
				frame->data_end[-1] == 0xd9)
			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
						NULL, 0);

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

		/* Get average lumination */
		if (gspca_dev->last_packet_type == LAST_PACKET &&
650 651
				n >= lum_offset)
			atomic_set(&sd->avg_lum, data[-lum_offset] +
652
						data[-lum_offset + 1]);
653
		else
654 655 656
			atomic_set(&sd->avg_lum, -1);

		/* Start the new frame with the jpeg header */
657 658
		pac_start_frame(gspca_dev, frame,
			gspca_dev->height, gspca_dev->width);
659
	}
660
	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
661 662 663 664 665 666 667
}

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

	sd->contrast = val;
668
	if (gspca_dev->streaming) {
669
		setcontrast(gspca_dev);
670
	}
671 672 673 674 675 676 677 678 679 680 681
	return 0;
}

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

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

682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717
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);
	return 0;
}

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);
	return 0;
}

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

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

718 719 720 721 722
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;

	sd->autogain = val;
723 724 725 726 727 728 729 730 731 732 733 734 735 736
	/* 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);
		}
	}
737

738 739 740 741 742 743 744 745 746 747 748
	return 0;
}

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

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

749 750 751 752 753 754 755 756 757 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 783 784
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);
	return 0;
}

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);
	return 0;
}

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

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

785
/* sub-driver description for pac7311 */
786 787 788 789 790
static struct sd_desc sd_desc = {
	.name = MODULE_NAME,
	.ctrls = sd_ctrls,
	.nctrls = ARRAY_SIZE(sd_ctrls),
	.config = sd_config,
791
	.init = sd_init,
792 793 794 795
	.start = sd_start,
	.stopN = sd_stopN,
	.stop0 = sd_stop0,
	.pkt_scan = sd_pkt_scan,
796
	.dq_callback = do_autogain,
797 798 799 800
};

/* -- module initialisation -- */
static __devinitdata struct usb_device_id device_table[] = {
801 802 803 804 805 806
	{USB_DEVICE(0x093a, 0x2600)},
	{USB_DEVICE(0x093a, 0x2601)},
	{USB_DEVICE(0x093a, 0x2603)},
	{USB_DEVICE(0x093a, 0x2608)},
	{USB_DEVICE(0x093a, 0x260e)},
	{USB_DEVICE(0x093a, 0x260f)},
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
	{}
};
MODULE_DEVICE_TABLE(usb, device_table);

/* -- device connect -- */
static int sd_probe(struct usb_interface *intf,
			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,
824 825 826 827
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume = gspca_resume,
#endif
828 829 830 831 832
};

/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
833 834 835
	int ret;
	ret = usb_register(&sd_driver);
	if (ret < 0)
836
		return ret;
837
	PDEBUG(D_PROBE, "registered");
838 839 840 841 842 843 844 845 846 847
	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);