static int rotator_ioctl(struct	inode *inode, struct file *file,
						u32 cmd, unsigned long arg)
{
	struct rot_ctrl	*ctrl =	&s5p_rot;
	struct rot_param *params;
	struct rot_param *parg;
	int ret;

	if (rotator_get_status(ctrl) !=	S5P_ROT_STATREG_STATUS_IDLE) {
		printk(KERN_ERR	"Rotator state : %x\n",
						rotator_get_status(ctrl));
		return -EBUSY;
	}

	mutex_lock(&ctrl->lock);

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

	ret = copy_from_user(params, parg, sizeof(struct rot_param));
	if (ret) {
		printk(KERN_ERR	"%s: error : copy_from_user\n",	__func__);
		mutex_unlock(&ctrl->lock);
		return -EINVAL;
	}

	ret = rotator_check_vars(params);
	if (ret) {
		printk(KERN_ERR	"%s: invalid parameters\n", __func__);
		mutex_unlock(&ctrl->lock);
		return -EINVAL;
	}

	/* set parameter to regs */
	rotator_set_src(ctrl, params);
	rotator_set_dst(ctrl, params);
	rotator_set_fmt(ctrl, params);
	rotator_set_degree_flip(ctrl, params);

	rotator_start(ctrl);
	ctrl->status = ROT_RUN;

	if (!(file->f_flags & O_NONBLOCK)) {
		ret = wait_event_timeout(ctrl->wq, (ctrl->status == ROT_IDLE),
				ROTATOR_TIMEOUT);
		if (ret	== 0) {
			ctrl->status = ROT_IDLE;
			printk(KERN_ERR	"%s: Interrupt timeout\n", __func__);
		}
	}

	mutex_unlock(&ctrl->lock);

	return 0;
}
static u32 rotator_poll(struct file *file, poll_table *wait)
{
	struct rot_ctrl	*ctrl =	&s5p_rot;
	u32 mask = 0;

	poll_wait(file,	&ctrl->wq, wait);

	if (rotator_get_status(ctrl) ==	S5P_ROT_STATREG_STATUS_IDLE)
		mask = POLLOUT | POLLWRNORM;

	return mask;
}
Esempio n. 3
0
/* button isr */
static irqreturn_t rnb4_rot_input_irq(int irq, void *dev_id)
{
    struct rnb4_rot_input *rnb4_rot_input = dev_id;

#if defined(CONFIG_ARCH_PARROT_USE_ROTATOR)

    if(irq == IRQ_ROTATOR_START)
    {
    	if(rotator_get_status(0) == ROTATOR_EVENT_LEFT)
    	{
			input_report_key(rnb4_rot_input->input, KEY_DOWN, 1);
			input_report_key(rnb4_rot_input->input, KEY_DOWN, 0);
			input_sync(rnb4_rot_input->input);
    	}
    	else
    	{
			input_report_key(rnb4_rot_input->input, KEY_UP, 1);
			input_report_key(rnb4_rot_input->input, KEY_UP, 0);
			input_sync(rnb4_rot_input->input);
    	}
    }

#else //defined(CONFIG_ARCH_PARROT_USE_ROTATOR)

/***********************************************************
 *  software management of a 4 state rotator:
 *  - wait for each state to occur before sending the event
 *  - if an unexpected event occur, return in a wait for the first state
 *  (in this case a rnb4_rot:ERR will be issued)
 ***********************************************************/

    int button = irq - IRQ_GPIO_START, cur_dir;
    static int last = 0xFF, direction = 0xFF, valid = 0xFF;

    if(irq == rnb4_rot_input->irq[0])
    	cur_dir = gpio_get_value(rnb4_rot_input->gpio[0]);
    else
    	cur_dir = gpio_get_value(rnb4_rot_input->gpio[1]);

    if(cur_dir > 0)
    	cur_dir = 1;

    if(valid == 0xFF)
    {
    	last = button;	direction = cur_dir;	valid = 0;
    }
    else if (valid == 0)
    { // change of irq and same gpio level
    	if(last != button && direction == cur_dir)
    	{
    		valid = 1;
    	}
    	else
    	{ // restart from here
    		printk("rnb4_rot:ERR\n");
    		last = button;	direction = cur_dir;	valid = 0;
    	}
    }
    else if (valid == 1)
    { // same  irq and different gpio level
    	if(last == button && direction != cur_dir)
    	{
    		valid = 2;
    	}
    	else
    	{ // restart from here
    		last = button;	direction = cur_dir;	valid = 0;
    		printk("rnb4_rot:ERR\n");
    	}
    }
    else
    {// different irq and same gpio level
    	if(last != button && direction != cur_dir)
    	{
        	if(last > button)
        	{
    			input_report_key(rnb4_rot_input->input, KEY_UP, 1);
    			input_report_key(rnb4_rot_input->input, KEY_UP, 0);
    			input_sync(rnb4_rot_input->input);
        	}
        	else
        	{
    			input_report_key(rnb4_rot_input->input, KEY_DOWN, 1);
    			input_report_key(rnb4_rot_input->input, KEY_DOWN, 0);
    			input_sync(rnb4_rot_input->input);
        	}
        	last = 0xFF;
        	direction = 0xFF;
        	valid = 0xFF;
    	}
    	else
    	{ // restart from here
    		printk("rnb4_rot:ERR\n");
    		last = button;	direction = cur_dir;	valid = 0;
    	}
    }

#endif //defined(ARCH_PARROT_USE_ROTATOR)

    return IRQ_HANDLED;
}