summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/media/video/s5p-fimc
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/media/video/s5p-fimc')
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/Makefile5
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-capture.c1583
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.c2045
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.h826
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.c862
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.h118
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-reg.c723
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.c729
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.h25
-rw-r--r--ANDROID_3.4.5/drivers/media/video/s5p-fimc/regs-fimc.h301
10 files changed, 0 insertions, 7217 deletions
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/Makefile b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/Makefile
deleted file mode 100644
index 33dec7f8..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-capture.o fimc-mdevice.o
-s5p-csis-objs := mipi-csis.o
-
-obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc.o
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-capture.c b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-capture.c
deleted file mode 100644
index 7e9b2c61..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-capture.c
+++ /dev/null
@@ -1,1583 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
- *
- * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki, <s.nawrocki@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 <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#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, false);
- fimc_hw_set_output_path(ctx);
- fimc_hw_set_out_dma(ctx);
- if (fimc->variant->has_alpha)
- fimc_hw_set_rgb_alpha(ctx);
- clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
-{
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_vid_buffer *buf;
- unsigned long flags;
- bool streaming;
-
- spin_lock_irqsave(&fimc->slock, flags);
- streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM);
-
- fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
- 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
- if (!suspend)
- fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);
-
- /* Release unused buffers */
- while (!suspend && !list_empty(&cap->pending_buf_q)) {
- buf = fimc_pending_queue_pop(cap);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- /* If suspending put unused buffers onto pending queue */
- while (!list_empty(&cap->active_buf_q)) {
- buf = fimc_active_queue_pop(cap);
- if (suspend)
- fimc_pending_queue_add(cap, buf);
- else
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- set_bit(ST_CAPT_SUSPENDED, &fimc->state);
-
- fimc_hw_reset(fimc);
- cap->buf_index = 0;
-
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (streaming)
- return fimc_pipeline_s_stream(fimc, 0);
- else
- return 0;
-}
-
-static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
-{
- unsigned long flags;
-
- if (!fimc_capture_active(fimc))
- return 0;
-
- spin_lock_irqsave(&fimc->slock, flags);
- set_bit(ST_CAPT_SHUT, &fimc->state);
- fimc_deactivate_capture(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- wait_event_timeout(fimc->irq_queue,
- !test_bit(ST_CAPT_SHUT, &fimc->state),
- (2*HZ/10)); /* 200 ms */
-
- return fimc_capture_state_cleanup(fimc, suspend);
-}
-
-/**
- * fimc_capture_config_update - apply the camera interface configuration
- *
- * To be called from within the interrupt handler with fimc.slock
- * spinlock held. It updates the camera pixel crop, rotation and
- * image flip in H/W.
- */
-int fimc_capture_config_update(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- if (!test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
- return 0;
-
- spin_lock(&ctx->slock);
- fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
- ret = fimc_set_scaler_info(ctx);
- if (ret == 0) {
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_prepare_dma_offset(ctx, &ctx->d_frame);
- fimc_hw_set_out_dma(ctx);
- if (fimc->variant->has_alpha)
- fimc_hw_set_rgb_alpha(ctx);
- clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- }
- spin_unlock(&ctx->slock);
- return ret;
-}
-
-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 fimc_vid_cap *vid_cap = &fimc->vid_cap;
- int min_bufs;
- int ret;
-
- vid_cap->frame_count = 0;
-
- ret = fimc_init_capture(fimc);
- if (ret)
- goto error;
-
- set_bit(ST_CAPT_PEND, &fimc->state);
-
- min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
-
- if (vid_cap->active_buf_cnt >= min_bufs &&
- !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
- fimc_activate_capture(ctx);
-
- if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- fimc_pipeline_s_stream(fimc, 1);
- }
-
- return 0;
-error:
- fimc_capture_state_cleanup(fimc, false);
- return ret;
-}
-
-static int stop_streaming(struct vb2_queue *q)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- if (!fimc_capture_active(fimc))
- return -EINVAL;
-
- return fimc_stop_capture(fimc, false);
-}
-
-int fimc_capture_suspend(struct fimc_dev *fimc)
-{
- bool suspend = fimc_capture_busy(fimc);
-
- int ret = fimc_stop_capture(fimc, suspend);
- if (ret)
- return ret;
- return fimc_pipeline_shutdown(fimc);
-}
-
-static void buffer_queue(struct vb2_buffer *vb);
-
-int fimc_capture_resume(struct fimc_dev *fimc)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct fimc_vid_buffer *buf;
- int i;
-
- if (!test_and_clear_bit(ST_CAPT_SUSPENDED, &fimc->state))
- return 0;
-
- INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
- vid_cap->buf_index = 0;
- fimc_pipeline_initialize(fimc, &fimc->vid_cap.vfd->entity,
- false);
- fimc_init_capture(fimc);
-
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
-
- for (i = 0; i < vid_cap->reqbufs_count; i++) {
- if (list_empty(&vid_cap->pending_buf_q))
- break;
- buf = fimc_pending_queue_pop(vid_cap);
- buffer_queue(&buf->vb);
- }
- return 0;
-
-}
-
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *allocators[])
-{
- const struct v4l2_pix_format_mplane *pixm = NULL;
- struct fimc_ctx *ctx = vq->drv_priv;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_fmt *fmt = frame->fmt;
- unsigned long wh;
- int i;
-
- if (pfmt) {
- pixm = &pfmt->fmt.pix_mp;
- fmt = fimc_find_format(&pixm->pixelformat, NULL,
- FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1);
- wh = pixm->width * pixm->height;
- } else {
- wh = frame->f_width * frame->f_height;
- }
-
- if (fmt == NULL)
- return -EINVAL;
-
- *num_planes = fmt->memplanes;
-
- for (i = 0; i < fmt->memplanes; i++) {
- unsigned int size = (wh * fmt->depth[i]) / 8;
- if (pixm)
- sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
- else
- sizes[i] = size;
- allocators[i] = ctx->fimc_dev->alloc_ctx;
- }
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct fimc_ctx *ctx = vq->drv_priv;
- int i;
-
- if (ctx->d_frame.fmt == NULL)
- return -EINVAL;
-
- for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
- unsigned long size = ctx->d_frame.payload[i];
-
- if (vb2_plane_size(vb, i) < size) {
- v4l2_err(ctx->fimc_dev->vid_cap.vfd,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct fimc_vid_buffer *buf
- = container_of(vb, struct fimc_vid_buffer, vb);
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- unsigned long flags;
- int min_bufs;
-
- spin_lock_irqsave(&fimc->slock, flags);
- fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
-
- if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
- !test_bit(ST_CAPT_STREAM, &fimc->state) &&
- vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
- /* Setup the buffer directly for processing. */
- int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
- vid_cap->buf_index;
-
- fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
- buf->index = vid_cap->buf_index;
- fimc_active_queue_add(vid_cap, buf);
-
- if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
- vid_cap->buf_index = 0;
- } else {
- fimc_pending_queue_add(vid_cap, buf);
- }
-
- min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
-
-
- if (vb2_is_streaming(&vid_cap->vbq) &&
- vid_cap->active_buf_cnt >= min_bufs &&
- !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
- fimc_activate_capture(ctx);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- fimc_pipeline_s_stream(fimc, 1);
- return;
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static void fimc_lock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_lock(&ctx->fimc_dev->lock);
-}
-
-static void fimc_unlock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_unlock(&ctx->fimc_dev->lock);
-}
-
-static struct vb2_ops fimc_capture_qops = {
- .queue_setup = queue_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .wait_prepare = fimc_unlock,
- .wait_finish = fimc_lock,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-/**
- * fimc_capture_ctrls_create - initialize the control handler
- * Initialize the capture video node control handler and fill it
- * with the FIMC controls. Inherit any sensor's controls if the
- * 'user_subdev_api' flag is false (default behaviour).
- * This function need to be called with the graph mutex held.
- */
-int fimc_capture_ctrls_create(struct fimc_dev *fimc)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- int ret;
-
- if (WARN_ON(vid_cap->ctx == NULL))
- return -ENXIO;
- if (vid_cap->ctx->ctrls_rdy)
- return 0;
-
- ret = fimc_ctrls_create(vid_cap->ctx);
- if (ret || vid_cap->user_subdev_api)
- return ret;
-
- return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrl_handler,
- fimc->pipeline.sensor->ctrl_handler);
-}
-
-static int fimc_capture_set_default_format(struct fimc_dev *fimc);
-
-static int fimc_capture_open(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret = v4l2_fh_open(file);
-
- if (ret)
- return ret;
-
- dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
-
- /* Return if the corresponding video mem2mem node is already opened. */
- if (fimc_m2m_active(fimc))
- return -EBUSY;
-
- set_bit(ST_CAPT_BUSY, &fimc->state);
- pm_runtime_get_sync(&fimc->pdev->dev);
-
- if (++fimc->vid_cap.refcnt == 1) {
- ret = fimc_pipeline_initialize(fimc,
- &fimc->vid_cap.vfd->entity, true);
- if (ret < 0) {
- dev_err(&fimc->pdev->dev,
- "Video pipeline initialization failed\n");
- pm_runtime_put_sync(&fimc->pdev->dev);
- fimc->vid_cap.refcnt--;
- v4l2_fh_release(file);
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- return ret;
- }
- ret = fimc_capture_ctrls_create(fimc);
-
- if (!ret && !fimc->vid_cap.user_subdev_api)
- ret = fimc_capture_set_default_format(fimc);
- }
- return ret;
-}
-
-static int fimc_capture_close(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
-
- if (--fimc->vid_cap.refcnt == 0) {
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- fimc_stop_capture(fimc, false);
- fimc_pipeline_shutdown(fimc);
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
- }
-
- pm_runtime_put(&fimc->pdev->dev);
-
- if (fimc->vid_cap.refcnt == 0) {
- vb2_queue_release(&fimc->vid_cap.vbq);
- fimc_ctrls_delete(fimc->vid_cap.ctx);
- }
- return v4l2_fh_release(file);
-}
-
-static unsigned int fimc_capture_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_poll(&fimc->vid_cap.vbq, file, wait);
-}
-
-static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_mmap(&fimc->vid_cap.vbq, vma);
-}
-
-static const struct v4l2_file_operations fimc_capture_fops = {
- .owner = THIS_MODULE,
- .open = fimc_capture_open,
- .release = fimc_capture_close,
- .poll = fimc_capture_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = fimc_capture_mmap,
-};
-
-/*
- * Format and crop negotiation helpers
- */
-
-static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
- u32 *width, u32 *height,
- u32 *code, u32 *fourcc, int pad)
-{
- bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct samsung_fimc_variant *var = fimc->variant;
- struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *dst = &ctx->d_frame;
- u32 depth, min_w, max_w, min_h, align_h = 3;
- u32 mask = FMT_FLAGS_CAM;
- struct fimc_fmt *ffmt;
-
- /* Color conversion from/to JPEG is not supported */
- if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
- fimc_fmt_is_jpeg(ctx->s_frame.fmt->color))
- *code = V4L2_MBUS_FMT_JPEG_1X8;
-
- if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK)
- mask |= FMT_FLAGS_M2M;
-
- ffmt = fimc_find_format(fourcc, code, mask, 0);
- if (WARN_ON(!ffmt))
- return NULL;
- if (code)
- *code = ffmt->mbus_code;
- if (fourcc)
- *fourcc = ffmt->fourcc;
-
- if (pad == FIMC_SD_PAD_SINK) {
- max_w = fimc_fmt_is_jpeg(ffmt->color) ?
- pl->scaler_dis_w : pl->scaler_en_w;
- /* Apply the camera input interface pixel constraints */
- v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
- height, max_t(u32, *height, 32),
- FIMC_CAMIF_MAX_HEIGHT,
- fimc_fmt_is_jpeg(ffmt->color) ? 3 : 1,
- 0);
- return ffmt;
- }
- /* Can't scale or crop in transparent (JPEG) transfer mode */
- if (fimc_fmt_is_jpeg(ffmt->color)) {
- *width = ctx->s_frame.f_width;
- *height = ctx->s_frame.f_height;
- return ffmt;
- }
- /* Apply the scaler and the output DMA constraints */
- max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w;
- min_w = ctx->state & FIMC_DST_CROP ? dst->width : var->min_out_pixsize;
- min_h = ctx->state & FIMC_DST_CROP ? dst->height : var->min_out_pixsize;
- if (var->min_vsize_align == 1 && !rotation)
- align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1;
-
- depth = fimc_get_format_depth(ffmt);
- v4l_bound_align_image(width, min_w, max_w,
- ffs(var->min_out_pixsize) - 1,
- height, min_h, FIMC_CAMIF_MAX_HEIGHT,
- align_h,
- 64/(ALIGN(depth, 8)));
-
- dbg("pad%d: code: 0x%x, %dx%d. dst fmt: %dx%d",
- pad, code ? *code : 0, *width, *height,
- dst->f_width, dst->f_height);
-
- return ffmt;
-}
-
-static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r,
- int pad)
-{
- bool rotate = ctx->rotation == 90 || ctx->rotation == 270;
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct samsung_fimc_variant *var = fimc->variant;
- struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *sink = &ctx->s_frame;
- u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
- u32 align_sz = 0, align_h = 4;
- u32 max_sc_h, max_sc_v;
-
- /* In JPEG transparent transfer mode cropping is not supported */
- if (fimc_fmt_is_jpeg(ctx->d_frame.fmt->color)) {
- r->width = sink->f_width;
- r->height = sink->f_height;
- r->left = r->top = 0;
- return;
- }
- if (pad == FIMC_SD_PAD_SOURCE) {
- if (ctx->rotation != 90 && ctx->rotation != 270)
- align_h = 1;
- max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3));
- max_sc_v = min(SCALER_MAX_VRATIO, 1 << (ffs(sink->height) - 1));
- min_sz = var->min_out_pixsize;
- } else {
- u32 depth = fimc_get_format_depth(sink->fmt);
- align_sz = 64/ALIGN(depth, 8);
- min_sz = var->min_inp_pixsize;
- min_w = min_h = min_sz;
- max_sc_h = max_sc_v = 1;
- }
- /*
- * For the crop rectangle at source pad the following constraints
- * must be met:
- * - it must fit in the sink pad format rectangle (f_width/f_height);
- * - maximum downscaling ratio is 64;
- * - maximum crop size depends if the rotator is used or not;
- * - the sink pad format width/height must be 4 multiple of the
- * prescaler ratios determined by sink pad size and source pad crop,
- * the prescaler ratio is returned by fimc_get_scaler_factor().
- */
- max_w = min_t(u32,
- rotate ? pl->out_rot_en_w : pl->out_rot_dis_w,
- rotate ? sink->f_height : sink->f_width);
- max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
- if (pad == FIMC_SD_PAD_SOURCE) {
- min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
- min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
- if (rotate) {
- swap(max_sc_h, max_sc_v);
- swap(min_w, min_h);
- }
- }
- v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1,
- &r->height, min_h, max_h, align_h,
- align_sz);
- /* Adjust left/top if cropping rectangle is out of bounds */
- r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width);
- r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height);
- r->left = round_down(r->left, var->hor_offs_align);
-
- dbg("pad%d: (%d,%d)/%dx%d, sink fmt: %dx%d",
- pad, r->left, r->top, r->width, r->height,
- sink->f_width, sink->f_height);
-}
-
-/*
- * The video node ioctl operations
- */
-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
- strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
-
- return 0;
-}
-
-static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M,
- f->index);
- if (!fmt)
- return -EINVAL;
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
- f->pixelformat = fmt->fourcc;
- if (fmt->fourcc == V4L2_MBUS_FMT_JPEG_1X8)
- f->flags |= V4L2_FMT_FLAG_COMPRESSED;
- return 0;
-}
-
-/**
- * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
- * elements
- * @ctx: FIMC capture context
- * @tfmt: media bus format to try/set on subdevs
- * @fmt_id: fimc pixel format id corresponding to returned @tfmt (output)
- * @set: true to set format on subdevs, false to try only
- */
-static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
- struct v4l2_mbus_framefmt *tfmt,
- struct fimc_fmt **fmt_id,
- bool set)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct v4l2_subdev *sd = fimc->pipeline.sensor;
- struct v4l2_subdev *csis = fimc->pipeline.csis;
- struct v4l2_subdev_format sfmt;
- struct v4l2_mbus_framefmt *mf = &sfmt.format;
- struct fimc_fmt *ffmt = NULL;
- int ret, i = 0;
-
- if (WARN_ON(!sd || !tfmt))
- return -EINVAL;
-
- memset(&sfmt, 0, sizeof(sfmt));
- sfmt.format = *tfmt;
-
- sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
- while (1) {
- ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
- FMT_FLAGS_CAM, i++);
- if (ffmt == NULL) {
- /*
- * Notify user-space if common pixel code for
- * host and sensor does not exist.
- */
- return -EINVAL;
- }
- mf->code = tfmt->code = ffmt->mbus_code;
-
- ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
- if (ret)
- return ret;
- if (mf->code != tfmt->code) {
- mf->code = 0;
- continue;
- }
- if (mf->width != tfmt->width || mf->height != tfmt->height) {
- u32 fcc = ffmt->fourcc;
- tfmt->width = mf->width;
- tfmt->height = mf->height;
- ffmt = fimc_capture_try_format(ctx,
- &tfmt->width, &tfmt->height,
- NULL, &fcc, FIMC_SD_PAD_SOURCE);
- if (ffmt && ffmt->mbus_code)
- mf->code = ffmt->mbus_code;
- if (mf->width != tfmt->width ||
- mf->height != tfmt->height)
- continue;
- tfmt->code = mf->code;
- }
- if (csis)
- ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt);
-
- if (mf->code == tfmt->code &&
- mf->width == tfmt->width && mf->height == tfmt->height)
- break;
- }
-
- if (fmt_id && ffmt)
- *fmt_id = ffmt;
- *tfmt = *mf;
-
- dbg("code: 0x%x, %dx%d, %p", mf->code, mf->width, mf->height, ffmt);
- return 0;
-}
-
-static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- return fimc_fill_format(&ctx->d_frame, f);
-}
-
-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_mbus_framefmt mf;
- struct fimc_fmt *ffmt = NULL;
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SINK);
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (!ffmt)
- return -EINVAL;
-
- if (!fimc->vid_cap.user_subdev_api) {
- mf.width = pix->width;
- mf.height = pix->height;
- mf.code = ffmt->mbus_code;
- fimc_md_graph_lock(fimc);
- fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
- fimc_md_graph_unlock(fimc);
-
- pix->width = mf.width;
- pix->height = mf.height;
- if (ffmt)
- pix->pixelformat = ffmt->fourcc;
- }
-
- fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
- return 0;
-}
-
-static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx, bool jpeg)
-{
- ctx->scaler.enabled = !jpeg;
- fimc_ctrls_activate(ctx, !jpeg);
-
- if (jpeg)
- set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
- else
- clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
-}
-
-static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.mf;
- struct fimc_frame *ff = &ctx->d_frame;
- struct fimc_fmt *s_fmt = NULL;
- int ret, i;
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
- if (vb2_is_busy(&fimc->vid_cap.vbq))
- return -EBUSY;
-
- /* Pre-configure format at camera interface input, for JPEG only */
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SINK);
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- /* Try the format at the scaler and the DMA output */
- ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (!ff->fmt)
- return -EINVAL;
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- /* Try to match format at the host and the sensor */
- if (!fimc->vid_cap.user_subdev_api) {
- mf->code = ff->fmt->mbus_code;
- mf->width = pix->width;
- mf->height = pix->height;
-
- fimc_md_graph_lock(fimc);
- ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
- fimc_md_graph_unlock(fimc);
- if (ret)
- return ret;
- pix->width = mf->width;
- pix->height = mf->height;
- }
- fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
- for (i = 0; i < ff->fmt->colplanes; i++)
- ff->payload[i] =
- (pix->width * pix->height * ff->fmt->depth[i]) / 8;
-
- set_frame_bounds(ff, pix->width, pix->height);
- /* Reset the composition rectangle if not yet configured */
- if (!(ctx->state & FIMC_DST_CROP))
- set_frame_crop(ff, 0, 0, pix->width, pix->height);
-
- fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color));
-
- /* Reset cropping and set format at the camera interface input */
- if (!fimc->vid_cap.user_subdev_api) {
- ctx->s_frame.fmt = s_fmt;
- set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
- set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
- }
-
- return ret;
-}
-
-static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return fimc_capture_set_format(fimc, f);
-}
-
-static int fimc_cap_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct v4l2_subdev *sd = fimc->pipeline.sensor;
-
- if (i->index != 0)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- if (sd)
- strlcpy(i->name, sd->name, sizeof(i->name));
- return 0;
-}
-
-static int fimc_cap_s_input(struct file *file, void *priv, unsigned int i)
-{
- return i == 0 ? i : -EINVAL;
-}
-
-static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-/**
- * fimc_pipeline_validate - check for formats inconsistencies
- * between source and sink pad of each link
- *
- * Return 0 if all formats match or -EPIPE otherwise.
- */
-static int fimc_pipeline_validate(struct fimc_dev *fimc)
-{
- struct v4l2_subdev_format sink_fmt, src_fmt;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct v4l2_subdev *sd;
- struct media_pad *pad;
- int ret;
-
- /* Start with the video capture node pad */
- pad = media_entity_remote_source(&vid_cap->vd_pad);
- if (pad == NULL)
- return -EPIPE;
- /* FIMC.{N} subdevice */
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
- while (1) {
- /* Retrieve format at the sink pad */
- pad = &sd->entity.pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
- /* Don't call FIMC subdev operation to avoid nested locking */
- if (sd == fimc->vid_cap.subdev) {
- struct fimc_frame *ff = &vid_cap->ctx->s_frame;
- sink_fmt.format.width = ff->f_width;
- sink_fmt.format.height = ff->f_height;
- sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0;
- } else {
- sink_fmt.pad = pad->index;
- sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
- }
- /* Retrieve format at the source pad */
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
- src_fmt.pad = pad->index;
- src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- if (src_fmt.format.width != sink_fmt.format.width ||
- src_fmt.format.height != sink_fmt.format.height ||
- src_fmt.format.code != sink_fmt.format.code)
- return -EPIPE;
- }
- return 0;
-}
-
-static int fimc_cap_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_pipeline *p = &fimc->pipeline;
- int ret;
-
- if (fimc_capture_active(fimc))
- return -EBUSY;
-
- media_entity_pipeline_start(&p->sensor->entity, p->pipe);
-
- if (fimc->vid_cap.user_subdev_api) {
- ret = fimc_pipeline_validate(fimc);
- if (ret)
- return ret;
- }
- return vb2_streamon(&fimc->vid_cap.vbq, type);
-}
-
-static int fimc_cap_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct v4l2_subdev *sd = fimc->pipeline.sensor;
- int ret;
-
- ret = vb2_streamoff(&fimc->vid_cap.vbq, type);
- if (ret == 0)
- media_entity_pipeline_stop(&sd->entity);
- return ret;
-}
-
-static int fimc_cap_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret = vb2_reqbufs(&fimc->vid_cap.vbq, reqbufs);
-
- if (!ret)
- fimc->vid_cap.reqbufs_count = reqbufs->count;
- return ret;
-}
-
-static int fimc_cap_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_querybuf(&fimc->vid_cap.vbq, buf);
-}
-
-static int fimc_cap_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_qbuf(&fimc->vid_cap.vbq, buf);
-}
-
-static int fimc_cap_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK);
-}
-
-static int fimc_cap_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *create)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_create_bufs(&fimc->vid_cap.vbq, create);
-}
-
-static int fimc_cap_prepare_buf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_prepare_buf(&fimc->vid_cap.vbq, b);
-}
-
-static int fimc_cap_g_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- f = &ctx->d_frame;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = f->o_width;
- s->r.height = f->o_height;
- return 0;
-
- case V4L2_SEL_TGT_COMPOSE_ACTIVE:
- f = &ctx->d_frame;
- case V4L2_SEL_TGT_CROP_ACTIVE:
- s->r.left = f->offs_h;
- s->r.top = f->offs_v;
- s->r.width = f->width;
- s->r.height = f->height;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
-int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
-{
- if (a->left < b->left || a->top < b->top)
- return 0;
- if (a->left + a->width > b->left + b->width)
- return 0;
- if (a->top + a->height > b->top + b->height)
- return 0;
-
- return 1;
-}
-
-static int fimc_cap_s_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_rect rect = s->r;
- struct fimc_frame *f;
- unsigned long flags;
- unsigned int pad;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- case V4L2_SEL_TGT_COMPOSE_ACTIVE:
- f = &ctx->d_frame;
- pad = FIMC_SD_PAD_SOURCE;
- break;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP_ACTIVE:
- f = &ctx->s_frame;
- pad = FIMC_SD_PAD_SINK;
- break;
- default:
- return -EINVAL;
- }
-
- fimc_capture_try_crop(ctx, &rect, pad);
-
- if (s->flags & V4L2_SEL_FLAG_LE &&
- !enclosed_rectangle(&rect, &s->r))
- return -ERANGE;
-
- if (s->flags & V4L2_SEL_FLAG_GE &&
- !enclosed_rectangle(&s->r, &rect))
- return -ERANGE;
-
- s->r = rect;
- spin_lock_irqsave(&fimc->slock, flags);
- set_frame_crop(f, s->r.left, s->r.top, s->r.width,
- s->r.height);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
- .vidioc_querycap = fimc_vidioc_querycap_capture,
-
- .vidioc_enum_fmt_vid_cap_mplane = fimc_cap_enum_fmt_mplane,
- .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
-
- .vidioc_reqbufs = fimc_cap_reqbufs,
- .vidioc_querybuf = fimc_cap_querybuf,
-
- .vidioc_qbuf = fimc_cap_qbuf,
- .vidioc_dqbuf = fimc_cap_dqbuf,
-
- .vidioc_prepare_buf = fimc_cap_prepare_buf,
- .vidioc_create_bufs = fimc_cap_create_bufs,
-
- .vidioc_streamon = fimc_cap_streamon,
- .vidioc_streamoff = fimc_cap_streamoff,
-
- .vidioc_g_selection = fimc_cap_g_selection,
- .vidioc_s_selection = fimc_cap_s_selection,
-
- .vidioc_enum_input = fimc_cap_enum_input,
- .vidioc_s_input = fimc_cap_s_input,
- .vidioc_g_input = fimc_cap_g_input,
-};
-
-/* Capture subdev media entity operations */
-static int fimc_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
-
- if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- return -EINVAL;
-
- if (WARN_ON(fimc == NULL))
- return 0;
-
- dbg("%s --> %s, flags: 0x%x. input: 0x%x",
- local->entity->name, remote->entity->name, flags,
- fimc->vid_cap.input);
-
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (fimc->vid_cap.input != 0)
- return -EBUSY;
- fimc->vid_cap.input = sd->grp_id;
- return 0;
- }
-
- fimc->vid_cap.input = 0;
- return 0;
-}
-
-static const struct media_entity_operations fimc_sd_media_ops = {
- .link_setup = fimc_link_setup,
-};
-
-/**
- * fimc_sensor_notify - v4l2_device notification from a sensor subdev
- * @sd: pointer to a subdev generating the notification
- * @notification: the notification type, must be S5P_FIMC_TX_END_NOTIFY
- * @arg: pointer to an u32 type integer that stores the frame payload value
- *
- * The End Of Frame notification sent by sensor subdev in its still capture
- * mode. If there is only a single VSYNC generated by the sensor at the
- * beginning of a frame transmission, FIMC does not issue the LastIrq
- * (end of frame) interrupt. And this notification is used to complete the
- * frame capture and returning a buffer to user-space. Subdev drivers should
- * call this notification from their last 'End of frame capture' interrupt.
- */
-void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
- void *arg)
-{
- struct fimc_sensor_info *sensor;
- struct fimc_vid_buffer *buf;
- struct fimc_md *fmd;
- struct fimc_dev *fimc;
- unsigned long flags;
-
- if (sd == NULL)
- return;
-
- sensor = v4l2_get_subdev_hostdata(sd);
- fmd = entity_to_fimc_mdev(&sd->entity);
-
- spin_lock_irqsave(&fmd->slock, flags);
- fimc = sensor ? sensor->host : NULL;
-
- if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
- test_bit(ST_CAPT_PEND, &fimc->state)) {
- unsigned long irq_flags;
- spin_lock_irqsave(&fimc->slock, irq_flags);
- if (!list_empty(&fimc->vid_cap.active_buf_q)) {
- buf = list_entry(fimc->vid_cap.active_buf_q.next,
- struct fimc_vid_buffer, list);
- vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
- }
- fimc_capture_irq_handler(fimc, true);
- fimc_deactivate_capture(fimc);
- spin_unlock_irqrestore(&fimc->slock, irq_flags);
- }
- spin_unlock_irqrestore(&fmd->slock, flags);
-}
-
-static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index);
- if (!fmt)
- return -EINVAL;
- code->code = fmt->mbus_code;
- return 0;
-}
-
-static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_mbus_framefmt *mf;
- struct fimc_frame *ff;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- fmt->format = *mf;
- return 0;
- }
- mf = &fmt->format;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- ff = fmt->pad == FIMC_SD_PAD_SINK ? &ctx->s_frame : &ctx->d_frame;
-
- mutex_lock(&fimc->lock);
- /* The pixel code is same on both input and output pad */
- if (!WARN_ON(ctx->s_frame.fmt == NULL))
- mf->code = ctx->s_frame.fmt->mbus_code;
- mf->width = ff->f_width;
- mf->height = ff->f_height;
- mutex_unlock(&fimc->lock);
-
- return 0;
-}
-
-static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *ff;
- struct fimc_fmt *ffmt;
-
- dbg("pad%d: code: 0x%x, %dx%d",
- fmt->pad, mf->code, mf->width, mf->height);
-
- if (fmt->pad == FIMC_SD_PAD_SOURCE &&
- vb2_is_busy(&fimc->vid_cap.vbq))
- return -EBUSY;
-
- mutex_lock(&fimc->lock);
- ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height,
- &mf->code, NULL, fmt->pad);
- mutex_unlock(&fimc->lock);
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- *mf = fmt->format;
- return 0;
- }
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color));
-
- ff = fmt->pad == FIMC_SD_PAD_SINK ?
- &ctx->s_frame : &ctx->d_frame;
-
- mutex_lock(&fimc->lock);
- set_frame_bounds(ff, mf->width, mf->height);
- fimc->vid_cap.mf = *mf;
- ff->fmt = ffmt;
-
- /* Reset the crop rectangle if required. */
- if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_DST_CROP)))
- set_frame_crop(ff, 0, 0, mf->width, mf->height);
-
- if (fmt->pad == FIMC_SD_PAD_SINK)
- ctx->state &= ~FIMC_DST_CROP;
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_subdev_get_crop(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_rect *r = &crop->rect;
- struct fimc_frame *ff;
-
- if (crop->which == V4L2_SUBDEV_FORMAT_TRY) {
- crop->rect = *v4l2_subdev_get_try_crop(fh, crop->pad);
- return 0;
- }
- ff = crop->pad == FIMC_SD_PAD_SINK ?
- &ctx->s_frame : &ctx->d_frame;
-
- mutex_lock(&fimc->lock);
- r->left = ff->offs_h;
- r->top = ff->offs_v;
- r->width = ff->width;
- r->height = ff->height;
- mutex_unlock(&fimc->lock);
-
- dbg("ff:%p, pad%d: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
- ff, crop->pad, r->left, r->top, r->width, r->height,
- ff->f_width, ff->f_height);
-
- return 0;
-}
-
-static int fimc_subdev_set_crop(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_rect *r = &crop->rect;
- struct fimc_frame *ff;
- unsigned long flags;
-
- dbg("(%d,%d)/%dx%d", r->left, r->top, r->width, r->height);
-
- ff = crop->pad == FIMC_SD_PAD_SOURCE ?
- &ctx->d_frame : &ctx->s_frame;
-
- mutex_lock(&fimc->lock);
- fimc_capture_try_crop(ctx, r, crop->pad);
-
- if (crop->which == V4L2_SUBDEV_FORMAT_TRY) {
- mutex_unlock(&fimc->lock);
- *v4l2_subdev_get_try_crop(fh, crop->pad) = *r;
- return 0;
- }
- spin_lock_irqsave(&fimc->slock, flags);
- set_frame_crop(ff, r->left, r->top, r->width, r->height);
- if (crop->pad == FIMC_SD_PAD_SOURCE)
- ctx->state |= FIMC_DST_CROP;
-
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- dbg("pad%d: (%d,%d)/%dx%d", crop->pad, r->left, r->top,
- r->width, r->height);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
- .enum_mbus_code = fimc_subdev_enum_mbus_code,
- .get_fmt = fimc_subdev_get_fmt,
- .set_fmt = fimc_subdev_set_fmt,
- .get_crop = fimc_subdev_get_crop,
- .set_crop = fimc_subdev_set_crop,
-};
-
-static struct v4l2_subdev_ops fimc_subdev_ops = {
- .pad = &fimc_subdev_pad_ops,
-};
-
-static int fimc_create_capture_subdev(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct v4l2_subdev *sd;
- int ret;
-
- sd = kzalloc(sizeof(*sd), GFP_KERNEL);
- if (!sd)
- return -ENOMEM;
-
- v4l2_subdev_init(sd, &fimc_subdev_ops);
- sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);
-
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
- fimc->vid_cap.sd_pads, 0);
- if (ret)
- goto me_err;
- ret = v4l2_device_register_subdev(v4l2_dev, sd);
- if (ret)
- goto sd_err;
-
- fimc->vid_cap.subdev = sd;
- v4l2_set_subdevdata(sd, fimc);
- sd->entity.ops = &fimc_sd_media_ops;
- return 0;
-sd_err:
- media_entity_cleanup(&sd->entity);
-me_err:
- kfree(sd);
- return ret;
-}
-
-static void fimc_destroy_capture_subdev(struct fimc_dev *fimc)
-{
- struct v4l2_subdev *sd = fimc->vid_cap.subdev;
-
- if (!sd)
- return;
- media_entity_cleanup(&sd->entity);
- v4l2_device_unregister_subdev(sd);
- kfree(sd);
- fimc->vid_cap.subdev = NULL;
-}
-
-/* Set default format at the sensor and host interface */
-static int fimc_capture_set_default_format(struct fimc_dev *fimc)
-{
- struct v4l2_format fmt = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- .fmt.pix_mp = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
- };
-
- return fimc_capture_set_format(fimc, &fmt);
-}
-
-/* fimc->lock must be already initialized */
-int fimc_register_capture_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct video_device *vfd;
- struct fimc_vid_cap *vid_cap;
- struct fimc_ctx *ctx;
- struct vb2_queue *q;
- int ret = -ENOMEM;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- ctx->fimc_dev = fimc;
- ctx->in_path = FIMC_CAMERA;
- ctx->out_path = FIMC_DMA;
- ctx->state = FIMC_CTX_CAP;
- ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
- ctx->d_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(v4l2_dev, "Failed to allocate video device\n");
- goto err_vd_alloc;
- }
-
- snprintf(vfd->name, sizeof(vfd->name), "%s.capture",
- dev_name(&fimc->pdev->dev));
-
- vfd->fops = &fimc_capture_fops;
- vfd->ioctl_ops = &fimc_capture_ioctl_ops;
- vfd->v4l2_dev = v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release;
- vfd->lock = &fimc->lock;
- video_set_drvdata(vfd, fimc);
-
- vid_cap = &fimc->vid_cap;
- vid_cap->vfd = vfd;
- vid_cap->active_buf_cnt = 0;
- vid_cap->reqbufs_count = 0;
- vid_cap->refcnt = 0;
-
- INIT_LIST_HEAD(&vid_cap->pending_buf_q);
- INIT_LIST_HEAD(&vid_cap->active_buf_q);
- spin_lock_init(&ctx->slock);
- vid_cap->ctx = ctx;
-
- q = &fimc->vid_cap.vbq;
- memset(q, 0, sizeof(*q));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = fimc->vid_cap.ctx;
- q->ops = &fimc_capture_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct fimc_vid_buffer);
-
- vb2_queue_init(q);
-
- fimc->vid_cap.vd_pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_init(&vfd->entity, 1, &fimc->vid_cap.vd_pad, 0);
- if (ret)
- goto err_ent;
- ret = fimc_create_capture_subdev(fimc, v4l2_dev);
- if (ret)
- goto err_sd_reg;
-
- vfd->ctrl_handler = &ctx->ctrl_handler;
- return 0;
-
-err_sd_reg:
- media_entity_cleanup(&vfd->entity);
-err_ent:
- video_device_release(vfd);
-err_vd_alloc:
- kfree(ctx);
- return ret;
-}
-
-void fimc_unregister_capture_device(struct fimc_dev *fimc)
-{
- struct video_device *vfd = fimc->vid_cap.vfd;
-
- if (vfd) {
- media_entity_cleanup(&vfd->entity);
- /* Can also be called if video device was
- not registered */
- video_unregister_device(vfd);
- }
- fimc_destroy_capture_subdev(fimc);
- kfree(fimc->vid_cap.ctx);
- fimc->vid_cap.ctx = NULL;
-}
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.c b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.c
deleted file mode 100644
index e09ba7b0..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.c
+++ /dev/null
@@ -1,2045 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series camera interface (video postprocessor) driver
- *
- * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
- * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "fimc-core.h"
-#include "fimc-mdevice.h"
-
-static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
- "sclk_fimc", "fimc"
-};
-
-static struct fimc_fmt fimc_formats[] = {
- {
- .name = "RGB565",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = { 16 },
- .color = S5P_FIMC_RGB565,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "BGR666",
- .fourcc = V4L2_PIX_FMT_BGR666,
- .depth = { 32 },
- .color = S5P_FIMC_RGB666,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "ARGB8888, 32 bpp",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .depth = { 32 },
- .color = S5P_FIMC_RGB888,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA,
- }, {
- .name = "ARGB1555",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .depth = { 16 },
- .color = S5P_FIMC_RGB555,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
- }, {
- .name = "ARGB4444",
- .fourcc = V4L2_PIX_FMT_RGB444,
- .depth = { 16 },
- .color = S5P_FIMC_RGB444,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
- }, {
- .name = "YUV 4:2:2 packed, YCbYCr",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = { 16 },
- .color = S5P_FIMC_YCBYCR422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 packed, CbYCrY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = { 16 },
- .color = S5P_FIMC_CBYCRY422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 packed, CrYCbY",
- .fourcc = V4L2_PIX_FMT_VYUY,
- .depth = { 16 },
- .color = S5P_FIMC_CRYCBY422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 packed, YCrYCb",
- .fourcc = V4L2_PIX_FMT_YVYU,
- .depth = { 16 },
- .color = S5P_FIMC_YCRYCB422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 planar, Y/Cb/Cr",
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .depth = { 12 },
- .color = S5P_FIMC_YCBYCR422,
- .memplanes = 1,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:2 planar, Y/CbCr",
- .fourcc = V4L2_PIX_FMT_NV16,
- .depth = { 16 },
- .color = S5P_FIMC_YCBYCR422,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:2 planar, Y/CrCb",
- .fourcc = V4L2_PIX_FMT_NV61,
- .depth = { 16 },
- .color = S5P_FIMC_YCRYCB422,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 planar, YCbCr",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .depth = { 12 },
- .color = S5P_FIMC_YCBCR420,
- .memplanes = 1,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 planar, Y/CbCr",
- .fourcc = V4L2_PIX_FMT_NV12,
- .depth = { 12 },
- .color = S5P_FIMC_YCBCR420,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .color = S5P_FIMC_YCBCR420,
- .depth = { 8, 4 },
- .memplanes = 2,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr",
- .fourcc = V4L2_PIX_FMT_YUV420M,
- .color = S5P_FIMC_YCBCR420,
- .depth = { 8, 2, 2 },
- .memplanes = 3,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled",
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .color = S5P_FIMC_YCBCR420,
- .depth = { 8, 4 },
- .memplanes = 2,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "JPEG encoded data",
- .fourcc = V4L2_PIX_FMT_JPEG,
- .color = S5P_FIMC_JPEG,
- .depth = { 8 },
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
- .flags = FMT_FLAGS_CAM,
- },
-};
-
-static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
-{
- if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return FMT_FLAGS_M2M_IN;
- else
- return FMT_FLAGS_M2M_OUT;
-}
-
-int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
- int dw, int dh, int rotation)
-{
- if (rotation == 90 || rotation == 270)
- swap(dw, dh);
-
- if (!ctx->scaler.enabled)
- return (sw == dw && sh == dh) ? 0 : -EINVAL;
-
- if ((sw >= SCALER_MAX_HRATIO * dw) || (sh >= SCALER_MAX_VRATIO * dh))
- return -EINVAL;
-
- return 0;
-}
-
-static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
-{
- u32 sh = 6;
-
- if (src >= 64 * tar)
- return -EINVAL;
-
- while (sh--) {
- u32 tmp = 1 << sh;
- if (src >= tar * tmp) {
- *shift = sh, *ratio = tmp;
- return 0;
- }
- }
- *shift = 0, *ratio = 1;
- return 0;
-}
-
-int fimc_set_scaler_info(struct fimc_ctx *ctx)
-{
- struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
- struct device *dev = &ctx->fimc_dev->pdev->dev;
- struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *s_frame = &ctx->s_frame;
- struct fimc_frame *d_frame = &ctx->d_frame;
- int tx, ty, sx, sy;
- int ret;
-
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- ty = d_frame->width;
- tx = d_frame->height;
- } else {
- tx = d_frame->width;
- ty = d_frame->height;
- }
- if (tx <= 0 || ty <= 0) {
- dev_err(dev, "Invalid target size: %dx%d", tx, ty);
- return -EINVAL;
- }
-
- sx = s_frame->width;
- sy = s_frame->height;
- if (sx <= 0 || sy <= 0) {
- dev_err(dev, "Invalid source size: %dx%d", sx, sy);
- return -EINVAL;
- }
- sc->real_width = sx;
- sc->real_height = sy;
-
- ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
- if (ret)
- return ret;
-
- ret = fimc_get_scaler_factor(sy, ty, &sc->pre_vratio, &sc->vfactor);
- if (ret)
- return ret;
-
- sc->pre_dst_width = sx / sc->pre_hratio;
- sc->pre_dst_height = sy / sc->pre_vratio;
-
- if (variant->has_mainscaler_ext) {
- sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
- sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
- } else {
- sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
- sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
-
- }
-
- sc->scaleup_h = (tx >= sx) ? 1 : 0;
- sc->scaleup_v = (ty >= sy) ? 1 : 0;
-
- /* check to see if input and output size/format differ */
- if (s_frame->fmt->color == d_frame->fmt->color
- && s_frame->width == d_frame->width
- && s_frame->height == d_frame->height)
- sc->copy_mode = 1;
- else
- sc->copy_mode = 0;
-
- return 0;
-}
-
-static void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
-{
- struct vb2_buffer *src_vb, *dst_vb;
-
- if (!ctx || !ctx->m2m_ctx)
- return;
-
- src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-
- if (src_vb && dst_vb) {
- v4l2_m2m_buf_done(src_vb, vb_state);
- v4l2_m2m_buf_done(dst_vb, vb_state);
- v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
- ctx->m2m_ctx);
- }
-}
-
-/* Complete the transaction which has been scheduled for execution. */
-static int fimc_m2m_shutdown(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- if (!fimc_m2m_pending(fimc))
- return 0;
-
- fimc_ctx_state_lock_set(FIMC_CTX_SHUT, ctx);
-
- ret = wait_event_timeout(fimc->irq_queue,
- !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
- FIMC_SHUTDOWN_TIMEOUT);
-
- return ret == 0 ? -ETIMEDOUT : ret;
-}
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- int ret;
-
- ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
- return ret > 0 ? 0 : ret;
-}
-
-static int stop_streaming(struct vb2_queue *q)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- int ret;
-
- ret = fimc_m2m_shutdown(ctx);
- if (ret == -ETIMEDOUT)
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
-
- pm_runtime_put(&ctx->fimc_dev->pdev->dev);
- return 0;
-}
-
-void fimc_capture_irq_handler(struct fimc_dev *fimc, bool final)
-{
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_vid_buffer *v_buf;
- struct timeval *tv;
- struct timespec ts;
-
- if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
- wake_up(&fimc->irq_queue);
- return;
- }
-
- if (!list_empty(&cap->active_buf_q) &&
- test_bit(ST_CAPT_RUN, &fimc->state) && final) {
- ktime_get_real_ts(&ts);
-
- v_buf = fimc_active_queue_pop(cap);
-
- tv = &v_buf->vb.v4l2_buf.timestamp;
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
- v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
-
- vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
- }
-
- if (!list_empty(&cap->pending_buf_q)) {
-
- v_buf = fimc_pending_queue_pop(cap);
- fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
- v_buf->index = cap->buf_index;
-
- /* Move the buffer to the capture active queue */
- fimc_active_queue_add(cap, v_buf);
-
- dbg("next frame: %d, done frame: %d",
- fimc_hw_get_frame_index(fimc), v_buf->index);
-
- if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
- cap->buf_index = 0;
- }
-
- if (cap->active_buf_cnt == 0) {
- if (final)
- clear_bit(ST_CAPT_RUN, &fimc->state);
-
- if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
- cap->buf_index = 0;
- } else {
- set_bit(ST_CAPT_RUN, &fimc->state);
- }
-
- fimc_capture_config_update(cap->ctx);
-
- dbg("frame: %d, active_buf_cnt: %d",
- fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
-}
-
-static irqreturn_t fimc_irq_handler(int irq, void *priv)
-{
- struct fimc_dev *fimc = priv;
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_ctx *ctx;
-
- fimc_hw_clear_irq(fimc);
-
- spin_lock(&fimc->slock);
-
- if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) {
- if (test_and_clear_bit(ST_M2M_SUSPENDING, &fimc->state)) {
- set_bit(ST_M2M_SUSPENDED, &fimc->state);
- wake_up(&fimc->irq_queue);
- goto out;
- }
- ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev);
- if (ctx != NULL) {
- spin_unlock(&fimc->slock);
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
-
- spin_lock(&ctx->slock);
- if (ctx->state & FIMC_CTX_SHUT) {
- ctx->state &= ~FIMC_CTX_SHUT;
- wake_up(&fimc->irq_queue);
- }
- spin_unlock(&ctx->slock);
- }
- return IRQ_HANDLED;
- } else if (test_bit(ST_CAPT_PEND, &fimc->state)) {
- fimc_capture_irq_handler(fimc,
- !test_bit(ST_CAPT_JPEG, &fimc->state));
- if (cap->active_buf_cnt == 1) {
- fimc_deactivate_capture(fimc);
- clear_bit(ST_CAPT_STREAM, &fimc->state);
- }
- }
-out:
- spin_unlock(&fimc->slock);
- return IRQ_HANDLED;
-}
-
-/* The color format (colplanes, memplanes) must be already configured. */
-int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *paddr)
-{
- int ret = 0;
- u32 pix_size;
-
- if (vb == NULL || frame == NULL)
- return -EINVAL;
-
- pix_size = frame->width * frame->height;
-
- dbg("memplanes= %d, colplanes= %d, pix_size= %d",
- frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
-
- paddr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- if (frame->fmt->memplanes == 1) {
- switch (frame->fmt->colplanes) {
- case 1:
- paddr->cb = 0;
- paddr->cr = 0;
- break;
- case 2:
- /* decompose Y into Y/Cb */
- paddr->cb = (u32)(paddr->y + pix_size);
- paddr->cr = 0;
- break;
- case 3:
- paddr->cb = (u32)(paddr->y + pix_size);
- /* decompose Y into Y/Cb/Cr */
- if (S5P_FIMC_YCBCR420 == frame->fmt->color)
- paddr->cr = (u32)(paddr->cb
- + (pix_size >> 2));
- else /* 422 */
- paddr->cr = (u32)(paddr->cb
- + (pix_size >> 1));
- break;
- default:
- return -EINVAL;
- }
- } else {
- if (frame->fmt->memplanes >= 2)
- paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
-
- if (frame->fmt->memplanes == 3)
- paddr->cr = vb2_dma_contig_plane_dma_addr(vb, 2);
- }
-
- dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
- paddr->y, paddr->cb, paddr->cr, ret);
-
- return ret;
-}
-
-/* Set order for 1 and 2 plane YCBCR 4:2:2 formats. */
-void fimc_set_yuv_order(struct fimc_ctx *ctx)
-{
- /* The one only mode supported in SoC. */
- ctx->in_order_2p = S5P_FIMC_LSB_CRCB;
- ctx->out_order_2p = S5P_FIMC_LSB_CRCB;
-
- /* Set order for 1 plane input formats. */
- switch (ctx->s_frame.fmt->color) {
- case S5P_FIMC_YCRYCB422:
- ctx->in_order_1p = S5P_MSCTRL_ORDER422_CBYCRY;
- break;
- case S5P_FIMC_CBYCRY422:
- ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCRYCB;
- break;
- case S5P_FIMC_CRYCBY422:
- ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCBYCR;
- break;
- case S5P_FIMC_YCBYCR422:
- default:
- ctx->in_order_1p = S5P_MSCTRL_ORDER422_CRYCBY;
- break;
- }
- dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
-
- switch (ctx->d_frame.fmt->color) {
- case S5P_FIMC_YCRYCB422:
- ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CBYCRY;
- break;
- case S5P_FIMC_CBYCRY422:
- ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCRYCB;
- break;
- case S5P_FIMC_CRYCBY422:
- ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCBYCR;
- break;
- case S5P_FIMC_YCBYCR422:
- default:
- ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CRYCBY;
- break;
- }
- dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
-}
-
-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;
-
- for (i = 0; i < f->fmt->colplanes; i++)
- depth += f->fmt->depth[i];
-
- f->dma_offset.y_h = f->offs_h;
- if (!variant->pix_hoff)
- f->dma_offset.y_h *= (depth >> 3);
-
- f->dma_offset.y_v = f->offs_v;
-
- f->dma_offset.cb_h = f->offs_h;
- f->dma_offset.cb_v = f->offs_v;
-
- f->dma_offset.cr_h = f->offs_h;
- f->dma_offset.cr_v = f->offs_v;
-
- if (!variant->pix_hoff) {
- if (f->fmt->colplanes == 3) {
- f->dma_offset.cb_h >>= 1;
- f->dma_offset.cr_h >>= 1;
- }
- if (f->fmt->color == S5P_FIMC_YCBCR420) {
- f->dma_offset.cb_v >>= 1;
- f->dma_offset.cr_v >>= 1;
- }
- }
-
- dbg("in_offset: color= %d, y_h= %d, y_v= %d",
- f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
-}
-
-/**
- * fimc_prepare_config - check dimensions, operation and color mode
- * and pre-calculate offset and the scaling coefficients.
- *
- * @ctx: hardware context information
- * @flags: flags indicating which parameters to check/update
- *
- * Return: 0 if dimensions are valid or non zero otherwise.
- */
-int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
-{
- struct fimc_frame *s_frame, *d_frame;
- struct vb2_buffer *vb = NULL;
- int ret = 0;
-
- s_frame = &ctx->s_frame;
- d_frame = &ctx->d_frame;
-
- if (flags & FIMC_PARAMS) {
- /* Prepare the DMA offset ratios for scaler. */
- fimc_prepare_dma_offset(ctx, &ctx->s_frame);
- fimc_prepare_dma_offset(ctx, &ctx->d_frame);
-
- if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) ||
- s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) {
- err("out of scaler range");
- return -EINVAL;
- }
- fimc_set_yuv_order(ctx);
- }
-
- if (flags & FIMC_SRC_ADDR) {
- vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- ret = fimc_prepare_addr(ctx, vb, s_frame, &s_frame->paddr);
- if (ret)
- return ret;
- }
-
- if (flags & FIMC_DST_ADDR) {
- vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- ret = fimc_prepare_addr(ctx, vb, d_frame, &d_frame->paddr);
- }
-
- return ret;
-}
-
-static void fimc_dma_run(void *priv)
-{
- struct fimc_ctx *ctx = priv;
- struct fimc_dev *fimc;
- unsigned long flags;
- u32 ret;
-
- if (WARN(!ctx, "null hardware context\n"))
- return;
-
- fimc = ctx->fimc_dev;
- spin_lock_irqsave(&fimc->slock, flags);
- set_bit(ST_M2M_PEND, &fimc->state);
-
- spin_lock(&ctx->slock);
- ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR);
- ret = fimc_prepare_config(ctx, ctx->state);
- if (ret)
- goto dma_unlock;
-
- /* Reconfigure hardware if the context has changed. */
- if (fimc->m2m.ctx != ctx) {
- ctx->state |= FIMC_PARAMS;
- fimc->m2m.ctx = ctx;
- }
- fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr);
-
- if (ctx->state & FIMC_PARAMS) {
- fimc_hw_set_input_path(ctx);
- fimc_hw_set_in_dma(ctx);
- ret = fimc_set_scaler_info(ctx);
- if (ret) {
- spin_unlock(&fimc->slock);
- goto dma_unlock;
- }
- 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, false);
- }
-
- fimc_hw_set_output_path(ctx);
- if (ctx->state & (FIMC_DST_ADDR | FIMC_PARAMS))
- fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr, -1);
-
- if (ctx->state & FIMC_PARAMS) {
- fimc_hw_set_out_dma(ctx);
- if (fimc->variant->has_alpha)
- fimc_hw_set_rgb_alpha(ctx);
- }
-
- fimc_activate_capture(ctx);
-
- ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
- FIMC_SRC_FMT | FIMC_DST_FMT);
- fimc_hw_activate_input_dma(fimc, true);
-dma_unlock:
- spin_unlock(&ctx->slock);
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static void fimc_job_abort(void *priv)
-{
- fimc_m2m_shutdown(priv);
-}
-
-static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *allocators[])
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- struct fimc_frame *f;
- int i;
-
- f = ctx_get_frame(ctx, vq->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
- /*
- * Return number of non-contigous planes (plane buffers)
- * depending on the configured color format.
- */
- if (!f->fmt)
- return -EINVAL;
-
- *num_planes = f->fmt->memplanes;
- for (i = 0; i < f->fmt->memplanes; i++) {
- sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
- allocators[i] = ctx->fimc_dev->alloc_ctx;
- }
- return 0;
-}
-
-static int fimc_buf_prepare(struct vb2_buffer *vb)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_frame *frame;
- int i;
-
- frame = ctx_get_frame(ctx, vb->vb2_queue->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- for (i = 0; i < frame->fmt->memplanes; i++)
- vb2_set_plane_payload(vb, i, frame->payload[i]);
-
- return 0;
-}
-
-static void fimc_buf_queue(struct vb2_buffer *vb)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
- dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
-
- if (ctx->m2m_ctx)
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-}
-
-static void fimc_lock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_lock(&ctx->fimc_dev->lock);
-}
-
-static void fimc_unlock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_unlock(&ctx->fimc_dev->lock);
-}
-
-static struct vb2_ops fimc_qops = {
- .queue_setup = fimc_queue_setup,
- .buf_prepare = fimc_buf_prepare,
- .buf_queue = fimc_buf_queue,
- .wait_prepare = fimc_unlock,
- .wait_finish = fimc_lock,
- .stop_streaming = stop_streaming,
- .start_streaming = start_streaming,
-};
-
-/*
- * V4L2 controls handling
- */
-#define ctrl_to_ctx(__ctrl) \
- container_of((__ctrl)->handler, struct fimc_ctx, ctrl_handler)
-
-static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct samsung_fimc_variant *variant = fimc->variant;
- unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
- int ret = 0;
-
- if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_HFLIP:
- ctx->hflip = ctrl->val;
- break;
-
- case V4L2_CID_VFLIP:
- ctx->vflip = ctrl->val;
- break;
-
- case V4L2_CID_ROTATE:
- if (fimc_capture_pending(fimc) ||
- (ctx->state & flags) == flags) {
- ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, ctx->d_frame.width,
- ctx->d_frame.height, ctrl->val);
- if (ret)
- return -EINVAL;
- }
- if ((ctrl->val == 90 || ctrl->val == 270) &&
- !variant->has_out_rot)
- return -EINVAL;
-
- ctx->rotation = ctrl->val;
- break;
-
- case V4L2_CID_ALPHA_COMPONENT:
- ctx->d_frame.alpha = ctrl->val;
- break;
- }
- ctx->state |= FIMC_PARAMS;
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return 0;
-}
-
-static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct fimc_ctx *ctx = ctrl_to_ctx(ctrl);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&ctx->slock, flags);
- ret = __fimc_s_ctrl(ctx, ctrl);
- spin_unlock_irqrestore(&ctx->slock, flags);
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops fimc_ctrl_ops = {
- .s_ctrl = fimc_s_ctrl,
-};
-
-int fimc_ctrls_create(struct fimc_ctx *ctx)
-{
- struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
- unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);
-
- if (ctx->ctrls_rdy)
- return 0;
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
-
- ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
- V4L2_CID_ROTATE, 0, 270, 90, 0);
- ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- if (variant->has_alpha)
- ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler,
- &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
- 0, max_alpha, 1, 0);
- else
- ctx->ctrl_alpha = NULL;
-
- ctx->ctrls_rdy = ctx->ctrl_handler.error == 0;
-
- return ctx->ctrl_handler.error;
-}
-
-void fimc_ctrls_delete(struct fimc_ctx *ctx)
-{
- if (ctx->ctrls_rdy) {
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- ctx->ctrls_rdy = false;
- ctx->ctrl_alpha = NULL;
- }
-}
-
-void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
-{
- unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;
-
- if (!ctx->ctrls_rdy)
- return;
-
- mutex_lock(&ctx->ctrl_handler.lock);
- v4l2_ctrl_activate(ctx->ctrl_rotate, active);
- v4l2_ctrl_activate(ctx->ctrl_hflip, active);
- v4l2_ctrl_activate(ctx->ctrl_vflip, active);
- if (ctx->ctrl_alpha)
- v4l2_ctrl_activate(ctx->ctrl_alpha, active && has_alpha);
-
- if (active) {
- ctx->rotation = ctx->ctrl_rotate->val;
- ctx->hflip = ctx->ctrl_hflip->val;
- ctx->vflip = ctx->ctrl_vflip->val;
- } else {
- ctx->rotation = 0;
- ctx->hflip = 0;
- ctx->vflip = 0;
- }
- mutex_unlock(&ctx->ctrl_handler.lock);
-}
-
-/* Update maximum value of the alpha color control */
-void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct v4l2_ctrl *ctrl = ctx->ctrl_alpha;
-
- if (ctrl == NULL || !fimc->variant->has_alpha)
- return;
-
- v4l2_ctrl_lock(ctrl);
- ctrl->maximum = fimc_get_alpha_mask(ctx->d_frame.fmt);
-
- if (ctrl->cur.val > ctrl->maximum)
- ctrl->cur.val = ctrl->maximum;
-
- v4l2_ctrl_unlock(ctrl);
-}
-
-/*
- * V4L2 ioctl handlers
- */
-static int fimc_m2m_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
- strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- cap->capabilities = V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
-
- return 0;
-}
-
-static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
- f->index);
- if (!fmt)
- return -EINVAL;
-
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- int i;
-
- pixm->width = frame->o_width;
- pixm->height = frame->o_height;
- pixm->field = V4L2_FIELD_NONE;
- pixm->pixelformat = frame->fmt->fourcc;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
- pixm->num_planes = frame->fmt->memplanes;
-
- for (i = 0; i < pixm->num_planes; ++i) {
- int bpl = frame->f_width;
- if (frame->fmt->colplanes == 1) /* packed formats */
- bpl = (bpl * frame->fmt->depth[0]) / 8;
- pixm->plane_fmt[i].bytesperline = bpl;
- pixm->plane_fmt[i].sizeimage = (frame->o_width *
- frame->o_height * frame->fmt->depth[i]) / 8;
- }
- return 0;
-}
-
-void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
-
- frame->f_width = pixm->plane_fmt[0].bytesperline;
- if (frame->fmt->colplanes == 1)
- frame->f_width = (frame->f_width * 8) / frame->fmt->depth[0];
- frame->f_height = pixm->height;
- frame->width = pixm->width;
- frame->height = pixm->height;
- frame->o_width = pixm->width;
- frame->o_height = pixm->height;
- frame->offs_h = 0;
- frame->offs_v = 0;
-}
-
-/**
- * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
- * @fmt: fimc pixel format description (input)
- * @width: requested pixel width
- * @height: requested pixel height
- * @pix: multi-plane format to adjust
- */
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
- struct v4l2_pix_format_mplane *pix)
-{
- u32 bytesperline = 0;
- int i;
-
- pix->colorspace = V4L2_COLORSPACE_JPEG;
- pix->field = V4L2_FIELD_NONE;
- pix->num_planes = fmt->memplanes;
- pix->pixelformat = fmt->fourcc;
- pix->height = height;
- pix->width = width;
-
- for (i = 0; i < pix->num_planes; ++i) {
- u32 bpl = pix->plane_fmt[i].bytesperline;
- u32 *sizeimage = &pix->plane_fmt[i].sizeimage;
-
- if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
- bpl = pix->width; /* Planar */
-
- if (fmt->colplanes == 1 && /* Packed */
- (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width))
- bpl = (pix->width * fmt->depth[0]) / 8;
-
- if (i == 0) /* Same bytesperline for each plane. */
- bytesperline = bpl;
-
- pix->plane_fmt[i].bytesperline = bytesperline;
- *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8;
- }
-}
-
-static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
-
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- return fimc_fill_format(frame, f);
-}
-
-/**
- * fimc_find_format - lookup fimc color format by fourcc or media bus format
- * @pixelformat: fourcc to match, ignored if null
- * @mbus_code: media bus code to match, ignored if null
- * @mask: the color flags to match
- * @index: offset in the fimc_formats array, ignored if negative
- */
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index)
-{
- struct fimc_fmt *fmt, *def_fmt = NULL;
- unsigned int i;
- int id = 0;
-
- if (index >= (int)ARRAY_SIZE(fimc_formats))
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
- fmt = &fimc_formats[i];
- if (!(fmt->flags & mask))
- continue;
- if (pixelformat && fmt->fourcc == *pixelformat)
- return fmt;
- if (mbus_code && fmt->mbus_code == *mbus_code)
- return fmt;
- if (index == id)
- def_fmt = fmt;
- id++;
- }
- return def_fmt;
-}
-
-static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct samsung_fimc_variant *variant = fimc->variant;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_fmt *fmt;
- u32 max_w, mod_x, mod_y;
-
- if (!IS_M2M(f->type))
- return -EINVAL;
-
- dbg("w: %d, h: %d", pix->width, pix->height);
-
- fmt = fimc_find_format(&pix->pixelformat, NULL,
- get_m2m_fmt_flags(f->type), 0);
- if (WARN(fmt == NULL, "Pixel format lookup failed"))
- return -EINVAL;
-
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
- else if (pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- max_w = variant->pix_limit->scaler_dis_w;
- mod_x = ffs(variant->min_inp_pixsize) - 1;
- } else {
- max_w = variant->pix_limit->out_rot_dis_w;
- mod_x = ffs(variant->min_out_pixsize) - 1;
- }
-
- if (tiled_fmt(fmt)) {
- mod_x = 6; /* 64 x 32 pixels tile */
- mod_y = 5;
- } else {
- if (variant->min_vsize_align == 1)
- mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
- else
- mod_y = ffs(variant->min_vsize_align) - 1;
- }
-
- v4l_bound_align_image(&pix->width, 16, max_w, mod_x,
- &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
-
- fimc_adjust_mplane_format(fmt, pix->width, pix->height, &f->fmt.pix_mp);
- return 0;
-}
-
-static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return fimc_try_fmt_mplane(ctx, f);
-}
-
-static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct vb2_queue *vq;
- struct fimc_frame *frame;
- struct v4l2_pix_format_mplane *pix;
- int i, ret = 0;
-
- ret = fimc_try_fmt_mplane(ctx, f);
- if (ret)
- return ret;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
-
- if (vb2_is_busy(vq)) {
- v4l2_err(fimc->m2m.vfd, "queue (%d) busy\n", f->type);
- return -EBUSY;
- }
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- frame = &ctx->s_frame;
- else
- frame = &ctx->d_frame;
-
- pix = &f->fmt.pix_mp;
- frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
- get_m2m_fmt_flags(f->type), 0);
- if (!frame->fmt)
- return -EINVAL;
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- for (i = 0; i < frame->fmt->colplanes; i++) {
- frame->payload[i] =
- (pix->width * pix->height * frame->fmt->depth[i]) / 8;
- }
-
- fimc_fill_frame(frame, f);
-
- ctx->scaler.enabled = 1;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
- else
- fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
-
- dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
-
- return 0;
-}
-
-static int fimc_m2m_reqbufs(struct file *file, void *fh,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int fimc_m2m_querybuf(struct file *file, void *fh,
- struct v4l2_buffer *buf)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int fimc_m2m_qbuf(struct file *file, void *fh,
- struct v4l2_buffer *buf)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int fimc_m2m_dqbuf(struct file *file, void *fh,
- struct v4l2_buffer *buf)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int fimc_m2m_streamon(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- /* The source and target color format need to be set */
- if (V4L2_TYPE_IS_OUTPUT(type)) {
- if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
- return -EINVAL;
- } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
- return -EINVAL;
- }
-
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int fimc_m2m_streamoff(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
-static int fimc_m2m_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cr)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame;
-
- frame = ctx_get_frame(ctx, cr->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- cr->bounds.left = 0;
- cr->bounds.top = 0;
- cr->bounds.width = frame->o_width;
- cr->bounds.height = frame->o_height;
- cr->defrect = cr->bounds;
-
- return 0;
-}
-
-static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame;
-
- frame = ctx_get_frame(ctx, cr->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- cr->c.left = frame->offs_h;
- cr->c.top = frame->offs_v;
- cr->c.width = frame->width;
- cr->c.height = frame->height;
-
- return 0;
-}
-
-static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
- u32 min_size, halign, depth = 0;
- int i;
-
- if (cr->c.top < 0 || cr->c.left < 0) {
- v4l2_err(fimc->m2m.vfd,
- "doesn't support negative values for top & left\n");
- return -EINVAL;
- }
- if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- f = &ctx->d_frame;
- else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- f = &ctx->s_frame;
- else
- return -EINVAL;
-
- min_size = (f == &ctx->s_frame) ?
- fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
-
- /* Get pixel alignment constraints. */
- if (fimc->variant->min_vsize_align == 1)
- halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
- else
- halign = ffs(fimc->variant->min_vsize_align) - 1;
-
- for (i = 0; i < f->fmt->colplanes; i++)
- depth += f->fmt->depth[i];
-
- v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
- ffs(min_size) - 1,
- &cr->c.height, min_size, f->o_height,
- halign, 64/(ALIGN(depth, 8)));
-
- /* adjust left/top if cropping rectangle is out of bounds */
- if (cr->c.left + cr->c.width > f->o_width)
- cr->c.left = f->o_width - cr->c.width;
- if (cr->c.top + cr->c.height > f->o_height)
- cr->c.top = f->o_height - cr->c.height;
-
- cr->c.left = round_down(cr->c.left, min_size);
- cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align);
-
- dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
- cr->c.left, cr->c.top, cr->c.width, cr->c.height,
- f->f_width, f->f_height);
-
- return 0;
-}
-
-static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
- int ret;
-
- ret = fimc_m2m_try_crop(ctx, cr);
- if (ret)
- return ret;
-
- f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
- &ctx->s_frame : &ctx->d_frame;
-
- /* Check to see if scaling ratio is within supported range */
- if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
- if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = fimc_check_scaler_ratio(ctx, cr->c.width,
- cr->c.height, ctx->d_frame.width,
- ctx->d_frame.height, ctx->rotation);
- } else {
- ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, cr->c.width,
- cr->c.height, ctx->rotation);
- }
- if (ret) {
- v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
- return -EINVAL;
- }
- }
-
- f->offs_h = cr->c.left;
- f->offs_v = cr->c.top;
- f->width = cr->c.width;
- f->height = cr->c.height;
-
- fimc_ctx_state_lock_set(FIMC_PARAMS, ctx);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
- .vidioc_querycap = fimc_m2m_querycap,
-
- .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
- .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
-
- .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
- .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
-
- .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
- .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
-
- .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
- .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
-
- .vidioc_reqbufs = fimc_m2m_reqbufs,
- .vidioc_querybuf = fimc_m2m_querybuf,
-
- .vidioc_qbuf = fimc_m2m_qbuf,
- .vidioc_dqbuf = fimc_m2m_dqbuf,
-
- .vidioc_streamon = fimc_m2m_streamon,
- .vidioc_streamoff = fimc_m2m_streamoff,
-
- .vidioc_g_crop = fimc_m2m_g_crop,
- .vidioc_s_crop = fimc_m2m_s_crop,
- .vidioc_cropcap = fimc_m2m_cropcap
-
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct fimc_ctx *ctx = priv;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- src_vq->drv_priv = ctx;
- src_vq->ops = &fimc_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- dst_vq->drv_priv = ctx;
- dst_vq->ops = &fimc_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-
- return vb2_queue_init(dst_vq);
-}
-
-static int fimc_m2m_open(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx;
- int ret;
-
- dbg("pid: %d, state: 0x%lx, refcnt: %d",
- task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
-
- /*
- * Return if the corresponding video capture node
- * is already opened.
- */
- if (fimc->vid_cap.refcnt > 0)
- return -EBUSY;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
- v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
- ctx->fimc_dev = fimc;
-
- /* Default color format */
- ctx->s_frame.fmt = &fimc_formats[0];
- ctx->d_frame.fmt = &fimc_formats[0];
-
- ret = fimc_ctrls_create(ctx);
- if (ret)
- goto error_fh;
-
- /* Use separate control handler per file handle */
- ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
-
- /* Setup the device context for memory-to-memory mode */
- ctx->state = FIMC_CTX_M2M;
- ctx->flags = 0;
- ctx->in_path = FIMC_DMA;
- ctx->out_path = FIMC_DMA;
- spin_lock_init(&ctx->slock);
-
- ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
- if (IS_ERR(ctx->m2m_ctx)) {
- ret = PTR_ERR(ctx->m2m_ctx);
- goto error_c;
- }
-
- if (fimc->m2m.refcnt++ == 0)
- set_bit(ST_M2M_RUN, &fimc->state);
- return 0;
-
-error_c:
- fimc_ctrls_delete(ctx);
-error_fh:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
- return ret;
-}
-
-static int fimc_m2m_release(struct file *file)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- dbg("pid: %d, state: 0x%lx, refcnt= %d",
- task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
-
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- fimc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
-
- if (--fimc->m2m.refcnt <= 0)
- clear_bit(ST_M2M_RUN, &fimc->state);
- kfree(ctx);
- return 0;
-}
-
-static unsigned int fimc_m2m_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
-
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-}
-
-
-static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
-
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
-static const struct v4l2_file_operations fimc_m2m_fops = {
- .owner = THIS_MODULE,
- .open = fimc_m2m_open,
- .release = fimc_m2m_release,
- .poll = fimc_m2m_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = fimc_m2m_mmap,
-};
-
-static struct v4l2_m2m_ops m2m_ops = {
- .device_run = fimc_dma_run,
- .job_abort = fimc_job_abort,
-};
-
-int fimc_register_m2m_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct video_device *vfd;
- struct platform_device *pdev;
- int ret = 0;
-
- if (!fimc)
- return -ENODEV;
-
- pdev = fimc->pdev;
- fimc->v4l2_dev = v4l2_dev;
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(v4l2_dev, "Failed to allocate video device\n");
- return -ENOMEM;
- }
-
- vfd->fops = &fimc_m2m_fops;
- vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
- vfd->v4l2_dev = v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release;
- vfd->lock = &fimc->lock;
-
- snprintf(vfd->name, sizeof(vfd->name), "%s.m2m", dev_name(&pdev->dev));
- video_set_drvdata(vfd, fimc);
-
- fimc->m2m.vfd = vfd;
- fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
- if (IS_ERR(fimc->m2m.m2m_dev)) {
- v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
- ret = PTR_ERR(fimc->m2m.m2m_dev);
- goto err_init;
- }
-
- ret = media_entity_init(&vfd->entity, 0, NULL, 0);
- if (!ret)
- return 0;
-
- v4l2_m2m_release(fimc->m2m.m2m_dev);
-err_init:
- video_device_release(fimc->m2m.vfd);
- return ret;
-}
-
-void fimc_unregister_m2m_device(struct fimc_dev *fimc)
-{
- if (!fimc)
- return;
-
- if (fimc->m2m.m2m_dev)
- v4l2_m2m_release(fimc->m2m.m2m_dev);
- if (fimc->m2m.vfd) {
- media_entity_cleanup(&fimc->m2m.vfd->entity);
- /* Can also be called if video device wasn't registered */
- video_unregister_device(fimc->m2m.vfd);
- }
-}
-
-static void fimc_clk_put(struct fimc_dev *fimc)
-{
- int i;
- for (i = 0; i < fimc->num_clocks; i++) {
- if (IS_ERR_OR_NULL(fimc->clock[i]))
- continue;
- clk_unprepare(fimc->clock[i]);
- clk_put(fimc->clock[i]);
- fimc->clock[i] = NULL;
- }
-}
-
-static int fimc_clk_get(struct fimc_dev *fimc)
-{
- int i, ret;
-
- for (i = 0; i < fimc->num_clocks; i++) {
- fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
- if (IS_ERR(fimc->clock[i]))
- goto err;
- ret = clk_prepare(fimc->clock[i]);
- if (ret < 0) {
- clk_put(fimc->clock[i]);
- fimc->clock[i] = NULL;
- goto err;
- }
- }
- return 0;
-err:
- fimc_clk_put(fimc);
- dev_err(&fimc->pdev->dev, "failed to get clock: %s\n",
- fimc_clocks[i]);
- return -ENXIO;
-}
-
-static int fimc_m2m_suspend(struct fimc_dev *fimc)
-{
- unsigned long flags;
- int timeout;
-
- spin_lock_irqsave(&fimc->slock, flags);
- if (!fimc_m2m_pending(fimc)) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- clear_bit(ST_M2M_SUSPENDED, &fimc->state);
- set_bit(ST_M2M_SUSPENDING, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- timeout = wait_event_timeout(fimc->irq_queue,
- test_bit(ST_M2M_SUSPENDED, &fimc->state),
- FIMC_SHUTDOWN_TIMEOUT);
-
- clear_bit(ST_M2M_SUSPENDING, &fimc->state);
- return timeout == 0 ? -EAGAIN : 0;
-}
-
-static int fimc_m2m_resume(struct fimc_dev *fimc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- /* Clear for full H/W setup in first run after resume */
- fimc->m2m.ctx = NULL;
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (test_and_clear_bit(ST_M2M_SUSPENDED, &fimc->state))
- fimc_m2m_job_finish(fimc->m2m.ctx,
- VB2_BUF_STATE_ERROR);
- return 0;
-}
-
-static int fimc_probe(struct platform_device *pdev)
-{
- struct fimc_dev *fimc;
- struct resource *res;
- struct samsung_fimc_driverdata *drv_data;
- struct s5p_platform_fimc *pdata;
- int ret = 0;
-
- drv_data = (struct samsung_fimc_driverdata *)
- platform_get_device_id(pdev)->driver_data;
-
- if (pdev->id >= drv_data->num_entities) {
- dev_err(&pdev->dev, "Invalid platform device id: %d\n",
- pdev->id);
- return -EINVAL;
- }
-
- fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
- if (!fimc)
- return -ENOMEM;
-
- fimc->id = pdev->id;
-
- fimc->variant = drv_data->variant[fimc->id];
- fimc->pdev = pdev;
- pdata = pdev->dev.platform_data;
- fimc->pdata = pdata;
-
- init_waitqueue_head(&fimc->irq_queue);
- spin_lock_init(&fimc->slock);
- mutex_init(&fimc->lock);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (fimc->regs == NULL) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -ENOENT;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "Failed to get IRQ resource\n");
- return -ENXIO;
- }
- fimc->irq = res->start;
-
- fimc->num_clocks = MAX_FIMC_CLOCKS;
- ret = fimc_clk_get(fimc);
- if (ret)
- return ret;
- clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
- clk_enable(fimc->clock[CLK_BUS]);
-
- platform_set_drvdata(pdev, fimc);
-
- ret = devm_request_irq(&pdev->dev, fimc->irq, fimc_irq_handler,
- 0, pdev->name, fimc);
- if (ret) {
- dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
- goto err_clk;
- }
-
- pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0)
- goto err_clk;
- /* Initialize contiguous memory allocator */
- fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(fimc->alloc_ctx)) {
- ret = PTR_ERR(fimc->alloc_ctx);
- goto err_pm;
- }
-
- dev_dbg(&pdev->dev, "FIMC.%d registered successfully\n", fimc->id);
-
- pm_runtime_put(&pdev->dev);
- return 0;
-
-err_pm:
- pm_runtime_put(&pdev->dev);
-err_clk:
- fimc_clk_put(fimc);
- return ret;
-}
-
-static int fimc_runtime_resume(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- /* Enable clocks and perform basic initalization */
- clk_enable(fimc->clock[CLK_GATE]);
- fimc_hw_reset(fimc);
-
- /* Resume the capture or mem-to-mem device */
- if (fimc_capture_busy(fimc))
- return fimc_capture_resume(fimc);
-
- return fimc_m2m_resume(fimc);
-}
-
-static int fimc_runtime_suspend(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- int ret = 0;
-
- if (fimc_capture_busy(fimc))
- ret = fimc_capture_suspend(fimc);
- else
- ret = fimc_m2m_suspend(fimc);
- if (!ret)
- clk_disable(fimc->clock[CLK_GATE]);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
- return ret;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_resume(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- unsigned long flags;
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- /* Do not resume if the device was idle before system suspend */
- spin_lock_irqsave(&fimc->slock, flags);
- if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
- (!fimc_m2m_active(fimc) && !fimc_capture_busy(fimc))) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- fimc_hw_reset(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (fimc_capture_busy(fimc))
- return fimc_capture_resume(fimc);
-
- return fimc_m2m_resume(fimc);
-}
-
-static int fimc_suspend(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- if (test_and_set_bit(ST_LPM, &fimc->state))
- return 0;
- if (fimc_capture_busy(fimc))
- return fimc_capture_suspend(fimc);
-
- return fimc_m2m_suspend(fimc);
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static int __devexit fimc_remove(struct platform_device *pdev)
-{
- struct fimc_dev *fimc = platform_get_drvdata(pdev);
-
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
-
- vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
-
- clk_disable(fimc->clock[CLK_BUS]);
- fimc_clk_put(fimc);
-
- dev_info(&pdev->dev, "driver unloaded\n");
- return 0;
-}
-
-/* Image pixel limits, similar across several FIMC HW revisions. */
-static struct fimc_pix_limit s5p_pix_limit[4] = {
- [0] = {
- .scaler_en_w = 3264,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1920,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1920,
- .out_rot_dis_w = 4224,
- },
- [1] = {
- .scaler_en_w = 4224,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1920,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1920,
- .out_rot_dis_w = 4224,
- },
- [2] = {
- .scaler_en_w = 1920,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1280,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1280,
- .out_rot_dis_w = 1920,
- },
- [3] = {
- .scaler_en_w = 1920,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1366,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1366,
- .out_rot_dis_w = 1920,
- },
-};
-
-static struct samsung_fimc_variant fimc0_variant_s5p = {
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[0],
-};
-
-static struct samsung_fimc_variant fimc2_variant_s5p = {
- .has_cam_if = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[1],
-};
-
-static struct samsung_fimc_variant fimc0_variant_s5pv210 = {
- .pix_hoff = 1,
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[1],
-};
-
-static struct samsung_fimc_variant fimc1_variant_s5pv210 = {
- .pix_hoff = 1,
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .has_mainscaler_ext = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 1,
- .min_vsize_align = 1,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[2],
-};
-
-static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
- .has_cam_if = 1,
- .pix_hoff = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[2],
-};
-
-static struct samsung_fimc_variant fimc0_variant_exynos4 = {
- .pix_hoff = 1,
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .has_cistatus2 = 1,
- .has_mainscaler_ext = 1,
- .has_alpha = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 2,
- .min_vsize_align = 1,
- .out_buf_count = 32,
- .pix_limit = &s5p_pix_limit[1],
-};
-
-static struct samsung_fimc_variant fimc3_variant_exynos4 = {
- .pix_hoff = 1,
- .has_cam_if = 1,
- .has_cistatus2 = 1,
- .has_mainscaler_ext = 1,
- .has_alpha = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 2,
- .min_vsize_align = 1,
- .out_buf_count = 32,
- .pix_limit = &s5p_pix_limit[3],
-};
-
-/* S5PC100 */
-static struct samsung_fimc_driverdata fimc_drvdata_s5p = {
- .variant = {
- [0] = &fimc0_variant_s5p,
- [1] = &fimc0_variant_s5p,
- [2] = &fimc2_variant_s5p,
- },
- .num_entities = 3,
- .lclk_frequency = 133000000UL,
-};
-
-/* S5PV210, S5PC110 */
-static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = {
- .variant = {
- [0] = &fimc0_variant_s5pv210,
- [1] = &fimc1_variant_s5pv210,
- [2] = &fimc2_variant_s5pv210,
- },
- .num_entities = 3,
- .lclk_frequency = 166000000UL,
-};
-
-/* S5PV310, S5PC210 */
-static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = {
- .variant = {
- [0] = &fimc0_variant_exynos4,
- [1] = &fimc0_variant_exynos4,
- [2] = &fimc0_variant_exynos4,
- [3] = &fimc3_variant_exynos4,
- },
- .num_entities = 4,
- .lclk_frequency = 166000000UL,
-};
-
-static struct platform_device_id fimc_driver_ids[] = {
- {
- .name = "s5p-fimc",
- .driver_data = (unsigned long)&fimc_drvdata_s5p,
- }, {
- .name = "s5pv210-fimc",
- .driver_data = (unsigned long)&fimc_drvdata_s5pv210,
- }, {
- .name = "exynos4-fimc",
- .driver_data = (unsigned long)&fimc_drvdata_exynos4,
- },
- {},
-};
-MODULE_DEVICE_TABLE(platform, fimc_driver_ids);
-
-static const struct dev_pm_ops fimc_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)
- SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)
-};
-
-static struct platform_driver fimc_driver = {
- .probe = fimc_probe,
- .remove = __devexit_p(fimc_remove),
- .id_table = fimc_driver_ids,
- .driver = {
- .name = FIMC_MODULE_NAME,
- .owner = THIS_MODULE,
- .pm = &fimc_pm_ops,
- }
-};
-
-int __init fimc_register_driver(void)
-{
- return platform_driver_probe(&fimc_driver, fimc_probe);
-}
-
-void __exit fimc_unregister_driver(void)
-{
- platform_driver_unregister(&fimc_driver);
-}
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.h b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.h
deleted file mode 100644
index 84fd8355..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-core.h
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
- *
- * 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.
- */
-
-#ifndef FIMC_CORE_H_
-#define FIMC_CORE_H_
-
-/*#define DEBUG*/
-
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <linux/io.h>
-
-#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-mediabus.h>
-#include <media/s5p_fimc.h>
-
-#include "regs-fimc.h"
-
-#define err(fmt, args...) \
- printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
-
-#define dbg(fmt, args...) \
- pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
-
-/* Time to wait for next frame VSYNC interrupt while stopping operation. */
-#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
-#define MAX_FIMC_CLOCKS 2
-#define FIMC_MODULE_NAME "s5p-fimc"
-#define FIMC_MAX_DEVS 4
-#define FIMC_MAX_OUT_BUFS 4
-#define SCALER_MAX_HRATIO 64
-#define SCALER_MAX_VRATIO 64
-#define DMA_MIN_SIZE 8
-#define FIMC_CAMIF_MAX_HEIGHT 0x2000
-
-/* indices to the clocks array */
-enum {
- CLK_BUS,
- CLK_GATE,
-};
-
-enum fimc_dev_flags {
- ST_LPM,
- /* m2m node */
- ST_M2M_RUN,
- ST_M2M_PEND,
- ST_M2M_SUSPENDING,
- ST_M2M_SUSPENDED,
- /* capture node */
- ST_CAPT_PEND,
- ST_CAPT_RUN,
- ST_CAPT_STREAM,
- ST_CAPT_ISP_STREAM,
- ST_CAPT_SUSPENDED,
- ST_CAPT_SHUT,
- ST_CAPT_BUSY,
- ST_CAPT_APPLY_CFG,
- ST_CAPT_JPEG,
-};
-
-#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
-#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
-
-#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
-#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
-#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
-
-enum fimc_datapath {
- FIMC_CAMERA,
- FIMC_DMA,
- FIMC_LCDFIFO,
- FIMC_WRITEBACK
-};
-
-enum fimc_color_fmt {
- S5P_FIMC_RGB444 = 0x10,
- S5P_FIMC_RGB555,
- S5P_FIMC_RGB565,
- S5P_FIMC_RGB666,
- S5P_FIMC_RGB888,
- S5P_FIMC_RGB30_LOCAL,
- S5P_FIMC_YCBCR420 = 0x20,
- S5P_FIMC_YCBYCR422,
- S5P_FIMC_YCRYCB422,
- S5P_FIMC_CBYCRY422,
- S5P_FIMC_CRYCBY422,
- S5P_FIMC_YCBCR444_LOCAL,
- S5P_FIMC_JPEG = 0x40,
-};
-
-#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
-#define fimc_fmt_is_jpeg(x) (!!((x) & 0x40))
-
-#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
- __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-
-/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */
-#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB
-
-/* The embedded image effect selection */
-#define S5P_FIMC_EFFECT_ORIGINAL S5P_CIIMGEFF_FIN_BYPASS
-#define S5P_FIMC_EFFECT_ARBITRARY S5P_CIIMGEFF_FIN_ARBITRARY
-#define S5P_FIMC_EFFECT_NEGATIVE S5P_CIIMGEFF_FIN_NEGATIVE
-#define S5P_FIMC_EFFECT_ARTFREEZE S5P_CIIMGEFF_FIN_ARTFREEZE
-#define S5P_FIMC_EFFECT_EMBOSSING S5P_CIIMGEFF_FIN_EMBOSSING
-#define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE
-
-/* The hardware context state. */
-#define FIMC_PARAMS (1 << 0)
-#define FIMC_SRC_ADDR (1 << 1)
-#define FIMC_DST_ADDR (1 << 2)
-#define FIMC_SRC_FMT (1 << 3)
-#define FIMC_DST_FMT (1 << 4)
-#define FIMC_DST_CROP (1 << 5)
-#define FIMC_CTX_M2M (1 << 16)
-#define FIMC_CTX_CAP (1 << 17)
-#define FIMC_CTX_SHUT (1 << 18)
-
-/* Image conversion flags */
-#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
-#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
-#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
-#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
-#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
-#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
-/*
- * YCbCr data dynamic range for RGB-YUV color conversion.
- * Y/Cb/Cr: (0 ~ 255) */
-#define FIMC_COLOR_RANGE_WIDE (0 << 3)
-/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
-#define FIMC_COLOR_RANGE_NARROW (1 << 3)
-
-/**
- * struct fimc_fmt - the driver's internal color format data
- * @mbus_code: Media Bus pixel code, -1 if not applicable
- * @name: format description
- * @fourcc: the fourcc code for this format, 0 if not applicable
- * @color: the corresponding fimc_color_fmt
- * @memplanes: number of physically non-contiguous data planes
- * @colplanes: number of physically contiguous data planes
- * @depth: per plane driver's private 'number of bits per pixel'
- * @flags: flags indicating which operation mode format applies to
- */
-struct fimc_fmt {
- enum v4l2_mbus_pixelcode mbus_code;
- char *name;
- u32 fourcc;
- u32 color;
- u16 memplanes;
- u16 colplanes;
- u8 depth[VIDEO_MAX_PLANES];
- u16 flags;
-#define FMT_FLAGS_CAM (1 << 0)
-#define FMT_FLAGS_M2M_IN (1 << 1)
-#define FMT_FLAGS_M2M_OUT (1 << 2)
-#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
-#define FMT_HAS_ALPHA (1 << 3)
-};
-
-/**
- * struct fimc_dma_offset - pixel offset information for DMA
- * @y_h: y value horizontal offset
- * @y_v: y value vertical offset
- * @cb_h: cb value horizontal offset
- * @cb_v: cb value vertical offset
- * @cr_h: cr value horizontal offset
- * @cr_v: cr value vertical offset
- */
-struct fimc_dma_offset {
- int y_h;
- int y_v;
- int cb_h;
- int cb_v;
- int cr_h;
- int cr_v;
-};
-
-/**
- * struct fimc_effect - color effect information
- * @type: effect type
- * @pat_cb: cr value when type is "arbitrary"
- * @pat_cr: cr value when type is "arbitrary"
- */
-struct fimc_effect {
- u32 type;
- u8 pat_cb;
- u8 pat_cr;
-};
-
-/**
- * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
- * @scaleup_h: flag indicating scaling up horizontally
- * @scaleup_v: flag indicating scaling up vertically
- * @copy_mode: flag indicating transparent DMA transfer (no scaling
- * and color format conversion)
- * @enabled: flag indicating if the scaler is used
- * @hfactor: horizontal shift factor
- * @vfactor: vertical shift factor
- * @pre_hratio: horizontal ratio of the prescaler
- * @pre_vratio: vertical ratio of the prescaler
- * @pre_dst_width: the prescaler's destination width
- * @pre_dst_height: the prescaler's destination height
- * @main_hratio: the main scaler's horizontal ratio
- * @main_vratio: the main scaler's vertical ratio
- * @real_width: source pixel (width - offset)
- * @real_height: source pixel (height - offset)
- */
-struct fimc_scaler {
- unsigned int scaleup_h:1;
- unsigned int scaleup_v:1;
- unsigned int copy_mode:1;
- unsigned int enabled:1;
- u32 hfactor;
- u32 vfactor;
- u32 pre_hratio;
- u32 pre_vratio;
- u32 pre_dst_width;
- u32 pre_dst_height;
- u32 main_hratio;
- u32 main_vratio;
- u32 real_width;
- u32 real_height;
-};
-
-/**
- * struct fimc_addr - the FIMC physical address set for DMA
- * @y: luminance plane physical address
- * @cb: Cb plane physical address
- * @cr: Cr plane physical address
- */
-struct fimc_addr {
- u32 y;
- u32 cb;
- u32 cr;
-};
-
-/**
- * struct fimc_vid_buffer - the driver's video buffer
- * @vb: v4l videobuf buffer
- * @list: linked list structure for buffer queue
- * @paddr: precalculated physical address set
- * @index: buffer index for the output DMA engine
- */
-struct fimc_vid_buffer {
- struct vb2_buffer vb;
- struct list_head list;
- struct fimc_addr paddr;
- int index;
-};
-
-/**
- * struct fimc_frame - source/target frame properties
- * @f_width: image full width (virtual screen size)
- * @f_height: image full height (virtual screen size)
- * @o_width: original image width as set by S_FMT
- * @o_height: original image height as set by S_FMT
- * @offs_h: image horizontal pixel offset
- * @offs_v: image vertical pixel offset
- * @width: image pixel width
- * @height: image pixel weight
- * @payload: image size in bytes (w x h x bpp)
- * @paddr: image frame buffer physical addresses
- * @dma_offset: DMA offset in bytes
- * @fmt: fimc color format pointer
- */
-struct fimc_frame {
- u32 f_width;
- u32 f_height;
- u32 o_width;
- u32 o_height;
- u32 offs_h;
- u32 offs_v;
- u32 width;
- u32 height;
- unsigned long payload[VIDEO_MAX_PLANES];
- struct fimc_addr paddr;
- struct fimc_dma_offset dma_offset;
- struct fimc_fmt *fmt;
- u8 alpha;
-};
-
-/**
- * struct fimc_m2m_device - v4l2 memory-to-memory device data
- * @vfd: the video device node for v4l2 m2m mode
- * @m2m_dev: v4l2 memory-to-memory device data
- * @ctx: hardware context data
- * @refcnt: the reference counter
- */
-struct fimc_m2m_device {
- struct video_device *vfd;
- struct v4l2_m2m_dev *m2m_dev;
- struct fimc_ctx *ctx;
- int refcnt;
-};
-
-#define FIMC_SD_PAD_SINK 0
-#define FIMC_SD_PAD_SOURCE 1
-#define FIMC_SD_PADS_NUM 2
-
-/**
- * struct fimc_vid_cap - camera capture device information
- * @ctx: hardware context data
- * @vfd: video device node for camera capture mode
- * @subdev: subdev exposing the FIMC processing block
- * @vd_pad: fimc video capture node pad
- * @sd_pads: fimc video processing block pads
- * @mf: media bus format at the FIMC camera input (and the scaler output) pad
- * @pending_buf_q: the pending buffer queue head
- * @active_buf_q: the queue head of buffers scheduled in hardware
- * @vbq: the capture am video buffer queue
- * @active_buf_cnt: number of video buffers scheduled in hardware
- * @buf_index: index for managing the output DMA buffers
- * @frame_count: the frame counter for statistics
- * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
- * @input_index: input (camera sensor) index
- * @refcnt: driver's private reference counter
- * @input: capture input type, grp_id of the attached subdev
- * @user_subdev_api: true if subdevs are not configured by the host driver
- */
-struct fimc_vid_cap {
- struct fimc_ctx *ctx;
- struct vb2_alloc_ctx *alloc_ctx;
- struct video_device *vfd;
- struct v4l2_subdev *subdev;
- struct media_pad vd_pad;
- struct v4l2_mbus_framefmt mf;
- struct media_pad sd_pads[FIMC_SD_PADS_NUM];
- struct list_head pending_buf_q;
- struct list_head active_buf_q;
- struct vb2_queue vbq;
- int active_buf_cnt;
- int buf_index;
- unsigned int frame_count;
- unsigned int reqbufs_count;
- int input_index;
- int refcnt;
- u32 input;
- bool user_subdev_api;
-};
-
-/**
- * struct fimc_pix_limit - image pixel size limits in various IP configurations
- *
- * @scaler_en_w: max input pixel width when the scaler is enabled
- * @scaler_dis_w: max input pixel width when the scaler is disabled
- * @in_rot_en_h: max input width with the input rotator is on
- * @in_rot_dis_w: max input width with the input rotator is off
- * @out_rot_en_w: max output width with the output rotator on
- * @out_rot_dis_w: max output width with the output rotator off
- */
-struct fimc_pix_limit {
- u16 scaler_en_w;
- u16 scaler_dis_w;
- u16 in_rot_en_h;
- u16 in_rot_dis_w;
- u16 out_rot_en_w;
- u16 out_rot_dis_w;
-};
-
-/**
- * struct samsung_fimc_variant - camera interface variant information
- *
- * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
- * @has_inp_rot: set if has input rotator
- * @has_out_rot: set if has output rotator
- * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
- * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
- * are present in this IP revision
- * @has_cam_if: set if this instance has a camera input interface
- * @pix_limit: pixel size constraints for the scaler
- * @min_inp_pixsize: minimum input pixel size
- * @min_out_pixsize: minimum output pixel size
- * @hor_offs_align: horizontal pixel offset aligment
- * @min_vsize_align: minimum vertical pixel size alignment
- * @out_buf_count: the number of buffers in output DMA sequence
- */
-struct samsung_fimc_variant {
- unsigned int pix_hoff:1;
- unsigned int has_inp_rot:1;
- unsigned int has_out_rot:1;
- unsigned int has_cistatus2:1;
- unsigned int has_mainscaler_ext:1;
- unsigned int has_cam_if:1;
- unsigned int has_alpha:1;
- struct fimc_pix_limit *pix_limit;
- u16 min_inp_pixsize;
- u16 min_out_pixsize;
- u16 hor_offs_align;
- u16 min_vsize_align;
- u16 out_buf_count;
-};
-
-/**
- * struct samsung_fimc_driverdata - per device type driver data for init time.
- *
- * @variant: the variant information for this driver.
- * @dev_cnt: number of fimc sub-devices available in SoC
- * @lclk_frequency: fimc bus clock frequency
- */
-struct samsung_fimc_driverdata {
- struct samsung_fimc_variant *variant[FIMC_MAX_DEVS];
- unsigned long lclk_frequency;
- int num_entities;
-};
-
-struct fimc_pipeline {
- struct media_pipeline *pipe;
- struct v4l2_subdev *sensor;
- struct v4l2_subdev *csis;
-};
-
-struct fimc_ctx;
-
-/**
- * struct fimc_dev - abstraction for FIMC entity
- * @slock: the spinlock protecting this data structure
- * @lock: the mutex protecting this data structure
- * @pdev: pointer to the FIMC platform device
- * @pdata: pointer to the device platform data
- * @variant: the IP variant information
- * @id: FIMC device index (0..FIMC_MAX_DEVS)
- * @num_clocks: the number of clocks managed by this device instance
- * @clock: clocks required for FIMC operation
- * @regs: the mapped hardware registers
- * @irq: FIMC interrupt number
- * @irq_queue: interrupt handler waitqueue
- * @v4l2_dev: root v4l2_device
- * @m2m: memory-to-memory V4L2 device information
- * @vid_cap: camera capture device information
- * @state: flags used to synchronize m2m and capture mode operation
- * @alloc_ctx: videobuf2 memory allocator context
- * @pipeline: fimc video capture pipeline data structure
- */
-struct fimc_dev {
- spinlock_t slock;
- struct mutex lock;
- struct platform_device *pdev;
- struct s5p_platform_fimc *pdata;
- struct samsung_fimc_variant *variant;
- u16 id;
- u16 num_clocks;
- struct clk *clock[MAX_FIMC_CLOCKS];
- void __iomem *regs;
- int irq;
- wait_queue_head_t irq_queue;
- struct v4l2_device *v4l2_dev;
- struct fimc_m2m_device m2m;
- struct fimc_vid_cap vid_cap;
- unsigned long state;
- struct vb2_alloc_ctx *alloc_ctx;
- struct fimc_pipeline pipeline;
-};
-
-/**
- * fimc_ctx - the device context data
- * @slock: spinlock protecting this data structure
- * @s_frame: source frame properties
- * @d_frame: destination frame properties
- * @out_order_1p: output 1-plane YCBCR order
- * @out_order_2p: output 2-plane YCBCR order
- * @in_order_1p input 1-plane YCBCR order
- * @in_order_2p: input 2-plane YCBCR order
- * @in_path: input mode (DMA or camera)
- * @out_path: output mode (DMA or FIFO)
- * @scaler: image scaler properties
- * @effect: image effect
- * @rotation: image clockwise rotation in degrees
- * @hflip: indicates image horizontal flip if set
- * @vflip: indicates image vertical flip if set
- * @flags: additional flags for image conversion
- * @state: flags to keep track of user configuration
- * @fimc_dev: the FIMC device this context applies to
- * @m2m_ctx: memory-to-memory device context
- * @fh: v4l2 file handle
- * @ctrl_handler: v4l2 controls handler
- * @ctrl_rotate image rotation control
- * @ctrl_hflip horizontal flip control
- * @ctrl_vflip vertical flip control
- * @ctrl_alpha RGB alpha control
- * @ctrls_rdy: true if the control handler is initialized
- */
-struct fimc_ctx {
- spinlock_t slock;
- struct fimc_frame s_frame;
- struct fimc_frame d_frame;
- u32 out_order_1p;
- u32 out_order_2p;
- u32 in_order_1p;
- u32 in_order_2p;
- enum fimc_datapath in_path;
- enum fimc_datapath out_path;
- struct fimc_scaler scaler;
- struct fimc_effect effect;
- int rotation;
- unsigned int hflip:1;
- unsigned int vflip:1;
- u32 flags;
- u32 state;
- struct fimc_dev *fimc_dev;
- struct v4l2_m2m_ctx *m2m_ctx;
- struct v4l2_fh fh;
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_ctrl *ctrl_rotate;
- struct v4l2_ctrl *ctrl_hflip;
- struct v4l2_ctrl *ctrl_vflip;
- struct v4l2_ctrl *ctrl_alpha;
- bool ctrls_rdy;
-};
-
-#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
-
-static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height)
-{
- f->o_width = width;
- f->o_height = height;
- f->f_width = width;
- f->f_height = height;
-}
-
-static inline void set_frame_crop(struct fimc_frame *f,
- u32 left, u32 top, u32 width, u32 height)
-{
- f->offs_h = left;
- f->offs_v = top;
- f->width = width;
- f->height = height;
-}
-
-static inline u32 fimc_get_format_depth(struct fimc_fmt *ff)
-{
- u32 i, depth = 0;
-
- if (ff != NULL)
- for (i = 0; i < ff->colplanes; i++)
- depth += ff->depth[i];
- return depth;
-}
-
-static inline bool fimc_capture_active(struct fimc_dev *fimc)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&fimc->slock, flags);
- ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
- fimc->state & (1 << ST_CAPT_PEND));
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-static inline void fimc_ctx_state_lock_set(u32 state, struct fimc_ctx *ctx)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ctx->slock, flags);
- ctx->state |= state;
- spin_unlock_irqrestore(&ctx->slock, flags);
-}
-
-static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&ctx->slock, flags);
- ret = (ctx->state & mask) == mask;
- spin_unlock_irqrestore(&ctx->slock, flags);
- return ret;
-}
-
-static inline int tiled_fmt(struct fimc_fmt *fmt)
-{
- return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
-}
-
-/* Return the alpha component bit mask */
-static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
-{
- switch (fmt->color) {
- case S5P_FIMC_RGB444: return 0x0f;
- case S5P_FIMC_RGB555: return 0x01;
- case S5P_FIMC_RGB888: return 0xff;
- default: return 0;
- };
-}
-
-static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
-{
- u32 cfg = readl(dev->regs + S5P_CIGCTRL);
- cfg |= S5P_CIGCTRL_IRQ_CLR;
- writel(cfg, dev->regs + S5P_CIGCTRL);
-}
-
-static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
-{
- u32 cfg = readl(dev->regs + S5P_CISCCTRL);
- if (on)
- cfg |= S5P_CISCCTRL_SCALERSTART;
- else
- cfg &= ~S5P_CISCCTRL_SCALERSTART;
- writel(cfg, dev->regs + S5P_CISCCTRL);
-}
-
-static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
-{
- u32 cfg = readl(dev->regs + S5P_MSCTRL);
- if (on)
- cfg |= S5P_MSCTRL_ENVID;
- else
- cfg &= ~S5P_MSCTRL_ENVID;
- writel(cfg, dev->regs + S5P_MSCTRL);
-}
-
-static inline void fimc_hw_dis_capture(struct fimc_dev *dev)
-{
- u32 cfg = readl(dev->regs + S5P_CIIMGCPT);
- cfg &= ~(S5P_CIIMGCPT_IMGCPTEN | S5P_CIIMGCPT_IMGCPTEN_SC);
- writel(cfg, dev->regs + S5P_CIIMGCPT);
-}
-
-/**
- * fimc_hw_set_dma_seq - configure output DMA buffer sequence
- * @mask: each bit corresponds to one of 32 output buffer registers set
- * 1 to include buffer in the sequence, 0 to disable
- *
- * This function mask output DMA ring buffers, i.e. it allows to configure
- * which of the output buffer address registers will be used by the DMA
- * engine.
- */
-static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
-{
- writel(mask, dev->regs + S5P_CIFCNTSEQ);
-}
-
-static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
- enum v4l2_buf_type type)
-{
- struct fimc_frame *frame;
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
- if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
- frame = &ctx->s_frame;
- else
- return ERR_PTR(-EINVAL);
- } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
- frame = &ctx->d_frame;
- } else {
- v4l2_err(ctx->fimc_dev->v4l2_dev,
- "Wrong buffer/video queue type (%d)\n", type);
- return ERR_PTR(-EINVAL);
- }
-
- return frame;
-}
-
-/* Return an index to the buffer actually being written. */
-static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
-{
- u32 reg;
-
- if (dev->variant->has_cistatus2) {
- reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
- return reg > 0 ? --reg : reg;
- } else {
- reg = readl(dev->regs + S5P_CISTATUS);
- return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
- S5P_CISTATUS_FRAMECNT_SHIFT;
- }
-}
-
-/* -----------------------------------------------------*/
-/* fimc-reg.c */
-void fimc_hw_reset(struct fimc_dev *fimc);
-void fimc_hw_set_rotation(struct fimc_ctx *ctx);
-void fimc_hw_set_target_format(struct fimc_ctx *ctx);
-void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
-void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
-void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
-void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
-void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
-void fimc_hw_en_capture(struct fimc_ctx *ctx);
-void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active);
-void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
-void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
-void fimc_hw_set_input_path(struct fimc_ctx *ctx);
-void fimc_hw_set_output_path(struct fimc_ctx *ctx);
-void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
-void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
- int index);
-int fimc_hw_set_camera_source(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam);
-int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
-int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam);
-int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam);
-
-/* -----------------------------------------------------*/
-/* fimc-core.c */
-int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f);
-int fimc_ctrls_create(struct fimc_ctx *ctx);
-void fimc_ctrls_delete(struct fimc_ctx *ctx);
-void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
-void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
-int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
- struct v4l2_pix_format_mplane *pix);
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index);
-
-int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
- int dw, int dh, int rotation);
-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);
-void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
-void fimc_capture_irq_handler(struct fimc_dev *fimc, bool done);
-
-int fimc_register_m2m_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev);
-void fimc_unregister_m2m_device(struct fimc_dev *fimc);
-int fimc_register_driver(void);
-void fimc_unregister_driver(void);
-
-/* -----------------------------------------------------*/
-/* fimc-capture.c */
-int fimc_register_capture_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev);
-void fimc_unregister_capture_device(struct fimc_dev *fimc);
-int fimc_capture_ctrls_create(struct fimc_dev *fimc);
-int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
- struct fimc_vid_buffer *fimc_vb);
-void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
- void *arg);
-int fimc_capture_suspend(struct fimc_dev *fimc);
-int fimc_capture_resume(struct fimc_dev *fimc);
-int fimc_capture_config_update(struct fimc_ctx *ctx);
-
-/* Locking: the caller holds fimc->slock */
-static inline void fimc_activate_capture(struct fimc_ctx *ctx)
-{
- fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
- fimc_hw_en_capture(ctx);
-}
-
-static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
-{
- fimc_hw_en_lastirq(fimc, true);
- fimc_hw_dis_capture(fimc);
- fimc_hw_enable_scaler(fimc, false);
- fimc_hw_en_lastirq(fimc, false);
-}
-
-/*
- * Buffer list manipulation functions. Must be called with fimc.slock held.
- */
-
-/**
- * fimc_active_queue_add - add buffer to the capture active buffers queue
- * @buf: buffer to add to the active buffers list
- */
-static inline void fimc_active_queue_add(struct fimc_vid_cap *vid_cap,
- struct fimc_vid_buffer *buf)
-{
- list_add_tail(&buf->list, &vid_cap->active_buf_q);
- vid_cap->active_buf_cnt++;
-}
-
-/**
- * fimc_active_queue_pop - pop buffer from the capture active buffers queue
- *
- * The caller must assure the active_buf_q list is not empty.
- */
-static inline struct fimc_vid_buffer *fimc_active_queue_pop(
- struct fimc_vid_cap *vid_cap)
-{
- struct fimc_vid_buffer *buf;
- buf = list_entry(vid_cap->active_buf_q.next,
- struct fimc_vid_buffer, list);
- list_del(&buf->list);
- vid_cap->active_buf_cnt--;
- return buf;
-}
-
-/**
- * fimc_pending_queue_add - add buffer to the capture pending buffers queue
- * @buf: buffer to add to the pending buffers list
- */
-static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
- struct fimc_vid_buffer *buf)
-{
- list_add_tail(&buf->list, &vid_cap->pending_buf_q);
-}
-
-/**
- * fimc_pending_queue_pop - pop buffer from the capture pending buffers queue
- *
- * The caller must assure the pending_buf_q list is not empty.
- */
-static inline struct fimc_vid_buffer *fimc_pending_queue_pop(
- struct fimc_vid_cap *vid_cap)
-{
- struct fimc_vid_buffer *buf;
- buf = list_entry(vid_cap->pending_buf_q.next,
- struct fimc_vid_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-#endif /* FIMC_CORE_H_ */
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.c b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.c
deleted file mode 100644
index 62ed37e4..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * S5P/EXYNOS4 SoC series camera host interface media device driver
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
- */
-
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <media/v4l2-ctrls.h>
-#include <media/media-device.h>
-
-#include "fimc-core.h"
-#include "fimc-mdevice.h"
-#include "mipi-csis.h"
-
-static int __fimc_md_set_camclk(struct fimc_md *fmd,
- struct fimc_sensor_info *s_info,
- bool on);
-/**
- * fimc_pipeline_prepare - update pipeline information with subdevice pointers
- * @fimc: fimc device terminating the pipeline
- *
- * Caller holds the graph mutex.
- */
-void fimc_pipeline_prepare(struct fimc_dev *fimc, struct media_entity *me)
-{
- struct media_entity_graph graph;
- struct v4l2_subdev *sd;
-
- media_entity_graph_walk_start(&graph, me);
-
- while ((me = media_entity_graph_walk_next(&graph))) {
- if (media_entity_type(me) != MEDIA_ENT_T_V4L2_SUBDEV)
- continue;
- sd = media_entity_to_v4l2_subdev(me);
-
- if (sd->grp_id == SENSOR_GROUP_ID)
- fimc->pipeline.sensor = sd;
- else if (sd->grp_id == CSIS_GROUP_ID)
- fimc->pipeline.csis = sd;
- }
-}
-
-/**
- * __subdev_set_power - change power state of a single subdev
- * @sd: subdevice to change power state for
- * @on: 1 to enable power or 0 to disable
- *
- * Return result of s_power subdev operation or -ENXIO if sd argument
- * is NULL. Return 0 if the subdevice does not implement s_power.
- */
-static int __subdev_set_power(struct v4l2_subdev *sd, int on)
-{
- int *use_count;
- int ret;
-
- if (sd == NULL)
- return -ENXIO;
-
- use_count = &sd->entity.use_count;
- if (on && (*use_count)++ > 0)
- return 0;
- else if (!on && (*use_count == 0 || --(*use_count) > 0))
- return 0;
- ret = v4l2_subdev_call(sd, core, s_power, on);
-
- return ret != -ENOIOCTLCMD ? ret : 0;
-}
-
-/**
- * fimc_pipeline_s_power - change power state of all pipeline subdevs
- * @fimc: fimc device terminating the pipeline
- * @state: 1 to enable power or 0 for power down
- *
- * Need to be called with the graph mutex held.
- */
-int fimc_pipeline_s_power(struct fimc_dev *fimc, int state)
-{
- int ret = 0;
-
- if (fimc->pipeline.sensor == NULL)
- return -ENXIO;
-
- if (state) {
- ret = __subdev_set_power(fimc->pipeline.csis, 1);
- if (ret && ret != -ENXIO)
- return ret;
- return __subdev_set_power(fimc->pipeline.sensor, 1);
- }
-
- ret = __subdev_set_power(fimc->pipeline.sensor, 0);
- if (ret)
- return ret;
- ret = __subdev_set_power(fimc->pipeline.csis, 0);
-
- return ret == -ENXIO ? 0 : ret;
-}
-
-/**
- * __fimc_pipeline_initialize - update the pipeline information, enable power
- * of all pipeline subdevs and the sensor clock
- * @me: media entity to start graph walk with
- * @prep: true to acquire sensor (and csis) subdevs
- *
- * This function must be called with the graph mutex held.
- */
-static int __fimc_pipeline_initialize(struct fimc_dev *fimc,
- struct media_entity *me, bool prep)
-{
- int ret;
-
- if (prep)
- fimc_pipeline_prepare(fimc, me);
- if (fimc->pipeline.sensor == NULL)
- return -EINVAL;
- ret = fimc_md_set_camclk(fimc->pipeline.sensor, true);
- if (ret)
- return ret;
- return fimc_pipeline_s_power(fimc, 1);
-}
-
-int fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me,
- bool prep)
-{
- int ret;
-
- mutex_lock(&me->parent->graph_mutex);
- ret = __fimc_pipeline_initialize(fimc, me, prep);
- mutex_unlock(&me->parent->graph_mutex);
-
- return ret;
-}
-
-/**
- * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power
- * @fimc: fimc device terminating the pipeline
- *
- * Disable power of all subdevs in the pipeline and turn off the external
- * sensor clock.
- * Called with the graph mutex held.
- */
-int __fimc_pipeline_shutdown(struct fimc_dev *fimc)
-{
- int ret = 0;
-
- if (fimc->pipeline.sensor) {
- ret = fimc_pipeline_s_power(fimc, 0);
- fimc_md_set_camclk(fimc->pipeline.sensor, false);
- }
- return ret == -ENXIO ? 0 : ret;
-}
-
-int fimc_pipeline_shutdown(struct fimc_dev *fimc)
-{
- struct media_entity *me = &fimc->vid_cap.vfd->entity;
- int ret;
-
- mutex_lock(&me->parent->graph_mutex);
- ret = __fimc_pipeline_shutdown(fimc);
- mutex_unlock(&me->parent->graph_mutex);
-
- return ret;
-}
-
-/**
- * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs
- * @fimc: fimc device terminating the pipeline
- * @on: passed as the s_stream call argument
- */
-int fimc_pipeline_s_stream(struct fimc_dev *fimc, int on)
-{
- struct fimc_pipeline *p = &fimc->pipeline;
- int ret = 0;
-
- if (p->sensor == NULL)
- return -ENODEV;
-
- if ((on && p->csis) || !on)
- ret = v4l2_subdev_call(on ? p->csis : p->sensor,
- video, s_stream, on);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
- if ((!on && p->csis) || on)
- ret = v4l2_subdev_call(on ? p->sensor : p->csis,
- video, s_stream, on);
- return ret == -ENOIOCTLCMD ? 0 : ret;
-}
-
-/*
- * Sensor subdevice helper functions
- */
-static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
- struct fimc_sensor_info *s_info)
-{
- struct i2c_adapter *adapter;
- struct v4l2_subdev *sd = NULL;
-
- if (!s_info || !fmd)
- return NULL;
-
- adapter = i2c_get_adapter(s_info->pdata->i2c_bus_num);
- if (!adapter)
- return NULL;
- sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
- s_info->pdata->board_info, NULL);
- if (IS_ERR_OR_NULL(sd)) {
- i2c_put_adapter(adapter);
- v4l2_err(&fmd->v4l2_dev, "Failed to acquire subdev\n");
- return NULL;
- }
- v4l2_set_subdev_hostdata(sd, s_info);
- sd->grp_id = SENSOR_GROUP_ID;
-
- v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n",
- s_info->pdata->board_info->type);
- return sd;
-}
-
-static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct i2c_adapter *adapter;
-
- if (!client)
- return;
- v4l2_device_unregister_subdev(sd);
- adapter = client->adapter;
- i2c_unregister_device(client);
- if (adapter)
- i2c_put_adapter(adapter);
-}
-
-static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
-{
- struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
- struct fimc_dev *fd = NULL;
- int num_clients, ret, i;
-
- /*
- * Runtime resume one of the FIMC entities to make sure
- * the sclk_cam clocks are not globally disabled.
- */
- for (i = 0; !fd && i < ARRAY_SIZE(fmd->fimc); i++)
- if (fmd->fimc[i])
- fd = fmd->fimc[i];
- if (!fd)
- return -ENXIO;
- ret = pm_runtime_get_sync(&fd->pdev->dev);
- if (ret < 0)
- return ret;
-
- WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor));
- num_clients = min_t(u32, pdata->num_clients, ARRAY_SIZE(fmd->sensor));
-
- fmd->num_sensors = num_clients;
- for (i = 0; i < num_clients; i++) {
- fmd->sensor[i].pdata = &pdata->isp_info[i];
- ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true);
- if (ret)
- break;
- fmd->sensor[i].subdev =
- fimc_md_register_sensor(fmd, &fmd->sensor[i]);
- ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false);
- if (ret)
- break;
- }
- pm_runtime_put(&fd->pdev->dev);
- return ret;
-}
-
-/*
- * MIPI CSIS and FIMC platform devices registration.
- */
-static int fimc_register_callback(struct device *dev, void *p)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- struct fimc_md *fmd = p;
- int ret;
-
- if (!fimc || !fimc->pdev)
- return 0;
- if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
- return 0;
-
- fmd->fimc[fimc->pdev->id] = fimc;
- ret = fimc_register_m2m_device(fimc, &fmd->v4l2_dev);
- if (ret)
- return ret;
- ret = fimc_register_capture_device(fimc, &fmd->v4l2_dev);
- if (!ret)
- fimc->vid_cap.user_subdev_api = fmd->user_subdev_api;
- return ret;
-}
-
-static int csis_register_callback(struct device *dev, void *p)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct platform_device *pdev;
- struct fimc_md *fmd = p;
- int id, ret;
-
- if (!sd)
- return 0;
- pdev = v4l2_get_subdevdata(sd);
- if (!pdev || pdev->id < 0 || pdev->id >= CSIS_MAX_ENTITIES)
- return 0;
- v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
-
- id = pdev->id < 0 ? 0 : pdev->id;
- fmd->csis[id].sd = sd;
- sd->grp_id = CSIS_GROUP_ID;
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (ret)
- v4l2_err(&fmd->v4l2_dev,
- "Failed to register CSIS subdevice: %d\n", ret);
- return ret;
-}
-
-/**
- * fimc_md_register_platform_entities - register FIMC and CSIS media entities
- */
-static int fimc_md_register_platform_entities(struct fimc_md *fmd)
-{
- struct device_driver *driver;
- int ret;
-
- driver = driver_find(FIMC_MODULE_NAME, &platform_bus_type);
- if (!driver)
- return -ENODEV;
- ret = driver_for_each_device(driver, NULL, fmd,
- fimc_register_callback);
- if (ret)
- return ret;
-
- driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type);
- if (driver)
- ret = driver_for_each_device(driver, NULL, fmd,
- csis_register_callback);
- return ret;
-}
-
-static void fimc_md_unregister_entities(struct fimc_md *fmd)
-{
- int i;
-
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (fmd->fimc[i] == NULL)
- continue;
- fimc_unregister_m2m_device(fmd->fimc[i]);
- fimc_unregister_capture_device(fmd->fimc[i]);
- fmd->fimc[i] = NULL;
- }
- for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
- if (fmd->csis[i].sd == NULL)
- continue;
- v4l2_device_unregister_subdev(fmd->csis[i].sd);
- fmd->csis[i].sd = NULL;
- }
- for (i = 0; i < fmd->num_sensors; i++) {
- if (fmd->sensor[i].subdev == NULL)
- continue;
- fimc_md_unregister_sensor(fmd->sensor[i].subdev);
- fmd->sensor[i].subdev = NULL;
- }
-}
-
-static int fimc_md_register_video_nodes(struct fimc_md *fmd)
-{
- struct video_device *vdev;
- int i, ret = 0;
-
- for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) {
- if (!fmd->fimc[i])
- continue;
-
- vdev = fmd->fimc[i]->m2m.vfd;
- if (vdev) {
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
- if (ret)
- break;
- v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n",
- vdev->name, video_device_node_name(vdev));
- }
-
- vdev = fmd->fimc[i]->vid_cap.vfd;
- if (vdev == NULL)
- continue;
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
- v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n",
- vdev->name, video_device_node_name(vdev));
- }
-
- return ret;
-}
-
-/**
- * __fimc_md_create_fimc_links - create links to all FIMC entities
- * @fmd: fimc media device
- * @source: the source entity to create links to all fimc entities from
- * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null
- * @pad: the source entity pad index
- * @fimc_id: index of the fimc device for which link should be enabled
- */
-static int __fimc_md_create_fimc_links(struct fimc_md *fmd,
- struct media_entity *source,
- struct v4l2_subdev *sensor,
- int pad, int fimc_id)
-{
- struct fimc_sensor_info *s_info;
- struct media_entity *sink;
- unsigned int flags;
- int ret, i;
-
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (!fmd->fimc[i])
- break;
- /*
- * Some FIMC variants are not fitted with camera capture
- * interface. Skip creating a link from sensor for those.
- */
- if (sensor->grp_id == SENSOR_GROUP_ID &&
- !fmd->fimc[i]->variant->has_cam_if)
- continue;
-
- flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0;
- sink = &fmd->fimc[i]->vid_cap.subdev->entity;
- ret = media_entity_create_link(source, pad, sink,
- FIMC_SD_PAD_SINK, flags);
- if (ret)
- return ret;
-
- /* Notify FIMC capture subdev entity */
- ret = media_entity_call(sink, link_setup, &sink->pads[0],
- &source->pads[pad], flags);
- if (ret)
- break;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
- source->name, flags ? '=' : '-', sink->name);
-
- if (flags == 0)
- continue;
- s_info = v4l2_get_subdev_hostdata(sensor);
- if (!WARN_ON(s_info == NULL)) {
- unsigned long irq_flags;
- spin_lock_irqsave(&fmd->slock, irq_flags);
- s_info->host = fmd->fimc[i];
- spin_unlock_irqrestore(&fmd->slock, irq_flags);
- }
- }
- return 0;
-}
-
-/**
- * fimc_md_create_links - create default links between registered entities
- *
- * Parallel interface sensor entities are connected directly to FIMC capture
- * entities. The sensors using MIPI CSIS bus are connected through immutable
- * link with CSI receiver entity specified by mux_id. Any registered CSIS
- * entity has a link to each registered FIMC capture entity. Enabled links
- * are created by default between each subsequent registered sensor and
- * subsequent FIMC capture entity. The number of default active links is
- * determined by the number of available sensors or FIMC entities,
- * whichever is less.
- */
-static int fimc_md_create_links(struct fimc_md *fmd)
-{
- struct v4l2_subdev *sensor, *csis;
- struct s5p_fimc_isp_info *pdata;
- struct fimc_sensor_info *s_info;
- struct media_entity *source, *sink;
- int i, pad, fimc_id = 0;
- int ret = 0;
- u32 flags;
-
- for (i = 0; i < fmd->num_sensors; i++) {
- if (fmd->sensor[i].subdev == NULL)
- continue;
-
- sensor = fmd->sensor[i].subdev;
- s_info = v4l2_get_subdev_hostdata(sensor);
- if (!s_info || !s_info->pdata)
- continue;
-
- source = NULL;
- pdata = s_info->pdata;
-
- switch (pdata->bus_type) {
- case FIMC_MIPI_CSI2:
- if (WARN(pdata->mux_id >= CSIS_MAX_ENTITIES,
- "Wrong CSI channel id: %d\n", pdata->mux_id))
- return -EINVAL;
-
- csis = fmd->csis[pdata->mux_id].sd;
- if (WARN(csis == NULL,
- "MIPI-CSI interface specified "
- "but s5p-csis module is not loaded!\n"))
- return -EINVAL;
-
- ret = media_entity_create_link(&sensor->entity, 0,
- &csis->entity, CSIS_PAD_SINK,
- MEDIA_LNK_FL_IMMUTABLE |
- MEDIA_LNK_FL_ENABLED);
- if (ret)
- return ret;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]",
- sensor->entity.name, csis->entity.name);
-
- source = &csis->entity;
- pad = CSIS_PAD_SOURCE;
- break;
-
- case FIMC_ITU_601...FIMC_ITU_656:
- source = &sensor->entity;
- pad = 0;
- break;
-
- default:
- v4l2_err(&fmd->v4l2_dev, "Wrong bus_type: %x\n",
- pdata->bus_type);
- return -EINVAL;
- }
- if (source == NULL)
- continue;
-
- ret = __fimc_md_create_fimc_links(fmd, source, sensor, pad,
- fimc_id++);
- }
- /* Create immutable links between each FIMC's subdev and video node */
- flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (!fmd->fimc[i])
- continue;
- source = &fmd->fimc[i]->vid_cap.subdev->entity;
- sink = &fmd->fimc[i]->vid_cap.vfd->entity;
- ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
- sink, 0, flags);
- if (ret)
- break;
- }
-
- return ret;
-}
-
-/*
- * The peripheral sensor clock management.
- */
-static int fimc_md_get_clocks(struct fimc_md *fmd)
-{
- char clk_name[32];
- struct clk *clock;
- int i;
-
- for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
- snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i);
- clock = clk_get(NULL, clk_name);
- if (IS_ERR_OR_NULL(clock)) {
- v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s",
- clk_name);
- return -ENXIO;
- }
- fmd->camclk[i].clock = clock;
- }
- return 0;
-}
-
-static void fimc_md_put_clocks(struct fimc_md *fmd)
-{
- int i = FIMC_MAX_CAMCLKS;
-
- while (--i >= 0) {
- if (IS_ERR_OR_NULL(fmd->camclk[i].clock))
- continue;
- clk_put(fmd->camclk[i].clock);
- fmd->camclk[i].clock = NULL;
- }
-}
-
-static int __fimc_md_set_camclk(struct fimc_md *fmd,
- struct fimc_sensor_info *s_info,
- bool on)
-{
- struct s5p_fimc_isp_info *pdata = s_info->pdata;
- struct fimc_camclk_info *camclk;
- int ret = 0;
-
- if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL)
- return -EINVAL;
-
- if (s_info->clk_on == on)
- return 0;
- camclk = &fmd->camclk[pdata->clk_id];
-
- dbg("camclk %d, f: %lu, clk: %p, on: %d",
- pdata->clk_id, pdata->clk_frequency, camclk, on);
-
- if (on) {
- if (camclk->use_count > 0 &&
- camclk->frequency != pdata->clk_frequency)
- return -EINVAL;
-
- if (camclk->use_count++ == 0) {
- clk_set_rate(camclk->clock, pdata->clk_frequency);
- camclk->frequency = pdata->clk_frequency;
- ret = clk_enable(camclk->clock);
- }
- s_info->clk_on = 1;
- dbg("Enabled camclk %d: f: %lu", pdata->clk_id,
- clk_get_rate(camclk->clock));
-
- return ret;
- }
-
- if (WARN_ON(camclk->use_count == 0))
- return 0;
-
- if (--camclk->use_count == 0) {
- clk_disable(camclk->clock);
- s_info->clk_on = 0;
- dbg("Disabled camclk %d", pdata->clk_id);
- }
- return ret;
-}
-
-/**
- * fimc_md_set_camclk - peripheral sensor clock setup
- * @sd: sensor subdev to configure sclk_cam clock for
- * @on: 1 to enable or 0 to disable the clock
- *
- * There are 2 separate clock outputs available in the SoC for external
- * image processors. These clocks are shared between all registered FIMC
- * devices to which sensors can be attached, either directly or through
- * the MIPI CSI receiver. The clock is allowed here to be used by
- * multiple sensors concurrently if they use same frequency.
- * The per sensor subdev clk_on attribute helps to synchronize accesses
- * to the sclk_cam clocks from the video and media device nodes.
- * This function should only be called when the graph mutex is held.
- */
-int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
-{
- struct fimc_sensor_info *s_info = v4l2_get_subdev_hostdata(sd);
- struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
-
- return __fimc_md_set_camclk(fmd, s_info, on);
-}
-
-static int fimc_md_link_notify(struct media_pad *source,
- struct media_pad *sink, u32 flags)
-{
- struct v4l2_subdev *sd;
- struct fimc_dev *fimc;
- int ret = 0;
-
- if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- return 0;
-
- sd = media_entity_to_v4l2_subdev(sink->entity);
- fimc = v4l2_get_subdevdata(sd);
-
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- ret = __fimc_pipeline_shutdown(fimc);
- fimc->pipeline.sensor = NULL;
- fimc->pipeline.csis = NULL;
-
- mutex_lock(&fimc->lock);
- fimc_ctrls_delete(fimc->vid_cap.ctx);
- mutex_unlock(&fimc->lock);
- return ret;
- }
- /*
- * Link activation. Enable power of pipeline elements only if the
- * pipeline is already in use, i.e. its video node is opened.
- * Recreate the controls destroyed during the link deactivation.
- */
- mutex_lock(&fimc->lock);
- if (fimc->vid_cap.refcnt > 0) {
- ret = __fimc_pipeline_initialize(fimc, source->entity, true);
- if (!ret)
- ret = fimc_capture_ctrls_create(fimc);
- }
- mutex_unlock(&fimc->lock);
-
- return ret ? -EPIPE : ret;
-}
-
-static ssize_t fimc_md_sysfs_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct fimc_md *fmd = platform_get_drvdata(pdev);
-
- if (fmd->user_subdev_api)
- return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
-
- return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
-}
-
-static ssize_t fimc_md_sysfs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct fimc_md *fmd = platform_get_drvdata(pdev);
- bool subdev_api;
- int i;
-
- if (!strcmp(buf, "vid-dev\n"))
- subdev_api = false;
- else if (!strcmp(buf, "sub-dev\n"))
- subdev_api = true;
- else
- return count;
-
- fmd->user_subdev_api = subdev_api;
- for (i = 0; i < FIMC_MAX_DEVS; i++)
- if (fmd->fimc[i])
- fmd->fimc[i]->vid_cap.user_subdev_api = subdev_api;
- return count;
-}
-/*
- * This device attribute is to select video pipeline configuration method.
- * There are following valid values:
- * vid-dev - for V4L2 video node API only, subdevice will be configured
- * by the host driver.
- * sub-dev - for media controller API, subdevs must be configured in user
- * space before starting streaming.
- */
-static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
- fimc_md_sysfs_show, fimc_md_sysfs_store);
-
-static int __devinit fimc_md_probe(struct platform_device *pdev)
-{
- struct v4l2_device *v4l2_dev;
- struct fimc_md *fmd;
- int ret;
-
- fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
- if (!fmd)
- return -ENOMEM;
-
- spin_lock_init(&fmd->slock);
- fmd->pdev = pdev;
-
- strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
- sizeof(fmd->media_dev.model));
- fmd->media_dev.link_notify = fimc_md_link_notify;
- fmd->media_dev.dev = &pdev->dev;
-
- v4l2_dev = &fmd->v4l2_dev;
- v4l2_dev->mdev = &fmd->media_dev;
- v4l2_dev->notify = fimc_sensor_notify;
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
- dev_name(&pdev->dev));
-
- ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
- return ret;
- }
- ret = media_device_register(&fmd->media_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
- goto err2;
- }
- ret = fimc_md_get_clocks(fmd);
- if (ret)
- goto err3;
-
- fmd->user_subdev_api = false;
- ret = fimc_md_register_platform_entities(fmd);
- if (ret)
- goto err3;
-
- if (pdev->dev.platform_data) {
- ret = fimc_md_register_sensor_entities(fmd);
- if (ret)
- goto err3;
- }
- ret = fimc_md_create_links(fmd);
- if (ret)
- goto err3;
- ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
- if (ret)
- goto err3;
- ret = fimc_md_register_video_nodes(fmd);
- if (ret)
- goto err3;
-
- ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
- if (!ret) {
- platform_set_drvdata(pdev, fmd);
- return 0;
- }
-err3:
- media_device_unregister(&fmd->media_dev);
- fimc_md_put_clocks(fmd);
- fimc_md_unregister_entities(fmd);
-err2:
- v4l2_device_unregister(&fmd->v4l2_dev);
- return ret;
-}
-
-static int __devexit fimc_md_remove(struct platform_device *pdev)
-{
- struct fimc_md *fmd = platform_get_drvdata(pdev);
-
- if (!fmd)
- return 0;
- device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
- fimc_md_unregister_entities(fmd);
- media_device_unregister(&fmd->media_dev);
- fimc_md_put_clocks(fmd);
- return 0;
-}
-
-static struct platform_driver fimc_md_driver = {
- .probe = fimc_md_probe,
- .remove = __devexit_p(fimc_md_remove),
- .driver = {
- .name = "s5p-fimc-md",
- .owner = THIS_MODULE,
- }
-};
-
-int __init fimc_md_init(void)
-{
- int ret;
- request_module("s5p-csis");
- ret = fimc_register_driver();
- if (ret)
- return ret;
- return platform_driver_register(&fimc_md_driver);
-}
-void __exit fimc_md_exit(void)
-{
- platform_driver_unregister(&fimc_md_driver);
- fimc_unregister_driver();
-}
-
-module_init(fimc_md_init);
-module_exit(fimc_md_exit);
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("S5P FIMC camera host interface/video postprocessor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("2.0.1");
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.h b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.h
deleted file mode 100644
index da378082..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-mdevice.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * 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.
- */
-
-#ifndef FIMC_MDEVICE_H_
-#define FIMC_MDEVICE_H_
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <media/media-device.h>
-#include <media/media-entity.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "fimc-core.h"
-#include "mipi-csis.h"
-
-/* Group IDs of sensor, MIPI CSIS and the writeback subdevs. */
-#define SENSOR_GROUP_ID (1 << 8)
-#define CSIS_GROUP_ID (1 << 9)
-#define WRITEBACK_GROUP_ID (1 << 10)
-
-#define FIMC_MAX_SENSORS 8
-#define FIMC_MAX_CAMCLKS 2
-
-struct fimc_csis_info {
- struct v4l2_subdev *sd;
- int id;
-};
-
-struct fimc_camclk_info {
- struct clk *clock;
- int use_count;
- unsigned long frequency;
-};
-
-/**
- * struct fimc_sensor_info - image data source subdev information
- * @pdata: sensor's atrributes passed as media device's platform data
- * @subdev: image sensor v4l2 subdev
- * @host: fimc device the sensor is currently linked to
- * @clk_on: sclk_cam clock's state associated with this subdev
- *
- * This data structure applies to image sensor and the writeback subdevs.
- */
-struct fimc_sensor_info {
- struct s5p_fimc_isp_info *pdata;
- struct v4l2_subdev *subdev;
- struct fimc_dev *host;
- bool clk_on;
-};
-
-/**
- * struct fimc_md - fimc media device information
- * @csis: MIPI CSIS subdevs data
- * @sensor: array of registered sensor subdevs
- * @num_sensors: actual number of registered sensors
- * @camclk: external sensor clock information
- * @fimc: array of registered fimc devices
- * @media_dev: top level media device
- * @v4l2_dev: top level v4l2_device holding up the subdevs
- * @pdev: platform device this media device is hooked up into
- * @user_subdev_api: true if subdevs are not configured by the host driver
- * @slock: spinlock protecting @sensor array
- */
-struct fimc_md {
- struct fimc_csis_info csis[CSIS_MAX_ENTITIES];
- struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
- int num_sensors;
- struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];
- struct fimc_dev *fimc[FIMC_MAX_DEVS];
- struct media_device media_dev;
- struct v4l2_device v4l2_dev;
- struct platform_device *pdev;
- bool user_subdev_api;
- spinlock_t slock;
-};
-
-#define is_subdev_pad(pad) (pad == NULL || \
- media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-
-#define me_subtype(me) \
- ((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
-
-#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
-
-static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
-{
- return me->parent == NULL ? NULL :
- container_of(me->parent, struct fimc_md, media_dev);
-}
-
-static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
-{
- BUG_ON(fimc->vid_cap.vfd == NULL);
- mutex_lock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
-}
-
-static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
-{
- BUG_ON(fimc->vid_cap.vfd == NULL);
- mutex_unlock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
-}
-
-int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
-void fimc_pipeline_prepare(struct fimc_dev *fimc, struct media_entity *me);
-int fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me,
- bool resume);
-int fimc_pipeline_shutdown(struct fimc_dev *fimc);
-int fimc_pipeline_s_power(struct fimc_dev *fimc, int state);
-int fimc_pipeline_s_stream(struct fimc_dev *fimc, int state);
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-reg.c b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-reg.c
deleted file mode 100644
index 15466d05..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/fimc-reg.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Register interface file for Samsung Camera Interface (FIMC) driver
- *
- * Copyright (c) 2010 Samsung Electronics
- *
- * Sylwester Nawrocki, s.nawrocki@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 <linux/io.h>
-#include <linux/delay.h>
-#include <mach/map.h>
-#include <media/s5p_fimc.h>
-
-#include "fimc-core.h"
-
-
-void fimc_hw_reset(struct fimc_dev *dev)
-{
- u32 cfg;
-
- cfg = readl(dev->regs + S5P_CISRCFMT);
- cfg |= S5P_CISRCFMT_ITU601_8BIT;
- writel(cfg, dev->regs + S5P_CISRCFMT);
-
- /* Software reset. */
- cfg = readl(dev->regs + S5P_CIGCTRL);
- cfg |= (S5P_CIGCTRL_SWRST | S5P_CIGCTRL_IRQ_LEVEL);
- writel(cfg, dev->regs + S5P_CIGCTRL);
- udelay(10);
-
- cfg = readl(dev->regs + S5P_CIGCTRL);
- cfg &= ~S5P_CIGCTRL_SWRST;
- writel(cfg, dev->regs + S5P_CIGCTRL);
-
- if (dev->variant->out_buf_count > 4)
- fimc_hw_set_dma_seq(dev, 0xF);
-}
-
-static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
-{
- u32 flip = S5P_MSCTRL_FLIP_NORMAL;
-
- if (ctx->hflip)
- flip = S5P_MSCTRL_FLIP_X_MIRROR;
- if (ctx->vflip)
- flip = S5P_MSCTRL_FLIP_Y_MIRROR;
-
- if (ctx->rotation <= 90)
- return flip;
-
- return (flip ^ S5P_MSCTRL_FLIP_180) & S5P_MSCTRL_FLIP_180;
-}
-
-static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
-{
- u32 flip = S5P_CITRGFMT_FLIP_NORMAL;
-
- if (ctx->hflip)
- flip |= S5P_CITRGFMT_FLIP_X_MIRROR;
- if (ctx->vflip)
- flip |= S5P_CITRGFMT_FLIP_Y_MIRROR;
-
- if (ctx->rotation <= 90)
- return flip;
-
- return (flip ^ S5P_CITRGFMT_FLIP_180) & S5P_CITRGFMT_FLIP_180;
-}
-
-void fimc_hw_set_rotation(struct fimc_ctx *ctx)
-{
- u32 cfg, flip;
- struct fimc_dev *dev = ctx->fimc_dev;
-
- cfg = readl(dev->regs + S5P_CITRGFMT);
- cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 |
- S5P_CITRGFMT_FLIP_180);
-
- /*
- * The input and output rotator cannot work simultaneously.
- * Use the output rotator in output DMA mode or the input rotator
- * in direct fifo output mode.
- */
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- if (ctx->out_path == FIMC_LCDFIFO)
- cfg |= S5P_CITRGFMT_INROT90;
- else
- cfg |= S5P_CITRGFMT_OUTROT90;
- }
-
- if (ctx->out_path == FIMC_DMA) {
- cfg |= fimc_hw_get_target_flip(ctx);
- writel(cfg, dev->regs + S5P_CITRGFMT);
- } else {
- /* LCD FIFO path */
- flip = readl(dev->regs + S5P_MSCTRL);
- flip &= ~S5P_MSCTRL_FLIP_MASK;
- flip |= fimc_hw_get_in_flip(ctx);
- writel(flip, dev->regs + S5P_MSCTRL);
- }
-}
-
-void fimc_hw_set_target_format(struct fimc_ctx *ctx)
-{
- u32 cfg;
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
-
- dbg("w= %d, h= %d color: %d", frame->width,
- frame->height, frame->fmt->color);
-
- cfg = readl(dev->regs + S5P_CITRGFMT);
- cfg &= ~(S5P_CITRGFMT_FMT_MASK | S5P_CITRGFMT_HSIZE_MASK |
- S5P_CITRGFMT_VSIZE_MASK);
-
- switch (frame->fmt->color) {
- case S5P_FIMC_RGB444...S5P_FIMC_RGB888:
- cfg |= S5P_CITRGFMT_RGB;
- break;
- case S5P_FIMC_YCBCR420:
- cfg |= S5P_CITRGFMT_YCBCR420;
- break;
- case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
- if (frame->fmt->colplanes == 1)
- cfg |= S5P_CITRGFMT_YCBCR422_1P;
- else
- cfg |= S5P_CITRGFMT_YCBCR422;
- break;
- default:
- break;
- }
-
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- cfg |= S5P_CITRGFMT_HSIZE(frame->height);
- cfg |= S5P_CITRGFMT_VSIZE(frame->width);
- } else {
-
- cfg |= S5P_CITRGFMT_HSIZE(frame->width);
- cfg |= S5P_CITRGFMT_VSIZE(frame->height);
- }
-
- writel(cfg, dev->regs + S5P_CITRGFMT);
-
- cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK;
- cfg |= (frame->width * frame->height);
- writel(cfg, dev->regs + S5P_CITAREA);
-}
-
-static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- u32 cfg;
-
- cfg = S5P_ORIG_SIZE_HOR(frame->f_width);
- cfg |= S5P_ORIG_SIZE_VER(frame->f_height);
- writel(cfg, dev->regs + S5P_ORGOSIZE);
-
- /* Select color space conversion equation (HD/SD size).*/
- cfg = readl(dev->regs + S5P_CIGCTRL);
- if (frame->f_width >= 1280) /* HD */
- cfg |= S5P_CIGCTRL_CSC_ITU601_709;
- else /* SD */
- cfg &= ~S5P_CIGCTRL_CSC_ITU601_709;
- writel(cfg, dev->regs + S5P_CIGCTRL);
-
-}
-
-void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
-{
- u32 cfg;
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- struct fimc_fmt *fmt = frame->fmt;
-
- /* Set the input dma offsets. */
- cfg = 0;
- cfg |= S5P_CIO_OFFS_HOR(offset->y_h);
- cfg |= S5P_CIO_OFFS_VER(offset->y_v);
- writel(cfg, dev->regs + S5P_CIOYOFF);
-
- cfg = 0;
- cfg |= S5P_CIO_OFFS_HOR(offset->cb_h);
- cfg |= S5P_CIO_OFFS_VER(offset->cb_v);
- writel(cfg, dev->regs + S5P_CIOCBOFF);
-
- cfg = 0;
- cfg |= S5P_CIO_OFFS_HOR(offset->cr_h);
- cfg |= S5P_CIO_OFFS_VER(offset->cr_v);
- writel(cfg, dev->regs + S5P_CIOCROFF);
-
- fimc_hw_set_out_dma_size(ctx);
-
- /* Configure chroma components order. */
- cfg = readl(dev->regs + S5P_CIOCTRL);
-
- cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK |
- S5P_CIOCTRL_YCBCR_PLANE_MASK | S5P_CIOCTRL_RGB16FMT_MASK);
-
- if (fmt->colplanes == 1)
- cfg |= ctx->out_order_1p;
- else if (fmt->colplanes == 2)
- cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE;
- else if (fmt->colplanes == 3)
- cfg |= S5P_CIOCTRL_YCBCR_3PLANE;
-
- if (fmt->color == S5P_FIMC_RGB565)
- cfg |= S5P_CIOCTRL_RGB565;
- else if (fmt->color == S5P_FIMC_RGB555)
- cfg |= S5P_CIOCTRL_ARGB1555;
- else if (fmt->color == S5P_FIMC_RGB444)
- cfg |= S5P_CIOCTRL_ARGB4444;
-
- writel(cfg, dev->regs + S5P_CIOCTRL);
-}
-
-static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable)
-{
- u32 cfg = readl(dev->regs + S5P_ORGISIZE);
- if (enable)
- cfg |= S5P_CIREAL_ISIZE_AUTOLOAD_EN;
- else
- cfg &= ~S5P_CIREAL_ISIZE_AUTOLOAD_EN;
- writel(cfg, dev->regs + S5P_ORGISIZE);
-}
-
-void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
-{
- u32 cfg = readl(dev->regs + S5P_CIOCTRL);
- if (enable)
- cfg |= S5P_CIOCTRL_LASTIRQ_ENABLE;
- else
- cfg &= ~S5P_CIOCTRL_LASTIRQ_ENABLE;
- writel(cfg, dev->regs + S5P_CIOCTRL);
-}
-
-void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_scaler *sc = &ctx->scaler;
- u32 cfg, shfactor;
-
- shfactor = 10 - (sc->hfactor + sc->vfactor);
-
- cfg = S5P_CISCPRERATIO_SHFACTOR(shfactor);
- cfg |= S5P_CISCPRERATIO_HOR(sc->pre_hratio);
- cfg |= S5P_CISCPRERATIO_VER(sc->pre_vratio);
- writel(cfg, dev->regs + S5P_CISCPRERATIO);
-
- cfg = S5P_CISCPREDST_WIDTH(sc->pre_dst_width);
- cfg |= S5P_CISCPREDST_HEIGHT(sc->pre_dst_height);
- writel(cfg, dev->regs + S5P_CISCPREDST);
-}
-
-static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *src_frame = &ctx->s_frame;
- struct fimc_frame *dst_frame = &ctx->d_frame;
-
- u32 cfg = readl(dev->regs + S5P_CISCCTRL);
-
- cfg &= ~(S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE |
- S5P_CISCCTRL_SCALEUP_H | S5P_CISCCTRL_SCALEUP_V |
- S5P_CISCCTRL_SCALERBYPASS | S5P_CISCCTRL_ONE2ONE |
- S5P_CISCCTRL_INRGB_FMT_MASK | S5P_CISCCTRL_OUTRGB_FMT_MASK |
- S5P_CISCCTRL_INTERLACE | S5P_CISCCTRL_RGB_EXT);
-
- if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
- cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE);
-
- if (!sc->enabled)
- cfg |= S5P_CISCCTRL_SCALERBYPASS;
-
- if (sc->scaleup_h)
- cfg |= S5P_CISCCTRL_SCALEUP_H;
-
- if (sc->scaleup_v)
- cfg |= S5P_CISCCTRL_SCALEUP_V;
-
- if (sc->copy_mode)
- cfg |= S5P_CISCCTRL_ONE2ONE;
-
- if (ctx->in_path == FIMC_DMA) {
- switch (src_frame->fmt->color) {
- case S5P_FIMC_RGB565:
- cfg |= S5P_CISCCTRL_INRGB_FMT_RGB565;
- break;
- case S5P_FIMC_RGB666:
- cfg |= S5P_CISCCTRL_INRGB_FMT_RGB666;
- break;
- case S5P_FIMC_RGB888:
- cfg |= S5P_CISCCTRL_INRGB_FMT_RGB888;
- break;
- }
- }
-
- if (ctx->out_path == FIMC_DMA) {
- u32 color = dst_frame->fmt->color;
-
- if (color >= S5P_FIMC_RGB444 && color <= S5P_FIMC_RGB565)
- cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB565;
- else if (color == S5P_FIMC_RGB666)
- cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB666;
- else if (color == S5P_FIMC_RGB888)
- cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888;
- } else {
- cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888;
-
- if (ctx->flags & FIMC_SCAN_MODE_INTERLACED)
- cfg |= S5P_CISCCTRL_INTERLACE;
- }
-
- writel(cfg, dev->regs + S5P_CISCCTRL);
-}
-
-void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct samsung_fimc_variant *variant = dev->variant;
- struct fimc_scaler *sc = &ctx->scaler;
- u32 cfg;
-
- dbg("main_hratio= 0x%X main_vratio= 0x%X",
- sc->main_hratio, sc->main_vratio);
-
- fimc_hw_set_scaler(ctx);
-
- cfg = readl(dev->regs + S5P_CISCCTRL);
- cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK);
-
- if (variant->has_mainscaler_ext) {
- cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
- cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
- writel(cfg, dev->regs + S5P_CISCCTRL);
-
- cfg = readl(dev->regs + S5P_CIEXTEN);
-
- cfg &= ~(S5P_CIEXTEN_MVRATIO_EXT_MASK |
- S5P_CIEXTEN_MHRATIO_EXT_MASK);
- cfg |= S5P_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
- cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
- writel(cfg, dev->regs + S5P_CIEXTEN);
- } else {
- cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio);
- cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio);
- writel(cfg, dev->regs + S5P_CISCCTRL);
- }
-}
-
-void fimc_hw_en_capture(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + S5P_CIIMGCPT);
-
- if (ctx->out_path == FIMC_DMA) {
- /* one shot mode */
- cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE | S5P_CIIMGCPT_IMGCPTEN;
- } else {
- /* Continuous frame capture mode (freerun). */
- cfg &= ~(S5P_CIIMGCPT_CPT_FREN_ENABLE |
- S5P_CIIMGCPT_CPT_FRMOD_CNT);
- cfg |= S5P_CIIMGCPT_IMGCPTEN;
- }
-
- if (ctx->scaler.enabled)
- cfg |= S5P_CIIMGCPT_IMGCPTEN_SC;
-
- writel(cfg | S5P_CIIMGCPT_IMGCPTEN, dev->regs + S5P_CIIMGCPT);
-}
-
-void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_effect *effect = &ctx->effect;
- u32 cfg = 0;
-
- if (active) {
- cfg |= S5P_CIIMGEFF_IE_SC_AFTER | S5P_CIIMGEFF_IE_ENABLE;
- cfg |= effect->type;
- if (effect->type == S5P_FIMC_EFFECT_ARBITRARY) {
- cfg |= S5P_CIIMGEFF_PAT_CB(effect->pat_cb);
- cfg |= S5P_CIIMGEFF_PAT_CR(effect->pat_cr);
- }
- }
-
- writel(cfg, dev->regs + S5P_CIIMGEFF);
-}
-
-void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- u32 cfg;
-
- if (!(frame->fmt->flags & FMT_HAS_ALPHA))
- return;
-
- cfg = readl(dev->regs + S5P_CIOCTRL);
- cfg &= ~S5P_CIOCTRL_ALPHA_OUT_MASK;
- cfg |= (frame->alpha << 4);
- writel(cfg, dev->regs + S5P_CIOCTRL);
-}
-
-static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- u32 cfg_o = 0;
- u32 cfg_r = 0;
-
- if (FIMC_LCDFIFO == ctx->out_path)
- cfg_r |= S5P_CIREAL_ISIZE_AUTOLOAD_EN;
-
- cfg_o |= S5P_ORIG_SIZE_HOR(frame->f_width);
- cfg_o |= S5P_ORIG_SIZE_VER(frame->f_height);
- cfg_r |= S5P_CIREAL_ISIZE_WIDTH(frame->width);
- cfg_r |= S5P_CIREAL_ISIZE_HEIGHT(frame->height);
-
- writel(cfg_o, dev->regs + S5P_ORGISIZE);
- writel(cfg_r, dev->regs + S5P_CIREAL_ISIZE);
-}
-
-void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- u32 cfg;
-
- /* Set the pixel offsets. */
- cfg = S5P_CIO_OFFS_HOR(offset->y_h);
- cfg |= S5P_CIO_OFFS_VER(offset->y_v);
- writel(cfg, dev->regs + S5P_CIIYOFF);
-
- cfg = S5P_CIO_OFFS_HOR(offset->cb_h);
- cfg |= S5P_CIO_OFFS_VER(offset->cb_v);
- writel(cfg, dev->regs + S5P_CIICBOFF);
-
- cfg = S5P_CIO_OFFS_HOR(offset->cr_h);
- cfg |= S5P_CIO_OFFS_VER(offset->cr_v);
- writel(cfg, dev->regs + S5P_CIICROFF);
-
- /* Input original and real size. */
- fimc_hw_set_in_dma_size(ctx);
-
- /* Use DMA autoload only in FIFO mode. */
- fimc_hw_en_autoload(dev, ctx->out_path == FIMC_LCDFIFO);
-
- /* Set the input DMA to process single frame only. */
- cfg = readl(dev->regs + S5P_MSCTRL);
- cfg &= ~(S5P_MSCTRL_INFORMAT_MASK
- | S5P_MSCTRL_IN_BURST_COUNT_MASK
- | S5P_MSCTRL_INPUT_MASK
- | S5P_MSCTRL_C_INT_IN_MASK
- | S5P_MSCTRL_2P_IN_ORDER_MASK);
-
- cfg |= (S5P_MSCTRL_IN_BURST_COUNT(4)
- | S5P_MSCTRL_INPUT_MEMORY
- | S5P_MSCTRL_FIFO_CTRL_FULL);
-
- switch (frame->fmt->color) {
- case S5P_FIMC_RGB565...S5P_FIMC_RGB888:
- cfg |= S5P_MSCTRL_INFORMAT_RGB;
- break;
- case S5P_FIMC_YCBCR420:
- cfg |= S5P_MSCTRL_INFORMAT_YCBCR420;
-
- if (frame->fmt->colplanes == 2)
- cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE;
- else
- cfg |= S5P_MSCTRL_C_INT_IN_3PLANE;
-
- break;
- case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
- if (frame->fmt->colplanes == 1) {
- cfg |= ctx->in_order_1p
- | S5P_MSCTRL_INFORMAT_YCBCR422_1P;
- } else {
- cfg |= S5P_MSCTRL_INFORMAT_YCBCR422;
-
- if (frame->fmt->colplanes == 2)
- cfg |= ctx->in_order_2p
- | S5P_MSCTRL_C_INT_IN_2PLANE;
- else
- cfg |= S5P_MSCTRL_C_INT_IN_3PLANE;
- }
- break;
- default:
- break;
- }
-
- writel(cfg, dev->regs + S5P_MSCTRL);
-
- /* Input/output DMA linear/tiled mode. */
- cfg = readl(dev->regs + S5P_CIDMAPARAM);
- cfg &= ~S5P_CIDMAPARAM_TILE_MASK;
-
- if (tiled_fmt(ctx->s_frame.fmt))
- cfg |= S5P_CIDMAPARAM_R_64X32;
-
- if (tiled_fmt(ctx->d_frame.fmt))
- cfg |= S5P_CIDMAPARAM_W_64X32;
-
- writel(cfg, dev->regs + S5P_CIDMAPARAM);
-}
-
-
-void fimc_hw_set_input_path(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + S5P_MSCTRL);
- cfg &= ~S5P_MSCTRL_INPUT_MASK;
-
- if (ctx->in_path == FIMC_DMA)
- cfg |= S5P_MSCTRL_INPUT_MEMORY;
- else
- cfg |= S5P_MSCTRL_INPUT_EXTCAM;
-
- writel(cfg, dev->regs + S5P_MSCTRL);
-}
-
-void fimc_hw_set_output_path(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + S5P_CISCCTRL);
- cfg &= ~S5P_CISCCTRL_LCDPATHEN_FIFO;
- if (ctx->out_path == FIMC_LCDFIFO)
- cfg |= S5P_CISCCTRL_LCDPATHEN_FIFO;
- writel(cfg, dev->regs + S5P_CISCCTRL);
-}
-
-void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr)
-{
- u32 cfg = readl(dev->regs + S5P_CIREAL_ISIZE);
- cfg |= S5P_CIREAL_ISIZE_ADDR_CH_DIS;
- writel(cfg, dev->regs + S5P_CIREAL_ISIZE);
-
- writel(paddr->y, dev->regs + S5P_CIIYSA(0));
- writel(paddr->cb, dev->regs + S5P_CIICBSA(0));
- writel(paddr->cr, dev->regs + S5P_CIICRSA(0));
-
- cfg &= ~S5P_CIREAL_ISIZE_ADDR_CH_DIS;
- writel(cfg, dev->regs + S5P_CIREAL_ISIZE);
-}
-
-void fimc_hw_set_output_addr(struct fimc_dev *dev,
- struct fimc_addr *paddr, int index)
-{
- int i = (index == -1) ? 0 : index;
- do {
- writel(paddr->y, dev->regs + S5P_CIOYSA(i));
- writel(paddr->cb, dev->regs + S5P_CIOCBSA(i));
- writel(paddr->cr, dev->regs + S5P_CIOCRSA(i));
- dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
- i, paddr->y, paddr->cb, paddr->cr);
- } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS);
-}
-
-int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam)
-{
- u32 cfg = readl(fimc->regs + S5P_CIGCTRL);
-
- cfg &= ~(S5P_CIGCTRL_INVPOLPCLK | S5P_CIGCTRL_INVPOLVSYNC |
- S5P_CIGCTRL_INVPOLHREF | S5P_CIGCTRL_INVPOLHSYNC |
- S5P_CIGCTRL_INVPOLFIELD);
-
- if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cfg |= S5P_CIGCTRL_INVPOLPCLK;
-
- if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cfg |= S5P_CIGCTRL_INVPOLVSYNC;
-
- if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= S5P_CIGCTRL_INVPOLHREF;
-
- if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= S5P_CIGCTRL_INVPOLHSYNC;
-
- if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW)
- cfg |= S5P_CIGCTRL_INVPOLFIELD;
-
- writel(cfg, fimc->regs + S5P_CIGCTRL);
-
- return 0;
-}
-
-int fimc_hw_set_camera_source(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam)
-{
- struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
- u32 cfg = 0;
- u32 bus_width;
- int i;
-
- static const struct {
- u32 pixelcode;
- u32 cisrcfmt;
- u16 bus_width;
- } pix_desc[] = {
- { V4L2_MBUS_FMT_YUYV8_2X8, S5P_CISRCFMT_ORDER422_YCBYCR, 8 },
- { V4L2_MBUS_FMT_YVYU8_2X8, S5P_CISRCFMT_ORDER422_YCRYCB, 8 },
- { V4L2_MBUS_FMT_VYUY8_2X8, S5P_CISRCFMT_ORDER422_CRYCBY, 8 },
- { V4L2_MBUS_FMT_UYVY8_2X8, S5P_CISRCFMT_ORDER422_CBYCRY, 8 },
- /* TODO: Add pixel codes for 16-bit bus width */
- };
-
- if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) {
- for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
- if (fimc->vid_cap.mf.code == pix_desc[i].pixelcode) {
- cfg = pix_desc[i].cisrcfmt;
- bus_width = pix_desc[i].bus_width;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(pix_desc)) {
- v4l2_err(fimc->vid_cap.vfd,
- "Camera color format not supported: %d\n",
- fimc->vid_cap.mf.code);
- return -EINVAL;
- }
-
- if (cam->bus_type == FIMC_ITU_601) {
- if (bus_width == 8)
- cfg |= S5P_CISRCFMT_ITU601_8BIT;
- else if (bus_width == 16)
- cfg |= S5P_CISRCFMT_ITU601_16BIT;
- } /* else defaults to ITU-R BT.656 8-bit */
- } else if (cam->bus_type == FIMC_MIPI_CSI2) {
- if (fimc_fmt_is_jpeg(f->fmt->color))
- cfg |= S5P_CISRCFMT_ITU601_8BIT;
- }
-
- cfg |= S5P_CISRCFMT_HSIZE(f->o_width) | S5P_CISRCFMT_VSIZE(f->o_height);
- writel(cfg, fimc->regs + S5P_CISRCFMT);
- return 0;
-}
-
-
-int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
-{
- u32 hoff2, voff2;
-
- u32 cfg = readl(fimc->regs + S5P_CIWDOFST);
-
- cfg &= ~(S5P_CIWDOFST_HOROFF_MASK | S5P_CIWDOFST_VEROFF_MASK);
- cfg |= S5P_CIWDOFST_OFF_EN |
- S5P_CIWDOFST_HOROFF(f->offs_h) |
- S5P_CIWDOFST_VEROFF(f->offs_v);
-
- writel(cfg, fimc->regs + S5P_CIWDOFST);
-
- /* See CIWDOFSTn register description in the datasheet for details. */
- hoff2 = f->o_width - f->width - f->offs_h;
- voff2 = f->o_height - f->height - f->offs_v;
- cfg = S5P_CIWDOFST2_HOROFF(hoff2) | S5P_CIWDOFST2_VEROFF(voff2);
-
- writel(cfg, fimc->regs + S5P_CIWDOFST2);
- return 0;
-}
-
-int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam)
-{
- u32 cfg, tmp;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
-
- cfg = readl(fimc->regs + S5P_CIGCTRL);
-
- /* Select ITU B interface, disable Writeback path and test pattern. */
- cfg &= ~(S5P_CIGCTRL_TESTPAT_MASK | S5P_CIGCTRL_SELCAM_ITU_A |
- S5P_CIGCTRL_SELCAM_MIPI | S5P_CIGCTRL_CAMIF_SELWB |
- S5P_CIGCTRL_SELCAM_MIPI_A | S5P_CIGCTRL_CAM_JPEG);
-
- if (cam->bus_type == FIMC_MIPI_CSI2) {
- cfg |= S5P_CIGCTRL_SELCAM_MIPI;
-
- if (cam->mux_id == 0)
- cfg |= S5P_CIGCTRL_SELCAM_MIPI_A;
-
- /* TODO: add remaining supported formats. */
- switch (vid_cap->mf.code) {
- case V4L2_MBUS_FMT_VYUY8_2X8:
- tmp = S5P_CSIIMGFMT_YCBCR422_8BIT;
- break;
- case V4L2_MBUS_FMT_JPEG_1X8:
- tmp = S5P_CSIIMGFMT_USER(1);
- cfg |= S5P_CIGCTRL_CAM_JPEG;
- break;
- default:
- v4l2_err(fimc->vid_cap.vfd,
- "Not supported camera pixel format: %d",
- vid_cap->mf.code);
- return -EINVAL;
- }
- tmp |= (cam->csi_data_align == 32) << 8;
-
- writel(tmp, fimc->regs + S5P_CSIIMGFMT);
-
- } else if (cam->bus_type == FIMC_ITU_601 ||
- cam->bus_type == FIMC_ITU_656) {
- if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
- cfg |= S5P_CIGCTRL_SELCAM_ITU_A;
- } else if (cam->bus_type == FIMC_LCD_WB) {
- cfg |= S5P_CIGCTRL_CAMIF_SELWB;
- } else {
- err("invalid camera bus type selected\n");
- return -EINVAL;
- }
- writel(cfg, fimc->regs + S5P_CIGCTRL);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.c b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.c
deleted file mode 100644
index f44f6903..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.c
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
- *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki, <s.nawrocki@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 <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/memory.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-#include <plat/mipi_csis.h>
-#include "mipi-csis.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* Register map definition */
-
-/* CSIS global control */
-#define S5PCSIS_CTRL 0x00
-#define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
-#define S5PCSIS_CTRL_DPDN_SWAP (1 << 31)
-#define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
-#define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
-#define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
-#define S5PCSIS_CTRL_RESET (1 << 4)
-#define S5PCSIS_CTRL_ENABLE (1 << 0)
-
-/* D-PHY control */
-#define S5PCSIS_DPHYCTRL 0x04
-#define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
-#define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
-
-#define S5PCSIS_CONFIG 0x08
-#define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
-#define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
-#define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
-#define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
-/* User defined formats, x = 1...4 */
-#define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
-#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
-#define S5PCSIS_CFG_NR_LANE_MASK 3
-
-/* Interrupt mask. */
-#define S5PCSIS_INTMSK 0x10
-#define S5PCSIS_INTMSK_EN_ALL 0xf000003f
-#define S5PCSIS_INTSRC 0x14
-
-/* Pixel resolution */
-#define S5PCSIS_RESOL 0x2c
-#define CSIS_MAX_PIX_WIDTH 0xffff
-#define CSIS_MAX_PIX_HEIGHT 0xffff
-
-enum {
- CSIS_CLK_MUX,
- CSIS_CLK_GATE,
-};
-
-static char *csi_clock_name[] = {
- [CSIS_CLK_MUX] = "sclk_csis",
- [CSIS_CLK_GATE] = "csis",
-};
-#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
-
-static const char * const csis_supply_name[] = {
- "vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */
- "vdd18", /* VDD 1.8V and MIPI CSI PLL supply */
-};
-#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
-
-enum {
- ST_POWERED = 1,
- ST_STREAMING = 2,
- ST_SUSPENDED = 4,
-};
-
-/**
- * struct csis_state - the driver's internal state data structure
- * @lock: mutex serializing the subdev and power management operations,
- * protecting @format and @flags members
- * @pads: CSIS pads array
- * @sd: v4l2_subdev associated with CSIS device instance
- * @pdev: CSIS platform device
- * @regs: mmaped I/O registers memory
- * @clock: CSIS clocks
- * @irq: requested s5p-mipi-csis irq number
- * @flags: the state variable for power and streaming control
- * @csis_fmt: current CSIS pixel format
- * @format: common media bus format for the source and sink pad
- */
-struct csis_state {
- struct mutex lock;
- struct media_pad pads[CSIS_PADS_NUM];
- struct v4l2_subdev sd;
- struct platform_device *pdev;
- void __iomem *regs;
- struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
- struct clk *clock[NUM_CSIS_CLOCKS];
- int irq;
- u32 flags;
- const struct csis_pix_format *csis_fmt;
- struct v4l2_mbus_framefmt format;
-};
-
-/**
- * struct csis_pix_format - CSIS pixel format description
- * @pix_width_alignment: horizontal pixel alignment, width will be
- * multiple of 2^pix_width_alignment
- * @code: corresponding media bus code
- * @fmt_reg: S5PCSIS_CONFIG register value
- */
-struct csis_pix_format {
- unsigned int pix_width_alignment;
- enum v4l2_mbus_pixelcode code;
- u32 fmt_reg;
-};
-
-static const struct csis_pix_format s5pcsis_formats[] = {
- {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
- }, {
- .code = V4L2_MBUS_FMT_JPEG_1X8,
- .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
- },
-};
-
-#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
-#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
-
-static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
-{
- return container_of(sdev, struct csis_state, sd);
-}
-
-static const struct csis_pix_format *find_csis_format(
- struct v4l2_mbus_framefmt *mf)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
- if (mf->code == s5pcsis_formats[i].code)
- return &s5pcsis_formats[i];
- return NULL;
-}
-
-static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
-
- val = on ? val | S5PCSIS_INTMSK_EN_ALL :
- val & ~S5PCSIS_INTMSK_EN_ALL;
- s5pcsis_write(state, S5PCSIS_INTMSK, val);
-}
-
-static void s5pcsis_reset(struct csis_state *state)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
-
- s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
- udelay(10);
-}
-
-static void s5pcsis_system_enable(struct csis_state *state, int on)
-{
- u32 val;
-
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- if (on)
- val |= S5PCSIS_CTRL_ENABLE;
- else
- val &= ~S5PCSIS_CTRL_ENABLE;
- s5pcsis_write(state, S5PCSIS_CTRL, val);
-
- val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
- if (on)
- val |= S5PCSIS_DPHYCTRL_ENABLE;
- else
- val &= ~S5PCSIS_DPHYCTRL_ENABLE;
- s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
-}
-
-/* Called with the state.lock mutex held */
-static void __s5pcsis_set_format(struct csis_state *state)
-{
- struct v4l2_mbus_framefmt *mf = &state->format;
- u32 val;
-
- v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
- mf->code, mf->width, mf->height);
-
- /* Color format */
- val = s5pcsis_read(state, S5PCSIS_CONFIG);
- val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
- s5pcsis_write(state, S5PCSIS_CONFIG, val);
-
- /* Pixel resolution */
- val = (mf->width << 16) | mf->height;
- s5pcsis_write(state, S5PCSIS_RESOL, val);
-}
-
-static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
-
- val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
- s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
-}
-
-static void s5pcsis_set_params(struct csis_state *state)
-{
- struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
- u32 val;
-
- val = s5pcsis_read(state, S5PCSIS_CONFIG);
- val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
- s5pcsis_write(state, S5PCSIS_CONFIG, val);
-
- __s5pcsis_set_format(state);
- s5pcsis_set_hsync_settle(state, pdata->hs_settle);
-
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- if (pdata->alignment == 32)
- val |= S5PCSIS_CTRL_ALIGN_32BIT;
- else /* 24-bits */
- val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
- /* Not using external clock. */
- val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
- s5pcsis_write(state, S5PCSIS_CTRL, val);
-
- /* Update the shadow register. */
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
-}
-
-static void s5pcsis_clk_put(struct csis_state *state)
-{
- int i;
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
- if (IS_ERR_OR_NULL(state->clock[i]))
- continue;
- clk_unprepare(state->clock[i]);
- clk_put(state->clock[i]);
- state->clock[i] = NULL;
- }
-}
-
-static int s5pcsis_clk_get(struct csis_state *state)
-{
- struct device *dev = &state->pdev->dev;
- int i, ret;
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
- state->clock[i] = clk_get(dev, csi_clock_name[i]);
- if (IS_ERR(state->clock[i]))
- goto err;
- ret = clk_prepare(state->clock[i]);
- if (ret < 0) {
- clk_put(state->clock[i]);
- state->clock[i] = NULL;
- goto err;
- }
- }
- return 0;
-err:
- s5pcsis_clk_put(state);
- dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
- return -ENXIO;
-}
-
-static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct device *dev = &state->pdev->dev;
-
- if (on)
- return pm_runtime_get_sync(dev);
-
- return pm_runtime_put_sync(dev);
-}
-
-static void s5pcsis_start_stream(struct csis_state *state)
-{
- s5pcsis_reset(state);
- s5pcsis_set_params(state);
- s5pcsis_system_enable(state, true);
- s5pcsis_enable_interrupts(state, true);
-}
-
-static void s5pcsis_stop_stream(struct csis_state *state)
-{
- s5pcsis_enable_interrupts(state, false);
- s5pcsis_system_enable(state, false);
-}
-
-/* v4l2_subdev operations */
-static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
- __func__, enable, state->flags);
-
- if (enable) {
- ret = pm_runtime_get_sync(&state->pdev->dev);
- if (ret && ret != 1)
- return ret;
- }
- mutex_lock(&state->lock);
- if (enable) {
- if (state->flags & ST_SUSPENDED) {
- ret = -EBUSY;
- goto unlock;
- }
- s5pcsis_start_stream(state);
- state->flags |= ST_STREAMING;
- } else {
- s5pcsis_stop_stream(state);
- state->flags &= ~ST_STREAMING;
- }
-unlock:
- mutex_unlock(&state->lock);
- if (!enable)
- pm_runtime_put(&state->pdev->dev);
-
- return ret == 1 ? 0 : ret;
-}
-
-static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index >= ARRAY_SIZE(s5pcsis_formats))
- return -EINVAL;
-
- code->code = s5pcsis_formats[code->index].code;
- return 0;
-}
-
-static struct csis_pix_format const *s5pcsis_try_format(
- struct v4l2_mbus_framefmt *mf)
-{
- struct csis_pix_format const *csis_fmt;
-
- csis_fmt = find_csis_format(mf);
- if (csis_fmt == NULL)
- csis_fmt = &s5pcsis_formats[0];
-
- mf->code = csis_fmt->code;
- v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
- csis_fmt->pix_width_alignment,
- &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
- 0);
- return csis_fmt;
-}
-
-static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
- struct csis_state *state, struct v4l2_subdev_fh *fh,
- u32 pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
-
- return &state->format;
-}
-
-static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct csis_pix_format const *csis_fmt;
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
- return -EINVAL;
-
- mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
-
- if (fmt->pad == CSIS_PAD_SOURCE) {
- if (mf) {
- mutex_lock(&state->lock);
- fmt->format = *mf;
- mutex_unlock(&state->lock);
- }
- return 0;
- }
- csis_fmt = s5pcsis_try_format(&fmt->format);
- if (mf) {
- mutex_lock(&state->lock);
- *mf = fmt->format;
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- state->csis_fmt = csis_fmt;
- mutex_unlock(&state->lock);
- }
- return 0;
-}
-
-static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
- return -EINVAL;
-
- mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
- if (!mf)
- return -EINVAL;
-
- mutex_lock(&state->lock);
- fmt->format = *mf;
- mutex_unlock(&state->lock);
- return 0;
-}
-
-static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
-
- format->colorspace = V4L2_COLORSPACE_JPEG;
- format->code = s5pcsis_formats[0].code;
- format->width = S5PCSIS_DEF_PIX_WIDTH;
- format->height = S5PCSIS_DEF_PIX_HEIGHT;
- format->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static const struct v4l2_subdev_internal_ops s5pcsis_sd_internal_ops = {
- .open = s5pcsis_open,
-};
-
-static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
- .s_power = s5pcsis_s_power,
-};
-
-static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
- .enum_mbus_code = s5pcsis_enum_mbus_code,
- .get_fmt = s5pcsis_get_fmt,
- .set_fmt = s5pcsis_set_fmt,
-};
-
-static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
- .s_stream = s5pcsis_s_stream,
-};
-
-static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
- .core = &s5pcsis_core_ops,
- .pad = &s5pcsis_pad_ops,
- .video = &s5pcsis_video_ops,
-};
-
-static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
-{
- struct csis_state *state = dev_id;
- u32 val;
-
- /* Just clear the interrupt pending bits. */
- val = s5pcsis_read(state, S5PCSIS_INTSRC);
- s5pcsis_write(state, S5PCSIS_INTSRC, val);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit s5pcsis_probe(struct platform_device *pdev)
-{
- struct s5p_platform_mipi_csis *pdata;
- struct resource *mem_res;
- struct csis_state *state;
- int ret = -ENOMEM;
- int i;
-
- state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
- if (!state)
- return -ENOMEM;
-
- mutex_init(&state->lock);
- state->pdev = pdev;
-
- pdata = pdev->dev.platform_data;
- if (pdata == NULL || pdata->phy_enable == NULL) {
- dev_err(&pdev->dev, "Platform data not fully specified\n");
- return -EINVAL;
- }
-
- if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
- pdata->lanes > CSIS0_MAX_LANES) {
- dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
- pdata->lanes);
- return -EINVAL;
- }
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- state->regs = devm_request_and_ioremap(&pdev->dev, mem_res);
- if (state->regs == NULL) {
- dev_err(&pdev->dev, "Failed to request and remap io memory\n");
- return -ENXIO;
- }
-
- state->irq = platform_get_irq(pdev, 0);
- if (state->irq < 0) {
- dev_err(&pdev->dev, "Failed to get irq\n");
- return state->irq;
- }
-
- for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
- state->supplies[i].supply = csis_supply_name[i];
-
- ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- return ret;
-
- ret = s5pcsis_clk_get(state);
- if (ret)
- goto e_clkput;
-
- clk_enable(state->clock[CSIS_CLK_MUX]);
- if (pdata->clk_rate)
- clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
- else
- dev_WARN(&pdev->dev, "No clock frequency specified!\n");
-
- ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
- 0, dev_name(&pdev->dev), state);
- if (ret) {
- dev_err(&pdev->dev, "Interrupt request failed\n");
- goto e_regput;
- }
-
- v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
- state->sd.owner = THIS_MODULE;
- strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
- state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- state->csis_fmt = &s5pcsis_formats[0];
-
- state->format.code = s5pcsis_formats[0].code;
- state->format.width = S5PCSIS_DEF_PIX_WIDTH;
- state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
-
- state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&state->sd.entity,
- CSIS_PADS_NUM, state->pads, 0);
- if (ret < 0)
- goto e_clkput;
-
- /* This allows to retrieve the platform device id by the host driver */
- v4l2_set_subdevdata(&state->sd, pdev);
-
- /* .. and a pointer to the subdev. */
- platform_set_drvdata(pdev, &state->sd);
-
- pm_runtime_enable(&pdev->dev);
- return 0;
-
-e_regput:
- regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
-e_clkput:
- clk_disable(state->clock[CSIS_CLK_MUX]);
- s5pcsis_clk_put(state);
- return ret;
-}
-
-static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
-{
- struct s5p_platform_mipi_csis *pdata = dev->platform_data;
- struct platform_device *pdev = to_platform_device(dev);
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
- __func__, state->flags);
-
- mutex_lock(&state->lock);
- if (state->flags & ST_POWERED) {
- s5pcsis_stop_stream(state);
- ret = pdata->phy_enable(state->pdev, false);
- if (ret)
- goto unlock;
- ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- goto unlock;
- clk_disable(state->clock[CSIS_CLK_GATE]);
- state->flags &= ~ST_POWERED;
- if (!runtime)
- state->flags |= ST_SUSPENDED;
- }
- unlock:
- mutex_unlock(&state->lock);
- return ret ? -EAGAIN : 0;
-}
-
-static int s5pcsis_pm_resume(struct device *dev, bool runtime)
-{
- struct s5p_platform_mipi_csis *pdata = dev->platform_data;
- struct platform_device *pdev = to_platform_device(dev);
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
- __func__, state->flags);
-
- mutex_lock(&state->lock);
- if (!runtime && !(state->flags & ST_SUSPENDED))
- goto unlock;
-
- if (!(state->flags & ST_POWERED)) {
- ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- goto unlock;
- ret = pdata->phy_enable(state->pdev, true);
- if (!ret) {
- state->flags |= ST_POWERED;
- } else {
- regulator_bulk_disable(CSIS_NUM_SUPPLIES,
- state->supplies);
- goto unlock;
- }
- clk_enable(state->clock[CSIS_CLK_GATE]);
- }
- if (state->flags & ST_STREAMING)
- s5pcsis_start_stream(state);
-
- state->flags &= ~ST_SUSPENDED;
- unlock:
- mutex_unlock(&state->lock);
- return ret ? -EAGAIN : 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int s5pcsis_suspend(struct device *dev)
-{
- return s5pcsis_pm_suspend(dev, false);
-}
-
-static int s5pcsis_resume(struct device *dev)
-{
- return s5pcsis_pm_resume(dev, false);
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int s5pcsis_runtime_suspend(struct device *dev)
-{
- return s5pcsis_pm_suspend(dev, true);
-}
-
-static int s5pcsis_runtime_resume(struct device *dev)
-{
- return s5pcsis_pm_resume(dev, true);
-}
-#endif
-
-static int __devexit s5pcsis_remove(struct platform_device *pdev)
-{
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
-
- pm_runtime_disable(&pdev->dev);
- s5pcsis_pm_suspend(&pdev->dev, false);
- clk_disable(state->clock[CSIS_CLK_MUX]);
- pm_runtime_set_suspended(&pdev->dev);
- s5pcsis_clk_put(state);
- regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
-
- media_entity_cleanup(&state->sd.entity);
-
- return 0;
-}
-
-static const struct dev_pm_ops s5pcsis_pm_ops = {
- SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
- NULL)
- SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
-};
-
-static struct platform_driver s5pcsis_driver = {
- .probe = s5pcsis_probe,
- .remove = __devexit_p(s5pcsis_remove),
- .driver = {
- .name = CSIS_DRIVER_NAME,
- .owner = THIS_MODULE,
- .pm = &s5pcsis_pm_ops,
- },
-};
-
-static int __init s5pcsis_init(void)
-{
- return platform_driver_probe(&s5pcsis_driver, s5pcsis_probe);
-}
-
-static void __exit s5pcsis_exit(void)
-{
- platform_driver_unregister(&s5pcsis_driver);
-}
-
-module_init(s5pcsis_init);
-module_exit(s5pcsis_exit);
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("S5P/EXYNOS4 MIPI CSI receiver driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.h b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.h
deleted file mode 100644
index 27092863..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/mipi-csis.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * 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.
- */
-#ifndef S5P_MIPI_CSIS_H_
-#define S5P_MIPI_CSIS_H_
-
-#define CSIS_DRIVER_NAME "s5p-mipi-csis"
-#define CSIS_MAX_ENTITIES 2
-#define CSIS0_MAX_LANES 4
-#define CSIS1_MAX_LANES 2
-
-#define CSIS_PAD_SINK 0
-#define CSIS_PAD_SOURCE 1
-#define CSIS_PADS_NUM 2
-
-#define S5PCSIS_DEF_PIX_WIDTH 640
-#define S5PCSIS_DEF_PIX_HEIGHT 480
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/regs-fimc.h b/ANDROID_3.4.5/drivers/media/video/s5p-fimc/regs-fimc.h
deleted file mode 100644
index c7a5bc51..00000000
--- a/ANDROID_3.4.5/drivers/media/video/s5p-fimc/regs-fimc.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Register definition file for Samsung Camera Interface (FIMC) driver
- *
- * Copyright (c) 2010 Samsung Electronics
- *
- * 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.
- */
-
-#ifndef REGS_FIMC_H_
-#define REGS_FIMC_H_
-
-/* Input source format */
-#define S5P_CISRCFMT 0x00
-#define S5P_CISRCFMT_ITU601_8BIT (1 << 31)
-#define S5P_CISRCFMT_ITU601_16BIT (1 << 29)
-#define S5P_CISRCFMT_ORDER422_YCBYCR (0 << 14)
-#define S5P_CISRCFMT_ORDER422_YCRYCB (1 << 14)
-#define S5P_CISRCFMT_ORDER422_CBYCRY (2 << 14)
-#define S5P_CISRCFMT_ORDER422_CRYCBY (3 << 14)
-#define S5P_CISRCFMT_HSIZE(x) ((x) << 16)
-#define S5P_CISRCFMT_VSIZE(x) ((x) << 0)
-
-/* Window offset */
-#define S5P_CIWDOFST 0x04
-#define S5P_CIWDOFST_OFF_EN (1 << 31)
-#define S5P_CIWDOFST_CLROVFIY (1 << 30)
-#define S5P_CIWDOFST_CLROVRLB (1 << 29)
-#define S5P_CIWDOFST_HOROFF_MASK (0x7ff << 16)
-#define S5P_CIWDOFST_CLROVFICB (1 << 15)
-#define S5P_CIWDOFST_CLROVFICR (1 << 14)
-#define S5P_CIWDOFST_HOROFF(x) ((x) << 16)
-#define S5P_CIWDOFST_VEROFF(x) ((x) << 0)
-#define S5P_CIWDOFST_VEROFF_MASK (0xfff << 0)
-
-/* Global control */
-#define S5P_CIGCTRL 0x08
-#define S5P_CIGCTRL_SWRST (1 << 31)
-#define S5P_CIGCTRL_CAMRST_A (1 << 30)
-#define S5P_CIGCTRL_SELCAM_ITU_A (1 << 29)
-#define S5P_CIGCTRL_TESTPAT_NORMAL (0 << 27)
-#define S5P_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27)
-#define S5P_CIGCTRL_TESTPAT_HOR_INC (2 << 27)
-#define S5P_CIGCTRL_TESTPAT_VER_INC (3 << 27)
-#define S5P_CIGCTRL_TESTPAT_MASK (3 << 27)
-#define S5P_CIGCTRL_TESTPAT_SHIFT (27)
-#define S5P_CIGCTRL_INVPOLPCLK (1 << 26)
-#define S5P_CIGCTRL_INVPOLVSYNC (1 << 25)
-#define S5P_CIGCTRL_INVPOLHREF (1 << 24)
-#define S5P_CIGCTRL_IRQ_OVFEN (1 << 22)
-#define S5P_CIGCTRL_HREF_MASK (1 << 21)
-#define S5P_CIGCTRL_IRQ_LEVEL (1 << 20)
-#define S5P_CIGCTRL_IRQ_CLR (1 << 19)
-#define S5P_CIGCTRL_IRQ_ENABLE (1 << 16)
-#define S5P_CIGCTRL_SHDW_DISABLE (1 << 12)
-#define S5P_CIGCTRL_CAM_JPEG (1 << 8)
-#define S5P_CIGCTRL_SELCAM_MIPI_A (1 << 7)
-#define S5P_CIGCTRL_CAMIF_SELWB (1 << 6)
-/* 0 - ITU601; 1 - ITU709 */
-#define S5P_CIGCTRL_CSC_ITU601_709 (1 << 5)
-#define S5P_CIGCTRL_INVPOLHSYNC (1 << 4)
-#define S5P_CIGCTRL_SELCAM_MIPI (1 << 3)
-#define S5P_CIGCTRL_INVPOLFIELD (1 << 1)
-#define S5P_CIGCTRL_INTERLACE (1 << 0)
-
-/* Window offset 2 */
-#define S5P_CIWDOFST2 0x14
-#define S5P_CIWDOFST2_HOROFF_MASK (0xfff << 16)
-#define S5P_CIWDOFST2_VEROFF_MASK (0xfff << 0)
-#define S5P_CIWDOFST2_HOROFF(x) ((x) << 16)
-#define S5P_CIWDOFST2_VEROFF(x) ((x) << 0)
-
-/* Output DMA Y/Cb/Cr plane start addresses */
-#define S5P_CIOYSA(n) (0x18 + (n) * 4)
-#define S5P_CIOCBSA(n) (0x28 + (n) * 4)
-#define S5P_CIOCRSA(n) (0x38 + (n) * 4)
-
-/* Target image format */
-#define S5P_CITRGFMT 0x48
-#define S5P_CITRGFMT_INROT90 (1 << 31)
-#define S5P_CITRGFMT_YCBCR420 (0 << 29)
-#define S5P_CITRGFMT_YCBCR422 (1 << 29)
-#define S5P_CITRGFMT_YCBCR422_1P (2 << 29)
-#define S5P_CITRGFMT_RGB (3 << 29)
-#define S5P_CITRGFMT_FMT_MASK (3 << 29)
-#define S5P_CITRGFMT_HSIZE_MASK (0xfff << 16)
-#define S5P_CITRGFMT_FLIP_SHIFT (14)
-#define S5P_CITRGFMT_FLIP_NORMAL (0 << 14)
-#define S5P_CITRGFMT_FLIP_X_MIRROR (1 << 14)
-#define S5P_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
-#define S5P_CITRGFMT_FLIP_180 (3 << 14)
-#define S5P_CITRGFMT_FLIP_MASK (3 << 14)
-#define S5P_CITRGFMT_OUTROT90 (1 << 13)
-#define S5P_CITRGFMT_VSIZE_MASK (0xfff << 0)
-#define S5P_CITRGFMT_HSIZE(x) ((x) << 16)
-#define S5P_CITRGFMT_VSIZE(x) ((x) << 0)
-
-/* Output DMA control */
-#define S5P_CIOCTRL 0x4c
-#define S5P_CIOCTRL_ORDER422_MASK (3 << 0)
-#define S5P_CIOCTRL_ORDER422_CRYCBY (0 << 0)
-#define S5P_CIOCTRL_ORDER422_CBYCRY (1 << 0)
-#define S5P_CIOCTRL_ORDER422_YCRYCB (2 << 0)
-#define S5P_CIOCTRL_ORDER422_YCBYCR (3 << 0)
-#define S5P_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
-#define S5P_CIOCTRL_YCBCR_3PLANE (0 << 3)
-#define S5P_CIOCTRL_YCBCR_2PLANE (1 << 3)
-#define S5P_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
-#define S5P_CIOCTRL_ALPHA_OUT_MASK (0xff << 4)
-#define S5P_CIOCTRL_RGB16FMT_MASK (3 << 16)
-#define S5P_CIOCTRL_RGB565 (0 << 16)
-#define S5P_CIOCTRL_ARGB1555 (1 << 16)
-#define S5P_CIOCTRL_ARGB4444 (2 << 16)
-#define S5P_CIOCTRL_ORDER2P_SHIFT (24)
-#define S5P_CIOCTRL_ORDER2P_MASK (3 << 24)
-#define S5P_CIOCTRL_ORDER422_2P_LSB_CRCB (0 << 24)
-
-/* Pre-scaler control 1 */
-#define S5P_CISCPRERATIO 0x50
-#define S5P_CISCPRERATIO_SHFACTOR(x) ((x) << 28)
-#define S5P_CISCPRERATIO_HOR(x) ((x) << 16)
-#define S5P_CISCPRERATIO_VER(x) ((x) << 0)
-
-#define S5P_CISCPREDST 0x54
-#define S5P_CISCPREDST_WIDTH(x) ((x) << 16)
-#define S5P_CISCPREDST_HEIGHT(x) ((x) << 0)
-
-/* Main scaler control */
-#define S5P_CISCCTRL 0x58
-#define S5P_CISCCTRL_SCALERBYPASS (1 << 31)
-#define S5P_CISCCTRL_SCALEUP_H (1 << 30)
-#define S5P_CISCCTRL_SCALEUP_V (1 << 29)
-#define S5P_CISCCTRL_CSCR2Y_WIDE (1 << 28)
-#define S5P_CISCCTRL_CSCY2R_WIDE (1 << 27)
-#define S5P_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
-#define S5P_CISCCTRL_INTERLACE (1 << 25)
-#define S5P_CISCCTRL_SCALERSTART (1 << 15)
-#define S5P_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
-#define S5P_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
-#define S5P_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
-#define S5P_CISCCTRL_INRGB_FMT_MASK (3 << 13)
-#define S5P_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
-#define S5P_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
-#define S5P_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
-#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
-#define S5P_CISCCTRL_RGB_EXT (1 << 10)
-#define S5P_CISCCTRL_ONE2ONE (1 << 9)
-#define S5P_CISCCTRL_MHRATIO(x) ((x) << 16)
-#define S5P_CISCCTRL_MVRATIO(x) ((x) << 0)
-#define S5P_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
-#define S5P_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
-#define S5P_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
-#define S5P_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
-
-/* Target area */
-#define S5P_CITAREA 0x5c
-#define S5P_CITAREA_MASK 0x0fffffff
-
-/* General status */
-#define S5P_CISTATUS 0x64
-#define S5P_CISTATUS_OVFIY (1 << 31)
-#define S5P_CISTATUS_OVFICB (1 << 30)
-#define S5P_CISTATUS_OVFICR (1 << 29)
-#define S5P_CISTATUS_VSYNC (1 << 28)
-#define S5P_CISTATUS_FRAMECNT_MASK (3 << 26)
-#define S5P_CISTATUS_FRAMECNT_SHIFT 26
-#define S5P_CISTATUS_WINOFF_EN (1 << 25)
-#define S5P_CISTATUS_IMGCPT_EN (1 << 22)
-#define S5P_CISTATUS_IMGCPT_SCEN (1 << 21)
-#define S5P_CISTATUS_VSYNC_A (1 << 20)
-#define S5P_CISTATUS_VSYNC_B (1 << 19)
-#define S5P_CISTATUS_OVRLB (1 << 18)
-#define S5P_CISTATUS_FRAME_END (1 << 17)
-#define S5P_CISTATUS_LASTCAPT_END (1 << 16)
-#define S5P_CISTATUS_VVALID_A (1 << 15)
-#define S5P_CISTATUS_VVALID_B (1 << 14)
-
-/* Indexes to the last and the currently processed buffer. */
-#define S5P_CISTATUS2 0x68
-
-/* Image capture control */
-#define S5P_CIIMGCPT 0xc0
-#define S5P_CIIMGCPT_IMGCPTEN (1 << 31)
-#define S5P_CIIMGCPT_IMGCPTEN_SC (1 << 30)
-#define S5P_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
-#define S5P_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
-
-/* Frame capture sequence */
-#define S5P_CICPTSEQ 0xc4
-
-/* Image effect */
-#define S5P_CIIMGEFF 0xd0
-#define S5P_CIIMGEFF_IE_ENABLE (1 << 30)
-#define S5P_CIIMGEFF_IE_SC_BEFORE (0 << 29)
-#define S5P_CIIMGEFF_IE_SC_AFTER (1 << 29)
-#define S5P_CIIMGEFF_FIN_BYPASS (0 << 26)
-#define S5P_CIIMGEFF_FIN_ARBITRARY (1 << 26)
-#define S5P_CIIMGEFF_FIN_NEGATIVE (2 << 26)
-#define S5P_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
-#define S5P_CIIMGEFF_FIN_EMBOSSING (4 << 26)
-#define S5P_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
-#define S5P_CIIMGEFF_FIN_MASK (7 << 26)
-#define S5P_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0))
-#define S5P_CIIMGEFF_PAT_CB(x) ((x) << 13)
-#define S5P_CIIMGEFF_PAT_CR(x) ((x) << 0)
-
-/* Input DMA Y/Cb/Cr plane start address 0/1 */
-#define S5P_CIIYSA(n) (0xd4 + (n) * 0x70)
-#define S5P_CIICBSA(n) (0xd8 + (n) * 0x70)
-#define S5P_CIICRSA(n) (0xdc + (n) * 0x70)
-
-/* Real input DMA image size */
-#define S5P_CIREAL_ISIZE 0xf8
-#define S5P_CIREAL_ISIZE_AUTOLOAD_EN (1 << 31)
-#define S5P_CIREAL_ISIZE_ADDR_CH_DIS (1 << 30)
-#define S5P_CIREAL_ISIZE_HEIGHT(x) ((x) << 16)
-#define S5P_CIREAL_ISIZE_WIDTH(x) ((x) << 0)
-
-
-/* Input DMA control */
-#define S5P_MSCTRL 0xfc
-#define S5P_MSCTRL_IN_BURST_COUNT_MASK (0xF << 24)
-#define S5P_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
-#define S5P_MSCTRL_2P_IN_ORDER_SHIFT 16
-#define S5P_MSCTRL_C_INT_IN_3PLANE (0 << 15)
-#define S5P_MSCTRL_C_INT_IN_2PLANE (1 << 15)
-#define S5P_MSCTRL_C_INT_IN_MASK (1 << 15)
-#define S5P_MSCTRL_FLIP_SHIFT 13
-#define S5P_MSCTRL_FLIP_MASK (3 << 13)
-#define S5P_MSCTRL_FLIP_NORMAL (0 << 13)
-#define S5P_MSCTRL_FLIP_X_MIRROR (1 << 13)
-#define S5P_MSCTRL_FLIP_Y_MIRROR (2 << 13)
-#define S5P_MSCTRL_FLIP_180 (3 << 13)
-#define S5P_MSCTRL_FIFO_CTRL_FULL (1 << 12)
-#define S5P_MSCTRL_ORDER422_SHIFT 4
-#define S5P_MSCTRL_ORDER422_YCBYCR (0 << 4)
-#define S5P_MSCTRL_ORDER422_CBYCRY (1 << 4)
-#define S5P_MSCTRL_ORDER422_YCRYCB (2 << 4)
-#define S5P_MSCTRL_ORDER422_CRYCBY (3 << 4)
-#define S5P_MSCTRL_ORDER422_MASK (3 << 4)
-#define S5P_MSCTRL_INPUT_EXTCAM (0 << 3)
-#define S5P_MSCTRL_INPUT_MEMORY (1 << 3)
-#define S5P_MSCTRL_INPUT_MASK (1 << 3)
-#define S5P_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
-#define S5P_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
-#define S5P_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1)
-#define S5P_MSCTRL_INFORMAT_RGB (3 << 1)
-#define S5P_MSCTRL_INFORMAT_MASK (3 << 1)
-#define S5P_MSCTRL_ENVID (1 << 0)
-#define S5P_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
-
-/* Output DMA Y/Cb/Cr offset */
-#define S5P_CIOYOFF 0x168
-#define S5P_CIOCBOFF 0x16c
-#define S5P_CIOCROFF 0x170
-
-/* Input DMA Y/Cb/Cr offset */
-#define S5P_CIIYOFF 0x174
-#define S5P_CIICBOFF 0x178
-#define S5P_CIICROFF 0x17c
-
-#define S5P_CIO_OFFS_VER(x) ((x) << 16)
-#define S5P_CIO_OFFS_HOR(x) ((x) << 0)
-
-/* Input DMA original image size */
-#define S5P_ORGISIZE 0x180
-
-/* Output DMA original image size */
-#define S5P_ORGOSIZE 0x184
-
-#define S5P_ORIG_SIZE_VER(x) ((x) << 16)
-#define S5P_ORIG_SIZE_HOR(x) ((x) << 0)
-
-/* Real output DMA image size (extension register) */
-#define S5P_CIEXTEN 0x188
-#define S5P_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
-#define S5P_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
-#define S5P_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
-#define S5P_CIEXTEN_MVRATIO_EXT_MASK 0x3f
-
-#define S5P_CIDMAPARAM 0x18c
-#define S5P_CIDMAPARAM_R_LINEAR (0 << 29)
-#define S5P_CIDMAPARAM_R_64X32 (3 << 29)
-#define S5P_CIDMAPARAM_W_LINEAR (0 << 13)
-#define S5P_CIDMAPARAM_W_64X32 (3 << 13)
-#define S5P_CIDMAPARAM_TILE_MASK ((3 << 29) | (3 << 13))
-
-/* MIPI CSI image format */
-#define S5P_CSIIMGFMT 0x194
-#define S5P_CSIIMGFMT_YCBCR422_8BIT 0x1e
-#define S5P_CSIIMGFMT_RAW8 0x2a
-#define S5P_CSIIMGFMT_RAW10 0x2b
-#define S5P_CSIIMGFMT_RAW12 0x2c
-/* User defined formats. x = 0...16. */
-#define S5P_CSIIMGFMT_USER(x) (0x30 + x - 1)
-
-/* Output frame buffer sequence mask */
-#define S5P_CIFCNTSEQ 0x1FC
-
-#endif /* REGS_FIMC_H_ */