spca561.c

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

C
1,264
字号
			if (gainG > 0x3f)				gainG = 0x3f;			else if (gainG < 4)				gainG = 3;			i2c_write(gspca_dev, gainG, 0x35);			if (expotimes >= 0x0256)				expotimes = 0x0256;			else if (expotimes < 4)				expotimes = 3;			i2c_write(gspca_dev, expotimes | pixelclk, 0x09);		}		break;	case Rev012A:		reg_r(gspca_dev, 0x8330, 2);		if (gspca_dev->usb_buf[1] > 0x08) {			reg8339[0] = ++sd->expo12a;			reg8339[1] = 0;			reg_w_buf(gspca_dev, 0x8339, reg8339, 2);		} else if (gspca_dev->usb_buf[1] < 0x02) {			reg8339[0] = --sd->expo12a;			reg8339[1] = 0;			reg_w_buf(gspca_dev, 0x8339, reg8339, 2);		}		break;	}}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;	switch (data[0]) {	case 0:		/* start of frame */		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,					data, 0);		data += SPCA561_OFFSET_DATA;		len -= SPCA561_OFFSET_DATA;		if (data[1] & 0x10) {			/* compressed bayer */			gspca_frame_add(gspca_dev, FIRST_PACKET,					frame, data, len);		} else {			/* raw bayer (with a header, which we skip) */			if (sd->chip_revision == Rev012A) {				data += 20;				len -= 20;			} else {				data += 16;				len -= 16;			}			gspca_frame_add(gspca_dev, FIRST_PACKET,						frame, data, len);		}		return;	case 0xff:		/* drop *//*		gspca_dev->last_packet_type = DISCARD_PACKET; */		return;	}	data++;	len--;	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);}/* rev 72a only */static void setbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 value;	value = sd->brightness;	reg_w_val(gspca_dev->dev, 0x8611, value);	reg_w_val(gspca_dev->dev, 0x8612, value);	reg_w_val(gspca_dev->dev, 0x8613, value);	reg_w_val(gspca_dev->dev, 0x8614, value);}static void getbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u16 tot;	tot = 0;	reg_r(gspca_dev, 0x8611, 1);	tot += gspca_dev->usb_buf[0];	reg_r(gspca_dev, 0x8612, 1);	tot += gspca_dev->usb_buf[0];	reg_r(gspca_dev, 0x8613, 1);	tot += gspca_dev->usb_buf[0];	reg_r(gspca_dev, 0x8614, 1);	tot += gspca_dev->usb_buf[0];	sd->brightness = tot >> 2;}/* rev72a only */static void getcontrast(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u16 tot;	tot = 0;	reg_r(gspca_dev, 0x8651, 1);	tot += gspca_dev->usb_buf[0];	reg_r(gspca_dev, 0x8652, 1);	tot += gspca_dev->usb_buf[0];	reg_r(gspca_dev, 0x8653, 1);	tot += gspca_dev->usb_buf[0];	reg_r(gspca_dev, 0x8654, 1);	tot += gspca_dev->usb_buf[0];	sd->contrast = tot << 6;	PDEBUG(D_CONF, "get contrast %d", sd->contrast);}/* rev 72a only */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;	getbrightness(gspca_dev);	*val = sd->brightness;	return 0;}/* rev 72a only */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;	getcontrast(gspca_dev);	*val = sd->contrast;	return 0;}static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val){	struct sd *sd = (struct sd *) gspca_dev;	sd->autogain = val;	if (gspca_dev->streaming)		setautogain(gspca_dev);	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;}/* rev12a only */static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val){	struct sd *sd = (struct sd *) gspca_dev;	sd->white = val;	if (gspca_dev->streaming)		setwhite(gspca_dev);	return 0;}static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val){	struct sd *sd = (struct sd *) gspca_dev;	*val = sd->white;	return 0;}/* rev12a only */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;}/* rev12a only */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;}/* control tables */static struct ctrl sd_ctrls_12a[] = {	{	    {		.id = V4L2_CID_DO_WHITE_BALANCE,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "White Balance",		.minimum = WHITE_MIN,		.maximum = WHITE_MAX,		.step = 1,		.default_value = WHITE_DEF,	    },	    .set = sd_setwhite,	    .get = sd_getwhite,	},	{	    {		.id = V4L2_CID_EXPOSURE,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Exposure",		.minimum = EXPOSURE_MIN,		.maximum = EXPOSURE_MAX,		.step = 1,		.default_value = EXPOSURE_DEF,	    },	    .set = sd_setexposure,	    .get = sd_getexposure,	},	{	    {		.id = V4L2_CID_AUTOGAIN,		.type = V4L2_CTRL_TYPE_BOOLEAN,		.name = "Auto Gain",		.minimum = AUTOGAIN_MIN,		.maximum = AUTOGAIN_MAX,		.step = 1,		.default_value = AUTOGAIN_DEF,	    },	    .set = sd_setautogain,	    .get = sd_getautogain,	},	{	    {		.id = V4L2_CID_GAIN,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Gain",		.minimum = GAIN_MIN,		.maximum = GAIN_MAX,		.step = 1,		.default_value = GAIN_DEF,	    },	    .set = sd_setgain,	    .get = sd_getgain,	},};static struct ctrl sd_ctrls_72a[] = {	{	   {		.id = V4L2_CID_BRIGHTNESS,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Brightness",		.minimum = BRIGHTNESS_MIN,		.maximum = BRIGHTNESS_MAX,		.step = 1,		.default_value = BRIGHTNESS_DEF,	    },	    .set = sd_setbrightness,	    .get = sd_getbrightness,	},	{	    {		.id = V4L2_CID_CONTRAST,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Contrast",		.minimum = CONTRAST_MIN,		.maximum = CONTRAST_MAX,		.step = 1,		.default_value = CONTRAST_DEF,	    },	    .set = sd_setcontrast,	    .get = sd_getcontrast,	},	{	    {		.id = V4L2_CID_AUTOGAIN,		.type = V4L2_CTRL_TYPE_BOOLEAN,		.name = "Auto Gain",		.minimum = AUTOGAIN_MIN,		.maximum = AUTOGAIN_MAX,		.step = 1,		.default_value = AUTOGAIN_DEF,	    },	    .set = sd_setautogain,	    .get = sd_getautogain,	},};/* sub-driver description */static const struct sd_desc sd_desc_12a = {	.name = MODULE_NAME,	.ctrls = sd_ctrls_12a,	.nctrls = ARRAY_SIZE(sd_ctrls_12a),	.config = sd_config,	.init = sd_init_12a,	.start = sd_start_12a,	.stopN = sd_stopN,	.stop0 = sd_stop0,	.pkt_scan = sd_pkt_scan,/*	.dq_callback = do_autogain,	 * fixme */};static const struct sd_desc sd_desc_72a = {	.name = MODULE_NAME,	.ctrls = sd_ctrls_72a,	.nctrls = ARRAY_SIZE(sd_ctrls_72a),	.config = sd_config,	.init = sd_init_72a,	.start = sd_start_72a,	.stopN = sd_stopN,	.stop0 = sd_stop0,	.pkt_scan = sd_pkt_scan,	.dq_callback = do_autogain,};static const struct sd_desc *sd_desc[2] = {	&sd_desc_12a,	&sd_desc_72a};/* -- module initialisation -- */static const __devinitdata struct usb_device_id device_table[] = {	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},	{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},	{USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},	{USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},	{USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},	{USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},	{USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},	{}};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[id->driver_info],				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 + -
显示快捷键?