update rk29 v4l2 vout drivers

This commit is contained in:
kfx
2011-02-14 11:00:30 +08:00
parent 1041014f36
commit 2522996b4b

View File

@@ -39,9 +39,14 @@
#define norm_maxw() 1920
#define norm_maxh() 1080
#if 1
#define rk29_vout_dbg(dev, format, arg...) \
dev_printk(KERN_INFO , dev , format , ## arg)
#else
#define rk29_vout_dbg(dev, format, arg...)
#endif
static int dev_nr = 1;
static int debug = 1;
static unsigned int vid_limit = 16; //16M
@@ -54,7 +59,7 @@ struct rk29_vid_device {
struct rk29_vout_device *vouts[VOUT_NR];
struct v4l2_device v4l2_dev;
struct list_head devlist;
struct device *dev;
};
struct rk29_vout_device {
int vid;
@@ -65,6 +70,7 @@ struct rk29_vout_device {
enum v4l2_memory memory;
struct v4l2_pix_format pix;
struct v4l2_rect crop;
struct v4l2_rect win;
struct v4l2_control ctrl;
struct rk29_vbuf vbuf;
@@ -127,8 +133,14 @@ static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
{
struct rk29_vout_device *vout = priv;
f->fmt.pix = vout->pix;
if(f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
f->fmt.pix = vout->pix;
else if(f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY) {
f->fmt.win.w.width = vout->win.width;
f->fmt.win.w.height = vout->win.height;
}
else
return -EINVAL;
return 0;
}
static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
@@ -140,7 +152,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
fmt = get_format(f);
if (!fmt) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Fourcc format (0x%08x) invalid.\n",
rk29_vout_dbg(vout->vid_dev->dev, "Fourcc format (0x%08x) invalid.\n",
f->fmt.pix.pixelformat);
return -EINVAL;
}
@@ -162,26 +174,66 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
{
struct rk29_vout_device *vout = priv;
int ret = vidioc_try_fmt_vid_out(file, vout, f);
if (ret < 0)
return ret;
int ret = 0;
if(f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
ret = vidioc_try_fmt_vid_out(file, vout, f);
if (ret < 0)
return ret;
mutex_lock(&vout->mutex);
mutex_lock(&vout->mutex);
if (videobuf_queue_is_busy(&vout->vbq)) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s queue busy\n", __func__);
ret = -EBUSY;
goto out;
}
if (videobuf_queue_is_busy(&vout->vbq)) {
rk29_vout_dbg(vout->vid_dev->dev, "%s queue busy\n", __func__);
ret = -EBUSY;
goto out;
}
vout->pix = f->fmt.pix;
vout->vbq.field = f->fmt.pix.field;
vout->type = f->type;
vout->pix = f->fmt.pix;
vout->vbq.field = f->fmt.pix.field;
vout->type = f->type;
ret = 0;
ret = 0;
out:
mutex_unlock(&vout->mutex);
mutex_unlock(&vout->mutex);
}
else if(f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY) {
if ((f->fmt.win.w.width < 0) || (f->fmt.win.w.height < 0)) {
rk29_vout_dbg(vout->vid_dev->dev, "The win rect must be bigger than 0\n");
ret = -EINVAL;
}
if ((f->fmt.win.w.width > vout->win.width) || (f->fmt.win.w.height > vout->win.height)) {
rk29_vout_dbg(vout->vid_dev->dev, "The win width/height must be smaller than "
"%d and %d\n", vout->win.width, vout->win.height);
ret = -EINVAL;
}
if ((f->fmt.win.w.left < 0) || (f->fmt.win.w.top < 0)) {
rk29_vout_dbg(vout->vid_dev->dev, "The win left, top must be bigger than 0\n");
ret = -EINVAL;
}
if ((f->fmt.win.w.left > vout->win.width) || (f->fmt.win.w.top > vout->win.height)) {
rk29_vout_dbg(vout->vid_dev->dev, "The win left, top must be smaller than %d, %d\n",
vout->win.width, vout->win.height);
ret = -EINVAL;
}
if ((f->fmt.win.w.left + f->fmt.win.w.width) > vout->win.width) {
rk29_vout_dbg(vout->vid_dev->dev, "The win rect must be in bound rect\n");
ret = -EINVAL;
}
if ((f->fmt.win.w.top + f->fmt.win.w.height) > vout->win.height) {
rk29_vout_dbg(vout->vid_dev->dev, "The win rect must be in bound rect\n");
ret = -EINVAL;
}
mutex_lock(&vout->mutex);
vout->win = f->fmt.win.w;
mutex_unlock(&vout->mutex);
}
else
ret = -EINVAL;
return ret;
}
static int vidioc_reqbufs(struct file *file, void *priv,
@@ -285,44 +337,38 @@ static int vidioc_s_crop(struct file *file, void *priv,
return -EINVAL;
if (vout->vbq.streaming) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "vedio is running\n");
rk29_vout_dbg(vout->vid_dev->dev, "vedio is running\n");
return -EBUSY;
}
if ((crop->c.width < 0) || (crop->c.height < 0)) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
"The crop rect must be bigger than 0\n");
rk29_vout_dbg(vout->vid_dev->dev, "The crop rect must be bigger than 0\n");
return -EINVAL;
}
if ((crop->c.width > norm_maxw()) || (crop->c.height > norm_maxh())) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
"The crop width/height must be smaller than "
"%d and %d\n", norm_maxw(), norm_maxh());
if ((crop->c.width > vout->pix.width) || (crop->c.height > vout->pix.height)) {
rk29_vout_dbg(vout->vid_dev->dev, "The crop width/height must be smaller than "
"%d and %d\n", vout->pix.width, vout->pix.height);
return -EINVAL;
}
if ((crop->c.left < 0) || (crop->c.top < 0)) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
"The crop left, top must be bigger than 0\n");
rk29_vout_dbg(vout->vid_dev->dev, "The crop left, top must be bigger than 0\n");
return -EINVAL;
}
if ((crop->c.left > norm_maxw()) || (crop->c.top > norm_maxh())) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
"The crop left, top must be smaller than %d, %d\n",
norm_maxw(), norm_maxh());
if ((crop->c.left > vout->pix.width) || (crop->c.top > vout->pix.height)) {
rk29_vout_dbg(vout->vid_dev->dev, "The crop left, top must be smaller than %d, %d\n",
vout->pix.width, vout->pix.height);
return -EINVAL;
}
if ((crop->c.left + crop->c.width) > norm_maxw()) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
"The crop rect must be in bound rect\n");
if ((crop->c.left + crop->c.width) > vout->pix.width) {
rk29_vout_dbg(vout->vid_dev->dev, "The crop rect must be in bound rect\n");
return -EINVAL;
}
if ((crop->c.top + crop->c.height) > norm_maxh()) {
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
"The crop rect must be in bound rect\n");
if ((crop->c.top + crop->c.height) > vout->pix.height) {
rk29_vout_dbg(vout->vid_dev->dev, "The crop rect must be in bound rect\n");
return -EINVAL;
}
@@ -414,7 +460,7 @@ static int rk29_vout_open(struct file *file)
{
struct rk29_vout_device *vout = video_drvdata(file);
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
rk29_vout_dbg(vout->vid_dev->dev, "Entering %s\n", __func__);
if (vout == NULL)
return -ENODEV;
@@ -437,7 +483,7 @@ static int rk29_vout_open(struct file *file)
vout->vbq.dev, &vout->lock, vout->type, V4L2_FIELD_NONE,
sizeof(struct videobuf_buffer), vout);
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
rk29_vout_dbg(vout->vid_dev->dev, "Exiting %s\n", __func__);
return 0;
}
@@ -446,7 +492,7 @@ static int rk29_vout_release(struct file *file)
struct videobuf_queue *q;
struct rk29_vout_device *vout = file->private_data;
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
rk29_vout_dbg(vout->vid_dev->dev, "Entering %s\n", __func__);
if (!vout)
return 0;
@@ -458,7 +504,7 @@ static int rk29_vout_release(struct file *file)
vout->opened -= 1;
mutex_unlock(&vout->mutex);
file->private_data = NULL;
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
rk29_vout_dbg(vout->vid_dev->dev, "Exiting %s\n", __func__);
return 0;
}
@@ -506,8 +552,8 @@ static int rk29_vout_create_video_devices(struct platform_device *pdev)
vid_dev->vouts[k] = vout;
vout->vid_dev = vid_dev;
vout->pix.width = VOUT_WIDTH;
vout->pix.height = VOUT_HEIGHT;
vout->pix.width = norm_maxw();
vout->pix.height = norm_maxh();
vout->pix.pixelformat = formats[0].fourcc;
vout->pix.field = V4L2_FIELD_NONE;
@@ -516,6 +562,11 @@ static int rk29_vout_create_video_devices(struct platform_device *pdev)
vout->pix.colorspace = V4L2_COLORSPACE_JPEG;
vout->pix.priv = 0;
vout->win.width = VOUT_WIDTH;
vout->win.height = VOUT_HEIGHT;
vout->win.left = 0;
vout->win.top = 0;
vfd = vout->vfd = video_device_alloc();
if (!vfd){
dev_err(&pdev->dev, "could not allocate video device struct\n");
@@ -546,7 +597,7 @@ error0:
return ret;
success:
dev_info(&pdev->dev, ": registered and initialized"
dev_info(&pdev->dev, "registered and initialized"
" video device %d\n", vfd->minor);
}
@@ -562,6 +613,8 @@ static int __init rk29_vout_probe(struct platform_device *pdev)
if (!vid_dev)
return -ENOMEM;
vid_dev->dev = &pdev->dev;
if ((ret = v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev)) < 0){
dev_err(&pdev->dev, "v4l2_device_register failed\n");
goto probe_err0;