camera: add mako camera driver imx111, imx119
Change-Id: I5451ba05023fe7cbe3442512924062e7dc63f3f4
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 8a6134f..6c38ac2 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5192,11 +5192,16 @@
CLK_LOOKUP("iface_clk", pmic_arb1_p_clk.c, ""),
CLK_LOOKUP("core_clk", pmic_ssbi2_clk.c, ""),
CLK_LOOKUP("mem_clk", rpm_msg_ram_p_clk.c, ""),
+#if defined(CONFIG_MACH_LGE)
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "4-000d"),
+ CLK_LOOKUP("cam_clk", cam2_clk.c, "4-006e"),
+#else /* QCT Original */
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-001a"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0034"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0020"),
CLK_LOOKUP("cam_clk", cam1_clk.c, "4-0048"),
CLK_LOOKUP("cam_clk", cam1_clk.c, "4-006c"),
+#endif
CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, "msm_csid.1"),
CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, "msm_csid.2"),
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index 9c791e4..affe844 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -123,6 +123,45 @@
---help---
MICRON 5M Bayer Sensor KM modules with Autofocus
+config IMX111
+ bool "Sensor IMX111 (Sony 8MP)"
+ depends on MSM_CAMERA
+ select IMX111_ACT
+ default n
+ ---help---
+ Sony 8M Bayer Sensor modules with Autofocus
+
+config IMX111_ACT
+ bool "Actuator imx111 (BAYER 8M)"
+ depends on MSM_CAMERA
+ select MSM_ACTUATOR
+ default n
+ ---help---
+ Actuator for SONY 8 MP Bayer Sensor
+
+config IMX091
+ bool "Sensor IMX091 (Sony 13MP)"
+ depends on MSM_CAMERA
+ select IMX091_ACT
+ default n
+ ---help---
+ Sony 13M Bayer Sensor modules with Autofocus
+
+config IMX091_ACT
+ bool "Actuator imx091 (BAYER 13M)"
+ depends on MSM_CAMERA
+ select MSM_ACTUATOR
+ default n
+ ---help---
+ Actuator for SONY 13MP Bayer Sensor
+
+config IMX119
+ bool "Sensor IMX119 1.3MP MIPI (Bayer 1.3M)"
+ depends on MSM_CAMERA
+ default n
+ ---help---
+ SONY 1.3M BAYER MIPI Sensor without Autofocus
+
config MT9E013
bool "Sensor mt9e013 module (BAYER 8M)"
depends on MSM_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM7X27A)
@@ -130,6 +169,13 @@
---help---
Aptina 8M Bayer Sensor modules with Autofocus
+config MSM_CAMERA_FLASH_LM3559
+ bool "Qualcomm MSM camera lm3559 flash support"
+ depends on MSM_CAMERA
+ default y
+ ---help---
+ Enable support for LED flash for msm camera.
+
config IMX074_ACT
bool "Actuator IMX074 (BAYER 13.5M)"
depends on MSM_CAMERA
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 95e1b0e..3509b27 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -153,11 +153,14 @@
/* message id for v4l2_subdev_notify*/
enum msm_camera_v4l2_subdev_notify {
+ NOTIFY_CID_CHANGE, /* arg = msm_camera_csid_params */
NOTIFY_ISP_MSG_EVT, /* arg = enum ISP_MESSAGE_ID */
NOTIFY_VFE_MSG_OUT, /* arg = struct isp_msg_output */
NOTIFY_VFE_MSG_STATS, /* arg = struct isp_msg_stats */
NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
+ NOTIFY_ISPIF_STREAM, /* arg = enable parameter for s_stream */
+ NOTIFY_VPE_MSG_EVT,
NOTIFY_PCLK_CHANGE, /* arg = pclk */
NOTIFY_CSIPHY_CFG, /* arg = msm_camera_csiphy_params */
NOTIFY_CSID_CFG, /* arg = msm_camera_csid_params */
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index abcee4b..87da486 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -486,6 +486,70 @@
return rc;
}
+int msm_mctl_pp_notify(struct msm_cam_media_controller *p_mctl,
+ struct msm_mctl_pp_frame_info *pp_frame_info)
+{
+ struct msm_mctl_pp_frame_cmd *pp_frame_cmd;
+ pp_frame_cmd = &pp_frame_info->pp_frame_cmd;
+
+ D("%s: msm_cam_evt_divert_frame=%d",
+ __func__, sizeof(struct msm_mctl_pp_event_info));
+ if ((MSM_MCTL_PP_VPE_FRAME_TO_APP &
+ pp_frame_cmd->vpe_output_action)) {
+ struct msm_free_buf done_frame;
+ int img_mode =
+ msm_mctl_pp_path_to_img_mode(
+ pp_frame_cmd->path);
+ if (img_mode < 0) {
+ pr_err("%s Invalid image mode\n", __func__);
+ return img_mode;
+ }
+ done_frame.ch_paddr[0] =
+ pp_frame_info->dest_frame.sp.phy_addr;
+ done_frame.vb =
+ pp_frame_info->dest_frame.handle;
+ msm_mctl_buf_done_pp(
+ p_mctl, img_mode, &done_frame, 0, 0);
+ D("%s: vpe done to app, vb=0x%x, path=%d, phy=0x%x",
+ __func__, done_frame.vb,
+ pp_frame_cmd->path, done_frame.ch_paddr[0]);
+ }
+ if ((MSM_MCTL_PP_VPE_FRAME_ACK &
+ pp_frame_cmd->vpe_output_action)) {
+ struct v4l2_event v4l2_evt;
+ struct msm_mctl_pp_event_info *pp_event_info;
+ struct msm_isp_event_ctrl *isp_event;
+ isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl),
+ GFP_ATOMIC);
+ if (!isp_event) {
+ pr_err("%s Insufficient memory.", __func__);
+ return -ENOMEM;
+ }
+ memset(&v4l2_evt, 0, sizeof(v4l2_evt));
+ *((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event;
+
+ /* Get hold of pp event info struct inside event ctrl.*/
+ pp_event_info = &(isp_event->isp_data.pp_event_info);
+
+ pp_event_info->event = MCTL_PP_EVENT_CMD_ACK;
+ pp_event_info->ack.cmd = pp_frame_info->user_cmd;
+ pp_event_info->ack.status = 0;
+ pp_event_info->ack.cookie = pp_frame_cmd->cookie;
+ v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_RESP_MCTL_PP_EVENT;
+
+ v4l2_event_queue(
+ p_mctl->config_device->
+ config_stat_event_queue.pvdev,
+ &v4l2_evt);
+ D("%s: ack to daemon, cookie=0x%x, event = 0x%x",
+ __func__, pp_frame_info->pp_frame_cmd.cookie,
+ v4l2_evt.type);
+ }
+ kfree(pp_frame_info); /* free mem */
+ return 0;
+}
+
int msm_mctl_pp_reserve_free_frame(
struct msm_cam_media_controller *p_mctl,
void __user *arg)
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index 5f3f6dd..bedc5ad 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -15,4 +15,6 @@
obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
obj-$(CONFIG_OV7692) += ov7692_v4l2.o
+obj-$(CONFIG_IMX111) += imx111.o
+obj-$(CONFIG_IMX119) += imx119_v4l2.o
obj-$(CONFIG_VX6953) += vx6953.o
diff --git a/drivers/media/video/msm/sensors/imx091.c b/drivers/media/video/msm/sensors/imx091.c
index 7fda037..6d708ed 100644
--- a/drivers/media/video/msm/sensors/imx091.c
+++ b/drivers/media/video/msm/sensors/imx091.c
@@ -35,6 +35,59 @@
};
static struct msm_camera_i2c_reg_conf imx091_prev_settings[] = {
+#ifdef CONFIG_MACH_LGE
+ {0x0307, 0x2F},
+ {0x303C, 0x4B},
+ {0x0340, 0x06},
+ {0x0341, 0x46},
+ {0x0346, 0x00},
+ {0x0347, 0x30},
+ {0x034A, 0x0C},
+ {0x034B, 0x5F},
+ {0x034C, 0x08},
+ {0x034D, 0x38},
+ {0x034E, 0x06},
+ {0x034F, 0x18},
+ {0x0381, 0x01},
+ {0x0383, 0x03},
+ {0x0385, 0x01},
+ {0x0387, 0x03},
+ {0x3048, 0x01},
+ {0x3064, 0x12},
+ {0x309B, 0x28},
+ {0x309E, 0x00},
+ {0x30D5, 0x09},
+ {0x30D6, 0x01},
+ {0x30D7, 0x01},
+ {0x30D8, 0x64},
+ {0x30D9, 0x89},
+ {0x30DE, 0x02},
+ {0x3102, 0x10},
+ {0x3103, 0x44},
+ {0x3104, 0x40},
+ {0x3105, 0x00},
+ {0x3106, 0x0D},
+ {0x3107, 0x01},
+ {0x310A, 0x0A},
+ {0x315C, 0x99},
+ {0x315D, 0x98},
+ {0x316E, 0x9A},
+ {0x316F, 0x99},
+ {0x3304, 0x05},
+ {0x3305, 0x04},
+ {0x3306, 0x12},
+ {0x3307, 0x03},
+ {0x3308, 0x0D},
+ {0x3309, 0x05},
+ {0x330A, 0x09},
+ {0x330B, 0x04},
+ {0x330C, 0x08},
+ {0x330D, 0x05},
+ {0x330E, 0x03},
+ {0x3318, 0x73},
+ {0x3322, 0x02},
+ {0x3342, 0x0F},
+#else
/* 30fps 1/2 * 1/2 */
/* PLL setting */
{0x0305, 0x02}, /* pre_pll_clk_div[7:0] */
@@ -86,11 +139,65 @@
{0x316E, 0x9A},
{0x316F, 0x99},
{0x3318, 0x73},
+#endif
};
static struct msm_camera_i2c_reg_conf imx091_snap_settings[] = {
/* full size */
/* PLL setting */
+#ifdef CONFIG_MACH_LGE
+ {0x0307, 0x2F}, //pll mul 47
+ {0x303C, 0x4B}, //mclk 24M
+ {0x0340, 0x0C}, //Frame length 3212
+ {0x0341, 0x8C},
+ {0x0346, 0x00}, // y start
+ {0x0347, 0x30},
+ {0x034A, 0x0C}, // y end
+ {0x034B, 0x5F},
+ {0x034C, 0x10}, // x output 4208
+ {0x034D, 0x70},
+ {0x034E, 0x0C}, // y output 3120
+ {0x034F, 0x30},
+ {0x0381, 0x01}, // x even inc
+ {0x0383, 0x01}, // x odd inc
+ {0x0385, 0x01}, //y even inc
+ {0x0387, 0x01}, // y odd inc
+ {0x3048, 0x00},
+ {0x3064, 0x12},
+ {0x309B, 0x20},
+ {0x309E, 0x00},
+ {0x30D5, 0x00},
+ {0x30D6, 0x85},
+ {0x30D7, 0x2A},
+ {0x30D8, 0x64},
+ {0x30D9, 0x89},
+ {0x30DE, 0x00},
+ {0x3102, 0x10},
+ {0x3103, 0x44},
+ {0x3104, 0x40},
+ {0x3105, 0x00},
+ {0x3106, 0x0D},
+ {0x3107, 0x01},
+ {0x310A, 0x0A},
+ {0x315C, 0x99},
+ {0x315D, 0x98},
+ {0x316E, 0x9A},
+ {0x316F, 0x99},
+ {0x3304, 0x05},
+ {0x3305, 0x04},
+ {0x3306, 0x12},
+ {0x3307, 0x03},
+ {0x3308, 0x0D},
+ {0x3309, 0x05},
+ {0x330A, 0x09},
+ {0x330B, 0x04},
+ {0x330C, 0x08},
+ {0x330D, 0x05},
+ {0x330E, 0x03},
+ {0x3318, 0x64},
+ {0x3322, 0x02},
+ {0x3342, 0x0F},
+#else
{0x0305, 0x02}, /* pre_pll_clk_div[7:0] */
{0x0307, 0x2B}, /* pll_multiplier[7:0] */
{0x30A4, 0x02},
@@ -140,6 +247,7 @@
{0x316E, 0x9A},
{0x316F, 0x99},
{0x3318, 0x64},
+#endif
};
static struct msm_camera_i2c_reg_conf imx091_recommend_settings[] = {
@@ -201,7 +309,11 @@
.x_output = 0x0838, /* 2104 */
.y_output = 0x0618, /* 1560 */
.line_length_pclk = 0x120C, /* 4620 */
+#ifdef CONFIG_MACH_LGE
+ .frame_length_lines = 0x0646, //1606,
+#else
.frame_length_lines = 0x065A, /* 1626 */
+#endif
.vt_pixel_clk = 225600000,
.op_pixel_clk = 225600000,
.binning_factor = 1,
@@ -343,5 +455,5 @@
};
module_init(imx091_sensor_init_module);
-MODULE_DESCRIPTION("SONY 12MP Bayer sensor driver");
+MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/imx111.c b/drivers/media/video/msm/sensors/imx111.c
new file mode 100644
index 0000000..1771b4c
--- /dev/null
+++ b/drivers/media/video/msm/sensors/imx111.c
@@ -0,0 +1,869 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 and
+ * only 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.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "msm.h"
+#include "msm_ispif.h"
+#define SENSOR_NAME "imx111"
+#define PLATFORM_DRIVER_NAME "msm_camera_imx111"
+#define imx111_obj imx111_##obj
+
+DEFINE_MUTEX(imx111_mut);
+static struct msm_sensor_ctrl_t imx111_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf imx111_start_settings[] = {
+ {0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_stop_settings[] = {
+ {0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_groupon_settings[] = {
+ {0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_groupoff_settings[] = {
+ {0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_prev_settings[] = {
+ {0x0101, 0x00}, /* read out direction */
+ {0x0305, 0x02},
+ {0x0307, 0x38},
+ {0x30A4, 0x02},
+ {0x303C, 0x4B},
+// randy added : s
+ {0x0202, 0x03},
+ {0x0203, 0xCE},
+ {0x0204, 0x00},
+ {0x0205, 0xC0},
+// randy added : e
+ {0x0340, 0x04},
+ {0x0341, 0xE6},
+ {0x0342, 0x0D},
+ {0x0343, 0xD0},
+ {0x0344, 0x00},
+ {0x0345, 0x08},
+ {0x0346, 0x00},
+ {0x0347, 0x30},
+ {0x0348, 0x0C},
+ {0x0349, 0xD7},
+ {0x034A, 0x09},
+ {0x034B, 0xCF},
+ {0x034C, 0x06},
+ {0x034D, 0x68},
+ {0x034E, 0x04},
+ {0x034F, 0xD0},
+ {0x0381, 0x01},
+ {0x0383, 0x03},
+ {0x0385, 0x01},
+ {0x0387, 0x03},
+ {0x3033, 0x00},
+ {0x303D, 0x10},
+ {0x303E, 0x40},
+ {0x3040, 0x08},
+ {0x3041, 0x97},
+ {0x3048, 0x01},
+ {0x304C, 0x6F},
+ {0x304D, 0x03},
+ {0x3064, 0x12},
+ {0x3073, 0x00},
+ {0x3074, 0x11},
+ {0x3075, 0x11},
+ {0x3076, 0x11},
+ {0x3077, 0x11},
+ {0x3079, 0x00},
+ {0x307A, 0x00},
+ {0x309B, 0x28},
+ {0x309E, 0x00},
+ {0x30A0, 0x14},
+ {0x30A1, 0x09},
+ {0x30AA, 0x03},
+ {0x30B2, 0x05},
+ {0x30D5, 0x09},
+ {0x30D6, 0x01},
+ {0x30D7, 0x01},
+ {0x30D8, 0x64},
+ {0x30D9, 0x89},
+ {0x30DE, 0x02},
+ {0x30DF, 0x20},
+ {0x3102, 0x08},
+ {0x3103, 0x22},
+ {0x3104, 0x20},
+ {0x3105, 0x00},
+ {0x3106, 0x87},
+ {0x3107, 0x00},
+ {0x3108, 0x03},
+ {0x3109, 0x02},
+ {0x310A, 0x03},
+ {0x315C, 0x9C},
+ {0x315D, 0x9B},
+ {0x316E, 0x9D},
+ {0x316F, 0x9C},
+ {0x3318, 0x72},
+ {0x3348, 0xE0},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_video_settings[] = {
+ {0x0101, 0x00}, /* read out direction */
+ {0x0305, 0x02},
+ {0x0307, 0x32},
+ {0x30A4, 0x02},
+ {0x303C, 0x4B},
+// {0x0340, 0x07}, /* randy blocked*/
+// {0x0341, 0x5C},
+ {0x0342, 0x0D},
+ {0x0343, 0xAC},
+ {0x0344, 0x00},
+ {0x0345, 0x16},
+ {0x0346, 0x01},
+ {0x0347, 0x6E},
+ {0x0348, 0x0C},
+ {0x0349, 0xCB},
+ {0x034A, 0x08},
+ {0x034B, 0x93},
+ {0x034C, 0x07},
+ {0x034D, 0xA0},
+ {0x034E, 0x04},
+ {0x034F, 0x4A},
+ {0x0381, 0x01},
+ {0x0383, 0x01},
+ {0x0385, 0x01},
+ {0x0387, 0x01},
+ {0x3033, 0x00},
+ {0x303D, 0x10},
+ {0x303E, 0x00},
+ {0x3040, 0x08},
+ {0x3041, 0x91},
+ {0x3048, 0x00},
+ {0x304C, 0x67},
+ {0x304D, 0x03},
+ {0x3064, 0x10},
+ {0x3073, 0xA0},
+ {0x3074, 0x12},
+ {0x3075, 0x12},
+ {0x3076, 0x12},
+ {0x3077, 0x11},
+ {0x3079, 0x0A},
+ {0x307A, 0x0A},
+ {0x309B, 0x60},
+ {0x309E, 0x04},
+ {0x30A0, 0x15},
+ {0x30A1, 0x08},
+ {0x30AA, 0x03},
+ {0x30B2, 0x05},
+ {0x30D5, 0x20},
+ {0x30D6, 0x85},
+ {0x30D7, 0x2A},
+ {0x30D8, 0x64},
+ {0x30D9, 0x89},
+ {0x30DE, 0x00},
+ {0x30DF, 0x21},
+ {0x3102, 0x08},
+ {0x3103, 0x1D},
+ {0x3104, 0x1E},
+ {0x3105, 0x00},
+ {0x3106, 0x74},
+ {0x3107, 0x00},
+ {0x3108, 0x03},
+ {0x3109, 0x02},
+ {0x310A, 0x03},
+ {0x315C, 0x37},
+ {0x315D, 0x36},
+ {0x316E, 0x38},
+ {0x316F, 0x37},
+ {0x3318, 0x63},
+ {0x3348, 0xA0},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_snap_settings[] = {
+ {0x0101, 0x00}, /* read out direction */
+ {0x0305, 0x02},
+ {0x0307, 0x53},
+ {0x30A4, 0x02},
+ {0x303C, 0x4B},
+// randy added : s
+ {0x0202, 0x04},
+ {0x0203, 0xEC},
+ {0x0204, 0x00},
+ {0x0205, 0xAC},
+// randy added : e
+ {0x0340, 0x09},
+ {0x0341, 0xBA},
+ {0x0342, 0x0D},
+ {0x0343, 0xD0},
+ {0x0344, 0x00},
+ {0x0345, 0x08},
+ {0x0346, 0x00},
+ {0x0347, 0x30},
+ {0x0348, 0x0C},
+ {0x0349, 0xD7},
+ {0x034A, 0x09},
+ {0x034B, 0xCF},
+ {0x034C, 0x0C},
+ {0x034D, 0xD0},
+ {0x034E, 0x09},
+ {0x034F, 0xA0},
+ {0x0381, 0x01},
+ {0x0383, 0x01},
+ {0x0385, 0x01},
+ {0x0387, 0x01},
+ {0x3033, 0x00},
+ {0x303D, 0x00},
+ {0x303E, 0x41},
+ {0x3040, 0x08},
+ {0x3041, 0x97},
+ {0x3048, 0x00},
+ {0x304C, 0x6F},
+ {0x304D, 0x03},
+ {0x3064, 0x12},
+ {0x3073, 0x00},
+ {0x3074, 0x11},
+ {0x3075, 0x11},
+ {0x3076, 0x11},
+ {0x3077, 0x11},
+ {0x3079, 0x00},
+ {0x307A, 0x00},
+ {0x309B, 0x20},
+ {0x309E, 0x00},
+ {0x30A0, 0x14},
+ {0x30A1, 0x08},
+ {0x30AA, 0x03},
+ {0x30B2, 0x07},
+ {0x30D5, 0x00},
+ {0x30D6, 0x85},
+ {0x30D7, 0x2A},
+ {0x30D8, 0x64},
+ {0x30D9, 0x89},
+ {0x30DE, 0x00},
+ {0x30DF, 0x20},
+ {0x3102, 0x10},
+ {0x3103, 0x44},
+ {0x3104, 0x40},
+ {0x3105, 0x00},
+ {0x3106, 0x0D},
+ {0x3107, 0x01},
+ {0x3108, 0x09},
+ {0x3109, 0x08},
+ {0x310A, 0x0F},
+ {0x315C, 0x5D},
+ {0x315D, 0x5C},
+ {0x316E, 0x5E},
+ {0x316F, 0x5D},
+ {0x3318, 0x60},
+ {0x3348, 0xE0},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_recommend_settings[] = {
+ {0x3080, 0x50},
+ {0x3087, 0x53},
+ {0x309D, 0x94},
+ {0x30B1, 0x03},
+ {0x30C6, 0x00},
+ {0x30C7, 0x00},
+ {0x3115, 0x0B},
+ {0x3118, 0x30},
+ {0x311D, 0x25},
+ {0x3121, 0x0A},
+ {0x3212, 0xF2},
+ {0x3213, 0x0F},
+ {0x3215, 0x0F},
+ {0x3217, 0x0B},
+ {0x3219, 0x0B},
+ {0x321B, 0x0D},
+ {0x321D, 0x0D},
+ {0x32AA, 0x11},
+ {0x3032, 0x40},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_comm1_settings[] = {
+ {0x3035, 0x10},
+ {0x303B, 0x14},
+ {0x3312, 0x45},
+ {0x3313, 0xC0},
+ {0x3310, 0x20},
+ {0x3310, 0x00},
+ {0x303B, 0x04},
+ {0x303D, 0x00},
+ {0x0100, 0x10},
+ {0x3035, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_comm2_part1_settings[] = {
+ {0x0307, 0x53},
+ {0x0340, 0x09},
+ {0x0341, 0xBA},
+ {0x034C, 0x0C},
+ {0x034D, 0xD0},
+ {0x034E, 0x09},
+ {0x034F, 0xA0},
+ {0x0383, 0x01},
+ {0x0387, 0x01},
+ {0x303D, 0x00},
+ {0x303E, 0x41},
+ {0x3048, 0x00},
+ {0x309B, 0x20},
+ {0x30A1, 0x08},
+ {0x30D5, 0x00},
+ {0x30D6, 0x85},
+ {0x30D7, 0x2A},
+ {0x30DE, 0x00},
+ {0x3102, 0x10},
+ {0x3103, 0x44},
+ {0x3104, 0x40},
+ {0x3106, 0x0D},
+ {0x3107, 0x01},
+ {0x3108, 0x09},
+ {0x3109, 0x08},
+ {0x310A, 0x0F},
+ {0x315C, 0x5D},
+ {0x315D, 0x5C},
+ {0x316E, 0x5E},
+ {0x316F, 0x5D},
+ {0x3318, 0x60},
+};
+
+static struct msm_camera_i2c_reg_conf imx111_comm2_part2_settings[] = {
+ {0x30B1, 0x43},
+ {0x3311, 0x80},
+ {0x3311, 0x00},
+};
+
+static struct msm_camera_i2c_conf_array imx111_comm_confs[] = {
+ {&imx111_comm1_settings[0],
+ ARRAY_SIZE(imx111_comm1_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx111_comm2_part1_settings[0],
+ ARRAY_SIZE(imx111_comm2_part1_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx111_comm2_part2_settings[0],
+ ARRAY_SIZE(imx111_comm2_part2_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct v4l2_subdev_info imx111_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+ /* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array imx111_init_conf[] = {
+ {&imx111_recommend_settings[0],
+ ARRAY_SIZE(imx111_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array imx111_confs[] = {
+ {&imx111_snap_settings[0],
+ ARRAY_SIZE(imx111_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx111_prev_settings[0],
+ ARRAY_SIZE(imx111_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx111_video_settings[0],
+ ARRAY_SIZE(imx111_video_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&imx111_snap_settings[0],
+ ARRAY_SIZE(imx111_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t imx111_dimensions[] = {
+ {
+ /* 22.5 fps */
+ .x_output = 0x0CD0, /* 3280 */
+ .y_output = 0x9A0, /* 2464 */
+ .line_length_pclk = 0xDD0, /* 3536 */
+ .frame_length_lines = 0x9D4, /* 2490 */
+ .vt_pixel_clk = 199200000,
+ .op_pixel_clk = 199200000,
+ },
+ {
+ /* 30 fps preview */
+ .x_output = 0x668, /* 1640 */
+ .y_output = 0x4D0, /* 1232 */
+ .line_length_pclk = 0xDD0, /* 3536 */
+ .frame_length_lines = 0x4E6, /* 1254 */
+ .vt_pixel_clk = 134400000,
+ .op_pixel_clk = 134400000,
+ },
+ {
+ /* 30 fps video */
+ .x_output = 0x7A0,
+ .y_output = 0x44A,
+ .line_length_pclk = 0xDAC,
+ .frame_length_lines = 0x75C,
+ .vt_pixel_clk = 200000000,
+ .op_pixel_clk = 200000000,
+ },
+ {
+ /* 22.5 fps */
+ .x_output = 0x0CD0, /* 3280 */
+ .y_output = 0x9A0, /* 2464 */
+ .line_length_pclk = 0xDD0, /* 3536 */
+ .frame_length_lines = 0x9D4, /* 2516 */
+ .vt_pixel_clk = 199200000,
+ .op_pixel_clk = 199200000,
+ },
+};
+
+static struct msm_camera_csid_vc_cfg imx111_cid_cfg[] = {
+ {0, CSI_RAW10, CSI_DECODE_10BIT},
+ {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
+};
+
+static struct msm_camera_csi2_params imx111_csi_params = {
+ .csid_params = {
+ .lane_assign = 0xe4,
+ .lane_cnt = 2,
+ .lut_params = {
+ .num_cid = 3,
+ .vc_cfg = imx111_cid_cfg,
+ },
+ },
+ .csiphy_params = {
+ .lane_cnt = 2,
+ //.settle_cnt = 0x14,
+ .settle_cnt = 0x12,
+ },
+};
+
+static struct msm_camera_csi2_params *imx111_csi_params_array[] = {
+ &imx111_csi_params,
+ &imx111_csi_params,
+ &imx111_csi_params,
+ &imx111_csi_params,
+};
+
+static struct msm_sensor_output_reg_addr_t imx111_reg_addr = {
+ .x_output = 0x34C,
+ .y_output = 0x34E,
+ .line_length_pclk = 0x342,
+ .frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t imx111_id_info = {
+ .sensor_id_reg_addr = 0x0,
+ .sensor_id = 0x0111,
+};
+
+static struct msm_sensor_exp_gain_info_t imx111_exp_gain_info = {
+ .coarse_int_time_addr = 0x202,
+ .global_gain_addr = 0x204,
+ .vert_offset = 5,
+};
+
+
+static const struct i2c_device_id imx111_i2c_id[] = {
+ {SENSOR_NAME, (kernel_ulong_t)&imx111_s_ctrl},
+ { }
+};
+
+static struct i2c_driver imx111_i2c_driver = {
+ .id_table = imx111_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client imx111_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+ pr_err("__jrchoi: %s: E\n", __func__);
+ return i2c_add_driver(&imx111_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops imx111_subdev_core_ops = {
+ .ioctl = msm_sensor_subdev_ioctl,
+ .s_power = msm_sensor_power,
+};
+
+int32_t imx111_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+ int update_type, int res)
+{
+ int32_t rc = 0;
+
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
+ PIX_0, ISPIF_OFF_IMMEDIATELY));
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+ msleep(30);
+ if (update_type == MSM_SENSOR_REG_INIT) {
+ s_ctrl->curr_csi_params = NULL;
+ msm_sensor_enable_debugfs(s_ctrl);
+ msm_sensor_write_init_settings(s_ctrl);
+ } else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+ if (res == 0) {
+ msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
+ (struct msm_camera_i2c_reg_conf *)
+ imx111_comm_confs[0].conf,
+ imx111_comm_confs[0].size,
+ imx111_comm_confs[0].data_type);
+ } else {
+ msm_sensor_write_res_settings(s_ctrl, res);
+ if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
+ s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
+ s_ctrl->curr_csi_params->csid_params.lane_assign =
+ s_ctrl->sensordata->sensor_platform_info->
+ csi_lane_params->csi_lane_assign;
+ s_ctrl->curr_csi_params->csiphy_params.lane_mask =
+ s_ctrl->sensordata->sensor_platform_info->
+ csi_lane_params->csi_lane_mask;
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CSID_CFG,
+ &s_ctrl->curr_csi_params->csid_params);
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CID_CHANGE, NULL);
+ mb();
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CSIPHY_CFG,
+ &s_ctrl->curr_csi_params->csiphy_params);
+ mb();
+ msleep(20);
+ }
+
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
+ output_settings[res].op_pixel_clk);
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
+ PIX_0, ISPIF_ON_FRAME_BOUNDARY));
+ s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
+ msleep(30);
+ }
+ }
+ printk("%s: X", __func__);
+ return rc;
+}
+
+int32_t imx111_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
+ struct fps_cfg *fps)
+{
+ uint16_t total_lines_per_frame;
+ int32_t rc = 0;
+ s_ctrl->fps_divider = fps->fps_div;
+
+ if (s_ctrl->curr_res != MSM_SENSOR_INVALID_RES) {
+ uint16_t fl_read = 0;
+ total_lines_per_frame = (uint16_t)
+ ((s_ctrl->curr_frame_length_lines) *
+ s_ctrl->fps_divider/Q10);
+
+ rc = msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
+ &fl_read, MSM_CAMERA_I2C_WORD_DATA);
+
+ CDBG("%s: before_fl = %d, new_fl = %d", __func__, fl_read, total_lines_per_frame);
+
+ if(fl_read < total_lines_per_frame) {
+ pr_err("%s: Write new_fl (before_fl = %d, new_fl = %d)", __func__, fl_read, total_lines_per_frame);
+ rc = msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
+ total_lines_per_frame, MSM_CAMERA_I2C_WORD_DATA);
+ }
+ }
+ return rc;
+}
+
+int32_t imx111_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
+ uint16_t gain, uint32_t line)
+{
+ uint32_t fl_lines;
+ uint8_t offset;
+ fl_lines = s_ctrl->curr_frame_length_lines;
+ fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+ offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+ if (line > (fl_lines - offset))
+ fl_lines = line + offset;
+
+ CDBG("\n%s:Gain:%d, Linecount:%d\n", __func__, gain, line);
+ if (s_ctrl->curr_res == 0) {
+ msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
+ (struct msm_camera_i2c_reg_conf *)
+ imx111_comm_confs[1].conf,
+ imx111_comm_confs[1].size,
+ imx111_comm_confs[1].data_type);
+
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
+ fl_lines, MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+ line, MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+ MSM_CAMERA_I2C_WORD_DATA);
+
+ msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
+ (struct msm_camera_i2c_reg_conf *)
+ imx111_comm_confs[2].conf,
+ imx111_comm_confs[2].size,
+ imx111_comm_confs[2].data_type);
+
+ if (s_ctrl->curr_csi_params !=
+ s_ctrl->csi_params[s_ctrl->curr_res]) {
+ s_ctrl->curr_csi_params =
+ s_ctrl->csi_params[s_ctrl->curr_res];
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CSID_CFG,
+ &s_ctrl->curr_csi_params->csid_params);
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CID_CHANGE, NULL);
+ mb();
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CSIPHY_CFG,
+ &s_ctrl->curr_csi_params->csiphy_params);
+ mb();
+ msleep(20);
+ }
+
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
+ output_settings[s_ctrl->curr_res].op_pixel_clk);
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
+ PIX_0, ISPIF_ON_FRAME_BOUNDARY));
+ s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
+ } else {
+ s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
+ fl_lines, MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+ line, MSM_CAMERA_I2C_WORD_DATA);
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+ MSM_CAMERA_I2C_WORD_DATA);
+ s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+ }
+
+ return 0;
+}
+
+#define IMX111_EEPROM_SADDR 0x50
+#define IMX111_EEPROM_PAGE_SIZE 0x100
+#define RED_START 0x0A
+#define GR_START 0xE7
+#define GB_START 0xC4
+#define BLUE_START 0xA1
+#define CRC_ADDR 0x7E
+#define R_REF_ADDR 0x80
+int32_t imx_i2c_read_eeprom_burst(unsigned char saddr,
+ unsigned char *rxdata, int length)
+{
+ int32_t rc = 0;
+ unsigned char tmp_buf = 0;
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = 1,
+ .buf = &tmp_buf,
+ },
+ {
+ .addr = saddr,
+ .flags = I2C_M_RD,
+ .len = length,
+ .buf = rxdata,
+ },
+ };
+ rc = i2c_transfer(imx111_s_ctrl.sensor_i2c_client->client->adapter, msgs, 2);
+ if (rc < 0)
+ pr_err("imx111_i2c_rxdata failed 0x%x\n", saddr);
+ return rc;
+}
+
+static int imx111_read_eeprom_data(struct msm_sensor_ctrl_t *s_ctrl, struct sensor_cfg_data *cfg)
+{
+ int32_t rc = 0;
+ uint8_t eepromdata[IMX111_EEPROM_PAGE_SIZE];
+ uint32_t crc_5100= 0 /*, crc_2850 = 0*/;
+ int i;
+
+ printk("%s: E\n", __func__);
+
+ memset(eepromdata, 0, sizeof(eepromdata));
+ // for LSC data
+ if(imx_i2c_read_eeprom_burst(IMX111_EEPROM_SADDR | 0x0 /* page_no:0 */,
+ eepromdata, IMX111_EEPROM_PAGE_SIZE) < 0) {
+ pr_err("%s: Error Reading EEPROM : page_no:0 \n", __func__);
+ return rc;
+ }
+ // for AWB data
+ cfg->cfg.calib_info.r_over_g = (eepromdata[1]<<8) |eepromdata[0];
+ printk("[QCTK_EEPROM] r_over_g = 0x%4x\n", cfg->cfg.calib_info.r_over_g);
+ cfg->cfg.calib_info.b_over_g = (eepromdata[3]<<8) |eepromdata[2];
+ printk("[QCTK_EEPROM] b_over_g = 0x%4x\n", cfg->cfg.calib_info.b_over_g);
+ cfg->cfg.calib_info.gr_over_gb = (eepromdata[5]<<8) |eepromdata[4];
+ printk("[QCTK_EEPROM] gr_over_gb = 0x%4x\n", cfg->cfg.calib_info.gr_over_gb);
+
+ for (i = 0; i < ROLLOFF_CALDATA_SIZE; i++) {
+ cfg->cfg.calib_info.rolloff.r_gain[i] = eepromdata[RED_START + i];
+ crc_5100 += eepromdata[RED_START + i];
+ //printk("[QCTK_EEPROM] R (0x%x, %d)\n", RED_START + i, eepromdata[RED_START + i]);
+ }
+
+ for (i = 0; i < IMX111_EEPROM_PAGE_SIZE - GR_START; i++) {
+ cfg->cfg.calib_info.rolloff.gr_gain[i] = eepromdata[GR_START + i];
+ crc_5100 += eepromdata[GR_START + i];
+ //printk("[QCTK_EEPROM] GR (0x%x, %d)\n", GR_START + i, eepromdata[GR_START + i]);
+ }
+
+ memset(eepromdata, 0, sizeof(eepromdata));
+ if(imx_i2c_read_eeprom_burst(IMX111_EEPROM_SADDR | 0x1 /* page_no:1 */,
+ eepromdata, IMX111_EEPROM_PAGE_SIZE) < 0) {
+ pr_err("%s: Error Reading EEPROM : page_no:1 \n", __func__);
+ return rc;
+ }
+
+ // rolloff_size : 221, Gr_start: 231, eep_page_size: 256
+ // i < 221 +231 - 256 (= 196) ==> in 2nd page of eeprom
+ for (i = 0; i < ROLLOFF_CALDATA_SIZE + GR_START - IMX111_EEPROM_PAGE_SIZE; i++) {
+ cfg->cfg.calib_info.rolloff.gr_gain[IMX111_EEPROM_PAGE_SIZE - GR_START + i] = eepromdata[i];
+ crc_5100 += eepromdata[i];
+ //printk("[QCTK_EEPROM] GR (0x%x, %d)\n", i, eepromdata[i]);
+ }
+
+ for (i = 0; i < IMX111_EEPROM_PAGE_SIZE - GB_START; i++) {
+ cfg->cfg.calib_info.rolloff.gb_gain[i] = eepromdata[GB_START + i];
+ crc_5100 += eepromdata[GB_START + i];
+ //printk("[QCTK_EEPROM] GB (0x%x, %d)\n", GB_START + i, eepromdata[GB_START + i]);
+ }
+
+ memset(eepromdata, 0, sizeof(eepromdata));
+ if(imx_i2c_read_eeprom_burst(IMX111_EEPROM_SADDR | 0x2 /* page_no:2 */,
+ eepromdata, IMX111_EEPROM_PAGE_SIZE) < 0) {
+ pr_err("%s: Error Reading EEPROM : page_no:2 \n", __func__);
+ return rc;
+ }
+ for (i = 0; i < ROLLOFF_CALDATA_SIZE + GB_START - IMX111_EEPROM_PAGE_SIZE; i++) {
+ cfg->cfg.calib_info.rolloff.gb_gain[IMX111_EEPROM_PAGE_SIZE - GB_START + i] = eepromdata[i];
+ crc_5100 += eepromdata[i];
+ //printk("[QCTK_EEPROM] GB (0x%x, %d)\n", i, eepromdata[i]);
+ }
+
+ for (i = 0; i < IMX111_EEPROM_PAGE_SIZE - BLUE_START; i++) {
+ cfg->cfg.calib_info.rolloff.b_gain[i] = eepromdata[BLUE_START + i];
+ crc_5100 += eepromdata[BLUE_START + i];
+ //printk("[QCTK_EEPROM] B (0x%x, %d)\n", BLUE_START + i, eepromdata[BLUE_START + i]);
+ }
+
+ memset(eepromdata, 0, sizeof(eepromdata));
+ if(imx_i2c_read_eeprom_burst(IMX111_EEPROM_SADDR | 0x3 /* page_no:3 */,
+ eepromdata, ROLLOFF_CALDATA_SIZE + BLUE_START - IMX111_EEPROM_PAGE_SIZE + 4 /*checksum*/ + 17 /*red_ref*/) < 0) {
+ pr_err("%s: Error Reading EEPROM : page_no:3 \n", __func__);
+ return rc;
+ }
+ for (i = 0; i < ROLLOFF_CALDATA_SIZE + BLUE_START - IMX111_EEPROM_PAGE_SIZE; i++) {
+ cfg->cfg.calib_info.rolloff.b_gain[IMX111_EEPROM_PAGE_SIZE - BLUE_START + i] = eepromdata[i];
+ crc_5100 += eepromdata[i];
+ //printk("[QCTK_EEPROM] B(0x%x, %d)\n", i, eepromdata[i]);
+ }
+
+ for (i = 0; i < 17; i++) {
+ cfg->cfg.calib_info.rolloff.red_ref[i] = eepromdata[R_REF_ADDR + i];
+ //printk("[QCTK_EEPROM] R_ref(0x%x)\n", cfg->cfg.calib_info.rolloff.red_ref[i]);
+ }
+
+ printk("%s: crc_from_eeprom(0x%x), cal_crc(0x%x)\n", __func__,
+ (eepromdata[CRC_ADDR] << 8) | eepromdata[CRC_ADDR+1], crc_5100& 0xFFFF);
+ #if 0
+ // CRC check
+ if (((eepromdata[CRC_ADDR]<<8)+eepromdata[CRC_ADDR+1]) != crc_5100)
+ {
+ pr_err("%s: CRC error R(read crc:0x%x, cal crc:0x%x)\n", __func__,
+ (eepromdata[CRC_ADDR]<<8)+eepromdata[CRC_ADDR+1], crc_red);
+ // return -EFAULT;
+ }
+ #endif
+
+ printk("%s: X\n", __func__);
+ return 0;
+}
+static struct v4l2_subdev_video_ops imx111_subdev_video_ops = {
+ .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx111_subdev_ops = {
+ .core = &imx111_subdev_core_ops,
+ .video = &imx111_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t imx111_func_tbl = {
+ .sensor_start_stream = msm_sensor_start_stream,
+ .sensor_stop_stream = msm_sensor_stop_stream,
+ .sensor_group_hold_on = msm_sensor_group_hold_on,
+ .sensor_group_hold_off = msm_sensor_group_hold_off,
+#if 0 /* removed at M8960AAAAANLYA1022 */
+ .sensor_get_prev_lines_pf = msm_sensor_get_prev_lines_pf,
+ .sensor_get_prev_pixels_pl = msm_sensor_get_prev_pixels_pl,
+ .sensor_get_pict_lines_pf = msm_sensor_get_pict_lines_pf,
+ .sensor_get_pict_pixels_pl = msm_sensor_get_pict_pixels_pl,
+ .sensor_get_pict_max_exp_lc = msm_sensor_get_pict_max_exp_lc,
+ .sensor_get_pict_fps = msm_sensor_get_pict_fps,
+#endif
+ .sensor_set_fps = imx111_sensor_set_fps,
+ .sensor_write_exp_gain = imx111_sensor_write_exp_gain1,
+ .sensor_write_snapshot_exp_gain = imx111_sensor_write_exp_gain1,
+ .sensor_setting = imx111_sensor_setting,
+ .sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+ .sensor_mode_init = msm_sensor_mode_init,
+ .sensor_get_output_info = msm_sensor_get_output_info,
+ .sensor_config = msm_sensor_config,
+ .sensor_get_eeprom_data = imx111_read_eeprom_data,
+ .sensor_power_up = msm_sensor_power_up,
+ .sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t imx111_regs = {
+ .default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+ .start_stream_conf = imx111_start_settings,
+ .start_stream_conf_size = ARRAY_SIZE(imx111_start_settings),
+ .stop_stream_conf = imx111_stop_settings,
+ .stop_stream_conf_size = ARRAY_SIZE(imx111_stop_settings),
+ .group_hold_on_conf = imx111_groupon_settings,
+ .group_hold_on_conf_size = ARRAY_SIZE(imx111_groupon_settings),
+ .group_hold_off_conf = imx111_groupoff_settings,
+ .group_hold_off_conf_size =
+ ARRAY_SIZE(imx111_groupoff_settings),
+ .init_settings = &imx111_init_conf[0],
+ .init_size = ARRAY_SIZE(imx111_init_conf),
+ .mode_settings = &imx111_confs[0],
+ .output_settings = &imx111_dimensions[0],
+ .num_conf = ARRAY_SIZE(imx111_confs),
+};
+
+static struct msm_sensor_ctrl_t imx111_s_ctrl = {
+ .msm_sensor_reg = &imx111_regs,
+ .sensor_i2c_client = &imx111_sensor_i2c_client,
+ .sensor_i2c_addr = 0x34,
+ .sensor_output_reg_addr = &imx111_reg_addr,
+ .sensor_id_info = &imx111_id_info,
+ .sensor_exp_gain_info = &imx111_exp_gain_info,
+ .cam_mode = MSM_SENSOR_MODE_INVALID,
+ .csi_params = &imx111_csi_params_array[0],
+ .msm_sensor_mutex = &imx111_mut,
+ .sensor_i2c_driver = &imx111_i2c_driver,
+ .sensor_v4l2_subdev_info = imx111_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx111_subdev_info),
+ .sensor_v4l2_subdev_ops = &imx111_subdev_ops,
+ .func_tbl = &imx111_func_tbl,
+.clk_rate = MSM_SENSOR_MCLK_24HZ, // ADD
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sony 8MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/imx119_v4l2.c b/drivers/media/video/msm/sensors/imx119_v4l2.c
new file mode 100644
index 0000000..3338fa7
--- /dev/null
+++ b/drivers/media/video/msm/sensors/imx119_v4l2.c
@@ -0,0 +1,252 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 and
+ * only 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.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "imx119"
+#define PLATFORM_DRIVER_NAME "msm_camera_imx119"
+#define imx119_obj imx119_##obj
+
+DEFINE_MUTEX(imx119_mut);
+static struct msm_sensor_ctrl_t imx119_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf imx119_start_settings[] = {
+ {0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx119_stop_settings[] = {
+ {0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx119_groupon_settings[] = {
+ {0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx119_groupoff_settings[] = {
+ {0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx119_prev_settings[] = {
+ {0x0101, 0x03}, /* read out direction */
+ {0x0340, 0x04},
+ {0x0341, 0x28},
+ {0x0346, 0x00},
+ {0x0347, 0x00},
+ {0x034A, 0x04},
+ {0x034B, 0x0F},
+ {0x034C, 0x05},
+ {0x034D, 0x10},
+ {0x034E, 0x04},
+ {0x034F, 0x10},
+ {0x0381, 0x01},
+ {0x0383, 0x01},
+ {0x0385, 0x01},
+ {0x0387, 0x01},
+ {0x3001, 0x00},
+ {0x3016, 0x02},
+ {0x3060, 0x30},
+ {0x30E8, 0x00},
+ {0x3301, 0x05},
+ {0x308A, 0x43},
+ {0x3305, 0x03},
+ {0x3309, 0x05},
+ {0x330B, 0x03},
+ {0x330D, 0x05},
+};
+
+static struct msm_camera_i2c_reg_conf imx119_recommend_settings[] = {
+ {0x0305, 0x02},
+ {0x0307, 0x26},
+ {0x3025, 0x0A},
+ {0x302B, 0x4B},
+ {0x0112, 0x0A},
+ {0x0113, 0x0A},
+ {0x301C, 0x02},
+ {0x302C, 0x85},
+ {0x303A, 0xA4},
+ {0x3108, 0x25},
+ {0x310A, 0x27},
+ {0x3122, 0x26},
+ {0x3138, 0x26},
+ {0x313A, 0x27},
+ {0x316D, 0x0A},
+ {0x308C, 0x00},
+ {0x302E, 0x8C},
+ {0x302F, 0x81},
+ {0x0101, 0x03},
+};
+
+static struct v4l2_subdev_info imx119_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+ /* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array imx119_init_conf[] = {
+ {&imx119_recommend_settings[0],
+ ARRAY_SIZE(imx119_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array imx119_confs[] = {
+ {&imx119_prev_settings[0],
+ ARRAY_SIZE(imx119_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t imx119_dimensions[] = {
+ {
+ .x_output = 0x510,
+ .y_output = 0x410,
+ .line_length_pclk = 0x570,
+ .frame_length_lines = 0x432,
+ .vt_pixel_clk = 45600000,
+ .op_pixel_clk = 45600000,
+ },
+};
+
+static struct msm_camera_csid_vc_cfg imx119_cid_cfg[] = {
+ {0, CSI_RAW10, CSI_DECODE_10BIT},
+ {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
+ {2, CSI_RESERVED_DATA_0, CSI_DECODE_8BIT},
+};
+
+static struct msm_camera_csi2_params imx119_csi_params = {
+ .csid_params = {
+ .lane_assign = 0xe4,
+ .lane_cnt = 1,
+ .lut_params = {
+ .num_cid = 3,
+ .vc_cfg = imx119_cid_cfg,
+ },
+ },
+ .csiphy_params = {
+ .lane_cnt = 1,
+ .settle_cnt = 0x1B,
+ },
+};
+
+static struct msm_camera_csi2_params *imx119_csi_params_array[] = {
+ &imx119_csi_params,
+};
+
+static struct msm_sensor_output_reg_addr_t imx119_reg_addr = {
+ .x_output = 0x34C,
+ .y_output = 0x34E,
+ .line_length_pclk = 0x342,
+ .frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t imx119_id_info = {
+ .sensor_id_reg_addr = 0x0,
+ .sensor_id = 0x119,
+};
+
+static struct msm_sensor_exp_gain_info_t imx119_exp_gain_info = {
+ .coarse_int_time_addr = 0x202,
+ .global_gain_addr = 0x204,
+ .vert_offset = 3,
+};
+
+
+static const struct i2c_device_id imx119_i2c_id[] = {
+ {SENSOR_NAME, (kernel_ulong_t)&imx119_s_ctrl},
+ { }
+};
+
+static struct i2c_driver imx119_i2c_driver = {
+ .id_table = imx119_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client imx119_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+ return i2c_add_driver(&imx119_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops imx119_subdev_core_ops = {
+ .ioctl = msm_sensor_subdev_ioctl,
+ .s_power = msm_sensor_power,
+};
+static struct v4l2_subdev_video_ops imx119_subdev_video_ops = {
+ .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx119_subdev_ops = {
+ .core = &imx119_subdev_core_ops,
+ .video = &imx119_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t imx119_func_tbl = {
+ .sensor_start_stream = msm_sensor_start_stream,
+ .sensor_stop_stream = msm_sensor_stop_stream,
+ .sensor_group_hold_on = msm_sensor_group_hold_on,
+ .sensor_group_hold_off = msm_sensor_group_hold_off,
+ .sensor_set_fps = msm_sensor_set_fps,
+ .sensor_write_exp_gain = msm_sensor_write_exp_gain1,
+ .sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
+ .sensor_setting = msm_sensor_setting,
+ .sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+ .sensor_mode_init = msm_sensor_mode_init,
+ .sensor_get_output_info = msm_sensor_get_output_info,
+ .sensor_config = msm_sensor_config,
+ .sensor_power_up = msm_sensor_power_up,
+ .sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t imx119_regs = {
+ .default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+ .start_stream_conf = imx119_start_settings,
+ .start_stream_conf_size = ARRAY_SIZE(imx119_start_settings),
+ .stop_stream_conf = imx119_stop_settings,
+ .stop_stream_conf_size = ARRAY_SIZE(imx119_stop_settings),
+ .group_hold_on_conf = imx119_groupon_settings,
+ .group_hold_on_conf_size = ARRAY_SIZE(imx119_groupon_settings),
+ .group_hold_off_conf = imx119_groupoff_settings,
+ .group_hold_off_conf_size = ARRAY_SIZE(imx119_groupoff_settings),
+ .init_settings = &imx119_init_conf[0],
+ .init_size = ARRAY_SIZE(imx119_init_conf),
+ .mode_settings = &imx119_confs[0],
+ .output_settings = &imx119_dimensions[0],
+ .num_conf = ARRAY_SIZE(imx119_confs),
+};
+
+static struct msm_sensor_ctrl_t imx119_s_ctrl = {
+ .msm_sensor_reg = &imx119_regs,
+ .sensor_i2c_client = &imx119_sensor_i2c_client,
+ .sensor_i2c_addr = 0x6E,
+ .sensor_output_reg_addr = &imx119_reg_addr,
+ .sensor_id_info = &imx119_id_info,
+ .sensor_exp_gain_info = &imx119_exp_gain_info,
+ .cam_mode = MSM_SENSOR_MODE_INVALID,
+ .csi_params = &imx119_csi_params_array[0],
+ .msm_sensor_mutex = &imx119_mut,
+ .sensor_i2c_driver = &imx119_i2c_driver,
+ .sensor_v4l2_subdev_info = imx119_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx119_subdev_info),
+ .sensor_v4l2_subdev_ops = &imx119_subdev_ops,
+ .func_tbl = &imx119_func_tbl,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sony 1.3MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index d94196f..4cc1fe8 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -135,6 +135,8 @@
(struct msm_sensor_ctrl_t *);
int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
+ int (*sensor_get_eeprom_data) (struct msm_sensor_ctrl_t *,
+ struct sensor_cfg_data *);
int (*sensor_adjust_frame_lines)
(struct msm_sensor_ctrl_t *s_ctrl, uint16_t res);
int32_t (*sensor_get_csi_params)(struct msm_sensor_ctrl_t *,
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 81b6a40..0b5724e 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1094,6 +1094,17 @@
uint8_t pict_res;
};
+#define ROLLOFF_CALDATA_SIZE (17 * 13)
+typedef struct
+{
+ unsigned short mesh_rolloff_table_size; // TableSize
+ uint8_t r_gain[ROLLOFF_CALDATA_SIZE]; // RGain
+ uint8_t gr_gain[ROLLOFF_CALDATA_SIZE]; // GRGain
+ uint8_t gb_gain[ROLLOFF_CALDATA_SIZE]; // GBGain
+ uint8_t b_gain[ROLLOFF_CALDATA_SIZE]; // BGain
+ uint8_t red_ref[17];
+} rolloff_caldata_array_type;
+
struct sensor_calib_data {
/* Color Related Measurements */
uint16_t r_over_g;
@@ -1106,6 +1117,8 @@
uint16_t stroke_amt;
uint16_t af_pos_1m;
uint16_t af_pos_inf;
+ /* Lens Shading Calibration Data */
+ rolloff_caldata_array_type rolloff;
};
enum msm_sensor_resolution_t {