Beispiel #1
0
static int s3c_rotator_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct s3c_rotator_ctrl	*ctrl = &s3c_rot;
	ro_params *params;
	ro_params *parg;
	unsigned int mode, divisor = 0;

	if (ctrl->status != ROT_IDLE) {
		printk(KERN_ERR "Rotator is busy.\n");
		return -EBUSY;
	}

	mutex_lock(h_rot_mutex);

	params	        = (ro_params *)file->private_data;
	parg	        = (ro_params *)arg;    

	get_user(params->src_width,     &parg->src_width);
	get_user(params->src_height,    &parg->src_height);

	get_user(params->src_format,    &parg->src_format);
	get_user(params->src_addr_rgb_y,&parg->src_addr_rgb_y);
	get_user(params->src_addr_cb,   &parg->src_addr_cb);
	get_user(params->src_addr_cr,   &parg->src_addr_cr);    

	get_user(params->dst_addr_rgb_y,&parg->dst_addr_rgb_y);    
	get_user(params->dst_addr_cb,   &parg->dst_addr_cb);    
	get_user(params->dst_addr_cr,   &parg->dst_addr_cr);    

	if( (params->src_width > 2048) || (params->src_height > 2048)) {
		printk(KERN_ERR "\n%s: maximum width and height size are 2048\n", __FUNCTION__);
		return -EINVAL;
	}

	switch(params->src_format) {
	case S3C_ROTATOR_CTRLCFG_INPUT_YUV420:
		divisor = 8;
		break;

	case S3C_ROTATOR_CTRLCFG_INPUT_YUV422:	/* fall through */
	case S3C_ROTATOR_CTRLCFG_INPUT_RGB565:	
		divisor = 2;
		break;

	case S3C_ROTATOR_CTRLCFG_INPUT_RGB888:
		divisor = 1;
		break;

	default :
		printk(KERN_ERR "requested src type is not supported!! plz check src format!!\n");
		break;
	}
	
	if((params->src_width % divisor) || (params->src_height % divisor)) {
		printk(KERN_ERR "\n%s: src & dst size is aligned to %d pixel boundary\n", __FUNCTION__, divisor);
		mutex_unlock(h_rot_mutex);
		return -EINVAL;
	}

	switch(cmd) {
	case ROTATOR_90:   
		mode = S3C_ROTATOR_CTRLCFG_DEGREE_90    | S3C_ROTATOR_CTRLCFG_FLIP_BYPASS;
		break;

	case ROTATOR_180:   
		mode = S3C_ROTATOR_CTRLCFG_DEGREE_180   | S3C_ROTATOR_CTRLCFG_FLIP_BYPASS;
		break;

	case ROTATOR_270:   
		mode = S3C_ROTATOR_CTRLCFG_DEGREE_270   | S3C_ROTATOR_CTRLCFG_FLIP_BYPASS;
		break;

	case HFLIP:   
		mode = S3C_ROTATOR_CTRLCFG_DEGREE_BYPASS| S3C_ROTATOR_CTRLCFG_FLIP_HOR;
		break;

	case VFLIP:   
		mode = S3C_ROTATOR_CTRLCFG_DEGREE_BYPASS| S3C_ROTATOR_CTRLCFG_FLIP_VER;
		break;

	default:
		return -EINVAL;
	}

	s3c_rotator_set_source(params);
	s3c_rotator_set_dest(params);
	s3c_rotator_start(params, mode);

	ctrl->status = ROT_RUN;

	if(!(file->f_flags & O_NONBLOCK)) {
		if (interruptible_sleep_on_timeout(&waitq_rotator, ROTATOR_TIMEOUT) == 0) {
			printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", __FUNCTION__);
		}
	}

	mutex_unlock(h_rot_mutex);

	return 0;
}
Beispiel #2
0
static int s3c_rotator_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct s3c_rotator_ctrl	*ctrl = &s3c_rot;
	ro_params *params;
	ro_params *parg;

	unsigned int check_rest = 0;

	if (s3c_rotator_get_status() != S3C_ROT_STATREG_STATUS_IDLE) {
		printk(KERN_ERR "Rotator is busy : %x\n", s3c_rotator_get_status());
		return -EBUSY;
	}

	mutex_lock(h_rot_mutex);

	params	        = (ro_params *)file->private_data;
	parg	        = (ro_params *)arg;

	get_user(params->src_width, &parg->src_width);
	get_user(params->src_height, &parg->src_height);

	get_user(params->src_window_offset_x, &parg->src_window_offset_x);
	get_user(params->src_window_offset_y, &parg->src_window_offset_y);

	get_user(params->src_window_width, &parg->src_window_width);
	get_user(params->src_window_height, &parg->src_window_height);

	get_user(params->src_format,    &parg->src_format);
	get_user(params->src_addr_rgb_y, &parg->src_addr_rgb_y);
	get_user(params->src_addr_cb,   &parg->src_addr_cb);
	get_user(params->src_addr_cr,   &parg->src_addr_cr);

	get_user(params->dst_window_offset_x, &parg->dst_window_offset_x);
	get_user(params->dst_window_offset_y, &parg->dst_window_offset_y);

	get_user(params->dst_window_width, &parg->dst_window_width);
	get_user(params->dst_window_height, &parg->dst_window_height);

	get_user(params->dst_addr_rgb_y, &parg->dst_addr_rgb_y);
	get_user(params->dst_addr_cb,   &parg->dst_addr_cb);
	get_user(params->dst_addr_cr,   &parg->dst_addr_cr);

	check_rest = s3c_rotator_check_restrictions(params);

	if (check_rest) {
		printk(KERN_ERR "\n%s: restrictions error : %d\n", __FUNCTION__, check_rest);
		return -EINVAL;
	}

	/* set source format*/
	s3c_rotator_set_inputfmt(params->src_format);

	/* set degree */
	s3c_rotator_set_degree(cmd);

	s3c_rotator_set_source(params);
	s3c_rotator_set_dest(params);
	s3c_rotator_start();

	ctrl->status = ROT_RUN;

	if (!(file->f_flags & O_NONBLOCK)) {
		if (interruptible_sleep_on_timeout(&waitq_rotator, ROTATOR_TIMEOUT) == 0) {
			ctrl->status = ROT_IDLE;
			printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", __FUNCTION__);
		}
	}

	mutex_unlock(h_rot_mutex);

	return 0;
}