diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 11:43:33 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-19 00:18:35 -0300 |
commit | 979ea1ddf80ac7383acdea03471355ca62702539 (patch) | |
tree | 2ee4c73eb672c1ee8167ed7e0906bac6f3b00e69 /drivers/media/video/soc_camera_platform.c | |
parent | 0bab829de1ab60d8c3cbf7e402192bb9446840b7 (diff) |
V4L/DVB (12510): soc-camera: (partially) convert to v4l2-(sub)dev API
Convert the soc-camera framework to use the v4l2-(sub)dev API. Start using
v4l2-subdev operations. Only a part of the interface between the
soc_camera core, soc_camera host drivers on one side and soc_camera device
drivers on the other side is replaced so far. The rest of the interface
will be replaced in incremental steps, and will require extensions and,
possibly, modifications to the v4l2-subdev code.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/soc_camera_platform.c')
-rw-r--r-- | drivers/media/video/soc_camera_platform.c | 115 |
1 files changed, 50 insertions, 65 deletions
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index d84c134f8d59..8168cf470eb3 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c @@ -16,11 +16,12 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/videodev2.h> -#include <media/v4l2-common.h> +#include <media/v4l2-subdev.h> #include <media/soc_camera.h> #include <media/soc_camera_platform.h> struct soc_camera_platform_priv { + struct v4l2_subdev subdev; struct soc_camera_data_format format; }; @@ -31,36 +32,10 @@ soc_camera_platform_get_info(struct soc_camera_device *icd) return pdev->dev.platform_data; } -static int soc_camera_platform_init(struct soc_camera_device *icd) +static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable) { - struct soc_camera_link *icl = to_soc_camera_link(icd); - - if (icl->power) - icl->power(dev_get_drvdata(&icd->dev), 1); - - return 0; -} - -static int soc_camera_platform_release(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - - if (icl->power) - icl->power(dev_get_drvdata(&icd->dev), 0); - - return 0; -} - -static int soc_camera_platform_start_capture(struct soc_camera_device *icd) -{ - struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); - return p->set_capture(p, 1); -} - -static int soc_camera_platform_stop_capture(struct soc_camera_device *icd) -{ - struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); - return p->set_capture(p, 0); + struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); + return p->set_capture(p, enable); } static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd, @@ -82,16 +57,10 @@ static int soc_camera_platform_set_crop(struct soc_camera_device *icd, return 0; } -static int soc_camera_platform_set_fmt(struct soc_camera_device *icd, +static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) { - return 0; -} - -static int soc_camera_platform_try_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); + struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); struct v4l2_pix_format *pix = &f->fmt.pix; pix->width = p->format.width; @@ -99,12 +68,11 @@ static int soc_camera_platform_try_fmt(struct soc_camera_device *icd, return 0; } -static int soc_camera_platform_video_probe(struct soc_camera_device *icd, - struct platform_device *pdev) +static void soc_camera_platform_video_probe(struct soc_camera_device *icd, + struct platform_device *pdev) { struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev); struct soc_camera_platform_info *p = pdev->dev.platform_data; - int ret; priv->format.name = p->format_name; priv->format.depth = p->format_depth; @@ -113,28 +81,29 @@ static int soc_camera_platform_video_probe(struct soc_camera_device *icd, icd->formats = &priv->format; icd->num_formats = 1; - - /* ..._video_start() does dev_set_drvdata(&icd->dev, &pdev->dev) */ - ret = soc_camera_video_start(icd, &pdev->dev); - soc_camera_video_stop(icd); - return ret; } +static struct v4l2_subdev_core_ops platform_subdev_core_ops; + +static struct v4l2_subdev_video_ops platform_subdev_video_ops = { + .s_stream = soc_camera_platform_s_stream, + .try_fmt = soc_camera_platform_try_fmt, +}; + +static struct v4l2_subdev_ops platform_subdev_ops = { + .core = &platform_subdev_core_ops, + .video = &platform_subdev_video_ops, +}; + static struct soc_camera_ops soc_camera_platform_ops = { - .owner = THIS_MODULE, - .init = soc_camera_platform_init, - .release = soc_camera_platform_release, - .start_capture = soc_camera_platform_start_capture, - .stop_capture = soc_camera_platform_stop_capture, .set_crop = soc_camera_platform_set_crop, - .set_fmt = soc_camera_platform_set_fmt, - .try_fmt = soc_camera_platform_try_fmt, .set_bus_param = soc_camera_platform_set_bus_param, .query_bus_param = soc_camera_platform_query_bus_param, }; static int soc_camera_platform_probe(struct platform_device *pdev) { + struct soc_camera_host *ici; struct soc_camera_platform_priv *priv; struct soc_camera_platform_info *p = pdev->dev.platform_data; struct soc_camera_device *icd; @@ -143,35 +112,48 @@ static int soc_camera_platform_probe(struct platform_device *pdev) if (!p) return -EINVAL; + if (!p->dev) { + dev_err(&pdev->dev, + "Platform has not set soc_camera_device pointer!\n"); + return -EINVAL; + } + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - platform_set_drvdata(pdev, priv); - icd = to_soc_camera_dev(p->dev); - if (!icd) - goto enoicd; - icd->ops = &soc_camera_platform_ops; + platform_set_drvdata(pdev, priv); dev_set_drvdata(&icd->dev, &pdev->dev); + icd->width_min = 0; icd->width_max = p->format.width; icd->height_min = 0; icd->height_max = p->format.height; icd->y_skip_top = 0; + icd->ops = &soc_camera_platform_ops; - ret = soc_camera_platform_video_probe(icd, pdev); - if (ret) { - icd->ops = NULL; - kfree(priv); - } + ici = to_soc_camera_host(icd->dev.parent); + + soc_camera_platform_video_probe(icd, pdev); + + v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); + v4l2_set_subdevdata(&priv->subdev, p); + priv->subdev.grp_id = (__u32)icd; + strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE); + + ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev); + if (ret) + goto evdrs; return ret; -enoicd: +evdrs: + icd->ops = NULL; + platform_set_drvdata(pdev, NULL); kfree(priv); - return -EINVAL; + return ret; } static int soc_camera_platform_remove(struct platform_device *pdev) @@ -180,7 +162,9 @@ static int soc_camera_platform_remove(struct platform_device *pdev) struct soc_camera_platform_info *p = pdev->dev.platform_data; struct soc_camera_device *icd = to_soc_camera_dev(p->dev); + v4l2_device_unregister_subdev(&priv->subdev); icd->ops = NULL; + platform_set_drvdata(pdev, NULL); kfree(priv); return 0; } @@ -188,6 +172,7 @@ static int soc_camera_platform_remove(struct platform_device *pdev) static struct platform_driver soc_camera_platform_driver = { .driver = { .name = "soc_camera_platform", + .owner = THIS_MODULE, }, .probe = soc_camera_platform_probe, .remove = soc_camera_platform_remove, |