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

📄 pwc-ctrl.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);}static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise){	int ret;	unsigned char buf;		ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);	if (ret < 0)		return ret;	*noise = buf;	return 0;}int pwc_mpt_reset(struct pwc_device *pdev, int flags){	unsigned char buf;		buf = flags & 0x03; // only lower two bits are currently used	return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);}static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt){	unsigned char buf[4];		/* set new relative angle; angles are expressed in degrees * 100,	   but cam as .5 degree resolution, hence devide by 200. Also	   the angle must be multiplied by 64 before it's send to	   the cam (??)	 */	pan  =  64 * pan  / 100;	tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */	buf[0] = pan & 0xFF;	buf[1] = (pan >> 8) & 0xFF;	buf[2] = tilt & 0xFF;	buf[3] = (tilt >> 8) & 0xFF;	return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);}static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status){	int ret;	unsigned char buf[5];		ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);	if (ret < 0)		return ret;	status->status = buf[0] & 0x7; // 3 bits are used for reporting	status->time_pan = (buf[1] << 8) + buf[2];	status->time_tilt = (buf[3] << 8) + buf[4];	return 0;}int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor){	unsigned char buf;	int ret = -1, request;		if (pdev->type < 675)		request = SENSOR_TYPE_FORMATTER1;	else if (pdev->type < 730)		return -1; /* The Vesta series doesn't have this call */	else		request = SENSOR_TYPE_FORMATTER2;		ret = RecvControlMsg(GET_STATUS_CTL, request, 1);	if (ret < 0)		return ret;	if (pdev->type < 675)		*sensor = buf | 0x100;	else		*sensor = buf;	return 0;} /* End of Add-Ons                                    */ /* ************************************************* *//* Linux 2.5.something and 2.6 pass direct pointers to arguments of   ioctl() calls. With 2.4, you have to do tedious copy_from_user()   and copy_to_user() calls. With these macros we circumvent this,   and let me maintain only one source file. The functionality is   exactly the same otherwise. */   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)/* define local variable for arg */#define ARG_DEF(ARG_type, ARG_name)\	ARG_type *ARG_name = arg;/* copy arg to local variable */	#define ARG_IN(ARG_name) /* nothing *//* argument itself (referenced) */#define ARGR(ARG_name) (*ARG_name)/* argument address */#define ARGA(ARG_name) ARG_name/* copy local variable to arg */#define ARG_OUT(ARG_name) /* nothing */#else#define ARG_DEF(ARG_type, ARG_name)\	ARG_type ARG_name;#define ARG_IN(ARG_name)\	if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\		ret = -EFAULT;\		break;\	}#define ARGR(ARG_name) ARG_name#define ARGA(ARG_name) &ARG_name#define ARG_OUT(ARG_name)\	if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\		ret = -EFAULT;\		break;\	}#endifint pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg){	int ret = 0;	switch(cmd) {	case VIDIOCPWCRUSER:	{		if (pwc_restore_user(pdev))			ret = -EINVAL;		break;	}		case VIDIOCPWCSUSER:	{		if (pwc_save_user(pdev))			ret = -EINVAL;		break;	}			case VIDIOCPWCFACTORY:	{		if (pwc_restore_factory(pdev))			ret = -EINVAL;		break;	}		case VIDIOCPWCSCQUAL:	{			ARG_DEF(int, qual)		ARG_IN(qual)		if (ARGR(qual) < 0 || ARGR(qual) > 3)			ret = -EINVAL;		else			ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);		if (ret >= 0)			pdev->vcompression = ARGR(qual);		break;	}		case VIDIOCPWCGCQUAL:	{		ARG_DEF(int, qual)				ARGR(qual) = pdev->vcompression;		ARG_OUT(qual)		break;	}		case VIDIOCPWCPROBE:	{		ARG_DEF(struct pwc_probe, probe)				strcpy(ARGR(probe).name, pdev->vdev->name);		ARGR(probe).type = pdev->type;		ARG_OUT(probe)		break;	}	case VIDIOCPWCGSERIAL:	{		ARG_DEF(struct pwc_serial, serial)				strcpy(ARGR(serial).serial, pdev->serial);		ARG_OUT(serial)		break;	}	case VIDIOCPWCSAGC:	{		ARG_DEF(int, agc)		ARG_IN(agc)		if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))			ret = -EINVAL;		break;	}		case VIDIOCPWCGAGC:	{		ARG_DEF(int, agc)				if (pwc_get_agc(pdev, ARGA(agc)))			ret = -EINVAL;		ARG_OUT(agc)		break;	}		case VIDIOCPWCSSHUTTER:	{		ARG_DEF(int, shutter_speed)		ARG_IN(shutter_speed)		ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));		break;	}	        case VIDIOCPWCSAWB:	{		ARG_DEF(struct pwc_whitebalance, wb)				ARG_IN(wb)		ret = pwc_set_awb(pdev, ARGR(wb).mode);		if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) {			pwc_set_red_gain(pdev, ARGR(wb).manual_red);			pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);		}		break;	}	case VIDIOCPWCGAWB:	{		ARG_DEF(struct pwc_whitebalance, wb)		memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));		ARGR(wb).mode = pwc_get_awb(pdev);		if (ARGR(wb).mode < 0)			ret = -EINVAL;		else {			if (ARGR(wb).mode == PWC_WB_MANUAL) {				ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);				if (ret < 0)					break;				ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);				if (ret < 0)					break;			}			if (ARGR(wb).mode == PWC_WB_AUTO) {				ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);				if (ret < 0)					break; 				ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); 				if (ret < 0) 					break;			}		}		ARG_OUT(wb)		break;	}		case VIDIOCPWCSAWBSPEED:	{		ARG_DEF(struct pwc_wb_speed, wbs)				if (ARGR(wbs).control_speed > 0) {			ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);		}		if (ARGR(wbs).control_delay > 0) {			ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);		}		break;	}		case VIDIOCPWCGAWBSPEED:	{		ARG_DEF(struct pwc_wb_speed, wbs)				ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);		if (ret < 0)			break;		ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);		if (ret < 0)			break;		ARG_OUT(wbs)		break;	}        case VIDIOCPWCSLED:	{		ARG_DEF(struct pwc_leds, leds)		ARG_IN(leds)		ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);	    	break;	}	case VIDIOCPWCGLED:	{		ARG_DEF(struct pwc_leds, leds)				ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);		ARG_OUT(leds)		break;	}	case VIDIOCPWCSCONTOUR:	{		ARG_DEF(int, contour)		ARG_IN(contour)		ret = pwc_set_contour(pdev, ARGR(contour));		break;	}				case VIDIOCPWCGCONTOUR:	{		ARG_DEF(int, contour)				ret = pwc_get_contour(pdev, ARGA(contour));		ARG_OUT(contour)		break;	}		case VIDIOCPWCSBACKLIGHT:	{		ARG_DEF(int, backlight)				ARG_IN(backlight)		ret = pwc_set_backlight(pdev, ARGR(backlight));		break;	}	case VIDIOCPWCGBACKLIGHT:	{		ARG_DEF(int, backlight)				ret = pwc_get_backlight(pdev, ARGA(backlight));		ARG_OUT(backlight)		break;	}		case VIDIOCPWCSFLICKER:	{		ARG_DEF(int, flicker)				ARG_IN(flicker)		ret = pwc_set_flicker(pdev, ARGR(flicker));		break;	}	case VIDIOCPWCGFLICKER:	{		ARG_DEF(int, flicker)				ret = pwc_get_flicker(pdev, ARGA(flicker));		ARG_OUT(flicker)		break;	}		case VIDIOCPWCSDYNNOISE:	{		ARG_DEF(int, dynnoise)				ARG_IN(dynnoise)		ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));		break;	}		case VIDIOCPWCGDYNNOISE:	{		ARG_DEF(int, dynnoise)		ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));		ARG_OUT(dynnoise);		break;	}	case VIDIOCPWCGREALSIZE:	{		ARG_DEF(struct pwc_imagesize, size)				ARGR(size).width = pdev->image.x;		ARGR(size).height = pdev->image.y;		ARG_OUT(size)		break; 	} 	 	case VIDIOCPWCMPTRESET: 	{ 		if (pdev->features & FEATURE_MOTOR_PANTILT) 		{	 		ARG_DEF(int, flags) 			ARG_IN(flags)			ret = pwc_mpt_reset(pdev, ARGR(flags)); 			if (ret >= 0) 			{ 				pdev->pan_angle = 0; 				pdev->tilt_angle = 0; 			} 		} 		else 		{ 			ret = -ENXIO; 		} 		break;		 	} 	 	case VIDIOCPWCMPTGRANGE: 	{ 		if (pdev->features & FEATURE_MOTOR_PANTILT) 		{ 			ARG_DEF(struct pwc_mpt_range, range) 			 			ARGR(range) = pdev->angle_range; 			ARG_OUT(range) 		} 		else 		{	 			ret = -ENXIO; 		} 		break; 	} 	 	case VIDIOCPWCMPTSANGLE: 	{ 		int new_pan, new_tilt; 		 		if (pdev->features & FEATURE_MOTOR_PANTILT) 		{	 		ARG_DEF(struct pwc_mpt_angles, angles)	 		ARG_IN(angles)			/* The camera can only set relative angles, so			   do some calculations when getting an absolute angle .			 */			if (ARGR(angles).absolute)			{ 				new_pan  = ARGR(angles).pan;  				new_tilt = ARGR(angles).tilt; 			} 			else 			{ 				new_pan  = pdev->pan_angle  + ARGR(angles).pan; 				new_tilt = pdev->tilt_angle + ARGR(angles).tilt;			}			/* check absolute ranges */			if (new_pan  < pdev->angle_range.pan_min  ||			    new_pan  > pdev->angle_range.pan_max  ||			    new_tilt < pdev->angle_range.tilt_min ||			    new_tilt > pdev->angle_range.tilt_max)			{				ret = -ERANGE;			}			else			{				/* go to relative range, check again */				new_pan  -= pdev->pan_angle;				new_tilt -= pdev->tilt_angle;				/* angles are specified in degrees * 100, thus the limit = 36000 */				if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000)					ret = -ERANGE;			}			if (ret == 0) /* no errors so far */			{				ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);				if (ret >= 0)				{					pdev->pan_angle  += new_pan;					pdev->tilt_angle += new_tilt;				}				if (ret == -EPIPE) /* stall -> out of range */					ret = -ERANGE;							} 		} 		else 		{ 			ret = -ENXIO; 		} 		break; 	} 	case VIDIOCPWCMPTGANGLE: 	{ 		 		if (pdev->features & FEATURE_MOTOR_PANTILT) 		{	 		ARG_DEF(struct pwc_mpt_angles, angles) 			ARGR(angles).absolute = 1; 			ARGR(angles).pan  = pdev->pan_angle; 			ARGR(angles).tilt = pdev->tilt_angle; 			ARG_OUT(angles) 		} 		else 		{ 			ret = -ENXIO; 		} 		break; 	}  	case VIDIOCPWCMPTSTATUS: 	{ 		if (pdev->features & FEATURE_MOTOR_PANTILT) 		{ 			ARG_DEF(struct pwc_mpt_status, status) 			 			ret = pwc_mpt_get_status(pdev, ARGA(status)); 			ARG_OUT(status) 		} 		else 		{ 			ret = -ENXIO; 		} 		break;	}	case VIDIOCPWCGVIDCMD:	{		ARG_DEF(struct pwc_video_command, cmd);		                ARGR(cmd).type = pdev->type;		ARGR(cmd).release = pdev->release;		ARGR(cmd).command_len = pdev->cmd_len;		memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);		ARGR(cmd).bandlength = pdev->vbandlength;		ARGR(cmd).frame_size = pdev->frame_size;		ARG_OUT(cmd)		break;	}	default:		ret = -ENOIOCTLCMD;		break;	}		if (ret > 0)		return 0;	return ret;}

⌨️ 快捷键说明

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