[media] s5p-fimc: Add PM helper function for streaming control
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Fri, 10 Jun 2011 18:36:53 +0000 (15:36 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 6 Sep 2011 20:40:53 +0000 (17:40 -0300)
Move the camera capture H/W initialization sequence to a separate
function. This is needed for reuse in the following runtime PM code.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/s5p-fimc/fimc-core.h

index 95996fb91a12f70bba6844daa905553489e1e4a1..6c4dca0925a9552566080c276a660ce0f716fc94 100644 (file)
 #include "fimc-mdevice.h"
 #include "fimc-core.h"
 
+static int fimc_init_capture(struct fimc_dev *fimc)
+{
+       struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+       struct fimc_sensor_info *sensor;
+       unsigned long flags;
+       int ret = 0;
+
+       if (fimc->pipeline.sensor == NULL || ctx == NULL)
+               return -ENXIO;
+       if (ctx->s_frame.fmt == NULL)
+               return -EINVAL;
+
+       sensor = v4l2_get_subdev_hostdata(fimc->pipeline.sensor);
+
+       spin_lock_irqsave(&fimc->slock, flags);
+       fimc_prepare_dma_offset(ctx, &ctx->d_frame);
+       fimc_set_yuv_order(ctx);
+
+       fimc_hw_set_camera_polarity(fimc, sensor->pdata);
+       fimc_hw_set_camera_type(fimc, sensor->pdata);
+       fimc_hw_set_camera_source(fimc, sensor->pdata);
+       fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
+
+       ret = fimc_set_scaler_info(ctx);
+       if (!ret) {
+               fimc_hw_set_input_path(ctx);
+               fimc_hw_set_prescaler(ctx);
+               fimc_hw_set_mainscaler(ctx);
+               fimc_hw_set_target_format(ctx);
+               fimc_hw_set_rotation(ctx);
+               fimc_hw_set_effect(ctx);
+               fimc_hw_set_output_path(ctx);
+               fimc_hw_set_out_dma(ctx);
+       }
+       spin_unlock_irqrestore(&fimc->slock, flags);
+       return ret;
+}
+
 static void fimc_capture_state_cleanup(struct fimc_dev *fimc)
 {
        struct fimc_vid_cap *cap = &fimc->vid_cap;
@@ -85,47 +123,17 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
 {
        struct fimc_ctx *ctx = q->drv_priv;
        struct fimc_dev *fimc = ctx->fimc_dev;
-       struct s5p_fimc_isp_info *isp_info;
+       struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
        int min_bufs;
        int ret;
 
        fimc_hw_reset(fimc);
+       vid_cap->frame_count = 0;
 
-       ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
-       if (ret && ret != -ENOIOCTLCMD)
-               goto error;
-
-       ret = fimc_prepare_config(ctx, ctx->state);
+       ret = fimc_init_capture(fimc);
        if (ret)
                goto error;
 
-       isp_info = &fimc->pdata->isp_info[fimc->vid_cap.input_index];
-       fimc_hw_set_camera_type(fimc, isp_info);
-       fimc_hw_set_camera_source(fimc, isp_info);
-       fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
-
-       if (ctx->state & FIMC_PARAMS) {
-               ret = fimc_set_scaler_info(ctx);
-               if (ret) {
-                       err("Scaler setup error");
-                       goto error;
-               }
-               fimc_hw_set_input_path(ctx);
-               fimc_hw_set_prescaler(ctx);
-               fimc_hw_set_mainscaler(ctx);
-               fimc_hw_set_target_format(ctx);
-               fimc_hw_set_rotation(ctx);
-               fimc_hw_set_effect(ctx);
-       }
-
-       fimc_hw_set_output_path(ctx);
-       fimc_hw_set_out_dma(ctx);
-
-       INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
-       INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
-       fimc->vid_cap.frame_count = 0;
-       fimc->vid_cap.buf_index = 0;
-
        set_bit(ST_CAPT_PEND, &fimc->state);
 
        min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
index c7ce93457a9b059b8a5fb51f79502ef50a1fbee7..c5e41355b6e2cafea6c70b278f58f1b05e6a3d01 100644 (file)
@@ -476,7 +476,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
 }
 
 /* Set order for 1 and 2 plane YCBCR 4:2:2 formats. */
-static void fimc_set_yuv_order(struct fimc_ctx *ctx)
+void fimc_set_yuv_order(struct fimc_ctx *ctx)
 {
        /* The one only mode supported in SoC. */
        ctx->in_order_2p = S5P_FIMC_LSB_CRCB;
@@ -518,7 +518,7 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
        dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
 }
 
-static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
+void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
 {
        struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
        u32 i, depth = 0;
index 87a89f1a81ba2fc2e1039dc7c44644d075911811..1d2cfda5edb1687a6242f228aec9184b30294198 100644 (file)
@@ -663,6 +663,9 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx);
 int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
 int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
                      struct fimc_frame *frame, struct fimc_addr *paddr);
+void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
+void fimc_set_yuv_order(struct fimc_ctx *ctx);
+
 int fimc_register_m2m_device(struct fimc_dev *fimc,
                             struct v4l2_device *v4l2_dev);
 void fimc_unregister_m2m_device(struct fimc_dev *fimc);