spca508.c

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

C
1,720
字号
		0000: 00  */	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8802 } ->		0000: 10  */	{0x0010, 0x8802},	{0x0028, 0x8801},	{0x002e, 0x8805},	{0x0000, 0x8800},	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8802 } ->		0000: 10  */	{0x0010, 0x8802},	{0x0039, 0x8801},	{0x0013, 0x8805},	{0x0000, 0x8800},	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8802 } ->		0000: 10  */	{0x0010, 0x8802},	{0x003b, 0x8801},	{0x000c, 0x8805},	{0x0000, 0x8800},	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8802 } ->		0000: 10  */	{0x0010, 0x8802},	{0x0035, 0x8801},	{0x0028, 0x8805},	{0x0000, 0x8800},	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	/* READ { 0, 0x0001, 0x8802 } ->		0000: 10  */	{0x0010, 0x8802},	{0x0009, 0x8801},	{0x0042, 0x8805},	{0x0001, 0x8800},	/* READ { 0, 0x0001, 0x8803 } ->		0000: 00  */	{0x0050, 0x8703},	{0x0002, 0x8704},	/* External input CKIx1 */	{0x0001, 0x870C},	/* Select CKOx2 output */	{0x009A, 0x8600},	/* Line memory Read Counter (L) */	{0x0001, 0x8606},  /* 1 Line memory Read Counter (H) Result: (d)410 */	{0x0023, 0x8601},	{0x0010, 0x8602},	{0x000A, 0x8603},	{0x009A, 0x8600},	{0x0001, 0x865B},	/* 1 Horizontal Offset for Valid Pixel(L) */	{0x0003, 0x865C},	/* Vertical offset for valid lines (L) */	{0x0058, 0x865D},	/* Horizontal valid pixels window (L) */	{0x0048, 0x865E},	/* Vertical valid lines window (L) */	{0x0000, 0x865F},	{0x0006, 0x8660},		    /* Enable nibble data input, select nibble input order */	{0x0013, 0x8608},	/* A11 Coeficients for color correction */	{0x0028, 0x8609},		    /* Note: these values are confirmed at the end of array */	{0x0005, 0x860A},	/* ... */	{0x0025, 0x860B},	{0x00E1, 0x860C},	{0x00FA, 0x860D},	{0x00F4, 0x860E},	{0x00E8, 0x860F},	{0x0025, 0x8610},	/* A33 Coef. */	{0x00FC, 0x8611},	/* White balance offset: R */	{0x0001, 0x8612},	/* White balance offset: Gr */	{0x00FE, 0x8613},	/* White balance offset: B */	{0x0000, 0x8614},	/* White balance offset: Gb */	{0x0064, 0x8651},	/* R gain for white balance (L) */	{0x0040, 0x8652},	/* Gr gain for white balance (L) */	{0x0066, 0x8653},	/* B gain for white balance (L) */	{0x0040, 0x8654},	/* Gb gain for white balance (L) */	{0x0001, 0x863F},	/* Enable fixed gamma correction */	{0x00A1, 0x8656},	/* Size - Window1: 256x256, Window2: 128x128 */	/* UV division: UV no change, Enable New edge enhancement */	{0x0018, 0x8657},	/* Edge gain high threshold */	{0x0020, 0x8658},	/* Edge gain low threshold */	{0x000A, 0x8659},	/* Edge bandwidth high threshold */	{0x0005, 0x865A},	/* Edge bandwidth low threshold */	{0x0064, 0x8607},	/* UV filter enable */	{0x0016, 0x8660},	{0x0000, 0x86B0},	/* Bad pixels compensation address */	{0x00DC, 0x86B1},	/* X coord for bad pixels compensation (L) */	{0x0000, 0x86B2},	{0x0009, 0x86B3},	/* Y coord for bad pixels compensation (L) */	{0x0000, 0x86B4},	{0x0001, 0x86B0},	{0x00F5, 0x86B1},	{0x0000, 0x86B2},	{0x00C6, 0x86B3},	{0x0000, 0x86B4},	{0x0002, 0x86B0},	{0x001C, 0x86B1},	{0x0001, 0x86B2},	{0x00D7, 0x86B3},	{0x0000, 0x86B4},	{0x0003, 0x86B0},	{0x001C, 0x86B1},	{0x0001, 0x86B2},	{0x00D8, 0x86B3},	{0x0000, 0x86B4},	{0x0004, 0x86B0},	{0x001D, 0x86B1},	{0x0001, 0x86B2},	{0x00D8, 0x86B3},	{0x0000, 0x86B4},	{0x001E, 0x8660},	/* READ { 0, 0x0000, 0x8608 } ->		0000: 13  */	/* READ { 0, 0x0000, 0x8609 } ->		0000: 28  */	/* READ { 0, 0x0000, 0x8610 } ->		0000: 05  */	/* READ { 0, 0x0000, 0x8611 } ->		0000: 25  */	/* READ { 0, 0x0000, 0x8612 } ->		0000: e1  */	/* READ { 0, 0x0000, 0x8613 } ->		0000: fa  */	/* READ { 0, 0x0000, 0x8614 } ->		0000: f4  */	/* READ { 0, 0x0000, 0x8615 } ->		0000: e8  */	/* READ { 0, 0x0000, 0x8616 } ->		0000: 25  */	{}};static int reg_write(struct usb_device *dev,			__u16 index, __u16 value){	int ret;	ret = usb_control_msg(dev,			usb_sndctrlpipe(dev, 0),			0,		/* request */			USB_TYPE_VENDOR | USB_RECIP_DEVICE,			value, index, NULL, 0, 500);	PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x",		index, value);	if (ret < 0)		PDEBUG(D_ERR|D_USBO, "reg write: error %d", ret);	return ret;}/* read 1 byte *//* returns: negative is error, pos or zero is data */static int reg_read(struct gspca_dev *gspca_dev,			__u16 index)	/* wIndex */{	int ret;	ret = usb_control_msg(gspca_dev->dev,			usb_rcvctrlpipe(gspca_dev->dev, 0),			0,			/* register */			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			0,		/* value */			index,			gspca_dev->usb_buf, 1,			500);			/* timeout */	PDEBUG(D_USBI, "reg read i:%04x --> %02x",		index, gspca_dev->usb_buf[0]);	if (ret < 0) {		PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret);		return ret;	}	return gspca_dev->usb_buf[0];}static int write_vector(struct gspca_dev *gspca_dev,			const __u16 data[][3]){	struct usb_device *dev = gspca_dev->dev;	int ret, i = 0;	while (data[i][1] != 0) {		ret = reg_write(dev, data[i][1], data[i][0]);		if (ret < 0)			return ret;		i++;	}	return 0;}/* this function is called at probe time */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;	int data1, data2;	/* Read from global register the USB product and vendor IDs, just to	 * prove that we can communicate with the device.  This works, which	 * confirms at we are communicating properly and that the device	 * is a 508. */	data1 = reg_read(gspca_dev, 0x8104);	data2 = reg_read(gspca_dev, 0x8105);	PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1);	data1 = reg_read(gspca_dev, 0x8106);	data2 = reg_read(gspca_dev, 0x8107);	PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1);	data1 = reg_read(gspca_dev, 0x8621);	PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);	cam = &gspca_dev->cam;	cam->epaddr = 0x01;	cam->cam_mode = sif_mode;	cam->nmodes = ARRAY_SIZE(sif_mode);	sd->subtype = id->driver_info;	sd->brightness = BRIGHTNESS_DEF;	switch (sd->subtype) {	case ViewQuestVQ110:		if (write_vector(gspca_dev, spca508_init_data))			return -1;		break;	default:/*	case MicroInnovationIC200: *//*	case IntelEasyPCCamera: */		if (write_vector(gspca_dev, spca508cs110_init_data))			return -1;		break;	case HamaUSBSightcam:		if (write_vector(gspca_dev, spca508_sightcam_init_data))			return -1;		break;	case HamaUSBSightcam2:		if (write_vector(gspca_dev, spca508_sightcam2_init_data))			return -1;		break;	case CreativeVista:		if (write_vector(gspca_dev, spca508_vista_init_data))			return -1;		break;	}	return 0;			/* success */}/* this function is called at probe and resume time */static int sd_init(struct gspca_dev *gspca_dev){/*	write_vector(gspca_dev, spca508_open_data); */	return 0;}static int sd_start(struct gspca_dev *gspca_dev){	int mode;	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;	reg_write(gspca_dev->dev, 0x8500, mode);	switch (mode) {	case 0:	case 1:		reg_write(gspca_dev->dev, 0x8700, 0x28);	/* clock */		break;	default:/*	case 2: *//*	case 3: */		reg_write(gspca_dev->dev, 0x8700, 0x23);	/* clock */		break;	}	reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20);	return 0;}static void sd_stopN(struct gspca_dev *gspca_dev){	/* Video ISO disable, Video Drop Packet enable: */	reg_write(gspca_dev->dev, 0x8112, 0x20);}static void sd_pkt_scan(struct gspca_dev *gspca_dev,			struct gspca_frame *frame,	/* target */			__u8 *data,			/* isoc packet */			int len)			/* iso packet length */{	switch (data[0]) {	case 0:				/* start of frame */		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,					data, 0);		data += SPCA508_OFFSET_DATA;		len -= SPCA508_OFFSET_DATA;		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,				data, len);		break;	case 0xff:			/* drop *//*		gspca_dev->last_packet_type = DISCARD_PACKET; */		break;	default:		data += 1;		len -= 1;		gspca_frame_add(gspca_dev, INTER_PACKET, frame,				data, len);		break;	}}static void setbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 brightness = sd->brightness;	/* MX seem contrast */	reg_write(gspca_dev->dev, 0x8651, brightness);	reg_write(gspca_dev->dev, 0x8652, brightness);	reg_write(gspca_dev->dev, 0x8653, brightness);	reg_write(gspca_dev->dev, 0x8654, brightness);}static void getbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	sd->brightness = reg_read(gspca_dev, 0x8651);}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;}/* 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(0x0130, 0x0130), .driver_info = HamaUSBSightcam},	{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},	{USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200},	{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},	{USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},	{USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},	{USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera},	{}};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 + -
显示快捷键?