⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sunplus.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* write <len> bytes from gspca_dev->usb_buf */static void reg_w(struct gspca_dev *gspca_dev,		   __u16 req,		   __u16 value,		   __u16 index,		   __u16 len){#ifdef GSPCA_DEBUG	if (len > USB_BUF_SZ) {		err("reg_w: buffer overflow");		return;	}#endif	usb_control_msg(gspca_dev->dev,			usb_sndctrlpipe(gspca_dev->dev, 0),			req,			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			value, index,			len ? gspca_dev->usb_buf : NULL, len,			500);}/* write req / index / value */static int reg_w_riv(struct usb_device *dev,		     __u16 req, __u16 index, __u16 value){	int ret;	ret = usb_control_msg(dev,			usb_sndctrlpipe(dev, 0),			req,			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			value, index, NULL, 0, 500);	PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",		req, index, value, ret);	if (ret < 0)		PDEBUG(D_ERR, "reg write: error %d", ret);	return ret;}/* read 1 byte */static int reg_r_1(struct gspca_dev *gspca_dev,			__u16 value)	/* wValue */{	int ret;	ret = usb_control_msg(gspca_dev->dev,			usb_rcvctrlpipe(gspca_dev->dev, 0),			0x20,			/* request */			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			value,			0,			/* index */			gspca_dev->usb_buf, 1,			500);			/* timeout */	if (ret < 0) {		PDEBUG(D_ERR, "reg_r_1 err %d", ret);		return 0;	}	return gspca_dev->usb_buf[0];}/* read 1 or 2 bytes - returns < 0 if error */static int reg_r_12(struct gspca_dev *gspca_dev,			__u16 req,	/* bRequest */			__u16 index,	/* wIndex */			__u16 length)	/* wLength (1 or 2 only) */{	int ret;	gspca_dev->usb_buf[1] = 0;	ret = usb_control_msg(gspca_dev->dev,			usb_rcvctrlpipe(gspca_dev->dev, 0),			req,			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			0,		/* value */			index,			gspca_dev->usb_buf, length,			500);	if (ret < 0) {		PDEBUG(D_ERR, "reg_read err %d", ret);		return -1;	}	return (gspca_dev->usb_buf[1] << 8) + 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][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {		ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);		if (ret < 0) {			PDEBUG(D_ERR,				"Register write failed for 0x%x,0x%x,0x%x",				data[i][0], data[i][1], data[i][2]);			return ret;		}		i++;	}	return 0;}static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,				unsigned int request,				unsigned int ybase,				unsigned int cbase,				const __u8 qtable[2][64]){	struct usb_device *dev = gspca_dev->dev;	int i, err;	/* loop over y components */	for (i = 0; i < 64; i++) {		err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);		if (err < 0)			return err;	}	/* loop over c components */	for (i = 0; i < 64; i++) {		err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);		if (err < 0)			return err;	}	return 0;}static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,			     __u16 req, __u16 idx, __u16 val){	struct usb_device *dev = gspca_dev->dev;	__u8 notdone;	reg_w_riv(dev, req, idx, val);	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);	reg_w_riv(dev, req, idx, val);	PDEBUG(D_FRAM, "before wait 0x%x", notdone);	msleep(200);	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);	PDEBUG(D_FRAM, "after wait 0x%x", notdone);}static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,			__u16 req,			__u16 idx, __u16 val, __u8 stat, __u8 count){	struct usb_device *dev = gspca_dev->dev;	__u8 status;	__u8 endcode;	reg_w_riv(dev, req, idx, val);	status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);	endcode = stat;	PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);	if (!count)		return;	count = 200;	while (--count > 0) {		msleep(10);		/* gsmart mini2 write a each wait setting 1 ms is enought *//*		reg_w_riv(dev, req, idx, val); */		status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);		if (status == endcode) {			PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",				status, 200 - count);				break;		}	}}static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev){	int count = 10;	while (--count > 0) {		reg_r(gspca_dev, 0x21, 0, 1);		if ((gspca_dev->usb_buf[0] & 0x01) == 0)			break;		msleep(10);	}	return gspca_dev->usb_buf[0];}static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev){	int count = 50;	while (--count > 0) {		reg_r(gspca_dev, 0x21, 1, 1);		if (gspca_dev->usb_buf[0] != 0) {			gspca_dev->usb_buf[0] = 0;			reg_w(gspca_dev, 0x21, 0, 1, 1);			reg_r(gspca_dev, 0x21, 1, 1);			spca504B_PollingDataReady(gspca_dev);			break;		}		msleep(10);	}}static void spca50x_GetFirmware(struct gspca_dev *gspca_dev){	__u8 *data;	data = gspca_dev->usb_buf;	reg_r(gspca_dev, 0x20, 0, 5);	PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",		data[0], data[1], data[2], data[3], data[4]);	reg_r(gspca_dev, 0x23, 0, 64);	reg_r(gspca_dev, 0x23, 1, 64);}static void spca504B_SetSizeType(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	struct usb_device *dev = gspca_dev->dev;	__u8 Size;	__u8 Type;	int rc;	Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;	Type = 0;	switch (sd->bridge) {	case BRIDGE_SPCA533:		reg_w(gspca_dev, 0x31, 0, 0, 0);		spca504B_WaitCmdStatus(gspca_dev);		rc = spca504B_PollingDataReady(gspca_dev);		spca50x_GetFirmware(gspca_dev);		gspca_dev->usb_buf[0] = 2;			/* type */		reg_w(gspca_dev, 0x24, 0, 8, 1);		reg_r(gspca_dev, 0x24, 8, 1);		gspca_dev->usb_buf[0] = Size;		reg_w(gspca_dev, 0x25, 0, 4, 1);		reg_r(gspca_dev, 0x25, 4, 1);			/* size */		rc = spca504B_PollingDataReady(gspca_dev);		/* Init the cam width height with some values get on init ? */		reg_w(gspca_dev, 0x31, 0, 4, 0);		spca504B_WaitCmdStatus(gspca_dev);		rc = spca504B_PollingDataReady(gspca_dev);		break;	default:/* case BRIDGE_SPCA504B: *//* case BRIDGE_SPCA536: */		gspca_dev->usb_buf[0] = Size;		reg_w(gspca_dev, 0x25, 0, 4, 1);		reg_r(gspca_dev, 0x25, 4, 1);			/* size */		Type = 6;		gspca_dev->usb_buf[0] = Type;		reg_w(gspca_dev, 0x27, 0, 0, 1);		reg_r(gspca_dev, 0x27, 0, 1);			/* type */		rc = spca504B_PollingDataReady(gspca_dev);		break;	case BRIDGE_SPCA504:		Size += 3;		if (sd->subtype == AiptekMiniPenCam13) {			/* spca504a aiptek */			spca504A_acknowledged_command(gspca_dev,						0x08, Size, 0,						0x80 | (Size & 0x0f), 1);			spca504A_acknowledged_command(gspca_dev,							1, 3, 0, 0x9f, 0);		} else {			spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);		}		break;	case BRIDGE_SPCA504C:		/* capture mode */		reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);		reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));		break;	}}static void spca504_wait_status(struct gspca_dev *gspca_dev){	int cnt;	cnt = 256;	while (--cnt > 0) {		/* With this we get the status, when return 0 it's all ok */		if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)			return;		msleep(10);	}}static void spca504B_setQtable(struct gspca_dev *gspca_dev){	gspca_dev->usb_buf[0] = 3;	reg_w(gspca_dev, 0x26, 0, 0, 1);	reg_r(gspca_dev, 0x26, 0, 1);	spca504B_PollingDataReady(gspca_dev);}static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int pollreg = 1;	switch (sd->bridge) {	case BRIDGE_SPCA504:	case BRIDGE_SPCA504C:		pollreg = 0;		/* fall thru */	default:/*	case BRIDGE_SPCA533: *//*	case BRIDGE_SPCA504B: */		reg_w(gspca_dev, 0, 0, 0x21a7, 0);	/* brightness */		reg_w(gspca_dev, 0, 0x20, 0x21a8, 0);	/* contrast */		reg_w(gspca_dev, 0, 0, 0x21ad, 0);	/* hue */		reg_w(gspca_dev, 0, 1, 0x21ac, 0);	/* sat/hue */		reg_w(gspca_dev, 0, 0x20, 0x21ae, 0);	/* saturation */		reg_w(gspca_dev, 0, 0, 0x21a3, 0);	/* gamma */		break;	case BRIDGE_SPCA536:		reg_w(gspca_dev, 0, 0, 0x20f0, 0);		reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);		reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);		reg_w(gspca_dev, 0, 1, 0x20f4, 0);		reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);		reg_w(gspca_dev, 0, 0, 0x2089, 0);		break;	}	if (pollreg)		spca504B_PollingDataReady(gspca_dev);}/* 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->bridge = id->driver_info >> 8;	sd->subtype = id->driver_info;	if (sd->subtype == AiptekMiniPenCam13) {/* try to get the firmware as some cam answer 2.0.1.2.2 * and should be a spca504b then overwrite that setting */		reg_r(gspca_dev, 0x20, 0, 1);		switch (gspca_dev->usb_buf[0]) {		case 1:			break;		/* (right bridge/subtype) */		case 2:			sd->bridge = BRIDGE_SPCA504B;			sd->subtype = 0;			break;		default:			return -ENODEV;		}	}	switch (sd->bridge) {	default:/*	case BRIDGE_SPCA504B: *//*	case BRIDGE_SPCA504: *//*	case BRIDGE_SPCA536: */		cam->cam_mode = vga_mode;		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];		break;	case BRIDGE_SPCA533:		cam->cam_mode = custom_mode;		cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];		break;	case BRIDGE_SPCA504C:		cam->cam_mode = vga_mode2;		cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];		break;	}	sd->qindex = 5;			/* set the quantization table */	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;	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;	struct usb_device *dev = gspca_dev->dev;	int rc;	__u8 i;	__u8 info[6];	int err_code;	switch (sd->bridge) {	case BRIDGE_SPCA504B:		reg_w(gspca_dev, 0x1d, 0, 0, 0);		reg_w(gspca_dev, 0, 1, 0x2306, 0);		reg_w(gspca_dev, 0, 0, 0x0d04, 0);		reg_w(gspca_dev, 0, 0, 0x2000, 0);		reg_w(gspca_dev, 0, 0x13, 0x2301, 0);		reg_w(gspca_dev, 0, 0, 0x2306, 0);		/* fall thru */	case BRIDGE_SPCA533:		rc = spca504B_PollingDataReady(gspca_dev);		spca50x_GetFirmware(gspca_dev);		break;	case BRIDGE_SPCA536:		spca50x_GetFirmware(gspca_dev);		reg_r(gspca_dev, 0x00, 0x5002, 1);		gspca_dev->usb_buf[0] = 0;		reg_w(gspca_dev, 0x24, 0, 0, 1);		reg_r(gspca_dev, 0x24, 0, 1);		rc = spca504B_PollingDataReady(gspca_dev);		reg_w(gspca_dev, 0x34, 0, 0, 0);		spca504B_WaitCmdStatus(gspca_dev);		break;	case BRIDGE_SPCA504C:	/* pccam600 */		PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");		reg_w_riv(dev, 0xe0, 0x0000, 0x0000);		reg_w_riv(dev, 0xe0, 0x0000, 0x0001);	/* reset */		spca504_wait_status(gspca_dev);		if (sd->subtype == LogitechClickSmart420)			write_vector(gspca_dev,					spca504A_clicksmart420_open_data);		else			write_vector(gspca_dev, spca504_pccam600_open_data);		err_code = spca50x_setup_qtable(gspca_dev,						0x00, 0x2800,						0x2840, qtable_creative_pccam);		if (err_code < 0) {			PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");			return err_code;		}		break;	default:/*	case BRIDGE_SPCA504: */		PDEBUG(D_STREAM, "Opening SPCA504");		if (sd->subtype == AiptekMiniPenCam13) {			/*****************************/			for (i = 0; i < 6; i++)				info[i] = reg_r_1(gspca_dev, i);			PDEBUG(D_STREAM,				"Read info: %d %d %d %d %d %d."				" Should be 1,0,2,2,0,0",				info[0], info[1], info[2],				info[3], info[4], info[5]);			/* spca504a aiptek */			/* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */			spca504A_acknowledged_command(gspca_dev, 0x24,							8, 3, 0x9e, 1);			/* Twice sequencial need status 0xff->0x9e->0x9d */			spca504A_acknowledged_command(gspca_dev, 0x24,							8, 3, 0x9e, 0);			spca504A_acknowledged_command(gspca_dev, 0x24,							0, 0, 0x9d, 1);			/******************************/			/* spca504a aiptek */			spca504A_acknowledged_command(gspca_dev, 0x08,							6, 0, 0x86, 1);/*			reg_write (dev, 0, 0x2000, 0); *//*			reg_write (dev, 0, 0x2883, 1); *//*			spca504A_acknowledged_command (gspca_dev, 0x08,							6, 0, 0x86, 1); *//*			spca504A_acknowledged_command (gspca_dev, 0x24,							0, 0, 0x9D, 1); */			reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */			reg_w_riv(dev, 0x0, 0x2310, 0x05);			spca504A_acknowledged_command(gspca_dev, 0x01,							0x0f, 0, 0xff, 0);		}		/* setup qtable */		reg_w_riv(dev, 0, 0x2000, 0);		reg_w_riv(dev, 0, 0x2883, 1);		err_code = spca50x_setup_qtable(gspca_dev,						0x00, 0x2800,						0x2840,						qtable_spca504_default);		if (err_code < 0) {			PDEBUG(D_ERR, "spca50x_setup_qtable failed");			return err_code;		}		break;	}	return 0;}static int sd_start(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	struct usb_device *dev = gspca_dev->dev;	int rc;	int enable;	__u8 i;	__u8 info[6];	if (sd->bridge == BRIDGE_SPCA504B)		spca504B_setQtable(gspca_dev);	spca504B_SetSizeType(gspca_dev);	switch (sd->bridge) {	default:

⌨️ 快捷键说明

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