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; }
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; }