Re: [RFC v3 07/13] [media] exynos5-fimc-is: Add scaler subdev
On 08/02/2013 05:02 PM, Arun Kumar K wrote: FIMC-IS has two hardware scalers named as scaler-codec and scaler-preview. This patch adds the common code handling the video nodes and subdevs of both the scalers. Signed-off-by: Arun Kumar Karun...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-scaler.c | 458 drivers/media/platform/exynos5-is/fimc-is-scaler.h | 112 + 2 files changed, 570 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-scaler.c b/drivers/media/platform/exynos5-is/fimc-is-scaler.c new file mode 100644 index 000..7cff186 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-scaler.c @@ -0,0 +1,458 @@ +/* + * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#includemedia/v4l2-ioctl.h +#includemedia/videobuf2-dma-contig.h + +#include fimc-is.h + +#define IS_SCALER_DRV_NAME fimc-is-scaler + +static const struct fimc_is_fmt formats[] = { + { + .name = YUV 4:2:0 3p MultiPlanar, + .fourcc = V4L2_PIX_FMT_YUV420M, + .depth = {8, 2, 2}, + .num_planes = 3, + }, + { + .name = YUV 4:2:0 2p MultiPlanar, + .fourcc = V4L2_PIX_FMT_NV12M, + .depth = {8, 4}, + .num_planes = 2, + }, + { + .name = YUV 4:2:2 1p MultiPlanar, + .fourcc = V4L2_PIX_FMT_NV16, + .depth = {16}, + .num_planes = 1, + }, +}; +#define NUM_FORMATS ARRAY_SIZE(formats) + +static const struct fimc_is_fmt *find_format(struct v4l2_format *f) +{ + unsigned int i; + + for (i = 0; i NUM_FORMATS; i++) { + if (formats[i].fourcc == f-fmt.pix_mp.pixelformat) + returnformats[i]; + } + return NULL; +} + +static int scaler_video_capture_start_streaming(struct vb2_queue *vq, + unsigned int count) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + int ret; + + /* Scaler start */ + ret = fimc_is_pipeline_scaler_start(ctx-pipeline, + ctx-scaler_id, + (unsigned int **)ctx-buf_paddr, + vq-num_buffers, + ctx-fmt-num_planes); + if (ret) { + pr_err(Scaler start failed.\n); Please avoid pr_*() and use v4l2_err() or dev_err() where possible. + return -EINVAL; + } + + set_bit(STATE_RUNNING,ctx-capture_state); + return 0; +} + +static int scaler_video_capture_stop_streaming(struct vb2_queue *vq) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + int ret; + + /* Scaler stop */ Isn't the function name below obvious enough to not require this comment ? + ret = fimc_is_pipeline_scaler_stop(ctx-pipeline, ctx-scaler_id); + if (ret) + pr_debug(Scaler already stopped.\n); + + clear_bit(STATE_RUNNING,ctx-capture_state); + return 0; +} + +static int scaler_video_capture_queue_setup(struct vb2_queue *vq, + const struct v4l2_format *pfmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *allocators[]) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + const struct fimc_is_fmt *fmt = ctx-fmt; + unsigned int wh; + int i; + + if (!fmt) + return -EINVAL; + + *num_planes = fmt-num_planes; + wh = ctx-width * ctx-height; + + for (i = 0; i *num_planes; i++) { + allocators[i] = ctx-alloc_ctx; + sizes[i] = (wh * fmt-depth[i]) / 8; + } + return 0; +} + +static int scaler_video_capture_buffer_init(struct vb2_buffer *vb) +{ + struct vb2_queue *vq = vb-vb2_queue; + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + struct fimc_is_buf *buf; + const struct fimc_is_fmt *fmt; + int i; + + buf =ctx-capture_bufs[vb-v4l2_buf.index]; I don't like such usage of vb-v4l2_buf.index. It would be nice to get rid of this pattern and leave v4l2_buf.index out for videobuf2 and user space. Or can't it really be avoided ? + /* Initialize buffer */ + buf-vb = vb; + fmt = ctx-fmt; + for (i = 0; i fmt-num_planes; i++) + buf-paddr[i] =
[RFC v3 07/13] [media] exynos5-fimc-is: Add scaler subdev
FIMC-IS has two hardware scalers named as scaler-codec and scaler-preview. This patch adds the common code handling the video nodes and subdevs of both the scalers. Signed-off-by: Arun Kumar K arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-scaler.c | 458 drivers/media/platform/exynos5-is/fimc-is-scaler.h | 112 + 2 files changed, 570 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-scaler.c b/drivers/media/platform/exynos5-is/fimc-is-scaler.c new file mode 100644 index 000..7cff186 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-scaler.c @@ -0,0 +1,458 @@ +/* + * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Arun Kumar K arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include media/v4l2-ioctl.h +#include media/videobuf2-dma-contig.h + +#include fimc-is.h + +#define IS_SCALER_DRV_NAME fimc-is-scaler + +static const struct fimc_is_fmt formats[] = { + { + .name = YUV 4:2:0 3p MultiPlanar, + .fourcc = V4L2_PIX_FMT_YUV420M, + .depth = {8, 2, 2}, + .num_planes = 3, + }, + { + .name = YUV 4:2:0 2p MultiPlanar, + .fourcc = V4L2_PIX_FMT_NV12M, + .depth = {8, 4}, + .num_planes = 2, + }, + { + .name = YUV 4:2:2 1p MultiPlanar, + .fourcc = V4L2_PIX_FMT_NV16, + .depth = {16}, + .num_planes = 1, + }, +}; +#define NUM_FORMATS ARRAY_SIZE(formats) + +static const struct fimc_is_fmt *find_format(struct v4l2_format *f) +{ + unsigned int i; + + for (i = 0; i NUM_FORMATS; i++) { + if (formats[i].fourcc == f-fmt.pix_mp.pixelformat) + return formats[i]; + } + return NULL; +} + +static int scaler_video_capture_start_streaming(struct vb2_queue *vq, + unsigned int count) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + int ret; + + /* Scaler start */ + ret = fimc_is_pipeline_scaler_start(ctx-pipeline, + ctx-scaler_id, + (unsigned int **)ctx-buf_paddr, + vq-num_buffers, + ctx-fmt-num_planes); + if (ret) { + pr_err(Scaler start failed.\n); + return -EINVAL; + } + + set_bit(STATE_RUNNING, ctx-capture_state); + return 0; +} + +static int scaler_video_capture_stop_streaming(struct vb2_queue *vq) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + int ret; + + /* Scaler stop */ + ret = fimc_is_pipeline_scaler_stop(ctx-pipeline, ctx-scaler_id); + if (ret) + pr_debug(Scaler already stopped.\n); + + clear_bit(STATE_RUNNING, ctx-capture_state); + return 0; +} + +static int scaler_video_capture_queue_setup(struct vb2_queue *vq, + const struct v4l2_format *pfmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *allocators[]) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + const struct fimc_is_fmt *fmt = ctx-fmt; + unsigned int wh; + int i; + + if (!fmt) + return -EINVAL; + + *num_planes = fmt-num_planes; + wh = ctx-width * ctx-height; + + for (i = 0; i *num_planes; i++) { + allocators[i] = ctx-alloc_ctx; + sizes[i] = (wh * fmt-depth[i]) / 8; + } + return 0; +} + +static int scaler_video_capture_buffer_init(struct vb2_buffer *vb) +{ + struct vb2_queue *vq = vb-vb2_queue; + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + struct fimc_is_buf *buf; + const struct fimc_is_fmt *fmt; + int i; + + buf = ctx-capture_bufs[vb-v4l2_buf.index]; + /* Initialize buffer */ + buf-vb = vb; + fmt = ctx-fmt; + for (i = 0; i fmt-num_planes; i++) + buf-paddr[i] = vb2_dma_contig_plane_dma_addr(vb, i); + + ctx-cap_buf_cnt++; + return 0; +} + +static void scaler_video_capture_buffer_queue(struct vb2_buffer *vb) +{ + struct vb2_queue *vq = vb-vb2_queue; + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + struct fimc_is_buf *buf; + + buf = ctx-capture_bufs[vb-v4l2_buf.index]; + + /* Add buffer to the