summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-moorestown-camera-driver-10.0-2-3.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-moorestown-camera-driver-10.0-2-3.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-moorestown-camera-driver-10.0-2-3.patch9779
1 files changed, 0 insertions, 9779 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-moorestown-camera-driver-10.0-2-3.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-moorestown-camera-driver-10.0-2-3.patch
deleted file mode 100644
index f3e8159eb..000000000
--- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-moorestown-camera-driver-10.0-2-3.patch
+++ /dev/null
@@ -1,9779 +0,0 @@
-From b5dc72f2a0bc509a241e03eea51e739204315f93 Mon Sep 17 00:00:00 2001
-From: Zheng Ba <zheng.ba@intel.com>
-Date: Thu, 1 Apr 2010 16:24:20 +0800
-Subject: [PATCH 2/3] Moorestown Camera Imaging driver Beta 10.0
-
-Patch-mainline: 2.6.35?
-
-Changes from Beta 9.0:
-1. Fixed hsd sighting
- 3469638 3469639 3469710 3469822 (high)
- 3469697 (medium)
-
-Changes from Beta 8.0:
-1. Fixed hsd sighting
- 3469056 3469058 (critical)
- 3469705 3469696 3469709 3469510 (medium)
-
-Changes from Beta 7.0:
-1. Fixed hsd sighting 3469681,3469682,3469683 (high)
-
-Changes from Beta 6.0:
-1. Fixed hsd sighting 3469668 (high)
-2. Fixed ov5630 v4l2 view-finding dark issue
-3. Enabled support for popular v4l2 applications (cheese, skype, ffmpeg)
-
-Changes from Beta 5.1:
-1. Fixed CRITICAL sighting 3469558 -- ciapp fails to launch with segment fault
-2. Fixed HIGH sighting 3479513 -- ov5630 AWB unstable
-3. Improved KMOT sensor 720p fps from 30 to 40
-
-Changes from Beta 5.0:
-Fixed a critical issue of camera driver not loading -- hsd 3469557
-
-Main changes from Beta 4.0:
-Fixed 4 HSD sightings: 3469392,3469099,3469470,3469500
-
-Main changes from Beta 3.0:
-Fixed 7 HSD sightings: 3469264,3469112,3469395,3469103,3469105,3469471,3469484
-
-Main changes from Beta 2.0:
-Fixed 6 HSD sightings: 3469047,3469315,3469317,3469101,3468409,3469391
-
-Main changes from Beta 1.1:
-1. Added interrupt mode for jpeg capture and KMOT viewfinding
-2. Fixed HSD sighting 3469228 and 3469147
-
-Main changes from Alpha2:
-Enabled MIPI interface in ISP driver and KMOT sensor s5k4e1.
-Enabled FIFO in ISP driver, which doubled the fps in view-finding mode.
-Enabled Subdev Framework in CI kernel driver.
-Enabled AF Continuous Mode.
-Enabled AE scene evaluation.
-
-Enabled the camera drivers in kernel:
-Device Drivers --> Multimedia support --> Video For Linux
-Device Drivers --> Mulitmedia support --> Video capture adapters -->
---> Moorestown Langwell Camera Imaging Subsystem support.
-
-Kernel configs:
-1. camera driver depends on GPIO library and I2C driver.
-CONFIG_GENERIC_GPIO=y
-CONFIG_I2C=y
-CONFIG_GPIOLIB=y
-2. camera driver depends on videobuf-core and videobuf-dma-contig.
-VIDEOBUF_GEN=y
-VIDEOBUF_DMA_CONTIG=y
-3. enable multimedia support and video capture.
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L2_COMMON=y
-CONFIG_VIDEO_MEDIA=y
-CONFIG_VIDEO_V4L2=y
-4. camera drivers incluing ISP, 5630, 5630-motor, s5k4e1, s5k4e1-motor, 2650,
-9665, flash.
-CONFIG_VIDEO_MRSTCI=y
-CONFIG_VIDEO_MRST_ISP=y
-CONFIG_VIDEO_MRST_OV5630=y
-CONFIG_VIDEO_MRST_OV5630_MOTOR=y
-CONFIG_VIDEO_MRST_S5K4E1=y
-CONFIG_VIDEO_MRST_S5K4E1_MOTOR=y
-CONFIG_VIDEO_MRST_FLASH=y
-CONFIG_VIDEO_MRST_OV2650=y
-CONFIG_VIDEO_MRST_OV9665=y
-
-Signed-off-by: Zheng Ba <zheng.ba@intel.com>
----
- drivers/media/video/mrstci/Kconfig | 26 +
- drivers/media/video/mrstci/Makefile | 8 +
- drivers/media/video/mrstci/mrstisp/Kconfig | 10 +
- drivers/media/video/mrstci/mrstisp/Makefile | 7 +
- .../video/mrstci/mrstisp/__mrstisp_private_ioctl.c | 324 +++
- drivers/media/video/mrstci/mrstisp/mrstisp_dp.c | 1301 +++++++++
- drivers/media/video/mrstci/mrstisp/mrstisp_hw.c | 1622 +++++++++++
- drivers/media/video/mrstci/mrstisp/mrstisp_isp.c | 1993 +++++++++++++
- drivers/media/video/mrstci/mrstisp/mrstisp_jpe.c | 569 ++++
- drivers/media/video/mrstci/mrstisp/mrstisp_main.c | 2977 ++++++++++++++++++++
- drivers/media/video/mrstci/mrstisp/mrstisp_mif.c | 763 +++++
- 11 files changed, 9600 insertions(+), 0 deletions(-)
- create mode 100644 drivers/media/video/mrstci/Kconfig
- create mode 100644 drivers/media/video/mrstci/Makefile
- create mode 100644 drivers/media/video/mrstci/mrstisp/Kconfig
- create mode 100644 drivers/media/video/mrstci/mrstisp/Makefile
- create mode 100644 drivers/media/video/mrstci/mrstisp/__mrstisp_private_ioctl.c
- create mode 100644 drivers/media/video/mrstci/mrstisp/mrstisp_dp.c
- create mode 100644 drivers/media/video/mrstci/mrstisp/mrstisp_hw.c
- create mode 100644 drivers/media/video/mrstci/mrstisp/mrstisp_isp.c
- create mode 100644 drivers/media/video/mrstci/mrstisp/mrstisp_jpe.c
- create mode 100644 drivers/media/video/mrstci/mrstisp/mrstisp_main.c
- create mode 100644 drivers/media/video/mrstci/mrstisp/mrstisp_mif.c
-
-diff --git a/drivers/media/video/mrstci/Kconfig b/drivers/media/video/mrstci/Kconfig
-new file mode 100644
-index 0000000..9ac7065
---- /dev/null
-+++ b/drivers/media/video/mrstci/Kconfig
-@@ -0,0 +1,26 @@
-+menuconfig VIDEO_MRSTCI
-+ bool "Moorestown Langwell Camera Imaging Subsystem support"
-+ depends on VIDEO_V4L2
-+ default y
-+
-+ ---help---
-+ Say Y here to enable selecting the Intel Moorestown Langwell Camera Imaging Subsystem for webcams.
-+
-+if VIDEO_MRSTCI && VIDEO_V4L2
-+
-+source "drivers/media/video/mrstci/mrstisp/Kconfig"
-+
-+source "drivers/media/video/mrstci/mrstov5630/Kconfig"
-+source "drivers/media/video/mrstci/mrstov5630_motor/Kconfig"
-+
-+source "drivers/media/video/mrstci/mrsts5k4e1/Kconfig"
-+source "drivers/media/video/mrstci/mrsts5k4e1_motor/Kconfig"
-+
-+source "drivers/media/video/mrstci/mrstflash/Kconfig"
-+
-+source "drivers/media/video/mrstci/mrstov2650/Kconfig"
-+
-+source "drivers/media/video/mrstci/mrstov9665/Kconfig"
-+
-+endif # VIDEO_MRSTCI
-+
-diff --git a/drivers/media/video/mrstci/Makefile b/drivers/media/video/mrstci/Makefile
-new file mode 100644
-index 0000000..9d3449e
---- /dev/null
-+++ b/drivers/media/video/mrstci/Makefile
-@@ -0,0 +1,8 @@
-+obj-$(CONFIG_VIDEO_MRST_OV2650) += mrstov2650/
-+obj-$(CONFIG_VIDEO_MRST_OV9665) += mrstov9665/
-+obj-$(CONFIG_VIDEO_MRST_OV5630) += mrstov5630/
-+obj-$(CONFIG_VIDEO_MRST_OV5630_MOTOR) += mrstov5630_motor/
-+obj-$(CONFIG_VIDEO_MRST_S5K4E1) += mrsts5k4e1/
-+obj-$(CONFIG_VIDEO_MRST_S5K4E1_MOTOR) += mrsts5k4e1_motor/
-+obj-$(CONFIG_VIDEO_MRST_FLASH) += mrstflash/
-+obj-$(CONFIG_VIDEO_MRST_ISP) += mrstisp/
-diff --git a/drivers/media/video/mrstci/mrstisp/Kconfig b/drivers/media/video/mrstci/mrstisp/Kconfig
-new file mode 100644
-index 0000000..8e58a87
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/Kconfig
-@@ -0,0 +1,10 @@
-+config VIDEO_MRST_ISP
-+ tristate "Moorstown Marvin - ISP Driver"
-+ depends on VIDEO_V4L2
-+ select VIDEOBUF_DMA_CONTIG
-+ default y
-+ ---help---
-+ Say Y here if you want support for cameras based on the Intel Moorestown platform.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called mrstisp.ko.
-diff --git a/drivers/media/video/mrstci/mrstisp/Makefile b/drivers/media/video/mrstci/mrstisp/Makefile
-new file mode 100644
-index 0000000..30f4e62
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/Makefile
-@@ -0,0 +1,7 @@
-+mrstisp-objs := mrstisp_main.o mrstisp_hw.o mrstisp_isp.o \
-+ mrstisp_dp.o mrstisp_mif.o mrstisp_jpe.o \
-+ __mrstisp_private_ioctl.o
-+
-+obj-$(CONFIG_VIDEO_MRST_ISP) += mrstisp.o
-+
-+EXTRA_CFLAGS += -I$(src)/../include -I$(src)/include
-diff --git a/drivers/media/video/mrstci/mrstisp/__mrstisp_private_ioctl.c b/drivers/media/video/mrstci/mrstisp/__mrstisp_private_ioctl.c
-new file mode 100644
-index 0000000..85cc482
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/__mrstisp_private_ioctl.c
-@@ -0,0 +1,324 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+
-+/*
-+static u32 copy_sensor_config_from_user(struct ci_sensor_config *des,
-+ struct ci_sensor_config *src)
-+{
-+ u32 ret = 0;
-+ ret = copy_from_user((void *)des, (const void *)src,
-+ sizeof(struct ci_sensor_config));
-+ if (ret)
-+ return -EFAULT;
-+ return ret;
-+}
-+
-+static u32 copy_sensor_caps_from_user(struct ci_sensor_caps *des,
-+ struct ci_sensor_caps *src)
-+{
-+ u32 ret = 0;
-+ ret = copy_from_user((void *)des, (const void *)src,
-+ sizeof(struct ci_sensor_caps));
-+ if (ret)
-+ return -EFAULT;
-+ return ret;
-+}
-+
-+static u32 copy_isp_config_from_user(struct ci_isp_config *des,
-+ struct ci_isp_config *src)
-+{
-+ int ret = 0;
-+ ret = copy_from_user((void *)des, (const void *)src,
-+ sizeof(struct ci_isp_config));
-+ if (ret) {
-+ eprintk("returning %d", ret);
-+ return ret;
-+ }
-+ return 0;
-+}
-+*/
-+
-+static void print_bls_cfg(struct ci_isp_config *isp_cfg)
-+{
-+ struct ci_isp_bls_config *bls_cfg = &isp_cfg->bls_cfg;
-+
-+ dprintk(4, "print_bls_cfg:");
-+ dprintk(4, "enable_automatic:%d", (bls_cfg->enable_automatic ? 1 : 0));
-+ dprintk(4, "disable_h:%d", (bls_cfg->disable_h ? 1 : 0));
-+ dprintk(4, "disable_v:%d", (bls_cfg->disable_v ? 1 : 0));
-+ dprintk(4, "enable_window1:%d",
-+ (bls_cfg->isp_bls_window1.enable_window ? 1 : 0));
-+ dprintk(4, "start_h:%d", (int)bls_cfg->isp_bls_window1.start_h);
-+ dprintk(4, "stop_h:%d", (int)bls_cfg->isp_bls_window1.stop_h);
-+ dprintk(4, "start_v:%d", (int)bls_cfg->isp_bls_window1.start_v);
-+ dprintk(4, "stop_v:%d", (int)bls_cfg->isp_bls_window1.stop_v);
-+ dprintk(4, "enable_window2: %d",
-+ (bls_cfg->isp_bls_window2.enable_window ? 1 : 0));
-+ dprintk(4, "start_h%d", (int)bls_cfg->isp_bls_window2.start_h);
-+ dprintk(4, "stop_h%d", (int)bls_cfg->isp_bls_window2.stop_h);
-+ dprintk(4, "start_v%d", (int)bls_cfg->isp_bls_window2.start_v);
-+ dprintk(4, "stop_v%d", (int)bls_cfg->isp_bls_window2.stop_v);
-+ dprintk(4, "bls_samples%d", (int)bls_cfg->bls_samples);
-+ dprintk(4, "fixed_a0x%02x", (int)bls_cfg->bls_subtraction.fixed_a);
-+ dprintk(4, "fixed_b0x%02x", (int)bls_cfg->bls_subtraction.fixed_b);
-+ dprintk(4, "fixed_c0x%02x", (int)bls_cfg->bls_subtraction.fixed_c);
-+ dprintk(4, "fixed_d0x%02x", (int)bls_cfg->bls_subtraction.fixed_d);
-+ dprintk(4, "\n");
-+}
-+
-+static int mrst_isp_set_cfg(struct file *file, void *priv,
-+ struct ci_pl_system_config *arg)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ if (arg == NULL) {
-+ eprintk("NULL pointer of arg");
-+ return 0;
-+ }
-+ mutex_lock(&isp->mutex);
-+
-+ /*
-+ if (arg->isi_config != NULL) {
-+ dprintk(2, "sync isi cfg");
-+ copy_sensor_config_from_user(isp->sys_conf.isi_config,
-+ arg->isi_config);
-+ } else {
-+ eprintk("NULL arg->isi_config");
-+ ret = CI_STATUS_NULL_POINTER;
-+ goto exit_unlock;
-+ }
-+
-+ if (arg->isi_caps != NULL) {
-+ dprintk(2, "sync isi caps");
-+ copy_sensor_caps_from_user(isp->sys_conf.isi_caps,
-+ arg->isi_caps);
-+ } else {
-+ eprintk("NULL arg->isi_caps");
-+ ret = CI_STATUS_NULL_POINTER;
-+ goto exit_unlock;
-+ }
-+ */
-+
-+ memcpy(&isp->sys_conf.isp_cfg, &arg->isp_cfg,
-+ sizeof(struct ci_isp_config));
-+
-+ print_bls_cfg(&isp->sys_conf.isp_cfg);
-+
-+ dprintk(2, "gammagamma2 = %d", arg->isp_cfg.flags.gamma2);
-+ dprintk(2, "gammagamma2 now = %d", isp->sys_conf.isp_cfg.flags.gamma2);
-+ mutex_unlock(&isp->mutex);
-+
-+ isp->sys_conf.isp_hal_enable = 1;
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+/* for buffer sharing between CI and VA */
-+static int mrst_isp_get_frame_info(struct file *file, void *priv,
-+ struct ci_frame_info *arg)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ mutex_lock(&isp->mutex);
-+
-+ arg->width = isp->bufwidth;
-+ arg->height = isp->bufheight;
-+ arg->fourcc = isp->pixelformat;
-+ arg->stride = isp->bufwidth; /* should be 64 bit alignment*/
-+ arg->offset = arg->frame_id * PAGE_ALIGN(isp->frame_size);
-+#if 0
-+ if (isp->bufwidth == 640 && isp->bufheight == 480)
-+ arg->offset = arg->frame_id * 0x71000;
-+ else if (isp->bufwidth == 1280 && isp->bufheight == 720)
-+ arg->offset = arg->frame_id * 0x152000;
-+#endif
-+
-+
-+ dprintk(2, "w=%d, h=%d, 4cc =%x, stride=%d, offset=%d,fsize=%d",
-+ arg->width, arg->height, arg->fourcc, arg->stride,
-+ arg->offset, isp->frame_size);
-+
-+ mutex_unlock(&isp->mutex);
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_set_jpg_enc_ratio(struct file *file, void *priv, int *arg)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ dprintk(2, "set jpg compression ratio is %d", *arg);
-+
-+ mutex_lock(&isp->mutex);
-+ isp->sys_conf.isp_cfg.jpeg_enc_ratio = *arg;
-+ mutex_unlock(&isp->mutex);
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+int mrst_isp_get_isp_mem_info(struct file *file, void *priv,
-+ struct ci_isp_mem_info *arg)
-+{
-+ u32 ret = 0;
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ mutex_lock(&isp->mutex);
-+ arg->isp_bar0_pa = isp->mb0;
-+ arg->isp_bar0_size = isp->mb0_size;
-+ arg->isp_bar1_pa = isp->mb1;
-+ arg->isp_bar1_size = isp->mb1_size;
-+ mutex_unlock(&isp->mutex);
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+int mrst_isp_create_jpg_review_frame(struct file *file, void *priv,
-+ struct v4l2_jpg_review_buffer *arg)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ u32 width = arg->width;
-+ u32 height = arg->height;
-+ u32 pix_fmt = arg->pix_fmt;
-+ u32 jpg_frame = arg->jpg_frame;
-+
-+ static struct v4l2_jpg_review_buffer *jpg_review;
-+
-+ jpg_review = &isp->sys_conf.jpg_review;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ if (width > 640 || height > 480 || width < 32 || height < 16) {
-+ eprintk("unsupported resolution: %d * %d", width, height);
-+ return -EINVAL;
-+ }
-+
-+ if (jpg_frame >= isp->num_frames) {
-+ eprintk("error jpeg frame id");
-+ return -1;
-+ }
-+
-+ jpg_review->width = width;
-+ jpg_review->height = height;
-+ jpg_review->pix_fmt = pix_fmt;
-+ jpg_review->jpg_frame = jpg_frame;
-+
-+ switch (arg->pix_fmt) {
-+ case V4L2_PIX_FMT_YUV422P:
-+ jpg_review->bytesperline = width * 2;
-+ jpg_review->frame_size = width * height * 2;
-+ break;
-+ case V4L2_PIX_FMT_YUV420:
-+ case V4L2_PIX_FMT_YVU420:
-+ case V4L2_PIX_FMT_NV12:
-+ jpg_review->bytesperline = width * 3/2;
-+ jpg_review->frame_size = width * height * 3/2;
-+ break;
-+ default:
-+ eprintk("unsupported pix_fmt: %d", arg->pix_fmt);
-+ return -EINVAL;
-+ }
-+
-+ jpg_review->offset = isp->mb1_size - 640*480*2;
-+
-+ isp->sys_conf.jpg_review_enable = 1; /* enable jpg review flag */
-+
-+ /* set user space data */
-+ arg->bytesperline = jpg_review->bytesperline;
-+ arg->frame_size = jpg_review->frame_size;
-+ arg->offset = jpg_review->offset;
-+
-+ dprintk(1, "create jpg review frame successfully: "
-+ "bytesperline = %d, frame_size = %d,"
-+ " offset = %d\n", arg->bytesperline,
-+ arg->frame_size, arg->offset);
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+/* isp private ioctl for libci */
-+long mrst_isp_vidioc_default(struct file *file, void *fh,
-+ int cmd, void *arg)
-+{
-+ void *priv = file->private_data;
-+
-+ DBG_entering;
-+
-+ switch (cmd) {
-+ case VIDIOC_GET_ISP_MEM_INFO:
-+ return mrst_isp_get_isp_mem_info(file, priv,
-+ (struct ci_isp_mem_info *)arg);
-+
-+ case VIDIOC_SET_SYS_CFG:
-+ return mrst_isp_set_cfg(file, priv,
-+ (struct ci_pl_system_config *)arg);
-+
-+ case VIDIOC_SET_JPG_ENC_RATIO:
-+ return mrst_isp_set_jpg_enc_ratio(file, priv, (int *)arg);
-+
-+ case ISP_IOCTL_GET_FRAME_INFO:
-+ return mrst_isp_get_frame_info(file, priv,
-+ (struct ci_frame_info *)arg);
-+
-+ case VIDIOC_CREATE_JPG_REVIEW_BUF:
-+ return mrst_isp_create_jpg_review_frame(file, priv,
-+ (struct v4l2_jpg_review_buffer *)arg);
-+ default:
-+ v4l_print_ioctl("lnw_isp", cmd);
-+ dprintk(2, "VIDIOC_SET_SYS_CFG = %x", VIDIOC_SET_SYS_CFG);
-+ return -EINVAL;
-+ }
-+
-+ DBG_leaving;
-+ return 0;
-+}
-diff --git a/drivers/media/video/mrstci/mrstisp/mrstisp_dp.c b/drivers/media/video/mrstci/mrstisp/mrstisp_dp.c
-new file mode 100644
-index 0000000..dd892fb
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/mrstisp_dp.c
-@@ -0,0 +1,1301 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * Copyright (c) Silicon Image 2008 www.siliconimage.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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+
-+/* mask for all chroma subsampling settings */
-+#define CI_ISP_DPD_CSS_MASK (CI_ISP_DPD_CSS_H_MASK | CI_ISP_DPD_CSS_V_MASK)
-+
-+#define SCALER_COFFS_COSITED 0x400
-+#define FIXEDPOINT_ONE 0x1000
-+
-+/* limitations of main and self scaler */
-+#define MAIN_SCALER_WIDTH_MAX 2600
-+
-+#define SELF_SCALER_WIDTH_MAX 640
-+#define SCALER_MIN 16
-+
-+#define SELF_UPSCALE_FACTOR_MAX 5
-+
-+#define MAIN_UPSCALE_FACTOR_MAX 5
-+
-+/*
-+ * upscale lookup table for smooth edges
-+ * (linear interpolation between pixels)
-+ */
-+
-+/* smooth edges */
-+static const struct ci_isp_rsz_lut isp_rsz_lut_smooth_lin = {
-+ {
-+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
-+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
-+ }
-+};
-+
-+/*
-+ * upscale lookup table for sharp edges
-+ * (no interpolation, just duplicate pixels)
-+ */
-+
-+/* sharp edges */
-+static const struct ci_isp_rsz_lut isp_rsz_lut_sharp = {
-+ {
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
-+ }
-+};
-+
-+/* structure combining virtual ISP windows settings */
-+struct ci_isp_virtual_isp_wnds {
-+ struct ci_isp_window wnd_blacklines;
-+ struct ci_isp_window wnd_zoom_crop;
-+};
-+
-+/* static storage to remember last applied virtual ISP window settings */
-+static struct ci_isp_virtual_isp_wnds last_isp_wnds;
-+
-+/*
-+ * Calculates the value to program into the struct ci_isp_scale or
-+ * tsMrvSScale structures to scale from in pixels to out pixels.
-+ *
-+ * The formulas are taken from the MARVIN / MARVIN3PLUS user
-+ * manuals (fixed-point calculation using 32 bit during
-+ * processing, will overflow at an output size of 1048575 pixels).
-+ */
-+static u32 ci_get_scale_reg(u16 in, u16 out)
-+{
-+ if (in > out) {
-+ /* downscaling */
-+ return (u32) (((((u32) out - 1) * RSZ_SCALER_BYPASS) /
-+ (u32) (in - 1)) + 1);
-+ } else if (in < out) {
-+ /* upscaling */
-+ return (u32) (((((u32) in - 1) * RSZ_SCALER_BYPASS) /
-+ (u32) (out - 1)) | (u32) RSZ_UPSCALE_ENABLE);
-+ }
-+
-+ /* no scaling */
-+ return RSZ_SCALER_BYPASS;
-+}
-+
-+/*
-+ * Calculates the values of the ci_isp_scale structure for the
-+ * given input size and data path descriptor.
-+ */
-+static u32 ci_calc_scale_factors(const struct ci_isp_datapath_desc *source,
-+ const struct ci_isp_datapath_desc *path,
-+ struct ci_isp_scale *scale, int implementation)
-+{
-+ u32 scaler_output_format;
-+ u32 cssflags;
-+ u32 scaler_input_format;
-+
-+ u16 chroma_in_w;
-+ u16 chroma_in_h;
-+ u16 chroma_out_wcr;
-+ u16 chroma_out_wcb;
-+ u16 chroma_out_h;
-+
-+ memset(scale, 0, sizeof(struct ci_isp_scale));
-+ dprintk(1, "srcw %d, srch %d;", source->out_w, source->out_h);
-+ dprintk(1, "dstw %d, dsth %d", path->out_w, path->out_h);
-+
-+ /* calculate Y scale factors */
-+ scale->scale_hy = ci_get_scale_reg(source->out_w, path->out_w);
-+ scale->scale_vy = ci_get_scale_reg(source->out_h, path->out_h);
-+
-+ /* figure out the color input format of the scaler */
-+ switch (path->flags & CI_ISP_DPD_MODE_MASK) {
-+ case CI_ISP_DPD_MODE_DMAYC_DIRECT:
-+ case CI_ISP_DPD_MODE_DMAYC_ISP:
-+ case CI_ISP_DPD_MODE_DMAJPEG_DIRECT:
-+ case CI_ISP_DPD_MODE_DMAJPEG_ISP:
-+ /* DMA-read originated data */
-+ scaler_input_format = path->flags & CI_ISP_DPD_DMA_IN_MASK;
-+ break;
-+ default:
-+ /* ISP originated data */
-+ scaler_input_format = CI_ISP_DPD_DMA_IN_422;
-+ break;
-+ }
-+
-+ dprintk(1, "scaler_input_format is 0x%x", scaler_input_format);
-+
-+ switch (scaler_input_format) {
-+ case CI_ISP_DPD_DMA_IN_422:
-+ chroma_in_w = source->out_w / 2;
-+ chroma_in_h = source->out_h;
-+ chroma_out_wcr = path->out_w / 2;
-+ chroma_out_wcb = (path->out_w + 1) / 2;
-+ chroma_out_h = path->out_h;
-+ break;
-+ case CI_ISP_DPD_DMA_IN_420:
-+ chroma_in_w = source->out_w / 2;
-+ chroma_in_h = source->out_h / 2;
-+ chroma_out_wcr = path->out_w / 2;
-+ chroma_out_wcb = (path->out_w + 1) / 2;
-+ chroma_out_h = path->out_h / 2;
-+ break;
-+ case CI_ISP_DPD_DMA_IN_411:
-+ chroma_in_w = source->out_w / 4;
-+ chroma_in_h = source->out_h;
-+ chroma_out_wcr = path->out_w / 4;
-+ chroma_out_wcb = (path->out_w + 2) / 4;
-+ chroma_out_h = path->out_h;
-+ break;
-+ case CI_ISP_DPD_DMA_IN_444:
-+ default:
-+ chroma_in_w = source->out_w;
-+ chroma_in_h = source->out_h;
-+ chroma_out_wcb = chroma_out_wcr = path->out_w;
-+ chroma_out_h = path->out_h;
-+ break;
-+ }
-+
-+ /* calculate chrominance scale factors */
-+ switch (path->flags & CI_ISP_DPD_CSS_H_MASK) {
-+ case CI_ISP_DPD_CSS_H2:
-+ chroma_out_wcb /= 2;
-+ chroma_out_wcr /= 2;
-+ break;
-+ case CI_ISP_DPD_CSS_H4:
-+ chroma_out_wcb /= 4;
-+ chroma_out_wcr /= 4;
-+ break;
-+ case CI_ISP_DPD_CSS_HUP2:
-+ chroma_out_wcb *= 2;
-+ chroma_out_wcr *= 2;
-+ break;
-+ case CI_ISP_DPD_CSS_HUP4:
-+ chroma_out_wcb *= 4;
-+ chroma_out_wcr *= 4;
-+ break;
-+ default:
-+ /*leave chroma_out_w untouched*/
-+ break;
-+ }
-+
-+ scale->scale_hcr = ci_get_scale_reg(chroma_in_w, chroma_out_wcr);
-+ scale->scale_hcb = ci_get_scale_reg(chroma_in_w, chroma_out_wcb);
-+ scale->scale_hcb = scale->scale_hcr;
-+
-+ switch (path->flags & CI_ISP_DPD_CSS_V_MASK) {
-+ case CI_ISP_DPD_CSS_V2:
-+ chroma_out_h /= 2;
-+ break;
-+ case CI_ISP_DPD_CSS_V4:
-+ chroma_out_h /= 4;
-+ break;
-+ case CI_ISP_DPD_CSS_VUP2:
-+ chroma_out_h *= 2;
-+ break;
-+ case CI_ISP_DPD_CSS_VUP4:
-+ chroma_out_h *= 4;
-+ break;
-+ default:
-+ /* leave chroma_out_h untouched */
-+ break;
-+ }
-+
-+ scale->scale_vc = ci_get_scale_reg(chroma_in_h, chroma_out_h);
-+
-+ /* additional chrominance phase shifts */
-+ if (path->flags & CI_ISP_DPD_CSS_HSHIFT)
-+ scale->phase_hc = SCALER_COFFS_COSITED;
-+ if (path->flags & CI_ISP_DPD_CSS_VSHIFT)
-+ scale->phase_vc = SCALER_COFFS_COSITED;
-+
-+ /* additional luminance phase shifts */
-+ if (path->flags & CI_ISP_DPD_LUMA_HSHIFT)
-+ scale->phase_hy = SCALER_COFFS_COSITED;
-+ if (path->flags & CI_ISP_DPD_LUMA_VSHIFT)
-+ scale->phase_vy = SCALER_COFFS_COSITED;
-+
-+ /* try to figure out the outcoming YCbCr format */
-+ cssflags = path->flags & CI_ISP_DPD_CSS_MASK;
-+ if (cssflags == (CI_ISP_DPD_CSS_H_OFF | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* trivial case: the output format is not changed */
-+ scaler_output_format = scaler_input_format;
-+ } else {
-+ /* output format gets changed by the scaler setting */
-+ /* assume invalid format by default */
-+ scaler_output_format = (u32) (-1);
-+ switch (scaler_input_format) {
-+ case CI_ISP_DPD_DMA_IN_444:
-+ if (cssflags == (CI_ISP_DPD_CSS_H2
-+ | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* conversion 444 -> 422 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_422;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_H4
-+ | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* conversion 444 -> 411 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_411;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_H2
-+ | CI_ISP_DPD_CSS_V2)) {
-+ /* conversion 444 -> 420 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_420;
-+ }
-+ break;
-+
-+ case CI_ISP_DPD_DMA_IN_422:
-+ if (cssflags == (CI_ISP_DPD_CSS_HUP2
-+ | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* conversion 422 -> 444 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_444;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_H2
-+ | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* conversion 422 -> 411 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_411;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_H_OFF
-+ | CI_ISP_DPD_CSS_V2)) {
-+ /* conversion 422 -> 420 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_420;
-+ }
-+ break;
-+
-+ case CI_ISP_DPD_DMA_IN_420:
-+ if (cssflags == (CI_ISP_DPD_CSS_HUP2
-+ | CI_ISP_DPD_CSS_VUP2)) {
-+ /* conversion 420 -> 444 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_444;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_H2
-+ | CI_ISP_DPD_CSS_VUP2)) {
-+ /* conversion 420 -> 411 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_411;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_H_OFF
-+ | CI_ISP_DPD_CSS_VUP2)) {
-+ /* conversion 420 -> 422 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_422;
-+ }
-+ break;
-+
-+ case CI_ISP_DPD_DMA_IN_411:
-+ if (cssflags == (CI_ISP_DPD_CSS_HUP4
-+ | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* conversion 411 -> 444 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_444;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_HUP2
-+ | CI_ISP_DPD_CSS_V_OFF)) {
-+ /* conversion 411 -> 422 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_422;
-+ } else if (cssflags == (CI_ISP_DPD_CSS_HUP2
-+ | CI_ISP_DPD_CSS_V2)) {
-+ /* conversion 411 -> 420 */
-+ scaler_output_format = CI_ISP_DPD_DMA_IN_420;
-+ }
-+ break;
-+
-+ default:
-+ /* DMA input format not supported */
-+ break;
-+ }
-+ }
-+
-+ return scaler_output_format;
-+}
-+
-+/*
-+ * Returns the address of up-scaling lookup table to use for
-+ * the given data path flags.
-+ */
-+static const struct ci_isp_rsz_lut *ci_get_rsz_lut(u32 flags)
-+{
-+ const struct ci_isp_rsz_lut *ret_val;
-+ switch (flags & CI_ISP_DPD_UPSCALE_MASK) {
-+ case CI_ISP_DPD_UPSCALE_SHARP:
-+ ret_val = &isp_rsz_lut_sharp;
-+ break;
-+ default:
-+ ret_val = &isp_rsz_lut_smooth_lin;
-+ break;
-+ }
-+ return ret_val;
-+}
-+
-+/*
-+ * Fills in scale factors and MI configuration for the main path.
-+ * Note that only self path related settings will be written into
-+ * the MI configuration struct, so this routine can be used for
-+ * both ISP and DMA originated data path setups.
-+ *
-+ * Following fields are being filled in:
-+ * scale_main: [all fields]
-+ * mrv_mi_ctrl: mrv_mif_mp_pic_form main_path
-+ */
-+static int ci_calc_main_path_settings(const struct ci_isp_datapath_desc *source,
-+ const struct ci_isp_datapath_desc *main,
-+ struct ci_isp_scale *scale_main,
-+ struct ci_isp_mi_ctrl *mrv_mi_ctrl)
-+{
-+ u32 main_flag;
-+
-+ WARN_ON(!(source != NULL));
-+ WARN_ON(!(scale_main != NULL));
-+ WARN_ON(!(mrv_mi_ctrl != NULL));
-+
-+ /* assume datapath deactivation if no selfpath pointer is given) */
-+ if (main)
-+ main_flag = main->flags;
-+ else
-+ main_flag = 0;
-+
-+ /* initialize the given parameters */
-+ memset(scale_main, 0, sizeof(struct ci_isp_scale));
-+ scale_main->scale_hy = RSZ_SCALER_BYPASS;
-+ scale_main->scale_hcb = RSZ_SCALER_BYPASS;
-+ scale_main->scale_hcr = RSZ_SCALER_BYPASS;
-+ scale_main->scale_vy = RSZ_SCALER_BYPASS;
-+ scale_main->scale_vc = RSZ_SCALER_BYPASS;
-+
-+ if (main_flag & CI_ISP_DPD_ENABLE) {
-+ switch (main_flag & CI_ISP_DPD_MODE_MASK) {
-+ case CI_ISP_DPD_MODE_ISPYC:
-+ case CI_ISP_DPD_MODE_DMAYC_ISP:
-+ mrv_mi_ctrl->main_path = CI_ISP_PATH_ON;
-+ break;
-+ case CI_ISP_DPD_MODE_ISPJPEG:
-+ case CI_ISP_DPD_MODE_DMAJPEG_DIRECT:
-+ case CI_ISP_DPD_MODE_DMAJPEG_ISP:
-+ mrv_mi_ctrl->main_path = CI_ISP_PATH_JPE;
-+ break;
-+ case CI_ISP_DPD_MODE_ISPRAW:
-+ mrv_mi_ctrl->main_path = CI_ISP_PATH_RAW8;
-+ break;
-+ case CI_ISP_DPD_MODE_ISPRAW_16B:
-+ mrv_mi_ctrl->main_path = CI_ISP_PATH_RAW816;
-+ break;
-+ default:
-+ eprintk("unsupported mode for main path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if (main_flag & (CI_ISP_DPD_H_FLIP | CI_ISP_DPD_V_FLIP |
-+ CI_ISP_DPD_90DEG_CCW)) {
-+ eprintk("not supported for main path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if (main_flag & CI_ISP_DPD_NORESIZE) {
-+ if (main_flag & CI_ISP_DPD_CSS_MASK) {
-+ eprintk("main path needs rezizer");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if (main_flag &
-+ (CI_ISP_DPD_LUMA_HSHIFT | CI_ISP_DPD_LUMA_VSHIFT)) {
-+ eprintk("main path needs rezizer");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ } else {
-+ if ((mrv_mi_ctrl->main_path == CI_ISP_PATH_RAW8)
-+ || (mrv_mi_ctrl->main_path == CI_ISP_PATH_RAW8)) {
-+ eprintk("scaler not in RAW mode");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ /* changed to avoid LINT warnings (Warning 613) */
-+ if (main != NULL) {
-+ if ((((u32) (source->out_w) *
-+ MAIN_UPSCALE_FACTOR_MAX) < main->out_w)
-+ ||
-+ (((u32) (source->out_h) *
-+ MAIN_UPSCALE_FACTOR_MAX) <
-+ main->out_h)) {
-+ eprintk("main upscaling exceeded");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if ((main->out_w >
-+ MAIN_SCALER_WIDTH_MAX)
-+ || (main->out_w < SCALER_MIN)
-+ || (main->out_h < SCALER_MIN)) {
-+ eprintk("main scaler ange exceeded");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ } else {
-+ WARN_ON(main == NULL);
-+ }
-+
-+ if (source->out_w & 0x01) {
-+ eprintk("input width must be even!");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* calculate scale factors. */
-+ (void)ci_calc_scale_factors(source, main, scale_main,
-+ MARVIN_FEATURE_MSCALE_FACTORCALC);
-+ }
-+ } else {
-+ mrv_mi_ctrl->main_path = CI_ISP_PATH_OFF;
-+ }
-+
-+ /* hardcoded MI settings */
-+ dprintk(1, "main_flag is 0x%x", main_flag);
-+ if (main_flag & CI_ISP_DPD_HWRGB_MASK) {
-+ switch (main_flag & CI_ISP_DPD_HWRGB_MASK) {
-+ case CI_ISP_DPD_YUV_420:
-+ case CI_ISP_DPD_YUV_422:
-+ mrv_mi_ctrl->mrv_mif_mp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ break;
-+ case CI_ISP_DPD_YUV_NV12:
-+ mrv_mi_ctrl->mrv_mif_mp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_SEMI_PLANAR;
-+ break;
-+ case CI_ISP_DPD_YUV_YUYV:
-+ mrv_mi_ctrl->mrv_mif_mp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_INTERLEAVED;
-+ break;
-+ default:
-+ mrv_mi_ctrl->mrv_mif_mp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ }
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Fills in scale factors and MI configuration for the self
-+ * path. Note that only self path related settings will be written into
-+ * the MI config struct, so this routine can be used for both ISP and DMA
-+ * originated datapath setups.
-+ *
-+ * Following fields are being filled in:
-+ * scale_flag :
-+ * [all fields]
-+ * mrv_mi_ctrl :
-+ * mrv_mif_sp_out_form
-+ * mrv_mif_sp_in_form
-+ * mrv_mif_sp_pic_form
-+ * mrv_mif_sp_mode
-+ * self_path
-+ */
-+static int ci_calc_self_path_settings(const struct ci_isp_datapath_desc *source,
-+ const struct ci_isp_datapath_desc *self,
-+ struct ci_isp_scale *scale_flag,
-+ struct ci_isp_mi_ctrl *mrv_mi_ctrl)
-+{
-+ u32 scaler_out_col_format;
-+ u32 self_flag;
-+
-+ WARN_ON(!(source != NULL));
-+ WARN_ON(!(scale_flag != NULL));
-+ WARN_ON(!(mrv_mi_ctrl != NULL));
-+
-+ /* assume datapath deactivation if no selfpath pointer is given) */
-+ if (self)
-+ self_flag = self->flags;
-+ else
-+ self_flag = 0;
-+
-+ /* initialize the given parameters */
-+ memset(scale_flag, 0, sizeof(struct ci_isp_scale));
-+ scale_flag->scale_hy = RSZ_SCALER_BYPASS;
-+ scale_flag->scale_hcb = RSZ_SCALER_BYPASS;
-+ scale_flag->scale_hcr = RSZ_SCALER_BYPASS;
-+ scale_flag->scale_vy = RSZ_SCALER_BYPASS;
-+ scale_flag->scale_vc = RSZ_SCALER_BYPASS;
-+
-+ if (self_flag & CI_ISP_DPD_ENABLE) {
-+
-+ switch (self_flag & CI_ISP_DPD_MODE_MASK) {
-+ case CI_ISP_DPD_MODE_ISPYC:
-+ mrv_mi_ctrl->self_path = CI_ISP_PATH_ON;
-+ scaler_out_col_format = CI_ISP_DPD_DMA_IN_422;
-+ break;
-+ case CI_ISP_DPD_MODE_DMAYC_ISP:
-+ case CI_ISP_DPD_MODE_DMAYC_DIRECT:
-+ mrv_mi_ctrl->self_path = CI_ISP_PATH_ON;
-+ scaler_out_col_format =
-+ self_flag & CI_ISP_DPD_DMA_IN_MASK;
-+ break;
-+ default:
-+ eprintk("unsupported mode for self path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ if (self_flag & CI_ISP_DPD_NORESIZE) {
-+ if (self_flag & CI_ISP_DPD_CSS_MASK) {
-+ eprintk("in self path needs rezizer");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if (self_flag &
-+ (CI_ISP_DPD_LUMA_HSHIFT | CI_ISP_DPD_LUMA_VSHIFT)) {
-+ eprintk("n self path needs rezizer");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ /* changed to avoid LINT warnings (Warning 613) */
-+ if (self != NULL) {
-+ if ((source->out_w != self->out_w) ||
-+ (source->out_h != self->out_h)) {
-+ eprintk("sizes needs resizer");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ } else {
-+ WARN_ON(self == NULL);
-+ }
-+ } else {
-+ /* changed to avoid LINT warnings (Warning 613) */
-+ if (self != NULL) {
-+ /* upscaling only to factor
-+ * SELF_UPSCALE_FACTOR_MAX possible
-+ */
-+ if ((((u32) (source->out_w) *
-+ SELF_UPSCALE_FACTOR_MAX) <
-+ self->out_w)
-+ ||
-+ (((u32) (source->out_h) *
-+ SELF_UPSCALE_FACTOR_MAX) <
-+ self->out_h)) {
-+ eprintk("apability exceeded");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if ((self->out_w >
-+ SELF_SCALER_WIDTH_MAX)
-+ || (self->out_w < SCALER_MIN)
-+ || (self->out_h < SCALER_MIN)) {
-+ eprintk("out range exceeded");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ } else {
-+ WARN_ON(self == NULL);
-+ }
-+ /* Remember that the input picture width should be
-+ * even if the scaler is used */
-+
-+ /* (otherwise the scaler may show unexpected
-+ * behaviour in some rare cases) */
-+ if (source->out_w & 0x01) {
-+ eprintk("width must be even!");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* calculate scale factors. */
-+ scaler_out_col_format =
-+ ci_calc_scale_factors(source, self, scale_flag,
-+ MARVIN_FEATURE_SSCALE_FACTORCALC);
-+ }
-+
-+ dprintk(2, "step1");
-+ /* figure out the input format setting */
-+ switch (scaler_out_col_format) {
-+ case CI_ISP_DPD_DMA_IN_444:
-+ mrv_mi_ctrl->mrv_mif_sp_in_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_444;
-+ break;
-+ case CI_ISP_DPD_DMA_IN_422:
-+ mrv_mi_ctrl->mrv_mif_sp_in_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_422;
-+ break;
-+ case CI_ISP_DPD_DMA_IN_420:
-+ mrv_mi_ctrl->mrv_mif_sp_in_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_420;
-+ break;
-+ /* no break, does not seem to be supported by HW */
-+ case CI_ISP_DPD_DMA_IN_411:
-+ default:
-+ eprintk("input color format not supported");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* figure out the output format setting */
-+ dprintk(2, "step2, self_flag is 0x%x", self_flag);
-+
-+ switch (self_flag & CI_ISP_DPD_HWRGB_MASK) {
-+ case CI_ISP_DPD_HWRGB_565:
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_RGB_565;
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ break;
-+ case CI_ISP_DPD_HWRGB_666:
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_RGB_666;
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ break;
-+ case CI_ISP_DPD_HWRGB_888:
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_RGB_888;
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ break;
-+ case CI_ISP_DPD_YUV_420:
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_420;
-+ break;
-+ case CI_ISP_DPD_YUV_422:
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_422;
-+ break;
-+ case CI_ISP_DPD_YUV_NV12:
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_SEMI_PLANAR;
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_420;
-+ break;
-+ case CI_ISP_DPD_YUV_YUYV:
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_INTERLEAVED;
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_422;
-+ break;
-+
-+ case CI_ISP_DPD_HWRGB_OFF:
-+ mrv_mi_ctrl->mrv_mif_sp_out_form =
-+ mrv_mi_ctrl->mrv_mif_sp_in_form;
-+ mrv_mi_ctrl->mrv_mif_sp_pic_form =
-+ CI_ISP_MIF_PIC_FORM_PLANAR;
-+ break;
-+ default:
-+ eprintk("output color format not supported");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* picture flipping / rotation */
-+ dprintk(2, "step3");
-+
-+ switch (self_flag &
-+ (CI_ISP_DPD_90DEG_CCW | CI_ISP_DPD_V_FLIP |
-+ CI_ISP_DPD_H_FLIP)) {
-+ case (CI_ISP_DPD_H_FLIP):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_HORIZONTAL_FLIP;
-+ break;
-+ case (CI_ISP_DPD_V_FLIP):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_VERTICAL_FLIP;
-+ break;
-+ case (CI_ISP_DPD_V_FLIP | CI_ISP_DPD_H_FLIP):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_ROTATION_180_DEG;
-+ break;
-+ case (CI_ISP_DPD_90DEG_CCW):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_ROTATION_090_DEG;
-+ break;
-+ case (CI_ISP_DPD_90DEG_CCW | CI_ISP_DPD_H_FLIP):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_ROT_270_V_FLIP;
-+ break;
-+ case (CI_ISP_DPD_90DEG_CCW | CI_ISP_DPD_V_FLIP):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_ROT_090_V_FLIP;
-+ break;
-+ case (CI_ISP_DPD_90DEG_CCW | CI_ISP_DPD_V_FLIP |
-+ CI_ISP_DPD_H_FLIP):
-+ mrv_mi_ctrl->mrv_mif_sp_mode =
-+ CI_ISP_MIF_SP_ROTATION_270_DEG;
-+ break;
-+ default:
-+ mrv_mi_ctrl->mrv_mif_sp_mode = CI_ISP_MIF_SP_ORIGINAL;
-+ break;
-+ }
-+
-+ } else {
-+ mrv_mi_ctrl->self_path = CI_ISP_PATH_OFF;
-+ }
-+
-+ dprintk(2, "step4");
-+ /*mrv_mi_ctrl->mrv_mif_sp_pic_form = CI_ISP_MIF_PIC_FORM_PLANAR;*/
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Translates the given memory interface configuration struct
-+ * into appropriate values to program the data path multiplexers.
-+ */
-+static int ci_calc_dp_mux_settings(const struct ci_isp_mi_ctrl *mi_ctrl,
-+ enum ci_isp_ycs_chn_mode *peYcsChnMode,
-+ enum ci_isp_dp_switch *peDpSwitch)
-+{
-+ switch (mi_ctrl->main_path) {
-+ case CI_ISP_PATH_RAW8:
-+ case CI_ISP_PATH_RAW816:
-+ *peDpSwitch = CI_ISP_DP_RAW;
-+ *peYcsChnMode = CI_ISP_YCS_MVRaw;
-+ if (mi_ctrl->self_path != CI_ISP_PATH_OFF) {
-+ eprintk("ombined with RAW mode of main path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ break;
-+
-+ case CI_ISP_PATH_JPE:
-+ *peDpSwitch = CI_ISP_DP_JPEG;
-+ if (mi_ctrl->self_path != CI_ISP_PATH_OFF)
-+ *peYcsChnMode = CI_ISP_YCS_MV_SP;
-+ else
-+ *peYcsChnMode = CI_ISP_YCS_MV;
-+ break;
-+
-+ case CI_ISP_PATH_ON:
-+ *peDpSwitch = CI_ISP_DP_MV;
-+ if (mi_ctrl->self_path != CI_ISP_PATH_OFF)
-+ *peYcsChnMode = CI_ISP_YCS_MV_SP;
-+ else
-+ *peYcsChnMode = CI_ISP_YCS_MV;
-+ break;
-+
-+ case CI_ISP_PATH_OFF:
-+ *peDpSwitch = CI_ISP_DP_MV;
-+ if (mi_ctrl->self_path != CI_ISP_PATH_OFF)
-+ *peYcsChnMode = CI_ISP_YCS_SP;
-+ else
-+ *peYcsChnMode = CI_ISP_YCS_OFF;
-+ break;
-+
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/* the windows to cut away black pixels and to zoom/crop the */
-+#define ISPWND_COMBINE_WNDS 0x00000001
-+/* image must be combined before they are applyed to the marvin registers */
-+/* call of the ci_isp_set_output_formatter() routine necessary */
-+#define ISPWND_APPLY_OUTFORM 0x00000002
-+/* call of the ci_isp_is_set_config() routine necessary */
-+#define ISPWND_APPLY_ISCONF 0x00000004
-+/* no cropping supported at all */
-+#define ISPWND_NO_CROPPING 0x00000008
-+
-+/*
-+ * Returns information about how to combine black pixel and
-+ * zoom/crop windows for programming the ISP output formatter and the image
-+ * stabilization unit for the given marvin derivative and ISP path.
-+ */
-+static u32 ci_get_isp_wnd_style(enum ci_isp_path isp_path)
-+{
-+ u32 res = 0;
-+
-+ /* output formatter exists at ISP input */
-+ /* image stabilization in both bayer and YCbCr paths */
-+ if ((isp_path == CI_ISP_PATH_BAYER) ||
-+ (isp_path == CI_ISP_PATH_YCBCR))
-+ /*we need to program the output formatter with the blackline
-+ * window and */
-+ res = ISPWND_APPLY_OUTFORM | ISPWND_APPLY_ISCONF;
-+ else
-+ res = ISPWND_COMBINE_WNDS | ISPWND_APPLY_OUTFORM;
-+
-+ return res;
-+}
-+
-+/*
-+ * the given windows for cutting away blacklines coming from
-+ * the image sensor and further cropping of the image for other
-+ * purposes like e.g. digital zoom to the output formatter and/or
-+ * image stabilisation modules of Marvins ISP.
-+ */
-+static int ci_set_isp_windows(const struct ci_sensor_config *isi_sensor_config,
-+ const struct ci_isp_window *wnd_blackline,
-+ const struct ci_isp_window *wnd_zoom_crop)
-+{
-+ struct ci_isp_window wnd_out_form;
-+ struct ci_isp_is_config is_conf;
-+ enum ci_isp_path isp_path;
-+ u32 wnd_style;
-+
-+ memset(&wnd_out_form, 0, sizeof(wnd_out_form));
-+ memset(&is_conf, 0, sizeof(is_conf));
-+
-+ /*
-+ * figure out the path through the ISP to process the data from the
-+ * image sensor
-+ */
-+ isp_path = ci_isp_select_path(isi_sensor_config, NULL);
-+ if (isp_path == CI_ISP_PATH_UNKNOWN) {
-+ eprintk("detect marvin ISP path to use");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /*
-+ * get the recommended way to configure output formatter and/or
-+ * image stabilization
-+ */
-+ wnd_style = ci_get_isp_wnd_style(isp_path);
-+ if (wnd_style & ISPWND_NO_CROPPING) {
-+ /*
-+ * cropping not possible -> make sure that it is *not*
-+ * supposed to be used
-+ */
-+ u16 isiX;
-+ u16 isiY;
-+ /* changed to avoid LINT warnings (Warning 534) */
-+ (void)ci_sensor_res2size(isi_sensor_config->res, &isiX, &isiY);
-+ if ((wnd_zoom_crop->hsize != isiX)
-+ || (wnd_zoom_crop->vsize != isiY)
-+ || (wnd_zoom_crop->hoffs != 0)
-+ || (wnd_zoom_crop->voffs != 0)) {
-+ eprintk("in selected ISP data path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ if ((wnd_blackline->hsize != isiX) ||
-+ (wnd_blackline->vsize != isiY) ||
-+ (wnd_blackline->hoffs != 0) ||
-+ (wnd_blackline->voffs != 0)) {
-+ eprintk("supported in selected ISP data path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ }
-+
-+ /*
-+ * The image stabilization is allowed to move the window in both
-+ * directions by the same amount of pixels we have calculated for
-+ * the offsets. The initial image stabilization window is equal to
-+ * the zoom/crop window
-+ */
-+ is_conf.max_dx = wnd_zoom_crop->hoffs;
-+ is_conf.max_dy = wnd_zoom_crop->voffs;
-+ is_conf.mrv_is_window = *wnd_zoom_crop;
-+
-+ /* combine both blackline and zoom/crop window */
-+ if (wnd_style & ISPWND_COMBINE_WNDS) {
-+ /* combine both blackline and zoom/crop window */
-+ wnd_out_form = *wnd_zoom_crop;
-+ wnd_out_form.voffs += wnd_blackline->voffs;
-+ wnd_out_form.hoffs += wnd_blackline->hoffs;
-+ is_conf.mrv_is_window = wnd_out_form;
-+ if (wnd_style & ISPWND_APPLY_OUTFORM) {
-+ /*
-+ * if the output formatter is to be used, offsets
-+ * are cut away there, so
-+ * we don't need additional ones in the imags
-+ * stabilization unit
-+ */
-+ is_conf.mrv_is_window.hoffs = 0;
-+ is_conf.mrv_is_window.voffs = 0;
-+ }
-+ } else {
-+ /*
-+ * do not combine windows --> blacklines done with output
-+ * formatter, zoom/cropping done with image stabilization
-+ */
-+ wnd_out_form = *wnd_blackline;
-+ is_conf.mrv_is_window = *wnd_zoom_crop;
-+ }
-+
-+ /* finally, apply the settings to marvin */
-+ if (wnd_style & ISPWND_APPLY_OUTFORM) {
-+ ci_isp_set_output_formatter(&wnd_out_form,
-+ CI_ISP_CFG_UPDATE_IMMEDIATE);
-+ }
-+ if (wnd_style & ISPWND_APPLY_ISCONF) {
-+ int res = ci_isp_is_set_config(&is_conf);
-+ if (res != CI_STATUS_SUCCESS) {
-+ eprintk("set image stabilization config");
-+ return res;
-+ }
-+ }
-+
-+ /* success - remember our virtual settings */
-+ last_isp_wnds.wnd_blacklines = *wnd_blackline;
-+ last_isp_wnds.wnd_zoom_crop = *wnd_zoom_crop;
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/* sets extended YCbCr mode */
-+static int ci_ext_ycb_cr_mode(const struct ci_isp_datapath_desc *path)
-+{
-+ u32 main_flag;
-+
-+ WARN_ON(!(path != NULL));
-+
-+ /* assume datapath deactivation if no selfpath pointer is given) */
-+ if (path)
-+ main_flag = path->flags;
-+ else
-+ main_flag = 0;
-+
-+ /* if flag CI_ISP_DPD_YCBCREXT is set set extended YCbCr mode */
-+ if (main_flag & CI_ISP_DPD_ENABLE) {
-+ if (main_flag & CI_ISP_DPD_YCBCREXT)
-+ ci_isp_set_ext_ycmode();
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Configures main and self data pathes and scaler for data coming from the ISP.
-+ *
-+ * Following MARVIN subsystems are programmed:
-+ * - ISP output formatter
-+ * - Image stabilization module
-+ * - YC-Splitter
-+ * - Self path DMA-read multiplexer
-+ * - Main path multiplexer
-+ * - Main & Self path resizer
-+ * - Small output unit
-+ * - Memory Interface (MI) input source, en/disable and data format
-+ *
-+ * Following MARVIN subsystems are *NOT* programmed:
-+ * - All ISP functionality but the output formatter & image stabilization module
-+ * - color Processing block
-+ * - JPEG encode subsystem (quantisation tables etc.)
-+ * - Memory Interface (MI) output buffer addresses and sizes
-+ */
-+int ci_datapath_isp(const struct ci_pl_system_config *sys_conf,
-+ const struct ci_sensor_config *isi_config,
-+ const struct ci_isp_datapath_desc *main,
-+ const struct ci_isp_datapath_desc *self, int zoom)
-+{
-+ int res;
-+ /*
-+ * copy of flags for main and self path to simplify access (no
-+ * pointer de-reference)
-+ */
-+ u32 main_flag;
-+ u32 self_flag;
-+ /* resolution from sensor configuration */
-+ u16 isiX;
-+ u16 isiY;
-+ /* things to apply to MARVIN */
-+ struct ci_isp_scale scale_main;
-+ struct ci_isp_scale scale_flag;
-+ enum ci_isp_ycs_chn_mode chn_mode = 0;
-+ enum ci_isp_dp_switch dp_switch = 0;
-+ struct ci_isp_mi_ctrl mrv_mi_ctrl;
-+ struct ci_isp_datapath_desc source;
-+ /* ISP windowing because of cutting away blacklines from the sensor */
-+ struct ci_isp_window wnd_blackline;
-+ /* ISP windowing because of aspect ratio change and/or zoom */
-+ struct ci_isp_window wnd_zoom_crop;
-+
-+ const struct ci_isp_datapath_desc *target = NULL;
-+
-+ /* assume dapapath deactivation for not provided descriptors */
-+ main_flag = 0;
-+ self_flag = 0;
-+ if (main)
-+ main_flag = main->flags; /* 0x012 */
-+
-+ if (self)
-+ self_flag = self->flags; /* 0x10015 */
-+
-+ /* initialize variables on the stack */
-+ res = CI_STATUS_SUCCESS;
-+ /* changed to avoid LINT warnings (Warning 534) */
-+ (void)ci_sensor_res2size(isi_config->res, &isiX, &isiY);
-+ memset(&mrv_mi_ctrl, 0, sizeof(struct ci_isp_mi_ctrl));
-+ memset(&wnd_blackline, 0, sizeof(wnd_blackline));
-+ memset(&wnd_zoom_crop, 0, sizeof(wnd_zoom_crop));
-+
-+ /*
-+ * ISP Windowing - fill in wnd_out_form, apply_out_form, is_conf and
-+ * apply_is_conf
-+ */
-+
-+ /*
-+ * by default, size of both blackline and zoom/crop window
-+ * is what the camera delivers.
-+ */
-+
-+ /* (no cropping, no offset) */
-+ wnd_blackline.hsize = isiX;
-+ wnd_blackline.vsize = isiY;
-+ wnd_zoom_crop = wnd_blackline;
-+
-+ /*
-+ * check if we have to crop because of aspect ratio
-+ * preservement of an
-+ */
-+
-+ /* output channel */
-+ if ((main_flag & CI_ISP_DPD_ENABLE) &&
-+ (main_flag & CI_ISP_DPD_KEEPRATIO)) {
-+ target = main;
-+ }
-+ if ((self_flag & CI_ISP_DPD_ENABLE) &&
-+ (self_flag & CI_ISP_DPD_KEEPRATIO)) {
-+ if (target) {
-+ eprintk("only allowed for one path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ target = self;
-+ }
-+
-+ /* if so, calculate the cropping */
-+ if (target) {
-+ u32 aspect_cam = (0x1000 * ((u32) isiX)) / isiY;
-+ u32 aspect_target = (0x1000 * ((u32) (target->out_w))) /
-+ target->out_h;
-+ if (aspect_cam < aspect_target) {
-+ /*
-+ * camera aspect is more 'portrait-like' as
-+ * target aspect. We have to crop the
-+ * camera picture by cutting off a bit of
-+ * the top & bottom changed to avoid LINT
-+ * warnings (Info 734)
-+ */
-+ wnd_zoom_crop.vsize = (u16) (((u32) isiX *
-+ (u32) (target->out_h)) / target->out_w);
-+ } else {
-+ /* camera aspect is more 'landscape-like'
-+ * as target aspect. We have to crop the
-+ * camera picture by cutting off a bit of
-+ * the left and right changed to avoid LINT
-+ * warnings (Info 734) */
-+ wnd_zoom_crop.hsize = (u16) (((u32) isiY *
-+ (u32) (target->out_w)) / target->out_h);
-+ }
-+ }
-+
-+ /*
-+ * now, we may also want to do digital zoom. If so, we need
-+ * to shrink the ISP window by the desired zoom factor.
-+ */
-+ if (zoom > 0) {
-+ /* changed to avoid LINT warnings (Warning 573) */
-+ wnd_zoom_crop.vsize = (u16) (((u32) (wnd_zoom_crop.vsize) *
-+ 1024) / (1024 + (u32) zoom));
-+ /* changed to avoid LINT warnings (Warning 573) */
-+ wnd_zoom_crop.hsize = (u16) (((u32) (wnd_zoom_crop.hsize) *
-+ 1024) / (1024 + (u32) zoom));
-+ }
-+ /*
-+ * Remember that the output formatter h_size should be
-+ * even if the scaler is used
-+ * (otherwise the scaler may show unexpected behaviour in
-+ * some rare cases)
-+ */
-+ wnd_zoom_crop.hsize &= ~0x01;
-+ /*
-+ * At last, we care about the offset of the ISP window. We
-+ * want it centered on the image data delivered by the
-+ * sensor (not counting possible black lines)
-+ */
-+ wnd_zoom_crop.hoffs = (isiX - wnd_zoom_crop.hsize) / 2;
-+ wnd_zoom_crop.voffs = (isiY - wnd_zoom_crop.vsize) / 2;
-+ /*
-+ * If the image sensor delivers blacklines, we cut them
-+ * away with moving wnd_blackline window by the given
-+ * amount of lines
-+ */
-+ switch (isi_config->bls) {
-+ /* no black lines */
-+ case SENSOR_BLS_OFF:
-+ break;
-+ /* two black lines at frame start */
-+ case SENSOR_BLS_TWO_LINES:
-+ wnd_blackline.voffs += 2;
-+ break;
-+ /* two black lines at frame start and two at the end */
-+ case SENSOR_BLS_FOUR_LINES:
-+ wnd_blackline.voffs += 2;
-+ break;
-+ default:
-+ eprintk("config");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ /*
-+ * if we are instructed to show the blacklines and the
-+ * sensor generates them,
-+ * we have to move the ISP windows to the upper border of
-+ * the whole sensor, and deny the image stabilization to
-+ * move around the window in vertical direction.
-+ */
-+ if (isi_config->bls != SENSOR_BLS_OFF) {
-+ if (((main_flag & CI_ISP_DPD_ENABLE)
-+ && (main_flag & CI_ISP_DPD_BLACKLINES_TOP))
-+ || ((self_flag & CI_ISP_DPD_ENABLE)
-+ && (self_flag & CI_ISP_DPD_BLACKLINES_TOP))) {
-+ if ((main_flag & CI_ISP_DPD_ENABLE)
-+ && (self_flag & CI_ISP_DPD_ENABLE)
-+ && ((main_flag & CI_ISP_DPD_BLACKLINES_TOP)
-+ != (self_flag & CI_ISP_DPD_BLACKLINES_TOP))) {
-+ eprintk("and self path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ wnd_blackline.voffs = 0;
-+ wnd_zoom_crop.voffs = 0;
-+ }
-+ }
-+
-+ source.out_w = wnd_zoom_crop.hsize;
-+ source.out_h = wnd_zoom_crop.vsize;
-+ source.flags = CI_ISP_DPD_DMA_IN_422;
-+
-+ /*to use crop set crop_flag first*/
-+ if (crop_flag) {
-+ wnd_zoom_crop.hsize = main->out_w;
-+ wnd_zoom_crop.vsize = main->out_h;
-+ }
-+
-+ dprintk(1, "source.out_w %d, source.out_h %d",
-+ source.out_w, source.out_h);
-+ if (main)
-+ dprintk(1, "main.out_w %d, main.out_h %d",
-+ main->out_w, main->out_h);
-+ if (self)
-+ dprintk(1, "self.out_w %d, self.out_h %d",
-+ self->out_w, self->out_h);
-+
-+ /*
-+ * At this point, wnd_zoom_crop and wnd_blackline contain
-+ * the window sizes that reflect the users request. We have
-+ * to configure the ISP output formatter and the image
-+ * stabilization formatter in order to achieve this, but
-+ * how they interact is highly dependant of the curr
-+ * marvin derivative and which datapath of the ISP is
-+ * activated. Therefore, translating wnd_zoom_crop and
-+ * wnd_blackline into marvin register settings is a bit
-+ * complicated and will be done by the
-+ * ci_set_isp_windows() routine.
-+ */
-+
-+ /* ISP Window */
-+ /* MAIN path - fill in main_path, scale_main and main_rsz_lut */
-+ /* basic selfpath settings */
-+ res = ci_calc_main_path_settings(&source, main, &scale_main,
-+ &mrv_mi_ctrl);
-+ if (res != CI_STATUS_SUCCESS)
-+ return res;
-+
-+ /* additional settings specific for main path fed from ISP */
-+ if (main_flag & CI_ISP_DPD_ENABLE) {
-+ switch (main_flag & CI_ISP_DPD_MODE_MASK) {
-+ case CI_ISP_DPD_MODE_ISPYC:
-+ case CI_ISP_DPD_MODE_ISPRAW:
-+ case CI_ISP_DPD_MODE_ISPRAW_16B:
-+ case CI_ISP_DPD_MODE_ISPJPEG:
-+ /* allowed cases, just proceed */
-+ break;
-+ default:
-+ eprintk("data coming from the ISP");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ }
-+
-+ /* SELF path - fill in self_path & scale_flag */
-+ /* basic selfpath settings */
-+ res = ci_calc_self_path_settings(&source, self, &scale_flag,
-+ &mrv_mi_ctrl);
-+ if (res != CI_STATUS_SUCCESS)
-+ return res;
-+
-+ if (sys_conf->isp_cfg.flags.ycbcr_non_cosited)
-+ mrv_mi_ctrl.mrv_mif_sp_in_phase = mrv_mif_col_phase_non_cosited;
-+ else
-+ mrv_mi_ctrl.mrv_mif_sp_in_phase = mrv_mif_col_phase_cosited;
-+ if (sys_conf->isp_cfg.flags.ycbcr_full_range)
-+ mrv_mi_ctrl.mrv_mif_sp_in_range = mrv_mif_col_range_full;
-+ else
-+ mrv_mi_ctrl.mrv_mif_sp_in_range = mrv_mif_col_range_std;
-+ if (self_flag & CI_ISP_DPD_ENABLE) {
-+ switch (self_flag & CI_ISP_DPD_MODE_MASK) {
-+ case CI_ISP_DPD_MODE_ISPYC:
-+ /* only allowed case, just proceed */
-+ break;
-+ default:
-+ eprintk("data coming from the ISP");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ }
-+
-+ /* Datapath multiplexers */
-+ res = ci_calc_dp_mux_settings(&mrv_mi_ctrl, &chn_mode, &dp_switch);
-+ if (res != CI_STATUS_SUCCESS)
-+ return res;
-+
-+ /* hardcoded global settings of the memory interface */
-+ mrv_mi_ctrl.byte_swap_enable = false;
-+
-+ mrv_mi_ctrl.init_vals = CI_ISP_MIF_INIT_OFFSAndBase;
-+
-+ /*
-+ * If we reach this point, we have collected all values to program
-+ * the MARVIN for the requested datapath setup. Now all we've left
-+ * to do is apply these to MARVINs register set. For this, we
-+ * mostly use the low level MARVIN driver routines.
-+ */
-+ /*to use crop set crop_flag first*/
-+ if (crop_flag) {
-+ wnd_blackline.hsize = main->out_w;
-+ wnd_blackline.vsize = main->out_h;
-+ }
-+
-+ res = ci_set_isp_windows(isi_config, &wnd_blackline,
-+ &wnd_zoom_crop);
-+ if (res != CI_STATUS_SUCCESS) {
-+ eprintk("failed to set ISP window configuration");
-+ return res;
-+ }
-+ res = ci_isp_set_data_path(chn_mode, dp_switch);
-+ if (res != CI_STATUS_SUCCESS)
-+ return res;
-+
-+ res = ci_isp_set_mipi_smia(isi_config->mode);
-+ if (res != CI_STATUS_SUCCESS)
-+ return res;
-+
-+ if (mrv_mi_ctrl.self_path != CI_ISP_PATH_OFF)
-+ ci_isp_res_set_self_resize(&scale_flag,
-+ CI_ISP_CFG_UPDATE_IMMEDIATE,
-+ ci_get_rsz_lut(self_flag));
-+
-+ if (mrv_mi_ctrl.main_path != CI_ISP_PATH_OFF)
-+ ci_isp_res_set_main_resize(&scale_main,
-+ CI_ISP_CFG_UPDATE_IMMEDIATE,
-+ ci_get_rsz_lut(main_flag));
-+
-+ ci_isp_set_dma_read_mode(CI_ISP_DMA_RD_OFF,
-+ CI_ISP_CFG_UPDATE_IMMEDIATE);
-+
-+ res = ci_isp_mif_set_path_and_orientation(&mrv_mi_ctrl);
-+ if (res != CI_STATUS_SUCCESS) {
-+ eprintk("failed to set MI path and orientation");
-+ return res;
-+ }
-+
-+ /* here the extended YCbCr mode is configured */
-+ if (sys_conf->isp_cfg.flags.ycbcr_full_range)
-+ res = ci_ext_ycb_cr_mode(main);
-+ else
-+ (void)ci_isp_set_yc_mode();
-+
-+ if (res != CI_STATUS_SUCCESS) {
-+ eprintk("failed to set ISP YCbCr extended mode");
-+ return res;
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-diff --git a/drivers/media/video/mrstci/mrstisp/mrstisp_hw.c b/drivers/media/video/mrstci/mrstisp/mrstisp_hw.c
-new file mode 100644
-index 0000000..56891c1
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/mrstisp_hw.c
-@@ -0,0 +1,1622 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * Copyright (c) Silicon Image 2008 www.siliconimage.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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+
-+static unsigned long jiffies_start;
-+
-+void mrst_timer_start(void)
-+{
-+ jiffies_start = jiffies;
-+}
-+
-+void mrst_timer_stop(void)
-+{
-+ jiffies_start = 0;
-+}
-+
-+unsigned long mrst_get_micro_sec(void)
-+{
-+ unsigned long time_diff = 0;
-+
-+ time_diff = jiffies - jiffies_start;
-+
-+ return jiffies_to_msecs(time_diff);
-+}
-+
-+/*
-+ * Returns the ISP hardware ID.
-+ */
-+static u32 ci_isp_get_ci_isp_id(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 result = 0;
-+
-+ result = REG_GET_SLICE(mrv_reg->vi_id, MRV_REV_ID);
-+
-+ return result;
-+}
-+
-+/*
-+ * Gets the hardware ID and compares it with the expected one.
-+ */
-+static int ci_isp_verify_chip_id(void)
-+{
-+ u32 mrv_id = ci_isp_get_ci_isp_id();
-+ dprintk(1, "HW-Id: 0x%08X", mrv_id);
-+
-+ if (mrv_id != MARVIN_FEATURE_CHIP_ID) {
-+ eprintk("HW-Id does not match! read:0x%08X, expected:0x%08X",
-+ mrv_id, MARVIN_FEATURE_CHIP_ID);
-+ return CI_STATUS_FAILURE;
-+ }
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Triggers an entire reset of MARVIN (equaling an asynchronous
-+ * hardware reset).
-+ * Checks the hardware ID. A debug warning is issued if the
-+ * module ID does not match the expected ID.
-+ * Enables all clocks of all sub-modules.
-+ * MARVIN is in idle state afterwards.
-+ */
-+void ci_isp_init(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /* verify ID, but no consequences if it doesn't match */
-+ (void)ci_isp_verify_chip_id();
-+
-+ /* enable main clock */
-+ REG_SET_SLICE(mrv_reg->vi_ccl, MRV_VI_CCLFDIS, MRV_VI_CCLFDIS_ENABLE);
-+
-+ /*
-+ * enable all clocks to make sure that all submodules will be able to
-+ * perform the reset correctly
-+ */
-+ REG_SET_SLICE(mrv_reg->vi_iccl, MRV_VI_ALL_CLK_ENABLE, ENABLE);
-+
-+ /*
-+ * Reset of the entire MARVIN triggered by software. The minimum time
-+ * permitted by mdelay ensures enough delay.
-+ */
-+
-+ /* The reset bit will be cleared by the reset itself. */
-+
-+ /*
-+ * The default value of the clock registers is all clocks on. So we
-+ * don't have to enable the clocks again afterwards.
-+ */
-+
-+ REG_SET_SLICE(mrv_reg->vi_ircl, MRV_VI_MARVIN_RST, ON);
-+ /*mdelay(CI_ISP_DELAY_AFTER_RESET);*/
-+ msleep(CI_ISP_DELAY_AFTER_RESET);
-+}
-+
-+void ci_isp_off(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /* enable main clock */
-+ REG_SET_SLICE(mrv_reg->vi_ccl, MRV_VI_CCLFDIS,
-+ MRV_VI_CCLFDIS_DISABLE);
-+
-+ /*
-+ * enable all clocks to make sure that all submodules will be able to
-+ * perform the reset correctly
-+ */
-+ REG_SET_SLICE(mrv_reg->vi_iccl, MRV_VI_ALL_CLK_ENABLE, DISABLE);
-+}
-+
-+/*
-+ * Returns the mask for the frame end interrupts, which are
-+ * used for Isp.
-+ */
-+u32 ci_isp_get_frame_end_irq_mask_isp(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ switch (REG_GET_SLICE(mrv_reg->vi_dpcl, MRV_VI_DMA_SWITCH)) {
-+ /*
-+ * 2: path to image effects block (i.e. replacement for data coming
-+ * from the ISP)
-+ */
-+ case MRV_VI_DMA_SWITCH_IE:
-+ /* datapath is used by DMA */
-+ return 0;
-+ /*
-+ * 0: direct path to self path mux
-+ */
-+ case MRV_VI_DMA_SWITCH_SELF:
-+ /*
-+ * 1: path to superimpose block
-+ */
-+ case MRV_VI_DMA_SWITCH_SI:
-+ /*
-+ * 3: direct path to JPEG encoder (R2B-buffer-less encodein mode)
-+ */
-+ case MRV_VI_DMA_SWITCH_JPG:
-+ default:
-+ /* main and/or self path depends on the YC-splitter setting */
-+ {
-+ switch (REG_GET_SLICE
-+ (mrv_reg->vi_dpcl, MRV_VI_CHAN_MODE)) {
-+ case MRV_VI_CHAN_MODE_MP:
-+ return MRV_MI_MP_FRAME_END_MASK;
-+ case MRV_VI_CHAN_MODE_SP:
-+ return MRV_MI_SP_FRAME_END_MASK;
-+ case MRV_VI_CHAN_MODE_MP_SP:
-+ return MRV_MI_MP_FRAME_END_MASK |
-+ MRV_MI_SP_FRAME_END_MASK;
-+ default:
-+ return 0;
-+ }
-+ }
-+ }
-+
-+}
-+
-+/*
-+ * Programs the number of frames to capture. Clears frame end
-+ * interrupt to allow waiting in ci_isp_wait_for_frame_end().
-+ * Enables the ISP input acquisition and output formatter.
-+ * If immediate=false, the hardware assures that enabling is
-+ * done frame synchronously.
-+ */
-+void ci_isp_start(u16 number_of_frames,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_ctrl = REG_READ(mrv_reg->isp_ctrl);
-+ u32 eof_irq_mask = ci_isp_get_frame_end_irq_mask_isp();
-+
-+ /* max. 10 bits allowed */
-+ WARN_ON(!(number_of_frames <= MRV_ISP_ACQ_NR_FRAMES_MAX));
-+
-+ REG_SET_SLICE(mrv_reg->isp_acq_nr_frames, MRV_ISP_ACQ_NR_FRAMES,
-+ number_of_frames);
-+
-+ /* clear frame end interrupt */
-+ REG_WRITE(mrv_reg->mi_icr, eof_irq_mask);
-+
-+ /* Enable ISP input Acquisition and output formatter. */
-+
-+ /*
-+ * Input Acquisition is always enabled synchronous to the image sensor
-+ * (no configuration update required). As soon as the input
-+ * acquisition is started bit in_enable_shd in the register
-+ * isp_flags_shd is set by hardware. In the following a frame end
-+ * recognized by the input acquisition unit leads to
-+ * ris_in_frame_end=1 in isp_ris. However a recognized frame end and
-+ * no signaled errors are no guarantee for a valid configuration.
-+ */
-+
-+ /*
-+ * The output formatter is enabled frame synchronously according to
-+ * the internal sync signals. Bit MRV_GEN_CFG_UPD has to be set. Bit
-+ * isp_on_shd in isp_flags_shd is set when the output formatter is
-+ * started. A recognized frame end is signaled with ris_out_frame_end
-+ * in isp_ris.
-+ */
-+
-+ /*
-+ * The configuration of the input acquisition and the output
-+ * formatter has to be correct to generate proper internal sync
-+ * signals and thus a proper frame-synchronous update signal.
-+ */
-+
-+ /* If the output formatter does not start check the following:
-+ * sync polarities
-+ * sample edge
-+ * mode in register isp_ctrl
-+ * sampling window of input acquisition <= picture size of image
-+ * sensor
-+ * output formatter window <= sampling window of input
-+ * acquisition
-+ */
-+
-+ /*
-+ * If problems with the window sizes are suspected preferably add some
-+ * offsets and reduce the window sizes, so that the above relations
-+ * are true by all means.
-+ */
-+
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, ENABLE);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ /*
-+ * MRV_ISP_ISP_CFG_UPD is used instead of
-+ * MRV_ISP_ISP_GEN_CFG_UPD. This updates the configuration
-+ * right away and MARVIN is ready to aquire the next incoming
-+ * frame.
-+ */
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_CFG_UPD, ENABLE);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ /* no update from within this function
-+ * but enable ISP and Input */
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_INFORM_ENABLE, ENABLE);
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_ENABLE, ENABLE);
-+ REG_WRITE(mrv_reg->isp_ctrl, isp_ctrl);
-+
-+ dprintk(3, "ISP_CTRL = 0x%08X", mrv_reg->isp_ctrl);
-+}
-+
-+/*
-+ * Clear frame end interrupt to allow waiting in
-+ * ci_isp_wait_for_frame_end(). Disable output formatter (frame
-+ * synchronously).
-+ */
-+void ci_isp_stop(enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_ctrl = REG_READ(mrv_reg->isp_ctrl);
-+ u32 eof_irq_mask = ci_isp_get_frame_end_irq_mask_isp();
-+
-+ /* clear frame end interrupt */
-+ REG_WRITE(mrv_reg->mi_icr, eof_irq_mask);
-+ /* disable output formatter */
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_ENABLE, DISABLE);
-+
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, ENABLE);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_CFG_UPD, ENABLE);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ REG_WRITE(mrv_reg->isp_ctrl, isp_ctrl);
-+}
-+
-+/*
-+ * Changes the data path settings.
-+ */
-+int ci_isp_set_data_path(enum ci_isp_ycs_chn_mode ycs_chn_mode,
-+ enum ci_isp_dp_switch dp_switch)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 vi_dpcl = REG_READ(mrv_reg->vi_dpcl);
-+ u32 vi_chan_mode;
-+ u32 vi_mp_mux;
-+
-+ /* get desired setting for ycs_chan_mode (or vi_chan_mode) bits */
-+ switch (ycs_chn_mode) {
-+ case CI_ISP_YCS_OFF:
-+ vi_chan_mode = MRV_VI_CHAN_MODE_OFF;
-+ break;
-+ case CI_ISP_YCS_Y:
-+ vi_chan_mode = MRV_VI_CHAN_MODE_Y;
-+ break;
-+ case CI_ISP_YCS_MVRaw:
-+ vi_chan_mode = MRV_VI_CHAN_MODE_MP_RAW;
-+ break;
-+ case CI_ISP_YCS_MV:
-+ vi_chan_mode = MRV_VI_CHAN_MODE_MP;
-+ break;
-+ case CI_ISP_YCS_SP:
-+ vi_chan_mode = MRV_VI_CHAN_MODE_SP;
-+ break;
-+ case CI_ISP_YCS_MV_SP:
-+ vi_chan_mode = MRV_VI_CHAN_MODE_MP_SP;
-+ break;
-+ default:
-+ eprintk("unknown value for ycs_chn_mode");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ if (vi_chan_mode & ~(MRV_VI_CHAN_MODE_MASK >> MRV_VI_CHAN_MODE_SHIFT)) {
-+ eprintk("enum ci_isp_ycs_chn_mode not supported");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* get desired setting for vi_dp_switch (or vi_dp_mux) bits */
-+ switch (dp_switch) {
-+ case CI_ISP_DP_RAW:
-+ vi_mp_mux = MRV_VI_MP_MUX_RAW;
-+ break;
-+ case CI_ISP_DP_JPEG:
-+ vi_mp_mux = MRV_VI_MP_MUX_JPEG;
-+ break;
-+ case CI_ISP_DP_MV:
-+ vi_mp_mux = MRV_VI_MP_MUX_MP;
-+ break;
-+ default:
-+ eprintk("unknown value for dp_switch");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ if (vi_mp_mux & ~MRV_VI_MP_MUX_MASK) {
-+ eprintk("dp_switch value not supported");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* program settings into MARVIN vi_dpcl register */
-+ REG_SET_SLICE(vi_dpcl, MRV_VI_CHAN_MODE, vi_chan_mode);
-+ REG_SET_SLICE(vi_dpcl, MRV_VI_MP_MUX, vi_mp_mux);
-+ REG_WRITE(mrv_reg->vi_dpcl, vi_dpcl);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Changes the data path settings to SMIA or MIPI.
-+ */
-+int ci_isp_set_mipi_smia(u32 mode)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 if_select;
-+
-+ /* get desired setting for if_select bits */
-+ switch (mode) {
-+ case SENSOR_MODE_SMIA:
-+ if_select = MRV_IF_SELECT_SMIA;
-+ break;
-+ case SENSOR_MODE_MIPI:
-+ if_select = MRV_IF_SELECT_MIPI;
-+ break;
-+ case SENSOR_MODE_BAYER:
-+ case SENSOR_MODE_BT601:
-+ case SENSOR_MODE_BT656:
-+ case SENSOR_MODE_PICT:
-+ case SENSOR_MODE_DATA:
-+ case SENSOR_MODE_BAY_BT656:
-+ case SENSOR_MODE_RAW_BT656:
-+ if_select = MRV_IF_SELECT_PAR;
-+ break;
-+ default:
-+ eprintk("unknown value for mode");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ /* program settings into MARVIN vi_dpcl register */
-+ REG_SET_SLICE(mrv_reg->vi_dpcl, MRV_IF_SELECT, if_select);
-+
-+ if (if_select == MRV_IF_SELECT_MIPI) {
-+ REG_WRITE(mrv_reg->mipi_ctrl, 0x1001); /*XXX FLUSH_FIFO? */
-+ /* REG_WRITE(mrv_reg->mipi_ctrl, 0x0001); FLUSH_FIFO? */
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Waits until the specified bits becomes signaled in the mi_ris
-+ * register.
-+ */
-+static int ci_isp_wait_for_mi(struct mrst_isp_device *intel, u32 bit_mask)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+#if 0
-+ int ret = 0;
-+ INIT_COMPLETION(intel->mi_complete);
-+ ret = wait_for_completion_interruptible_timeout(&intel->mi_complete,
-+ 10*HZ);
-+ if (ret == 0) {
-+ eprintk("time out in wait for mi");
-+ /*
-+ * Try to recover. Softreset of submodules (but not
-+ * entire marvin) resets processing and status
-+ * information, but not configuration register
-+ * content. Bits are sticky. So we have to clear them.
-+ * Reset affects the MARVIN 1..2 clock cycles after
-+ * the bits are set to high. So we don't have to wait
-+ * in software before clearing them.
-+ */
-+
-+ /*
-+ * Note that only modules with clock enabled will be
-+ * affected.
-+ */
-+ REG_SET_SLICE(mrv_reg->vi_ircl, MRV_VI_ALL_SOFT_RST, ON);
-+ REG_SET_SLICE(mrv_reg->vi_ircl, MRV_VI_ALL_SOFT_RST, OFF);
-+ mdelay(CI_ISP_DELAY_AFTER_RESET);
-+ /*
-+ * isp config update, neccessary to update v/h_size
-+ * into shadow registers
-+ */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_CFG_UPD, ON);
-+ return CI_STATUS_FAILURE;
-+ }
-+ return CI_STATUS_SUCCESS;
-+#endif
-+ u32 irq;
-+ static int err_frame_cnt;
-+ mrst_timer_start();
-+ /*
-+ * Wait for the curr BitMask. If the BitMask is zero, then it's no
-+ * waiting.
-+ */
-+ while ((mrv_reg->mi_ris & bit_mask) != bit_mask) {
-+
-+ irq = REG_READ(mrv_reg->isp_ris);
-+ if (irq & (MRV_ISP_RIS_DATA_LOSS_MASK
-+ | MRV_ISP_RIS_PIC_SIZE_ERR_MASK)){
-+ err_frame_cnt++;
-+ dprintk(1, "irq = 0x%x, err rumber = %d", irq,
-+ err_frame_cnt);
-+ }
-+ if (mrst_get_micro_sec() > 1000) {
-+ /*
-+ * Note: Don't use REG_READ because content of
-+ * registers would be already printed here.
-+ */
-+ dprintk(1, "time out");
-+ mrst_timer_stop();
-+ /*
-+ * Try to recover. Softreset of submodules (but not
-+ * entire marvin) resets processing and status
-+ * information, but not configuration register
-+ * content. Bits are sticky. So we have to clear them.
-+ * Reset affects the MARVIN 1..2 clock cycles after
-+ * the bits are set to high. So we don't have to wait
-+ * in software before clearing them.
-+ */
-+
-+ /*
-+ * Note that only modules with clock enabled will be
-+ * affected.
-+ */
-+ REG_SET_SLICE(mrv_reg->vi_ircl,
-+ MRV_VI_ALL_SOFT_RST, ON);
-+ REG_SET_SLICE(mrv_reg->vi_ircl,
-+ MRV_VI_ALL_SOFT_RST, OFF);
-+ /*mdelay(CI_ISP_DELAY_AFTER_RESET);*/
-+ msleep(CI_ISP_DELAY_AFTER_RESET);
-+ /*
-+ * isp config update, neccessary to update v/h_size
-+ * into shadow registers
-+ */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_CFG_UPD,
-+ ON);
-+ return CI_STATUS_FAILURE;
-+ }
-+ }
-+
-+ mrst_timer_stop();
-+ if (REG_GET_SLICE(mrv_reg->isp_ris, MRV_ISP_RIS_DATA_LOSS))
-+ dprintk(1, "no failure, but MRV_ISPINT_DATA_LOSS");
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Waits until a frame is written to memory (frame end
-+ * interrupt occurs).
-+ * Waits for the frame end interrupt of the memory
-+ * interface.
-+ */
-+int ci_isp_wait_for_frame_end(struct mrst_isp_device *intel)
-+{
-+ return ci_isp_wait_for_mi(intel, ci_isp_get_frame_end_irq_mask_isp());
-+}
-+
-+/*
-+ * Writes '0xFFFFFFFF' into all *_icr registers to clear all
-+ * interrupts.
-+ */
-+void ci_isp_reset_interrupt_status(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /* ISP interrupt clear register */
-+ REG_SET_SLICE(mrv_reg->isp_icr, MRV_ISP_ICR_ALL, ON);
-+ REG_SET_SLICE(mrv_reg->isp_err_clr, MRV_ISP_ALL_ERR, ON);
-+ REG_SET_SLICE(mrv_reg->mi_icr, MRV_MI_ALLIRQS, ON);
-+ /* JPEG error interrupt clear register */
-+ REG_SET_SLICE(mrv_reg->jpe_error_icr, MRV_JPE_ALL_ERR, ON);
-+ /* JPEG status interrupt clear register */
-+ REG_SET_SLICE(mrv_reg->jpe_status_icr, MRV_JPE_ALL_STAT, ON);
-+
-+ REG_WRITE(mrv_reg->mipi_icr, 0xffffffff); /*XXX replace by a macro */
-+}
-+
-+void mrst_isp_disable_interrupt(struct mrst_isp_device *isp)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *)MEM_MRV_REG_BASE;
-+ REG_SET_SLICE(mrv_reg->isp_imsc, MRV_ISP_IMSC_ALL, OFF);
-+ REG_SET_SLICE(mrv_reg->mi_imsc, MRV_MI_ALLIRQS, OFF);
-+ REG_SET_SLICE(mrv_reg->jpe_error_imr, MRV_JPE_ALL_ERR, OFF);
-+ REG_SET_SLICE(mrv_reg->jpe_status_imr, MRV_JPE_ALL_STAT, OFF);
-+ REG_WRITE(mrv_reg->mipi_imsc, 0x00000000);
-+}
-+
-+void mrst_isp_enable_interrupt(struct mrst_isp_device *isp)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *)MEM_MRV_REG_BASE;
-+
-+ REG_SET_SLICE(mrv_reg->isp_imsc, MRV_ISP_IMSC_DATA_LOSS, ON);
-+ REG_SET_SLICE(mrv_reg->isp_imsc, MRV_ISP_IMSC_PIC_SIZE_ERR, ON);
-+
-+ REG_WRITE(mrv_reg->mi_imsc, MRV_MI_MP_FRAME_END_MASK);
-+
-+ REG_SET_SLICE(mrv_reg->mi_imsc, MRV_MI_MBLK_LINE, ON);
-+
-+ REG_SET_SLICE(mrv_reg->jpe_error_imr, MRV_JPE_ALL_ERR, ON);
-+ REG_SET_SLICE(mrv_reg->jpe_status_imr, MRV_JPE_ALL_STAT, ON);
-+
-+ REG_WRITE(mrv_reg->mipi_imsc, 0x00f00000);
-+
-+ ci_isp_reset_interrupt_status();
-+}
-+
-+/*
-+ * Selects DMA read mode (i.e. sink of the data read from system
-+ * memory by the DMA-read block).
-+ * update_time is only used on Marvin3plus,
-+ * on all other Marvin derivates immediate update is made
-+ */
-+void ci_isp_set_dma_read_mode(enum ci_isp_dma_read_mode mode,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ /* added to avoid LINT warnings (Info 530) */
-+ u32 vi_dma_switch = 0;
-+ /* added to avoid LINT warnings (Info 530) */
-+ u32 vi_dma_spmux = 0;
-+ /* added to avoid LINT warnings (Info 530) */
-+ u32 vi_dma_iemux = 0;
-+ /* added to avoid LINT warnings (Info 530) */
-+ int dma_jpeg_select = false;
-+
-+ u32 vi_dpcl = REG_READ(mrv_reg->vi_dpcl);
-+
-+ /*
-+ * DMA-read feature connected through a dedicated DMA-read
-+ * multiplexer.
-+ */
-+
-+ /* Programming is done via vi_dpcl register only */
-+#define DMA_READ_MODE_PROGRAMMING_VI_SPMCL 0
-+#define DMA_READ_MODE_PROGRAMMING_VI_DPCL 1
-+ WARN_ON(!((mode == CI_ISP_DMA_RD_OFF) ||
-+ (mode == CI_ISP_DMA_RD_SELF_PATH) ||
-+ (mode == CI_ISP_DMA_RD_IE_PATH) ||
-+ (mode == CI_ISP_DMA_RD_SUPERIMPOSE)));
-+
-+ switch (mode) {
-+ case CI_ISP_DMA_RD_OFF:
-+ vi_dma_switch = MRV_VI_DMA_SWITCH_SELF;
-+ vi_dma_spmux = MRV_VI_DMA_SPMUX_CAM;
-+ vi_dma_iemux = MRV_VI_DMA_IEMUX_CAM;
-+ dma_jpeg_select = false;
-+ break;
-+ case CI_ISP_DMA_RD_SELF_PATH:
-+ vi_dma_switch = MRV_VI_DMA_SWITCH_SELF;
-+ vi_dma_spmux = MRV_VI_DMA_SPMUX_DMA;
-+ vi_dma_iemux = MRV_VI_DMA_IEMUX_CAM;
-+ dma_jpeg_select = false;
-+ break;
-+ case CI_ISP_DMA_RD_IE_PATH:
-+ vi_dma_switch = MRV_VI_DMA_SWITCH_IE;
-+ vi_dma_spmux = MRV_VI_DMA_SPMUX_CAM;
-+ vi_dma_iemux = MRV_VI_DMA_IEMUX_DMA;
-+ dma_jpeg_select = false;
-+ break;
-+ case CI_ISP_DMA_RD_JPG_ENC:
-+ vi_dma_switch = MRV_VI_DMA_SWITCH_JPG;
-+ vi_dma_spmux = MRV_VI_DMA_SPMUX_CAM;
-+ vi_dma_iemux = MRV_VI_DMA_IEMUX_CAM;
-+ dma_jpeg_select = true;
-+ break;
-+ case CI_ISP_DMA_RD_SUPERIMPOSE:
-+ vi_dma_switch = MRV_VI_DMA_SWITCH_SI;
-+ vi_dma_spmux = MRV_VI_DMA_SPMUX_CAM;
-+ vi_dma_iemux = MRV_VI_DMA_IEMUX_CAM;
-+ dma_jpeg_select = false;
-+ break;
-+ default:
-+ /* unknown DMA-read mode */
-+ WARN_ON(1);
-+ }
-+
-+ REG_SET_SLICE(vi_dpcl, MRV_VI_DMA_SWITCH, vi_dma_switch);
-+ REG_SET_SLICE(vi_dpcl, MRV_VI_DMA_SPMUX, vi_dma_spmux);
-+ REG_SET_SLICE(vi_dpcl, MRV_VI_DMA_IEMUX, vi_dma_iemux);
-+#if ((MRV_VI_MP_MUX_JPGDIRECT & \
-+~(MRV_VI_MP_MUX_MASK >> MRV_VI_MP_MUX_SHIFT)) == 0)
-+ if (dma_jpeg_select) {
-+ REG_SET_SLICE(vi_dpcl, MRV_VI_MP_MUX,
-+ MRV_VI_MP_MUX_JPGDIRECT);
-+ }
-+#else
-+ /* direct DMA to JPEG not supported */
-+ UNUSED_PARAM(dma_jpeg_select);
-+#endif
-+ REG_WRITE(mrv_reg->vi_dpcl, vi_dpcl);
-+}
-+
-+/*
-+ * Set extended mode with unrestricted values for YCbCr
-+ * Y (0-255) CbCr (0-255)
-+ */
-+void ci_isp_set_ext_ycmode(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_ctrl = REG_READ(mrv_reg->isp_ctrl);
-+
-+ /* modify isp_ctrl register */
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_CSM_C_RANGE,
-+ MRV_ISP_ISP_CSM_C_RANGE_FULL);
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_CSM_Y_RANGE,
-+ MRV_ISP_ISP_CSM_Y_RANGE_FULL);
-+ REG_WRITE(mrv_reg->isp_ctrl, isp_ctrl);
-+
-+ /* program RGB to YUV color conversion with extended range */
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_0, MRV_ISP_CC_COEFF_0, 0x0026);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_1, MRV_ISP_CC_COEFF_1, 0x004B);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_2, MRV_ISP_CC_COEFF_2, 0x000F);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_3, MRV_ISP_CC_COEFF_3, 0x01EA);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_4, MRV_ISP_CC_COEFF_4, 0x01D6);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_5, MRV_ISP_CC_COEFF_5, 0x0040);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_6, MRV_ISP_CC_COEFF_6, 0x0040);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_7, MRV_ISP_CC_COEFF_7, 0x01CA);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_8, MRV_ISP_CC_COEFF_8, 0x01F6);
-+}
-+
-+void ci_isp_set_yc_mode(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *)MEM_MRV_REG_BASE;
-+ u32 isp_ctrl = REG_READ(mrv_reg->isp_ctrl);
-+
-+ /* modify isp_ctrl register */
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_CSM_C_RANGE,
-+ MRV_ISP_ISP_CSM_Y_RANGE_BT601);
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_CSM_Y_RANGE,
-+ MRV_ISP_ISP_CSM_Y_RANGE_BT601);
-+ REG_WRITE(mrv_reg->isp_ctrl, isp_ctrl);
-+
-+ /* program RGB to YUV color conversion with extended range */
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_0, MRV_ISP_CC_COEFF_0, 0x0021);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_1, MRV_ISP_CC_COEFF_1, 0x0040);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_2, MRV_ISP_CC_COEFF_2, 0x000D);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_3, MRV_ISP_CC_COEFF_3, 0x01ED);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_4, MRV_ISP_CC_COEFF_4, 0x01DB);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_5, MRV_ISP_CC_COEFF_5, 0x0038);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_6, MRV_ISP_CC_COEFF_6, 0x0038);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_7, MRV_ISP_CC_COEFF_7, 0x01D1);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_8, MRV_ISP_CC_COEFF_8, 0x01F7);
-+}
-+
-+/*
-+ * writes the color values for contrast, brightness,
-+ * saturation and hue into the appropriate Marvin
-+ * registers
-+ */
-+void ci_isp_col_set_color_processing(
-+ const struct ci_isp_color_settings *col)
-+{
-+ struct isp_register *mrv_reg =
-+ (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (col == NULL) {
-+ /* disable color processing (bypass) */
-+ mrv_reg->c_proc_ctrl = 0;
-+ } else {
-+ mrv_reg->c_proc_contrast = col->contrast;
-+ mrv_reg->c_proc_brightness = col->brightness;
-+ mrv_reg->c_proc_saturation = col->saturation;
-+ mrv_reg->c_proc_hue = col->hue;
-+
-+ /* modify color processing registers */
-+
-+ if (col->flags & CI_ISP_CPROC_C_OUT_RANGE) {
-+ mrv_reg->c_proc_ctrl =
-+ mrv_reg->c_proc_ctrl | CI_ISP_CPROC_C_OUT_RANGE;
-+ }
-+
-+ if (col->flags & CI_ISP_CPROC_Y_IN_RANGE) {
-+ mrv_reg->c_proc_ctrl =
-+ mrv_reg->c_proc_ctrl | CI_ISP_CPROC_Y_IN_RANGE;
-+ }
-+
-+ if (col->flags & CI_ISP_CPROC_Y_OUT_RANGE) {
-+ mrv_reg->c_proc_ctrl =
-+ mrv_reg->c_proc_ctrl | CI_ISP_CPROC_Y_OUT_RANGE;
-+ }
-+
-+ if (col->flags & CI_ISP_CPROC_ENABLE) {
-+ mrv_reg->c_proc_ctrl =
-+ mrv_reg->c_proc_ctrl | CI_ISP_CPROC_ENABLE;
-+ }
-+ }
-+}
-+
-+/*
-+ * Translates a chrominance component value from usual
-+ * representation (range 16..240, 128=neutral grey)
-+ * to the one used by the ie_tint register
-+ * The value is returned as 32 bit unsigned to support shift
-+ * operation without explicit cast.
-+ * The translation formular implemented here is taken from
-+ * the image effects functional specification document,
-+ * Doc-ID 30-001-481.130, revision 1.1 from november, 21st. 2005
-+ */
-+static u32 ci_isp_ie_tint_cx2_reg_val(u8 cx)
-+{
-+ s32 temp;
-+ u32 reg_val;
-+
-+ /*
-+ * apply scaling as specified in the image effects functional
-+ * specification
-+ */
-+ temp = 128 - (s32) cx;
-+ temp = ((temp * 64) / 110);
-+
-+ /* convert from two's complement to sign/value */
-+ if (temp < 0) {
-+ reg_val = 0x80;
-+ temp *= (-1);
-+ } else
-+ reg_val = 0;
-+
-+ /* saturate at 7 bits */
-+ if (temp > 0x7F)
-+ temp = 0x7F;
-+
-+ /* combine sign and value to build the regiter value */
-+ reg_val |= (u32) temp;
-+
-+ return reg_val;
-+}
-+
-+/*
-+ * Translates usual (decimal) matrix coefficient into the
-+ * 4 bit register representation (used in the ie_mat_X registers).
-+ * for unsupported decimal numbers, a supported replacement is
-+ * selected automatically.
-+ * The value is returned as 32 bit unsigned to support shift
-+ * operation without explicit cast.
-+ * The translation formular implemented here is taken from
-+ * the image effects functional specification document,
-+ * Doc-ID 30-001-481.130, revision 1.1 from november, 21st. 2005
-+ */
-+static u32 ci_isp_ie_mx_dec2_reg_val(s8 dec)
-+{
-+ if (dec <= (-6)) {
-+ /* equivlent to -8 */
-+ return 0x0f;
-+ } else if (dec <= (-3)) {
-+ /* equivlent to -4 */
-+ return 0x0e;
-+ } else if (dec == (-2)) {
-+ /* equivlent to -2 */
-+ return 0x0d;
-+ } else if (dec == (-1)) {
-+ /* equivlent to -1 */
-+ return 0x0c;
-+ } else if (dec == 0) {
-+ /* equivlent to 0 (entry not used) */
-+ return 0x00;
-+ } else if (dec == 1) {
-+ /* equivlent to 1 */
-+ return 0x08;
-+ } else if (dec == 2) {
-+ /* equivlent to 2 */
-+ return 0x09;
-+ } else if (dec < 6) {
-+ /* equivlent to 4 */
-+ return 0x0a;
-+ } else {
-+ /* equivlent to 8 */
-+ return 0x0b;
-+ }
-+}
-+
-+/*
-+ * translates the values of the given configuration
-+ * structure into register settings for the image effects
-+ * submodule and loads the registers.
-+ */
-+int ci_isp_ie_set_config(const struct ci_isp_ie_config *ie_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!ie_config) {
-+ /* just disable the module, i.e. put it in bypass mode */
-+ REG_SET_SLICE(mrv_reg->img_eff_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_BYPASS);
-+ } else {
-+ /* apply the given settings */
-+ u32 ul_ie_ctrl = REG_READ(mrv_reg->img_eff_ctrl);
-+ u32 ul_ie_csel = REG_READ(mrv_reg->img_eff_color_sel);
-+ u32 ul_ie_tint = REG_READ(mrv_reg->img_eff_tint);
-+ u32 ul_ie_mat1 = REG_READ(mrv_reg->img_eff_mat_1);
-+ u32 ul_ie_mat2 = REG_READ(mrv_reg->img_eff_mat_2);
-+ u32 ul_ie_mat3 = REG_READ(mrv_reg->img_eff_mat_3);
-+ u32 ul_ie_mat4 = REG_READ(mrv_reg->img_eff_mat_4);
-+ u32 ul_ie_mat5 = REG_READ(mrv_reg->img_eff_mat_5);
-+
-+ /* overall operation mode */
-+ switch (ie_config->mode) {
-+ case CI_ISP_IE_MODE_OFF:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_BYPASS);
-+ break;
-+ case CI_ISP_IE_MODE_GRAYSCALE:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_EFFECT_MODE,
-+ MRV_IMGEFF_EFFECT_MODE_GRAY);
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_PROCESS);
-+ break;
-+ case CI_ISP_IE_MODE_NEGATIVE:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_EFFECT_MODE,
-+ MRV_IMGEFF_EFFECT_MODE_NEGATIVE);
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_PROCESS);
-+ break;
-+ case CI_ISP_IE_MODE_SEPIA:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_EFFECT_MODE,
-+ MRV_IMGEFF_EFFECT_MODE_SEPIA);
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_PROCESS);
-+ break;
-+ case CI_ISP_IE_MODE_COLOR_SEL:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_EFFECT_MODE,
-+ MRV_IMGEFF_EFFECT_MODE_COLOR_SEL);
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_PROCESS);
-+ break;
-+ case CI_ISP_IE_MODE_EMBOSS:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_EFFECT_MODE,
-+ MRV_IMGEFF_EFFECT_MODE_EMBOSS);
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_PROCESS);
-+ break;
-+ case CI_ISP_IE_MODE_SKETCH:
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_EFFECT_MODE,
-+ MRV_IMGEFF_EFFECT_MODE_SKETCH);
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_BYPASS_MODE,
-+ MRV_IMGEFF_BYPASS_MODE_PROCESS);
-+ break;
-+ default:
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+
-+ /* use next frame sync update */
-+ REG_SET_SLICE(ul_ie_ctrl, MRV_IMGEFF_CFG_UPD, ON);
-+
-+ /* color selection settings */
-+ REG_SET_SLICE(ul_ie_csel, MRV_IMGEFF_COLOR_THRESHOLD,
-+ (u32) (ie_config->color_thres));
-+ REG_SET_SLICE(ul_ie_csel, MRV_IMGEFF_COLOR_SELECTION,
-+ (u32) (ie_config->color_sel));
-+
-+ /* tint color settings */
-+ REG_SET_SLICE(ul_ie_tint, MRV_IMGEFF_INCR_CB,
-+ ci_isp_ie_tint_cx2_reg_val(ie_config->tint_cb));
-+ REG_SET_SLICE(ul_ie_tint, MRV_IMGEFF_INCR_CR,
-+ ci_isp_ie_tint_cx2_reg_val(ie_config->tint_cr));
-+
-+ /* matrix coefficients */
-+ REG_SET_SLICE(ul_ie_mat1, MRV_IMGEFF_EMB_COEF_11_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_11));
-+ REG_SET_SLICE(ul_ie_mat1, MRV_IMGEFF_EMB_COEF_12_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_12));
-+ REG_SET_SLICE(ul_ie_mat1, MRV_IMGEFF_EMB_COEF_13_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_13));
-+ REG_SET_SLICE(ul_ie_mat1, MRV_IMGEFF_EMB_COEF_21_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_21));
-+ REG_SET_SLICE(ul_ie_mat2, MRV_IMGEFF_EMB_COEF_22_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_22));
-+ REG_SET_SLICE(ul_ie_mat2, MRV_IMGEFF_EMB_COEF_23_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_23));
-+ REG_SET_SLICE(ul_ie_mat2, MRV_IMGEFF_EMB_COEF_31_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_31));
-+ REG_SET_SLICE(ul_ie_mat2, MRV_IMGEFF_EMB_COEF_32_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_32));
-+ REG_SET_SLICE(ul_ie_mat3, MRV_IMGEFF_EMB_COEF_33_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_emboss.
-+ coeff_33));
-+ REG_SET_SLICE(ul_ie_mat3, MRV_IMGEFF_SKET_COEF_11_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_11));
-+ REG_SET_SLICE(ul_ie_mat3, MRV_IMGEFF_SKET_COEF_12_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_12));
-+ REG_SET_SLICE(ul_ie_mat3, MRV_IMGEFF_SKET_COEF_13_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_13));
-+ REG_SET_SLICE(ul_ie_mat4, MRV_IMGEFF_SKET_COEF_21_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_21));
-+ REG_SET_SLICE(ul_ie_mat4, MRV_IMGEFF_SKET_COEF_22_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_22));
-+ REG_SET_SLICE(ul_ie_mat4, MRV_IMGEFF_SKET_COEF_23_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_23));
-+ REG_SET_SLICE(ul_ie_mat4, MRV_IMGEFF_SKET_COEF_31_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_31));
-+ REG_SET_SLICE(ul_ie_mat5, MRV_IMGEFF_SKET_COEF_32_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_32));
-+ REG_SET_SLICE(ul_ie_mat5, MRV_IMGEFF_SKET_COEF_33_4,
-+ ci_isp_ie_mx_dec2_reg_val(ie_config->mat_sketch.
-+ coeff_33));
-+
-+ /* write changed values back to registers */
-+ REG_WRITE(mrv_reg->img_eff_ctrl, ul_ie_ctrl);
-+ REG_WRITE(mrv_reg->img_eff_color_sel, ul_ie_csel);
-+ REG_WRITE(mrv_reg->img_eff_tint, ul_ie_tint);
-+ REG_WRITE(mrv_reg->img_eff_mat_1, ul_ie_mat1);
-+ REG_WRITE(mrv_reg->img_eff_mat_2, ul_ie_mat2);
-+ REG_WRITE(mrv_reg->img_eff_mat_3, ul_ie_mat3);
-+ REG_WRITE(mrv_reg->img_eff_mat_4, ul_ie_mat4);
-+ REG_WRITE(mrv_reg->img_eff_mat_5, ul_ie_mat5);
-+
-+ /* frame synchronous update of shadow registers */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, ON);
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Applies the new image stabilisation settings to the module.
-+ */
-+int ci_isp_is_set_config(const struct ci_isp_is_config *is_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!is_config) {
-+ eprintk("is_config NULL");
-+ return CI_STATUS_NULL_POINTER;
-+ }
-+
-+ /* set maximal margin distance for X */
-+ if (is_config->max_dx > MRV_IS_IS_MAX_DX_MAX) {
-+ REG_SET_SLICE(mrv_reg->isp_is_max_dx, MRV_IS_IS_MAX_DX,
-+ (u32) (MRV_IS_IS_MAX_DX_MAX));
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_is_max_dx, MRV_IS_IS_MAX_DX,
-+ (u32) (is_config->max_dx));
-+ }
-+
-+ /* set maximal margin distance for Y */
-+ if (is_config->max_dy > MRV_IS_IS_MAX_DY_MAX) {
-+ REG_SET_SLICE(mrv_reg->isp_is_max_dy, MRV_IS_IS_MAX_DY,
-+ (u32) (MRV_IS_IS_MAX_DY_MAX));
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_is_max_dy, MRV_IS_IS_MAX_DY,
-+ (u32) (is_config->max_dy));
-+ }
-+
-+ /* set H offset */
-+ REG_SET_SLICE(mrv_reg->isp_is_h_offs, MRV_IS_IS_H_OFFS,
-+ (u32) (is_config->mrv_is_window.hoffs));
-+ /* set V offset */
-+ REG_SET_SLICE(mrv_reg->isp_is_v_offs, MRV_IS_IS_V_OFFS,
-+ (u32) (is_config->mrv_is_window.voffs));
-+ /* set H size */
-+ REG_SET_SLICE(mrv_reg->isp_is_h_size, MRV_IS_IS_H_SIZE,
-+ (u32) (is_config->mrv_is_window.hsize));
-+ /* set V size */
-+ REG_SET_SLICE(mrv_reg->isp_is_v_size, MRV_IS_IS_V_SIZE,
-+ (u32) (is_config->mrv_is_window.vsize));
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+static int ci_isp_bls_set_fixed_values(const struct ci_isp_bls_subtraction
-+ *bls_subtraction)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!bls_subtraction)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ if ((bls_subtraction->fixed_a > MRV_ISP_BLS_FIX_SUB_MAX) ||
-+ (bls_subtraction->fixed_b > MRV_ISP_BLS_FIX_SUB_MAX) ||
-+ (bls_subtraction->fixed_c > MRV_ISP_BLS_FIX_SUB_MAX) ||
-+ (bls_subtraction->fixed_d > MRV_ISP_BLS_FIX_SUB_MAX) ||
-+ (bls_subtraction->fixed_a < (s16) MRV_ISP_BLS_FIX_SUB_MIN) ||
-+ (bls_subtraction->fixed_b < (s16) MRV_ISP_BLS_FIX_SUB_MIN) ||
-+ (bls_subtraction->fixed_c < (s16) MRV_ISP_BLS_FIX_SUB_MIN) ||
-+ (bls_subtraction->fixed_d < (s16) MRV_ISP_BLS_FIX_SUB_MIN)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ } else {
-+ /* we are in this path */
-+ REG_SET_SLICE(mrv_reg->isp_bls_a_fixed, MRV_BLS_BLS_A_FIXED,
-+ bls_subtraction->fixed_a);
-+ REG_SET_SLICE(mrv_reg->isp_bls_b_fixed, MRV_BLS_BLS_B_FIXED, \
-+ bls_subtraction->fixed_b);
-+ REG_SET_SLICE(mrv_reg->isp_bls_c_fixed, MRV_BLS_BLS_C_FIXED,
-+ bls_subtraction->fixed_c);
-+ REG_SET_SLICE(mrv_reg->isp_bls_d_fixed, MRV_BLS_BLS_D_FIXED,
-+ bls_subtraction->fixed_d);
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Sets the desired configuration values to the BLS registers,
-+ * if possible. In the case the parameter (bls_config == NULL)
-+ * the BLS module will be deactivated.
-+ */
-+int ci_isp_bls_set_config(const struct ci_isp_bls_config *bls_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_bls_ctrl = 0;
-+
-+ int error = CI_STATUS_FAILURE;
-+
-+ if (!bls_config) {
-+ /* disable the BLS module */
-+ REG_SET_SLICE(mrv_reg->isp_bls_ctrl,
-+ MRV_BLS_BLS_ENABLE, DISABLE);
-+ return CI_STATUS_SUCCESS;
-+ }
-+
-+ /* measurement window 2, enable_window =0 */
-+ if (bls_config->isp_bls_window2.enable_window) {
-+ if ((bls_config->isp_bls_window2.start_h >
-+ MRV_BLS_BLS_H2_START_MAX)
-+ || (bls_config->isp_bls_window2.stop_h >
-+ MRV_BLS_BLS_H2_STOP_MAX)
-+ || (bls_config->isp_bls_window2.start_v >
-+ MRV_BLS_BLS_V2_START_MAX)
-+ || (bls_config->isp_bls_window2.stop_v >
-+ MRV_BLS_BLS_V2_STOP_MAX)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_bls_h2_start,
-+ MRV_BLS_BLS_H2_START,
-+ bls_config->isp_bls_window2.start_h);
-+ REG_SET_SLICE(mrv_reg->isp_bls_h2_stop,
-+ MRV_BLS_BLS_H2_STOP,
-+ bls_config->isp_bls_window2.stop_h);
-+ REG_SET_SLICE(mrv_reg->isp_bls_v2_start,
-+ MRV_BLS_BLS_V2_START,
-+ bls_config->isp_bls_window2.start_v);
-+ REG_SET_SLICE(mrv_reg->isp_bls_v2_stop,
-+ MRV_BLS_BLS_V2_STOP,
-+ bls_config->isp_bls_window2.stop_v);
-+ }
-+ }
-+
-+ /* measurement window 1, enable_window=0 */
-+ if (bls_config->isp_bls_window1.enable_window) {
-+ if ((bls_config->isp_bls_window1.start_h >
-+ MRV_BLS_BLS_H1_START_MAX)
-+ || (bls_config->isp_bls_window1.stop_h >
-+ MRV_BLS_BLS_H1_STOP_MAX)
-+ || (bls_config->isp_bls_window1.start_v >
-+ MRV_BLS_BLS_V1_START_MAX)
-+ || (bls_config->isp_bls_window1.stop_v >
-+ MRV_BLS_BLS_V1_STOP_MAX)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_bls_h1_start,
-+ MRV_BLS_BLS_H1_START,
-+ bls_config->isp_bls_window1.start_h);
-+ REG_SET_SLICE(mrv_reg->isp_bls_h1_stop,
-+ MRV_BLS_BLS_H1_STOP,
-+ bls_config->isp_bls_window1.stop_h);
-+ REG_SET_SLICE(mrv_reg->isp_bls_v1_start,
-+ MRV_BLS_BLS_V1_START,
-+ bls_config->isp_bls_window1.start_v);
-+ REG_SET_SLICE(mrv_reg->isp_bls_v1_stop,
-+ MRV_BLS_BLS_V1_STOP,
-+ bls_config->isp_bls_window1.stop_v);
-+ }
-+ }
-+
-+ if (bls_config->bls_samples > MRV_BLS_BLS_SAMPLES_MAX) {
-+ return CI_STATUS_OUTOFRANGE;
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_bls_samples, MRV_BLS_BLS_SAMPLES,
-+ bls_config->bls_samples);
-+ }
-+
-+ /* fixed subtraction values, enable_automatic=0 */
-+ if (!bls_config->enable_automatic) {
-+ error = ci_isp_bls_set_fixed_values(
-+ &(bls_config->bls_subtraction));
-+ if (error != CI_STATUS_SUCCESS)
-+ return error;
-+ }
-+
-+ if ((bls_config->disable_h) || (bls_config->disable_v))
-+ return CI_STATUS_OUTOFRANGE;
-+
-+ isp_bls_ctrl = REG_READ(mrv_reg->isp_bls_ctrl);
-+
-+ /* enable measurement window(s) */
-+ REG_SET_SLICE(isp_bls_ctrl, MRV_BLS_WINDOW_ENABLE,
-+ ((bls_config->isp_bls_window1.enable_window)
-+ ? MRV_BLS_WINDOW_ENABLE_WND1 : 0) |
-+ ((bls_config->isp_bls_window2.enable_window)
-+ ? MRV_BLS_WINDOW_ENABLE_WND2 : 0));
-+
-+ /* set Mode */
-+ REG_SET_SLICE(isp_bls_ctrl, MRV_BLS_BLS_MODE,
-+ (bls_config->enable_automatic) ? MRV_BLS_BLS_MODE_MEAS :
-+ MRV_BLS_BLS_MODE_FIX);
-+
-+ /* enable module */
-+ REG_SET_SLICE(isp_bls_ctrl, MRV_BLS_BLS_ENABLE, ENABLE);
-+
-+ /* write into register */
-+ REG_WRITE(mrv_reg->isp_bls_ctrl, isp_bls_ctrl);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+#define RSZ_FLAGS_MASK (RSZ_UPSCALE_ENABLE | RSZ_SCALER_BYPASS)
-+
-+/*
-+ * writes the scaler values to the appropriate Marvin registers.
-+ */
-+void ci_isp_res_set_main_resize(const struct ci_isp_scale *scale,
-+ enum ci_isp_conf_update_time update_time,
-+ const struct ci_isp_rsz_lut *rsz_lut)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 mrsz_ctrl = REG_READ(mrv_reg->mrsz_ctrl);
-+ u32 i;
-+ int upscaling = false;
-+
-+ /* flags must be "outside" scaler value */
-+ WARN_ON(!((RSZ_FLAGS_MASK & MRV_RSZ_SCALE_MASK) == 0));
-+ WARN_ON(!((scale->scale_hy & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_hcb & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_hcr & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_vy & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_vc & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+
-+ /* horizontal luminance scale factor */
-+ dprintk(1, "scale_hy = %d( %x )", scale->scale_hy, scale->scale_hy);
-+
-+ if (scale->scale_hy & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HY_ENABLE, DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HY_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_hy, MRV_MRSZ_SCALE_HY,
-+ (u32) scale->scale_hy);
-+ REG_SET_SLICE(mrv_reg->mrsz_phase_hy, MRV_MRSZ_PHASE_HY,
-+ (u32) scale->phase_hy);
-+
-+ if (scale->scale_hy & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ dprintk(1, "enable up scale");
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HY_UP,
-+ MRV_MRSZ_SCALE_HY_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HY_UP,
-+ MRV_MRSZ_SCALE_HY_UP_DOWNSCALE);
-+ }
-+
-+ /* horizontal chrominance scale factors */
-+ WARN_ON(!((scale->scale_hcb & RSZ_FLAGS_MASK) == (scale->scale_hcr &
-+ RSZ_FLAGS_MASK)));
-+ dprintk(1, "scale_hcb = %d( %x )", scale->scale_hcb, scale->scale_hcb);
-+
-+ if (scale->scale_hcb & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HC_ENABLE, DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HC_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_hcb, MRV_MRSZ_SCALE_HCB,
-+ (u32) scale->scale_hcb);
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_hcr, MRV_MRSZ_SCALE_HCB,
-+ (u32) scale->scale_hcr);
-+ REG_SET_SLICE(mrv_reg->mrsz_phase_hc, MRV_MRSZ_PHASE_HC,
-+ (u32) scale->phase_hc);
-+
-+ if (scale->scale_hcb & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HC_UP,
-+ MRV_MRSZ_SCALE_HC_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_HC_UP,
-+ MRV_MRSZ_SCALE_HC_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* vertical luminance scale factor */
-+ dprintk(1, "scale_vy = %d ( %x )", scale->scale_vy, scale->scale_vy);
-+
-+ if (scale->scale_vy & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VY_ENABLE,
-+ DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VY_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_vy, MRV_MRSZ_SCALE_VY,
-+ (u32) scale->scale_vy);
-+ REG_SET_SLICE(mrv_reg->mrsz_phase_vy, MRV_MRSZ_PHASE_VY,
-+ (u32) scale->phase_vy);
-+
-+ if (scale->scale_vy & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VY_UP,
-+ MRV_MRSZ_SCALE_VY_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VY_UP,
-+ MRV_MRSZ_SCALE_VY_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* vertical chrominance scale factor */
-+ dprintk(1, "scale_vc = %d( %x )", scale->scale_vc, scale->scale_vc);
-+
-+ if (scale->scale_vc & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VC_ENABLE,
-+ DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VC_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_vc, MRV_MRSZ_SCALE_VC,
-+ (u32) scale->scale_vc);
-+ REG_SET_SLICE(mrv_reg->mrsz_phase_vc, MRV_MRSZ_PHASE_VC,
-+ (u32) scale->phase_vc);
-+
-+ if (scale->scale_vc & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VC_UP,
-+ MRV_MRSZ_SCALE_VC_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_SCALE_VC_UP,
-+ MRV_MRSZ_SCALE_VC_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* apply upscaling lookup table */
-+ if (rsz_lut) {
-+ for (i = 0; i <= MRV_MRSZ_SCALE_LUT_ADDR_MASK; i++) {
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_lut_addr,
-+ MRV_MRSZ_SCALE_LUT_ADDR, i);
-+ REG_SET_SLICE(mrv_reg->mrsz_scale_lut,
-+ MRV_MRSZ_SCALE_LUT,
-+ rsz_lut->rsz_lut[i]);
-+ }
-+ } else if (upscaling) {
-+ eprintk("Upscaling requires lookup table!");
-+ WARN_ON(1);
-+ }
-+
-+ /* handle immediate update flag and write mrsz_ctrl */
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ /* frame synchronous update of shadow registers */
-+ REG_WRITE(mrv_reg->mrsz_ctrl, mrsz_ctrl);
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ /* immediate update of shadow registers */
-+ REG_SET_SLICE(mrsz_ctrl, MRV_MRSZ_CFG_UPD, ON);
-+ REG_WRITE(mrv_reg->mrsz_ctrl, mrsz_ctrl);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ default:
-+ /* no update from within this function */
-+ REG_WRITE(mrv_reg->mrsz_ctrl, mrsz_ctrl);
-+ break;
-+ }
-+}
-+
-+/*
-+ * writes the scaler values to the appropriate Marvin registers.
-+ */
-+void ci_isp_res_set_self_resize(const struct ci_isp_scale *scale,
-+ enum ci_isp_conf_update_time update_time,
-+ const struct ci_isp_rsz_lut *rsz_lut)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 srsz_ctrl = REG_READ(mrv_reg->srsz_ctrl);
-+ u32 i;
-+ int upscaling = false;
-+
-+ /* flags must be "outside" scaler value */
-+ WARN_ON(!((RSZ_FLAGS_MASK & MRV_RSZ_SCALE_MASK) == 0));
-+ WARN_ON(!((scale->scale_hy & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_hcb & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_hcr & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_vy & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+ WARN_ON(!((scale->scale_vc & ~RSZ_FLAGS_MASK) <= MRV_RSZ_SCALE_MAX));
-+
-+ /* horizontal luminance scale factor */
-+ dprintk(1, "scale_hy = %d,%x", scale->scale_hy, scale->scale_hy);
-+
-+ if (scale->scale_hy & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HY_ENABLE,
-+ DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HY_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->srsz_scale_hy, MRV_SRSZ_SCALE_HY,
-+ (u32) scale->scale_hy);
-+ REG_SET_SLICE(mrv_reg->srsz_phase_hy, MRV_SRSZ_PHASE_HY,
-+ (u32) scale->phase_hy);
-+
-+ if (scale->scale_hy & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HY_UP,
-+ MRV_SRSZ_SCALE_HY_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HY_UP,
-+ MRV_SRSZ_SCALE_HY_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* horizontal chrominance scale factors */
-+ WARN_ON(!((scale->scale_hcb & RSZ_FLAGS_MASK) == (scale->scale_hcr &
-+ RSZ_FLAGS_MASK)));
-+
-+ dprintk(1, "scale_hcb = %d,%x", scale->scale_hcb, scale->scale_hcb);
-+
-+ if (scale->scale_hcb & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HC_ENABLE,
-+ DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HC_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->srsz_scale_hcb, MRV_SRSZ_SCALE_HCB,
-+ (u32) scale->scale_hcb);
-+ REG_SET_SLICE(mrv_reg->srsz_scale_hcr, MRV_SRSZ_SCALE_HCB,
-+ (u32) scale->scale_hcr);
-+
-+ REG_SET_SLICE(mrv_reg->srsz_phase_hc, MRV_SRSZ_PHASE_HC,
-+ (u32) scale->phase_hc);
-+
-+ if (scale->scale_hcb & RSZ_UPSCALE_ENABLE) {
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HC_UP,
-+ MRV_SRSZ_SCALE_HC_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_HC_UP,
-+ MRV_SRSZ_SCALE_HC_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* vertical luminance scale factor */
-+ dprintk(1, "scale_vy = %d,%x", scale->scale_vy, scale->scale_vy);
-+
-+ if (scale->scale_vy & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VY_ENABLE,
-+ DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VY_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->srsz_scale_vy, MRV_SRSZ_SCALE_VY,
-+ (u32) scale->scale_vy);
-+ REG_SET_SLICE(mrv_reg->srsz_phase_vy, MRV_SRSZ_PHASE_VY,
-+ (u32) scale->phase_vy);
-+
-+ if (scale->scale_vy & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VY_UP,
-+ MRV_SRSZ_SCALE_VY_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VY_UP,
-+ MRV_SRSZ_SCALE_VY_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* vertical chrominance scale factor */
-+ dprintk(1, "scale_vc = %d,%x", scale->scale_vc, scale->scale_vc);
-+
-+ if (scale->scale_vc & RSZ_SCALER_BYPASS) {
-+ /* disable (bypass) scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VC_ENABLE,
-+ DISABLE);
-+ } else {
-+ /* enable scaler */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VC_ENABLE, ENABLE);
-+ /* program scale factor and phase */
-+ REG_SET_SLICE(mrv_reg->srsz_scale_vc, MRV_SRSZ_SCALE_VC,
-+ (u32) scale->scale_vc);
-+ REG_SET_SLICE(mrv_reg->srsz_phase_vc, MRV_SRSZ_PHASE_VC,
-+ (u32) scale->phase_vc);
-+
-+ if (scale->scale_vc & RSZ_UPSCALE_ENABLE) {
-+ /* enable upscaling mode */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VC_UP,
-+ MRV_SRSZ_SCALE_VC_UP_UPSCALE);
-+ /* scaler and upscaling enabled */
-+ upscaling = true;
-+ } else {
-+ /* disable upscaling mode */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_SCALE_VC_UP,
-+ MRV_SRSZ_SCALE_VC_UP_DOWNSCALE);
-+ }
-+ }
-+
-+ /* apply upscaling lookup table */
-+ if (rsz_lut) {
-+ for (i = 0; i <= MRV_SRSZ_SCALE_LUT_ADDR_MASK; i++) {
-+ REG_SET_SLICE(mrv_reg->srsz_scale_lut_addr,
-+ MRV_SRSZ_SCALE_LUT_ADDR, i);
-+ REG_SET_SLICE(mrv_reg->srsz_scale_lut,
-+ MRV_SRSZ_SCALE_LUT,
-+ rsz_lut->rsz_lut[i]);
-+ }
-+ } else if (upscaling) {
-+ eprintk("Upscaling requires lookup table!");
-+ WARN_ON(1);
-+ }
-+
-+ /* handle immediate update flag and write mrsz_ctrl */
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ /* frame synchronous update of shadow registers */
-+ REG_WRITE(mrv_reg->srsz_ctrl, srsz_ctrl);
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD,
-+ ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ /* immediate update of shadow registers */
-+ REG_SET_SLICE(srsz_ctrl, MRV_SRSZ_CFG_UPD, ON);
-+ REG_WRITE(mrv_reg->srsz_ctrl, srsz_ctrl);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ default:
-+ /* no update from within this function */
-+ REG_WRITE(mrv_reg->srsz_ctrl, srsz_ctrl);
-+ break;
-+ }
-+}
-+
-+#if MRV_SUPPORT_SL
-+
-+/* bad pixel table */
-+static struct ci_sensor_bp_table bp_table = { 0 };
-+
-+/*
-+ * Initialization of the Bad Pixel Detection and Correction.
-+ */
-+int ci_bp_init(const struct ci_isp_bp_corr_config *bp_corr_config,
-+ const struct ci_isp_bp_det_config *bp_det_config)
-+{
-+ int error = CI_STATUS_SUCCESS;
-+
-+ /* number of table elements */
-+ /* number of table elements */
-+#define MRVSLS_BPINIT_MAX_TABLE 2048
-+
-+ /* check the parameters */
-+ if (!bp_corr_config || !bp_det_config)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ if (bp_corr_config->bp_corr_type == CI_ISP_BP_CORR_TABLE) {
-+ /* set badpixel correction */
-+ error |= ci_isp_set_bp_correction(bp_corr_config);
-+ /* set badpixel detection */
-+ error |= ci_isp_set_bp_detection(bp_det_config);
-+ /* zero element inside */
-+ bp_table.bp_number = 0;
-+ if (!bp_table.bp_table_elem) {
-+ /* allocate mem space for the table */
-+ bp_table.bp_table_elem =
-+ (struct ci_sensor_bp_table_elem *)
-+ kmalloc((sizeof(struct ci_sensor_bp_table_elem)*
-+ MRVSLS_BPINIT_MAX_TABLE), GFP_KERNEL);
-+ if (!bp_table.bp_table_elem)
-+ error |= CI_STATUS_FAILURE;
-+ }
-+ /* max count of elements */
-+ bp_table.bp_table_elem_num = MRVSLS_BPINIT_MAX_TABLE;
-+ /* Clear Interrupt Status */
-+ error |= ci_isp_clear_bp_int();
-+ } else {
-+ if (bp_corr_config->bp_corr_type == CI_ISP_BP_CORR_DIRECT) {
-+ /* set badpixel correction */
-+ error |= ci_isp_set_bp_correction(bp_corr_config);
-+ /* set badpixel detection */
-+ error |= ci_isp_set_bp_detection(NULL);
-+ } else {
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ }
-+ return error;
-+}
-+
-+/*
-+ * Disable the Bad Pixel Detection and Correction.
-+ */
-+int ci_bp_end(const struct ci_isp_bp_corr_config *bp_corr_config)
-+{
-+ int uiResult = CI_STATUS_SUCCESS;
-+
-+ /* check the parameter */
-+ if (!bp_corr_config)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ /* disable badpixel correction */
-+ uiResult |= ci_isp_set_bp_correction(NULL);
-+
-+ /* disable badpixel detection */
-+ uiResult |= ci_isp_set_bp_detection(NULL);
-+
-+ if (bp_corr_config->bp_corr_type == CI_ISP_BP_CORR_TABLE) {
-+ /* Clear Interrupt Status */
-+ uiResult |= ci_isp_clear_bp_int();
-+
-+ /* deallocate BP Table */
-+ kfree(bp_table.bp_table_elem);
-+ bp_table.bp_table_elem = NULL;
-+ }
-+ return uiResult;
-+}
-+#endif
-diff --git a/drivers/media/video/mrstci/mrstisp/mrstisp_isp.c b/drivers/media/video/mrstci/mrstisp/mrstisp_isp.c
-new file mode 100644
-index 0000000..7c96bc4
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/mrstisp_isp.c
-@@ -0,0 +1,1993 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * Copyright (c) Silicon Image 2008 www.siliconimage.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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+
-+int mrst_isp_set_color_conversion_ex(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_0, MRV_ISP_CC_COEFF_0, 0x00001021);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_1, MRV_ISP_CC_COEFF_1, 0x00001040);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_2, MRV_ISP_CC_COEFF_2, 0x0000100D);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_3, MRV_ISP_CC_COEFF_3, 0x00000FED);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_4, MRV_ISP_CC_COEFF_4, 0x00000FDB);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_5, MRV_ISP_CC_COEFF_5, 0x00001038);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_6, MRV_ISP_CC_COEFF_6, 0x00001038);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_7, MRV_ISP_CC_COEFF_7, 0x00000FD1);
-+ REG_SET_SLICE(mrv_reg->isp_cc_coeff_8, MRV_ISP_CC_COEFF_8, 0x00000FF7);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Selects the ISP path that will become active while processing
-+ * data coming from an image sensor configured by the given ISI
-+ * configuration struct.
-+ */
-+enum ci_isp_path ci_isp_select_path(const struct ci_sensor_config *isi_cfg,
-+ u8 *words_per_pixel)
-+{
-+ u8 words;
-+ enum ci_isp_path ret_val;
-+
-+ switch (isi_cfg->mode) {
-+ case SENSOR_MODE_DATA:
-+ ret_val = CI_ISP_PATH_RAW;
-+ words = 1;
-+ break;
-+ case SENSOR_MODE_PICT:
-+ ret_val = CI_ISP_PATH_RAW;
-+ words = 1;
-+ break;
-+ case SENSOR_MODE_RGB565:
-+ ret_val = CI_ISP_PATH_RAW;
-+ words = 2;
-+ break;
-+ case SENSOR_MODE_BT601:
-+ ret_val = CI_ISP_PATH_YCBCR;
-+ words = 2;
-+ break;
-+ case SENSOR_MODE_BT656:
-+ ret_val = CI_ISP_PATH_YCBCR;
-+ words = 2;
-+ break;
-+ case SENSOR_MODE_BAYER:
-+ ret_val = CI_ISP_PATH_BAYER;
-+ words = 1;
-+ break;
-+
-+ case SENSOR_MODE_SMIA:
-+ switch (isi_cfg->smia_mode) {
-+ case SENSOR_SMIA_MODE_RAW_12:
-+ case SENSOR_SMIA_MODE_RAW_10:
-+ case SENSOR_SMIA_MODE_RAW_8:
-+ case SENSOR_SMIA_MODE_RAW_8_TO_10_DECOMP:
-+ ret_val = CI_ISP_PATH_BAYER;
-+ words = 1;
-+ break;
-+ case SENSOR_SMIA_MODE_YUV_422:
-+ ret_val = CI_ISP_PATH_YCBCR;
-+ words = 2;
-+ break;
-+ case SENSOR_SMIA_MODE_YUV_420:
-+ case SENSOR_SMIA_MODE_RGB_444:
-+ case SENSOR_SMIA_MODE_RGB_565:
-+ case SENSOR_SMIA_MODE_RGB_888:
-+ case SENSOR_SMIA_MODE_COMPRESSED:
-+ case SENSOR_SMIA_MODE_RAW_7:
-+ case SENSOR_SMIA_MODE_RAW_6:
-+ default:
-+ ret_val = CI_ISP_PATH_RAW;
-+ words = 1;
-+ break;
-+ }
-+ break;
-+
-+ case SENSOR_MODE_MIPI:
-+ switch (isi_cfg->mipi_mode) {
-+ case SENSOR_MIPI_MODE_RAW_12:
-+ case SENSOR_MIPI_MODE_RAW_10:
-+ case SENSOR_MIPI_MODE_RAW_8:
-+ ret_val = CI_ISP_PATH_BAYER;
-+ words = 1;
-+ break;
-+ case SENSOR_MIPI_MODE_YUV422_8:
-+ case SENSOR_MIPI_MODE_YUV422_10:
-+ ret_val = CI_ISP_PATH_YCBCR;
-+ words = 2;
-+ break;
-+ case SENSOR_MIPI_MODE_YUV420_8:
-+ case SENSOR_MIPI_MODE_YUV420_10:
-+ case SENSOR_MIPI_MODE_LEGACY_YUV420_8:
-+ case SENSOR_MIPI_MODE_YUV420_CSPS_8:
-+ case SENSOR_MIPI_MODE_YUV420_CSPS_10:
-+ case SENSOR_MIPI_MODE_RGB444:
-+ case SENSOR_MIPI_MODE_RGB555:
-+ case SENSOR_MIPI_MODE_RGB565:
-+ case SENSOR_MIPI_MODE_RGB666:
-+ case SENSOR_MIPI_MODE_RGB888:
-+ case SENSOR_MIPI_MODE_RAW_7:
-+ case SENSOR_MIPI_MODE_RAW_6:
-+ default:
-+ ret_val = CI_ISP_PATH_RAW;
-+ words = 1;
-+ break;
-+ }
-+ break;
-+ case SENSOR_MODE_BAY_BT656:
-+ ret_val = CI_ISP_PATH_BAYER;
-+ words = 1;
-+ break;
-+ case SENSOR_MODE_RAW_BT656:
-+ ret_val = CI_ISP_PATH_RAW;
-+ words = 1;
-+ break;
-+ default:
-+ ret_val = CI_ISP_PATH_UNKNOWN;
-+ words = 1;
-+ }
-+
-+ if (words_per_pixel)
-+ *words_per_pixel = words ;
-+ return ret_val;
-+}
-+
-+/*
-+ * configures the input acquisition according to the
-+ * given config structure
-+ */
-+int ci_isp_set_input_aquisition(const struct ci_sensor_config *isi_cfg)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_ctrl = REG_READ(mrv_reg->isp_ctrl);
-+ u32 isp_acq_prop = REG_READ(mrv_reg->isp_acq_prop);
-+ /* factor between pixel count and amount of bytes to sample */
-+ u8 sample_factor;
-+ /* number of additional black lines at frame start */
-+ u8 black_lines;
-+
-+ if (ci_isp_select_path(isi_cfg, &sample_factor)
-+ == CI_ISP_PATH_UNKNOWN) {
-+ eprintk("failed to select path");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->mode) {
-+ case SENSOR_MODE_DATA:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_DATA);
-+ break;
-+ case SENSOR_MODE_PICT:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_RAW);
-+ break;
-+ case SENSOR_MODE_RGB565:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_RAW);
-+ break;
-+ case SENSOR_MODE_BT601:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_601);
-+ break;
-+ case SENSOR_MODE_BT656:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_656);
-+ break;
-+ case SENSOR_MODE_BAYER:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_RGB);
-+ break;
-+ case SENSOR_MODE_BAY_BT656:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_RGB656);
-+ break;
-+ case SENSOR_MODE_RAW_BT656:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_RAW656);
-+ break;
-+
-+ case SENSOR_MODE_SMIA:
-+ switch (isi_cfg->smia_mode) {
-+ case SENSOR_SMIA_MODE_RAW_12:
-+ case SENSOR_SMIA_MODE_RAW_10:
-+ case SENSOR_SMIA_MODE_RAW_8:
-+ case SENSOR_SMIA_MODE_RAW_8_TO_10_DECOMP:
-+ case SENSOR_SMIA_MODE_RAW_7:
-+ case SENSOR_SMIA_MODE_RAW_6:
-+ case SENSOR_SMIA_MODE_YUV_422:
-+ case SENSOR_SMIA_MODE_YUV_420:
-+ case SENSOR_SMIA_MODE_RGB_888:
-+ case SENSOR_SMIA_MODE_RGB_565:
-+ case SENSOR_SMIA_MODE_RGB_444:
-+ case SENSOR_SMIA_MODE_COMPRESSED:
-+ return CI_STATUS_SUCCESS;
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ break;
-+
-+ case SENSOR_MODE_MIPI:
-+ REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_MODE,
-+ MRV_ISP_ISP_MODE_RGB);
-+ REG_WRITE(mrv_reg->mipi_img_data_sel, 0x02b);
-+ break;
-+
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->bus_width) {
-+ case SENSOR_BUSWIDTH_12BIT:
-+ /* 000- 12Bit external Interface */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_INPUT_SELECTION,
-+ MRV_ISP_INPUT_SELECTION_12EXT);
-+ break;
-+ case SENSOR_BUSWIDTH_10BIT_ZZ:
-+ /* 001- 10Bit Interface, append 2 zeroes as LSBs */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_INPUT_SELECTION,
-+ MRV_ISP_INPUT_SELECTION_10ZERO);
-+ break;
-+ case SENSOR_BUSWIDTH_10BIT_EX:
-+ /* 010- 10Bit Interface, append 2 MSBs as LSBs */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_INPUT_SELECTION,
-+ MRV_ISP_INPUT_SELECTION_10MSB);
-+ break;
-+ case SENSOR_BUSWIDTH_8BIT_ZZ:
-+ /* 011- 8Bit Interface, append 4 zeroes as LSBs */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_INPUT_SELECTION,
-+ MRV_ISP_INPUT_SELECTION_8ZERO);
-+ break;
-+ case SENSOR_BUSWIDTH_8BIT_EX:
-+ /* 100- 8Bit Interface, append 4 MSBs as LSBs */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_INPUT_SELECTION,
-+ MRV_ISP_INPUT_SELECTION_8MSB);
-+ break;
-+ /* 101...111 reserved */
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->field_sel) {
-+ case SENSOR_FIELDSEL_ODD:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_FIELD_SELECTION,
-+ MRV_ISP_FIELD_SELECTION_ODD);
-+ break;
-+ case SENSOR_FIELDSEL_EVEN:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_FIELD_SELECTION,
-+ MRV_ISP_FIELD_SELECTION_EVEN);
-+ break;
-+ case SENSOR_FIELDSEL_BOTH:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_FIELD_SELECTION,
-+ MRV_ISP_FIELD_SELECTION_BOTH);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->ycseq) {
-+ case SENSOR_YCSEQ_CRYCBY:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CCIR_SEQ,
-+ MRV_ISP_CCIR_SEQ_CRYCBY);
-+ break;
-+ case SENSOR_YCSEQ_CBYCRY:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CCIR_SEQ,
-+ MRV_ISP_CCIR_SEQ_CBYCRY);
-+ break;
-+ case SENSOR_YCSEQ_YCRYCB:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CCIR_SEQ,
-+ MRV_ISP_CCIR_SEQ_YCRYCB);
-+ break;
-+ case SENSOR_YCSEQ_YCBYCR:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CCIR_SEQ,
-+ MRV_ISP_CCIR_SEQ_YCBYCR);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->conv422) {
-+ case SENSOR_CONV422_INTER:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CONV_422,
-+ MRV_ISP_CONV_422_INTER);
-+ break;
-+
-+ case SENSOR_CONV422_NOCOSITED:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CONV_422,
-+ MRV_ISP_CONV_422_NONCO);
-+ break;
-+ case SENSOR_CONV422_COSITED:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_CONV_422,
-+ MRV_ISP_CONV_422_CO);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->bpat) {
-+ case SENSOR_BPAT_BGBGGRGR:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_BAYER_PAT,
-+ MRV_ISP_BAYER_PAT_BG);
-+ break;
-+ case SENSOR_BPAT_GBGBRGRG:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_BAYER_PAT,
-+ MRV_ISP_BAYER_PAT_GB);
-+ break;
-+ case SENSOR_BPAT_GRGRBGBG:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_BAYER_PAT,
-+ MRV_ISP_BAYER_PAT_GR);
-+ break;
-+ case SENSOR_BPAT_RGRGGBGB:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_BAYER_PAT,
-+ MRV_ISP_BAYER_PAT_RG);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->vpol) {
-+ case SENSOR_VPOL_POS:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_VSYNC_POL, 1);
-+ break;
-+ case SENSOR_VPOL_NEG:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_VSYNC_POL, 0);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->hpol) {
-+ /* The trigger edge differs for vsync_pol and hsync_pol. */
-+ /* vsync_pol = 1 triggers on positive edge whereas */
-+ /* hsync_pol = 1 triggers on negative edge and vice versa */
-+ case SENSOR_HPOL_SYNCPOS:
-+ /* trigger on negative edge */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_HSYNC_POL, 1);
-+ break;
-+ case SENSOR_HPOL_SYNCNEG:
-+ /* trigger on positive edge */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_HSYNC_POL, 0);
-+ break;
-+ case SENSOR_HPOL_REFPOS:
-+ /* trigger on positive edge */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_HSYNC_POL, 0);
-+ break;
-+ case SENSOR_HPOL_REFNEG:
-+ /* trigger on negative edge */
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_HSYNC_POL, 1);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ switch (isi_cfg->edge) {
-+ case SENSOR_EDGE_RISING:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_SAMPLE_EDGE, 1);
-+ break;
-+ case SENSOR_EDGE_FALLING:
-+ REG_SET_SLICE(isp_acq_prop, MRV_ISP_SAMPLE_EDGE, 0);
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ dprintk(2, "isp_acq_prop = 0x%x", isp_acq_prop);
-+
-+ /* now write values to registers */
-+ REG_WRITE(mrv_reg->isp_ctrl, isp_ctrl);
-+ REG_WRITE(mrv_reg->isp_acq_prop, isp_acq_prop);
-+
-+ /* number of additional black lines at frame start */
-+ switch (isi_cfg->bls) {
-+ case SENSOR_BLS_OFF:
-+ black_lines = 0;
-+ break;
-+ case SENSOR_BLS_TWO_LINES:
-+ black_lines = 2;
-+ break;
-+ case SENSOR_BLS_FOUR_LINES:
-+ black_lines = 4;
-+ break;
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_offs, MRV_ISP_ACQ_H_OFFS,
-+ 0 * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_offs, MRV_ISP_ACQ_V_OFFS, 0);
-+
-+ dprintk(2, "res = %x", isi_cfg->res);
-+ switch (isi_cfg->res) {
-+ /* 88x72 */
-+ case SENSOR_RES_QQCIF:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QQCIF_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QQCIF_SIZE_V + black_lines);
-+ break;
-+ /* 160x120 */
-+ case SENSOR_RES_QQVGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QQVGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QQVGA_SIZE_V + black_lines);
-+ break;
-+ /* 176x144 */
-+ case SENSOR_RES_QCIF:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QCIF_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QCIF_SIZE_V + black_lines);
-+ break;
-+ /* 320x240 */
-+ case SENSOR_RES_QVGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QVGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QVGA_SIZE_V + black_lines);
-+ break;
-+ /* 352x288 */
-+ case SENSOR_RES_CIF:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ CIF_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ CIF_SIZE_V + black_lines);
-+ break;
-+ /* 640x480 */
-+ case SENSOR_RES_VGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ VGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ VGA_SIZE_V + black_lines);
-+ break;
-+ /* 800x600 */
-+ case SENSOR_RES_SVGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ SVGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ SVGA_SIZE_V + black_lines);
-+ break;
-+ /* 1024x768 */
-+ case SENSOR_RES_XGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ XGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ XGA_SIZE_V + black_lines);
-+ break;
-+ case SENSOR_RES_720P:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ RES_720P_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ RES_720P_SIZE_V + black_lines);
-+ break;
-+ /* 1280x960 */
-+ case SENSOR_RES_XGA_PLUS:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ XGA_PLUS_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ XGA_PLUS_SIZE_V + black_lines);
-+ break;
-+ /* 1280x1024 */
-+ case SENSOR_RES_SXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ SXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ SXGA_SIZE_V + black_lines);
-+ break;
-+ /* 1600x1200 */
-+ case SENSOR_RES_UXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QSVGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QSVGA_SIZE_V + black_lines);
-+ break;
-+ /* 1920x1280 */
-+ case SENSOR_RES_1080P:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ 1920 * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ 1080 + black_lines);
-+ break;
-+ /* 2048x1536 */
-+ case SENSOR_RES_QXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QXGA_SIZE_V + black_lines);
-+ break;
-+ /* 2586x2048 */
-+ case SENSOR_RES_QSXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QSXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QSXGA_SIZE_V + black_lines);
-+ break;
-+ /* 2600x2048 */
-+ case SENSOR_RES_QSXGA_PLUS:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QSXGA_PLUS_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QSXGA_PLUS_SIZE_V + black_lines);
-+ break;
-+ /* 2600x1950 */
-+ case SENSOR_RES_QSXGA_PLUS2:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QSXGA_PLUS2_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QSXGA_PLUS2_SIZE_V + black_lines);
-+ break;
-+ /* 2686x2048, 5.30M */
-+ case SENSOR_RES_QSXGA_PLUS3:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QSXGA_PLUS3_SIZE_V * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QSXGA_PLUS3_SIZE_V + black_lines);
-+ break;
-+ /* 2592*1944 5M */
-+ case SENSOR_RES_QXGA_PLUS:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QXGA_PLUS_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QXGA_PLUS_SIZE_V + black_lines);
-+ break;
-+ /* 3200x2048, 6.56M */
-+ case SENSOR_RES_WQSXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ WQSXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ WQSXGA_SIZE_V + black_lines);
-+ break;
-+ /* 3200x2400, 7.68M */
-+ case SENSOR_RES_QUXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ QUXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ QUXGA_SIZE_V + black_lines);
-+ break;
-+ /* 3840x2400, 9.22M */
-+ case SENSOR_RES_WQUXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ WQUXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ WQUXGA_SIZE_V + black_lines);
-+ break;
-+ /* 4096x3072, 12.59M */
-+ case SENSOR_RES_HXGA:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ HXGA_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ HXGA_SIZE_V + black_lines);
-+ break;
-+ /* 4080x1024 */
-+ case SENSOR_RES_YUV_HMAX:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ YUV_HMAX_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ YUV_HMAX_SIZE_V);
-+ break;
-+ /* 1024x4080 */
-+ case SENSOR_RES_YUV_VMAX:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ YUV_VMAX_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ YUV_VMAX_SIZE_V);
-+ break;
-+ /* 4096x2048 */
-+ case SENSOR_RES_RAWMAX:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ RAWMAX_SIZE_H);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ RAWMAX_SIZE_V);
-+ break;
-+ /* 352x240 */
-+ case SENSOR_RES_BP1:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ BP1_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ BP1_SIZE_V);
-+ break;
-+ /* 720x480 */
-+ case SENSOR_RES_L_AFM:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ L_AFM_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ L_AFM_SIZE_V);
-+ break;
-+ /* 128x96 */
-+ case SENSOR_RES_M_AFM:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ M_AFM_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ M_AFM_SIZE_V);
-+ break;
-+ /* 64x32 */
-+ case SENSOR_RES_S_AFM:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ S_AFM_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ S_AFM_SIZE_V);
-+ break;
-+ /* 1304x980 */
-+ case SENSOR_RES_VGA_PLUS:
-+ REG_SET_SLICE(mrv_reg->isp_acq_h_size, MRV_ISP_ACQ_H_SIZE,
-+ VGA_PLUS_SIZE_H * sample_factor);
-+ REG_SET_SLICE(mrv_reg->isp_acq_v_size, MRV_ISP_ACQ_V_SIZE,
-+ VGA_PLUS_SIZE_V);
-+ break;
-+
-+ default:
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * sets output window
-+ */
-+void ci_isp_set_output_formatter(const struct ci_isp_window *window,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (window) {
-+ /* set output window */
-+ REG_SET_SLICE(mrv_reg->isp_out_h_offs, MRV_IS_IS_H_OFFS,
-+ window->hoffs);
-+ REG_SET_SLICE(mrv_reg->isp_out_v_offs, MRV_IS_IS_V_OFFS,
-+ window->voffs);
-+ REG_SET_SLICE(mrv_reg->isp_out_h_size, MRV_IS_IS_H_SIZE,
-+ window->hsize);
-+ REG_SET_SLICE(mrv_reg->isp_out_v_size, MRV_IS_IS_V_SIZE,
-+ window->vsize);
-+
-+ REG_SET_SLICE(mrv_reg->isp_is_h_offs, MRV_IS_IS_H_OFFS, 0);
-+ REG_SET_SLICE(mrv_reg->isp_is_v_offs, MRV_IS_IS_V_OFFS, 0);
-+ REG_SET_SLICE(mrv_reg->isp_is_h_size, MRV_IS_IS_H_SIZE,
-+ window->hsize);
-+ REG_SET_SLICE(mrv_reg->isp_is_v_size, MRV_IS_IS_V_SIZE,
-+ window->vsize);
-+
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ /* frame synchronous update of shadow registers */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl,
-+ MRV_ISP_ISP_GEN_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ /* immediate update of shadow registers */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl,
-+ MRV_ISP_ISP_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ /* no update from within this function */
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+}
-+
-+/*
-+ * programs the given Bayer pattern demosaic parameters
-+ */
-+void ci_isp_set_demosaic(enum ci_isp_demosaic_mode demosaic_mode,
-+ u8 demosaic_th)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_demosaic = REG_READ(mrv_reg->isp_demosaic);
-+
-+ /* set demosaic mode */
-+ switch (demosaic_mode) {
-+ case CI_ISP_DEMOSAIC_STANDARD:
-+ REG_SET_SLICE(isp_demosaic, MRV_ISP_DEMOSAIC_MODE,
-+ MRV_ISP_DEMOSAIC_MODE_STD);
-+ break;
-+ case CI_ISP_DEMOSAIC_ENHANCED:
-+ REG_SET_SLICE(isp_demosaic, MRV_ISP_DEMOSAIC_MODE,
-+ MRV_ISP_DEMOSAIC_MODE_ENH);
-+ break;
-+ default:
-+ WARN_ON(!(false));
-+ }
-+
-+ /* set demosaic threshold */
-+ REG_SET_SLICE(isp_demosaic, MRV_ISP_DEMOSAIC_TH, demosaic_th);
-+ REG_WRITE(mrv_reg->isp_demosaic, isp_demosaic);
-+}
-+
-+/*
-+ * Sets the dedicated AWB block mode.
-+ */
-+int ci_isp_set_wb_mode(enum ci_isp_awb_mode wb_mode)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ switch (wb_mode) {
-+ case CI_ISP_AWB_COMPLETELY_OFF:
-+ /* manual WB, no measurements*/
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MODE,
-+ MRV_ISP_AWB_MODE_NOMEAS);
-+ /* switch ABW block off */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_AWB_ENABLE,
-+ DISABLE);
-+ break;
-+ case CI_ISP_AWB_MAN_MEAS:
-+ case CI_ISP_AWB_AUTO:
-+ case CI_ISP_AWB_MAN_PUSH_AUTO:
-+ case CI_ISP_AWB_ONLY_MEAS:
-+ /* manual white balance, measure YCbCr means */
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MODE,
-+ MRV_ISP_AWB_MODE_MEAS);
-+ /* switch ABW block on */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_AWB_ENABLE,
-+ ENABLE);
-+ break;
-+ case CI_ISP_AWB_MAN_NOMEAS:
-+ /* manual white balance, no measurements */
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MODE,
-+ MRV_ISP_AWB_MODE_NOMEAS);
-+ /* switch ABW block on */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_AWB_ENABLE,
-+ ENABLE);
-+ break;
-+ default:
-+ /* to be sure that a regular value is set: */
-+ /* manual white balance, no measurements */
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MODE,
-+ MRV_ISP_AWB_MODE_NOMEAS);
-+ /* switch ABW block off */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_AWB_ENABLE,
-+ DISABLE);
-+ return CI_STATUS_FAILURE;
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_get_wb_mode(enum ci_isp_awb_mode *wb_mode)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!wb_mode)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ if (REG_GET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_AWB_ENABLE) ==
-+ DISABLE) {
-+ *wb_mode = CI_ISP_AWB_COMPLETELY_OFF;
-+ } else {
-+
-+ switch (REG_GET_SLICE(mrv_reg->isp_awb_prop,
-+ MRV_ISP_AWB_MODE)) {
-+ case MRV_ISP_AWB_MODE_MEAS:
-+ *wb_mode = CI_ISP_AWB_MAN_MEAS;
-+ break;
-+ case MRV_ISP_AWB_MODE_NOMEAS:
-+ *wb_mode = CI_ISP_AWB_MAN_NOMEAS;
-+ break;
-+ default:
-+ *wb_mode = CI_ISP_AWB_COMPLETELY_OFF;
-+ return CI_STATUS_FAILURE;
-+ }
-+ }
-+ return CI_STATUS_SUCCESS;
-+}
-+int ci_isp_set_wb_meas_config(const struct ci_isp_wb_meas_config
-+ *wb_meas_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_awb_thresh = REG_READ(mrv_reg->isp_awb_thresh);
-+
-+ if (!wb_meas_config)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ /* measurement window */
-+ REG_SET_SLICE(mrv_reg->isp_awb_h_size, MRV_ISP_AWB_H_SIZE,
-+ (u32) wb_meas_config->awb_window.hsize);
-+ REG_SET_SLICE(mrv_reg->isp_awb_v_size, MRV_ISP_AWB_V_SIZE,
-+ (u32) wb_meas_config->awb_window.vsize);
-+ REG_SET_SLICE(mrv_reg->isp_awb_h_offs, MRV_ISP_AWB_H_OFFS,
-+ (u32) wb_meas_config->awb_window.hoffs);
-+ REG_SET_SLICE(mrv_reg->isp_awb_v_offs, MRV_ISP_AWB_V_OFFS,
-+ (u32) wb_meas_config->awb_window.voffs);
-+
-+ /* adjust awb properties (Y_MAX compare) */
-+ if (wb_meas_config->max_y == 0) {
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MAX_EN,
-+ DISABLE);
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MAX_EN,
-+ ENABLE);
-+ }
-+
-+ /* measurement thresholds */
-+ REG_SET_SLICE(isp_awb_thresh, MRV_ISP_AWB_MAX_Y,
-+ (u32) wb_meas_config->max_y);
-+ REG_SET_SLICE(isp_awb_thresh, MRV_ISP_AWB_MIN_Y__MAX_G,
-+ (u32) wb_meas_config->minY_MaxG);
-+ REG_SET_SLICE(isp_awb_thresh, MRV_ISP_AWB_MAX_CSUM,
-+ (u32) wb_meas_config->max_csum);
-+ REG_SET_SLICE(isp_awb_thresh, MRV_ISP_AWB_MIN_C,
-+ (u32) wb_meas_config->min_c);
-+ REG_WRITE(mrv_reg->isp_awb_thresh, isp_awb_thresh);
-+ REG_SET_SLICE(mrv_reg->isp_awb_ref, MRV_ISP_AWB_REF_CR__MAX_R,
-+ (u32)(wb_meas_config->ref_cr_MaxR));
-+ REG_SET_SLICE(mrv_reg->isp_awb_ref, MRV_ISP_AWB_REF_CB__MAX_B,
-+ (u32)(wb_meas_config->ref_cb_MaxB));
-+
-+ /* amount of measurement frames */
-+ REG_SET_SLICE(mrv_reg->isp_awb_frames, MRV_ISP_AWB_FRAMES,
-+ (u32) wb_meas_config->frames);
-+
-+ /* set measurement mode */
-+ REG_SET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MEAS_MODE,
-+ (u32)(wb_meas_config->meas_mode));
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_get_wb_meas_config(struct ci_isp_wb_meas_config *wb_meas_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!wb_meas_config)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ /* measurement window */
-+ wb_meas_config->awb_window.hsize =
-+ (u16) REG_GET_SLICE(mrv_reg->isp_awb_h_size, MRV_ISP_AWB_H_SIZE);
-+ wb_meas_config->awb_window.vsize =
-+ (u16) REG_GET_SLICE(mrv_reg->isp_awb_v_size, MRV_ISP_AWB_V_SIZE);
-+ wb_meas_config->awb_window.hoffs =
-+ (u16) REG_GET_SLICE(mrv_reg->isp_awb_h_offs, MRV_ISP_AWB_H_OFFS);
-+ wb_meas_config->awb_window.voffs =
-+ (u16) REG_GET_SLICE(mrv_reg->isp_awb_v_offs, MRV_ISP_AWB_V_OFFS);
-+
-+ /* measurement thresholds */
-+ wb_meas_config->min_c =
-+ (u8) REG_GET_SLICE(mrv_reg->isp_awb_thresh, MRV_ISP_AWB_MIN_C);
-+ wb_meas_config->max_csum =
-+ (u8) REG_GET_SLICE(mrv_reg->isp_awb_thresh, MRV_ISP_AWB_MAX_CSUM);
-+ wb_meas_config->minY_MaxG =
-+ (u8) REG_GET_SLICE(mrv_reg->isp_awb_thresh,
-+ MRV_ISP_AWB_MIN_Y__MAX_G);
-+ wb_meas_config->max_y =
-+ (u8) REG_GET_SLICE(mrv_reg->isp_awb_thresh, MRV_ISP_AWB_MAX_Y);
-+ wb_meas_config->ref_cb_MaxB =
-+ (u8)REG_GET_SLICE(mrv_reg->isp_awb_ref, MRV_ISP_AWB_REF_CB__MAX_B);
-+ wb_meas_config->ref_cr_MaxR =
-+ (u8)REG_GET_SLICE(mrv_reg->isp_awb_ref, MRV_ISP_AWB_REF_CR__MAX_R);
-+
-+ /* amount of measurement frames */
-+ wb_meas_config->frames =
-+ (u8) REG_GET_SLICE(mrv_reg->isp_awb_frames, MRV_ISP_AWB_FRAMES);
-+
-+ /* overwrite max_y if the feature is disabled */
-+ if (REG_GET_SLICE(mrv_reg->isp_awb_prop, MRV_ISP_AWB_MAX_EN) ==
-+ DISABLE) {
-+ wb_meas_config->max_y = 0;
-+ }
-+
-+ /* get measurement mode */
-+ wb_meas_config->meas_mode = REG_GET_SLICE(mrv_reg->isp_awb_prop,
-+ MRV_ISP_AWB_MEAS_MODE);
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_get_wb_meas(struct ci_sensor_awb_mean *awb_mean)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (awb_mean == NULL)
-+ return CI_STATUS_NULL_POINTER;
-+
-+ awb_mean->white = REG_GET_SLICE(mrv_reg->isp_awb_white_cnt,
-+ MRV_ISP_AWB_WHITE_CNT);
-+ awb_mean->mean_Y__G = (u8) REG_GET_SLICE(mrv_reg->isp_awb_mean,
-+ MRV_ISP_AWB_MEAN_Y__G);
-+ awb_mean->mean_cb__B = (u8) REG_GET_SLICE(mrv_reg->isp_awb_mean,
-+ MRV_ISP_AWB_MEAN_CB__B);
-+ awb_mean->mean_cr__R = (u8) REG_GET_SLICE(mrv_reg->isp_awb_mean,
-+ MRV_ISP_AWB_MEAN_CR__R);
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * calculates left-top and right-bottom register values
-+ * for a given AF measurement window
-+ */
-+static int ci_isp_afm_wnd2_regs(const struct ci_isp_window *wnd, u32 *lt,
-+ u32 *rb)
-+{
-+ WARN_ON(!((wnd != NULL) && (lt != NULL) && (rb != NULL)));
-+
-+ if (wnd->hsize && wnd->vsize) {
-+ u32 left = wnd->hoffs;
-+ u32 top = wnd->voffs;
-+ u32 right = left + wnd->hsize - 1;
-+ u32 bottom = top + wnd->vsize - 1;
-+
-+ if ((left < MRV_AFM_A_H_L_MIN)
-+ || (left > MRV_AFM_A_H_L_MAX)
-+ || (top < MRV_AFM_A_V_T_MIN)
-+ || (top > MRV_AFM_A_V_T_MAX)
-+ || (right < MRV_AFM_A_H_R_MIN)
-+ || (right > MRV_AFM_A_H_R_MAX)
-+ || (bottom < MRV_AFM_A_V_B_MIN)
-+ || (bottom > MRV_AFM_A_V_B_MAX)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+
-+ /* combine the values and return */
-+ REG_SET_SLICE(*lt, MRV_AFM_A_H_L, left);
-+ REG_SET_SLICE(*lt, MRV_AFM_A_V_T, top);
-+ REG_SET_SLICE(*rb, MRV_AFM_A_H_R, right);
-+ REG_SET_SLICE(*rb, MRV_AFM_A_V_B, bottom);
-+ } else {
-+ *lt = 0;
-+ *rb = 0;
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_set_auto_focus(const struct ci_isp_af_config *af_config)
-+{
-+
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 result = CI_STATUS_SUCCESS;
-+
-+ /* disable measurement module */
-+ REG_SET_SLICE(mrv_reg->isp_afm_ctrl, MRV_AFM_AFM_EN, DISABLE);
-+
-+ if (af_config) {
-+ u32 lt;
-+ u32 rb;
-+ result = ci_isp_afm_wnd2_regs(&(af_config->wnd_pos_a),
-+ &lt, &rb);
-+ /* set measurement window boundaries */
-+ if (result != CI_STATUS_SUCCESS)
-+ return result;
-+
-+ REG_WRITE(mrv_reg->isp_afm_lt_a, lt);
-+ REG_WRITE(mrv_reg->isp_afm_rb_a, rb);
-+
-+ result = ci_isp_afm_wnd2_regs(&(af_config->wnd_pos_b),
-+ &lt, &rb);
-+
-+ if (result != CI_STATUS_SUCCESS)
-+ return result;
-+
-+ REG_WRITE(mrv_reg->isp_afm_lt_b, lt);
-+ REG_WRITE(mrv_reg->isp_afm_rb_b, rb);
-+
-+ result = ci_isp_afm_wnd2_regs(&(af_config->wnd_pos_c),
-+ &lt, &rb);
-+
-+ if (result != CI_STATUS_SUCCESS)
-+ return result;
-+
-+ REG_WRITE(mrv_reg->isp_afm_lt_c, lt);
-+ REG_WRITE(mrv_reg->isp_afm_rb_c, rb);
-+
-+ /* set other af measurement paraneters */
-+ REG_SET_SLICE(mrv_reg->isp_afm_thres, MRV_AFM_AFM_THRES,
-+ af_config->threshold);
-+ REG_SET_SLICE(mrv_reg->isp_afm_var_shift, MRV_AFM_LUM_VAR_SHIFT,
-+ (af_config->var_shift >> 16));
-+ REG_SET_SLICE(mrv_reg->isp_afm_var_shift, MRV_AFM_AFM_VAR_SHIFT,
-+ (af_config->var_shift >> 0));
-+
-+ /* enable measurement module */
-+ REG_SET_SLICE(mrv_reg->isp_afm_ctrl, MRV_AFM_AFM_EN, ENABLE);
-+ }
-+
-+ return result;
-+}
-+
-+
-+void ci_isp_get_auto_focus_meas(struct ci_isp_af_meas *af_meas)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ WARN_ON(!(af_meas != NULL));
-+
-+ af_meas->afm_sum_a =
-+ REG_GET_SLICE(mrv_reg->isp_afm_sum_a, MRV_AFM_AFM_SUM_A);
-+ af_meas->afm_sum_b =
-+ REG_GET_SLICE(mrv_reg->isp_afm_sum_b, MRV_AFM_AFM_SUM_B);
-+ af_meas->afm_sum_c =
-+ REG_GET_SLICE(mrv_reg->isp_afm_sum_c, MRV_AFM_AFM_SUM_C);
-+ af_meas->afm_lum_a =
-+ REG_GET_SLICE(mrv_reg->isp_afm_lum_a, MRV_AFM_AFM_LUM_A);
-+ af_meas->afm_lum_b =
-+ REG_GET_SLICE(mrv_reg->isp_afm_lum_b, MRV_AFM_AFM_LUM_B);
-+ af_meas->afm_lum_c =
-+ REG_GET_SLICE(mrv_reg->isp_afm_lum_c, MRV_AFM_AFM_LUM_C);
-+}
-+
-+int ci_isp_set_ls_correction(struct ci_sensor_ls_corr_config *ls_corr_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 i, n;
-+ u32 data = 0;
-+ int enabled = false;
-+
-+ if (!ls_corr_config) {
-+ /* disable lens shading module */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ctrl, MRV_LSC_LSC_EN, DISABLE);
-+ } else {
-+ /* test if lens shading correction is enabled */
-+ if (REG_GET_SLICE(mrv_reg->isp_lsc_ctrl, MRV_LSC_LSC_EN)) {
-+ /* switch off lens shading correction */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ctrl,
-+ MRV_LSC_LSC_EN, DISABLE);
-+ /* wait 1ms to make sure that
-+ * the LSC have time enough to switch off */
-+ /* wait over 1 ms */
-+ /*mdelay(1000);*/
-+ msleep(1000);
-+ enabled = true;
-+ }
-+
-+ /* clear address counters */
-+ REG_WRITE(mrv_reg->isp_lsc_r_table_addr, 0);
-+ REG_WRITE(mrv_reg->isp_lsc_g_table_addr, 0);
-+ REG_WRITE(mrv_reg->isp_lsc_b_table_addr, 0);
-+
-+ /* program data tables (table size is 9 * 17 = 153;
-+ * see also MRV_LSC_?_RAM_ADDR_MAX) */
-+ WARN_ON(!(((CI_ISP_MAX_LSC_SECTORS + 1) *
-+ ((CI_ISP_MAX_LSC_SECTORS + 2) / 2)) ==
-+ (MRV_LSC_R_RAM_ADDR_MAX + 1)));
-+
-+ /* 17 steps */
-+ for (n = 0;
-+ n < ((CI_ISP_MAX_LSC_SECTORS + 1) *
-+ (CI_ISP_MAX_LSC_SECTORS + 1));
-+ n += CI_ISP_MAX_LSC_SECTORS + 1) {
-+ dprintk(2, "set ls correct step n = %d", n);
-+ /* 17 sectors with 2 values in one DWORD = 9
-+ * DWORDs (8 steps + 1 outside loop) */
-+ for (i = 0; i < (CI_ISP_MAX_LSC_SECTORS); i += 2) {
-+ REG_SET_SLICE(data, MRV_LSC_R_SAMPLE_0,
-+ ls_corr_config->ls_rdata_tbl[n + i]);
-+ REG_SET_SLICE(data, MRV_LSC_R_SAMPLE_1,
-+ ls_corr_config->ls_rdata_tbl
-+ [n + i + 1]);
-+ REG_WRITE(mrv_reg->isp_lsc_r_table_data, data);
-+ REG_SET_SLICE(data, MRV_LSC_G_SAMPLE_0,
-+ ls_corr_config->ls_gdata_tbl
-+ [n + i]);
-+ REG_SET_SLICE(data, MRV_LSC_G_SAMPLE_1,
-+ ls_corr_config->ls_gdata_tbl
-+ [n + i + 1]);
-+ REG_WRITE(mrv_reg->isp_lsc_g_table_data, data);
-+ REG_SET_SLICE(data, MRV_LSC_B_SAMPLE_0,
-+ ls_corr_config->ls_bdata_tbl[n + i]);
-+ REG_SET_SLICE(data, MRV_LSC_B_SAMPLE_1,
-+ ls_corr_config->ls_bdata_tbl
-+ [n + i + 1]);
-+ REG_WRITE(mrv_reg->isp_lsc_b_table_data, data);
-+ }
-+ REG_SET_SLICE(data, MRV_LSC_R_SAMPLE_0,
-+ ls_corr_config->ls_rdata_tbl
-+ [n + CI_ISP_MAX_LSC_SECTORS]);
-+ REG_SET_SLICE(data, MRV_LSC_R_SAMPLE_1, 0);
-+ REG_WRITE(mrv_reg->isp_lsc_r_table_data, data);
-+ REG_SET_SLICE(data, MRV_LSC_G_SAMPLE_0,
-+ ls_corr_config->ls_gdata_tbl
-+ [n + CI_ISP_MAX_LSC_SECTORS]);
-+ REG_SET_SLICE(data, MRV_LSC_G_SAMPLE_1, 0);
-+ REG_WRITE(mrv_reg->isp_lsc_g_table_data, data);
-+ REG_SET_SLICE(data, MRV_LSC_B_SAMPLE_0,
-+ ls_corr_config->ls_bdata_tbl
-+ [n + CI_ISP_MAX_LSC_SECTORS]);
-+ REG_SET_SLICE(data, MRV_LSC_B_SAMPLE_1, 0);
-+ REG_WRITE(mrv_reg->isp_lsc_b_table_data, data);
-+ }
-+
-+ /* program x size tables */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_01, MRV_LSC_X_SECT_SIZE_0,
-+ ls_corr_config->ls_xsize_tbl[0]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_01, MRV_LSC_X_SECT_SIZE_1,
-+ ls_corr_config->ls_xsize_tbl[1]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_23, MRV_LSC_X_SECT_SIZE_2,
-+ ls_corr_config->ls_xsize_tbl[2]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_23, MRV_LSC_X_SECT_SIZE_3,
-+ ls_corr_config->ls_xsize_tbl[3]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_45, MRV_LSC_X_SECT_SIZE_4,
-+ ls_corr_config->ls_xsize_tbl[4]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_45, MRV_LSC_X_SECT_SIZE_5,
-+ ls_corr_config->ls_xsize_tbl[5]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_67, MRV_LSC_X_SECT_SIZE_6,
-+ ls_corr_config->ls_xsize_tbl[6]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xsize_67, MRV_LSC_X_SECT_SIZE_7,
-+ ls_corr_config->ls_xsize_tbl[7]);
-+
-+ /* program y size tables */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_01, MRV_LSC_Y_SECT_SIZE_0,
-+ ls_corr_config->ls_ysize_tbl[0]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_01, MRV_LSC_Y_SECT_SIZE_1,
-+ ls_corr_config->ls_ysize_tbl[1]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_23, MRV_LSC_Y_SECT_SIZE_2,
-+ ls_corr_config->ls_ysize_tbl[2]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_23, MRV_LSC_Y_SECT_SIZE_3,
-+ ls_corr_config->ls_ysize_tbl[3]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_45, MRV_LSC_Y_SECT_SIZE_4,
-+ ls_corr_config->ls_ysize_tbl[4]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_45, MRV_LSC_Y_SECT_SIZE_5,
-+ ls_corr_config->ls_ysize_tbl[5]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_67, MRV_LSC_Y_SECT_SIZE_6,
-+ ls_corr_config->ls_ysize_tbl[6]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ysize_67, MRV_LSC_Y_SECT_SIZE_7,
-+ ls_corr_config->ls_ysize_tbl[7]);
-+
-+ /* program x grad tables */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_01, MRV_LSC_XGRAD_0,
-+ ls_corr_config->ls_xgrad_tbl[0]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_01, MRV_LSC_XGRAD_1,
-+ ls_corr_config->ls_xgrad_tbl[1]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_23, MRV_LSC_XGRAD_2,
-+ ls_corr_config->ls_xgrad_tbl[2]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_23, MRV_LSC_XGRAD_3,
-+ ls_corr_config->ls_xgrad_tbl[3]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_45, MRV_LSC_XGRAD_4,
-+ ls_corr_config->ls_xgrad_tbl[4]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_45, MRV_LSC_XGRAD_5,
-+ ls_corr_config->ls_xgrad_tbl[5]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_67, MRV_LSC_XGRAD_6,
-+ ls_corr_config->ls_xgrad_tbl[6]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_xgrad_67, MRV_LSC_XGRAD_7,
-+ ls_corr_config->ls_xgrad_tbl[7]);
-+
-+ /* program y grad tables */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_01, MRV_LSC_YGRAD_0,
-+ ls_corr_config->ls_ygrad_tbl[0]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_01, MRV_LSC_YGRAD_1,
-+ ls_corr_config->ls_ygrad_tbl[1]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_23, MRV_LSC_YGRAD_2,
-+ ls_corr_config->ls_ygrad_tbl[2]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_23, MRV_LSC_YGRAD_3,
-+ ls_corr_config->ls_ygrad_tbl[3]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_45, MRV_LSC_YGRAD_4,
-+ ls_corr_config->ls_ygrad_tbl[4]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_45, MRV_LSC_YGRAD_5,
-+ ls_corr_config->ls_ygrad_tbl[5]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_67, MRV_LSC_YGRAD_6,
-+ ls_corr_config->ls_ygrad_tbl[6]);
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ygrad_67, MRV_LSC_YGRAD_7,
-+ ls_corr_config->ls_ygrad_tbl[7]);
-+
-+ if (enabled) {
-+ /* switch on lens chading correction */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ctrl,
-+ MRV_LSC_LSC_EN, ENABLE);
-+ }
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_ls_correction_on_off(int ls_corr_on_off)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (ls_corr_on_off) {
-+ /* switch on lens chading correction */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ctrl, MRV_LSC_LSC_EN, ENABLE);
-+ } else {
-+ /* switch off lens chading correction */
-+ REG_SET_SLICE(mrv_reg->isp_lsc_ctrl, MRV_LSC_LSC_EN, DISABLE);
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Sets the Bad Pixel Correction configuration
-+ */
-+int ci_isp_set_bp_correction(const struct ci_isp_bp_corr_config
-+ *bp_corr_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_bp_ctrl = REG_READ(mrv_reg->isp_bp_ctrl);
-+
-+ if (!bp_corr_config) {
-+ /* disable correction module */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_HOT_COR_EN, DISABLE);
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_DEAD_COR_EN, DISABLE);
-+ } else {
-+ /* set bad pixel configuration */
-+ if (bp_corr_config->bp_corr_type == CI_ISP_BP_CORR_DIRECT) {
-+ /* direct detection */
-+ u32 isp_bp_cfg1 = REG_READ(mrv_reg->isp_bp_cfg1);
-+ u32 isp_bp_cfg2 = REG_READ(mrv_reg->isp_bp_cfg2);
-+
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_COR_TYPE,
-+ MRV_BP_COR_TYPE_DIRECT);
-+
-+ WARN_ON(!(!REG_GET_SLICE(mrv_reg->isp_bp_ctrl,
-+ MRV_BP_BP_DET_EN)));
-+
-+ /* threshold register only used for direct mode */
-+ REG_SET_SLICE(isp_bp_cfg1, MRV_BP_HOT_THRES,
-+ bp_corr_config->bp_abs_hot_thres);
-+ REG_SET_SLICE(isp_bp_cfg1, MRV_BP_DEAD_THRES,
-+ bp_corr_config->bp_abs_dead_thres);
-+ REG_WRITE(mrv_reg->isp_bp_cfg1, isp_bp_cfg1);
-+ REG_SET_SLICE(isp_bp_cfg2, MRV_BP_DEV_HOT_THRES,
-+ bp_corr_config->bp_dev_hot_thres);
-+ REG_SET_SLICE(isp_bp_cfg2, MRV_BP_DEV_DEAD_THRES,
-+ bp_corr_config->bp_dev_dead_thres);
-+ REG_WRITE(mrv_reg->isp_bp_cfg2, isp_bp_cfg2);
-+ } else {
-+ /* use bad pixel table */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_COR_TYPE,
-+ MRV_BP_COR_TYPE_TABLE);
-+ }
-+
-+ if (bp_corr_config->bp_corr_rep == CI_ISP_BP_CORR_REP_LIN) {
-+ /* use linear approch */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_REP_APPR,
-+ MRV_BP_REP_APPR_INTERPOL);
-+ } else {
-+ /* use best neighbour */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_REP_APPR,
-+ MRV_BP_REP_APPR_NEAREST);
-+ }
-+
-+ switch (bp_corr_config->bp_corr_mode) {
-+ case CI_ISP_BP_CORR_HOT_EN:
-+ /* enable Hot */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_HOT_COR_EN, ENABLE);
-+ /* disable Dead */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_DEAD_COR_EN, DISABLE);
-+ break;
-+ case CI_ISP_BP_CORR_DEAD_EN:
-+ /* disable Hot */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_HOT_COR_EN, DISABLE);
-+ /* enable Dead */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_DEAD_COR_EN, ENABLE);
-+ break;
-+ case CI_ISP_BP_CORR_HOT_DEAD_EN:
-+ default:
-+ /* enable Hot */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_HOT_COR_EN, ENABLE);
-+ /* enable Dead */
-+ REG_SET_SLICE(isp_bp_ctrl, MRV_BP_DEAD_COR_EN, ENABLE);
-+ break;
-+ }
-+ }
-+
-+ REG_WRITE(mrv_reg->isp_bp_ctrl, isp_bp_ctrl);
-+
-+ return CI_STATUS_SUCCESS;
-+
-+}
-+
-+/*
-+ * Sets the Bad Pixel configuration for detection
-+ */
-+int ci_isp_set_bp_detection(const struct ci_isp_bp_det_config *bp_det_config)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!bp_det_config) {
-+ /* disable measurement module */
-+ REG_SET_SLICE(mrv_reg->isp_bp_ctrl, MRV_BP_BP_DET_EN, DISABLE);
-+ } else {
-+ WARN_ON(!(REG_GET_SLICE(mrv_reg->isp_bp_ctrl, MRV_BP_COR_TYPE)
-+ == MRV_BP_COR_TYPE_TABLE));
-+
-+ /* set dead threshold for bad pixel detection */
-+ REG_SET_SLICE(mrv_reg->isp_bp_cfg1, MRV_BP_DEAD_THRES,
-+ bp_det_config->bp_dead_thres);
-+
-+ /* enable measurement module */
-+ REG_SET_SLICE(mrv_reg->isp_bp_ctrl, MRV_BP_BP_DET_EN, ENABLE);
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_clear_bp_int(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /* clear bp_det irq (only if it is signalled to prevent loss of irqs) */
-+ if (REG_GET_SLICE(mrv_reg->isp_ris, MRV_ISP_RIS_BP_DET))
-+ REG_SET_SLICE(mrv_reg->isp_icr, MRV_ISP_ICR_BP_DET, 1);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Initializes Isp filter registers with default reset values.
-+ */
-+static int ci_isp_initialize_filter_registers(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ mrv_reg->isp_filt_mode = 0x00000000;
-+ mrv_reg->isp_filt_fac_sh1 = 0x00000010;
-+ mrv_reg->isp_filt_fac_sh0 = 0x0000000C;
-+ mrv_reg->isp_filt_fac_mid = 0x0000000A;
-+ mrv_reg->isp_filt_fac_bl0 = 0x00000006;
-+ mrv_reg->isp_filt_fac_bl1 = 0x00000002;
-+ mrv_reg->isp_filt_thresh_bl0 = 0x0000000D;
-+ mrv_reg->isp_filt_thresh_bl1 = 0x00000005;
-+ mrv_reg->isp_filt_thresh_sh0 = 0x0000001A;
-+ mrv_reg->isp_filt_thresh_sh1 = 0x0000002C;
-+ mrv_reg->isp_filt_lum_weight = 0x00032040;
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_isp_activate_filter(int activate_filter)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ int retval = CI_STATUS_SUCCESS;
-+
-+ /* Initialize ISP filter control registers first */
-+ retval = ci_isp_initialize_filter_registers();
-+ if (retval != CI_STATUS_SUCCESS)
-+ return retval;
-+
-+ /* Activate or deactivate filter algorythm */
-+ REG_SET_SLICE(mrv_reg->isp_filt_mode, MRV_FILT_FILT_ENABLE,
-+ (activate_filter) ? ENABLE : DISABLE);
-+
-+ return retval;
-+}
-+
-+/*
-+ * Write coefficient and threshold values into Isp filter
-+ * registers for noise, sharpness and blurring filtering.
-+ */
-+int ci_isp_set_filter_params(u8 noise_reduc_level, u8 sharp_level)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 isp_filt_mode = 0;
-+
-+ if (!REG_GET_SLICE(mrv_reg->isp_filt_mode, MRV_FILT_FILT_ENABLE))
-+ return CI_STATUS_CANCELED;
-+
-+ REG_WRITE(mrv_reg->isp_filt_mode, isp_filt_mode);
-+
-+ if (((noise_reduc_level <= 10) || (noise_reduc_level == 99))
-+ && (sharp_level <= 10)) {
-+ switch (noise_reduc_level) {
-+ /* Test Mode */
-+ case 99:
-+ /* 10 bit max value */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 0x000003FF);
-+ /* 10 bit max value */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 0x000003FF);
-+ /* 10 bit max value */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 0x000003FF);
-+ /* 10 bit max value */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 0x000003FF);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 0
-+ /* MRV_FILT_STAGE1_SELECT_MAX_BLUR */);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_BYPASS);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_BYPASS);
-+ break;
-+
-+ case 0:
-+ /* NoiseReductionLevel = 0 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 0x000000);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 0x000000);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 0x000000);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 0x000000);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 6);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC8);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_BYPASS);
-+ break;
-+
-+ case 1:
-+ /* NoiseReductionLevel = 1; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 33);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 18);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 8);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 2);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 6);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 2:
-+ /* NoiseReductionLevel = 2; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 44);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 26);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 13);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 5);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 4
-+ /* MRV_FILT_STAGE1_SELECT_DEFAULT */);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 3:
-+ /* NoiseReductionLevel = 3; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 51);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 36);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 23);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 10);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 4
-+ /* MRV_FILT_STAGE1_SELECT_DEFAULT */);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 4:
-+ /* NoiseReductionLevel = 4; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 67);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 41);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 26);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 15);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 3);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 5:
-+ /* NoiseReductionLevel = 5; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 100);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 75);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 50);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 20);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 3);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 6:
-+ /* NoiseReductionLevel = 6; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 120);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 90);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 60);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 26);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 2);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 7:
-+ /* NoiseReductionLevel = 7; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 150);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 120);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 80);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 51);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 2);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 8:
-+ /* NoiseReductionLevel = 8; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 200);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 170);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 140);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 100);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT, 2);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 9:
-+ /* NoiseReductionLevel = 9; */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 300);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 250);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 180);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 150);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT,
-+ (sharp_level > 3) ? 2 : 1);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ case 10:
-+ /* NoiseReductionLevel = 10; extrem noise */
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1, 1023);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 1023);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl0,
-+ MRV_FILT_FILT_THRESH_BL0, 1023);
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_bl1,
-+ MRV_FILT_FILT_THRESH_BL1, 1023);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_STAGE1_SELECT,
-+ (sharp_level > 5) ? 2 :
-+ ((sharp_level > 3) ? 1 : 0));
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_V_MODE,
-+ MRV_FILT_FILT_CHR_V_MODE_STATIC12);
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_CHR_H_MODE,
-+ MRV_FILT_FILT_CHR_H_MODE_DYN_2);
-+ break;
-+
-+ default:
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+
-+ switch (sharp_level) {
-+ /* SharpLevel = 0; no sharp enhancement */
-+ case 0:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000004);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x00000004);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000004);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000002);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000000);
-+ break;
-+
-+ /* SharpLevel = 1; */
-+ case 1:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000008);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x00000007);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000006);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000002);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000000);
-+ break;
-+
-+ /* SharpLevel = 2; */
-+ case 2:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x0000000C);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x0000000A);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000008);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000004);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000000);
-+ break;
-+
-+ /* SharpLevel = 3; */
-+ case 3:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000010);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x0000000C);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x0000000A);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000006);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000002);
-+ break;
-+
-+ /* SharpLevel = 4; */
-+ case 4:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000016);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x00000010);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x0000000C);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000008);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000004);
-+ break;
-+
-+ /* SharpLevel = 5; */
-+ case 5:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x0000001B);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x00000014);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000010);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x0000000A);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000004);
-+ break;
-+
-+ /* SharpLevel = 6; */
-+ case 6:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000020);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x0000001A);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000013);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x0000000C);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000006);
-+ break;
-+
-+ /* SharpLevel = 7; */
-+ case 7:
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000026);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x0000001E);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000017);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000010);
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000008);
-+ break;
-+
-+ /* SharpLevel = 8; */
-+ case 8:
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 0x00000013);
-+ if (REG_GET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1) > 0x0000008A) {
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1,
-+ 0x0000008A);
-+ }
-+ /* 43 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x0000002C);
-+ /* 36 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x00000024);
-+ /* 29 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x0000001D);
-+ /* 21 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000015);
-+ /* 14 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x0000000D);
-+ break;
-+
-+ /* SharpLevel = 9; */
-+ case 9:
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ MRV_FILT_FILT_THRESH_SH0, 0x00000013);
-+ if (REG_GET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1) > 0x0000008A) {
-+ REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ MRV_FILT_FILT_THRESH_SH1,
-+ 0x0000008A);
-+ }
-+ /* 48 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x00000030);
-+ /* 42 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x0000002A);
-+ /* 34 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000022);
-+ /* 26 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x0000001A);
-+ /* 20 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000014);
-+ break;
-+
-+ /* SharpLevel = 10; */
-+ case 10:
-+ /* REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh0,
-+ * MRV_FILT_FILT_THRESH_SH0, 0x00000013); */
-+ /* if (REG_GET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ * MRV_FILT_FILT_THRESH_SH1) > 0x0000008A) */
-+ /* { */
-+ /* REG_SET_SLICE(mrv_reg->isp_filt_thresh_sh1,
-+ * MRV_FILT_FILT_THRESH_SH1, 0x0000008A); */
-+ /* } */
-+
-+ /* 63 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh1,
-+ MRV_FILT_FILT_FAC_SH1, 0x0000003F);
-+ /* 48 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_sh0,
-+ MRV_FILT_FILT_FAC_SH0, 0x00000030);
-+ /* 40 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_mid,
-+ MRV_FILT_FILT_FAC_MID, 0x00000028);
-+ /* 36 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0, 0x00000024);
-+ /* 32 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1, 0x00000020);
-+ break;
-+
-+ default:
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+
-+ if (noise_reduc_level > 7) {
-+ if (sharp_level > 7) {
-+ u32 filt_fac_bl0 = REG_GET_SLICE
-+ (mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0);
-+ u32 filt_fac_bl1 =
-+ REG_GET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1);
-+ /* * 0.50 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0,
-+ (filt_fac_bl0) >> 1);
-+ /* * 0.25 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1,
-+ (filt_fac_bl1) >> 2);
-+ } else if (sharp_level > 4) {
-+ u32 filt_fac_bl0 =
-+ REG_GET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0);
-+ u32 filt_fac_bl1 =
-+ REG_GET_SLICE(mrv_reg->
-+ isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1);
-+ /* * 0.75 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl0,
-+ MRV_FILT_FILT_FAC_BL0,
-+ (filt_fac_bl0 * 3) >> 2);
-+ /* * 0.50 */
-+ REG_SET_SLICE(mrv_reg->isp_filt_fac_bl1,
-+ MRV_FILT_FILT_FAC_BL1,
-+ (filt_fac_bl1) >> 1);
-+ }
-+ }
-+
-+ /* Set ISP filter mode register values */
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_MODE,
-+ MRV_FILT_FILT_MODE_DYNAMIC);
-+
-+ /* enable filter */
-+ REG_SET_SLICE(isp_filt_mode, MRV_FILT_FILT_ENABLE, ENABLE);
-+ REG_WRITE(mrv_reg->isp_filt_mode, isp_filt_mode);
-+
-+ return CI_STATUS_SUCCESS;
-+ } else {
-+ /* At least one function parameter is out of range */
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+}
-+
-+int ci_isp_meas_exposure_initialize_module(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ REG_SET_SLICE(mrv_reg->isp_exp_h_size, MRV_AE_ISP_EXP_H_SIZE, 0);
-+ REG_SET_SLICE(mrv_reg->isp_exp_v_size, MRV_AE_ISP_EXP_V_SIZE, 0);
-+ REG_SET_SLICE(mrv_reg->isp_exp_h_offset, MRV_AE_ISP_EXP_H_OFFSET, 0);
-+ REG_SET_SLICE(mrv_reg->isp_exp_v_offset, MRV_AE_ISP_EXP_V_OFFSET, 0);
-+
-+ return CI_STATUS_SUCCESS;
-+
-+}
-+
-+/*
-+ * Configures the exposure measurement module.
-+ */
-+int ci_isp_meas_exposure_set_config(const struct ci_isp_window *wnd,
-+ const struct ci_isp_exp_ctrl *isp_exp_ctrl)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ if (!wnd) {
-+ /* stop loop if running */
-+ REG_SET_SLICE(mrv_reg->isp_exp_ctrl, MRV_AE_AUTOSTOP, ON);
-+ /* required? */
-+ REG_SET_SLICE(mrv_reg->isp_exp_ctrl, MRV_AE_EXP_START, OFF);
-+ return CI_STATUS_SUCCESS;
-+ }
-+
-+ /* range check */
-+ if ((wnd->hoffs > MRV_AE_ISP_EXP_H_OFFSET_MAX)
-+ || (wnd->hsize > MRV_AE_ISP_EXP_H_SIZE_MAX)
-+ || (wnd->voffs > MRV_AE_ISP_EXP_V_OFFSET_MAX)
-+ || (wnd->vsize > MRV_AE_ISP_EXP_V_SIZE_MAX)
-+ || (wnd->vsize & ~MRV_AE_ISP_EXP_V_SIZE_VALID_MASK))
-+ return CI_STATUS_OUTOFRANGE;
-+
-+ /* configure measurement windows */
-+ REG_SET_SLICE(mrv_reg->isp_exp_h_size, MRV_AE_ISP_EXP_H_SIZE,
-+ wnd->hsize);
-+ REG_SET_SLICE(mrv_reg->isp_exp_v_size, MRV_AE_ISP_EXP_V_SIZE,
-+ wnd->vsize);
-+ REG_SET_SLICE(mrv_reg->isp_exp_h_offset, MRV_AE_ISP_EXP_H_OFFSET,
-+ wnd->hoffs);
-+ REG_SET_SLICE(mrv_reg->isp_exp_v_offset, MRV_AE_ISP_EXP_V_OFFSET,
-+ wnd->voffs);
-+
-+ /* set exposure measurement mode */
-+ REG_SET_SLICE(mrv_reg->isp_exp_ctrl, MRV_AE_EXP_MEAS_MODE,
-+ (isp_exp_ctrl->exp_meas_mode) ? ON : OFF);
-+
-+ /* set or clear AE autostop bit */
-+ REG_SET_SLICE(mrv_reg->isp_exp_ctrl, MRV_AE_AUTOSTOP,
-+ (isp_exp_ctrl->auto_stop) ? ON : OFF);
-+ REG_SET_SLICE(mrv_reg->isp_exp_ctrl, MRV_AE_EXP_START,
-+ (isp_exp_ctrl->exp_start) ? ON : OFF);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Programs the given gamma curve for the input gamma
-+ * block. Enables or disables gamma processing for the
-+ * input gamma block.
-+ */
-+void ci_isp_set_gamma(const struct ci_sensor_gamma_curve *r,
-+ const struct ci_sensor_gamma_curve *g,
-+ const struct ci_sensor_gamma_curve *b)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *)MEM_MRV_REG_BASE;
-+ /* values stored as 16bit - use MSBs if cambuswidth is smaller */
-+ const u8 shift_val = 16 - MARVIN_FEATURE_CAMBUSWIDTH;
-+ /* used to round up values */
-+ const u16 round_ofs = 0 << (shift_val - 1);
-+ s32 i;
-+
-+ if (r) {
-+
-+ /*
-+ * Note: gamma curve increments are already register conform,
-+ * so REG_WRITE is used instead of REG_SET_SLICE
-+ */
-+
-+ /*
-+ * better would be split into 16 separate values to be
-+ * register independant
-+ */
-+
-+ /* gamma curve dx1..dx16 increments (each nibble of */
-+ REG_WRITE(mrv_reg->isp_gamma_dx_lo, r->gamma_dx0);
-+ /* the 32bit-values hold 3 valid bits, see register) */
-+ REG_WRITE(mrv_reg->isp_gamma_dx_hi, r->gamma_dx1);
-+
-+ for (i = 0; i < MRV_ISP_GAMMA_R_Y_ARR_SIZE; i++) {
-+ REG_SET_SLICE(mrv_reg->isp_gamma_r_y[i],
-+ MRV_ISP_GAMMA_R_Y,
-+ (r->isp_gamma_y[i] + round_ofs) >> shift_val);
-+ REG_SET_SLICE(mrv_reg->isp_gamma_g_y[i],
-+ MRV_ISP_GAMMA_G_Y,
-+ (g->isp_gamma_y[i] + round_ofs) >> shift_val);
-+ REG_SET_SLICE(mrv_reg->isp_gamma_b_y[i],
-+ MRV_ISP_GAMMA_B_Y,
-+ (b->isp_gamma_y[i] + round_ofs) >> shift_val);
-+ }
-+
-+ REG_SET_SLICE(mrv_reg->isp_ctrl,
-+ MRV_ISP_ISP_GAMMA_IN_ENABLE, ENABLE);
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_ctrl,
-+ MRV_ISP_ISP_GAMMA_IN_ENABLE, DISABLE);
-+ }
-+}
-+
-+/*
-+ * Programs the given gamma curve for the output gamma
-+ * block. Enables or disables gamma processing for the
-+ * output gamma block.
-+ */
-+void ci_isp_set_gamma2(const struct ci_isp_gamma_out_curve *gamma)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ s32 i;
-+
-+ if (gamma) {
-+ WARN_ON(!(MRV_ISP_GAMMA_OUT_Y_ARR_SIZE ==
-+ CI_ISP_GAMMA_OUT_CURVE_ARR_SIZE));
-+
-+ for (i = 0; i < MRV_ISP_GAMMA_OUT_Y_ARR_SIZE; i++) {
-+ REG_SET_SLICE(mrv_reg->isp_gamma_out_y[i],
-+ MRV_ISP_ISP_GAMMA_OUT_Y,
-+ gamma->isp_gamma_y[i]);
-+ }
-+
-+ /* gamma curve linear or log */
-+ REG_SET_SLICE(mrv_reg->isp_gamma_out_mode, MRV_ISP_EQU_SEGM,
-+ gamma->gamma_segmentation);
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_GAMMA_OUT_ENABLE,
-+ ENABLE);
-+ } else {
-+ REG_SET_SLICE(mrv_reg->isp_ctrl,
-+ MRV_ISP_ISP_GAMMA_OUT_ENABLE, DISABLE);
-+ }
-+
-+}
-diff --git a/drivers/media/video/mrstci/mrstisp/mrstisp_jpe.c b/drivers/media/video/mrstci/mrstisp/mrstisp_jpe.c
-new file mode 100644
-index 0000000..c042e06
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/mrstisp_jpe.c
-@@ -0,0 +1,569 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * Copyright (c) Silicon Image 2008 www.siliconimage.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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+
-+int ci_isp_jpe_init_ex(u16 hsize, u16 vsize, u8 compression_ratio, u8 jpe_scale)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /*
-+ * Reset JPEG-Encoder. In contrast to other software resets
-+ * this triggers the modules asynchronous reset resulting
-+ * in loss of all data.
-+ */
-+
-+ REG_SET_SLICE(mrv_reg->vi_ircl, MRV_VI_JPEG_SOFT_RST, ON);
-+ REG_SET_SLICE(mrv_reg->vi_ircl, MRV_VI_JPEG_SOFT_RST, OFF);
-+
-+ /* set configuration for the Jpeg capturing */
-+ ci_isp_jpe_set_config(hsize, vsize, jpe_scale);
-+
-+ /*
-+ * Sleep a while before setting up tables because of the 400
-+ * clock cycles required to initialize the table RAM after a
-+ * reset was issued. On FPGA we are running with only 30MHz,
-+ * so at least 13us are required.
-+ */
-+
-+
-+ /*
-+ * Note: this func is called when holding spin lock,
-+ * so can not change to msleep.
-+ */
-+ mdelay(15);
-+
-+ /* program tables */
-+ ci_isp_jpe_set_tables(compression_ratio);
-+
-+ /* choose tables */
-+ ci_isp_jpe_select_tables();
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * initialization of JPEG encoder
-+ */
-+int ci_isp_jpe_init(u32 resolution, u8 compression_ratio, int jpe_scale)
-+{
-+ u16 hsize = 0;
-+ u16 vsize = 0;
-+
-+ switch (resolution) {
-+ case SENSOR_RES_BP1:
-+ /* 352; */
-+ hsize = BP1_SIZE_H;
-+ /* 240; */
-+ vsize = BP1_SIZE_V;
-+ break;
-+ case SENSOR_RES_S_AFM:
-+ /* 64; */
-+ hsize = S_AFM_SIZE_H;
-+ /* 32; */
-+ vsize = S_AFM_SIZE_V;
-+ break;
-+ case SENSOR_RES_M_AFM:
-+ /* 128; */
-+ hsize = M_AFM_SIZE_H;
-+ /* 96; */
-+ vsize = M_AFM_SIZE_V;
-+ break;
-+ case SENSOR_RES_L_AFM:
-+ /* 720; */
-+ hsize = L_AFM_SIZE_H;
-+ /* 480; */
-+ vsize = L_AFM_SIZE_V;
-+ break;
-+ case SENSOR_RES_QQCIF:
-+ /* 88; */
-+ hsize = QQCIF_SIZE_H;
-+ /* 72; */
-+ vsize = QQCIF_SIZE_V;
-+ break;
-+ case SENSOR_RES_QQVGA:
-+ /* 160; */
-+ hsize = QQVGA_SIZE_H;
-+ /* 120; */
-+ vsize = QQVGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_QCIF:
-+ /* 176; */
-+ hsize = QCIF_SIZE_H;
-+ /* 144; */
-+ vsize = QCIF_SIZE_V;
-+ break;
-+ case SENSOR_RES_QVGA:
-+ /* 320; */
-+ hsize = QVGA_SIZE_H;
-+ /* 240; */
-+ vsize = QVGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_CIF:
-+ /* 352; */
-+ hsize = CIF_SIZE_H;
-+ /* 288; */
-+ vsize = CIF_SIZE_V;
-+ break;
-+ case SENSOR_RES_VGA:
-+ /* 640; */
-+ hsize = VGA_SIZE_H;
-+ /* 480; */
-+ vsize = VGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_SVGA:
-+ /* 800; */
-+ hsize = SVGA_SIZE_H;
-+ /* 600; */
-+ vsize = SVGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_XGA:
-+ /* 1024; */
-+ hsize = XGA_SIZE_H;
-+ /* 768; */
-+ vsize = XGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_XGA_PLUS:
-+ /* 1280; */
-+ hsize = XGA_PLUS_SIZE_H;
-+ /* 960; */
-+ vsize = XGA_PLUS_SIZE_V;
-+ break;
-+ case SENSOR_RES_SXGA:
-+ /* 1280; */
-+ hsize = SXGA_SIZE_H;
-+ /* 1024; */
-+ vsize = SXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_UXGA:
-+ /* 1600; */
-+ hsize = UXGA_SIZE_H;
-+ /* 1200; */
-+ vsize = UXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_QXGA:
-+ /* 2048; */
-+ hsize = QXGA_SIZE_H;
-+ /* 1536; */
-+ vsize = QXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_QSXGA:
-+ /* 2586; */
-+ hsize = QSXGA_SIZE_H;
-+ /* 2048; */
-+ vsize = QSXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_QSXGA_PLUS:
-+ /* 2600; */
-+ hsize = QSXGA_PLUS_SIZE_H;
-+ /* 2048; */
-+ vsize = QSXGA_PLUS_SIZE_V;
-+ break;
-+ case SENSOR_RES_QSXGA_PLUS2:
-+ /* 2600; */
-+ hsize = QSXGA_PLUS2_SIZE_H;
-+ /* 1950; */
-+ vsize = QSXGA_PLUS2_SIZE_V;
-+ break;
-+ case SENSOR_RES_QSXGA_PLUS3:
-+ /* 2686; */
-+ hsize = QSXGA_PLUS3_SIZE_H;
-+ /* 2048; */
-+ vsize = QSXGA_PLUS3_SIZE_V;
-+ break;
-+ case SENSOR_RES_WQSXGA:
-+ /* 3200 */
-+ hsize = WQSXGA_SIZE_H;
-+ /* 2048 */
-+ vsize = WQSXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_QUXGA:
-+ /* 3200 */
-+ hsize = QUXGA_SIZE_H;
-+ /* 2400 */
-+ vsize = QUXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_WQUXGA:
-+ /* 3840 */
-+ hsize = WQUXGA_SIZE_H;
-+ /* 2400 */
-+ vsize = WQUXGA_SIZE_V;
-+ break;
-+ case SENSOR_RES_HXGA:
-+ /* 4096 */
-+ hsize = HXGA_SIZE_H;
-+ /* 3072 */
-+ vsize = HXGA_SIZE_V;
-+ break;
-+ default:
-+ eprintk("resolution not supported");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ return ci_isp_jpe_init_ex(hsize, vsize, compression_ratio, jpe_scale);
-+}
-+
-+void ci_isp_jpe_set_tables(u8 compression_ratio)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ /* required because auto-increment register */
-+ u32 jpe_table_data = 0;
-+
-+ u8 idx, size;
-+ const u8 *yqtable = NULL;
-+ const u8 *uvqtable = NULL;
-+
-+ switch (compression_ratio) {
-+ case CI_ISP_JPEG_LOW_COMPRESSION:
-+ yqtable = ci_isp_yq_table_low_comp1;
-+ uvqtable = ci_isp_uv_qtable_low_comp1;
-+ break;
-+ case CI_ISP_JPEG_01_PERCENT:
-+ yqtable = ci_isp_yq_table01_per_cent;
-+ uvqtable = ci_isp_uv_qtable01_per_cent;
-+ break;
-+ case CI_ISP_JPEG_20_PERCENT:
-+ yqtable = ci_isp_yq_table20_per_cent;
-+ uvqtable = ci_isp_uv_qtable20_per_cent;
-+ break;
-+ case CI_ISP_JPEG_30_PERCENT:
-+ yqtable = ci_isp_yq_table30_per_cent;
-+ uvqtable = ci_isp_uv_qtable30_per_cent;
-+ break;
-+ case CI_ISP_JPEG_40_PERCENT:
-+ yqtable = ci_isp_yq_table40_per_cent;
-+ uvqtable = ci_isp_uv_qtable40_per_cent;
-+ break;
-+ case CI_ISP_JPEG_50_PERCENT:
-+ yqtable = ci_isp_yq_table50_per_cent;
-+ uvqtable = ci_isp_uv_qtable50_per_cent;
-+ break;
-+ case CI_ISP_JPEG_60_PERCENT:
-+ yqtable = ci_isp_yq_table60_per_cent;
-+ uvqtable = ci_isp_uv_qtable60_per_cent;
-+ break;
-+ case CI_ISP_JPEG_70_PERCENT:
-+ yqtable = ci_isp_yq_table70_per_cent;
-+ uvqtable = ci_isp_uv_qtable70_per_cent;
-+ break;
-+ case CI_ISP_JPEG_80_PERCENT:
-+ yqtable = ci_isp_yq_table80_per_cent;
-+ uvqtable = ci_isp_uv_qtable80_per_cent;
-+ break;
-+ case CI_ISP_JPEG_90_PERCENT:
-+ yqtable = ci_isp_yq_table90_per_cent;
-+ uvqtable = ci_isp_uv_qtable90_per_cent;
-+ break;
-+ case CI_ISP_JPEG_99_PERCENT:
-+ yqtable = ci_isp_yq_table99_per_cent;
-+ uvqtable = ci_isp_uv_qtable99_per_cent;
-+ break;
-+ case CI_ISP_JPEG_HIGH_COMPRESSION:
-+ default:
-+ /*
-+ * in the case an unknown value is set,
-+ * use CI_JPEG_HIGH_COMPRESSION
-+ */
-+ yqtable = ci_isp_yq_table75_per_cent;
-+ uvqtable = ci_isp_uv_qtable75_per_cent;
-+ break;
-+ }
-+
-+ /* Y q-table 0 programming */
-+
-+ /* all possible assigned tables have same size */
-+ size = sizeof(ci_isp_yq_table75_per_cent)/
-+ sizeof(ci_isp_yq_table75_per_cent[0]);
-+ REG_SET_SLICE(mrv_reg->jpe_table_id, MRV_JPE_TABLE_ID,
-+ MRV_JPE_TABLE_ID_QUANT0);
-+ for (idx = 0; idx < (size - 1); idx += 2) {
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_H,
-+ yqtable[idx]);
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_L,
-+ yqtable[idx + 1]);
-+ /* auto-increment register! */
-+ REG_WRITE(mrv_reg->jpe_table_data, jpe_table_data);
-+ }
-+
-+ /* U/V q-table 0 programming */
-+
-+ /* all possible assigned tables have same size */
-+ size = sizeof(ci_isp_uv_qtable75_per_cent) /
-+ sizeof(ci_isp_uv_qtable75_per_cent[0]);
-+ REG_SET_SLICE(mrv_reg->jpe_table_id, MRV_JPE_TABLE_ID,
-+ MRV_JPE_TABLE_ID_QUANT1);
-+ for (idx = 0; idx < (size - 1); idx += 2) {
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_H,
-+ uvqtable[idx]);
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_L,
-+ uvqtable[idx + 1]);
-+ /* auto-increment register! */
-+ REG_WRITE(mrv_reg->jpe_table_data, jpe_table_data);
-+ }
-+
-+ /* Y AC-table 0 programming */
-+
-+ size = sizeof(ci_isp_ac_luma_table_annex_k) /
-+ sizeof(ci_isp_ac_luma_table_annex_k[0]);
-+ REG_SET_SLICE(mrv_reg->jpe_table_id, MRV_JPE_TABLE_ID,
-+ MRV_JPE_TABLE_ID_VLC_AC0);
-+ REG_SET_SLICE(mrv_reg->jpe_tac0_len, MRV_JPE_TAC0_LEN, size);
-+ for (idx = 0; idx < (size - 1); idx += 2) {
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_H,
-+ ci_isp_ac_luma_table_annex_k[idx]);
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_L,
-+ ci_isp_ac_luma_table_annex_k[idx + 1]);
-+ /* auto-increment register! */
-+ REG_WRITE(mrv_reg->jpe_table_data, jpe_table_data);
-+ }
-+
-+ /* U/V AC-table 1 programming */
-+
-+ size = sizeof(ci_isp_ac_chroma_table_annex_k) /
-+ sizeof(ci_isp_ac_chroma_table_annex_k[0]);
-+ REG_SET_SLICE(mrv_reg->jpe_table_id, MRV_JPE_TABLE_ID,
-+ MRV_JPE_TABLE_ID_VLC_AC1);
-+ REG_SET_SLICE(mrv_reg->jpe_tac1_len, MRV_JPE_TAC1_LEN, size);
-+ for (idx = 0; idx < (size - 1); idx += 2) {
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_H,
-+ ci_isp_ac_chroma_table_annex_k[idx]);
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_L,
-+ ci_isp_ac_chroma_table_annex_k[idx + 1]);
-+ /* auto-increment register! */
-+ REG_WRITE(mrv_reg->jpe_table_data, jpe_table_data);
-+ }
-+
-+ /* Y DC-table 0 programming */
-+
-+ size = sizeof(ci_isp_dc_luma_table_annex_k) /
-+ sizeof(ci_isp_dc_luma_table_annex_k[0]);
-+ REG_SET_SLICE(mrv_reg->jpe_table_id, MRV_JPE_TABLE_ID,
-+ MRV_JPE_TABLE_ID_VLC_DC0);
-+ REG_SET_SLICE(mrv_reg->jpe_tdc0_len, MRV_JPE_TDC0_LEN, size);
-+ for (idx = 0; idx < (size - 1); idx += 2) {
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_H,
-+ ci_isp_dc_luma_table_annex_k[idx]);
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_L,
-+ ci_isp_dc_luma_table_annex_k[idx + 1]);
-+ /* auto-increment register! */
-+ REG_WRITE(mrv_reg->jpe_table_data, jpe_table_data);
-+ }
-+
-+ /* U/V DC-table 1 programming */
-+
-+ size = sizeof(ci_isp_dc_chroma_table_annex_k) /
-+ sizeof(ci_isp_dc_chroma_table_annex_k[0]);
-+ REG_SET_SLICE(mrv_reg->jpe_table_id, MRV_JPE_TABLE_ID,
-+ MRV_JPE_TABLE_ID_VLC_DC1);
-+ REG_SET_SLICE(mrv_reg->jpe_tdc1_len, MRV_JPE_TDC1_LEN, size);
-+ for (idx = 0; idx < (size - 1); idx += 2) {
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_H,
-+ ci_isp_dc_chroma_table_annex_k[idx]);
-+ REG_SET_SLICE(jpe_table_data, MRV_JPE_TABLE_WDATA_L,
-+ ci_isp_dc_chroma_table_annex_k[idx + 1]);
-+ /* auto-increment register! */
-+ REG_WRITE(mrv_reg->jpe_table_data, jpe_table_data);
-+ }
-+}
-+
-+/*
-+ * selects tables to be used by encoder
-+ */
-+void ci_isp_jpe_select_tables(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /* selects quantization table for Y */
-+ REG_SET_SLICE(mrv_reg->jpe_tq_y_select, MRV_JPE_TQ0_SELECT,
-+ MRV_JPE_TQ_SELECT_TAB0);
-+ /* selects quantization table for U */
-+ REG_SET_SLICE(mrv_reg->jpe_tq_u_select, MRV_JPE_TQ1_SELECT,
-+ MRV_JPE_TQ_SELECT_TAB1);
-+ /* selects quantization table for V */
-+ REG_SET_SLICE(mrv_reg->jpe_tq_v_select, MRV_JPE_TQ2_SELECT,
-+ MRV_JPE_TQ_SELECT_TAB1);
-+ /* selects Huffman DC table */
-+ REG_SET_SLICE(mrv_reg->jpe_dc_table_select,
-+ MRV_JPE_DC_TABLE_SELECT_Y, 0);
-+ REG_SET_SLICE(mrv_reg->jpe_dc_table_select,
-+ MRV_JPE_DC_TABLE_SELECT_U, 1);
-+ REG_SET_SLICE(mrv_reg->jpe_dc_table_select,
-+ MRV_JPE_DC_TABLE_SELECT_V, 1);
-+ /* selects Huffman AC table */
-+ REG_SET_SLICE(mrv_reg->jpe_ac_table_select,
-+ MRV_JPE_AC_TABLE_SELECT_Y, 0);
-+ REG_SET_SLICE(mrv_reg->jpe_ac_table_select,
-+ MRV_JPE_AC_TABLE_SELECT_U, 1);
-+ REG_SET_SLICE(mrv_reg->jpe_ac_table_select,
-+ MRV_JPE_AC_TABLE_SELECT_V, 1);
-+}
-+
-+/*
-+ * configure JPEG encoder
-+ */
-+void ci_isp_jpe_set_config(u16 hsize, u16 vsize, int jpe_scale)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ /* JPEG image size */
-+
-+ REG_SET_SLICE(mrv_reg->jpe_enc_hsize, MRV_JPE_ENC_HSIZE, hsize);
-+ REG_SET_SLICE(mrv_reg->jpe_enc_vsize, MRV_JPE_ENC_VSIZE, vsize);
-+
-+ if (jpe_scale) {
-+ /* upscaling of BT601 color space to full range 0..255 */
-+ REG_SET_SLICE(mrv_reg->jpe_y_scale_en, MRV_JPE_Y_SCALE_EN,
-+ ENABLE);
-+ REG_SET_SLICE(mrv_reg->jpe_cbcr_scale_en,
-+ MRV_JPE_CBCR_SCALE_EN, ENABLE);
-+ } else {
-+ /* bypass scaler */
-+ REG_SET_SLICE(mrv_reg->jpe_y_scale_en,
-+ MRV_JPE_Y_SCALE_EN, DISABLE);
-+ REG_SET_SLICE(mrv_reg->jpe_cbcr_scale_en,
-+ MRV_JPE_CBCR_SCALE_EN, DISABLE);
-+ }
-+
-+ /* picture format YUV 422 */
-+ REG_SET_SLICE(mrv_reg->jpe_pic_format, MRV_JPE_ENC_PIC_FORMAT,
-+ MRV_JPE_ENC_PIC_FORMAT_422);
-+ REG_SET_SLICE(mrv_reg->jpe_table_flush, MRV_JPE_TABLE_FLUSH, 0);
-+}
-+
-+int ci_isp_jpe_generate_header(struct mrst_isp_device *intel, u8 header_mode)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ WARN_ON(!((header_mode == MRV_JPE_HEADER_MODE_JFIF)
-+ || (header_mode == MRV_JPE_HEADER_MODE_NO)));
-+
-+ /* clear jpeg gen_header_done interrupt */
-+ /* since we poll them later to detect command completion */
-+
-+ REG_SET_SLICE(mrv_reg->jpe_status_icr, MRV_JPE_GEN_HEADER_DONE, 1);
-+ REG_SET_SLICE(mrv_reg->jpe_header_mode, MRV_JPE_HEADER_MODE,
-+ header_mode);
-+
-+ /* start header generation */
-+ REG_SET_SLICE(mrv_reg->jpe_gen_header, MRV_JPE_GEN_HEADER, ON);
-+
-+ return ci_isp_jpe_wait_for_header_gen_done(intel);
-+}
-+
-+void ci_isp_jpe_prep_enc(enum ci_isp_jpe_enc_mode jpe_enc_mode)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 jpe_encode = REG_READ(mrv_reg->jpe_encode);
-+
-+ /* clear jpeg encode_done interrupt */
-+ /* since we poll them later to detect command completion */
-+
-+ REG_SET_SLICE(mrv_reg->jpe_status_icr, MRV_JPE_ENCODE_DONE, 1);
-+ REG_SET_SLICE(jpe_encode, MRV_JPE_ENCODE, ON);
-+
-+ switch (jpe_enc_mode) {
-+ case CI_ISP_JPE_LARGE_CONT_MODE:
-+ /* motion JPEG with header generation */
-+ REG_SET_SLICE(jpe_encode, MRV_JPE_CONT_MODE,
-+ MRV_JPE_CONT_MODE_HEADER);
-+ break;
-+ case CI_ISP_JPE_SHORT_CONT_MODE:
-+ /* motion JPEG only first frame with header */
-+ REG_SET_SLICE(jpe_encode, MRV_JPE_CONT_MODE,
-+ MRV_JPE_CONT_MODE_NEXT);
-+ break;
-+ default:
-+ /* single shot JPEG */
-+ REG_SET_SLICE(jpe_encode, MRV_JPE_CONT_MODE,
-+ MRV_JPE_CONT_MODE_STOP);
-+ break;
-+ }
-+
-+ REG_WRITE(mrv_reg->jpe_encode, jpe_encode);
-+ REG_SET_SLICE(mrv_reg->jpe_init, MRV_JPE_JP_INIT, 1);
-+}
-+
-+/*
-+ * wait until JPG Header is generated (MRV_JPGINT_GEN_HEADER_DONE
-+ * interrupt occurs)
-+ * waiting for JPG Header to be generated
-+ */
-+int ci_isp_jpe_wait_for_header_gen_done(struct mrst_isp_device *intel)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ mrst_timer_start();
-+
-+ while (!REG_GET_SLICE(mrv_reg->jpe_status_ris,
-+ MRV_JPE_GEN_HEADER_DONE)) {
-+ if (mrst_get_micro_sec() > 2000000) {
-+ mrst_timer_stop();
-+ eprintk("timeout");
-+ return CI_STATUS_FAILURE;
-+ }
-+ }
-+
-+ mrst_timer_stop();
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * wait until JPG Encoder is done (MRV_JPGINT_ENCODE_DONE
-+ * interrupt occurs) waiting for the JPG Encoder to be done
-+ */
-+int ci_isp_jpe_wait_for_encode_done(struct mrst_isp_device *intel)
-+{
-+#if 0
-+ int ret = 0;
-+ INIT_COMPLETION(intel->jpe_complete);
-+ ret = wait_for_completion_interruptible_timeout(&intel->jpe_complete,
-+ 100 * HZ);
-+ if ((ret == 0) | (intel->irq_stat == IRQ_JPE_ERROR)) {
-+ eprintk("timeout");
-+ return CI_STATUS_FAILURE;
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+#endif
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ mrst_timer_start();
-+
-+ while (!REG_GET_SLICE(mrv_reg->jpe_status_ris,
-+ MRV_JPE_ENCODE_DONE)) {
-+ if (mrst_get_micro_sec() > 200000) {
-+ mrst_timer_stop();
-+ eprintk("timeout");
-+ return CI_STATUS_FAILURE;
-+ }
-+ }
-+
-+ mrst_timer_stop();
-+
-+ /* clear jpeg encode_done interrupt */
-+ REG_SET_SLICE(mrv_reg->jpe_status_icr, MRV_JPE_ENCODE_DONE, 1);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-diff --git a/drivers/media/video/mrstci/mrstisp/mrstisp_main.c b/drivers/media/video/mrstci/mrstisp/mrstisp_main.c
-new file mode 100644
-index 0000000..e37b3d1
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/mrstisp_main.c
-@@ -0,0 +1,2977 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+#include "ci_isp_fmts_common.h"
-+
-+#define GPIO_SCLK_25 44
-+#define GPIO_STDBY1_PIN 48
-+#define GPIO_STDBY2_PIN 49
-+#define GPIO_RESET_PIN 50
-+
-+int mrstisp_debug;
-+module_param(mrstisp_debug, int, 0644);
-+
-+/*XXX*/
-+static int frame_cnt;
-+static long mipi_error_num;
-+static u32 mipi_error_flag;
-+static long isp_error_num;
-+static u32 isp_error_flag;
-+static unsigned long jiffies_start;
-+static int mipi_flag;
-+
-+void intel_timer_start(void)
-+{
-+ jiffies_start = jiffies;
-+}
-+void intel_timer_stop(void)
-+{
-+ jiffies_start = 0;
-+}
-+unsigned long intel_get_micro_sec(void)
-+{
-+ unsigned long time_diff = 0;
-+
-+ time_diff = jiffies - jiffies_start;
-+
-+ return jiffies_to_msecs(time_diff);
-+}
-+
-+
-+static inline struct mrst_isp_device *to_isp(struct v4l2_device *dev)
-+{
-+ return container_of(dev, struct mrst_isp_device, v4l2_dev);
-+}
-+
-+static struct mrst_camera mrst_camera_table[] = {
-+ {
-+ .type = MRST_CAMERA_SOC,
-+ .name = "ov2650",
-+ .sensor_addr = 0x30,
-+ },
-+ {
-+ .type = MRST_CAMERA_SOC,
-+ .name = "ov9665",
-+ .sensor_addr = 0x30,
-+ },
-+ {
-+ .type = MRST_CAMERA_RAW,
-+ .name = "ov5630",
-+ .sensor_addr = 0x36,
-+ .motor_name = "ov5630_motor",
-+ .motor_addr = (0x18 >> 1),
-+ },
-+ {
-+ .type = MRST_CAMERA_RAW,
-+ .name = "s5k4e1",
-+ .sensor_addr = 0x36,
-+ .motor_name = "s5k4e1_motor",
-+ .motor_addr = (0x18 >> 1),
-+ },
-+};
-+
-+#define N_CAMERA (ARRAY_SIZE(mrst_camera_table))
-+
-+struct videobuf_dma_contig_memory {
-+ u32 magic;
-+ void *vaddr;
-+ dma_addr_t dma_handle;
-+ unsigned long size;
-+ int is_userptr;
-+};
-+#define MAGIC_DC_MEM 0x0733ac61
-+#define MAGIC_CHECK(is, should) \
-+ if (unlikely((is) != (should))) { \
-+ pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
-+ BUG(); \
-+ }
-+/* flag to determine whether to do the handler of mblk_line irq */
-+int mrst_isp_to_do_mblk_line;
-+unsigned char *mrst_isp_regs;
-+
-+static inline struct ci_sensor_config *to_sensor_config(struct v4l2_subdev *sd)
-+{
-+ return container_of(sd, struct ci_sensor_config, sd);
-+}
-+
-+/* g45-th20-b5 gamma out curve with enhanced black level */
-+static struct ci_isp_gamma_out_curve g45_th20_b5 = {
-+ {
-+ 0x0000, 0x0014, 0x003C, 0x0064,
-+ 0x00A0, 0x0118, 0x0171, 0x01A7,
-+ 0x01D8, 0x0230, 0x027A, 0x02BB,
-+ 0x0323, 0x0371, 0x03AD, 0x03DB,
-+ 0x03FF}
-+ ,
-+ 0
-+};
-+
-+static void print_snr_cfg(struct ci_sensor_config *cfg)
-+{
-+ dprintk(2, "bus width = %x", cfg->bus_width);
-+ dprintk(2, "mode = %x", cfg->mode);
-+ dprintk(2, "field_inv = %x", cfg->field_inv);
-+ dprintk(2, "field_sel = %x", cfg->field_sel);
-+ dprintk(2, "ycseq = %x", cfg->ycseq);
-+ dprintk(2, "conv422 = %x", cfg->conv422);
-+ dprintk(2, "bpat = %x", cfg->bpat);
-+ dprintk(2, "hpol = %x", cfg->hpol);
-+ dprintk(2, "vpol = %x", cfg->vpol);
-+ dprintk(2, "edge = %x", cfg->edge);
-+ dprintk(2, "bls = %x", cfg->bls);
-+ dprintk(2, "gamma = %x", cfg->gamma);
-+ dprintk(2, "cconv = %x", cfg->cconv);
-+ dprintk(2, "res = %x", cfg->res);
-+ dprintk(2, "blc = %x", cfg->blc);
-+ dprintk(2, "agc = %x", cfg->agc);
-+ dprintk(2, "awb = %x", cfg->awb);
-+ dprintk(2, "aec = %x", cfg->aec);
-+ dprintk(2, "cie_profile = %x", cfg->cie_profile);
-+ dprintk(2, "flicker_freq = %x", cfg->flicker_freq);
-+ dprintk(2, "smia_mode = %x", cfg->smia_mode);
-+ dprintk(2, "mipi_mode = %x", cfg->mipi_mode);
-+ dprintk(2, "type = %x", cfg->type);
-+ dprintk(2, "name = %s", cfg->name);
-+}
-+
-+static int mrst_isp_defcfg_all_load(struct ci_isp_config *isp_config)
-+{
-+
-+ DBG_entering;
-+
-+ /* demosaic mode */
-+ isp_config->demosaic_mode = CI_ISP_DEMOSAIC_ENHANCED;
-+
-+ /* bpc */
-+ isp_config->bpc_cfg.bp_corr_type = CI_ISP_BP_CORR_DIRECT;
-+ isp_config->bpc_cfg.bp_corr_rep = CI_ISP_BP_CORR_REP_NB;
-+ isp_config->bpc_cfg.bp_corr_mode = CI_ISP_BP_CORR_HOT_DEAD_EN;
-+ isp_config->bpc_cfg.bp_abs_hot_thres = 496;
-+ isp_config->bpc_cfg.bp_abs_dead_thres = 20;
-+ isp_config->bpc_cfg.bp_dev_hot_thres = 328;
-+ isp_config->bpc_cfg.bp_dev_dead_thres = 328;
-+ isp_config->bpd_cfg.bp_dead_thres = 1;
-+
-+ /* WB */
-+ isp_config->wb_config.mrv_wb_mode = CI_ISP_AWB_AUTO;
-+ isp_config->wb_config.mrv_wb_sub_mode = CI_ISP_AWB_AUTO_ON;
-+ isp_config->wb_config.awb_pca_damping = 16;
-+ isp_config->wb_config.awb_prior_exp_damping = 12;
-+ isp_config->wb_config.awb_pca_push_damping = 16;
-+ isp_config->wb_config.awb_prior_exp_push_damping = 12;
-+ isp_config->wb_config.awb_auto_max_y = 254;
-+ isp_config->wb_config.awb_push_max_y = 250;
-+ isp_config->wb_config.awb_measure_max_y = 200;
-+ isp_config->wb_config.awb_underexp_det = 10;
-+ isp_config->wb_config.awb_push_underexp_det = 170;
-+
-+ /* CAC */
-+ isp_config->cac_config.hsize = 2048;
-+ isp_config->cac_config.vsize = 1536;
-+ isp_config->cac_config.hcenter_offset = 0;
-+ isp_config->cac_config.vcenter_offset = 0;
-+ isp_config->cac_config.hclip_mode = 1;
-+ isp_config->cac_config.vclip_mode = 2;
-+ isp_config->cac_config.ablue = 24;
-+ isp_config->cac_config.ared = 489;
-+ isp_config->cac_config.bblue = 450;
-+ isp_config->cac_config.bred = 53;
-+ isp_config->cac_config.cblue = 40;
-+ isp_config->cac_config.cred = 479;
-+ isp_config->cac_config.aspect_ratio = 0.000000;
-+
-+ /* BLS */
-+ isp_config->bls_cfg.enable_automatic = 0;
-+ isp_config->bls_cfg.disable_h = 0;
-+ isp_config->bls_cfg.disable_v = 0;
-+ isp_config->bls_cfg.isp_bls_window1.enable_window = 0;
-+ isp_config->bls_cfg.isp_bls_window1.start_h = 0;
-+ isp_config->bls_cfg.isp_bls_window1.stop_h = 0;
-+ isp_config->bls_cfg.isp_bls_window1.start_v = 0;
-+ isp_config->bls_cfg.isp_bls_window1.stop_v = 0;
-+ isp_config->bls_cfg.isp_bls_window2.enable_window = 0;
-+ isp_config->bls_cfg.isp_bls_window2.start_h = 0;
-+ isp_config->bls_cfg.isp_bls_window2.stop_h = 0;
-+ isp_config->bls_cfg.isp_bls_window2.start_v = 0;
-+ isp_config->bls_cfg.isp_bls_window2.stop_v = 0;
-+ isp_config->bls_cfg.bls_samples = 5;
-+ isp_config->bls_cfg.bls_subtraction.fixed_a = 0x100;
-+ isp_config->bls_cfg.bls_subtraction.fixed_b = 0x100;
-+ isp_config->bls_cfg.bls_subtraction.fixed_c = 0x100;
-+ isp_config->bls_cfg.bls_subtraction.fixed_d = 0x100;
-+
-+ /* AF */
-+ isp_config->af_cfg.wnd_pos_a.hoffs = 874;
-+ isp_config->af_cfg.wnd_pos_a.voffs = 618;
-+ isp_config->af_cfg.wnd_pos_a.hsize = 300;
-+ isp_config->af_cfg.wnd_pos_a.vsize = 300;
-+ isp_config->af_cfg.wnd_pos_b.hoffs = 0;
-+ isp_config->af_cfg.wnd_pos_b.voffs = 0;
-+ isp_config->af_cfg.wnd_pos_b.hsize = 0;
-+ isp_config->af_cfg.wnd_pos_b.vsize = 0;
-+ isp_config->af_cfg.wnd_pos_c.hoffs = 0;
-+ isp_config->af_cfg.wnd_pos_c.voffs = 0;
-+ isp_config->af_cfg.wnd_pos_c.hsize = 0;
-+ isp_config->af_cfg.wnd_pos_c.vsize = 0;
-+ isp_config->af_cfg.threshold = 0x00000000;
-+
-+ /* color */
-+ isp_config->color.contrast = 128;
-+ isp_config->color.brightness = 0;
-+ isp_config->color.saturation = 128;
-+ isp_config->color.hue = 0;
-+
-+ /* Img Effect */
-+ isp_config->img_eff_cfg.mode = CI_ISP_IE_MODE_OFF;
-+ isp_config->img_eff_cfg.color_sel = 4;
-+ isp_config->img_eff_cfg.color_thres = 128;
-+ isp_config->img_eff_cfg.tint_cb = 108;
-+ isp_config->img_eff_cfg.tint_cr = 141;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_11 = 2;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_12 = 1;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_13 = 0;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_21 = 1;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_22 = 0;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_23 = -1;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_31 = 0;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_32 = -1;
-+ isp_config->img_eff_cfg.mat_emboss.coeff_33 = -2;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_11 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_12 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_13 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_21 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_22 = 8;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_23 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_31 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_32 = -1;
-+ isp_config->img_eff_cfg.mat_sketch.coeff_33 = -1;
-+
-+ /* Framefun */
-+ isp_config->flags.bls = 0;
-+ isp_config->flags.lsc = 0;
-+ isp_config->flags.bpc = 0;
-+ isp_config->flags.awb = 0;
-+ isp_config->flags.aec = 0;
-+ isp_config->flags.af = 0;
-+ isp_config->flags.cp = 0;
-+ isp_config->flags.gamma = 0;
-+ isp_config->flags.cconv = 0;
-+ isp_config->flags.demosaic = 0;
-+ isp_config->flags.gamma2 = 0;
-+ isp_config->flags.isp_filters = 0;
-+ isp_config->flags.cac = 0;
-+ isp_config->flags.cconv_basic = 0;
-+ isp_config->demosaic_th = 4;
-+
-+ isp_config->view_finder.flags = VFFLAG_HWRGB;
-+
-+ isp_config->afm_mode = 1;
-+ isp_config->filter_level_noise_reduc = 4;
-+ isp_config->filter_level_sharp = 4;
-+
-+ isp_config->jpeg_enc_ratio = 1;
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static void mrst_isp_update_marvinvfaddr(struct mrst_isp_device *isp,
-+ u32 buffer_base,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ struct ci_isp_mi_path_conf isp_mi_path_conf;
-+ struct ci_isp_mi_path_conf isp_sf_mi_path_conf;
-+ static struct v4l2_jpg_review_buffer *jpg_review;
-+ u32 bufsize = 0;
-+ u32 w;
-+ u32 h;
-+
-+ jpg_review = &isp->sys_conf.jpg_review;
-+ memset(&isp_mi_path_conf, 0, sizeof(struct ci_isp_mi_path_conf));
-+ memset(&isp_sf_mi_path_conf, 0, sizeof(struct ci_isp_mi_path_conf));
-+
-+ w = isp_mi_path_conf.llength = isp->bufwidth;
-+ h = isp_mi_path_conf.ypic_height = isp->bufheight;
-+ isp_mi_path_conf.ypic_width = isp->bufwidth;
-+
-+ /*XXX Zheng: disable jpg review for MIPI sensor */
-+ /*if ((isp->sys_conf.isi_config)->mipi_mode == SENSOR_MIPI_MODE_RAW_10)
-+ isp->sys_conf.jpg_review_enable = 0;
-+ */
-+
-+ if (isp->sys_conf.jpg_review_enable) {
-+
-+ /* for self path, JPEG review */
-+ isp_sf_mi_path_conf.ypic_width = jpg_review->width;
-+ isp_sf_mi_path_conf.llength = jpg_review->width;
-+ isp_sf_mi_path_conf.ypic_height = jpg_review->height;
-+
-+ bufsize = jpg_review->width * jpg_review->height;
-+
-+ /* buffer size in bytes */
-+ if (jpg_review->pix_fmt == V4L2_PIX_FMT_YUV420
-+ || jpg_review->pix_fmt == V4L2_PIX_FMT_YVU420) {
-+
-+ dprintk(3, "VF yuv420 fmt");
-+ isp_sf_mi_path_conf.ybuffer.size = bufsize;
-+ isp_sf_mi_path_conf.cb_buffer.size = bufsize/4;
-+ isp_sf_mi_path_conf.cr_buffer.size = bufsize/4;
-+
-+ } else if (jpg_review->pix_fmt == V4L2_PIX_FMT_YUV422P) {
-+
-+ dprintk(3, "VF yuv422 fmt");
-+ isp_sf_mi_path_conf.ybuffer.size = bufsize;
-+ isp_sf_mi_path_conf.cb_buffer.size = bufsize/2;
-+ isp_sf_mi_path_conf.cr_buffer.size = bufsize/2;
-+
-+ } else if (jpg_review->pix_fmt == V4L2_PIX_FMT_NV12) {
-+
-+ dprintk(3, "VF nv12 fmt");
-+ isp_sf_mi_path_conf.ybuffer.size = bufsize;
-+ isp_sf_mi_path_conf.cb_buffer.size = bufsize/2;
-+ isp_sf_mi_path_conf.cr_buffer.size = 0;
-+
-+ } else {
-+ printk(KERN_ERR "mrstisp: no support jpg review fmt\n");
-+ }
-+
-+ /* buffer address */
-+ if (isp_sf_mi_path_conf.ybuffer.size != 0) {
-+ isp_sf_mi_path_conf.ybuffer.pucbuffer =
-+ (u8 *)(unsigned long)
-+ isp->mb1 + isp->mb1_size - 640*480*2;
-+ }
-+
-+ if (isp_sf_mi_path_conf.cb_buffer.size != 0) {
-+ isp_sf_mi_path_conf.cb_buffer.pucbuffer =
-+ isp_sf_mi_path_conf.ybuffer.pucbuffer +
-+ isp_sf_mi_path_conf.ybuffer.size;
-+ }
-+
-+ if (isp_sf_mi_path_conf.cr_buffer.size != 0) {
-+ isp_sf_mi_path_conf.cr_buffer.pucbuffer =
-+ isp_sf_mi_path_conf.cb_buffer.pucbuffer +
-+ isp_sf_mi_path_conf.cb_buffer.size;
-+ }
-+
-+ if (jpg_review->pix_fmt == V4L2_PIX_FMT_YVU420) {
-+ isp_sf_mi_path_conf.cr_buffer.pucbuffer =
-+ isp_sf_mi_path_conf.ybuffer.pucbuffer +
-+ isp_sf_mi_path_conf.ybuffer.size;
-+ isp_sf_mi_path_conf.cb_buffer.pucbuffer =
-+ isp_sf_mi_path_conf.cr_buffer.pucbuffer +
-+ isp_sf_mi_path_conf.cr_buffer.size;
-+ }
-+
-+ }
-+
-+ if (isp->pixelformat == V4L2_PIX_FMT_YUV420 ||
-+ isp->pixelformat == V4L2_PIX_FMT_YVU420 ||
-+ isp->pixelformat == V4L2_PIX_FMT_YUV422P ||
-+ isp->pixelformat == V4L2_PIX_FMT_NV12) {
-+ bufsize = w*h;
-+ } else
-+ bufsize = isp->frame_size;
-+
-+ /* buffer size in bytes */
-+ if (isp->pixelformat == V4L2_PIX_FMT_YUV420
-+ || isp->pixelformat == V4L2_PIX_FMT_YVU420) {
-+
-+ dprintk(3, "yuv420 fmt");
-+ isp_mi_path_conf.ybuffer.size = bufsize;
-+ isp_mi_path_conf.cb_buffer.size = bufsize/4;
-+ isp_mi_path_conf.cr_buffer.size = bufsize/4;
-+ } else if (isp->pixelformat == V4L2_PIX_FMT_YUV422P) {
-+
-+ dprintk(3, "yuv422 fmt");
-+ isp_mi_path_conf.ybuffer.size = bufsize;
-+ isp_mi_path_conf.cb_buffer.size = bufsize/2;
-+ isp_mi_path_conf.cr_buffer.size = bufsize/2;
-+ } else if (isp->pixelformat == V4L2_PIX_FMT_NV12) {
-+
-+ dprintk(3, "nv12 fmt");
-+ isp_mi_path_conf.ybuffer.size = bufsize;
-+ isp_mi_path_conf.cb_buffer.size = bufsize/2;
-+ isp_mi_path_conf.cr_buffer.size = 0;
-+ } else {
-+
-+ dprintk(3, "jpeg and rgb fmt");
-+ isp_mi_path_conf.ybuffer.size = bufsize;
-+ isp_mi_path_conf.cb_buffer.size = 0;
-+ isp_mi_path_conf.cr_buffer.size = 0;
-+ }
-+
-+ /* buffer address */
-+ if (isp_mi_path_conf.ybuffer.size != 0) {
-+ isp_mi_path_conf.ybuffer.pucbuffer =
-+ (u8 *)(unsigned long) buffer_base;
-+ }
-+
-+ if (isp_mi_path_conf.cb_buffer.size != 0) {
-+ isp_mi_path_conf.cb_buffer.pucbuffer =
-+ isp_mi_path_conf.ybuffer.pucbuffer +
-+ isp_mi_path_conf.ybuffer.size;
-+ }
-+
-+ if (isp_mi_path_conf.cr_buffer.size != 0) {
-+ isp_mi_path_conf.cr_buffer.pucbuffer =
-+ isp_mi_path_conf.cb_buffer.pucbuffer +
-+ isp_mi_path_conf.cb_buffer.size;
-+ }
-+
-+ if (isp->pixelformat == V4L2_PIX_FMT_YVU420) {
-+ isp_mi_path_conf.cr_buffer.pucbuffer =
-+ isp_mi_path_conf.ybuffer.pucbuffer +
-+ isp_mi_path_conf.ybuffer.size;
-+ isp_mi_path_conf.cb_buffer.pucbuffer =
-+ isp_mi_path_conf.cr_buffer.pucbuffer +
-+ isp_mi_path_conf.cr_buffer.size;
-+ }
-+
-+ if (isp->sys_conf.isp_cfg.view_finder.flags & VFFLAG_USE_MAINPATH) {
-+ ci_isp_mif_set_main_buffer(&isp_mi_path_conf, update_time);
-+ if (isp->pixelformat == V4L2_PIX_FMT_JPEG)
-+ if (isp->sys_conf.jpg_review_enable)
-+ ci_isp_mif_set_self_buffer(
-+ &isp_sf_mi_path_conf, update_time);
-+ } else {
-+ ci_isp_mif_set_self_buffer(&isp_mi_path_conf, update_time);
-+ }
-+}
-+
-+static int mrst_isp_setup_viewfinder_path(struct mrst_isp_device *isp,
-+ struct ci_sensor_config *isi_config,
-+ int zoom)
-+{
-+ int error = CI_STATUS_SUCCESS;
-+ struct ci_isp_datapath_desc dp_main;
-+ struct ci_isp_datapath_desc dp_self;
-+ struct ci_isp_rect self_rect;
-+ u16 isi_hsize;
-+ u16 isi_vsize;
-+ int jpe_scale;
-+ struct ci_pl_system_config *sys_conf = &isp->sys_conf;
-+ struct ci_isp_config *config = &sys_conf->isp_cfg;
-+ struct v4l2_jpg_review_buffer *jpg_review = &sys_conf->jpg_review;
-+ u32 dp_mode;
-+
-+ DBG_entering;
-+
-+ if (sys_conf->isp_cfg.flags.ycbcr_full_range)
-+ jpe_scale = false;
-+ else
-+ jpe_scale = true;
-+
-+ memset(&dp_main, 0, sizeof(struct ci_isp_datapath_desc));
-+ memset(&dp_self, 0, sizeof(struct ci_isp_datapath_desc));
-+
-+ self_rect.x = 0;
-+ self_rect.y = 0;
-+ self_rect.w = isp->bufwidth; /* 640 */
-+ self_rect.h = isp->bufheight; /* 480 */
-+
-+ if (isp->pixelformat == V4L2_PIX_FMT_JPEG) {
-+
-+ dprintk(1, "jpeg fmt");
-+
-+ dp_main.flags = CI_ISP_DPD_ENABLE | CI_ISP_DPD_MODE_ISPJPEG;
-+ config->view_finder.flags |= VFFLAG_USE_MAINPATH;
-+
-+ dp_main.out_w = (u16) isp->bufwidth;
-+ dp_main.out_h = (u16) isp->bufheight;
-+
-+ if (isp->sys_conf.jpg_review_enable) {
-+
-+ dprintk(1, "jpg_review enabled in VF");
-+
-+ self_rect.w = jpg_review->width;
-+ self_rect.h = jpg_review->height;
-+
-+ dp_self.flags = (CI_ISP_DPD_ENABLE
-+ | CI_ISP_DPD_MODE_ISPYC);
-+ if (jpg_review->pix_fmt == V4L2_PIX_FMT_YUV420 ||
-+ jpg_review->pix_fmt == V4L2_PIX_FMT_YVU420)
-+ dp_self.flags |= CI_ISP_DPD_YUV_420
-+ | CI_ISP_DPD_CSS_V2;
-+ else if (jpg_review->pix_fmt == V4L2_PIX_FMT_YUV422P)
-+ dp_self.flags |= CI_ISP_DPD_YUV_422;
-+ else if (jpg_review->pix_fmt == V4L2_PIX_FMT_NV12)
-+ dp_self.flags |= CI_ISP_DPD_YUV_NV12
-+ | CI_ISP_DPD_CSS_V2;
-+ else if (jpg_review->pix_fmt == V4L2_PIX_FMT_YUYV)
-+ dp_self.flags |= CI_ISP_DPD_YUV_YUYV;
-+
-+ dprintk(1, "dp_self.flags is 0x%x", dp_self.flags);
-+ }
-+
-+ } else if (isp->pixelformat == INTEL_PIX_FMT_RAW08) {
-+
-+ dp_main.flags = CI_ISP_DPD_ENABLE | CI_ISP_DPD_MODE_ISPRAW;
-+ config->view_finder.flags |= VFFLAG_USE_MAINPATH;
-+
-+ /*just take the output of the sensor without any resizing*/
-+ dp_main.flags |= CI_ISP_DPD_NORESIZE;
-+ (void)ci_sensor_res2size(isi_config->res,
-+ &(dp_main.out_w), &(dp_main.out_h));
-+
-+ dprintk(1, "RAW08 dp_main.flags is 0x%x", dp_main.flags);
-+
-+ } else if (isp->pixelformat == INTEL_PIX_FMT_RAW10
-+ || isp->pixelformat == INTEL_PIX_FMT_RAW12) {
-+
-+ dp_main.flags = (CI_ISP_DPD_ENABLE
-+ | CI_ISP_DPD_MODE_ISPRAW_16B);
-+ config->view_finder.flags |= VFFLAG_USE_MAINPATH;
-+
-+ /*just take the output of the sensor without any resizing*/
-+ dp_main.flags |= CI_ISP_DPD_NORESIZE;
-+ (void)ci_sensor_res2size(isi_config->res,
-+ &(dp_main.out_w), &(dp_main.out_h));
-+
-+ dprintk(1, "RAW10 dp_main.flags is 0x%x", dp_main.flags);
-+
-+ } /*else if (isp->bufwidth >= 640 && isp->bufheight >= 480) {*/
-+ else if (isp->bufwidth >= 32 && isp->bufheight >= 16) {
-+
-+ dp_main.flags = (CI_ISP_DPD_ENABLE | CI_ISP_DPD_MODE_ISPYC);
-+ dp_main.out_w = (u16) isp->bufwidth;
-+ dp_main.out_h = (u16) isp->bufheight;
-+ config->view_finder.flags |= VFFLAG_USE_MAINPATH;
-+
-+ if (isp->pixelformat == V4L2_PIX_FMT_YUV420 ||
-+ isp->pixelformat == V4L2_PIX_FMT_YVU420)
-+ dp_main.flags |= CI_ISP_DPD_YUV_420 | CI_ISP_DPD_CSS_V2;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_YUV422P)
-+ dp_main.flags |= CI_ISP_DPD_YUV_422;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_NV12) {
-+ /* to use crop set crop_flag first */
-+ dp_main.flags |= CI_ISP_DPD_YUV_NV12;
-+ if (!crop_flag)
-+ dp_main.flags |= CI_ISP_DPD_CSS_V2;
-+ } else if (isp->pixelformat == V4L2_PIX_FMT_YUYV)
-+ dp_main.flags |= CI_ISP_DPD_YUV_YUYV;
-+
-+ dprintk(1, "YUV dp_main.flags is 0x%x", dp_main.flags);
-+
-+ } /* else if (isp->bufwidth <= 640 && isp->bufheight <= 480) {
-+
-+ dp_self.flags = (CI_ISP_DPD_ENABLE | CI_ISP_DPD_MODE_ISPYC);
-+
-+ if (isp->pixelformat == V4L2_PIX_FMT_YUV420 ||
-+ isp->pixelformat == V4L2_PIX_FMT_YVU420)
-+ dp_self.flags |= CI_ISP_DPD_YUV_420 | CI_ISP_DPD_CSS_V2;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_YUV422P)
-+ dp_self.flags |= CI_ISP_DPD_YUV_422;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_NV12)
-+ dp_self.flags |= CI_ISP_DPD_YUV_NV12
-+ | CI_ISP_DPD_CSS_V2;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_YUYV)
-+ dp_self.flags |= CI_ISP_DPD_YUV_YUYV;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_RGB565)
-+ dp_self.flags |= CI_ISP_DPD_HWRGB_565;
-+ else if (isp->pixelformat == V4L2_PIX_FMT_BGR32)
-+ dp_self.flags |= CI_ISP_DPD_HWRGB_888;
-+
-+ dprintk(1, "YUV dp_self.flags is 0x%x", dp_self.flags);
-+ }
-+ */
-+
-+ dprintk(1, "sensor_res = %x", isi_config->res);
-+
-+ (void)ci_sensor_res2size(isi_config->res, &isi_hsize, &isi_vsize);
-+ dprintk(1, "self path: w:%d, h:%d; sensor: w:%d, h:%d",
-+ self_rect.w, self_rect.h, isi_hsize, isi_vsize);
-+ dprintk(1, "main path: out_w:%d, out_h:%d ",
-+ dp_main.out_w, dp_main.out_h);
-+
-+ /* no stretching/squeezing */
-+ if (dp_self.flags && CI_ISP_DPD_ENABLE)
-+ dp_self.flags |= CI_ISP_DPD_KEEPRATIO;
-+ else
-+ dp_main.flags |= CI_ISP_DPD_KEEPRATIO;
-+
-+ /* prepare datapath, 640x480, can changed to the bufsize */
-+ dp_self.out_w = (u16) self_rect.w;
-+ dp_self.out_h = (u16) self_rect.h;
-+
-+ if (sys_conf->isp_cfg.view_finder.flags & VFFLAG_HWRGB) {
-+ /* YCbCr to RGB conversion in hardware */
-+ if (isp->pixelformat == V4L2_PIX_FMT_RGB565)
-+ dp_self.flags |= CI_ISP_DPD_HWRGB_565;
-+ if (isp->pixelformat == V4L2_PIX_FMT_BGR32)
-+ dp_self.flags |= CI_ISP_DPD_HWRGB_888;
-+ }
-+
-+ if (sys_conf->isp_cfg.view_finder.flags & VFFLAG_MIRROR)
-+ dp_self.flags |= CI_ISP_DPD_H_FLIP;
-+
-+
-+ if (sys_conf->isp_cfg.view_finder.flags & VFFLAG_V_FLIP)
-+ dp_self.flags |= CI_ISP_DPD_V_FLIP;
-+
-+
-+ if (sys_conf->isp_cfg.view_finder.flags & VFFLAG_ROT90_CCW)
-+ dp_self.flags |= CI_ISP_DPD_90DEG_CCW;
-+
-+ /* setup self & main path with zoom */
-+ if (zoom < 0)
-+ zoom = sys_conf->isp_cfg.view_finder.zoom;
-+
-+ if (sys_conf->isp_cfg.view_finder.flags & VFFLAG_USE_MAINPATH) {
-+ /* For RAW snapshots, we have to bypass the ISP too */
-+ dp_mode = dp_main.flags & CI_ISP_DPD_MODE_MASK;
-+ if ((dp_mode == CI_ISP_DPD_MODE_ISPRAW) ||
-+ (dp_mode == CI_ISP_DPD_MODE_ISPRAW_16B)) {
-+ struct ci_sensor_config isi_conf;
-+ /* isi_conf = *sys_conf->isi_config; */
-+ isi_conf = *isi_config;
-+ isi_conf.mode = SENSOR_MODE_PICT;
-+ error = ci_isp_set_input_aquisition(&isi_conf);
-+ if (error != CI_STATUS_SUCCESS)
-+ eprintk("33");
-+ }
-+ }
-+ /* to use crop mode, set crop_flag */
-+ if (crop_flag)
-+ dp_main.flags |= CI_ISP_DPD_NORESIZE;
-+
-+ error = ci_datapath_isp(sys_conf, isi_config, &dp_main, &dp_self, zoom);
-+ if (error != CI_STATUS_SUCCESS) {
-+ printk(KERN_ERR "mrstisp: failed to setup marvins datapath\n");
-+ return error;
-+ }
-+
-+ DBG_leaving;
-+ return error;
-+}
-+
-+static int mrst_isp_init_mrv_image_effects(struct ci_pl_system_config *sys_conf,
-+ int enable)
-+{
-+ int res;
-+
-+ DBG_entering;
-+
-+ if (enable && sys_conf->isp_cfg.img_eff_cfg.mode
-+ != CI_ISP_IE_MODE_OFF) {
-+ res = ci_isp_ie_set_config(&(sys_conf->isp_cfg.img_eff_cfg));
-+ if (res != CI_STATUS_SUCCESS)
-+ printk(KERN_ERR "mrstisp: error setting ie config\n");
-+ } else {
-+ (void)ci_isp_ie_set_config(NULL);
-+ res = CI_STATUS_SUCCESS;
-+ }
-+
-+ DBG_leaving;
-+ return res;
-+}
-+
-+static int mrst_isp_init_mrvisp_lensshade(struct ci_pl_system_config *sys_conf,
-+ int enable)
-+{
-+ if (enable) {
-+ ci_isp_set_ls_correction(&sys_conf->isp_cfg.lsc_cfg);
-+ ci_isp_ls_correction_on_off(1);
-+ } else {
-+ ci_isp_ls_correction_on_off(0);
-+ }
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+static int mrst_isp_init_mrvisp_badpixel(const struct ci_pl_system_config
-+ *sys_conf, int enable)
-+{
-+ if ((enable) && (sys_conf->isp_cfg.flags.bpc)) {
-+ (void)ci_bp_init(&sys_conf->isp_cfg.bpc_cfg,
-+ &sys_conf->isp_cfg.bpd_cfg);
-+ } else {
-+ (void)ci_bp_end(&sys_conf->isp_cfg.bpc_cfg);
-+ (void)ci_isp_set_bp_correction(NULL);
-+ (void)ci_isp_set_bp_detection(NULL);
-+ }
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+static int mrst_isp_init_mrv_ispfilter(const struct ci_pl_system_config
-+ *sys_conf, int enable)
-+{
-+ int res;
-+
-+ DBG_entering;
-+
-+ if ((enable) && (sys_conf->isp_cfg.flags.isp_filters)) {
-+ ci_isp_activate_filter(true);
-+ res = ci_isp_set_filter_params(sys_conf->isp_cfg.
-+ filter_level_noise_reduc,
-+ sys_conf->isp_cfg.
-+ filter_level_sharp);
-+ if (res != CI_STATUS_SUCCESS)
-+ printk(KERN_ERR "mrstisp: error set filter param\n");
-+ } else {
-+ ci_isp_activate_filter(false);
-+ res = CI_STATUS_SUCCESS;
-+ }
-+
-+ DBG_leaving;
-+ return res;
-+}
-+
-+static int mrst_isp_init_mrvisp_cac(const struct ci_pl_system_config *sys_conf,
-+ int enable)
-+{
-+ return 0;
-+}
-+
-+static int mrst_isp_initbls(const struct ci_pl_system_config *sys_conf)
-+{
-+ struct ci_isp_bls_config *bls_config =
-+ (struct ci_isp_bls_config *)&sys_conf->isp_cfg.bls_cfg;
-+ return ci_isp_bls_set_config(bls_config);
-+}
-+
-+static int mrst_isp_dp_init(struct ci_pl_system_config *sys_conf,
-+ struct ci_sensor_config *isi_config)
-+{
-+ int error;
-+ u8 words_per_pixel;
-+
-+ DBG_entering;
-+
-+ /* base initialisation of Marvin */
-+ ci_isp_init();
-+
-+ /* setup input acquisition according to image sensor settings */
-+ print_snr_cfg(isi_config);
-+ error = ci_isp_set_input_aquisition(isi_config);
-+ if (error) {
-+ printk(KERN_ERR "mrstisp: error setting input acquisition\n");
-+ return error;
-+ }
-+
-+ /* setup functional blocks for Bayer pattern processing */
-+ if (ci_isp_select_path(isi_config, &words_per_pixel)
-+ == CI_ISP_PATH_BAYER) {
-+
-+ /* black level */
-+ if (sys_conf->isp_cfg.flags.bls) {
-+ error = mrst_isp_initbls(sys_conf);
-+ if (error != CI_STATUS_SUCCESS) {
-+ printk(KERN_ERR "mrstisp: error set bls\n");
-+ return error;
-+ }
-+ } else {
-+ ci_isp_bls_set_config(NULL);
-+ }
-+
-+ /* gamma */
-+ if (sys_conf->isp_cfg.flags.gamma2) {
-+ dprintk(1, "setting gamma 2 ");
-+ ci_isp_set_gamma2(&g45_th20_b5);
-+ } else {
-+ dprintk(1, "no setting gamma 2 ");
-+ ci_isp_set_gamma2(NULL);
-+ }
-+
-+ /* demosaic */
-+ ci_isp_set_demosaic(sys_conf->isp_cfg.demosaic_mode,
-+ sys_conf->isp_cfg.demosaic_th);
-+
-+ /* color convertion */
-+ if (sys_conf->isp_cfg.flags.cconv) {
-+ if (!sys_conf->isp_cfg.flags.cconv_basic) {
-+ mrst_isp_set_color_conversion_ex();
-+ /* set color converstion skipped by xiaolin,
-+ * to be done in libci */
-+ if (error != CI_STATUS_SUCCESS) {
-+ printk(KERN_ERR "mrstisp: error set"
-+ " color conversion\n");
-+ return error;
-+ }
-+ }
-+ }
-+
-+ /* af setting */
-+ if (sys_conf->isp_cfg.flags.af)
-+ ci_isp_set_auto_focus(&sys_conf->isp_cfg.af_cfg);
-+ else
-+ ci_isp_set_auto_focus(NULL);
-+
-+ /* filter */
-+ mrst_isp_init_mrv_ispfilter(sys_conf, true);
-+
-+ /* cac */
-+ mrst_isp_init_mrvisp_cac(sys_conf, true);
-+ }
-+
-+ /*
-+ * disable color processing for now (will be set under user control
-+ * in the main loop)
-+ */
-+ ci_isp_col_set_color_processing(NULL);
-+
-+ /* configure image effects */
-+ mrst_isp_init_mrv_image_effects(sys_conf, true);
-+
-+ /* configure lens shading correction */
-+ if (strcmp(isi_config->name, "s5k4e1") == 0
-+ && (isi_config->res == SENSOR_RES_720P
-+ || isi_config->res == SENSOR_RES_QXGA_PLUS)) {
-+ dprintk(1, "enabling lsc for kmot 720p and qsxga\n");
-+ mrst_isp_init_mrvisp_lensshade(sys_conf, true);
-+ } else
-+ mrst_isp_init_mrvisp_lensshade(sys_conf,
-+ sys_conf->isp_cfg.flags.lsc);
-+
-+ /* configure bad pixel detection/correction */
-+ mrst_isp_init_mrvisp_badpixel(sys_conf, true);
-+
-+ DBG_leaving;
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+int ci_jpe_encode(struct mrst_isp_device *intel,
-+ enum ci_isp_conf_update_time update_time,
-+ enum ci_isp_jpe_enc_mode mrv_jpe_encMode)
-+{
-+ u32 mipi_data_id = 1;
-+ struct isp_register *mrv_reg =
-+ (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ ci_isp_jpe_prep_enc(mrv_jpe_encMode);
-+
-+ if (to_sensor_config(intel->sensor_curr)->mipi_mode) {
-+ ci_isp_start(1, update_time);
-+ v4l2_subdev_call(intel->sensor_curr, video, s_stream, 1);
-+ if (mipi_flag)
-+ while (mipi_data_id)
-+ mipi_data_id =
-+ REG_READ_EX(mrv_reg->mipi_cur_data_id);
-+ mipi_flag = 0;
-+
-+ } else
-+ ci_isp_start(1, update_time);
-+
-+ return ci_isp_jpe_wait_for_encode_done(intel);
-+}
-+
-+/* capture one frame */
-+u32 ci_jpe_capture(struct mrst_isp_device *isp,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ int retval = CI_STATUS_SUCCESS;
-+
-+ /* generate header */
-+ retval = ci_isp_jpe_generate_header(isp, MRV_JPE_HEADER_MODE_JFIF);
-+ if (retval != CI_STATUS_SUCCESS)
-+ return 0;
-+
-+ /* now encode JPEG */
-+ retval = ci_jpe_encode(isp, update_time, CI_ISP_JPE_SINGLE_SHOT);
-+ if (retval != CI_STATUS_SUCCESS)
-+ return 0;
-+
-+ /* return ci_isp_mif_get_byte_cnt(); */
-+ return 0;
-+}
-+
-+static int mrst_ci_capture(struct mrst_isp_device *isp)
-+{
-+ u32 bufbase;
-+ u32 mipi_data_id = 1;
-+ struct videobuf_buffer *vb;
-+ struct isp_register *mrv_reg =
-+ (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ bufbase = videobuf_to_dma_contig(isp->active);
-+ mrst_isp_update_marvinvfaddr(isp, bufbase, CI_ISP_CFG_UPDATE_IMMEDIATE);
-+ ci_isp_mif_reset_offsets(CI_ISP_CFG_UPDATE_IMMEDIATE);
-+
-+ ci_isp_reset_interrupt_status();
-+ mrst_isp_enable_interrupt(isp);
-+
-+ if (isp->pixelformat == V4L2_PIX_FMT_JPEG) {
-+ mrst_isp_disable_interrupt(isp);
-+ ci_isp_jpe_init_ex(isp->bufwidth, isp->bufheight,
-+ isp->sys_conf.isp_cfg.jpeg_enc_ratio,
-+ true);
-+ ci_jpe_capture(isp, CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+
-+ vb = isp->active;
-+ vb->size = ci_isp_mif_get_byte_cnt();
-+ vb->state = VIDEOBUF_DONE;
-+ do_gettimeofday(&vb->ts);
-+ vb->field_count++;
-+ wake_up(&vb->done);
-+ isp->active = NULL;
-+
-+ dprintk(2, "countcount = %lx", vb->size);
-+ } else if (isp->pixelformat == INTEL_PIX_FMT_RAW08
-+ || isp->pixelformat == INTEL_PIX_FMT_RAW10
-+ || isp->pixelformat == INTEL_PIX_FMT_RAW12) {
-+ mrst_isp_disable_interrupt(isp);
-+ ci_isp_start(1, CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+ ci_isp_wait_for_frame_end(isp);
-+
-+ /* update captured frame status */
-+ vb = isp->active;
-+ /* vb->size = ci_isp_mif_get_byte_cnt(); */
-+ vb->state = VIDEOBUF_DONE;
-+ do_gettimeofday(&vb->ts);
-+ vb->field_count++;
-+ wake_up(&vb->done);
-+ isp->active = NULL;
-+ /* ci_isp_reg_dump_all(); */
-+ dprintk(3, "captured index = %d", vb->i);
-+ } else if (to_sensor_config(isp->sensor_curr)->mipi_mode) {
-+ ci_isp_start(0, CI_ISP_CFG_UPDATE_IMMEDIATE);
-+
-+ if (mipi_flag) {
-+ v4l2_subdev_call(isp->sensor_curr, video, s_stream, 1);
-+
-+ while (mipi_data_id) {
-+ mipi_data_id =
-+ REG_READ_EX(mrv_reg->mipi_cur_data_id);
-+ dprintk(5, "mipi_cur_data_id = %x",
-+ mipi_data_id);
-+ }
-+ mipi_flag = 0;
-+ }
-+ } else
-+ ci_isp_start(0, CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+
-+ return 0;
-+}
-+
-+static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
-+ unsigned int *size)
-+{
-+ struct mrst_isp_fh *fh = vq->priv_data;
-+ struct mrst_isp_device *isp = fh->dev;
-+
-+ u32 w = isp->bufwidth;
-+ u32 h = isp->bufheight;
-+ u32 depth = isp->depth;
-+ u32 fourcc = isp->pixelformat;
-+
-+ if (fourcc == V4L2_PIX_FMT_JPEG) {
-+ *size = PAGE_ALIGN((isp->mb1_size
-+ - 640*480*2)/(*count)) - PAGE_SIZE;
-+ /* *size = PAGE_ALIGN(2 * 1024 * 1024); */
-+ } else if (fourcc == INTEL_PIX_FMT_RAW08
-+ || fourcc == INTEL_PIX_FMT_RAW10
-+ || fourcc == INTEL_PIX_FMT_RAW12) {
-+ *size = (w * h * depth)/8;
-+ } else {
-+ *size = (w * h * depth)/8;
-+ }
-+
-+ isp->frame_size = *size;
-+ isp->num_frames = *count;
-+
-+ if (0 == *count)
-+ *count = 3;
-+
-+ while (*size * *count > isp->mb1_size)
-+ (*count)--;
-+
-+ dprintk(1, "count=%d, size=%d", *count, *size);
-+ return 0;
-+}
-+
-+static void free_buffer(struct videobuf_queue *vq, struct mrst_isp_buffer *buf)
-+{
-+ struct videobuf_buffer *vb = &buf->vb;
-+
-+ dprintk(1, "(vb=0x%p) baddr = 0x%08lx bsize = %d", vb,
-+ vb->baddr, vb->bsize);
-+
-+ videobuf_dma_contig_free(vq, vb);
-+
-+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
-+ dprintk(1, "free_buffer: freed");
-+}
-+
-+static int buffer_prepare(struct videobuf_queue *vq,
-+ struct videobuf_buffer *vb, enum v4l2_field field)
-+{
-+ struct mrst_isp_fh *fh = vq->priv_data;
-+ struct mrst_isp_device *isp = fh->dev;
-+ struct mrst_isp_buffer *buf = container_of(vb, struct mrst_isp_buffer,
-+ vb);
-+ int ret;
-+
-+ if (vb->width != isp->bufwidth || vb->height != isp->bufheight
-+ || vb->field != field) {
-+ /* buf->fmt = isp->pixelformat; */
-+ vb->width = isp->bufwidth;
-+ vb->height = isp->bufheight;
-+ vb->field = field;
-+ vb->state = VIDEOBUF_NEEDS_INIT;
-+ }
-+
-+ vb->size = isp->frame_size;
-+
-+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-+ ret = videobuf_iolock(vq, vb, NULL);
-+ if (ret)
-+ goto fail;
-+ vb->state = VIDEOBUF_PREPARED;
-+ }
-+
-+ return 0;
-+
-+fail:
-+ printk(KERN_ERR "mrstisp: error calling videobuf_iolock");
-+ free_buffer(vq, buf);
-+ return ret;
-+}
-+
-+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-+{
-+ struct mrst_isp_fh *fh = vq->priv_data;
-+ struct mrst_isp_device *isp = fh->dev;
-+ u32 bufbase;
-+
-+ vb->state = VIDEOBUF_QUEUED;
-+ dprintk(1, "buffer %d in buffer querue", vb->i);
-+ if (isp->stopflag) {
-+ list_add_tail(&vb->queue, &isp->capture);
-+ if (isp->active) {
-+ /* dprintk(1, "AAAAAAAAAA in flag condition"); */
-+ /* isp->active->state = VIDEOBUF_ACTIVE; */
-+ /* mrst_isp_to_do_mblk_line = 1; */
-+ bufbase = videobuf_to_dma_contig(vb);
-+ mrst_isp_update_marvinvfaddr(isp, bufbase, 0);
-+ /* mrst_isp_enable_interrupt(isp); */
-+ } else {
-+ isp->active = vb;
-+ mrst_isp_enable_interrupt(isp);
-+ /*
-+ dprintk(1, "xxxxxxxxx in flag condition");
-+ isp->active->state = VIDEOBUF_ACTIVE;
-+ mrst_isp_to_do_mblk_line = 1;
-+ bufbase = videobuf_to_dma_contig(isp->active);
-+ mrst_isp_update_marvinvfaddr(isp, bufbase,
-+ CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+ */
-+ }
-+ isp->stopflag = 0;
-+ } else if (!isp->active) {
-+ dprintk(1, "no active queue");
-+ isp->active = vb;
-+ isp->active->state = VIDEOBUF_ACTIVE;
-+ mrst_isp_to_do_mblk_line = 1;
-+ mrst_ci_capture(isp);
-+ } else {
-+ dprintk(1, "capture to active queue");
-+ list_add_tail(&vb->queue, &isp->capture);
-+ }
-+
-+ return;
-+}
-+
-+static void buffer_release(struct videobuf_queue *vq,
-+ struct videobuf_buffer *vb)
-+{
-+ struct mrst_isp_buffer *buf = container_of(vb,
-+ struct mrst_isp_buffer, vb);
-+ DBG_entering;
-+ free_buffer(vq, buf);
-+ DBG_leaving;
-+}
-+
-+static struct videobuf_queue_ops mrst_isp_videobuf_qops = {
-+ .buf_setup = buffer_setup,
-+ .buf_prepare = buffer_prepare,
-+ .buf_queue = buffer_queue,
-+ .buf_release = buffer_release,
-+};
-+
-+static int mrst_isp_open(struct file *file)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(vdev);
-+ struct mrst_isp_fh *fh = NULL;
-+ struct v4l2_format sensor_format;
-+ int ret;
-+
-+ DBG_entering;
-+
-+ if (!isp) {
-+ printk(KERN_ERR "null in mrst_isp_open\n");
-+ return -ENODEV;
-+ }
-+
-+ dprintk(2, "open = %d", isp->open);
-+ mutex_lock(&isp->mutex);
-+ if (isp->open == 0) {
-+ if (isp->sensor_soc) {
-+ dprintk(0, "cur senfor soc");
-+ isp->sensor_curr = isp->sensor_soc;
-+ } else {
-+ dprintk(0, "cur sensor raw");
-+ isp->sensor_curr = isp->sensor_raw;
-+ }
-+ }
-+ ++isp->open;
-+
-+ ret = v4l2_subdev_call(isp->sensor_curr, video, g_fmt,
-+ &sensor_format);
-+ if (ret) {
-+ printk(KERN_ERR "can't get current pix from sensor!\n");
-+ ret = -EINVAL;
-+ goto exit_unlock;
-+ }
-+
-+ dprintk(1, "current sensor format: %d x %d",
-+ sensor_format.fmt.pix.width,
-+ sensor_format.fmt.pix.height);
-+
-+ fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-+ if (NULL == fh) {
-+ printk(KERN_ERR "no mem for fh \n");
-+ ret = -ENOMEM;
-+ goto exit_unlock;
-+ }
-+
-+ file->private_data = fh;
-+ fh->dev = isp;
-+
-+ videobuf_queue_dma_contig_init(&fh->vb_q, &mrst_isp_videobuf_qops,
-+ vdev->parent, &isp->lock,
-+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
-+ V4L2_FIELD_NONE,
-+ sizeof(struct mrst_isp_buffer), fh);
-+
-+exit_unlock:
-+ mutex_unlock(&isp->mutex);
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_close(struct file *file)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ struct mrst_isp_fh *fh = file->private_data;
-+ unsigned long flags;
-+
-+ DBG_entering;
-+ mutex_lock(&isp->mutex);
-+ --isp->open;
-+ dprintk(2, "close = %d", isp->open);
-+ if (isp->open == 0) {
-+ if (isp->streaming == 1) {
-+ videobuf_streamoff(&fh->vb_q);
-+ isp->streaming = 0;
-+ isp->buffer_required = 0;
-+ isp->stopflag = 0;
-+
-+ spin_lock_irqsave(&isp->lock, flags);
-+ INIT_LIST_HEAD(&isp->capture);
-+ isp->active = NULL;
-+ isp->next = NULL;
-+ isp->sys_conf.isp_hal_enable = 0;
-+ isp->sys_conf.jpg_review_enable = 0;
-+ spin_unlock_irqrestore(&isp->lock, flags);
-+
-+ ci_isp_stop(CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+ v4l2_subdev_call(isp->sensor_curr, video, s_stream, 0);
-+ isp->sensor_curr = NULL;
-+ }
-+ if (isp->sensor_soc)
-+ v4l2_subdev_call(isp->sensor_soc, core, s_gpio, 1);
-+ if (isp->sensor_raw)
-+ v4l2_subdev_call(isp->sensor_raw, core, s_gpio, 1);
-+ }
-+
-+ kfree(file->private_data);
-+
-+ mutex_unlock(&isp->mutex);
-+
-+ /*XXX zheng*/
-+ if (isp->open == 0)
-+ frame_cnt = 0;
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static ssize_t mrst_isp_read(struct file *file, char __user *buf,
-+ size_t count, loff_t *ppos)
-+{
-+ return 0;
-+}
-+
-+static void mrst_isp_videobuf_vm_open(struct vm_area_struct *vma)
-+{
-+ struct videobuf_mapping *map = vma->vm_private_data;
-+
-+ dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
-+ map, map->count, vma->vm_start, vma->vm_end);
-+
-+ map->count++;
-+}
-+
-+static void mrst_isp_videobuf_vm_close(struct vm_area_struct *vma)
-+{
-+ struct videobuf_mapping *map = vma->vm_private_data;
-+ struct videobuf_queue *q = map->q;
-+ int i;
-+
-+ dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
-+ map, map->count, vma->vm_start, vma->vm_end);
-+
-+ map->count--;
-+ if (0 == map->count) {
-+ struct videobuf_dma_contig_memory *mem;
-+
-+ dprintk(2, "munmap %p q=%p\n", map, q);
-+ mutex_lock(&q->vb_lock);
-+
-+ /* We need first to cancel streams, before unmapping */
-+ if (q->streaming)
-+ videobuf_queue_cancel(q);
-+
-+ for (i = 0; i < VIDEO_MAX_FRAME; i++) {
-+ if (NULL == q->bufs[i])
-+ continue;
-+
-+ if (q->bufs[i]->map != map)
-+ continue;
-+
-+ mem = q->bufs[i]->priv;
-+ if (mem) {
-+ /* This callback is called only if kernel has
-+ allocated memory and this memory is mmapped.
-+ In this case, memory should be freed,
-+ in order to do memory unmap.
-+ */
-+
-+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-+
-+ /* vfree is not atomic - can't be
-+ called with IRQ's disabled
-+ */
-+ dprintk(2, "buf[%d] freeing %p\n",
-+ i, mem->vaddr);
-+
-+ /*
-+ dma_free_coherent(q->dev, mem->size,
-+ mem->vaddr, mem->dma_handle);
-+ */
-+ mem->vaddr = NULL;
-+ }
-+
-+ q->bufs[i]->map = NULL;
-+ q->bufs[i]->baddr = 0;
-+ }
-+
-+ kfree(map);
-+
-+ mutex_unlock(&q->vb_lock);
-+ }
-+}
-+
-+static struct vm_operations_struct mrst_isp_videobuf_vm_ops = {
-+ .open = mrst_isp_videobuf_vm_open,
-+ .close = mrst_isp_videobuf_vm_close,
-+};
-+
-+static int mrst_isp_mmap_mapper(struct videobuf_queue *q,
-+ struct vm_area_struct *vma)
-+{
-+ struct videobuf_dma_contig_memory *mem;
-+ struct videobuf_mapping *map;
-+ unsigned int first;
-+ int retval;
-+ unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;
-+
-+ struct mrst_isp_fh *fh = q->priv_data;
-+ struct mrst_isp_device *isp = fh->dev;
-+
-+ DBG_entering;
-+
-+ if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
-+ return -EINVAL;
-+
-+ /* look for first buffer to map */
-+ for (first = 0; first < VIDEO_MAX_FRAME; first++) {
-+ if (!q->bufs[first])
-+ continue;
-+
-+ if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
-+ continue;
-+ if (q->bufs[first]->boff == offset) {
-+ dprintk(1, "buff id %d is mapped", first);
-+ break;
-+ }
-+ }
-+ if (VIDEO_MAX_FRAME == first) {
-+ eprintk("invalid user space offset [offset=0x%lx]", offset);
-+ return -EINVAL;
-+ }
-+
-+ /* create mapping + update buffer list */
-+ map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
-+ if (!map)
-+ return -ENOMEM;
-+
-+ q->bufs[first]->map = map;
-+ map->start = vma->vm_start;
-+ map->end = vma->vm_end;
-+ map->q = q;
-+
-+ q->bufs[first]->baddr = vma->vm_start;
-+
-+ mem = q->bufs[first]->priv;
-+ BUG_ON(!mem);
-+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-+
-+ mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
-+ mem->dma_handle = isp->mb1 + (mem->size * first);
-+ mem->vaddr = (void *)0x1;
-+ /*
-+ mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
-+ &mem->dma_handle, GFP_KERNEL);
-+ */
-+ if (mem->size > isp->mb1_size) {
-+ eprintk("to big size, can not be mmapped");
-+ return -EINVAL;
-+ }
-+
-+ /* Try to remap memory */
-+
-+ size = vma->vm_end - vma->vm_start;
-+ size = (size < mem->size) ? size : mem->size;
-+
-+ dprintk(1, "vm_end - vm_start = %ld, mem-size = %ld", size, mem->size);
-+
-+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+ retval = remap_pfn_range(vma, vma->vm_start,
-+ mem->dma_handle >> PAGE_SHIFT,
-+ size, vma->vm_page_prot);
-+ if (retval) {
-+ eprintk("mmap: remap failed with error %d. ", retval);
-+ goto error;
-+ }
-+
-+ vma->vm_ops = &mrst_isp_videobuf_vm_ops;
-+ vma->vm_flags |= VM_DONTEXPAND;
-+ vma->vm_private_data = map;
-+
-+ dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
-+ map, q, vma->vm_start, vma->vm_end,
-+ (long int) q->bufs[first]->bsize,
-+ vma->vm_pgoff, first);
-+
-+ mrst_isp_videobuf_vm_open(vma);
-+
-+ return 0;
-+
-+error:
-+ kfree(map);
-+ return -ENOMEM;
-+}
-+int mrst_isp_videobuf_mmap_mapper(struct videobuf_queue *q,
-+ struct vm_area_struct *vma)
-+{
-+ MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-+
-+ mutex_lock(&q->vb_lock);
-+ mrst_isp_mmap_mapper(q, vma);
-+ /* retval = CALL(q, mmap_mapper, q, vma); */
-+ q->is_mmapped = 1;
-+ mutex_unlock(&q->vb_lock);
-+
-+ return 0;
-+}
-+static int mrst_isp_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ int ret;
-+ int map_by_myself;
-+ struct mrst_isp_fh *fh;
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-+ unsigned long size = vma->vm_end-vma->vm_start;
-+ unsigned long page;
-+
-+ DBG_entering;
-+
-+ /* temporarily put here */
-+ if (isp->open > 1) {
-+ printk(KERN_ERR "ISP already opened...");
-+ return -EINVAL;
-+ }
-+
-+ fh = file->private_data;
-+
-+ if (!(vma->vm_flags & (VM_WRITE | VM_READ))
-+ || !(vma->vm_flags & VM_SHARED)) {
-+ printk(KERN_ERR "mrstisp: wrong vma flag");
-+ return -EINVAL;
-+ }
-+
-+ /* to check whether if it is ISP bar 0 map */
-+ if (offset == isp->mb0_size + isp->mb1_size) {
-+ dprintk(1, "---- map bar0 ----");
-+ page = isp->mb0;
-+ map_by_myself = 1;
-+ } else if (offset == 0 && size == isp->mb1_size) {
-+ dprintk(1, "---- map bar1 ----");
-+ page = isp->mb1;
-+ map_by_myself = 1;
-+ } else if (isp->pixelformat == V4L2_PIX_FMT_JPEG
-+ && isp->sys_conf.jpg_review_enable == 1
-+ && offset == isp->sys_conf.jpg_review.offset) {
-+ dprintk(1, "---- map jpeg review buffer----");
-+ page = isp->mb1 + isp->sys_conf.jpg_review.offset;
-+ map_by_myself = 1;
-+ } else {
-+ dprintk(1, "----map one certain buffer----");
-+ map_by_myself = 0;
-+ }
-+
-+ if (map_by_myself) {
-+ vma->vm_flags |= VM_IO;
-+ vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
-+
-+ page = page >> PAGE_SHIFT;
-+
-+ if (remap_pfn_range(vma, vma->vm_start, page, size,
-+ PAGE_SHARED)) {
-+ printk(KERN_ERR "fail to put MMAP buffer to user space\n");
-+ return -EAGAIN;
-+ }
-+
-+ return 0;
-+ }
-+
-+ if (size > isp->num_frames * PAGE_ALIGN(isp->frame_size)) {
-+ eprintk("length is larger than num * size");
-+ return -EINVAL;
-+ }
-+
-+ ret = mrst_isp_videobuf_mmap_mapper(&fh->vb_q, vma);
-+
-+ dprintk(1, "vma start=0x%08lx, size=%ld, offset=%ld ret=%d",
-+ (unsigned long)vma->vm_start,
-+ (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
-+ (unsigned long)offset, ret);
-+
-+ return ret;
-+}
-+
-+static int mrst_isp_g_fmt_cap(struct file *file, void *priv,
-+ struct v4l2_format *f)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ int ret;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-+ f->fmt.pix.width = isp->bufwidth;
-+ f->fmt.pix.height = isp->bufheight;
-+ f->fmt.pix.pixelformat = isp->pixelformat;
-+ f->fmt.pix.bytesperline = (f->fmt.pix.width * isp->depth) >> 3;
-+ f->fmt.pix.sizeimage = f->fmt.pix.height
-+ * f->fmt.pix.bytesperline;
-+ ret = 0;
-+ } else {
-+ ret = -EINVAL;
-+ }
-+
-+ dprintk(1, "get fmt %d x %d ", f->fmt.pix.width, f->fmt.pix.height);
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static struct intel_fmt *fmt_by_fourcc(unsigned int fourcc)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < NUM_FORMATS; i++)
-+ if (fmts[i].fourcc == fourcc)
-+ return fmts+i;
-+ return NULL;
-+}
-+
-+static int mrst_isp_try_fmt_cap(struct file *file, void *priv,
-+ struct v4l2_format *f)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ struct intel_fmt *fmt;
-+ int w, h;
-+ int ret;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ mutex_lock(&isp->mutex);
-+
-+ fmt = fmt_by_fourcc(f->fmt.pix.pixelformat);
-+ if (NULL == fmt && f->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG) {
-+ printk(KERN_ERR "mrstisp: fmt not found\n");
-+ ret = -EINVAL;
-+ goto exit_unlock;
-+ }
-+
-+ w = f->fmt.pix.width;
-+ h = f->fmt.pix.height;
-+
-+ dprintk(1, "sensor name %s: before w = %d, h = %d",
-+ isp->sensor_curr->name, w, h);
-+
-+ ret = v4l2_subdev_call(isp->sensor_curr, video, try_fmt, f);
-+ if (ret)
-+ goto exit_unlock;
-+
-+
-+ w = f->fmt.pix.width;
-+ h = f->fmt.pix.height;
-+
-+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 ||
-+ f->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) {
-+ if (w < INTEL_MIN_WIDTH)
-+ w = INTEL_MIN_WIDTH;
-+ if (w > INTEL_MAX_WIDTH)
-+ w = INTEL_MAX_WIDTH;
-+ if (h < INTEL_MIN_HEIGHT)
-+ h = INTEL_MIN_HEIGHT;
-+ if (h > INTEL_MAX_HEIGHT)
-+ h = INTEL_MAX_HEIGHT;
-+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
-+ } else {
-+ if (w < INTEL_MIN_WIDTH)
-+ w = INTEL_MIN_WIDTH;
-+ if (w > INTEL_MAX_WIDTH_MP)
-+ w = INTEL_MAX_WIDTH_MP;
-+ if (h < INTEL_MIN_HEIGHT)
-+ h = INTEL_MIN_HEIGHT;
-+ if (h > INTEL_MAX_HEIGHT_MP)
-+ h = INTEL_MAX_HEIGHT_MP;
-+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-+ }
-+
-+ f->fmt.pix.width = w;
-+ f->fmt.pix.height = h;
-+
-+ f->fmt.pix.field = V4L2_FIELD_NONE;
-+ f->fmt.pix.bytesperline = (w * h)/8;
-+ if (fmt)
-+ f->fmt.pix.sizeimage = (w * h * fmt->depth)/8;
-+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
-+ f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-+ f->fmt.pix.priv = 0;
-+
-+ dprintk(3, "after w = %d, h = %d", w, h);
-+ ret = 0;
-+
-+exit_unlock:
-+ mutex_unlock(&isp->mutex);
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_s_fmt_cap(struct file *file, void *priv,
-+ struct v4l2_format *f)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ struct intel_fmt *fmt;
-+ int ret;
-+ unsigned int width_o, height_o;
-+ unsigned short width_sensor, height_sensor;
-+ unsigned int w, h;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ mipi_flag = 1;
-+
-+ w = f->fmt.pix.width;
-+ h = f->fmt.pix.height;
-+
-+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 ||
-+ f->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) {
-+ if (w < INTEL_MIN_WIDTH)
-+ w = INTEL_MIN_WIDTH;
-+ if (w > INTEL_MAX_WIDTH)
-+ w = INTEL_MAX_WIDTH;
-+ if (h < INTEL_MIN_HEIGHT)
-+ h = INTEL_MIN_HEIGHT;
-+ if (h > INTEL_MAX_HEIGHT)
-+ h = INTEL_MAX_HEIGHT;
-+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
-+ } else {
-+ if (w < INTEL_MIN_WIDTH)
-+ w = INTEL_MIN_WIDTH;
-+ if (w > INTEL_MAX_WIDTH_MP)
-+ w = INTEL_MAX_WIDTH_MP;
-+ if (h < INTEL_MIN_HEIGHT)
-+ h = INTEL_MIN_HEIGHT;
-+ if (h > INTEL_MAX_HEIGHT_MP)
-+ h = INTEL_MAX_HEIGHT_MP;
-+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-+ }
-+
-+ f->fmt.pix.width = w;
-+ f->fmt.pix.height = h;
-+
-+ width_o = f->fmt.pix.width;
-+ height_o = f->fmt.pix.height;
-+
-+ (void)ci_sensor_res2size(to_sensor_config(isp->sensor_curr)->res,
-+ &width_sensor, &height_sensor);
-+
-+ ret = mrst_isp_try_fmt_cap(file, priv, f);
-+ if (0 != ret) {
-+ printk(KERN_ERR "mrstisp: set format failed\n");
-+ return ret;
-+ }
-+
-+ /* set fmt for only sensor */
-+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_MPEG) {
-+ ret = v4l2_subdev_call(isp->sensor_curr, video, s_fmt, f);
-+ dprintk(1, "------------set fmt only for sensor (%d x %d)",
-+ f->fmt.pix.width, f->fmt.pix.height);
-+ return ret;
-+ }
-+
-+ if (isp->sys_conf.isp_hal_enable) {
-+ /* set fmt for isp */
-+ mutex_lock(&isp->mutex);
-+ fmt = fmt_by_fourcc(f->fmt.pix.pixelformat);
-+
-+ isp->pixelformat = fmt->fourcc;
-+ isp->depth = fmt->depth;
-+
-+ dprintk(1, "sensor (%d x %d)", width_sensor, height_sensor);
-+ if (width_o < f->fmt.pix.width &&
-+ height_o < f->fmt.pix.height) {
-+ isp->bufwidth = width_o;
-+ isp->bufheight = height_o;
-+ } else if (width_sensor < f->fmt.pix.width &&
-+ height_sensor < f->fmt.pix.height) {
-+ isp->bufwidth = width_sensor;
-+ isp->bufheight = height_sensor;
-+ f->fmt.pix.width = width_sensor;
-+ f->fmt.pix.height = height_sensor;
-+ } else {
-+ isp->bufwidth = f->fmt.pix.width;
-+ isp->bufheight = f->fmt.pix.height;
-+ }
-+
-+ /* FIXME
-+ * check if buf res is larger than
-+ * sensor real res(1304x980)
-+ * if yes, down buf res to VGA
-+ */
-+ if (to_sensor_config(isp->sensor_curr)->res ==
-+ SENSOR_RES_VGA_PLUS)
-+ if (isp->bufwidth >= VGA_SIZE_H &&
-+ isp->bufheight >= VGA_SIZE_V) {
-+ isp->bufwidth = VGA_SIZE_H;
-+ isp->bufheight = VGA_SIZE_V;
-+ }
-+
-+ mutex_unlock(&isp->mutex);
-+
-+ dprintk(1, "----------set fmt only to isp: w %d, h%d, "
-+ "fourcc: %lx", isp->bufwidth,
-+ isp->bufheight, fmt->fourcc);
-+ } else {
-+
-+ /* set fmt for both isp and sensor */
-+ mutex_lock(&isp->mutex);
-+ fmt = fmt_by_fourcc(f->fmt.pix.pixelformat);
-+
-+ isp->pixelformat = fmt->fourcc;
-+ isp->depth = fmt->depth;
-+ isp->bufwidth = width_o;
-+ isp->bufheight = height_o;
-+
-+ mutex_unlock(&isp->mutex);
-+
-+ dprintk(1, "--------set fmt for isp : w%d, h%d, fourcc: %lx",
-+ isp->bufwidth, isp->bufheight, fmt->fourcc);
-+ dprintk(1, "--------set fmt for sesnro : w%d, h%d, fourcc: %lx",
-+ f->fmt.pix.width, f->fmt.pix.height, fmt->fourcc);
-+
-+ ret = v4l2_subdev_call(isp->sensor_curr, video, s_fmt, f);
-+ }
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_enum_framesizes(struct file *file, void *priv,
-+ struct v4l2_frmsizeenum *arg)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ int ret;
-+
-+ DBG_entering;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ ret = v4l2_subdev_call(isp->sensor_curr, video, enum_framesizes, arg);
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_enum_frameintervals(struct file *file, void *priv,
-+ struct v4l2_frmivalenum *arg)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ int ret;
-+
-+ DBG_entering;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ ret = v4l2_subdev_call(isp->sensor_curr, video, enum_frameintervals,
-+ arg);
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_queryctrl(struct file *file, void *priv,
-+ struct v4l2_queryctrl *c)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(vdev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ if (!v4l2_subdev_call(isp->sensor_curr, core, queryctrl, c))
-+ return 0;
-+ else if (!v4l2_subdev_call(isp->motor, core, queryctrl, c))
-+ return 0;
-+
-+ /* No controls supported */
-+ return -EINVAL;
-+}
-+
-+static int mrst_isp_g_ctrl(struct file *file, void *priv,
-+ struct v4l2_control *c)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ int ret;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+ if (c->id == V4L2_CID_FOCUS_ABSOLUTE) {
-+ ret = v4l2_subdev_call(isp->motor, core, g_ctrl, c);
-+ dprintk(2, "get focus from motor : %d", c->value);
-+ return ret;
-+ } else {
-+ ret = v4l2_subdev_call(isp->sensor_curr, core, g_ctrl, c);
-+ dprintk(2, "get other cotrol from senrsor : %d", c->value);
-+ return ret;
-+ }
-+}
-+
-+static int mrst_isp_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ DBG_entering;
-+
-+ if (c->id == V4L2_CID_FOCUS_ABSOLUTE) {
-+ dprintk(2, "setting focus %d to motor", c->value);
-+ return v4l2_subdev_call(isp->motor, core, s_ctrl, c);
-+ } else {
-+ dprintk(2, "setting other ctrls, value = %d", c->value);
-+ return v4l2_subdev_call(isp->sensor_curr, core, s_ctrl, c);
-+ }
-+}
-+
-+static int mrst_isp_index_to_camera(struct mrst_isp_device *isp, u32 index)
-+{
-+ int camera = MRST_CAMERA_NONE;
-+
-+ if (isp->sensor_soc && isp->sensor_raw) {
-+ switch (index) {
-+ case 0:
-+ camera = isp->sensor_soc_index;
-+ break;
-+ case 1:
-+ camera = isp->sensor_raw_index;
-+ break;
-+ }
-+ } else if (isp->sensor_soc) {
-+ switch (index) {
-+ case 0:
-+ camera = isp->sensor_soc_index;
-+ break;
-+ }
-+ } else if (isp->sensor_raw) {
-+ switch (index) {
-+ case 0:
-+ camera = isp->sensor_raw_index;
-+ break;
-+ }
-+ }
-+
-+ return camera;
-+}
-+
-+static int mrst_isp_enum_input(struct file *file, void *priv,
-+ struct v4l2_input *i)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(vdev);
-+ int camera;
-+
-+ DBG_entering;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ camera = mrst_isp_index_to_camera(isp, i->index);
-+ if (MRST_CAMERA_NONE == camera)
-+ return -EINVAL;
-+
-+ i->type = V4L2_INPUT_TYPE_CAMERA;
-+ i->std = V4L2_STD_UNKNOWN;
-+ strcpy(i->name, mrst_camera_table[camera].name);
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+static int mrst_isp_g_input(struct file *file, void *priv, unsigned int *i)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(vdev);
-+
-+ DBG_entering;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ if (isp->sensor_soc && isp->sensor_raw)
-+ if (isp->sensor_curr == isp->sensor_soc)
-+ *i = 0;
-+ else
-+ *i = 1;
-+ else
-+ *i = 0;
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_s_input(struct file *file, void *priv, unsigned int i)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(vdev);
-+
-+ int camera;
-+
-+ DBG_entering;
-+
-+ if (isp->streaming) {
-+ printk(KERN_WARNING "VIDIOC_S_INPUT error: ISP is streaming\n");
-+ return -EBUSY;
-+ }
-+
-+ camera = mrst_isp_index_to_camera(isp, i);
-+ if (MRST_CAMERA_NONE == camera)
-+ return -EINVAL;
-+
-+ if (mrst_camera_table[camera].type == MRST_CAMERA_SOC)
-+ isp->sensor_curr = isp->sensor_soc;
-+ else
-+ isp->sensor_curr = isp->sensor_raw;
-+
-+ dprintk(1, "set sensor %s as input", isp->sensor_curr->name);
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_g_ext_ctrls(struct file *file,
-+ void *fh,
-+ struct v4l2_ext_controls *c)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ int ret = -EINVAL;
-+
-+ DBG_entering;
-+
-+ if (c->ctrl_class != V4L2_CTRL_CLASS_CAMERA) {
-+ printk(KERN_ERR "Invalid control class\n");
-+ return ret;
-+ }
-+
-+ c->error_idx = 0;
-+ if (isp->motor) {
-+ ret = v4l2_subdev_call(isp->motor, core, g_ext_ctrls, c);
-+ if (c->error_idx) {
-+ printk(KERN_ERR "mrst: error call g_ext_ctrls\n");
-+ return ret;
-+ }
-+ }
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_s_ext_ctrls(struct file *file, void *fh,
-+ struct v4l2_ext_controls *c)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ int ret = -EINVAL;
-+
-+ DBG_entering;
-+
-+ if (c->ctrl_class != V4L2_CTRL_CLASS_CAMERA) {
-+ printk(KERN_INFO "Invalid control class\n");
-+ return ret;
-+ }
-+
-+ c->error_idx = 0;
-+ if (isp->motor) {
-+ ret = v4l2_subdev_call(isp->motor, core, s_ext_ctrls, c);
-+ if (c->error_idx) {
-+ printk(KERN_ERR "mrst: error call s_ext_ctrls\n");
-+ return ret;
-+ }
-+ }
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_s_std(struct file *filp, void *priv, v4l2_std_id *a)
-+{
-+ DBG_entering;
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_querycap(struct file *file, void *priv,
-+ struct v4l2_capability *cap)
-+{
-+ struct video_device *dev = video_devdata(file);
-+
-+ DBG_entering;
-+
-+ strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
-+ strlcpy(cap->card, dev->name, sizeof(cap->card));
-+
-+ cap->version = INTEL_VERSION(0, 5, 0);
-+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-+
-+ DBG_leaving;
-+
-+ return 0;
-+}
-+
-+static int mrst_isp_cropcap(struct file *file, void *priv,
-+ struct v4l2_cropcap *cap)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+
-+ if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ cap->bounds.left = 0;
-+ cap->bounds.top = 0;
-+ cap->bounds.width = isp->bufwidth;
-+ cap->bounds.height = isp->bufheight;
-+ cap->defrect = cap->bounds;
-+ cap->pixelaspect.numerator = 1;
-+ cap->pixelaspect.denominator = 1;
-+
-+ DBG_leaving;
-+
-+ return 0;
-+}
-+
-+static int mrst_isp_enum_fmt_cap(struct file *file, void *priv,
-+ struct v4l2_fmtdesc *f)
-+{
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ unsigned int index;
-+
-+ DBG_entering;
-+
-+ index = f->index;
-+
-+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+ else {
-+ if (isp->sensor_curr == isp->sensor_soc)
-+ if (index >= 8)
-+ return -EINVAL;
-+ if (index >= sizeof(fmts) / sizeof(*fmts))
-+ return -EINVAL;
-+
-+ f->index = index;
-+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ strlcpy(f->description, fmts[index].name,
-+ sizeof(f->description));
-+ f->pixelformat = fmts[index].fourcc;
-+ if (fmts[index].fourcc == V4L2_PIX_FMT_JPEG)
-+ f->flags = V4L2_FMT_FLAG_COMPRESSED;
-+ }
-+
-+ DBG_leaving;
-+
-+ return 0;
-+
-+}
-+
-+#define ALIGN4(x) ((((long)(x)) & 0x3) == 0)
-+
-+static int mrst_isp_reqbufs(struct file *file, void *priv,
-+ struct v4l2_requestbuffers *req)
-+{
-+ int ret;
-+ struct mrst_isp_fh *fh = file->private_data;
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+ if (req->count == 0)
-+ return 0;
-+
-+ /*
-+ * if (req->count > 3)
-+ req->count = 3;
-+ */
-+
-+ if (req->memory != V4L2_MEMORY_MMAP) {
-+ eprintk("wrong memory type");
-+ return -EINVAL;
-+ }
-+ ret = videobuf_reqbufs(&fh->vb_q, req);
-+ if (ret)
-+ eprintk("err calling videobuf_reqbufs ret = %d", ret);
-+
-+ if (!ret)
-+ isp->buffer_required = 1;
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_querybuf(struct file *file, void *priv,
-+ struct v4l2_buffer *buf)
-+{
-+ int ret;
-+ struct mrst_isp_fh *fh = file->private_data;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+ ret = videobuf_querybuf(&fh->vb_q, buf);
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-+{
-+ int ret;
-+ struct mrst_isp_fh *fh = file->private_data;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ DBG_entering;
-+ ret = videobuf_qbuf(&fh->vb_q, buf);
-+ /* identify which video buffer was q-ed */
-+ if (ret == 0)
-+ fh->qbuf_flag |= (1<<buf->index);
-+ dprintk(1, "q-ed index = %d", buf->index);
-+
-+ DBG_leaving;
-+
-+ return ret;
-+}
-+
-+static int mrst_isp_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-+{
-+ int ret;
-+ struct mrst_isp_fh *fh = file->private_data;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ /*XXX zheng*/
-+ /*
-+ if (frame_cnt == 0) {
-+ printk(KERN_WARNING "timer start\n");
-+ intel_timer_start();
-+ }
-+ */
-+
-+ DBG_entering;
-+
-+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+ if (b->memory != V4L2_MEMORY_MMAP)
-+ return -EINVAL;
-+ if (fh->qbuf_flag == 0) {
-+ dprintk(1, "no buffer can be dq-ed\n");
-+ return -EINVAL;
-+ }
-+
-+ /*dprintk(3, "entering");*/
-+ /* ret = videobuf_dqbuf(&fh->vb_q, b, file->f_flags & O_NONBLOCK); */
-+ ret = videobuf_dqbuf(&fh->vb_q, b, 0);
-+ /* identify which video buffer was dq-ed */
-+ if (ret == 0)
-+ fh->qbuf_flag &= ~(1<<b->index);
-+
-+ /*XXX zheng*/
-+ ++frame_cnt;
-+ /*
-+ if (frame_cnt % 10 == 0)
-+ printk(KERN_WARNING "%d frames takes %dms to go, fps = %d\n",
-+ frame_cnt, intel_get_micro_sec(),
-+ frame_cnt * 1000 / intel_get_micro_sec());
-+ */
-+
-+ dprintk(1, "dq-ed index = %d", b->index);
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_streamon(struct file *file, void *priv,
-+ enum v4l2_buf_type type)
-+{
-+ struct mrst_isp_fh *fh = file->private_data;
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+ int ret;
-+
-+ DBG_entering;
-+
-+ if (!isp->buffer_required) {
-+ eprintk("buffer is not required, can not stream on ");
-+ return -EINVAL;
-+ }
-+
-+ dprintk(2, "gamma2 = %d", isp->sys_conf.isp_cfg.flags.gamma2);
-+ WARN_ON(priv != file->private_data);
-+
-+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp->mutex);
-+
-+ if (!to_sensor_config(isp->sensor_curr)->mipi_mode)
-+ v4l2_subdev_call(isp->sensor_curr, video, s_stream, 1);
-+
-+ mrst_isp_dp_init(&isp->sys_conf, to_sensor_config(isp->sensor_curr));
-+ mrst_isp_setup_viewfinder_path(isp,
-+ to_sensor_config(isp->sensor_curr), -1);
-+
-+ ret = videobuf_streamon(&fh->vb_q);
-+ isp->streaming = 1;
-+
-+ mutex_unlock(&isp->mutex);
-+
-+ dprintk(1, "isp->active = %p", isp->active);
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static int mrst_isp_streamoff(struct file *file, void *priv,
-+ enum v4l2_buf_type type)
-+{
-+ struct mrst_isp_fh *fh = file->private_data;
-+ struct video_device *dev = video_devdata(file);
-+ struct mrst_isp_device *isp = video_get_drvdata(dev);
-+
-+ unsigned long flags;
-+ int ret;
-+
-+ DBG_entering;
-+
-+ WARN_ON(priv != file->private_data);
-+
-+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp->mutex);
-+
-+ ret = videobuf_streamoff(&fh->vb_q);
-+ dprintk(1, "ret of videobuf_streamoff = %d", ret);
-+ isp->streaming = 0;
-+
-+ spin_lock_irqsave(&isp->lock, flags);
-+ INIT_LIST_HEAD(&isp->capture);
-+ isp->active = NULL;
-+ isp->next = NULL;
-+ isp->stopflag = 0;
-+ isp->sys_conf.isp_hal_enable = 0;
-+ isp->sys_conf.jpg_review_enable = 0;
-+ isp->sys_conf.isp_cfg.img_eff_cfg.mode = CI_ISP_IE_MODE_OFF;
-+ isp->sys_conf.isp_cfg.jpeg_enc_ratio = 1;
-+
-+ spin_unlock_irqrestore(&isp->lock, flags);
-+
-+ v4l2_subdev_call(isp->sensor_curr, video, s_stream, 0);
-+ ci_isp_stop(CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+
-+ mutex_unlock(&isp->mutex);
-+
-+ DBG_leaving;
-+ return ret;
-+}
-+
-+static const struct v4l2_file_operations mrst_isp_fops = {
-+ .owner = THIS_MODULE,
-+ .open = mrst_isp_open,
-+ .release = mrst_isp_close,
-+ .read = mrst_isp_read,
-+ .mmap = mrst_isp_mmap,
-+ .ioctl = video_ioctl2,
-+};
-+
-+static const struct v4l2_ioctl_ops mrst_isp_ioctl_ops = {
-+ .vidioc_querycap = mrst_isp_querycap,
-+ .vidioc_enum_fmt_vid_cap = mrst_isp_enum_fmt_cap,
-+ .vidioc_g_fmt_vid_cap = mrst_isp_g_fmt_cap,
-+ /* .vidioc_g_fmt_vid_out =
-+ * mrst_isp_g_fmt_cap_for_sensor_hal, */
-+ .vidioc_try_fmt_vid_cap = mrst_isp_try_fmt_cap,
-+ .vidioc_s_fmt_vid_cap = mrst_isp_s_fmt_cap,
-+ .vidioc_cropcap = mrst_isp_cropcap,
-+ .vidioc_reqbufs = mrst_isp_reqbufs,
-+ .vidioc_querybuf = mrst_isp_querybuf,
-+ .vidioc_qbuf = mrst_isp_qbuf,
-+ .vidioc_dqbuf = mrst_isp_dqbuf,
-+ .vidioc_enum_input = mrst_isp_enum_input,
-+ .vidioc_g_input = mrst_isp_g_input,
-+ .vidioc_s_input = mrst_isp_s_input,
-+ .vidioc_s_std = mrst_isp_s_std,
-+ .vidioc_queryctrl = mrst_isp_queryctrl,
-+ .vidioc_streamon = mrst_isp_streamon,
-+ .vidioc_streamoff = mrst_isp_streamoff,
-+ .vidioc_g_ctrl = mrst_isp_g_ctrl,
-+ .vidioc_s_ctrl = mrst_isp_s_ctrl,
-+ .vidioc_enum_framesizes = mrst_isp_enum_framesizes,
-+ .vidioc_enum_frameintervals = mrst_isp_enum_frameintervals,
-+ .vidioc_g_ext_ctrls = mrst_isp_g_ext_ctrls,
-+ .vidioc_s_ext_ctrls = mrst_isp_s_ext_ctrls,
-+ /* FIXME private ioctls */
-+ .vidioc_default = mrst_isp_vidioc_default,
-+};
-+
-+static struct video_device mrst_isp_vdev = {
-+ .name = "mrst_isp",
-+ .minor = -1,
-+ .fops = &mrst_isp_fops,
-+ .ioctl_ops = &mrst_isp_ioctl_ops,
-+ .release = video_device_release_empty,
-+};
-+
-+static int mrst_ci_sensor_probe(struct mrst_isp_device *isp)
-+{
-+ struct v4l2_subdev *sensor = NULL, *motor = NULL;
-+ int i;
-+ char *name;
-+ u8 addr;
-+
-+ isp->adapter_sensor = i2c_get_adapter(MRST_I2C_BUS_SENSOR);
-+ if (NULL == isp->adapter_sensor) {
-+ printk(KERN_ERR "mrstisp: no sensor i2c adapter\n");
-+ return -ENODEV;
-+ }
-+
-+ dprintk(1, "got sensor i2c adapter: %s", isp->adapter_sensor->name);
-+
-+ gpio_request(GPIO_STDBY1_PIN, "Sensor Standby1");
-+ gpio_request(GPIO_STDBY2_PIN, "Sensor Standby2");
-+ gpio_request(GPIO_RESET_PIN, "Sensor Reset");
-+ gpio_request(GPIO_SCLK_25, "Sensor clock");
-+ gpio_request(95, "Camera Motor");
-+
-+ /* Enable sensor related GPIO in system */
-+ gpio_direction_output(GPIO_STDBY1_PIN, 0);
-+ gpio_direction_output(GPIO_STDBY2_PIN, 0);
-+ gpio_direction_output(GPIO_RESET_PIN, 1);
-+ gpio_direction_output(GPIO_SCLK_25, 0);
-+ /* gpio_direction_output(GPIO_AF_PD, 1); */
-+
-+ /*
-+ gpio_alt_func(GPIO_STDBY1_PIN, 0);
-+ gpio_alt_func(GPIO_STDBY2_PIN, 0);
-+ gpio_alt_func(GPIO_RESET_PIN, 0);
-+ gpio_alt_func(GPIO_SCLK_25, 1);
-+ */
-+
-+ for (i = 0; i < N_CAMERA; i++) {
-+ name = mrst_camera_table[i].name;
-+ addr = mrst_camera_table[i].sensor_addr;
-+ if (mrst_camera_table[i].type == MRST_CAMERA_SOC) {
-+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
-+ sensor = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_sensor,
-+ name, name, addr);
-+#else
-+ sensor = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_sensor,
-+ name, name, addr, NULL);
-+#endif
-+
-+ if (sensor == NULL) {
-+ dprintk(2, "sensor %s not found", name);
-+ continue;
-+ }
-+ isp->sensor_soc = sensor;
-+ isp->sensor_soc_index = i;
-+ dprintk(0, "soc camera sensor %s-%s successfully found",
-+ name, sensor->name);
-+ }
-+
-+ if (mrst_camera_table[i].type == MRST_CAMERA_RAW) {
-+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
-+ sensor = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_sensor,
-+ name, name, addr);
-+#else
-+ sensor = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_sensor,
-+ name, name, addr, NULL);
-+#endif
-+
-+ if (sensor == NULL) {
-+ dprintk(2, "sensor %s not found", name);
-+ continue;
-+ }
-+ isp->sensor_raw = sensor;
-+ isp->sensor_raw_index = i;
-+ dprintk(0, "raw camera sensor %s successfully found",
-+ name);
-+ name = mrst_camera_table[i].motor_name;
-+ addr = mrst_camera_table[i].motor_addr;
-+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
-+ motor = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_sensor,
-+ name, name, addr);
-+#else
-+ motor = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_sensor,
-+ name, name, addr, NULL);
-+#endif
-+
-+ if (motor == NULL)
-+ dprintk(2, "motor %s not found", name);
-+ else {
-+ isp->motor = motor;
-+ dprintk(0, "motor %s successfully found", name);
-+ }
-+ }
-+ }
-+
-+ if (!isp->sensor_soc && !isp->sensor_raw) {
-+ dprintk(0, "no camera sensor device attached");
-+ return -ENODEV;
-+ } else {
-+ if (isp->sensor_soc)
-+ isp->sensor_curr = isp->sensor_soc;
-+ else
-+ isp->sensor_curr = isp->sensor_raw;
-+ return 0;
-+ }
-+}
-+
-+static int mrst_ci_flash_probe(struct mrst_isp_device *isp)
-+{
-+ struct v4l2_subdev *flash = NULL;
-+ char *name = "mrst_camera_flash";
-+
-+ gpio_request(45, "Camera Flash");
-+ gpio_direction_output(45, 0);
-+
-+ isp->adapter_flash = i2c_get_adapter(MRST_I2C_BUS_FLASH);
-+ if (NULL == isp->adapter_flash) {
-+ dprintk(0, "no flash i2c adapter\n");
-+ return -ENODEV;
-+ }
-+
-+ dprintk(1, "got flash i2c adapter: %s", isp->adapter_flash->name);
-+
-+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
-+ flash = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_flash,
-+ name, name, 0x53);
-+#else
-+ flash = v4l2_i2c_new_subdev(&isp->v4l2_dev,
-+ isp->adapter_flash,
-+ name, name, 0x53, NULL);
-+#endif
-+
-+ if (flash == NULL) {
-+ dprintk(0, "no flash IC found\n");
-+ return -ENODEV;
-+ }
-+
-+ dprintk(0, "flash IC found");
-+ return 0;
-+}
-+
-+#if IRQ
-+static irqreturn_t mrst_isp_irq_handler(int this_irq, void *dev_id)
-+{
-+ struct isp_register *mrv_reg =
-+ (struct isp_register *) MEM_MRV_REG_BASE;
-+ struct mrst_isp_device *isp = dev_id;
-+ struct videobuf_buffer *vb;
-+ unsigned long flags;
-+
-+ u32 mi_mask = ci_isp_get_frame_end_irq_mask_isp();
-+ u32 isp_mask = MRV_ISP_RIS_DATA_LOSS_MASK
-+ | MRV_ISP_RIS_PIC_SIZE_ERR_MASK;
-+ u32 jpe_status_mask = MRV_JPE_ALL_STAT_MASK;
-+ u32 jpe_error_mask = MRV_JPE_ALL_ERR_MASK;
-+ u32 mblk_line_mask = MRV_MI_MBLK_LINE_MASK;
-+
-+ u32 isp_irq;
-+ u32 mi_irq;
-+ u32 jpe_status_irq;
-+ u32 jpe_error_irq;
-+ u32 mipi_irq;
-+ u32 mblk_line;
-+ u32 bufbase;
-+
-+ isp_irq = REG_READ_EX(mrv_reg->isp_ris) & isp_mask;
-+ mi_irq = REG_READ_EX(mrv_reg->mi_ris) & mi_mask;
-+
-+ mblk_line = REG_READ_EX(mrv_reg->mi_ris) & mblk_line_mask;
-+
-+ jpe_status_irq = REG_READ_EX(mrv_reg->jpe_status_ris) & jpe_status_mask;
-+ jpe_error_irq = REG_READ_EX(mrv_reg->jpe_error_ris) & jpe_error_mask;
-+
-+ mipi_irq = REG_READ_EX(mrv_reg->mipi_ris) & 0x00f00000;
-+
-+ dprintk(3, "IRQ: mblk_line = %x, mi_irq = %x, jpe_status_irq = %x,"
-+ " jpe_error_irq = %x, isp_irq = %x", mblk_line, mi_irq,
-+ jpe_status_irq, jpe_error_irq, isp_irq);
-+
-+ if (!(isp_irq | mi_irq | jpe_status_irq | jpe_error_irq | mblk_line
-+ | mipi_irq)) {
-+ dprintk(2, "unknown interrupt");
-+ return IRQ_HANDLED;
-+ }
-+
-+ REG_SET_SLICE_EX(mrv_reg->isp_icr, MRV_ISP_ICR_ALL, ON);
-+ REG_SET_SLICE_EX(mrv_reg->mi_icr, MRV_MI_ALLIRQS, ON);
-+ REG_SET_SLICE_EX(mrv_reg->jpe_error_icr, MRV_JPE_ALL_ERR, ON);
-+ REG_SET_SLICE_EX(mrv_reg->jpe_status_icr, MRV_JPE_ALL_STAT, ON);
-+ REG_WRITE_EX(mrv_reg->mipi_icr, 0xffffffff);
-+
-+ if (isp_irq) {
-+ /* Currently we don't reset hardware even error detect */
-+ dprintk(3, "ISP error IRQ received %x", isp_irq);
-+ isp_error_num++;
-+ isp_error_flag |= isp_irq;
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (mipi_irq) {
-+ dprintk(3, "error in mipi_irq %x", mipi_irq);
-+ mipi_error_num++;
-+ mipi_error_flag |= mipi_irq;
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (mblk_line && mrst_isp_to_do_mblk_line) {
-+ REG_SET_SLICE(mrv_reg->mi_imsc, MRV_MI_MBLK_LINE, OFF);
-+ dprintk(3, "enter mblk_line irq");
-+
-+ if (!(isp->active && !isp->next)) {
-+ dprintk(3, "wrong isq status");
-+ if (isp->active)
-+ dprintk(2, "actie->i = %d", isp->active->i);
-+ else
-+ dprintk(2, "actie = NULL");
-+ if (isp->next)
-+ dprintk(2, "next->i = %d", isp->next->i);
-+ else
-+ dprintk(2, "next = NULL");
-+ return IRQ_HANDLED;
-+ }
-+
-+ spin_lock_irqsave(&isp->lock, flags);
-+
-+ if (!list_empty(&isp->capture)) {
-+ isp->next = list_entry(isp->capture.next,
-+ struct videobuf_buffer, queue);
-+ isp->next->state = VIDEOBUF_ACTIVE;
-+ bufbase = videobuf_to_dma_contig(isp->next);
-+ mrst_isp_update_marvinvfaddr(isp, bufbase,
-+ CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+ dprintk(1, "updating new addr, next = %d",
-+ isp->next->i);
-+ } else {
-+ isp->stopflag = 1;
-+ dprintk(0, "stop isp");
-+ }
-+
-+ mrst_isp_to_do_mblk_line = 0;
-+
-+ spin_unlock_irqrestore(&isp->lock, flags);
-+
-+ /* return IRQ_HANDLED; */
-+ }
-+
-+ if (mi_irq && isp->pixelformat != V4L2_PIX_FMT_JPEG &&
-+ !jpe_status_irq) {
-+ dprintk(1, "view finding case");
-+
-+ if (!isp->active) {
-+ dprintk(0, "no active queue, You should not go here");
-+ mrst_isp_to_do_mblk_line = 1;
-+ REG_SET_SLICE(mrv_reg->mi_imsc, MRV_MI_MBLK_LINE, ON);
-+ return IRQ_HANDLED;
-+ }
-+
-+ spin_lock_irqsave(&isp->lock, flags);
-+
-+ /* update captured frame status */
-+ vb = isp->active;
-+ /* vb->size = ci_isp_mif_get_byte_cnt(); */
-+ /* if this buffer has been dq-ed, set nothing to state*/
-+ if (vb->state != VIDEOBUF_IDLE)
-+ vb->state = VIDEOBUF_DONE;
-+ vb->field_count++;
-+
-+ isp->active = NULL;
-+ dprintk(1, "buf %d size = %lx", vb->i, vb->size);
-+ do_gettimeofday(&vb->ts);
-+ wake_up(&vb->done);
-+
-+ if (!isp->next) {
-+ if (!list_empty(&isp->capture)) {
-+ isp->active = list_entry(isp->capture.next,
-+ struct videobuf_buffer, queue);
-+ list_del_init(&isp->active->queue);
-+ isp->active->state = VIDEOBUF_ACTIVE;
-+ dprintk(3, "start next frame %d",
-+ isp->active->i);
-+ mrst_isp_to_do_mblk_line = 1;
-+ REG_SET_SLICE(mrv_reg->mi_imsc,
-+ MRV_MI_MBLK_LINE, ON);
-+ } else {
-+ mrst_isp_to_do_mblk_line = 1;
-+ REG_SET_SLICE(mrv_reg->mi_imsc,
-+ MRV_MI_MBLK_LINE, ON);
-+ mrst_isp_disable_interrupt(isp);
-+ dprintk(3, "no frame right now");
-+ }
-+ } else {
-+ isp->active = isp->next;
-+ list_del_init(&isp->next->queue);
-+ isp->next = NULL;
-+ dprintk(1, "active = next = %d, next = NULL",
-+ isp->active->i);
-+ mrst_isp_to_do_mblk_line = 1;
-+ REG_SET_SLICE(mrv_reg->mi_imsc, MRV_MI_MBLK_LINE, ON);
-+ }
-+
-+ spin_unlock_irqrestore(&isp->lock, flags);
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (jpe_status_irq) {
-+ dprintk(2, "jpeg capture case");
-+
-+ if (!isp->active)
-+ return IRQ_HANDLED;
-+
-+ spin_lock_irqsave(&isp->lock, flags);
-+
-+ vb = isp->active;
-+ vb->size = ci_isp_mif_get_byte_cnt();
-+ vb->state = VIDEOBUF_DONE;
-+ do_gettimeofday(&vb->ts);
-+ vb->field_count++;
-+ wake_up(&vb->done);
-+ isp->active = NULL;
-+
-+ dprintk(2, "index =%d, bufsize = %lx", vb->i, vb->size);
-+
-+ spin_unlock_irqrestore(&isp->lock, flags);
-+
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (jpe_error_irq)
-+ dprintk(2, "entered jpe_error_irq");
-+
-+ return IRQ_HANDLED;
-+}
-+#endif
-+
-+static void __devexit mrst_isp_pci_remove(struct pci_dev *pdev)
-+{
-+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
-+ struct mrst_isp_device *isp = to_isp(v4l2_dev);
-+
-+ DBG_entering;
-+
-+ ci_isp_stop(CI_ISP_CFG_UPDATE_FRAME_SYNC);
-+ mrst_isp_disable_interrupt(isp);
-+
-+#if IRQ
-+ free_irq(pdev->irq, isp);
-+#endif
-+
-+ if (isp->vdev) {
-+ dprintk(2, "isp->vdev = %p", isp->vdev);
-+ video_unregister_device(isp->vdev);
-+ }
-+
-+ dma_release_declared_memory(&pdev->dev);
-+
-+ iounmap(isp->regs);
-+
-+ pci_release_regions(pdev);
-+
-+ pci_disable_device(pdev);
-+
-+ v4l2_device_unregister(&isp->v4l2_dev);
-+
-+ kfree(isp);
-+
-+ DBG_leaving;
-+}
-+
-+static int __devinit mrst_isp_pci_probe(struct pci_dev *pdev,
-+ const struct pci_device_id *pci_id)
-+{
-+ struct mrst_isp_device *isp;
-+ unsigned int start = 0;
-+ unsigned int len = 0;
-+ int ret = 0;
-+
-+ DBG_entering;
-+
-+ /* alloc device struct */
-+ isp = kzalloc(sizeof(struct mrst_isp_device), GFP_KERNEL);
-+ if (NULL == isp) {
-+ printk(KERN_ERR "mrstisp: fail to kzalloc mrst_isp_device\n");
-+ ret = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ /* register v4l2 device */
-+ ret = v4l2_device_register(&pdev->dev, &isp->v4l2_dev);
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: fail to register v4l2 device\n");
-+ goto exit_free_isp;
-+ }
-+
-+ /* PCI operations */
-+ ret = pci_enable_device(pdev);
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: can't enable isp\n");
-+ goto exit_unregister_v4l2;
-+ }
-+
-+ pci_set_master(pdev);
-+
-+ ret = pci_request_regions(pdev, "mrst isp");
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: can't request regions\n");
-+ goto exit_disable_isp;
-+ }
-+
-+ /* mem bar 0 */
-+ start = isp->mb0 = pci_resource_start(pdev, 0);
-+ len = isp->mb0_size = pci_resource_len(pdev, 0);
-+
-+ isp->regs = ioremap_nocache(start, len);
-+ mrst_isp_regs = isp->regs;
-+ if (isp->regs == NULL) {
-+ printk(KERN_ERR "mrstisp: fail to ioremap isp registers\n");
-+ goto exit_release_regions;
-+ }
-+
-+ dprintk(1, "isp mb0 = %lx, mb0_size = %lx, regs = %p",
-+ isp->mb0, isp->mb0_size, isp->regs);
-+
-+ /* mem bar 1 */
-+ start = isp->mb1 = pci_resource_start(pdev, 1);
-+ len = isp->mb1_size = pci_resource_len(pdev, 1);
-+
-+ dprintk(1, "isp mb1 = %lx, mb1_size = %lx", isp->mb1, isp->mb1_size);
-+
-+ ret = dma_declare_coherent_memory(&pdev->dev, start,
-+ /* start, len - 640 * 480 * 2, */
-+ start, len,
-+ DMA_MEMORY_MAP);
-+ /*
-+ DMA_MEMORY_MAP
-+ | DMA_MEMORY_EXCLUSIVE);
-+ */
-+ if (!ret) {
-+ dprintk(0, "failed to declare dma memory");
-+ ret = -ENXIO;
-+ goto exit_iounmap;
-+ }
-+
-+ /* init device struct */
-+ INIT_LIST_HEAD(&isp->capture);
-+ spin_lock_init(&isp->lock);
-+ mutex_init(&isp->mutex);
-+
-+ pci_read_config_word(pdev, PCI_VENDOR_ID, &isp->vendorID);
-+ pci_read_config_word(pdev, PCI_DEVICE_ID, &isp->deviceID);
-+
-+ mrst_isp_defcfg_all_load(&isp->sys_conf.isp_cfg);
-+
-+ isp->bufwidth = 640;
-+ isp->bufheight = 480;
-+ isp->depth = 12;
-+ isp->pixelformat = V4L2_PIX_FMT_YVU420;
-+ isp->streaming = 0;
-+ isp->buffer_required = 0;
-+
-+
-+ /* probe sensor */
-+ ret = mrst_ci_sensor_probe(isp);
-+ if (ret) {
-+ dprintk(0, "failed to sensor probe\n");
-+ goto exit_dma_release;
-+ }
-+
-+ /* regiter video device */
-+ isp->vdev = &mrst_isp_vdev;
-+ isp->vdev->parent = &pdev->dev;
-+ video_set_drvdata(isp->vdev, isp);
-+
-+ ret = video_register_device(isp->vdev, VFL_TYPE_GRABBER, -1);
-+ if (ret) {
-+ dprintk(0, "fail to register video deivice");
-+ goto exit_dma_release;
-+ }
-+
-+ dprintk(0, "registered dev/video%d", isp->vdev->num);
-+ dprintk(0, "isp->vdev = %p", isp->vdev);
-+
-+#if IRQ
-+ /* request irq */
-+ ret = request_irq(pdev->irq, mrst_isp_irq_handler, IRQF_SHARED,
-+ /* pci_name(pdev), isp); */
-+ "mrst_camera_imaging", isp);
-+ if (ret) {
-+ dprintk(0, "fail to request irq");
-+ goto exit_unregister_video;
-+ }
-+
-+ mrst_isp_disable_interrupt(isp);
-+#endif
-+
-+ /* probe flash */
-+ mrst_ci_flash_probe(isp);
-+
-+ mrst_isp_to_do_mblk_line = 0;
-+
-+ dprintk(0, "mrstisp driver module successfully loaded");
-+ return 0;
-+
-+exit_unregister_video:
-+ video_unregister_device(isp->vdev);
-+exit_dma_release:
-+ dma_release_declared_memory(&pdev->dev);
-+exit_iounmap:
-+ iounmap(isp->regs);
-+exit_release_regions:
-+ pci_release_regions(pdev);
-+exit_disable_isp:
-+ pci_disable_device(pdev);
-+exit_unregister_v4l2:
-+ v4l2_device_unregister(&isp->v4l2_dev);
-+exit_free_isp:
-+ kfree(isp);
-+exit:
-+ return ret;
-+}
-+
-+#ifdef CONFIG_PM
-+static int mrst_isp_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-+{
-+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
-+ struct mrst_isp_device *isp = to_isp(v4l2_dev);
-+ int ret;
-+
-+ DBG_entering;
-+
-+ ci_isp_off();
-+
-+ ret = pci_save_state(pdev);
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: pci_save_state failed %d\n", ret);
-+ return ret;
-+ }
-+
-+ ret = pci_set_power_state(pdev, PCI_D3cold);
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: fail to set power state\n");
-+ return ret;
-+ }
-+
-+/*
-+ ret = ci_sensor_suspend();
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: Fail to suspend sensor\n");
-+ return ret;
-+ }
-+*/
-+ if (isp->sensor_soc)
-+ v4l2_subdev_call(isp->sensor_soc, core, s_gpio, 1);
-+ if (isp->sensor_raw)
-+ v4l2_subdev_call(isp->sensor_raw, core, s_gpio, 1);
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static int mrst_isp_pci_resume(struct pci_dev *pdev)
-+{
-+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
-+ struct mrst_isp_device *isp = to_isp(v4l2_dev);
-+ int ret;
-+
-+ DBG_entering;
-+
-+ pci_set_power_state(pdev, PCI_D0);
-+ pci_restore_state(pdev);
-+
-+ ret = pci_enable_device(pdev);
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: fail to enable device in resume\n");
-+ return ret;
-+ }
-+
-+/*
-+ ret = ci_sensor_resume();
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: Fail to resume sensor\n");
-+ return ret;
-+ }
-+*/
-+ if (isp->sensor_soc)
-+ v4l2_subdev_call(isp->sensor_soc, core, s_gpio, 0);
-+ if (isp->sensor_raw)
-+ v4l2_subdev_call(isp->sensor_raw, core, s_gpio, 0);
-+
-+ ci_isp_init();
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+#endif
-+
-+static struct pci_device_id mrst_isp_pci_tbl[] __devinitdata = {
-+ { PCI_DEVICE(0x8086, 0x080B) },
-+ {0,}
-+};
-+
-+MODULE_DEVICE_TABLE(pci, mrst_isp_pci_tbl);
-+
-+static struct pci_driver mrst_isp_pci_driver = {
-+ .name = "mrstisp",
-+ .id_table = mrst_isp_pci_tbl,
-+ .probe = mrst_isp_pci_probe,
-+ .remove = mrst_isp_pci_remove,
-+ #ifdef CONFIG_PM
-+ .suspend = mrst_isp_pci_suspend,
-+ .resume = mrst_isp_pci_resume,
-+ #endif
-+};
-+
-+static int __init mrst_isp_pci_init(void)
-+{
-+ int ret;
-+
-+ DBG_entering;
-+
-+ ret = pci_register_driver(&mrst_isp_pci_driver);
-+ if (ret) {
-+ printk(KERN_ERR "mrstisp: Unable to register driver\n");
-+ return ret;
-+ }
-+
-+ if (ret)
-+ dprintk(1, "Unable to register flash driver");
-+
-+ DBG_leaving;
-+ return 0;
-+}
-+
-+static void __exit mrst_isp_pci_exit(void)
-+{
-+ DBG_entering;
-+
-+ pci_unregister_driver(&mrst_isp_pci_driver);
-+
-+ DBG_leaving;
-+}
-+
-+module_init(mrst_isp_pci_init);
-+/* late_initcall(mrst_isp_pci_init); */
-+module_exit(mrst_isp_pci_exit);
-+
-+MODULE_DESCRIPTION("Intel Moorestown ISP driver");
-+MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
-+MODULE_LICENSE("GPL");
-+MODULE_SUPPORTED_DEVICE("video");
-+
-diff --git a/drivers/media/video/mrstci/mrstisp/mrstisp_mif.c b/drivers/media/video/mrstci/mrstisp/mrstisp_mif.c
-new file mode 100644
-index 0000000..a05731a
---- /dev/null
-+++ b/drivers/media/video/mrstci/mrstisp/mrstisp_mif.c
-@@ -0,0 +1,763 @@
-+/*
-+ * Support for Moorestown Langwell Camera Imaging ISP subsystem.
-+ *
-+ * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
-+ *
-+ * Copyright (c) Silicon Image 2008 www.siliconimage.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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ *
-+ * Xiaolin Zhang <xiaolin.zhang@intel.com>
-+ */
-+
-+#include "mrstisp_stdinc.h"
-+
-+/*
-+ * sets all main picture and self picture buffer offsets back to 0
-+ */
-+void ci_isp_mif_reset_offsets(enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ REG_SET_SLICE(mrv_reg->mi_mp_y_offs_cnt_init,
-+ MRV_MI_MP_Y_OFFS_CNT_INIT, 0);
-+ REG_SET_SLICE(mrv_reg->mi_mp_cb_offs_cnt_init,
-+ MRV_MI_MP_CB_OFFS_CNT_INIT, 0);
-+ REG_SET_SLICE(mrv_reg->mi_mp_cr_offs_cnt_init,
-+ MRV_MI_MP_CR_OFFS_CNT_INIT, 0);
-+
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_offs_cnt_init,
-+ MRV_MI_SP_Y_OFFS_CNT_INIT, 0);
-+ REG_SET_SLICE(mrv_reg->mi_sp_cb_offs_cnt_init,
-+ MRV_MI_SP_CB_OFFS_CNT_INIT, 0);
-+ REG_SET_SLICE(mrv_reg->mi_sp_cr_offs_cnt_init,
-+ MRV_MI_SP_CR_OFFS_CNT_INIT, 0);
-+
-+ REG_SET_SLICE(mrv_reg->mi_ctrl, MRV_MI_INIT_OFFSET_EN, ON);
-+ REG_SET_SLICE(mrv_reg->mi_ctrl, MRV_MI_INIT_BASE_EN, ON);
-+
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ REG_SET_SLICE(mrv_reg->mi_init, MRV_MI_MI_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+/*
-+ * This function get the byte count from the last JPEG or raw data transfer
-+ */
-+u32 ci_isp_mif_get_byte_cnt(void)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+
-+ return (u32) REG_GET_SLICE(mrv_reg->mi_byte_cnt, MRV_MI_BYTE_CNT);
-+}
-+
-+/*
-+ * Sets the desired self picture orientation, if possible.
-+ */
-+static int ci_isp_mif_set_self_pic_orientation(enum ci_isp_mif_sp_mode
-+ mrv_mif_sp_mode,
-+ int activate_self_path)
-+{
-+
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ u32 mi_ctrl = REG_READ(mrv_reg->mi_ctrl);
-+
-+ u32 output_format = REG_GET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT);
-+
-+ /* apply the desired self picture orientation, if possible */
-+ switch (mrv_mif_sp_mode) {
-+ case CI_ISP_MIF_SP_ORIGINAL:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP, 0);
-+ break;
-+
-+ case CI_ISP_MIF_SP_HORIZONTAL_FLIP:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_H_FLIP);
-+ break;
-+
-+ case CI_ISP_MIF_SP_VERTICAL_FLIP:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_V_FLIP);
-+ break;
-+
-+ case CI_ISP_MIF_SP_ROTATION_090_DEG:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_ROTATE);
-+ break;
-+
-+ case CI_ISP_MIF_SP_ROTATION_180_DEG:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_H_FLIP |
-+ MRV_MI_ROT_AND_FLIP_V_FLIP);
-+ break;
-+
-+ case CI_ISP_MIF_SP_ROTATION_270_DEG:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_H_FLIP |
-+ MRV_MI_ROT_AND_FLIP_V_FLIP |
-+ MRV_MI_ROT_AND_FLIP_ROTATE);
-+ break;
-+
-+ case CI_ISP_MIF_SP_ROT_090_V_FLIP:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_V_FLIP |
-+ MRV_MI_ROT_AND_FLIP_ROTATE);
-+ break;
-+
-+ case CI_ISP_MIF_SP_ROT_270_V_FLIP:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP,
-+ MRV_MI_ROT_AND_FLIP_H_FLIP |
-+ MRV_MI_ROT_AND_FLIP_ROTATE);
-+ break;
-+
-+ default:
-+ eprintk("unknown value for mrv_mif_sp_mode");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+
-+ if (REG_GET_SLICE(mi_ctrl, MRV_MI_ROT_AND_FLIP) &
-+ MRV_MI_ROT_AND_FLIP_ROTATE) {
-+ switch (output_format) {
-+ case MRV_MI_SP_OUTPUT_FORMAT_RGB888:
-+ case MRV_MI_SP_OUTPUT_FORMAT_RGB666:
-+ case MRV_MI_SP_OUTPUT_FORMAT_RGB565:
-+ /* rotation supported on this output modes */
-+ break;
-+ default:
-+ eprintk("rotation is only allowed for RGB modes.");
-+ return CI_STATUS_NOTSUPP;
-+ }
-+ }
-+
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_ENABLE,
-+ (activate_self_path) ? ENABLE : DISABLE);
-+ REG_WRITE(mrv_reg->mi_ctrl, mi_ctrl);
-+ REG_SET_SLICE(mrv_reg->mi_init, MRV_MI_MI_CFG_UPD, ON);
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Checks the main or self picture path buffer structure.
-+ */
-+static int ci_isp_mif_check_mi_path_conf(const struct ci_isp_mi_path_conf
-+ *isp_mi_path_conf, int main_buffer)
-+{
-+ if (!isp_mi_path_conf) {
-+ eprintk("isp_mi_path_conf is NULL");
-+ return CI_STATUS_NULL_POINTER;
-+ }
-+
-+ if (!isp_mi_path_conf->ybuffer.pucbuffer) {
-+ eprintk("isp_mi_path_conf->ybuffer.pucbuffer is NULL");
-+ return CI_STATUS_NULL_POINTER;
-+ }
-+
-+ if (main_buffer) {
-+ if ((((unsigned long)(isp_mi_path_conf->ybuffer.pucbuffer)
-+ & ~(MRV_MI_MP_Y_BASE_AD_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->ybuffer.size
-+ & ~(MRV_MI_MP_Y_SIZE_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->ybuffer.size
-+ & (MRV_MI_MP_Y_SIZE_INIT_VALID_MASK)) == 0)
-+ ||
-+ ((isp_mi_path_conf->ybuffer.offs
-+ & ~(MRV_MI_MP_Y_OFFS_CNT_INIT_VALID_MASK)) != 0)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+ } else {
-+ if ((((unsigned long) isp_mi_path_conf->ybuffer.pucbuffer
-+ & ~(MRV_MI_SP_Y_BASE_AD_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->ybuffer.size &
-+ ~(MRV_MI_SP_Y_SIZE_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->ybuffer.size &
-+ (MRV_MI_SP_Y_SIZE_INIT_VALID_MASK)) == 0)
-+ ||
-+ ((isp_mi_path_conf->ybuffer.offs &
-+ ~(MRV_MI_SP_Y_OFFS_CNT_INIT_VALID_MASK)) !=
-+ 0)
-+ ||
-+ ((isp_mi_path_conf->llength &
-+ ~(MRV_MI_SP_Y_LLENGTH_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->
-+ llength & (MRV_MI_SP_Y_LLENGTH_VALID_MASK)) == 0)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+ }
-+
-+ if (isp_mi_path_conf->cb_buffer.pucbuffer != 0) {
-+ if (main_buffer) {
-+ if ((((unsigned long)
-+ isp_mi_path_conf->cb_buffer.pucbuffer
-+ & ~(MRV_MI_MP_CB_BASE_AD_INIT_VALID_MASK)) !=
-+ 0)
-+ ||
-+ ((isp_mi_path_conf->cb_buffer.size &
-+ ~(MRV_MI_MP_CB_SIZE_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->cb_buffer.size &
-+ (MRV_MI_MP_CB_SIZE_INIT_VALID_MASK)) == 0)
-+ ||
-+ ((isp_mi_path_conf->cb_buffer.offs &
-+ ~(MRV_MI_MP_CB_OFFS_CNT_INIT_VALID_MASK)) !=
-+ 0)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+ } else {
-+ if ((((unsigned long)
-+ isp_mi_path_conf->cb_buffer.pucbuffer
-+ & ~(MRV_MI_SP_CB_BASE_AD_INIT_VALID_MASK)) !=
-+ 0)
-+ ||
-+ ((isp_mi_path_conf->cb_buffer.size &
-+ ~(MRV_MI_SP_CB_SIZE_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->cb_buffer.size &
-+ (MRV_MI_SP_CB_SIZE_INIT_VALID_MASK)) == 0)
-+ ||
-+ ((isp_mi_path_conf->cb_buffer.offs &
-+ ~(MRV_MI_SP_CB_OFFS_CNT_INIT_VALID_MASK)) !=
-+ 0)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+ }
-+ }
-+
-+ if (isp_mi_path_conf->cr_buffer.pucbuffer != 0) {
-+ if (main_buffer) {
-+ if ((((unsigned long)
-+ isp_mi_path_conf->cr_buffer.pucbuffer
-+ & ~(MRV_MI_MP_CR_BASE_AD_INIT_VALID_MASK)) !=
-+ 0)
-+ ||
-+ ((isp_mi_path_conf->cr_buffer.size &
-+ ~(MRV_MI_MP_CR_SIZE_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->cr_buffer.size &
-+ (MRV_MI_MP_CR_SIZE_INIT_VALID_MASK)) == 0)
-+ ||
-+ ((isp_mi_path_conf->cr_buffer.offs &
-+ ~(MRV_MI_MP_CR_OFFS_CNT_INIT_VALID_MASK)) !=
-+ 0)){
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+ } else {
-+ if ((((unsigned long)
-+ isp_mi_path_conf->cr_buffer.pucbuffer
-+ & ~(MRV_MI_SP_CR_BASE_AD_INIT_VALID_MASK))
-+ != 0)
-+ ||
-+ ((isp_mi_path_conf->cr_buffer.size &
-+ ~(MRV_MI_SP_CR_SIZE_INIT_VALID_MASK)) != 0)
-+ ||
-+ ((isp_mi_path_conf->cr_buffer.size &
-+ (MRV_MI_SP_CR_SIZE_INIT_VALID_MASK)) == 0)
-+ ||
-+ ((isp_mi_path_conf->cr_buffer.offs &
-+ ~(MRV_MI_SP_CR_OFFS_CNT_INIT_VALID_MASK)) != 0)) {
-+ return CI_STATUS_OUTOFRANGE;
-+ }
-+ }
-+ }
-+
-+ return CI_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * Configures the main picture path buffers of the MI.
-+ */
-+int ci_isp_mif_set_main_buffer(const struct ci_isp_mi_path_conf
-+ *isp_mi_path_conf,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ int error = CI_STATUS_FAILURE;
-+
-+ error = ci_isp_mif_check_mi_path_conf(isp_mi_path_conf, true);
-+ if (error != CI_STATUS_SUCCESS)
-+ return error;
-+
-+ /* set register values */
-+ REG_SET_SLICE(mrv_reg->mi_mp_y_base_ad_init,
-+ MRV_MI_MP_Y_BASE_AD_INIT,
-+ (u32)(unsigned long)isp_mi_path_conf->ybuffer.pucbuffer);
-+ REG_SET_SLICE(mrv_reg->mi_mp_y_size_init, MRV_MI_MP_Y_SIZE_INIT,
-+ isp_mi_path_conf->ybuffer.size);
-+ REG_SET_SLICE(mrv_reg->mi_mp_y_offs_cnt_init,
-+ MRV_MI_MP_Y_OFFS_CNT_INIT,
-+ isp_mi_path_conf->ybuffer.offs);
-+
-+ if (isp_mi_path_conf->cb_buffer.pucbuffer != 0) {
-+ REG_SET_SLICE(mrv_reg->mi_mp_cb_base_ad_init,
-+ MRV_MI_MP_CB_BASE_AD_INIT,
-+ (u32)(unsigned long) isp_mi_path_conf->cb_buffer.
-+ pucbuffer);
-+ REG_SET_SLICE(mrv_reg->mi_mp_cb_size_init,
-+ MRV_MI_MP_CB_SIZE_INIT,
-+ isp_mi_path_conf->cb_buffer.size);
-+ REG_SET_SLICE(mrv_reg->mi_mp_cb_offs_cnt_init,
-+ MRV_MI_MP_CB_OFFS_CNT_INIT,
-+ isp_mi_path_conf->cb_buffer.offs);
-+ }
-+
-+ if (isp_mi_path_conf->cr_buffer.pucbuffer != 0) {
-+ REG_SET_SLICE(mrv_reg->mi_mp_cr_base_ad_init,
-+ MRV_MI_MP_CR_BASE_AD_INIT,
-+ (u32)(unsigned long) isp_mi_path_conf->cr_buffer.
-+ pucbuffer);
-+ REG_SET_SLICE(mrv_reg->mi_mp_cr_size_init,
-+ MRV_MI_MP_CR_SIZE_INIT,
-+ isp_mi_path_conf->cr_buffer.size);
-+ REG_SET_SLICE(mrv_reg->mi_mp_cr_offs_cnt_init,
-+ MRV_MI_MP_CR_OFFS_CNT_INIT,
-+ isp_mi_path_conf->cr_buffer.offs);
-+ }
-+
-+ /*
-+ * update base and offset registers during next immediate or
-+ * automatic update request
-+ */
-+ REG_SET_SLICE(mrv_reg->mi_ctrl, MRV_MI_INIT_OFFSET_EN, ENABLE);
-+ REG_SET_SLICE(mrv_reg->mi_ctrl, MRV_MI_INIT_BASE_EN, ENABLE);
-+
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ /*
-+ * frame synchronous update of shadow registers,
-+ * update is done after the curr frame
-+ */
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ /*
-+ * immediate update of shadow registers
-+ * (will disturb an ongoing frame processing)
-+ */
-+ REG_SET_SLICE(mrv_reg->mi_init, MRV_MI_MI_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ /* no update from within this function */
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return error;
-+}
-+
-+/*
-+ * Configures the self picture path buffers of the MI.
-+ *
-+ */
-+int ci_isp_mif_set_self_buffer(const struct ci_isp_mi_path_conf
-+ *isp_mi_path_conf,
-+ enum ci_isp_conf_update_time update_time)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ int error = CI_STATUS_FAILURE;
-+
-+ error = ci_isp_mif_check_mi_path_conf(isp_mi_path_conf, false);
-+ if (error != CI_STATUS_SUCCESS)
-+ return error;
-+
-+ /* set register values */
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_base_ad_init,
-+ MRV_MI_SP_Y_BASE_AD_INIT,
-+ (u32)(unsigned long)isp_mi_path_conf->ybuffer.pucbuffer);
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_size_init, MRV_MI_SP_Y_SIZE_INIT,
-+ isp_mi_path_conf->ybuffer.size);
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_offs_cnt_init,
-+ MRV_MI_SP_Y_OFFS_CNT_INIT,
-+ isp_mi_path_conf->ybuffer.offs);
-+
-+ /*
-+ * llength is counted in pixels and this value could be stored
-+ * directly into the register
-+ */
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_llength, MRV_MI_SP_Y_LLENGTH,
-+ isp_mi_path_conf->llength);
-+
-+ if (isp_mi_path_conf->cb_buffer.pucbuffer) {
-+ REG_SET_SLICE(mrv_reg->mi_sp_cb_base_ad_init,
-+ MRV_MI_SP_CB_BASE_AD_INIT,
-+ (u32) (unsigned long)isp_mi_path_conf->cb_buffer.
-+ pucbuffer);
-+ REG_SET_SLICE(mrv_reg->mi_sp_cb_size_init,
-+ MRV_MI_SP_CB_SIZE_INIT,
-+ isp_mi_path_conf->cb_buffer.size);
-+ REG_SET_SLICE(mrv_reg->mi_sp_cb_offs_cnt_init,
-+ MRV_MI_SP_CB_OFFS_CNT_INIT,
-+ isp_mi_path_conf->cb_buffer.offs);
-+ }
-+
-+ if (isp_mi_path_conf->cr_buffer.pucbuffer) {
-+ REG_SET_SLICE(mrv_reg->mi_sp_cr_base_ad_init,
-+ MRV_MI_SP_CR_BASE_AD_INIT,
-+ (u32) (unsigned long)isp_mi_path_conf->cr_buffer.
-+ pucbuffer);
-+ REG_SET_SLICE(mrv_reg->mi_sp_cr_size_init,
-+ MRV_MI_SP_CR_SIZE_INIT,
-+ isp_mi_path_conf->cr_buffer.size);
-+ REG_SET_SLICE(mrv_reg->mi_sp_cr_offs_cnt_init,
-+ MRV_MI_SP_CR_OFFS_CNT_INIT,
-+ isp_mi_path_conf->cr_buffer.offs);
-+ }
-+
-+ if ((!isp_mi_path_conf->ypic_width)
-+ || (!isp_mi_path_conf->ypic_height)) {
-+ return CI_STATUS_FAILURE;
-+ }
-+
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_pic_width, MRV_MI_SP_Y_PIC_WIDTH,
-+ isp_mi_path_conf->ypic_width);
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_pic_height, MRV_MI_SP_Y_PIC_HEIGHT,
-+ isp_mi_path_conf->ypic_height);
-+ REG_SET_SLICE(mrv_reg->mi_sp_y_pic_size, MRV_MI_SP_Y_PIC_SIZE,
-+ isp_mi_path_conf->ypic_height *
-+ isp_mi_path_conf->llength);
-+
-+ /*
-+ * update base and offset registers during next immediate or
-+ * automatic update request
-+ */
-+ REG_SET_SLICE(mrv_reg->mi_ctrl, MRV_MI_INIT_OFFSET_EN, ENABLE);
-+ REG_SET_SLICE(mrv_reg->mi_ctrl, MRV_MI_INIT_BASE_EN, ENABLE);
-+
-+ switch (update_time) {
-+ case CI_ISP_CFG_UPDATE_FRAME_SYNC:
-+ REG_SET_SLICE(mrv_reg->isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD,
-+ ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_IMMEDIATE:
-+ REG_SET_SLICE(mrv_reg->mi_init, MRV_MI_MI_CFG_UPD, ON);
-+ break;
-+ case CI_ISP_CFG_UPDATE_LATER:
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return error;
-+}
-+
-+/*
-+ * Configures the DMA path of the MI.
-+ *
-+ */
-+int ci_isp_mif_set_path_and_orientation(const struct ci_isp_mi_ctrl
-+ *mrv_mi_ctrl)
-+{
-+ struct isp_register *mrv_reg = (struct isp_register *) MEM_MRV_REG_BASE;
-+ int error = CI_STATUS_OUTOFRANGE;
-+ u32 mi_ctrl = 0;
-+
-+ if (!mrv_mi_ctrl) {
-+ eprintk("mrv_mi_ctrl is NULL");
-+ return CI_STATUS_NULL_POINTER;
-+ }
-+
-+ if ((mrv_mi_ctrl->irq_offs_init &
-+ ~(MRV_MI_MP_Y_IRQ_OFFS_INIT_VALID_MASK)) != 0) {
-+ eprintk("bad mrv_mi_ctrl->irq_offs_init value");
-+ return error;
-+ }
-+
-+ REG_SET_SLICE(mrv_reg->mi_mp_y_irq_offs_init,
-+ MRV_MI_MP_Y_IRQ_OFFS_INIT, mrv_mi_ctrl->irq_offs_init);
-+
-+ /* main picture path */
-+ switch (mrv_mi_ctrl->main_path) {
-+ case CI_ISP_PATH_OFF:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_MP_ENABLE, OFF);
-+ break;
-+ case CI_ISP_PATH_ON:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_MP_ENABLE, ON);
-+ break;
-+ case CI_ISP_PATH_JPE:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_JPEG_ENABLE, ON);
-+ break;
-+ case CI_ISP_PATH_RAW8:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_RAW_ENABLE, ON);
-+ break;
-+ case CI_ISP_PATH_RAW816:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_RAW_ENABLE, ON);
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
-+ MRV_MI_MP_WRITE_FORMAT_INTERLEAVED);
-+ break;
-+ default:
-+ eprintk("bad mrv_mi_ctrl->main_path value");
-+ return error;
-+ }
-+
-+ /* self picture path output format */
-+ switch (mrv_mi_ctrl->mrv_mif_sp_out_form) {
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_422:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_YUV422);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_444:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_YUV444);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_420:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_YUV420);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_400:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_YUV400);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_RGB_565:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_RGB565);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_RGB_888:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_RGB888);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_RGB_666:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
-+ MRV_MI_SP_OUTPUT_FORMAT_RGB666);
-+ break;
-+
-+ default:
-+ eprintk("bad mrv_mi_ctrl->mrv_mif_sp_out_form value");
-+ return error;
-+ }
-+
-+ /* self picture path input format */
-+ switch (mrv_mi_ctrl->mrv_mif_sp_in_form) {
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_422:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_INPUT_FORMAT,
-+ MRV_MI_SP_INPUT_FORMAT_YUV422);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_444:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_INPUT_FORMAT,
-+ MRV_MI_SP_INPUT_FORMAT_YUV444);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_420:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_INPUT_FORMAT,
-+ MRV_MI_SP_INPUT_FORMAT_YUV420);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_YCBCR_400:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_INPUT_FORMAT,
-+ MRV_MI_SP_INPUT_FORMAT_YUV400);
-+ break;
-+ case CI_ISP_MIF_COL_FORMAT_RGB_565:
-+ case CI_ISP_MIF_COL_FORMAT_RGB_666:
-+ case CI_ISP_MIF_COL_FORMAT_RGB_888:
-+ default:
-+ eprintk("bad mrv_mi_ctrl->mrv_mif_sp_in_form value");
-+ return error;
-+ }
-+
-+ error = CI_STATUS_SUCCESS;
-+
-+ /* self picture path write format */
-+ switch (mrv_mi_ctrl->mrv_mif_sp_pic_form) {
-+ case CI_ISP_MIF_PIC_FORM_PLANAR:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
-+ MRV_MI_SP_WRITE_FORMAT_PLANAR);
-+ break;
-+ case CI_ISP_MIF_PIC_FORM_SEMI_PLANAR:
-+ if ((mrv_mi_ctrl->mrv_mif_sp_out_form ==
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_422)
-+ || (mrv_mi_ctrl->mrv_mif_sp_out_form ==
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_420)) {
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
-+ MRV_MI_SP_WRITE_FORMAT_SEMIPLANAR);
-+ } else {
-+ error = CI_STATUS_NOTSUPP;
-+ }
-+ break;
-+ case CI_ISP_MIF_PIC_FORM_INTERLEAVED:
-+ if (mrv_mi_ctrl->mrv_mif_sp_out_form ==
-+ CI_ISP_MIF_COL_FORMAT_YCBCR_422) {
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
-+ MRV_MI_SP_WRITE_FORMAT_INTERLEAVED);
-+ } else {
-+ error = CI_STATUS_NOTSUPP;
-+ }
-+ break;
-+ default:
-+ error = CI_STATUS_OUTOFRANGE;
-+ break;
-+
-+ }
-+
-+ if (error != CI_STATUS_SUCCESS) {
-+ eprintk("bad mrv_mi_ctrl->mrv_mif_sp_pic_form value");
-+ return error;
-+ }
-+
-+ if (mrv_mi_ctrl->main_path == CI_ISP_PATH_ON) {
-+ /* for YCbCr mode only, permitted for raw mode */
-+ /* main picture path write format */
-+ switch (mrv_mi_ctrl->mrv_mif_mp_pic_form) {
-+ case CI_ISP_MIF_PIC_FORM_PLANAR:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
-+ MRV_MI_MP_WRITE_FORMAT_PLANAR);
-+ break;
-+ case CI_ISP_MIF_PIC_FORM_SEMI_PLANAR:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
-+ MRV_MI_MP_WRITE_FORMAT_SEMIPLANAR);
-+ break;
-+ case CI_ISP_MIF_PIC_FORM_INTERLEAVED:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
-+ MRV_MI_MP_WRITE_FORMAT_INTERLEAVED);
-+ break;
-+ default:
-+ error = CI_STATUS_OUTOFRANGE;
-+ break;
-+ }
-+ }
-+
-+ if (error != CI_STATUS_SUCCESS) {
-+ eprintk("bad mrv_mi_ctrl->mrv_mif_mp_pic_form value");
-+ return error;
-+ }
-+
-+ /* burst length for chrominance for write port */
-+ /* setting burst mode to 16 bits
-+ switch (mrv_mi_ctrl->burst_length_chrom) {
-+ case CI_ISP_MIF_BURST_LENGTH_4:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_CHROM,
-+ MRV_MI_BURST_LEN_CHROM_4);
-+ break;
-+ case CI_ISP_MIF_BURST_LENGTH_8:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_CHROM,
-+ MRV_MI_BURST_LEN_CHROM_8);
-+ break;
-+ case CI_ISP_MIF_BURST_LENGTH_16:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_CHROM,
-+ MRV_MI_BURST_LEN_CHROM_16);
-+ break;
-+ default:
-+ error = CI_STATUS_OUTOFRANGE;
-+ break;
-+ }
-+ */
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_CHROM,
-+ MRV_MI_BURST_LEN_CHROM_16);
-+
-+ if (error != CI_STATUS_SUCCESS) {
-+ eprintk("bad mrv_mi_ctrl->burst_length_chrom value");
-+ return error;
-+ }
-+
-+ /* burst length for luminance for write port */
-+ /* setting burst mode to 16 bits
-+ switch (mrv_mi_ctrl->burst_length_lum) {
-+ case CI_ISP_MIF_BURST_LENGTH_4:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_LUM,
-+ MRV_MI_BURST_LEN_LUM_4);
-+ break;
-+ case CI_ISP_MIF_BURST_LENGTH_8:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_LUM,
-+ MRV_MI_BURST_LEN_LUM_8);
-+ break;
-+ case CI_ISP_MIF_BURST_LENGTH_16:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_LUM,
-+ MRV_MI_BURST_LEN_LUM_16);
-+ break;
-+ default:
-+ error = CI_STATUS_OUTOFRANGE;
-+ break;
-+ }
-+ */
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_LUM,
-+ MRV_MI_BURST_LEN_LUM_16);
-+
-+ if (error != CI_STATUS_SUCCESS) {
-+ eprintk("bad mrv_mi_ctrl->burst_length_lum value");
-+ return error;
-+ }
-+
-+ /* enable updating of the shadow registers for main and self picture
-+ * to their init values
-+ */
-+ switch (mrv_mi_ctrl->init_vals) {
-+ case CI_ISP_MIF_NO_INIT_VALS:
-+ break;
-+ case CI_ISP_MIF_INIT_OFFS:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_INIT_OFFSET_EN, ENABLE);
-+ break;
-+ case CI_ISP_MIF_INIT_BASE:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_INIT_BASE_EN, ENABLE);
-+ break;
-+ case CI_ISP_MIF_INIT_OFFSAndBase:
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_INIT_OFFSET_EN, ENABLE);
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_INIT_BASE_EN, ENABLE);
-+ break;
-+ default:
-+ error = CI_STATUS_OUTOFRANGE;
-+ break;
-+ }
-+
-+ if (error != CI_STATUS_SUCCESS) {
-+ eprintk("bad mrv_mi_ctrl->init_vals value");
-+ return error;
-+ }
-+
-+ /* enable change of byte order for write port */
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_BYTE_SWAP,
-+ (mrv_mi_ctrl->byte_swap_enable) ? ON : OFF);
-+
-+ /* enable or disable the last pixel signalization */
-+ REG_SET_SLICE(mi_ctrl, MRV_MI_LAST_PIXEL_SIG_EN,
-+ (mrv_mi_ctrl->last_pixel_enable) ? ON : OFF);
-+
-+ /* now write settings into register */
-+ REG_WRITE(mrv_reg->mi_ctrl, mi_ctrl);
-+
-+ dprintk(2, "mi_ctrl = 0x%x", mi_ctrl);
-+
-+ /* self picture path operating mode */
-+ if ((mrv_mi_ctrl->self_path == CI_ISP_PATH_ON) ||
-+ (mrv_mi_ctrl->self_path == CI_ISP_PATH_OFF)) {
-+
-+ /* do not call if not supported */
-+
-+ /* support has been restricted to >= MI_V2 && <= MI_V3 in
-+ * ci_isp_mif_set_self_pic_orientation, so we do the same here
-+ */
-+
-+ error = ci_isp_mif_set_self_pic_orientation(
-+ mrv_mi_ctrl->mrv_mif_sp_mode,
-+ (int) (mrv_mi_ctrl->self_path
-+ == CI_ISP_PATH_ON));
-+ } else {
-+ eprintk("bad mrv_mi_ctrl->self_path value");
-+ error = CI_STATUS_OUTOFRANGE;
-+ }
-+
-+ REG_SET_SLICE(mrv_reg->mi_init, MRV_MI_MI_CFG_UPD, ON);
-+
-+ return error;
-+}
---
-1.6.0.6
-