tv8532.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 670 行 · 第 1/2 页

C
670
字号
{	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);	tv_8532ReadRegisters(gspca_dev);	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);	reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,				ADHEIGHH);	/* 401d 0x0169; 0e */	reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,				EXPOH);		/* 350d 0x014c; 1c */	reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL);	/* 0x20; 0x0c */	reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH);	/* 0x0d */	/*******************************************************************/	reg_w_1(gspca_dev, TV8532_QUANT_COMP,			TESTCOMP);	/* 0x72 compressed mode 0x28 */	reg_w_1(gspca_dev, TV8532_MODE_PACKET,			TESTLINE);	/* 0x84; // CIF | 4 packet 0x29 */	/************************************************/	reg_w_1(gspca_dev, TV8532_SETCLK,			TESTCLK);		/* 0x48; //0x08; 0x2c */	reg_w_1(gspca_dev, TV8532_POINT_L,			TESTPTL);		/* 0x38; 0x2d */	reg_w_1(gspca_dev, TV8532_POINT_H,			TESTPTH);		/* 0x04; 0x2e */	reg_w_1(gspca_dev, TV8532_POINTB_L,			TESTPTBL);		/* 0x04; 0x2f */	reg_w_1(gspca_dev, TV8532_POINTB_H,			TESTPTBH);		/* 0x04; 0x30 */	reg_w_1(gspca_dev, TV8532_PART_CTRL,			TV8532_CMD_UPDATE);	/* 0x00<-0x84 */	/*************************************************/	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01);	/* 0x31 */	msleep(200);	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */	/*************************************************/	tv_8532_setReg(gspca_dev);	/*************************************************/	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);	/*************************************************/	tv_8532_setReg(gspca_dev);	/*************************************************/	tv_8532_PollReg(gspca_dev);	return 0;}static void setbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int brightness = sd->brightness;	reg_w_2(gspca_dev, TV8532_EXPOSURE,		brightness >> 8, brightness);		/* 1c */	reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);}/* -- start the camera -- */static int sd_start(struct gspca_dev *gspca_dev){	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);	tv_8532ReadRegisters(gspca_dev);	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);	reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,		ADHEIGHL, ADHEIGHH);	/* 401d 0x0169; 0e *//*	reg_w_2(gspca_dev, TV8532_EXPOSURE,		EXPOL, EXPOH);		 * 350d 0x014c; 1c */	setbrightness(gspca_dev);	reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL);	/* 0x20; 0x0c */	reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH);	/* 0x0d */	/************************************************/	reg_w_1(gspca_dev, TV8532_QUANT_COMP,			TESTCOMP);	/* 0x72 compressed mode 0x28 */	if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {		/* 176x144 */		reg_w_1(gspca_dev, TV8532_MODE_PACKET,			QCIFLINE);	/* 0x84; // CIF | 4 packet 0x29 */	} else {		/* 352x288 */		reg_w_1(gspca_dev, TV8532_MODE_PACKET,			TESTLINE);	/* 0x84; // CIF | 4 packet 0x29 */	}	/************************************************/	reg_w_1(gspca_dev, TV8532_SETCLK,			TESTCLK);		/* 0x48; //0x08; 0x2c */	reg_w_1(gspca_dev, TV8532_POINT_L,			TESTPTL);		/* 0x38; 0x2d */	reg_w_1(gspca_dev, TV8532_POINT_H,			TESTPTH);		/* 0x04; 0x2e */	reg_w_1(gspca_dev, TV8532_POINTB_L,			TESTPTBL);		/* 0x04; 0x2f */	reg_w_1(gspca_dev, TV8532_POINTB_H,			TESTPTBH);		/* 0x04; 0x30 */	reg_w_1(gspca_dev, TV8532_PART_CTRL,			TV8532_CMD_UPDATE);	/* 0x00<-0x84 */	/************************************************/	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01);	/* 0x31 */	msleep(200);	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */	/************************************************/	tv_8532_setReg(gspca_dev);	/************************************************/	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);	/************************************************/	tv_8532_setReg(gspca_dev);	/************************************************/	tv_8532_PollReg(gspca_dev);	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */	return 0;}static void sd_stopN(struct gspca_dev *gspca_dev){	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);}static void tv8532_preprocess(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;/* we should received a whole frame with header and EOL marker * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2 * sequence 2bytes header the Alternate pixels bayer GB 4 bytes * Alternate pixels bayer RG 4 bytes EOL */	int width = gspca_dev->width;	int height = gspca_dev->height;	unsigned char *dst = sd->tmpbuf2;	unsigned char *data = sd->tmpbuf;	int i;	/* precompute where is the good bayer line */	if (((data[3] + data[width + 7]) >> 1)	    + (data[4] >> 2)	    + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)	    + (data[3] >> 2)	    + (data[width + 5] >> 1))		data += 3;	else		data += 2;	for (i = 0; i < height / 2; i++) {		memcpy(dst, data, width);		data += width + 3;		dst += width;		memcpy(dst, data, width);		data += width + 7;		dst += width;	}}static void sd_pkt_scan(struct gspca_dev *gspca_dev,			struct gspca_frame *frame,	/* target */			__u8 *data,			/* isoc packet */			int len)			/* iso packet length */{	struct sd *sd = (struct sd *) gspca_dev;	if (data[0] != 0x80) {		sd->packet++;		if (sd->buflen + len > sizeof sd->tmpbuf) {			if (gspca_dev->last_packet_type != DISCARD_PACKET) {				PDEBUG(D_PACK, "buffer overflow");				gspca_dev->last_packet_type = DISCARD_PACKET;			}			return;		}		memcpy(&sd->tmpbuf[sd->buflen], data, len);		sd->buflen += len;		return;	}	/* here we detect 0x80 */	/* counter is limited so we need few header for a frame :) */	/* header 0x80 0x80 0x80 0x80 0x80 */	/* packet  00   63  127  145  00   */	/* sof     0     1   1    0    0   */	/* update sequence */	if (sd->packet == 63 || sd->packet == 127)		sd->synchro = 1;	/* is there a frame start ? */	if (sd->packet >= (gspca_dev->height >> 1) - 1) {		PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro,		       sd->packet);		if (!sd->synchro) {	/* start of frame */			if (gspca_dev->last_packet_type == FIRST_PACKET) {				tv8532_preprocess(gspca_dev);				frame = gspca_frame_add(gspca_dev,							LAST_PACKET,							frame, sd->tmpbuf2,							gspca_dev->width *							    gspca_dev->width);			}			gspca_frame_add(gspca_dev, FIRST_PACKET,					frame, data, 0);			memcpy(sd->tmpbuf, data, len);			sd->buflen = len;			sd->packet = 0;			return;		}		if (gspca_dev->last_packet_type != DISCARD_PACKET) {			PDEBUG(D_PACK,			       "Warning wrong TV8532 frame detection %d",			       sd->packet);			gspca_dev->last_packet_type = DISCARD_PACKET;		}		return;	}	if (!sd->synchro) {		/* Drop packet frame corrupt */		PDEBUG(D_PACK, "DROP SOF %d packet %d",		       sd->synchro, sd->packet);		sd->packet = 0;		gspca_dev->last_packet_type = DISCARD_PACKET;		return;	}	sd->synchro = 1;	sd->packet++;	memcpy(&sd->tmpbuf[sd->buflen], data, len);	sd->buflen += len;}static void setcontrast(struct gspca_dev *gspca_dev){#if 0	value[0] = (gspca_dev->contrast) & 0xff;	value[1] = (gspca_dev->contrast >> 8) & 0xff;	reg_w_1(gspca_dev, 0x0020, value[1]);	reg_w_1(gspca_dev, 0x0022, value[1]);	reg_w_1(gspca_dev, 0x0024, value[1]);	reg_w_1(gspca_dev, 0x0026, value[1]);	reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);#endif}static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val){	struct sd *sd = (struct sd *) gspca_dev;	sd->brightness = val;	if (gspca_dev->streaming)		setbrightness(gspca_dev);	return 0;}static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val){	struct sd *sd = (struct sd *) gspca_dev;	*val = sd->brightness;	return 0;}static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val){	struct sd *sd = (struct sd *) gspca_dev;	sd->contrast = val;	if (gspca_dev->streaming)		setcontrast(gspca_dev);	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;}/* sub-driver description */static const struct sd_desc sd_desc = {	.name = MODULE_NAME,	.ctrls = sd_ctrls,	.nctrls = ARRAY_SIZE(sd_ctrls),	.config = sd_config,	.init = sd_init,	.start = sd_start,	.stopN = sd_stopN,	.pkt_scan = sd_pkt_scan,};/* -- module initialisation -- */static const __devinitdata struct usb_device_id device_table[] = {	{USB_DEVICE(0x046d, 0x0920)},	{USB_DEVICE(0x046d, 0x0921)},	{USB_DEVICE(0x0545, 0x808b)},	{USB_DEVICE(0x0545, 0x8333)},	{USB_DEVICE(0x0923, 0x010f)},	{}};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,#ifdef CONFIG_PM	.suspend = gspca_suspend,	.resume = gspca_resume,#endif};/* -- module insert / remove -- */static int __init sd_mod_init(void){	if (usb_register(&sd_driver) < 0)		return -1;	PDEBUG(D_PROBE, "registered");	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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?