sonixj.c

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

C
1,721
字号
{	int i = 0;	static const __u8 SetSensorClk[] =	/* 0x08 Mclk */		{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };	while (hv7131r_sensor_init[i][0]) {		i2c_w8(gspca_dev, hv7131r_sensor_init[i]);		i++;	}	i2c_w8(gspca_dev, SetSensorClk);}static void mi0360_InitSensor(struct gspca_dev *gspca_dev){	int i = 0;	while (mi0360_sensor_init[i][0]) {		i2c_w8(gspca_dev, mi0360_sensor_init[i]);		i++;	}}static void mo4000_InitSensor(struct gspca_dev *gspca_dev){	int i = 0;	while (mo4000_sensor_init[i][0]) {		i2c_w8(gspca_dev, mo4000_sensor_init[i]);		i++;	}}static void om6802_InitSensor(struct gspca_dev *gspca_dev){	int i = 0;	while (om6802_sensor_init[i][0]) {		i2c_w8(gspca_dev, om6802_sensor_init[i]);		i++;	}}static void ov7630_InitSensor(struct gspca_dev *gspca_dev){	int i = 0;	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 76 01 */	i++;	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 (RGB+SRST) */	i++;	msleep(20);	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */	i++;	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 */	i++;	msleep(20);	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */	i++;/*jfm:win i2c_r from 00 to 80*/	while (ov7630_sensor_init[i][0]) {		i2c_w8(gspca_dev, ov7630_sensor_init[i]);		i++;	}}static void ov7648_InitSensor(struct gspca_dev *gspca_dev){	int i = 0;	while (ov7648_sensor_init[i][0]) {		i2c_w8(gspca_dev, ov7648_sensor_init[i]);		i++;	}}static void ov7660_InitSensor(struct gspca_dev *gspca_dev){	int i = 0;	i2c_w8(gspca_dev, ov7660_sensor_init[i]);	/* reset SCCB */	i++;	msleep(20);	while (ov7660_sensor_init[i][0]) {		i2c_w8(gspca_dev, ov7660_sensor_init[i]);		i++;	}}/* 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;	cam->nmodes = ARRAY_SIZE(vga_mode);	sd->bridge = id->driver_info >> 16;	sd->sensor = id->driver_info >> 8;	sd->i2c_base = id->driver_info;	sd->qindex = 4;			/* set the quantization table */	sd->brightness = BRIGHTNESS_DEF;	sd->contrast = CONTRAST_DEF;	sd->colors = COLOR_DEF;	sd->autogain = AUTOGAIN_DEF;	sd->ag_cnt = -1;	switch (sd->sensor) {	case SENSOR_OV7630:	case SENSOR_OV7648:	case SENSOR_OV7660:		gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);		break;	}	if (sd->sensor != SENSOR_OV7630)		gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);	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;/*	const __u8 *sn9c1xx; */	__u8 regGpio[] = { 0x29, 0x74 };	__u8 regF1;	/* setup a selector by bridge */	reg_w1(gspca_dev, 0xf1, 0x01);	reg_r(gspca_dev, 0x00, 1);	reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);	reg_r(gspca_dev, 0x00, 1);		/* get sonix chip id */	regF1 = gspca_dev->usb_buf[0];	PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);	switch (sd->bridge) {	case BRIDGE_SN9C102P:		if (regF1 != 0x11)			return -ENODEV;		reg_w1(gspca_dev, 0x02, regGpio[1]);		break;	case BRIDGE_SN9C105:		if (regF1 != 0x11)			return -ENODEV;		reg_w(gspca_dev, 0x01, regGpio, 2);		break;	case BRIDGE_SN9C120:		if (regF1 != 0x12)			return -ENODEV;		regGpio[1] = 0x70;		reg_w(gspca_dev, 0x01, regGpio, 2);		break;	default:/*	case BRIDGE_SN9C110: *//*	case BRIDGE_SN9C325: */		if (regF1 != 0x12)			return -ENODEV;		reg_w1(gspca_dev, 0x02, 0x62);		break;	}	reg_w1(gspca_dev, 0xf1, 0x01);#if 1 /*jfm: from win trace*/	return 0;#else	sn9c1xx = sn_tb[(int) sd->sensor];	return configure_gpio(gspca_dev, sn9c1xx);#endif}static unsigned int setexposure(struct gspca_dev *gspca_dev,				unsigned int expo){	struct sd *sd = (struct sd *) gspca_dev;	static const __u8 doit[] =		/* update sensor */		{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };	static const __u8 sensorgo[] =		/* sensor on */		{ 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };	static const __u8 gainMo[] =		{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };	switch (sd->sensor) {	case SENSOR_HV7131R: {		__u8 Expodoit[] =			{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };		Expodoit[3] = expo >> 16;		Expodoit[4] = expo >> 8;		Expodoit[5] = expo;		i2c_w8(gspca_dev, Expodoit);		break;	    }	case SENSOR_MI0360: {		__u8 expoMi[] =	 /* exposure 0x0635 -> 4 fp/s 0x10 */			{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };		if (expo > 0x0635)			expo = 0x0635;		else if (expo < 0x0001)			expo = 0x0001;		expoMi[3] = expo >> 8;		expoMi[4] = expo;		i2c_w8(gspca_dev, expoMi);		i2c_w8(gspca_dev, doit);		i2c_w8(gspca_dev, sensorgo);		break;	    }	case SENSOR_MO4000: {		__u8 expoMof[] =			{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };		__u8 expoMo10[] =			{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };		if (expo > 0x1fff)			expo = 0x1fff;		else if (expo < 0x0001)			expo = 0x0001;		expoMof[3] = (expo & 0x03fc) >> 2;		i2c_w8(gspca_dev, expoMof);		expoMo10[3] = ((expo & 0x1c00) >> 10)				| ((expo & 0x0003) << 4);		i2c_w8(gspca_dev, expoMo10);		i2c_w8(gspca_dev, gainMo);		PDEBUG(D_CONF, "set exposure %d",			((expoMo10[3] & 0x07) << 10)			| (expoMof[3] << 2)			| ((expoMo10[3] & 0x30) >> 4));		break;	    }	case SENSOR_OM6802: {		__u8 gainOm[] =			{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };		if (expo > 0x03ff)			expo = 0x03ff;		 if (expo < 0x0001)			expo = 0x0001;		gainOm[3] = expo >> 2;		i2c_w8(gspca_dev, gainOm);		reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);		PDEBUG(D_CONF, "set exposure %d", gainOm[3]);		break;	    }	}	return expo;}/* this function is used for sensors o76xx only */static void setbrightcont(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int val;	__u8 reg84_full[0x15];	memcpy(reg84_full, reg84, sizeof reg84_full);	val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10;	/* 10..40 */	reg84_full[0] = (val + 1) / 2;		/* red */	reg84_full[2] = val;			/* green */	reg84_full[4] = (val + 1) / 5;		/* blue */	val = (sd->brightness - BRIGHTNESS_DEF) * 0x10			/ BRIGHTNESS_MAX;	reg84_full[0x12] = val & 0x1f;		/* 5:0 signed value */	reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);}/* sensor != ov76xx */static void setbrightness(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	unsigned int expo;	__u8 k2;	k2 = sd->brightness >> 10;	switch (sd->sensor) {	case SENSOR_HV7131R:		expo = sd->brightness << 4;		if (expo > 0x002dc6c0)			expo = 0x002dc6c0;		else if (expo < 0x02a0)			expo = 0x02a0;		sd->exposure = setexposure(gspca_dev, expo);		break;	case SENSOR_MI0360:	case SENSOR_MO4000:		expo = sd->brightness >> 4;		sd->exposure = setexposure(gspca_dev, expo);		break;	case SENSOR_OM6802:		expo = sd->brightness >> 6;		sd->exposure = setexposure(gspca_dev, expo);		k2 = sd->brightness >> 11;		break;	}	reg_w1(gspca_dev, 0x96, k2);}/* sensor != ov76xx */static void setcontrast(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 k2;	__u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };	k2 = sd->contrast;	contrast[2] = k2;	contrast[0] = (k2 + 1) >> 1;	contrast[4] = (k2 + 1) / 5;	reg_w(gspca_dev, 0x84, contrast, 6);}static void setcolors(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	__u8 blue, red;	if (sd->colors >= 32) {		red = 32 + (sd->colors - 32) / 2;		blue = 64 - sd->colors;	} else {		red = sd->colors;		blue = 32 + (32 - sd->colors) / 2;	}	reg_w1(gspca_dev, 0x05, red);/*	reg_w1(gspca_dev, 0x07, 32); */	reg_w1(gspca_dev, 0x06, blue);}static void setautogain(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))		return;	if (sd->autogain)		sd->ag_cnt = AG_CNT_START;	else		sd->ag_cnt = -1;}static void setvflip(struct sd *sd){	if (sd->sensor != SENSOR_OV7630)		return;	i2c_w1(&sd->gspca_dev, 0x75,			/* COMN */		sd->vflip ? 0x82 : 0x02);}/* -- start the camera -- */static int sd_start(struct gspca_dev *gspca_dev){	struct sd *sd = (struct sd *) gspca_dev;	int i;	__u8 reg1, reg17, reg18;	const __u8 *sn9c1xx;	int mode;	static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };	static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };	static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */	static const __u8 CE_ov76xx[] =				{ 0x32, 0xdd, 0x32, 0xdd };	sn9c1xx = sn_tb[(int) sd->sensor];	configure_gpio(gspca_dev, sn9c1xx);	reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);	reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);	reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);	reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);	reg_w1(gspca_dev, 0xd2, 0x6a);		/* DC29 */	reg_w1(gspca_dev, 0xd3, 0x50);	reg_w1(gspca_dev, 0xc6, 0x00);	reg_w1(gspca_dev, 0xc7, 0x00);	reg_w1(gspca_dev, 0xc8, 0x50);	reg_w1(gspca_dev, 0xc9, 0x3c);	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);	switch (sd->sensor) {	case SENSOR_OV7630:		reg17 = 0xe2;		break;	case SENSOR_OV7648:		reg17 = 0xae;		break;#if 1/*jfm: from win trace */	case SENSOR_OV7660:		reg17 = 0xa0;		break;#endif	default:		reg17 = 0x60;		break;	}	reg_w1(gspca_dev, 0x17, reg17);	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);	reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);	for (i = 0; i < 8; i++)		reg_w(gspca_dev, 0x84, reg84, sizeof reg84);	switch (sd->sensor) {	case SENSOR_OV7660:		reg_w1(gspca_dev, 0x9a, 0x05);		break;	default:		reg_w1(gspca_dev, 0x9a, 0x08);		reg_w1(gspca_dev, 0x99, 0x59);		break;	}	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;	if (mode)		reg1 = 0x46;	/* 320 clk 48Mhz */	else		reg1 = 0x06;	/* 640 clk 24Mz */	reg17 = 0x61;	switch (sd->sensor) {	case SENSOR_HV7131R:		hv7131R_InitSensor(gspca_dev);		break;	case SENSOR_MI0360:		mi0360_InitSensor(gspca_dev);		break;

⌨️ 快捷键说明

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