spca500.c

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

C
1,126
字号
		PDEBUG(D_ERR, "reg_r_wait() failed");		return err;	}	/* all ok */	return 0;}/* Synchro the Bridge with sensor *//* Maybe that will work on all spca500 chip *//* because i only own a clicksmart310 try for that chip *//* using spca50x_set_packet_size() cause an Ooops here *//* usb_set_interface from kernel 2.6.x clear all the urb stuff *//* up-port the same feature as in 2.4.x kernel */static int spca500_synch310(struct gspca_dev *gspca_dev){	if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {		PDEBUG(D_ERR, "Set packet size: set interface error");		goto error;	}	spca500_ping310(gspca_dev);	reg_r(gspca_dev, 0x0d00, 1);	/* need alt setting here */	PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);	/* Windoze use pipe with altsetting 6 why 7 here */	if (usb_set_interface(gspca_dev->dev,				gspca_dev->iface,				gspca_dev->alt) < 0) {		PDEBUG(D_ERR, "Set packet size: set interface error");		goto error;	}	return 0;error:	return -EBUSY;}static void spca500_reinit(struct gspca_dev *gspca_dev){	int err;	__u8 Data;	/* some unknow command from Aiptek pocket dv and family300 */	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);	/* enable drop packet */	reg_w(gspca_dev, 0x00, 0x850a, 0x0001);	err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,				 qtable_pocketdv);	if (err < 0)		PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");	/* set qtable index */	reg_w(gspca_dev, 0x00, 0x8880, 2);	/* family cam Quicksmart stuff */	reg_w(gspca_dev, 0x00, 0x800a, 0x00);	/* Set agc transfer: synced inbetween frames */	reg_w(gspca_dev, 0x00, 0x820f, 0x01);	/* Init SDRAM - needed for SDRAM access */	reg_w(gspca_dev, 0x00, 0x870a, 0x04);	/*Start init sequence or stream */	reg_w(gspca_dev, 0, 0x8003, 0x00);	/* switch to video camera mode */	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);	msleep(2000);	if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);	}}/* 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;	cam = &gspca_dev->cam;	cam->epaddr = 0x01;	sd->subtype = id->driver_info;	if (sd->subtype != LogitechClickSmart310) {		cam->cam_mode = vga_mode;		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];	} else {		cam->cam_mode = sif_mode;		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];	}	sd->qindex = 5;	sd->brightness = BRIGHTNESS_DEF;	sd->contrast = CONTRAST_DEF;	sd->colors = COLOR_DEF;	return 0;}/* this function is called at probe and resume time */static int sd_init(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	/* initialisation of spca500 based cameras is deferred */	PDEBUG(D_STREAM, "SPCA500 init");	if (sd->subtype == LogitechClickSmart310)		spca500_clksmart310_init(gspca_dev);/*	else		spca500_initialise(gspca_dev); */	PDEBUG(D_STREAM, "SPCA500 init done");	return 0;}static int sd_start(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int err;	__u8 Data;	__u8 xmult, ymult;	if (sd->subtype == LogitechClickSmart310) {		xmult = 0x16;		ymult = 0x12;	} else {		xmult = 0x28;		ymult = 0x1e;	}	/* is there a sensor here ? */	reg_r(gspca_dev, 0x8a04, 1);	PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",		gspca_dev->usb_buf[0]);	PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",		gspca_dev->curr_mode, xmult, ymult);	/* setup qtable */	switch (sd->subtype) {	case LogitechClickSmart310:		 spca500_setmode(gspca_dev, xmult, ymult);		/* enable drop packet */		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);		reg_w(gspca_dev, 0x00, 0x8880, 3);		err = spca50x_setup_qtable(gspca_dev,					   0x00, 0x8800, 0x8840,					   qtable_creative_pccam);		if (err < 0)			PDEBUG(D_ERR, "spca50x_setup_qtable failed");		/* Init SDRAM - needed for SDRAM access */		reg_w(gspca_dev, 0x00, 0x870a, 0x04);		/* switch to video camera mode */		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);		msleep(500);		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)			PDEBUG(D_ERR, "reg_r_wait() failed");		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);		spca500_synch310(gspca_dev);		write_vector(gspca_dev, spca500_visual_defaults);		spca500_setmode(gspca_dev, xmult, ymult);		/* enable drop packet */		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);			PDEBUG(D_ERR, "failed to enable drop packet");		reg_w(gspca_dev, 0x00, 0x8880, 3);		err = spca50x_setup_qtable(gspca_dev,					   0x00, 0x8800, 0x8840,					   qtable_creative_pccam);		if (err < 0)			PDEBUG(D_ERR, "spca50x_setup_qtable failed");		/* Init SDRAM - needed for SDRAM access */		reg_w(gspca_dev, 0x00, 0x870a, 0x04);		/* switch to video camera mode */		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)			PDEBUG(D_ERR, "reg_r_wait() failed");		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);		break;	case CreativePCCam300:		/* Creative PC-CAM 300 640x480 CCD */	case IntelPocketPCCamera:	/* FIXME: Temporary fix for					 *	Intel Pocket PC Camera					 *	- NWG (Sat 29th March 2003) */		/* do a full reset */		err = spca500_full_reset(gspca_dev);		if (err < 0)			PDEBUG(D_ERR, "spca500_full_reset failed");		/* enable drop packet */		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);		if (err < 0)			PDEBUG(D_ERR, "failed to enable drop packet");		reg_w(gspca_dev, 0x00, 0x8880, 3);		err = spca50x_setup_qtable(gspca_dev,					   0x00, 0x8800, 0x8840,					   qtable_creative_pccam);		if (err < 0)			PDEBUG(D_ERR, "spca50x_setup_qtable failed");		spca500_setmode(gspca_dev, xmult, ymult);		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);		/* switch to video camera mode */		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)			PDEBUG(D_ERR, "reg_r_wait() failed");		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);/*		write_vector(gspca_dev, spca500_visual_defaults); */		break;	case KodakEZ200:		/* Kodak EZ200 */		/* do a full reset */		err = spca500_full_reset(gspca_dev);		if (err < 0)			PDEBUG(D_ERR, "spca500_full_reset failed");		/* enable drop packet */		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);		reg_w(gspca_dev, 0x00, 0x8880, 0);		err = spca50x_setup_qtable(gspca_dev,					   0x00, 0x8800, 0x8840,					   qtable_kodak_ez200);		if (err < 0)			PDEBUG(D_ERR, "spca50x_setup_qtable failed");		spca500_setmode(gspca_dev, xmult, ymult);		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);		/* switch to video camera mode */		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)			PDEBUG(D_ERR, "reg_r_wait() failed");		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);/*		write_vector(gspca_dev, spca500_visual_defaults); */		break;	case BenqDC1016:	case DLinkDSC350:		/* FamilyCam 300 */	case AiptekPocketDV:		/* Aiptek PocketDV */	case Gsmartmini:		/*Mustek Gsmart Mini */	case MustekGsmart300:		/* Mustek Gsmart 300 */	case PalmPixDC85:	case Optimedia:	case ToptroIndus:	case AgfaCl20:		spca500_reinit(gspca_dev);		reg_w(gspca_dev, 0x00, 0x0d01, 0x01);		/* enable drop packet */		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);		err = spca50x_setup_qtable(gspca_dev,				   0x00, 0x8800, 0x8840, qtable_pocketdv);		if (err < 0)			PDEBUG(D_ERR, "spca50x_setup_qtable failed");		reg_w(gspca_dev, 0x00, 0x8880, 2);		/* familycam Quicksmart pocketDV stuff */		reg_w(gspca_dev, 0x00, 0x800a, 0x00);		/* Set agc transfer: synced inbetween frames */		reg_w(gspca_dev, 0x00, 0x820f, 0x01);		/* Init SDRAM - needed for SDRAM access */		reg_w(gspca_dev, 0x00, 0x870a, 0x04);		spca500_setmode(gspca_dev, xmult, ymult);		/* switch to video camera mode */		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);		break;	case LogitechTraveler:	case LogitechClickSmart510:		reg_w(gspca_dev, 0x02, 0x00, 0x00);		/* enable drop packet */		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);		err = spca50x_setup_qtable(gspca_dev,					0x00, 0x8800,					0x8840, qtable_creative_pccam);		if (err < 0)			PDEBUG(D_ERR, "spca50x_setup_qtable failed");		reg_w(gspca_dev, 0x00, 0x8880, 3);		reg_w(gspca_dev, 0x00, 0x800a, 0x00);		/* Init SDRAM - needed for SDRAM access */		reg_w(gspca_dev, 0x00, 0x870a, 0x04);		spca500_setmode(gspca_dev, xmult, ymult);		/* switch to video camera mode */		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);		reg_r(gspca_dev, 0x816b, 1);		Data = gspca_dev->usb_buf[0];		reg_w(gspca_dev, 0x00, 0x816b, Data);		write_vector(gspca_dev, Clicksmart510_defaults);		break;	}	return 0;}static void sd_stopN(struct gspca_dev *gspca_dev){	reg_w(gspca_dev, 0, 0x8003, 0x00);	/* switch to video camera mode */	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);	reg_r(gspca_dev, 0x8000, 1);	PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",		gspca_dev->usb_buf[0]);}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;	int i;	__u8 *s, *d;	static __u8 ffd9[] = {0xff, 0xd9};/* frames are jpeg 4.1.1 without 0xff escape */	if (data[0] == 0xff) {		if (data[1] != 0x01) {	/* drop packet *//*			gspca_dev->last_packet_type = DISCARD_PACKET; */			return;		}		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,					ffd9, 2);		/* put the JPEG header in the new frame */		jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);		data += SPCA500_OFFSET_DATA;		len -= SPCA500_OFFSET_DATA;	} else {		data += 1;		len -= 1;	}	/* add 0x00 after 0xff */	for (i = len; --i >= 0; )		if (data[i] == 0xff)			break;	if (i < 0) {			/* no 0xff */		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);		return;	}	s = data;	d = sd->packet;	for (i = 0; i < len; i++) {		*d++ = *s++;		if (s[-1] == 0xff)			*d++ = 0x00;	}	gspca_frame_add(gspca_dev, INTER_PACKET, frame,			sd->packet, d - sd->packet);}static void setbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	reg_w(gspca_dev, 0x00, 0x8167,			(__u8) (sd->brightness - 128));}static void getbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int ret;	ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);	if (ret >= 0)		sd->brightness = ret + 128;}static void setcontrast(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);}static void getcontrast(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int ret;	ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);	if (ret >= 0)		sd->contrast = ret;}static void setcolors(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	reg_w(gspca_dev, 0x00, 0x8169, sd->colors);}static void getcolors(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int ret;	ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);	if (ret >= 0)		sd->colors = ret;}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;}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_setcolors(struct gspca_dev *gspca_dev, __s32 val){	struct sd *sd = (struct sd *) gspca_dev;	sd->colors = val;	if (gspca_dev->streaming)		setcolors(gspca_dev);	return 0;}static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val){	struct sd *sd = (struct sd *) gspca_dev;	getcolors(gspca_dev);	*val = sd->colors;	return 0;}/* sub-driver description */static 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(0x040a, 0x0300), .driver_info = KodakEZ200},	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},	{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},	{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},	{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},	{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},	{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},	{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},	{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},	{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},	{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},	{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},	{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},	{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},	{}};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 + -
显示快捷键?