summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorSandor Yu <R01008@freescale.com>2014-11-20 16:36:25 +0800
committerNitin Garg <nitin.garg@freescale.com>2015-04-14 14:01:02 -0500
commitdfcce3cdbab9985c4f970edc323c3a9b798e6920 (patch)
treee1ec9093a918d343f595a4d5286b8e848563986a /drivers/media
parentb9eb439a210f3fc323b6f4c586594fdcd746dfb8 (diff)
MLK-9779-05 csi: Remove csi driver source from mxc/capture folder
- Remove v4l2 csi capture driver, vadc driver and csi driver from mxc/capture folder. - Rename ov5640 module name from ov5640_camera.ko to ov5640_camera_int.ko Signed-off-by: Sandor Yu <R01008@freescale.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/mxc/capture/Kconfig13
-rw-r--r--drivers/media/platform/mxc/capture/Makefile9
-rw-r--r--drivers/media/platform/mxc/capture/csi_v4l2_capture.c2405
-rw-r--r--drivers/media/platform/mxc/capture/fsl_csi.c532
4 files changed, 2 insertions, 2957 deletions
diff --git a/drivers/media/platform/mxc/capture/Kconfig b/drivers/media/platform/mxc/capture/Kconfig
index a9e8f817f2b6..e8728d9dedeb 100644
--- a/drivers/media/platform/mxc/capture/Kconfig
+++ b/drivers/media/platform/mxc/capture/Kconfig
@@ -9,13 +9,6 @@ config VIDEO_MXC_IPU_CAMERA
depends on VIDEO_MXC_CAPTURE && MXC_IPU
default y
-config VIDEO_MXC_CSI_CAMERA
- tristate "CSI camera support"
- select VIDEO_V4L2_MXC_INT_DEVICE
- depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
- ---help---
- This is the video4linux2 capture driver based on CSI module.
-
config MXC_CAMERA_OV5640
tristate "OmniVision ov5640 camera support"
depends on !VIDEO_MXC_EMMA_CAMERA && I2C
@@ -40,12 +33,6 @@ config MXC_TVIN_ADV7180
---help---
If you plan to use the adv7180 video decoder with your MXC system, say Y here.
-config MXC_VADC
- tristate "mxc VADC support"
- depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
- ---help---
- If you plan to use the VADC with your MXC system, say Y here.
-
choice
prompt "Select Overlay Rounting"
default MXC_IPU_DEVICE_QUEUE_SDC
diff --git a/drivers/media/platform/mxc/capture/Makefile b/drivers/media/platform/mxc/capture/Makefile
index 12ed8a4abcf2..86854ba9354a 100644
--- a/drivers/media/platform/mxc/capture/Makefile
+++ b/drivers/media/platform/mxc/capture/Makefile
@@ -1,5 +1,3 @@
-obj-$(CONFIG_VIDEO_MXC_CSI_CAMERA) += fsl_csi.o csi_v4l2_capture.o
-
ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y)
obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc_v4l2_capture.o
obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o
@@ -8,8 +6,8 @@ ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y)
obj-$(CONFIG_MXC_IPU_CSI_ENC) += ipu_csi_enc.o ipu_still.o
endif
-ov5640_camera-objs := ov5640.o
-obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera.o
+ov5640_camera_int-objs := ov5640.o
+obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera_int.o
ov5642_camera-objs := ov5642.o
obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
@@ -20,7 +18,4 @@ obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
adv7180_tvin-objs := adv7180.o
obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
-mxc_vadc_tvin-objs := mxc_vadc.o
-obj-$(CONFIG_MXC_VADC) += mxc_vadc_tvin.o
-
obj-$(CONFIG_VIDEO_V4L2_MXC_INT_DEVICE) += v4l2-int-device.o
diff --git a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
deleted file mode 100644
index b000813a2f1c..000000000000
--- a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
+++ /dev/null
@@ -1,2405 +0,0 @@
-/*
- * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/*!
- * @file drivers/media/video/mxc/capture/csi_v4l2_capture.c
- * This file is derived from mxc_v4l2_capture.c
- *
- * @brief Video For Linux 2 capture driver
- *
- * @ingroup MXC_V4L2_CAPTURE
- */
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/semaphore.h>
-#include <linux/pagemap.h>
-#include <linux/vmalloc.h>
-#include <linux/types.h>
-#include <linux/fb.h>
-#include <linux/mxcfb.h>
-#include <linux/dma-mapping.h>
-#include <media/v4l2-ioctl.h>
-#include "v4l2-int-device.h"
-#include <media/v4l2-chip-ident.h>
-#include "mxc_v4l2_capture.h"
-#include "fsl_csi.h"
-
-static int video_nr = -1;
-static int req_buf_number;
-
-static int csi_v4l2_master_attach(struct v4l2_int_device *slave);
-static void csi_v4l2_master_detach(struct v4l2_int_device *slave);
-static u8 camera_power(cam_data *cam, bool cameraOn);
-
-/*! Information about this driver. */
-static struct v4l2_int_master csi_v4l2_master = {
- .attach = csi_v4l2_master_attach,
- .detach = csi_v4l2_master_detach,
-};
-
-static struct v4l2_queryctrl pxp_controls[] = {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Horizontal Flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vertical Flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_PRIVATE_BASE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Rotation",
- .minimum = 0,
- .maximum = 270,
- .step = 90,
- .default_value = 0,
- .flags = 0,
- },
-};
-
-/*! List of TV input video formats supported. The video formats is corresponding
- * to the v4l2_id in video_fmt_t.
- * Currently, only PAL and NTSC is supported. Needs to be expanded in the
- * future.
- */
-typedef enum _video_fmt_idx {
- TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
- TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */
- TV_NOT_LOCKED, /*!< Not locked on a signal. */
-} video_fmt_idx;
-
-/*! Number of video standards supported (including 'not locked' signal). */
-#define TV_STD_MAX (TV_NOT_LOCKED + 1)
-
-/*! Video format structure. */
-typedef struct _video_fmt_t {
- int v4l2_id; /*!< Video for linux ID. */
- char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
- u16 raw_width; /*!< Raw width. */
- u16 raw_height; /*!< Raw height. */
- u16 active_width; /*!< Active width. */
- u16 active_height; /*!< Active height. */
- u16 active_top; /*!< Active top. */
- u16 active_left; /*!< Active left. */
-} video_fmt_t;
-
-/*!
- * Description of video formats supported.
- *
- * PAL: raw=720x625, active=720x576.
- * NTSC: raw=720x525, active=720x480.
- */
-static video_fmt_t video_fmts[] = {
- { /*! NTSC */
- .v4l2_id = V4L2_STD_NTSC,
- .name = "NTSC",
- .raw_width = 720, /* SENS_FRM_WIDTH */
- .raw_height = 525, /* SENS_FRM_HEIGHT */
- .active_width = 720, /* ACT_FRM_WIDTH */
- .active_height = 480, /* ACT_FRM_HEIGHT */
- .active_top = 0,
- .active_left = 0,
- },
- { /*! (B, G, H, I, N) PAL */
- .v4l2_id = V4L2_STD_PAL,
- .name = "PAL",
- .raw_width = 720,
- .raw_height = 625,
- .active_width = 720,
- .active_height = 576,
- .active_top = 0,
- .active_left = 0,
- },
- { /*! Unlocked standard */
- .v4l2_id = V4L2_STD_ALL,
- .name = "Autodetect",
- .raw_width = 720,
- .raw_height = 625,
- .active_width = 720,
- .active_height = 576,
- .active_top = 0,
- .active_left = 0,
- },
-};
-
-#define CSI_V4L2_CAPTURE_NUM_INPUTS 2
-static struct v4l2_input csi_capture_inputs[CSI_V4L2_CAPTURE_NUM_INPUTS] = {
- {
- .index = 0,
- .name = "Camera",
- .type = V4L2_INPUT_TYPE_CAMERA,
- .audioset = 0,
- .tuner = 0,
- .std = V4L2_STD_UNKNOWN,
- .status = 0,
- },
- {
- .index = 1,
- .name = "Vadc",
- .type = V4L2_INPUT_TYPE_CAMERA,
- .audioset = 0,
- .tuner = 0,
- .std = V4L2_STD_UNKNOWN,
- .status = 0,
- },
-};
-
-/*!* Standard index of TV. */
-static video_fmt_idx video_index = TV_NOT_LOCKED;
-
-/* Callback function triggered after PxP receives an EOF interrupt */
-static void pxp_dma_done(void *arg)
-{
- struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
- struct dma_chan *chan = tx_desc->txd.chan;
- struct pxp_channel *pxp_chan = to_pxp_channel(chan);
- cam_data *cam = pxp_chan->client;
-
- /* This call will signal wait_for_completion_timeout() */
- complete(&cam->pxp_tx_cmpl);
-}
-
-static bool chan_filter(struct dma_chan *chan, void *arg)
-{
- if (imx_dma_is_pxp(chan))
- return true;
- else
- return false;
-}
-
-/* Function to request PXP DMA channel */
-static int pxp_chan_init(cam_data *cam)
-{
- dma_cap_mask_t mask;
- struct dma_chan *chan;
-
- /* Request a free channel */
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
- dma_cap_set(DMA_PRIVATE, mask);
- chan = dma_request_channel(mask, chan_filter, NULL);
- if (!chan) {
- pr_err("Unsuccessfully request channel!\n");
- return -EBUSY;
- }
-
- cam->pxp_chan = to_pxp_channel(chan);
- cam->pxp_chan->client = cam;
-
- init_completion(&cam->pxp_tx_cmpl);
-
- return 0;
-}
-
-static int v4l2_fmt_2_pxp_fmt(int fmt)
-{
- int ret;
- switch (fmt) {
- case V4L2_PIX_FMT_YUV420:
- ret = PXP_PIX_FMT_YUV420P2;
- break;
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YUV444:
- default:
- ret = fmt;
- break;
- }
- return ret;
-}
-/*
- * Function to call PxP DMA driver and send our new V4L2 buffer
- * through the PxP.
- * Note: This is a blocking call, so upon return the PxP tx should be complete.
- */
-static int pxp_process_update(cam_data *cam)
-{
- dma_cookie_t cookie;
- struct scatterlist *sg = cam->sg;
- struct dma_chan *dma_chan;
- struct pxp_tx_desc *desc;
- struct dma_async_tx_descriptor *txd;
- struct pxp_config_data *pxp_conf = &cam->pxp_conf;
- struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
- int i, ret;
- int length;
-
- pr_debug("Starting PxP Send Buffer\n");
-
- /* First, check to see that we have acquired a PxP Channel object */
- if (cam->pxp_chan == NULL) {
- /*
- * PxP Channel has not yet been created and initialized,
- * so let's go ahead and try
- */
- ret = pxp_chan_init(cam);
- if (ret) {
- /*
- * PxP channel init failed, and we can't use the
- * PxP until the PxP DMA driver has loaded, so we abort
- */
- pr_err("PxP chan init failed\n");
- return -ENODEV;
- }
- }
-
- /*
- * Init completion, so that we can be properly informed of
- * the completion of the PxP task when it is done.
- */
- init_completion(&cam->pxp_tx_cmpl);
-
- dma_chan = &cam->pxp_chan->dma_chan;
-
- txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
- DMA_TO_DEVICE,
- DMA_PREP_INTERRUPT,
- NULL);
- if (!txd) {
- pr_err("Error preparing a DMA transaction descriptor.\n");
- return -EIO;
- }
-
- txd->callback_param = txd;
- txd->callback = pxp_dma_done;
-
- /*
- * Configure PxP for processing of new v4l2 buf
- */
- pxp_conf->s0_param.pixel_fmt =
- v4l2_fmt_2_pxp_fmt(cam->input_fmt.fmt.pix.pixelformat);
- pxp_conf->s0_param.color_key = -1;
- pxp_conf->s0_param.color_key_enable = false;
- pxp_conf->s0_param.width = cam->input_fmt.fmt.pix.width;
- pxp_conf->s0_param.height = cam->input_fmt.fmt.pix.height;
-
- pxp_conf->ol_param[0].combine_enable = false;
-
- proc_data->srect.top = 0;
- proc_data->srect.left = 0;
- proc_data->srect.width = pxp_conf->s0_param.width;
- proc_data->srect.height = pxp_conf->s0_param.height;
-
- if (cam->crop_current.top != 0)
- proc_data->srect.top = cam->crop_current.top;
- if (cam->crop_current.left != 0)
- proc_data->srect.left = cam->crop_current.left;
- if (cam->crop_current.width != 0)
- proc_data->srect.width = cam->crop_current.width;
- if (cam->crop_current.height != 0)
- proc_data->srect.height = cam->crop_current.height;
-
- proc_data->drect.left = 0;
- proc_data->drect.top = 0;
- proc_data->drect.width = cam->v2f.fmt.pix.width;
- proc_data->drect.height = cam->v2f.fmt.pix.height;
-
- /* Out buffer */
- pxp_conf->out_param.pixel_fmt =
- v4l2_fmt_2_pxp_fmt(cam->v2f.fmt.pix.pixelformat);
- pxp_conf->out_param.width = proc_data->drect.width;
- pxp_conf->out_param.height = proc_data->drect.height;
-
- pr_debug("srect l: %d, t: %d, w: %d, h: %d; "
- "drect l: %d, t: %d, w: %d, h: %d\n",
- proc_data->srect.left, proc_data->srect.top,
- proc_data->srect.width, proc_data->srect.height,
- proc_data->drect.left, proc_data->drect.top,
- proc_data->drect.width, proc_data->drect.height);
-
- if (cam->rotation % 180)
- pxp_conf->out_param.stride = pxp_conf->out_param.height;
- else
- pxp_conf->out_param.stride = pxp_conf->out_param.width;
-
- desc = to_tx_desc(txd);
- length = desc->len;
- for (i = 0; i < length; i++) {
- if (i == 0) {/* S0 */
- memcpy(&desc->proc_data, proc_data,
- sizeof(struct pxp_proc_data));
- pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
- memcpy(&desc->layer_param.s0_param,
- &pxp_conf->s0_param,
- sizeof(struct pxp_layer_param));
- } else if (i == 1) {/* output */
- pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
- memcpy(&desc->layer_param.out_param,
- &pxp_conf->out_param,
- sizeof(struct pxp_layer_param));
- } else {/* overlay */
- memcpy(&desc->layer_param.ol_param,
- &pxp_conf->ol_param,
- sizeof(struct pxp_layer_param));
- }
-
- desc = desc->next;
- }
-
- /* Submitting our TX starts the PxP processing task */
- cookie = txd->tx_submit(txd);
- if (cookie < 0) {
- pr_err("Error sending FB through PxP\n");
- return -EIO;
- }
-
- cam->txd = txd;
-
- /* trigger PxP */
- dma_async_issue_pending(dma_chan);
-
- return 0;
-}
-
-static int pxp_complete_update(cam_data *cam)
-{
- int ret;
- /*
- * Wait for completion event, which will be set
- * through our TX callback function.
- */
- ret = wait_for_completion_timeout(&cam->pxp_tx_cmpl, HZ / 10);
- if (ret <= 0) {
- pr_warning("PxP operation failed due to %s\n",
- ret < 0 ? "user interrupt" : "timeout");
- dma_release_channel(&cam->pxp_chan->dma_chan);
- cam->pxp_chan = NULL;
- return ret ? : -ETIMEDOUT;
- }
-
- dma_release_channel(&cam->pxp_chan->dma_chan);
- cam->pxp_chan = NULL;
-
- pr_debug("TX completed\n");
-
- return 0;
-}
-
-/*!
- * Camera V4l2 callback function.
- *
- * @param mask u32
- * @param dev void device structure
- *
- * @return none
- */
-static void camera_callback(u32 mask, void *dev)
-{
- struct mxc_v4l_frame *done_frame;
- struct mxc_v4l_frame *ready_frame;
- cam_data *cam;
-
- cam = (cam_data *) dev;
- if (cam == NULL)
- return;
-
- spin_lock(&cam->queue_int_lock);
- spin_lock(&cam->dqueue_int_lock);
- if (!list_empty(&cam->working_q)) {
- done_frame = list_entry(cam->working_q.next,
- struct mxc_v4l_frame, queue);
-
- if (done_frame->csi_buf_num != cam->ping_pong_csi)
- goto next;
-
- if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
- done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
- done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
-
- /* Added to the done queue */
- list_del(cam->working_q.next);
- list_add_tail(&done_frame->queue, &cam->done_q);
- cam->enc_counter++;
- wake_up_interruptible(&cam->enc_queue);
- } else {
- pr_err("ERROR: v4l2 capture: %s: "
- "buffer not queued\n", __func__);
- }
- }
-
-next:
- if (!list_empty(&cam->ready_q)) {
- ready_frame = list_entry(cam->ready_q.next,
- struct mxc_v4l_frame, queue);
- list_del(cam->ready_q.next);
- list_add_tail(&ready_frame->queue, &cam->working_q);
-
- csi_write(cam->csi_soc, ready_frame->paddress,
- cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
- CSI_CSIDMASA_FB2);
- ready_frame->csi_buf_num = cam->ping_pong_csi;
- } else {
- csi_write(cam->csi_soc, cam->dummy_frame.paddress,
- cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
- CSI_CSIDMASA_FB2);
- }
- spin_unlock(&cam->dqueue_int_lock);
- spin_unlock(&cam->queue_int_lock);
-
- return;
-}
-
-/*!
- * Make csi ready for capture image.
- *
- * @param cam structure cam_data *
- *
- * @return status 0 success
- */
-static int csi_cap_image(cam_data *cam)
-{
- unsigned int value;
-
- value = csi_read(cam->csi_soc, CSI_CSICR3);
- csi_write(cam->csi_soc, value | BIT_FRMCNT_RST, CSI_CSICR3);
- value = csi_read(cam->csi_soc, CSI_CSISR);
- csi_write(cam->csi_soc, value, CSI_CSISR);
-
- return 0;
-}
-
-/***************************************************************************
- * Functions for handling Frame buffers.
- **************************************************************************/
-
-/*!
- * Free frame buffers
- *
- * @param cam Structure cam_data *
- *
- * @return status 0 success.
- */
-static int csi_free_frame_buf(cam_data *cam)
-{
- int i;
-
- pr_debug("MVC: In %s\n", __func__);
-
- for (i = 0; i < FRAME_NUM; i++) {
- if (cam->frame[i].vaddress != 0) {
- dma_free_coherent(0, cam->frame[i].buffer.length,
- cam->frame[i].vaddress,
- cam->frame[i].paddress);
- cam->frame[i].vaddress = 0;
- }
- }
-
- if (cam->dummy_frame.vaddress != 0) {
- dma_free_coherent(0, cam->dummy_frame.buffer.length,
- cam->dummy_frame.vaddress,
- cam->dummy_frame.paddress);
- cam->dummy_frame.vaddress = 0;
- }
-
- return 0;
-}
-
-/*!
- * Allocate frame buffers
- *
- * @param cam Structure cam_data *
- * @param count int number of buffer need to allocated
- *
- * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
- */
-static int csi_allocate_frame_buf(cam_data *cam, int count)
-{
- int i;
-
- pr_debug("In MVC:%s- size=%d\n",
- __func__, cam->v2f.fmt.pix.sizeimage);
- for (i = 0; i < count; i++) {
- cam->frame[i].vaddress = dma_alloc_coherent(0, PAGE_ALIGN
- (cam->v2f.fmt.
- pix.sizeimage),
- &cam->frame[i].
- paddress,
- GFP_DMA |
- GFP_KERNEL);
- if (cam->frame[i].vaddress == 0) {
- pr_err("ERROR: v4l2 capture: "
- "%s failed.\n", __func__);
- csi_free_frame_buf(cam);
- return -ENOBUFS;
- }
- cam->frame[i].buffer.index = i;
- cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
- cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cam->frame[i].buffer.length = cam->v2f.fmt.pix.sizeimage;
- cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
- cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
- cam->frame[i].index = i;
- cam->frame[i].csi_buf_num = 0;
- }
-
- return 0;
-}
-
-/*!
- * Free frame buffers status
- *
- * @param cam Structure cam_data *
- *
- * @return none
- */
-static void csi_free_frames(cam_data *cam)
-{
- int i;
-
- pr_debug("In MVC: %s\n", __func__);
-
- for (i = 0; i < FRAME_NUM; i++)
- cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
-
- cam->enc_counter = 0;
- INIT_LIST_HEAD(&cam->ready_q);
- INIT_LIST_HEAD(&cam->working_q);
- INIT_LIST_HEAD(&cam->done_q);
-
- return;
-}
-
-/*!
- * Return the buffer status
- *
- * @param cam Structure cam_data *
- * @param buf Structure v4l2_buffer *
- *
- * @return status 0 success, EINVAL failed.
- */
-static int csi_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
-{
- pr_debug("In MVC: %s\n", __func__);
-
- if (buf->index < 0 || buf->index >= FRAME_NUM) {
- pr_err("ERROR: v4l2 capture: %s buffers "
- "not allocated\n", __func__);
- return -EINVAL;
- }
-
- memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
-
- return 0;
-}
-
-static int csi_v4l2_release_bufs(cam_data *cam)
-{
- pr_debug("In MVC:csi_v4l2_release_bufs\n");
- return 0;
-}
-
-static int csi_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
-{
- pr_debug("In MVC:csi_v4l2_prepare_bufs\n");
-
- if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
- cam->v2f.fmt.pix.sizeimage) {
- pr_err("ERROR: v4l2 capture: csi_v4l2_prepare_bufs buffers "
- "not allocated,index=%d, length=%d\n", buf->index,
- buf->length);
- return -EINVAL;
- }
-
- cam->frame[buf->index].buffer.index = buf->index;
- cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
- cam->frame[buf->index].buffer.length = buf->length;
- cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
- = buf->m.offset;
- cam->frame[buf->index].buffer.type = buf->type;
- cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
- cam->frame[buf->index].index = buf->index;
-
- return 0;
-}
-
-/*!
- * Indicates whether the palette is supported.
- *
- * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_UYVY or V4L2_PIX_FMT_YUV420
- *
- * @return 0 if failed
- */
-static inline int valid_mode(u32 palette)
-{
- return (palette == V4L2_PIX_FMT_RGB565) ||
- (palette == V4L2_PIX_FMT_YUYV) ||
- (palette == V4L2_PIX_FMT_RGB32) ||
- (palette == V4L2_PIX_FMT_UYVY) ||
- (palette == V4L2_PIX_FMT_YUV444) ||
- (palette == V4L2_PIX_FMT_YUV420);
-}
-
-/*!
- * Start stream I/O
- *
- * @param cam structure cam_data *
- *
- * @return status 0 Success
- */
-static int csi_streamon(cam_data *cam)
-{
- struct mxc_v4l_frame *frame;
- unsigned long flags;
- unsigned long val;
- int timeout, timeout2;
-
- pr_debug("In MVC: %s\n", __func__);
-
- if (NULL == cam) {
- pr_err("ERROR: v4l2 capture: %s cam parameter is NULL\n",
- __func__);
- return -1;
- }
- cam->dummy_frame.vaddress = dma_alloc_coherent(0,
- PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
- &cam->dummy_frame.paddress,
- GFP_DMA | GFP_KERNEL);
- if (cam->dummy_frame.vaddress == 0) {
- pr_err("ERROR: v4l2 capture: Allocate dummy frame "
- "failed.\n");
- return -ENOBUFS;
- }
- cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
- cam->dummy_frame.buffer.length = cam->v2f.fmt.pix.sizeimage;
- cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
-
- spin_lock_irqsave(&cam->queue_int_lock, flags);
- /* move the frame from readyq to workingq */
- if (list_empty(&cam->ready_q)) {
- pr_err("ERROR: v4l2 capture: %s: "
- "ready_q queue empty\n", __func__);
- spin_unlock_irqrestore(&cam->queue_int_lock, flags);
- return -1;
- }
- frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
- list_del(cam->ready_q.next);
- list_add_tail(&frame->queue, &cam->working_q);
- csi_write(cam->csi_soc, frame->paddress, CSI_CSIDMASA_FB1);
- frame->csi_buf_num = 1;
-
- if (list_empty(&cam->ready_q)) {
- pr_err("ERROR: v4l2 capture: %s: "
- "ready_q queue empty\n", __func__);
- spin_unlock_irqrestore(&cam->queue_int_lock, flags);
- return -1;
- }
- frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
- list_del(cam->ready_q.next);
- list_add_tail(&frame->queue, &cam->working_q);
- csi_write(cam->csi_soc, frame->paddress, CSI_CSIDMASA_FB2);
- frame->csi_buf_num = 2;
- spin_unlock_irqrestore(&cam->queue_int_lock, flags);
-
- cam->capture_pid = current->pid;
- cam->capture_on = true;
- csi_cap_image(cam);
-
- local_irq_save(flags);
- for (timeout = 1000000; timeout > 0; timeout--) {
- if (csi_read(cam->csi_soc, CSI_CSISR) & BIT_SOF_INT) {
- val = csi_read(cam->csi_soc, CSI_CSICR3);
- csi_write(cam->csi_soc, val | BIT_DMA_REFLASH_RFF,
- CSI_CSICR3);
- /* Wait DMA reflash done */
- for (timeout2 = 1000000; timeout2 > 0; timeout2--) {
- if (csi_read(cam->csi_soc, CSI_CSICR3) &
- BIT_DMA_REFLASH_RFF)
- cpu_relax();
- else
- break;
- }
- if (timeout2 <= 0) {
- pr_err("timeout when wait for reflash done.\n");
- local_irq_restore(flags);
- return -ETIME;
- }
-
- csi_dmareq_rff_enable(cam->csi_soc);
- csi_enable_int(cam, 1);
- csi_enable(cam, 1);
- break;
- } else
- cpu_relax();
- }
- if (timeout <= 0) {
- pr_err("timeout when wait for SOF\n");
- local_irq_restore(flags);
- return -ETIME;
- }
- local_irq_restore(flags);
-
- return 0;
-}
-
-/*!
- * Stop stream I/O
- *
- * @param cam structure cam_data *
- *
- * @return status 0 Success
- */
-static int csi_streamoff(cam_data *cam)
-{
- pr_debug("In MVC: %s\n", __func__);
-
- if (cam->capture_on == false)
- return 0;
-
- csi_dmareq_rff_disable(cam->csi_soc);
- csi_disable_int(cam);
- cam->capture_on = false;
-
- /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
- csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB1);
- csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB2);
-
- if (strcmp(csi_capture_inputs[cam->current_input].name,
- "Vadc") == 0) {
- csi_buf_stride_set(cam, 0);
- csi_deinterlace_enable(cam, false);
- csi_tvdec_enable(cam, false);
- }
- csi_enable(cam, 0);
-
- csi_free_frames(cam);
- csi_free_frame_buf(cam);
-
- return 0;
-}
-
-/*!
- * start the viewfinder job
- *
- * @param cam structure cam_data *
- *
- * @return status 0 Success
- */
-static int start_preview(cam_data *cam)
-{
- unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base;
-
- csi_write(cam->csi_soc, fb_addr, CSI_CSIDMASA_FB1);
- csi_write(cam->csi_soc, fb_addr, CSI_CSIDMASA_FB2);
- csi_write(cam->csi_soc,
- csi_read(cam->csi_soc, CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
- CSI_CSICR3);
-
- csi_enable_int(cam, 0);
-
- return 0;
-}
-
-/*!
- * shut down the viewfinder job
- *
- * @param cam structure cam_data *
- *
- * @return status 0 Success
- */
-static int stop_preview(cam_data *cam)
-{
- csi_disable_int(cam);
-
- /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
- csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB1);
- csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB2);
- csi_write(cam->csi_soc,
- csi_read(cam->csi_soc, CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
- CSI_CSICR3);
-
- return 0;
-}
-
-/***************************************************************************
- * VIDIOC Functions.
- **************************************************************************/
-
-/*!
- *
- * @param cam structure cam_data *
- *
- * @param f structure v4l2_format *
- *
- * @return status 0 success, EINVAL failed
- */
-static int csi_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
-{
- int retval = 0;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
- f->fmt.pix = cam->v2f.fmt.pix;
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
- f->fmt.win = cam->win;
- break;
- default:
- pr_debug(" type is invalid\n");
- retval = -EINVAL;
- }
-
- pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
- __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
-
- return retval;
-}
-
-/*!
- * V4L2 - csi_v4l2_s_fmt function
- *
- * @param cam structure cam_data *
- *
- * @param f structure v4l2_format *
- *
- * @return status 0 success, EINVAL failed
- */
-static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
-{
- int retval = 0;
- int size = 0;
- int bytesperline = 0;
- int *width, *height;
-
- pr_debug("In MVC: %s\n", __func__);
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
- if (!valid_mode(f->fmt.pix.pixelformat)) {
- pr_err("ERROR: v4l2 capture: %s: format "
- "not supported\n", __func__);
- return -EINVAL;
- }
-
- /* Handle case where size requested is larger than current
- * camera setting. */
- if ((f->fmt.pix.width > cam->crop_bounds.width)
- || (f->fmt.pix.height > cam->crop_bounds.height)) {
- /* Need the logic here, calling vidioc_s_param if
- * camera can change. */
- pr_debug("csi_v4l2_s_fmt size changed\n");
- }
- if (cam->rotation % 180) {
- height = &f->fmt.pix.width;
- width = &f->fmt.pix.height;
- } else {
- width = &f->fmt.pix.width;
- height = &f->fmt.pix.height;
- }
-
- if (*width == 0 || *height == 0) {
- pr_err("ERROR: csi v4l2 capture: width or height"
- " too small.\n");
- return -EINVAL;
- }
-
- if ((cam->crop_bounds.width / *width > 8) ||
- ((cam->crop_bounds.width / *width == 8) &&
- (cam->crop_bounds.width % *width))) {
- *width = cam->crop_bounds.width / 8;
- if (*width % 8)
- *width += 8 - *width % 8;
- pr_err("ERROR: v4l2 capture: width exceeds limit "
- "resize to %d.\n", *width);
- }
-
- if ((cam->crop_bounds.height / *height > 8) ||
- ((cam->crop_bounds.height / *height == 8) &&
- (cam->crop_bounds.height % *height))) {
- *height = cam->crop_bounds.height / 8;
- if (*height % 8)
- *height += 8 - *height % 8;
- pr_err("ERROR: v4l2 capture: height exceeds limit "
- "resize to %d.\n", *height);
- }
-
- /* disable swap function */
- csi_format_swap16(cam, false);
- cam->bswapenable = false;
-
- switch (f->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_RGB32:
- size = f->fmt.pix.width * f->fmt.pix.height * 4;
- bytesperline = f->fmt.pix.width * 4;
- break;
- case V4L2_PIX_FMT_RGB565:
- size = f->fmt.pix.width * f->fmt.pix.height * 2;
- bytesperline = f->fmt.pix.width * 2;
- break;
- case V4L2_PIX_FMT_YUV444:
- size = f->fmt.pix.width * f->fmt.pix.height * 4;
- bytesperline = f->fmt.pix.width * 4;
- break;
- case V4L2_PIX_FMT_UYVY:
- size = f->fmt.pix.width * f->fmt.pix.height * 2;
- bytesperline = f->fmt.pix.width * 2;
- if (cam->input_fmt.fmt.pix.pixelformat ==
- V4L2_PIX_FMT_YUYV) {
- csi_format_swap16(cam, true);
- cam->bswapenable = true;
- }
- break;
- case V4L2_PIX_FMT_YUYV:
- size = f->fmt.pix.width * f->fmt.pix.height * 2;
- bytesperline = f->fmt.pix.width * 2;
- if (cam->input_fmt.fmt.pix.pixelformat ==
- V4L2_PIX_FMT_UYVY) {
- csi_format_swap16(cam, true);
- cam->bswapenable = true;
- }
- break;
- case V4L2_PIX_FMT_YUV420:
- size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
- bytesperline = f->fmt.pix.width;
- break;
- case V4L2_PIX_FMT_YUV422P:
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_BGR24:
- case V4L2_PIX_FMT_BGR32:
- case V4L2_PIX_FMT_NV12:
- default:
- pr_debug(" case not supported\n");
- break;
- }
-
- if (f->fmt.pix.bytesperline < bytesperline)
- f->fmt.pix.bytesperline = bytesperline;
- else
- bytesperline = f->fmt.pix.bytesperline;
-
- if (f->fmt.pix.sizeimage < size)
- f->fmt.pix.sizeimage = size;
- else
- size = f->fmt.pix.sizeimage;
-
- if (cam->input_fmt.fmt.pix.sizeimage > f->fmt.pix.sizeimage)
- f->fmt.pix.sizeimage =
- cam->input_fmt.fmt.pix.sizeimage;
-
- cam->v2f.fmt.pix = f->fmt.pix;
-
- if (cam->v2f.fmt.pix.priv != 0) {
- if (copy_from_user(&cam->offset,
- (void *)cam->v2f.fmt.pix.priv,
- sizeof(cam->offset))) {
- retval = -EFAULT;
- break;
- }
- }
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
- cam->win = f->fmt.win;
-
- break;
- default:
- retval = -EINVAL;
- }
-
- pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
- __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
-
- return retval;
-}
-
-/*!
- * V4L2 - csi_v4l2_s_param function
- * Allows setting of capturemode and frame rate.
- *
- * @param cam structure cam_data *
- * @param parm structure v4l2_streamparm *
- *
- * @return status 0 success, EINVAL failed
- */
-static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
-{
- struct v4l2_ifparm ifparm;
- struct v4l2_format *f;
- struct v4l2_streamparm currentparm;
- int err = 0;
- int size = 0;
-
- pr_debug("In %s\n", __func__);
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- pr_err(KERN_ERR "%s invalid type\n", __func__);
- return -EINVAL;
- }
-
- /* Stop the viewfinder */
- if (cam->overlay_on == true)
- stop_preview(cam);
-
- currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- /* First check that this device can support the changes requested. */
- err = vidioc_int_g_parm(cam->sensor, &currentparm);
- if (err) {
- pr_err("%s: vidioc_int_g_parm returned an error %d\n",
- __func__, err);
- goto exit;
- }
-
- pr_debug(" Current capabilities are %x\n",
- currentparm.parm.capture.capability);
- pr_debug(" Current capturemode is %d change to %d\n",
- currentparm.parm.capture.capturemode,
- parm->parm.capture.capturemode);
- pr_debug(" Current framerate is %d change to %d\n",
- currentparm.parm.capture.timeperframe.denominator,
- parm->parm.capture.timeperframe.denominator);
-
- err = vidioc_int_s_parm(cam->sensor, parm);
- if (err) {
- pr_err("%s: vidioc_int_s_parm returned an error %d\n",
- __func__, err);
- goto exit;
- }
-
- vidioc_int_g_ifparm(cam->sensor, &ifparm);
- cam->input_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- vidioc_int_g_fmt_cap(cam->sensor, &cam->input_fmt);
-
- pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
- cam->input_fmt.fmt.pix.width, cam->input_fmt.fmt.pix.height);
-
- f = &cam->input_fmt;
- switch (f->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_YUV444:
- size = f->fmt.pix.width * f->fmt.pix.height * 4;
- csi_set_32bit_imagpara(cam,
- f->fmt.pix.width,
- f->fmt.pix.height);
- break;
- case V4L2_PIX_FMT_UYVY:
- size = f->fmt.pix.width * f->fmt.pix.height * 2;
- csi_set_16bit_imagpara(cam,
- f->fmt.pix.width,
- f->fmt.pix.height);
- break;
- case V4L2_PIX_FMT_YUYV:
- size = f->fmt.pix.width * f->fmt.pix.height * 2;
- csi_set_16bit_imagpara(cam,
- f->fmt.pix.width,
- f->fmt.pix.height);
- break;
- case V4L2_PIX_FMT_YUV420:
- size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
- csi_set_12bit_imagpara(cam,
- f->fmt.pix.width,
- f->fmt.pix.height);
- break;
- case V4L2_PIX_FMT_YUV422P:
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_BGR24:
- case V4L2_PIX_FMT_BGR32:
- case V4L2_PIX_FMT_RGB32:
- case V4L2_PIX_FMT_NV12:
- default:
- pr_debug(" case not supported\n");
- return -EINVAL;
- }
- f->fmt.pix.sizeimage = size;
-
- cam->crop_bounds.top = cam->crop_bounds.left = 0;
- cam->crop_bounds.width = cam->input_fmt.fmt.pix.width;
- cam->crop_bounds.height = cam->input_fmt.fmt.pix.height;
- cam->crop_current.width = cam->crop_bounds.width;
- cam->crop_current.height = cam->crop_bounds.height;
-
-exit:
- return err;
-}
-
-static int pxp_set_cstate(cam_data *cam, struct v4l2_control *vc)
-{
- struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
-
- if (vc->id == V4L2_CID_HFLIP) {
- proc_data->hflip = vc->value;
- } else if (vc->id == V4L2_CID_VFLIP) {
- proc_data->vflip = vc->value;
- } else if (vc->id == V4L2_CID_PRIVATE_BASE) {
- if (vc->value % 90)
- return -ERANGE;
- proc_data->rotate = vc->value;
- cam->rotation = vc->value;
- }
-
- return 0;
-}
-
-static int pxp_get_cstate(cam_data *cam, struct v4l2_control *vc)
-{
- struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
-
- if (vc->id == V4L2_CID_HFLIP)
- vc->value = proc_data->hflip;
- else if (vc->id == V4L2_CID_VFLIP)
- vc->value = proc_data->vflip;
- else if (vc->id == V4L2_CID_PRIVATE_BASE)
- vc->value = proc_data->rotate;
-
- return 0;
-}
-
-/*!
- * V4L2 - csi_v4l_s_std function
- *
- * Sets the TV standard to be used.
- *
- * @param cam structure cam_data *
- * @param parm structure v4l2_std_id *
- *
- * @return status 0 success, -EINVAL failed
- */
-static int csi_v4l_s_std(cam_data *cam, v4l2_std_id e)
-{
- pr_debug("In csi_v4l2_s_std %Lx\n", e);
-
- if (e == V4L2_STD_PAL) {
- pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL);
- cam->standard.id = V4L2_STD_PAL;
- video_index = TV_PAL;
- } else if (e == V4L2_STD_NTSC) {
- pr_debug(" Setting standard to NTSC %Lx\n",
- V4L2_STD_NTSC);
- /* Get rid of the white dot line in NTSC signal input */
- cam->standard.id = V4L2_STD_NTSC;
- video_index = TV_NTSC;
- } else {
- cam->standard.id = V4L2_STD_ALL;
- video_index = TV_NOT_LOCKED;
- pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
- e, V4L2_STD_PAL, V4L2_STD_NTSC);
- }
-
- cam->standard.index = video_index;
- strcpy(cam->standard.name, video_fmts[video_index].name);
-
- /* Enable csi PAL/NTSC deinterlace mode */
- csi_buf_stride_set(cam, video_fmts[video_index].active_width);
- csi_deinterlace_mode(cam, cam->standard.id);
- csi_deinterlace_enable(cam, true);
-
- /* crop will overwrite */
- cam->crop_bounds.width = video_fmts[video_index].active_width;
- cam->crop_bounds.height = video_fmts[video_index].active_height;
- cam->crop_current.width = video_fmts[video_index].active_width;
- cam->crop_current.height = video_fmts[video_index].active_height;
- cam->crop_current.top = video_fmts[video_index].active_top;
- cam->crop_current.left = video_fmts[video_index].active_left;
-
- return 0;
-}
-
-/*!
- * V4L2 - csi_v4l_g_std function
- *
- * Gets the TV standard from the TV input device.
- *
- * @param cam structure cam_data *
- *
- * @param e structure v4l2_std_id *
- *
- * @return status 0 success, -EINVAL failed
- */
-static int csi_v4l_g_std(cam_data *cam, v4l2_std_id *e)
-{
- struct v4l2_format tv_fmt;
-
- pr_debug("In csi_v4l2_g_std, cam->csi %d\n", cam->csi);
-
- if (cam->device_type == 1) {
- /* Use this function to get what the TV-In device detects the
- * format to be. pixelformat is used to return the std value
- * since the interface has no vidioc_g_std.*/
- tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
- vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
-
- /* If the TV-in automatically detects the standard, then if it
- * changes, the settings need to change. */
- if (cam->standard_autodetect) {
- if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
- pr_debug("csi_v4l2_g_std: "
- "Changing standard\n");
- csi_v4l_s_std(cam, tv_fmt.fmt.pix.pixelformat);
- }
- }
-
- *e = tv_fmt.fmt.pix.pixelformat;
- }
-
- return 0;
-}
-
-static void csi_input_select(cam_data *cam)
-{
- if (strcmp(csi_capture_inputs[cam->current_input].name, "Vadc") == 0)
- /* Enable csi tvdec */
- csi_tvdec_enable(cam, true);
- else
- csi_tvdec_enable(cam, false);
-}
-
-/*!
- * Dequeue one V4L capture buffer
- *
- * @param cam structure cam_data *
- * @param buf structure v4l2_buffer *
- *
- * @return status 0 success, EINVAL invalid frame number
- * ETIME timeout, ERESTARTSYS interrupted by user
- */
-static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
-{
- int retval = 0;
- struct mxc_v4l_frame *frame;
- unsigned long lock_flags;
-
- if (!wait_event_interruptible_timeout(cam->enc_queue,
- cam->enc_counter != 0, 10 * HZ)) {
- pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
- "enc_counter %x\n", cam->enc_counter);
- return -ETIME;
- } else if (signal_pending(current)) {
- pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
- "interrupt received\n");
- return -ERESTARTSYS;
- }
-
- if (down_interruptible(&cam->busy_lock))
- return -EBUSY;
-
- spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
-
- if (list_empty(&cam->done_q)) {
- spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
- up(&cam->busy_lock);
- return -EINVAL;
- }
-
- cam->enc_counter--;
-
- frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
- list_del(cam->done_q.next);
-
- if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
- frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
- } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
- pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
- "Buffer not filled.\n");
- frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
- retval = -EINVAL;
- } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
- pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
- "Buffer not queued.\n");
- retval = -EINVAL;
- }
-
- spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
-
- buf->bytesused = cam->v2f.fmt.pix.sizeimage;
- buf->index = frame->index;
- buf->flags = frame->buffer.flags;
- buf->m = cam->frame[frame->index].buffer.m;
-
- /*
- * Note:
- * If want to do preview on LCD, use PxP CSC to convert from UYVY
- * to RGB565; but for encoding, usually we don't use RGB format.
- */
- if (cam->v2f.fmt.pix.pixelformat != cam->input_fmt.fmt.pix.pixelformat
- && !cam->bswapenable) {
- sg_dma_address(&cam->sg[0]) = buf->m.offset;
- /* last frame buffer as pxp output buffer */
- sg_dma_address(&cam->sg[1]) =
- cam->frame[req_buf_number].paddress;
- retval = pxp_process_update(cam);
- if (retval) {
- pr_err("Unable to submit PxP update task.\n");
- return retval;
- }
- pxp_complete_update(cam);
- /* Copy data from pxp output buffer to original buffer
- * Need optimization */
- if (cam->frame[buf->index].vaddress)
- memcpy(cam->frame[buf->index].vaddress,
- cam->frame[req_buf_number].vaddress,
- cam->v2f.fmt.pix.sizeimage);
- }
-
- up(&cam->busy_lock);
-
- return retval;
-}
-
-/*!
- * V4L interface - open function
- *
- * @param file structure file *
- *
- * @return status 0 success, ENODEV invalid device instance,
- * ENODEV timeout, ERESTARTSYS interrupted by user
- */
-static int csi_v4l_open(struct file *file)
-{
- struct v4l2_ifparm ifparm;
- struct v4l2_format cam_fmt;
- struct video_device *dev = video_devdata(file);
- cam_data *cam = video_get_drvdata(dev);
- struct sensor_data *sensor;
- int err = 0;
-
- pr_debug(" device name is %s\n", dev->name);
-
- if (!cam) {
- pr_err("%s: Internal error, cam_data not found!\n", __func__);
- return -EBADF;
- }
-
- if (!cam->sensor) {
- pr_err("%s: Internal error, camera is not found!\n", __func__);
- return -EBADF;
- }
-
- sensor = cam->sensor->priv;
- if (!sensor) {
- pr_err("%s: Internal error, sensor_data is not found!\n",
- __func__);
- return -EBADF;
- }
-
- down(&cam->busy_lock);
- err = 0;
- if (signal_pending(current))
- goto oops;
-
- if (cam->open_count++ == 0) {
- wait_event_interruptible(cam->power_queue,
- cam->low_power == false);
-
- cam->enc_counter = 0;
- INIT_LIST_HEAD(&cam->ready_q);
- INIT_LIST_HEAD(&cam->working_q);
- INIT_LIST_HEAD(&cam->done_q);
-
- vidioc_int_g_ifparm(cam->sensor, &ifparm);
-
- cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- csi_clk_enable();
- clk_prepare_enable(sensor->sensor_clk);
- vidioc_int_s_power(cam->sensor, 1);
- vidioc_int_init(cam->sensor);
- vidioc_int_dev_init(cam->sensor);
- }
-
- file->private_data = dev;
-
-oops:
- up(&cam->busy_lock);
- return err;
-}
-
-/*!
- * V4L interface - close function
- *
- * @param file struct file *
- *
- * @return 0 success
- */
-static int csi_v4l_close(struct file *file)
-{
- struct video_device *dev = video_devdata(file);
- int err = 0;
- cam_data *cam = video_get_drvdata(dev);
- struct sensor_data *sensor;
-
- pr_debug("In MVC:%s\n", __func__);
-
- if (!cam) {
- pr_err("%s: Internal error, cam_data not found!\n",
- __func__);
- return -EBADF;
- }
-
- if (!cam->sensor) {
- pr_err("%s: Internal error, camera is not found!\n",
- __func__);
- return -EBADF;
- }
-
- sensor = cam->sensor->priv;
- if (!sensor) {
- pr_err("%s: Internal error, sensor_data is not found!\n",
- __func__);
- return -EBADF;
- }
-
- /* for the case somebody hit the ctrl C */
- if (cam->overlay_pid == current->pid) {
- err = stop_preview(cam);
- cam->overlay_on = false;
- }
-
- if (--cam->open_count == 0) {
- wait_event_interruptible(cam->power_queue,
- cam->low_power == false);
- file->private_data = NULL;
- vidioc_int_s_power(cam->sensor, 0);
- clk_disable_unprepare(sensor->sensor_clk);
- }
-
- return err;
-}
-
-/*
- * V4L interface - read function
- *
- * @param file struct file *
- * @param read buf char *
- * @param count size_t
- * @param ppos structure loff_t *
- *
- * @return bytes read
- */
-static ssize_t csi_v4l_read(struct file *file, char *buf, size_t count,
- loff_t *ppos)
-{
- int err = 0;
- struct video_device *dev = video_devdata(file);
- cam_data *cam = video_get_drvdata(dev);
-
- if (down_interruptible(&cam->busy_lock))
- return -EINTR;
-
- /* Stop the viewfinder */
- if (cam->overlay_on == true)
- stop_preview(cam);
-
- if (cam->still_buf_vaddr == NULL) {
- cam->still_buf_vaddr = dma_alloc_coherent(0,
- PAGE_ALIGN
- (cam->v2f.fmt.
- pix.sizeimage),
- &cam->
- still_buf[0],
- GFP_DMA | GFP_KERNEL);
- if (cam->still_buf_vaddr == NULL) {
- pr_err("alloc dma memory failed\n");
- return -ENOMEM;
- }
- cam->still_counter = 0;
- csi_write(cam->csi_soc, cam->still_buf[0], CSI_CSIDMASA_FB2);
- csi_write(cam->csi_soc, cam->still_buf[0], CSI_CSIDMASA_FB1);
- csi_write(cam->csi_soc,
- csi_read(cam->csi_soc, CSI_CSICR3) |
- BIT_DMA_REFLASH_RFF,
- CSI_CSICR3);
- csi_write(cam->csi_soc, csi_read(cam->csi_soc, CSI_CSISR),
- CSI_CSISR);
- csi_write(cam->csi_soc,
- csi_read(cam->csi_soc, CSI_CSICR3) | BIT_FRMCNT_RST,
- CSI_CSICR3);
- csi_enable_int(cam, 1);
- csi_enable(cam, 1);
- }
-
- wait_event_interruptible(cam->still_queue, cam->still_counter);
- csi_disable_int(cam);
- err = copy_to_user(buf, cam->still_buf_vaddr,
- cam->v2f.fmt.pix.sizeimage);
-
- if (cam->still_buf_vaddr != NULL) {
- dma_free_coherent(0, PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
- cam->still_buf_vaddr, cam->still_buf[0]);
- cam->still_buf[0] = 0;
- cam->still_buf_vaddr = NULL;
- }
-
- if (cam->overlay_on == true)
- start_preview(cam);
-
- up(&cam->busy_lock);
- if (err < 0)
- return err;
-
- return cam->v2f.fmt.pix.sizeimage - err;
-}
-
-/*!
- * V4L interface - ioctl function
- *
- * @param file struct file*
- *
- * @param ioctlnr unsigned int
- *
- * @param arg void*
- *
- * @return 0 success, ENODEV for invalid device instance,
- * -1 for other errors.
- */
-static long csi_v4l_do_ioctl(struct file *file,
- unsigned int ioctlnr, void *arg)
-{
- struct video_device *dev = video_devdata(file);
- cam_data *cam = video_get_drvdata(dev);
- int retval = 0;
- unsigned long lock_flags;
-
- pr_debug("In MVC: %s, %x\n", __func__, ioctlnr);
- wait_event_interruptible(cam->power_queue, cam->low_power == false);
- /* make this _really_ smp-safe */
- if (ioctlnr != VIDIOC_DQBUF)
- if (down_interruptible(&cam->busy_lock))
- return -EBUSY;
-
- switch (ioctlnr) {
- /*!
- * V4l2 VIDIOC_G_FMT ioctl
- */
- case VIDIOC_G_FMT:{
- struct v4l2_format *gf = arg;
- pr_debug(" case VIDIOC_G_FMT\n");
- retval = csi_v4l2_g_fmt(cam, gf);
- break;
- }
-
- /*!
- * V4l2 VIDIOC_S_FMT ioctl
- */
- case VIDIOC_S_FMT:{
- struct v4l2_format *sf = arg;
- pr_debug(" case VIDIOC_S_FMT\n");
- retval = csi_v4l2_s_fmt(cam, sf);
- vidioc_int_s_fmt_cap(cam->sensor, sf);
- break;
- }
-
- /*!
- * V4l2 VIDIOC_OVERLAY ioctl
- */
- case VIDIOC_OVERLAY:{
- int *on = arg;
- pr_debug(" case VIDIOC_OVERLAY\n");
- if (*on) {
- cam->overlay_on = true;
- cam->overlay_pid = current->pid;
- start_preview(cam);
- }
- if (!*on) {
- stop_preview(cam);
- cam->overlay_on = false;
- }
- break;
- }
-
- /*!
- * V4l2 VIDIOC_G_FBUF ioctl
- */
- case VIDIOC_G_FBUF:{
- struct v4l2_framebuffer *fb = arg;
- *fb = cam->v4l2_fb;
- fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
- break;
- }
-
- /*!
- * V4l2 VIDIOC_S_FBUF ioctl
- */
- case VIDIOC_S_FBUF:{
- struct v4l2_framebuffer *fb = arg;
- cam->v4l2_fb = *fb;
- break;
- }
-
- case VIDIOC_G_PARM:{
- struct v4l2_streamparm *parm = arg;
- pr_debug(" case VIDIOC_G_PARM\n");
- vidioc_int_g_parm(cam->sensor, parm);
- break;
- }
-
- case VIDIOC_S_PARM:{
- struct v4l2_streamparm *parm = arg;
- pr_debug(" case VIDIOC_S_PARM\n");
- retval = csi_v4l2_s_param(cam, parm);
- break;
- }
-
- case VIDIOC_QUERYCAP:{
- struct v4l2_capability *cap = arg;
- pr_debug(" case VIDIOC_QUERYCAP\n");
- strcpy(cap->driver, "csi_v4l2");
- cap->version = KERNEL_VERSION(0, 1, 11);
- cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_READWRITE;
- cap->card[0] = '\0';
- cap->bus_info[0] = '\0';
- break;
- }
-
- case VIDIOC_CROPCAP:
- {
- struct v4l2_cropcap *cap = arg;
-
- if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
- retval = -EINVAL;
- break;
- }
- cap->bounds = cam->crop_bounds;
- cap->defrect = cam->crop_defrect;
- break;
- }
- case VIDIOC_S_CROP:
- {
- struct v4l2_crop *crop = arg;
- struct v4l2_rect *b = &cam->crop_bounds;
-
- pr_debug(" case VIDIOC_S_CROP\n");
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- retval = -EINVAL;
- break;
- }
-
- crop->c.top = (crop->c.top < b->top) ? b->top
- : crop->c.top;
- if (crop->c.top > b->top + b->height)
- crop->c.top = b->top + b->height - 1;
- if (crop->c.height > b->top + b->height - crop->c.top)
- crop->c.height =
- b->top + b->height - crop->c.top;
-
- crop->c.left = (crop->c.left < b->left) ? b->left
- : crop->c.left;
- if (crop->c.left > b->left + b->width)
- crop->c.left = b->left + b->width - 1;
- if (crop->c.width > b->left - crop->c.left + b->width)
- crop->c.width =
- b->left - crop->c.left + b->width;
-
- crop->c.width -= crop->c.width % 8;
- crop->c.height -= crop->c.height % 8;
-
- cam->crop_current = crop->c;
-
- break;
- }
- case VIDIOC_G_CROP:
- {
- struct v4l2_crop *crop = arg;
- pr_debug(" case VIDIOC_G_CROP\n");
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- retval = -EINVAL;
- break;
- }
- crop->c = cam->crop_current;
-
- break;
-
- }
- case VIDIOC_REQBUFS: {
- struct v4l2_requestbuffers *req = arg;
- pr_debug(" case VIDIOC_REQBUFS\n");
-
- if (req->count > FRAME_NUM) {
- pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
- "not enough buffers\n");
- req->count = FRAME_NUM;
- }
-
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
- "wrong buffer type\n");
- retval = -EINVAL;
- break;
- }
-
- csi_streamoff(cam);
- if (req->memory & V4L2_MEMORY_MMAP) {
- csi_free_frame_buf(cam);
- retval = csi_allocate_frame_buf(cam, req->count + 1);
- req_buf_number = req->count;
- }
- break;
- }
-
- case VIDIOC_QUERYBUF: {
- struct v4l2_buffer *buf = arg;
- int index = buf->index;
- pr_debug(" case VIDIOC_QUERYBUF\n");
-
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- retval = -EINVAL;
- break;
- }
-
- if (buf->memory & V4L2_MEMORY_MMAP) {
- memset(buf, 0, sizeof(buf));
- buf->index = index;
- }
-
- down(&cam->param_lock);
- if (buf->memory & V4L2_MEMORY_USERPTR) {
- csi_v4l2_release_bufs(cam);
- retval = csi_v4l2_prepare_bufs(cam, buf);
- }
- if (buf->memory & V4L2_MEMORY_MMAP)
- retval = csi_v4l2_buffer_status(cam, buf);
- up(&cam->param_lock);
- break;
- }
-
- case VIDIOC_QBUF: {
- struct v4l2_buffer *buf = arg;
- int index = buf->index;
- pr_debug(" case VIDIOC_QBUF\n");
-
- spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
- cam->frame[index].buffer.m.offset = buf->m.offset;
- if ((cam->frame[index].buffer.flags & 0x7) ==
- V4L2_BUF_FLAG_MAPPED) {
- cam->frame[index].buffer.flags |= V4L2_BUF_FLAG_QUEUED;
- list_add_tail(&cam->frame[index].queue, &cam->ready_q);
- } else if (cam->frame[index].buffer.flags &
- V4L2_BUF_FLAG_QUEUED) {
- pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
- "buffer already queued\n");
- retval = -EINVAL;
- } else if (cam->frame[index].buffer.
- flags & V4L2_BUF_FLAG_DONE) {
- pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
- "overwrite done buffer.\n");
- cam->frame[index].buffer.flags &=
- ~V4L2_BUF_FLAG_DONE;
- cam->frame[index].buffer.flags |=
- V4L2_BUF_FLAG_QUEUED;
- retval = -EINVAL;
- }
- buf->flags = cam->frame[index].buffer.flags;
- spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
-
- break;
- }
-
- case VIDIOC_DQBUF: {
- struct v4l2_buffer *buf = arg;
- pr_debug(" case VIDIOC_DQBUF\n");
-
- retval = csi_v4l_dqueue(cam, buf);
-
- break;
- }
-
- case VIDIOC_STREAMON: {
- pr_debug(" case VIDIOC_STREAMON\n");
- retval = csi_streamon(cam);
- break;
- }
-
- case VIDIOC_STREAMOFF: {
- pr_debug(" case VIDIOC_STREAMOFF\n");
- retval = csi_streamoff(cam);
- break;
- }
- case VIDIOC_ENUM_FMT: {
- struct v4l2_fmtdesc *fmt = arg;
- if (cam->sensor)
- retval = vidioc_int_enum_fmt_cap(cam->sensor, fmt);
- else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
- retval = -ENODEV;
- }
- break;
- }
- case VIDIOC_ENUM_FRAMESIZES: {
- struct v4l2_frmsizeenum *fsize = arg;
- if (cam->sensor)
- retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
- else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
- retval = -ENODEV;
- }
- break;
- }
- case VIDIOC_ENUM_FRAMEINTERVALS: {
- struct v4l2_frmivalenum *fival = arg;
- if (cam->sensor)
- retval = vidioc_int_enum_frameintervals(cam->sensor,
- fival);
- else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
- retval = -ENODEV;
- }
- break;
- }
- case VIDIOC_DBG_G_CHIP_IDENT: {
- struct v4l2_dbg_chip_ident *p = arg;
- p->ident = V4L2_IDENT_NONE;
- p->revision = 0;
- if (cam->sensor)
- retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
- else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
- retval = -ENODEV;
- }
- break;
- }
-
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
- if (vc->id == pxp_controls[i].id) {
- if (vc->value < pxp_controls[i].minimum ||
- vc->value > pxp_controls[i].maximum) {
- retval = -ERANGE;
- break;
- }
- retval = pxp_set_cstate(cam, vc);
- break;
- }
-
- if (i >= ARRAY_SIZE(pxp_controls))
- retval = -EINVAL;
- break;
-
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
- if (vc->id == pxp_controls[i].id) {
- retval = pxp_get_cstate(cam, vc);
- break;
- }
-
- if (i >= ARRAY_SIZE(pxp_controls))
- retval = -EINVAL;
- break;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
- if (qc->id && qc->id == pxp_controls[i].id) {
- memcpy(qc, &(pxp_controls[i]), sizeof(*qc));
- break;
- }
-
- if (i >= ARRAY_SIZE(pxp_controls))
- retval = -EINVAL;
- break;
- }
-
- case VIDIOC_G_STD: {
- v4l2_std_id *e = arg;
- pr_debug(" case VIDIOC_G_STD\n");
- if (cam->sensor) {
- retval = csi_v4l_g_std(cam, e);
- } else {
- pr_err("ERROR: v4l2 capture: slave not found!\n");
- retval = -ENODEV;
- }
- break;
- }
-
- case VIDIOC_S_STD: {
- v4l2_std_id *e = arg;
- pr_debug(" case VIDIOC_S_STD\n");
- retval = csi_v4l_s_std(cam, *e);
-
- break;
- }
-
- case VIDIOC_ENUMINPUT: {
- struct v4l2_input *input = arg;
- pr_debug(" case VIDIOC_ENUMINPUT\n");
- if (input->index >= CSI_V4L2_CAPTURE_NUM_INPUTS) {
- retval = -EINVAL;
- break;
- }
- *input = csi_capture_inputs[input->index];
- break;
- }
-
- case VIDIOC_G_INPUT: {
- int *index = arg;
- pr_debug(" case VIDIOC_G_INPUT\n");
- *index = cam->current_input;
- break;
- }
-
- case VIDIOC_S_INPUT: {
- int *index = arg;
- pr_debug(" case VIDIOC_S_INPUT\n");
- if (*index >= CSI_V4L2_CAPTURE_NUM_INPUTS) {
- retval = -EINVAL;
- break;
- }
-
- cam->current_input = *index;
-
- csi_input_select(cam);
- break;
- }
- case VIDIOC_G_OUTPUT:
- case VIDIOC_S_OUTPUT:
- case VIDIOC_ENUMSTD:
- case VIDIOC_TRY_FMT:
- case VIDIOC_G_TUNER:
- case VIDIOC_S_TUNER:
- case VIDIOC_G_FREQUENCY:
- case VIDIOC_S_FREQUENCY:
- case VIDIOC_ENUMOUTPUT:
- default:
- pr_debug(" case not supported\n");
- retval = -EINVAL;
- break;
- }
-
- if (ioctlnr != VIDIOC_DQBUF)
- up(&cam->busy_lock);
- return retval;
-}
-
-/*
- * V4L interface - ioctl function
- *
- * @return None
- */
-static long csi_v4l_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, csi_v4l_do_ioctl);
-}
-
-/*!
- * V4L interface - mmap function
- *
- * @param file structure file *
- *
- * @param vma structure vm_area_struct *
- *
- * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
- */
-static int csi_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *dev = video_devdata(file);
- unsigned long size;
- int res = 0;
- cam_data *cam = video_get_drvdata(dev);
-
- pr_debug("%s\n", __func__);
- pr_debug("\npgoff=0x%lx, start=0x%lx, end=0x%lx\n",
- vma->vm_pgoff, vma->vm_start, vma->vm_end);
-
- /* make this _really_ smp-safe */
- if (down_interruptible(&cam->busy_lock))
- return -EINTR;
-
- size = vma->vm_end - vma->vm_start;
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-
- if (remap_pfn_range(vma, vma->vm_start,
- vma->vm_pgoff, size, vma->vm_page_prot)) {
- pr_err("ERROR: v4l2 capture: %s : "
- "remap_pfn_range failed\n", __func__);
- res = -ENOBUFS;
- goto csi_mmap_exit;
- }
-
- vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
-
-csi_mmap_exit:
- up(&cam->busy_lock);
- return res;
-}
-
-/*!
- * This structure defines the functions to be called in this driver.
- */
-static struct v4l2_file_operations csi_v4l_fops = {
- .owner = THIS_MODULE,
- .open = csi_v4l_open,
- .release = csi_v4l_close,
- .read = csi_v4l_read,
- .ioctl = csi_v4l_ioctl,
- .mmap = csi_mmap,
-};
-
-static struct video_device csi_v4l_template = {
- .name = "Mx25 Camera",
- .fops = &csi_v4l_fops,
- .release = video_device_release,
-};
-
-/*!
- * initialize cam_data structure
- *
- * @param cam structure cam_data *
- *
- * @return status 0 Success
- */
-static void init_camera_struct(cam_data *cam, struct platform_device *pdev)
-{
- struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
- struct device_node *np = pdev->dev.of_node;
- int ret = 0;
- int csi_id;
- pr_debug("In MVC: %s\n", __func__);
-
- ret = of_property_read_u32(np, "csi_id", &csi_id);
- if (ret) {
- dev_err(&pdev->dev, "csi_id missing or invalid\n");
- return;
- }
-
- proc_data->hflip = 0;
- proc_data->vflip = 0;
- proc_data->rotate = 0;
- proc_data->bgcolor = 0;
-
- /* Default everything to 0 */
- memset(cam, 0, sizeof(cam_data));
-
- sema_init(&cam->param_lock, 1);
- sema_init(&cam->busy_lock, 1);
-
- /* TODO sanity check */
- cam->csi_soc = csi_get_soc(csi_id);
-
- cam->video_dev = video_device_alloc();
- if (cam->video_dev == NULL)
- return;
-
- *(cam->video_dev) = csi_v4l_template;
-
- video_set_drvdata(cam->video_dev, cam);
- cam->video_dev->minor = -1;
-
- init_waitqueue_head(&cam->enc_queue);
- init_waitqueue_head(&cam->still_queue);
-
- cam->streamparm.parm.capture.capturemode = 0;
-
- cam->standard.index = 0;
- cam->standard.id = V4L2_STD_UNKNOWN;
- cam->standard.frameperiod.denominator = 30;
- cam->standard.frameperiod.numerator = 1;
- cam->standard.framelines = 480;
- cam->standard_autodetect = true;
- cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
- cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- cam->overlay_on = false;
- cam->capture_on = false;
- cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
-
- cam->v2f.fmt.pix.sizeimage = 480 * 640 * 2;
- cam->v2f.fmt.pix.bytesperline = 640 * 2;
- cam->v2f.fmt.pix.width = 640;
- cam->v2f.fmt.pix.height = 480;
- cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
- cam->win.w.width = 160;
- cam->win.w.height = 160;
- cam->win.w.left = 0;
- cam->win.w.top = 0;
- cam->still_counter = 0;
- /* setup cropping */
- cam->crop_bounds.left = 0;
- cam->crop_bounds.width = 640;
- cam->crop_bounds.top = 0;
- cam->crop_bounds.height = 480;
- cam->crop_current = cam->crop_defrect = cam->crop_bounds;
-
- cam->csi = csi_id;
- cam->enc_callback = camera_callback;
- csi_start_callback(cam);
- init_waitqueue_head(&cam->power_queue);
- spin_lock_init(&cam->queue_int_lock);
- spin_lock_init(&cam->dqueue_int_lock);
-
- cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
- cam->self->module = THIS_MODULE;
- sprintf(cam->self->name, "csi_v4l2_cap%d", cam->csi);
- cam->self->type = v4l2_int_type_master;
- cam->self->u.master = &csi_v4l2_master;
-}
-
-/*!
- * camera_power function
- * Turns Sensor power On/Off
- *
- * @param cam cam data struct
- * @param cameraOn true to turn camera on, false to turn off power.
- *
- * @return status
- */
-static u8 camera_power(cam_data *cam, bool cameraOn)
-{
- pr_debug("In MVC: %s on=%d\n", __func__, cameraOn);
-
- if (cameraOn == true)
- vidioc_int_s_power(cam->sensor, 1);
- else
- vidioc_int_s_power(cam->sensor, 0);
- return 0;
-}
-
-static const struct of_device_id imx_csi_v4l2_dt_ids[] = {
- { .compatible = "fsl,imx6sl-csi-v4l2", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_csi_v4l2_dt_ids);
-
-static int csi_v4l2_probe(struct platform_device *pdev)
-{
- static cam_data *g_cam;
- struct scatterlist *sg;
- u8 err = 0;
-
- /* Create g_cam and initialize it. */
- g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
- if (g_cam == NULL) {
- pr_err("ERROR: v4l2 capture: failed to register camera\n");
- err = -ENOMEM;
- goto out;
- }
- memset(&g_cam->input_fmt, 0, sizeof(g_cam->input_fmt));
- init_camera_struct(g_cam, pdev);
- platform_set_drvdata(pdev, (void *)g_cam);
-
- /* Set up the v4l2 device and register it */
- g_cam->self->priv = g_cam;
- v4l2_int_device_register(g_cam->self);
-
- /* register v4l video device */
- if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
- == -1) {
- kfree(g_cam);
- g_cam = NULL;
- pr_err("ERROR: v4l2 capture: video_register_device failed\n");
- err = -ENODEV;
- goto out;
- }
- pr_debug(" Video device registered: %s #%d\n",
- g_cam->video_dev->name, g_cam->video_dev->minor);
-
- g_cam->pxp_chan = NULL;
- /* Initialize Scatter-gather list containing 2 buffer addresses. */
- sg = g_cam->sg;
- sg_init_table(sg, 2);
-
-out:
- return err;
-}
-
-static int csi_v4l2_remove(struct platform_device *pdev)
-{
- cam_data *g_cam = platform_get_drvdata(pdev);
-
- if (g_cam == NULL)
- return -EINVAL;
-
- if (g_cam->open_count) {
- pr_err("ERROR: v4l2 capture:camera open "
- "-- setting ops to NULL\n");
- } else {
- pr_info("V4L2 freeing image input device\n");
- v4l2_int_device_unregister(g_cam->self);
- csi_stop_callback(g_cam);
- video_unregister_device(g_cam->video_dev);
- platform_set_drvdata(pdev, NULL);
-
- kfree(g_cam);
- g_cam = NULL;
- }
-
- return 0;
-}
-
-/*!
- * This function is called to put the sensor in a low power state.
- * Refer to the document driver-model/driver.txt in the kernel source tree
- * for more information.
- *
- * @param pdev the device structure used to give information on which I2C
- * to suspend
- * @param state the power state the device is entering
- *
- * @return The function returns 0 on success and -1 on failure.
- */
-static int csi_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
-{
- cam_data *cam = platform_get_drvdata(pdev);
-
- pr_debug("In MVC: %s\n", __func__);
-
- if (cam == NULL)
- return -1;
-
- cam->low_power = true;
-
- if (cam->overlay_on == true)
- stop_preview(cam);
-
- if (cam->capture_on == true || cam->overlay_on == true)
- camera_power(cam, false);
-
- return 0;
-}
-
-/*!
- * This function is called to bring the sensor back from a low power state.
- * Refer to the document driver-model/driver.txt in the kernel source tree
- * for more information.
- *
- * @param pdev the device structure
- *
- * @return The function returns 0 on success and -1 on failure
- */
-static int csi_v4l2_resume(struct platform_device *pdev)
-{
- cam_data *cam = platform_get_drvdata(pdev);
-
- pr_debug("In MVC: %s\n", __func__);
-
- if (cam == NULL)
- return -1;
-
- cam->low_power = false;
- wake_up_interruptible(&cam->power_queue);
- if (cam->capture_on == true || cam->overlay_on == true)
- camera_power(cam, true);
-
- if (cam->overlay_on == true)
- start_preview(cam);
-
- return 0;
-}
-
-/*!
- * This structure contains pointers to the power management callback functions.
- */
-static struct platform_driver csi_v4l2_driver = {
- .driver = {
- .name = "csi_v4l2",
- .of_match_table = of_match_ptr(imx_csi_v4l2_dt_ids),
- },
- .probe = csi_v4l2_probe,
- .remove = csi_v4l2_remove,
-#ifdef CONFIG_PM
- .suspend = csi_v4l2_suspend,
- .resume = csi_v4l2_resume,
-#endif
- .shutdown = NULL,
-};
-
-/*!
- * Initializes the camera driver.
- */
-static int csi_v4l2_master_attach(struct v4l2_int_device *slave)
-{
- cam_data *cam = slave->u.slave->master->priv;
- struct sensor_data *sdata = slave->priv;
- struct v4l2_format cam_fmt;
-
- pr_debug("In MVC: %s\n", __func__);
- pr_debug(" slave.name = %s\n", slave->name);
- pr_debug(" master.name = %s\n", slave->u.slave->master->name);
-
- if (slave == NULL) {
- pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
- return -1;
- }
- if (sdata->csi != cam->csi) {
- pr_debug("%s: csi doesn't match\n", __func__);
- return -1;
- }
-
- cam->sensor = slave;
-
- cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
-
- /* Used to detect TV in (type 1) vs. camera (type 0) */
- cam->device_type = cam_fmt.fmt.pix.priv;
-
- cam->crop_bounds.top = cam->crop_bounds.left = 0;
- cam->crop_bounds.width = cam_fmt.fmt.pix.width;
- cam->crop_bounds.height = cam_fmt.fmt.pix.height;
-
- /* This also is the max crop size for this device. */
- cam->crop_defrect.top = cam->crop_defrect.left = 0;
- cam->crop_defrect.width = cam_fmt.fmt.pix.width;
- cam->crop_defrect.height = cam_fmt.fmt.pix.height;
-
- /* At this point, this is also the current image size. */
- cam->crop_current.top = cam->crop_current.left = 0;
- cam->crop_current.width = cam_fmt.fmt.pix.width;
- cam->crop_current.height = cam_fmt.fmt.pix.height;
-
- pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
- __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
-
- return 0;
-}
-
-/*!
- * Disconnects the camera driver.
- */
-static void csi_v4l2_master_detach(struct v4l2_int_device *slave)
-{
- pr_debug("In MVC: %s\n", __func__);
-
- vidioc_int_dev_exit(slave);
-}
-
-module_platform_driver(csi_v4l2_driver);
-
-module_param(video_nr, int, 0444);
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("V4L2 capture driver for Mx25 based cameras");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("video");
diff --git a/drivers/media/platform/mxc/capture/fsl_csi.c b/drivers/media/platform/mxc/capture/fsl_csi.c
deleted file mode 100644
index 721e6686fc59..000000000000
--- a/drivers/media/platform/mxc/capture/fsl_csi.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/*!
- * @file fsl_csi.c, this file is derived from mx27_csi.c
- *
- * @brief mx25 CMOS Sensor interface functions
- *
- * @ingroup CSI
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/of.h>
-#include <linux/sched.h>
-
-#include "mxc_v4l2_capture.h"
-#include "fsl_csi.h"
-
-#define CSI_MAX_NUM 2
-struct csi_soc csi_array[CSI_MAX_NUM], *csi;
-
-static csi_irq_callback_t g_callback;
-static void *g_callback_data;
-static struct clk *disp_axi_clk;
-static struct clk *dcic_clk;
-static struct clk *csi_clk;
-
-void csi_clk_enable(void)
-{
- clk_prepare_enable(disp_axi_clk);
- clk_prepare_enable(dcic_clk);
- clk_prepare_enable(csi_clk);
-}
-EXPORT_SYMBOL(csi_clk_enable);
-
-void csi_clk_disable(void)
-{
- clk_disable_unprepare(csi_clk);
- clk_disable_unprepare(dcic_clk);
- clk_disable_unprepare(disp_axi_clk);
-}
-EXPORT_SYMBOL(csi_clk_disable);
-
-static irqreturn_t csi_irq_handler(int irq, void *data)
-{
- cam_data *cam = (cam_data *) data;
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long status = __raw_readl(csi->regbase + CSI_CSISR);
- u32 cr3, cr18;
-
- __raw_writel(status, csi->regbase + CSI_CSISR);
-
- if (status & BIT_HRESP_ERR_INT)
- pr_warning("Hresponse error is detected.\n");
-
- if (status & BIT_ADDR_CH_ERR_INT) {
- /* Disable csi */
- cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
- cr18 &= ~BIT_CSI_ENABLE;
- __raw_writel(cr18, csi->regbase + CSI_CSICR18);
-
- /* DMA reflash */
- cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
- cr3 |= BIT_DMA_REFLASH_RFF;
- __raw_writel(cr3, csi->regbase + CSI_CSICR3);
-
- /* Ensable csi */
- cr18 |= BIT_CSI_ENABLE;
- __raw_writel(cr18, csi->regbase + CSI_CSICR18);
-
- pr_debug("base address switching Change Err.\n");
- }
-
- if ((status & BIT_DMA_TSF_DONE_FB1) &&
- (status & BIT_DMA_TSF_DONE_FB2)) {
- /* For both FB1 and FB2 interrupter bits set case,
- * CSI DMA is work in one of FB1 and FB2 buffer,
- * but software can not know the state.
- * Skip it to avoid base address updated
- * when csi work in field0 and field1 will write to
- * new base address.
- * PDM TKT230775 */
- pr_debug("Skip two frames\n");
- } else if (status & BIT_DMA_TSF_DONE_FB1) {
- if (cam->capture_on) {
- spin_lock(&cam->queue_int_lock);
- cam->ping_pong_csi = 1;
- spin_unlock(&cam->queue_int_lock);
- cam->enc_callback(0, cam);
- } else {
- cam->still_counter++;
- wake_up_interruptible(&cam->still_queue);
- }
- } else if (status & BIT_DMA_TSF_DONE_FB2) {
- if (cam->capture_on) {
- spin_lock(&cam->queue_int_lock);
- cam->ping_pong_csi = 2;
- spin_unlock(&cam->queue_int_lock);
- cam->enc_callback(0, cam);
- } else {
- cam->still_counter++;
- wake_up_interruptible(&cam->still_queue);
- }
- }
-
- if (g_callback)
- g_callback(g_callback_data, status);
-
- pr_debug("CSI status = 0x%08lX\n", status);
-
- return IRQ_HANDLED;
-}
-
-static void csihw_reset_frame_count(struct csi_soc *csi)
-{
- __raw_writel(__raw_readl(csi->regbase + CSI_CSICR3) | BIT_FRMCNT_RST,
- csi->regbase + CSI_CSICR3);
-}
-
-static void csihw_reset(struct csi_soc *csi)
-{
- csihw_reset_frame_count(csi);
- __raw_writel(CSICR1_RESET_VAL, csi->regbase + CSI_CSICR1);
- __raw_writel(CSICR2_RESET_VAL, csi->regbase + CSI_CSICR2);
- __raw_writel(CSICR3_RESET_VAL, csi->regbase + CSI_CSICR3);
-}
-
-/*!
- * csi_init_interface
- * Init csi interface
- */
-static void csi_init_interface(struct csi_soc *csi)
-{
- unsigned int val = 0;
- unsigned int imag_para;
-
- val |= BIT_SOF_POL;
- val |= BIT_REDGE;
- val |= BIT_GCLK_MODE;
- val |= BIT_HSYNC_POL;
- val |= BIT_FCC;
- val |= 1 << SHIFT_MCLKDIV;
- val |= BIT_MCLKEN;
- __raw_writel(val, csi->regbase + CSI_CSICR1);
-
- imag_para = (640 << 16) | 960;
- __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
-
- val = 0x1010;
- val |= BIT_DMA_REFLASH_RFF;
- __raw_writel(val, csi->regbase + CSI_CSICR3);
-}
-
-void csi_format_swap16(cam_data *cam, bool enable)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned int val;
-
- val = __raw_readl(csi->regbase + CSI_CSICR1);
- if (enable) {
- val |= BIT_PACK_DIR;
- val |= BIT_SWAP16_EN;
- } else {
- val &= ~BIT_PACK_DIR;
- val &= ~BIT_SWAP16_EN;
- }
-
- __raw_writel(val, csi->regbase + CSI_CSICR1);
-}
-EXPORT_SYMBOL(csi_format_swap16);
-
-/*!
- * csi_read_mclk_flag
- *
- * @return gcsi_mclk_source
- */
-int csi_read_mclk_flag(void)
-{
- return 0;
-}
-EXPORT_SYMBOL(csi_read_mclk_flag);
-
-void csi_start_callback(void *data)
-{
- cam_data *cam = (cam_data *) data;
-
- if (request_irq(csi_array[cam->csi].irq_nr, csi_irq_handler, 0, "csi",
- cam) < 0)
- pr_debug("CSI error: irq request fail\n");
-
-}
-EXPORT_SYMBOL(csi_start_callback);
-
-void csi_stop_callback(void *data)
-{
- cam_data *cam = (cam_data *) data;
-
- free_irq(csi_array[cam->csi].irq_nr, cam);
-}
-EXPORT_SYMBOL(csi_stop_callback);
-
-void csi_enable_int(cam_data *cam, int arg)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long cr1 = __raw_readl(csi->regbase + CSI_CSICR1);
-
- cr1 |= BIT_SOF_INTEN;
- if (arg == 1) {
- /* still capture needs DMA intterrupt */
- cr1 |= BIT_FB1_DMA_DONE_INTEN;
- cr1 |= BIT_FB2_DMA_DONE_INTEN;
- }
- __raw_writel(cr1, csi->regbase + CSI_CSICR1);
-}
-EXPORT_SYMBOL(csi_enable_int);
-
-void csi_disable_int(cam_data *cam)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long cr1 = __raw_readl(csi->regbase + CSI_CSICR1);
-
- cr1 &= ~BIT_SOF_INTEN;
- cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
- cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
- __raw_writel(cr1, csi->regbase + CSI_CSICR1);
-}
-EXPORT_SYMBOL(csi_disable_int);
-
-void csi_enable(cam_data *cam, int arg)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long cr = __raw_readl(csi->regbase + CSI_CSICR18);
-
- if (arg == 1)
- cr |= BIT_CSI_ENABLE;
- else
- cr &= ~BIT_CSI_ENABLE;
- __raw_writel(cr, csi->regbase + CSI_CSICR18);
-}
-EXPORT_SYMBOL(csi_enable);
-
-void csi_buf_stride_set(cam_data *cam, u32 stride)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
-
- __raw_writel(stride, csi->regbase + CSI_CSIFBUF_PARA);
-}
-EXPORT_SYMBOL(csi_buf_stride_set);
-
-void csi_deinterlace_enable(cam_data *cam, bool enable)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
-
- if (enable == true)
- cr18 |= BIT_DEINTERLACE_EN;
- else
- cr18 &= ~BIT_DEINTERLACE_EN;
-
- __raw_writel(cr18, csi->regbase + CSI_CSICR18);
-}
-EXPORT_SYMBOL(csi_deinterlace_enable);
-
-void csi_deinterlace_mode(cam_data *cam, int mode)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
-
- if (mode == V4L2_STD_NTSC)
- cr18 |= BIT_NTSC_EN;
- else
- cr18 &= ~BIT_NTSC_EN;
-
- __raw_writel(cr18, csi->regbase + CSI_CSICR18);
-}
-EXPORT_SYMBOL(csi_deinterlace_mode);
-
-void csi_tvdec_enable(cam_data *cam, bool enable)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- unsigned long cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
- unsigned long cr1 = __raw_readl(csi->regbase + CSI_CSICR1);
-
- if (enable == true) {
- cr18 |= (BIT_TVDECODER_IN_EN |
- BIT_BASEADDR_SWITCH_EN |
- BIT_BASEADDR_SWITCH_SEL |
- BIT_BASEADDR_CHG_ERR_EN);
- cr1 |= BIT_CCIR_MODE;
- cr1 &= ~(BIT_SOF_POL | BIT_REDGE);
- } else {
- cr18 &= ~(BIT_TVDECODER_IN_EN |
- BIT_BASEADDR_SWITCH_EN |
- BIT_BASEADDR_SWITCH_SEL |
- BIT_BASEADDR_CHG_ERR_EN);
- cr1 &= ~BIT_CCIR_MODE;
- cr1 |= BIT_SOF_POL | BIT_REDGE;
- }
-
- __raw_writel(cr18, csi->regbase + CSI_CSICR18);
- __raw_writel(cr1, csi->regbase + CSI_CSICR1);
-}
-EXPORT_SYMBOL(csi_tvdec_enable);
-
-void csi_set_32bit_imagpara(cam_data *cam, int width, int height)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- int imag_para = 0;
- unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
-
- imag_para = (width << 16) | height;
- __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
-
-
- /* reflash the embeded DMA controller */
- __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
-}
-EXPORT_SYMBOL(csi_set_32bit_imagpara);
-
-void csi_set_16bit_imagpara(cam_data *cam, int width, int height)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- int imag_para = 0;
- unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
-
- imag_para = (width << 16) | (height * 2);
- __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
-
- /* reflash the embeded DMA controller */
- __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
-}
-EXPORT_SYMBOL(csi_set_16bit_imagpara);
-
-void csi_set_12bit_imagpara(cam_data *cam, int width, int height)
-{
- struct csi_soc *csi = &csi_array[cam->csi];
- int imag_para = 0;
- unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
-
- imag_para = (width << 16) | (height * 3 / 2);
- __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
-
- /* reflash the embeded DMA controller */
- __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
-}
-EXPORT_SYMBOL(csi_set_12bit_imagpara);
-
-void csi_dmareq_rff_enable(struct csi_soc *csi)
-{
- unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
- unsigned long cr2 = __raw_readl(csi->regbase + CSI_CSICR2);
-
- /* Burst Type of DMA Transfer from RxFIFO. INCR16 */
- cr2 |= 0xC0000000;
-
- cr3 |= BIT_DMA_REQ_EN_RFF;
- cr3 |= BIT_HRESP_ERR_EN;
- cr3 &= ~BIT_RXFF_LEVEL;
- cr3 |= 0x2 << 4;
-
- __raw_writel(cr3, csi->regbase + CSI_CSICR3);
- __raw_writel(cr2, csi->regbase + CSI_CSICR2);
-}
-EXPORT_SYMBOL(csi_dmareq_rff_enable);
-
-void csi_dmareq_rff_disable(struct csi_soc *csi)
-{
- unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
-
- cr3 &= ~BIT_DMA_REQ_EN_RFF;
- cr3 &= ~BIT_HRESP_ERR_EN;
- __raw_writel(cr3, csi->regbase + CSI_CSICR3);
-}
-EXPORT_SYMBOL(csi_dmareq_rff_disable);
-
-struct csi_soc *csi_get_soc(int id)
-{
- if (id >= CSI_MAX_NUM)
- return ERR_PTR(-ENODEV);
- else if (!csi_array[id].online)
- return ERR_PTR(-ENODEV);
- else
- return &(csi_array[id]);
-}
-EXPORT_SYMBOL_GPL(csi_get_soc);
-
-static const struct of_device_id fsl_csi_dt_ids[] = {
- { .compatible = "fsl,imx6sl-csi", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, fsl_csi_dt_ids);
-
-static int csi_probe(struct platform_device *pdev)
-{
- int ret = 0;
- struct resource *res;
- int id;
-
- id = of_alias_get_id(pdev->dev.of_node, "csi");
- if (id < 0) {
- dev_dbg(&pdev->dev, "can not get alias id\n");
- return id;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev, "No csi irq found.\n");
- ret = -ENODEV;
- goto err;
- }
-
- csi = &csi_array[id];
- csi->irq_nr = res->start;
- csi->online = false;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "No csi base address found.\n");
- ret = -ENODEV;
- goto err;
- }
- csi->regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (!csi->regbase) {
- dev_err(&pdev->dev, "ioremap failed with csi base\n");
- ret = -ENOMEM;
- goto err;
- }
-
- disp_axi_clk = devm_clk_get(&pdev->dev, "disp-axi");
- if (IS_ERR(disp_axi_clk)) {
- dev_err(&pdev->dev, "get csi clock failed\n");
- return PTR_ERR(disp_axi_clk);
- }
- csi_clk = devm_clk_get(&pdev->dev, "csi_mclk");
- if (IS_ERR(csi_clk)) {
- dev_err(&pdev->dev, "get csi mclk failed\n");
- return PTR_ERR(csi_clk);
- }
-
- dcic_clk = devm_clk_get(&pdev->dev, "dcic");
- if (IS_ERR(dcic_clk)) {
- dev_err(&pdev->dev, "get dcic clk failed\n");
- return PTR_ERR(dcic_clk);
- }
-
- platform_set_drvdata(pdev, csi);
-
- csi_clk_enable();
- csihw_reset(csi);
- csi_init_interface(csi);
- csi_dmareq_rff_disable(csi);
-
- csi->online = true;
-err:
- return ret;
-}
-
-static int csi_remove(struct platform_device *pdev)
-{
- struct csi_soc *csi = platform_get_drvdata(pdev);
-
- csi->online = false;
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int csi_suspend(struct device *dev)
-{
- struct csi_soc *csi = dev_get_drvdata(dev);
-
- csi->online = false;
-
- return 0;
-}
-
-static int csi_resume(struct device *dev)
-{
- struct csi_soc *csi = dev_get_drvdata(dev);
-
- csi_clk_enable();
- csihw_reset(csi);
- csi_init_interface(csi);
- csi_dmareq_rff_disable(csi);
- csi_clk_disable();
-
- csi->online = true;
-
- return 0;
-}
-#else
-#define csi_suspend NULL
-#define csi_resume NULL
-#endif
-
-static const struct dev_pm_ops csi_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(csi_suspend, csi_resume)
-};
-
-static struct platform_driver csi_driver = {
- .driver = {
- .name = "fsl_csi",
- .of_match_table = of_match_ptr(fsl_csi_dt_ids),
- .pm = &csi_pm_ops,
- },
- .probe = csi_probe,
- .remove = csi_remove,
-};
-
-module_platform_driver(csi_driver);
-
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("fsl CSI driver");
-MODULE_LICENSE("GPL");