t613.c

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

C
1,192
字号
	 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,	 0xa0, 0xff},	{0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a,	/* 14 */	 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,	 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,	 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,	 0xa0, 0xff},	{0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7,	/* 15 */	 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,	 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,	 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,	 0xa0, 0xff}};static const __u8 tas5130a_sensor_init[][8] = {	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},	{},};static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};/* read 1 byte */static int reg_r(struct gspca_dev *gspca_dev,		   __u16 index){	usb_control_msg(gspca_dev->dev,			usb_rcvctrlpipe(gspca_dev->dev, 0),			0,		/* request */			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			0,		/* value */			index,			gspca_dev->usb_buf, 1, 500);	return gspca_dev->usb_buf[0];}static void reg_w(struct gspca_dev *gspca_dev,		  __u16 index){	usb_control_msg(gspca_dev->dev,			usb_sndctrlpipe(gspca_dev->dev, 0),			0,			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			0, index,			NULL, 0, 500);}static void reg_w_buf(struct gspca_dev *gspca_dev,		  const __u8 *buffer, __u16 len){	if (len <= USB_BUF_SZ) {		memcpy(gspca_dev->usb_buf, buffer, len);		usb_control_msg(gspca_dev->dev,				usb_sndctrlpipe(gspca_dev->dev, 0),				0,			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,				0x01, 0,				gspca_dev->usb_buf, len, 500);	} else {		__u8 *tmpbuf;		tmpbuf = kmalloc(len, GFP_KERNEL);		memcpy(tmpbuf, buffer, len);		usb_control_msg(gspca_dev->dev,				usb_sndctrlpipe(gspca_dev->dev, 0),				0,			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,				0x01, 0,				tmpbuf, len, 500);		kfree(tmpbuf);	}}/* Reported as OM6802*/static void om6802_sensor_init(struct gspca_dev *gspca_dev){	int i;	const __u8 *p;	__u8 byte;	__u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};	static const __u8 sensor_init[] = {		0xdf, 0x6d,		0xdd, 0x18,		0x5a, 0xe0,		0x5c, 0x07,		0x5d, 0xb0,		0x5e, 0x1e,		0x60, 0x71,		0xef, 0x00,		0xe9, 0x00,		0xea, 0x00,		0x90, 0x24,		0x91, 0xb2,		0x82, 0x32,		0xfd, 0x41,		0x00			/* table end */	};	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);	msleep(5);	i = 4;	while (--i < 0) {		byte = reg_r(gspca_dev, 0x0060);		if (!(byte & 0x01))			break;		msleep(100);	}	byte = reg_r(gspca_dev, 0x0063);	if (byte != 0x17) {		err("Bad sensor reset %02x", byte);		/* continue? */	}	p = sensor_init;	while (*p != 0) {		val[1] = *p++;		val[3] = *p++;		if (*p == 0)			reg_w(gspca_dev, 0x3c80);		reg_w_buf(gspca_dev, val, sizeof val);		i = 4;		while (--i >= 0) {			msleep(15);			byte = reg_r(gspca_dev, 0x60);			if (!(byte & 0x01))				break;		}	}	msleep(15);	reg_w(gspca_dev, 0x3c80);}/* 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;	cam->cam_mode = vga_mode_t16;	cam->nmodes = ARRAY_SIZE(vga_mode_t16);	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;	sd->gamma = GAMMA_DEF;	sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;	sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;	sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;	sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;	sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;	return 0;}static void setbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	unsigned int brightness;	__u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };	brightness = sd->brightness;	if (brightness < 7) {		set6[1] = 0x26;		set6[3] = 0x70 - brightness * 0x10;	} else {		set6[3] = 0x00 + ((brightness - 7) * 0x10);	}	reg_w_buf(gspca_dev, set6, sizeof set6);}static void setcontrast(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	unsigned int contrast = sd->contrast;	__u16 reg_to_write;	if (contrast < 7)		reg_to_write = 0x8ea9 - contrast * 0x200;	else		reg_to_write = 0x00a9 + (contrast - 7) * 0x200;	reg_w(gspca_dev, reg_to_write);}static void setcolors(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u16 reg_to_write;	reg_to_write = 0x80bb + sd->colors * 0x100;	/* was 0xc0 */	reg_w(gspca_dev, reg_to_write);}static void setgamma(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	PDEBUG(D_CONF, "Gamma: %d", sd->gamma);	reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);}static void setwhitebalance(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 white_balance[8] =		{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};	if (sd->whitebalance)		white_balance[7] = 0x3c;	reg_w_buf(gspca_dev, white_balance, sizeof white_balance);}static void setsharpness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u16 reg_to_write;	reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;	reg_w(gspca_dev, reg_to_write);}/* this function is called at probe and resume time */static int sd_init(struct gspca_dev *gspca_dev){	/* some of this registers are not really neded, because	 * they are overriden by setbrigthness, setcontrast, etc,	 * but wont hurt anyway, and can help someone with similar webcam	 * to see the initial parameters.*/	struct sd *sd = (struct sd *) gspca_dev;	int i;	__u8 byte, test_byte;	static const __u8 read_indexs[] =		{ 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };	static const __u8 n1[] =			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};	static const __u8 n2[] =			{0x08, 0x00};	static const __u8 n3[] =			{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};	static const __u8 n4[] =		{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,		 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,		 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,		 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,		 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,		 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,		 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,		 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,		 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};	static const __u8 nset9[4] =			{ 0x0b, 0x04, 0x0a, 0x78 };	static const __u8 nset8[6] =			{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };	byte = reg_r(gspca_dev, 0x06);	test_byte = reg_r(gspca_dev, 0x07);	if (byte == 0x08 && test_byte == 0x07) {		PDEBUG(D_CONF, "sensor om6802");		sd->sensor = SENSOR_OM6802;	} else if (byte == 0x08 && test_byte == 0x01) {		PDEBUG(D_CONF, "sensor tas5130a");		sd->sensor = SENSOR_TAS5130A;	} else {		PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);		sd->sensor = SENSOR_TAS5130A;	}	reg_w_buf(gspca_dev, n1, sizeof n1);	test_byte = 0;	i = 5;	while (--i >= 0) {		reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);		test_byte = reg_r(gspca_dev, 0x0063);		msleep(100);		if (test_byte == 0x17)			break;		/* OK */	}	if (i < 0) {		err("Bad sensor reset %02x", test_byte);/*		return -EIO; *//*fixme: test - continue */	}	reg_w_buf(gspca_dev, n2, sizeof n2);	i = 0;	while (read_indexs[i] != 0x00) {		test_byte = reg_r(gspca_dev, read_indexs[i]);		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],		       test_byte);		i++;	}	reg_w_buf(gspca_dev, n3, sizeof n3);	reg_w_buf(gspca_dev, n4, sizeof n4);	reg_r(gspca_dev, 0x0080);	reg_w(gspca_dev, 0x2c80);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,			sizeof sensor_data[sd->sensor].data1);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,			sizeof sensor_data[sd->sensor].data3);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,			sizeof sensor_data[sd->sensor].data2);	reg_w(gspca_dev, 0x3880);	reg_w(gspca_dev, 0x3880);	reg_w(gspca_dev, 0x338e);	setbrightness(gspca_dev);	setcontrast(gspca_dev);	setgamma(gspca_dev);	setcolors(gspca_dev);	setsharpness(gspca_dev);	setwhitebalance(gspca_dev);	reg_w(gspca_dev, 0x2087);	/* tied to white balance? */	reg_w(gspca_dev, 0x2088);	reg_w(gspca_dev, 0x2089);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,			sizeof sensor_data[sd->sensor].data4);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,			sizeof sensor_data[sd->sensor].data5);	reg_w_buf(gspca_dev, nset8, sizeof nset8);	reg_w_buf(gspca_dev, nset9, sizeof nset9);	reg_w(gspca_dev, 0x2880);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,			sizeof sensor_data[sd->sensor].data1);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,			sizeof sensor_data[sd->sensor].data3);	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,			sizeof sensor_data[sd->sensor].data2);	return 0;}static void setflip(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 flipcmd[8] =		{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};	if (sd->mirror)		flipcmd[3] = 0x01;	reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);}static void seteffect(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	reg_w_buf(gspca_dev, effects_table[sd->effect],				sizeof effects_table[0]);	if (sd->effect == 1 || sd->effect == 5) {		PDEBUG(D_CONF,		       "This effect have been disabled for webcam \"safety\"");		return;	}	if (sd->effect == 1 || sd->effect == 4)		reg_w(gspca_dev, 0x4aa6);	else		reg_w(gspca_dev, 0xfaa6);}static void setlightfreq(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };	if (sd->freq == 2)	/* 60hz */		freq[1] = 0x00;	reg_w_buf(gspca_dev, freq, sizeof freq);}/* Is this really needed? * i added some module parameters for test with some users */static void poll_sensor(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	static const __u8 poll1[] =		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,

⌨️ 快捷键说明

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