||
驱动的ioctl
static int s3c_g2d_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
s3c_g2d_params *params;
s3c_g2d_line_params line_params;
s3c_g2d_transmit tarns_params;
//u32 val ;
ROT_DEG rot_degree;
//int i_te;
params = (s3c_g2d_params*)file->private_data;
//s3c_g2d_check_fifo(30);
mutex_lock(h_rot_mutex);
switch(cmd) {
case S3C_G2D_PARAMS_INIT:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
s3c_g2d_init_regs(params);
break;
case S3C_G2D_ROTATOR_0:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
rot_degree = ROT_0;
s3c_g2d_rotator_start(params, rot_degree);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
case S3C_G2D_ROTATOR_90:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
rot_degree = ROT_90;
s3c_g2d_rotator_start(params, rot_degree);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
case S3C_G2D_ROTATOR_180:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
rot_degree = ROT_180;
s3c_g2d_rotator_start(params, rot_degree);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
case S3C_G2D_ROTATOR_270:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
rot_degree = ROT_270;
s3c_g2d_rotator_start(params, rot_degree);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
case S3C_G2D_ROTATOR_X_FLIP:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
rot_degree = ROT_X_FLIP;
s3c_g2d_rotator_start(params, rot_degree);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
case S3C_G2D_ROTATOR_Y_FLIP:
if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
rot_degree = ROT_Y_FLIP;
s3c_g2d_rotator_start(params, rot_degree);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
case DRAWING_LINE:
if(copy_from_user(&line_params, (s3c_g2d_line_params*)arg, sizeof(s3c_g2d_line_params)))
{
mutex_unlock(h_rot_mutex);
return -EFAULT;
}
line_drawing_flag =0;
s3c_g2d_drawing_line_start(&line_params);
wait_event_interruptible(waitq_g2d,line_drawing_flag !=0 );
line_drawing_flag =0;
break;
case S3C_G2D_TRANS_DATA:
if(copy_from_user(&tarns_params, (s3c_g2d_transmit *)arg, sizeof(s3c_g2d_transmit)))
{
mutex_unlock(h_rot_mutex);
}
s3c_g2d_trans(&tarns_params);
if(!(file->f_flags & O_NONBLOCK))
{
if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
{
printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
}
}
break;
default:
mutex_unlock(h_rot_mutex);
return -EINVAL;
}
测试代码
/*
* 函数介绍: 硬件画线
* 输入参数: u16 start_x, u16 start_y 起始坐标 u16 end_x, u16 end_y,u32 colour结束坐标 colour线的颜色
* 输出参数:
* 返回值 : 0 成功 -1失败
*/
int G2D_CTL::drawing_line(XY *start_xy, XY *end_xy, u32 colour)
{
s3c_g2d_line_params line_params;
line_params.dst_base_addr = g2d_context.dst_addr;
line_params.start_x = start_xy->x;
line_params.start_y =start_xy->y;
line_params.end_x = end_xy->x;
line_params.end_y =end_xy->y;
line_params.line_colour = colour;
/* printf("line_params.start_x =%d\n",line_params.start_x);
printf("line_params.start_y =%d\n",line_params.start_y);
printf("line_params.end_x =%d\n",line_params.end_x);
printf("line_params.end_y = %d\n",line_params.end_y);
printf("line_params.line_colour = %x\n",line_params.line_colour);*/
line_params.line_or_point = 1;
if(ioctl(g2d_fd, DRAWING_LINE, &line_params) < 0)
{
printf("DRAWING_LINE fail\n");
return -1;
}
return 0;
}
/*
* 函数介绍: 硬件拷贝
* 输入参数: src_base_addr 源地址 src_r 源图像大小 dst_base_addr 目的地址 dst_r 目的图像大小
* 输出参数:
* 返回值 : 0 成功 -1失败
*/
int G2D_CTL::transmit_bit_blt(u32 src_base_addr, G2D_RECT *src_r, u32 dst_base_addr, G2D_RECT *dst_r)
{
s3c_g2d_transmit trans_params;
trans_params.src_base_addr = src_base_addr;
trans_params.src_start_x = src_r->begin.x;
trans_params.src_start_y = src_r->begin.y;
trans_params.src_end_x = src_r->end.x;
trans_params.src_end_y = src_r->end.y;
trans_params.dst_base_addr = dst_base_addr;
trans_params.dst_start_x = dst_r->begin.x;
trans_params.dst_start_y = dst_r->begin.y;
trans_params.dst_end_x = dst_r->end.x;
trans_params.dst_end_y = dst_r->end.y;
if(ioctl(g2d_fd, S3C_G2D_TRANS_DATA, &trans_params) < 0)
{
printf("S3C_G2D_TRANS_DATA fail\n");
return -1;
}
return 0;
}
/*
* 函数介绍: 2d参数初始化
* 输入参数: s3c_g2d_params *params 2d参数结构体
src_base_addr LCD源地址
dst_base_addr LCD目的地址
src_r LCD源参数
dst_r LCD目的参数
* 输出参数:
* 返回值 : 0 成功 -1失败
*/
int G2D_CTL::init_params(s3c_g2d_params *params,u32 src_base_addr,u32 dst_base_addr, G2D_RECT *src_r, G2D_RECT *dst_r)
{
params->bpp = DF_BPP;
params->alpha_mode = 0;
params->alpha_val = 0;
params->color_key_mode = 0;
params->color_key_val = 0;
params->src_base_addr = src_base_addr;
params->src_full_width = src_r->end.x;
params->src_full_height = src_r->end.y;
params->src_start_x = src_r->begin.x;
params->src_start_y = src_r->begin.y;
params->src_work_width = src_r->end.x-1;
params->src_work_height = src_r->end.y-1;
params->dst_base_addr = dst_base_addr;
params->dst_full_width = dst_r->end.x;
params->dst_full_height = dst_r->end.y;
params->dst_start_x = dst_r->begin.x;
params->dst_start_y = dst_r->begin.y;
params->dst_work_width = dst_r->end.x-1;
params->dst_work_height = dst_r->end.y-1;
params->cw_x1 = dst_r->begin.x;
params->cw_y1 = dst_r->begin.y;
params->cw_x2 = dst_r->end.x-1;
params->cw_y2 = dst_r->end.y-1;
params->color_val[G2D_BLACK] = 0x0;
params->color_val[G2D_RED] = 0xF800;
params->color_val[G2D_GREEN] = 0x07E0;
params->color_val[G2D_BLUE] = 0x001F;
params->color_val[G2D_WHITE] = 0xFFFF;
params->color_val[G2D_YELLOW] = 0xFFE0;
params->color_val[G2D_CYAN] = 0x07FF;
params->color_val[G2D_MAGENTA] = 0xF81F;
if(ioctl(g2d_fd, S3C_G2D_PARAMS_INIT, params) < 0)
{
printf("S3C_G2D_ROTATOR fail\n");
return -1;
}
return 0;
}
/*
* 函数介绍:放大或缩小矩形,并指定放大缩小率,高度、长度的放大倍数可以不一样
* 输入参数:src_r源图像位置大小,ratio_w长度放大缩小率,ratio_h高度放大缩小率
* 输出参数:
* 返 回:0 成功 -1失败
*/
int G2D_CTL::stretch_rect(G2D_RECT *src_r, float ratio_w, float ratio_h)
{
G2D_RECT dst_r;
int begin_x;
int begin_y;
int end_x;
int end_y;
begin_x = (int)((float)src_r->begin.x - (ratio_w-1)*((float)(src_r->end.x - src_r->begin.x))/2);
begin_y = (int)((float)src_r->begin.y - (ratio_h-1)*((float)(src_r->end.y - src_r->begin.y))/2);
dst_r.begin.x = begin_x;//(begin_x >0 ? begin_x : 0);
dst_r.begin.y = begin_y;//(begin_y >0 ? begin_y : 0);
end_x = (int)((float)src_r->end.x + (ratio_w-1)*((float)(src_r->end.x - src_r->begin.x))/2);
end_y = (int)((float)src_r->end.y + (ratio_h-1)*((float)(src_r->end.y - src_r->begin.y))/2);
dst_r.end.x = end_x;//(end_x >478 ? 479 : end_x);
dst_r.end.y = end_y;//(end_y >638 ? 639 : end_y);
return transmit_bit_blt(g2d_context.src_addr,src_r, g2d_context.dst_addr, &dst_r);
}