Merge "defconfig: msm8960: disable CONFIG_SLUB_DEBUG_ON for non-perf config" into msm-3.0
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index d4a605c..e70a0a5 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -42,6 +42,12 @@
default n
---help---
Omni 5M YUV Sensor
+
+config OV5647
+ bool "Sensor ov5647 (BAYER 5M)"
+ depends on MSM_CAMERA
+ ---help---
+ OV 5M Bayer Sensor with AutoFocus
config WEBCAM_OV7692_QRD
bool "Sensor OV7692 QRD(VGA YUV)"
depends on MSM_CAMERA && ARCH_MSM7X27A && !MSM_CAMERA_V4L2
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index b91449a..8703669 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -44,6 +44,8 @@
obj-$(CONFIG_QS_S5K4E1) += qs_s5k4e1.o qs_s5k4e1_reg.o
obj-$(CONFIG_VB6801) += vb6801.o
obj-$(CONFIG_IMX072) += imx072.o imx072_reg.o
+obj-$(CONFIG_WEBCAM_OV9726) += ov9726.o ov9726_reg.o
+obj-$(CONFIG_OV5647) += ov5647.o ov5647_reg.o
obj-$(CONFIG_WEBCAM_OV7692) += ov7692.o
obj-$(CONFIG_WEBCAM_OV7692_QRD) += ov7692_qrd.o
obj-$(CONFIG_OV5640) += ov5640.o
diff --git a/drivers/media/video/msm/ov5647.c b/drivers/media/video/msm/ov5647.c
new file mode 100644
index 0000000..2a6e7be
--- /dev/null
+++ b/drivers/media/video/msm/ov5647.c
@@ -0,0 +1,1201 @@
+/* Copyright (c) 2012, 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 <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/bitops.h>
+#include <linux/leds.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include "ov5647.h"
+
+/* 16bit address - 8 bit context register structure */
+#define Q8 0x00000100
+#define Q10 0x00000400
+
+#define REG_OV5647_GAIN_MSB 0x350A
+#define REG_OV5647_GAIN_LSB 0x350B
+#define REG_OV5647_LINE_HSB 0x3500
+#define REG_OV5647_LINE_MSB 0x3501
+#define REG_OV5647_LINE_LSB 0x3502
+
+/* MCLK */
+#define OV5647_MASTER_CLK_RATE 24000000
+
+/* AF Total steps parameters */
+#define OV5647_TOTAL_STEPS_NEAR_TO_FAR 32
+
+#define OV5647_REG_PREV_FRAME_LEN_1 31
+#define OV5647_REG_PREV_FRAME_LEN_2 32
+#define OV5647_REG_PREV_LINE_LEN_1 33
+#define OV5647_REG_PREV_LINE_LEN_2 34
+
+#define OV5647_REG_SNAP_FRAME_LEN_1 15
+#define OV5647_REG_SNAP_FRAME_LEN_2 16
+#define OV5647_REG_SNAP_LINE_LEN_1 17
+#define OV5647_REG_SNAP_LINE_LEN_2 18
+#define MSB 1
+#define LSB 0
+
+/* Debug switch */
+#ifdef CDBG
+#undef CDBG
+#endif
+#ifdef CDBG_HIGH
+#undef CDBG_HIGH
+#endif
+
+/*#define OV5647_VERBOSE_DGB*/
+
+#ifdef OV5647_VERBOSE_DGB
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+/*for debug*/
+#ifdef CDBG
+#undef CDBG
+#endif
+#define CDBG(fmt, args...) printk(fmt, ##args)
+
+static uint8_t mode_mask = 0x09;
+struct ov5647_work_t {
+ struct work_struct work;
+};
+
+static struct ov5647_work_t *ov5647_sensorw;
+static struct ov5647_work_t *ov5647_af_sensorw;
+static struct i2c_client *ov5647_af_client;
+static struct i2c_client *ov5647_client;
+
+struct ov5647_ctrl_t {
+ const struct msm_camera_sensor_info *sensordata;
+
+ uint32_t sensormode;
+ uint32_t fps_divider;/* init to 1 * 0x00000400 */
+ uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+ uint16_t fps;
+
+ uint16_t curr_lens_pos;
+ uint16_t curr_step_pos;
+ uint16_t my_reg_gain;
+ uint32_t my_reg_line_count;
+ uint16_t total_lines_per_frame;
+
+ enum ov5647_resolution_t prev_res;
+ enum ov5647_resolution_t pict_res;
+ enum ov5647_resolution_t curr_res;
+ enum ov5647_test_mode_t set_test;
+};
+
+static bool CSI_CONFIG;
+static struct ov5647_ctrl_t *ov5647_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(ov5647_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(ov5647_af_wait_queue);
+DEFINE_MUTEX(ov5647_mut);
+
+static uint16_t prev_line_length_pck;
+static uint16_t prev_frame_length_lines;
+static uint16_t snap_line_length_pck;
+static uint16_t snap_frame_length_lines;
+
+static int ov5647_i2c_rxdata(unsigned short saddr,
+ unsigned char *rxdata, int length)
+{
+ struct i2c_msg msgs[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = 2,
+ .buf = rxdata,
+ },
+ {
+ .addr = saddr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = rxdata,
+ },
+ };
+ if (i2c_transfer(ov5647_client->adapter, msgs, 2) < 0) {
+ CDBG("ov5647_i2c_rxdata faild 0x%x\n", saddr);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int32_t ov5647_i2c_txdata(unsigned short saddr,
+ unsigned char *txdata, int length)
+{
+ struct i2c_msg msg[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = length,
+ .buf = txdata,
+ },
+ };
+ if (i2c_transfer(ov5647_client->adapter, msg, 1) < 0) {
+ CDBG("ov5647_i2c_txdata faild 0x%x\n", saddr);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int32_t ov5647_i2c_read(unsigned short raddr,
+ unsigned short *rdata)
+{
+ int32_t rc = 0;
+ unsigned char buf[2];
+
+ if (!rdata)
+ return -EIO;
+ CDBG("%s:saddr:0x%x raddr:0x%x data:0x%x",
+ __func__, ov5647_client->addr, raddr, *rdata);
+ memset(buf, 0, sizeof(buf));
+ buf[0] = (raddr & 0xFF00) >> 8;
+ buf[1] = (raddr & 0x00FF);
+ rc = ov5647_i2c_rxdata(ov5647_client->addr >> 1, buf, 1);
+ if (rc < 0) {
+ CDBG("ov5647_i2c_read 0x%x failed!\n", raddr);
+ return rc;
+ }
+ *rdata = buf[0];
+ CDBG("ov5647_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+
+ return rc;
+}
+
+static int32_t ov5647_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+ int32_t rc = -EFAULT;
+ unsigned char buf[3];
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = (waddr & 0xFF00) >> 8;
+ buf[1] = (waddr & 0x00FF);
+ buf[2] = bdata;
+ CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+ rc = ov5647_i2c_txdata(ov5647_client->addr >> 1, buf, 3);
+ if (rc < 0) {
+ pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+ waddr, bdata);
+ }
+ return rc;
+}
+
+static int32_t ov5647_i2c_write_b_table(struct ov5647_i2c_reg_conf const
+ *reg_conf_tbl, int num)
+{
+ int i;
+ int32_t rc = -EIO;
+
+ for (i = 0; i < num; i++) {
+ rc = ov5647_i2c_write_b_sensor(reg_conf_tbl->waddr,
+ reg_conf_tbl->wdata);
+ if (rc < 0)
+ break;
+ reg_conf_tbl++;
+ }
+ return rc;
+}
+
+static int32_t ov5647_af_i2c_txdata(unsigned short saddr,
+ unsigned char *txdata, int length)
+{
+ struct i2c_msg msg[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = length,
+ .buf = txdata,
+ },
+ };
+ if (i2c_transfer(ov5647_af_client->adapter, msg, 1) < 0) {
+ pr_err("ov5647_af_i2c_txdata faild 0x%x\n", saddr);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int32_t ov5647_af_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
+{
+ int32_t rc = -EFAULT;
+ unsigned char buf[2];
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = waddr;
+ buf[1] = bdata;
+ CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+ rc = ov5647_af_i2c_txdata(ov5647_af_client->addr, buf, 2);
+ if (rc < 0) {
+ pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+ waddr, bdata);
+ }
+ return rc;
+}
+
+static void ov5647_start_stream(void)
+{
+ CDBG("CAMERA_DBG: 0x4202 0x0, stream on...\r\n");
+ ov5647_i2c_write_b_sensor(0x4202, 0x00);/* streaming on */
+}
+
+static void ov5647_stop_stream(void)
+{
+ CDBG("CAMERA_DBG: 0x4202 0xf, stream off...\r\n");
+ ov5647_i2c_write_b_sensor(0x4202, 0x0f);/* streaming off */
+}
+
+static void ov5647_group_hold_on(void)
+{
+ ov5647_i2c_write_b_sensor(0x0104, 0x01);
+}
+
+static void ov5647_group_hold_off(void)
+{
+ ov5647_i2c_write_b_sensor(0x0104, 0x0);
+}
+
+static void ov5647_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+ /* input fps is preview fps in Q8 format */
+ uint32_t divider, d1, d2;
+ uint32_t preview_pclk = 0x37, snapshot_pclk = 0x4f;
+
+ d1 = (prev_frame_length_lines * 0x00000400) / snap_frame_length_lines;
+ d2 = (prev_line_length_pck * 0x00000400) / snap_line_length_pck;
+ divider = (d1 * d2*preview_pclk/snapshot_pclk) / 0x400;
+ CDBG(KERN_ERR "ov5647_get_pict_fps divider = %d", divider);
+ /*Verify PCLK settings and frame sizes.*/
+ *pfps = (uint16_t) (fps * divider / 0x400);
+}
+
+static uint16_t ov5647_get_prev_lines_pf(void)
+{
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ return prev_frame_length_lines;
+ else
+ return snap_frame_length_lines;
+}
+
+static uint16_t ov5647_get_prev_pixels_pl(void)
+{
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ return prev_line_length_pck;
+ else
+ return snap_line_length_pck;
+}
+
+static uint16_t ov5647_get_pict_lines_pf(void)
+{
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ return prev_frame_length_lines;
+ else
+ return snap_frame_length_lines;
+}
+
+static uint16_t ov5647_get_pict_pixels_pl(void)
+{
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ return prev_line_length_pck;
+ else
+ return snap_line_length_pck;
+}
+
+static uint32_t ov5647_get_pict_max_exp_lc(void)
+{
+ return snap_frame_length_lines * 24;
+}
+
+static int32_t ov5647_set_fps(struct fps_cfg *fps)
+{
+ uint16_t total_lines_per_frame;
+ int32_t rc = 0;
+
+ ov5647_ctrl->fps_divider = fps->fps_div;
+ ov5647_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+ if (ov5647_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+ total_lines_per_frame = (uint16_t)
+ ((prev_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
+ } else {
+ total_lines_per_frame = (uint16_t)
+ ((snap_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
+ }
+
+ ov5647_group_hold_on();
+ rc = ov5647_i2c_write_b_sensor(0x0340,
+ ((total_lines_per_frame & 0xFF00) >> 8));
+ rc = ov5647_i2c_write_b_sensor(0x0341,
+ (total_lines_per_frame & 0x00FF));
+ ov5647_group_hold_off();
+
+ return rc;
+}
+
+static inline uint8_t ov5647_byte(uint16_t word, uint8_t offset)
+{
+ return word >> (offset * BITS_PER_BYTE);
+}
+
+static int32_t ov5647_write_exp_gain(uint16_t gain, uint32_t line)
+{
+ int rc = 0;
+ uint16_t max_line;
+ u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+ uint8_t gain_lsb, gain_hsb;
+ ov5647_ctrl->my_reg_gain = gain;
+ ov5647_ctrl->my_reg_line_count = (uint16_t)line;
+
+ CDBG(KERN_ERR "preview exposure setting 0x%x, 0x%x, %d",
+ gain, line, line);
+
+ gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
+ gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
+ /* adjust frame rate */
+ if (line > 980) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)((line+4) >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)((line+4) & 0x00FF)) ;
+ max_line = line + 4;
+ } else if (max_line > 984) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)(984 >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)(984 & 0x00FF)) ;
+ max_line = 984;
+ }
+
+ line = line<<4;
+ /* ov5647 need this operation */
+ intg_time_hsb = (u8)(line>>16);
+ intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+ intg_time_lsb = (u8) (line & 0x00FF);
+
+ ov5647_group_hold_on();
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
+ ov5647_group_hold_off();
+
+ return rc;
+}
+
+
+static int32_t ov5647_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+ uint16_t max_line;
+ int rc = 0;
+ uint8_t gain_lsb, gain_hsb;
+ u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+
+ ov5647_ctrl->my_reg_gain = gain;
+ ov5647_ctrl->my_reg_line_count = (uint16_t)line;
+
+ gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
+ gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
+
+ CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
+ , gain, line, line);
+
+ if (line > 1964) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)((line+4) >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)((line+4) & 0x00FF)) ;
+ max_line = line + 4;
+ } else if (max_line > 1968) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)(1968 >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)(1968 & 0x00FF)) ;
+ max_line = 1968;
+ }
+ line = line<<4;
+ /* ov5647 need this operation */
+ intg_time_hsb = (u8)(line>>16);
+ intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+ intg_time_lsb = (u8) (line & 0x00FF);
+
+ /* FIXME for BLC trigger */
+ ov5647_group_hold_on();
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb - 1) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
+ ov5647_group_hold_off();
+
+ msleep(500);
+ return rc;
+
+}
+
+static int32_t ov5647_move_focus(int direction, int32_t num_steps)
+{
+ uint8_t code_val_msb = 0;
+ uint8_t code_val_lsb = 0;
+ int16_t step_direction, actual_step, next_position;
+ int rc;
+
+ if (num_steps == 0)
+ return 0;
+
+ if (direction == MOVE_NEAR)
+ step_direction = 20;
+ else if (direction == MOVE_FAR)
+ step_direction = -20;
+ else
+ return -EINVAL;
+
+ actual_step = (int16_t)(step_direction * num_steps);
+ next_position = (int16_t)ov5647_ctrl->curr_lens_pos + actual_step;
+ if (next_position < 0) {
+ CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
+ __func__, next_position);
+ next_position = 0;
+ }
+ if (next_position > 0x3FF) {
+ CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
+ __func__, next_position);
+ next_position = 0x3FF;
+ }
+ ov5647_ctrl->curr_lens_pos = next_position;
+
+ code_val_msb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4);
+ code_val_lsb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x000F) << 4);
+ code_val_lsb |= mode_mask;
+
+ rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
+ /* DAC Setting */
+ if (rc != 0) {
+ CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+ } else {
+ CDBG(KERN_ERR "%s: Successful lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+ /* delay may set based on the steps moved
+ when I2C write successful */
+ msleep(100);
+ }
+ return 0;
+}
+
+static int32_t ov5647_set_default_focus(uint8_t af_step)
+{
+ uint8_t code_val_msb = 0;
+ uint8_t code_val_lsb = 0;
+ int rc = 0;
+
+ ov5647_ctrl->curr_lens_pos = 200;
+
+
+ code_val_msb = (ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4;
+ code_val_lsb = (ov5647_ctrl->curr_lens_pos & 0x000F) << 4;
+ code_val_lsb |= mode_mask;
+
+ CDBG(KERN_ERR "ov5647_set_default_focus:lens pos = %d",
+ ov5647_ctrl->curr_lens_pos);
+ rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
+ /* DAC Setting */
+ if (rc != 0)
+ CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+ else
+ CDBG(KERN_ERR "%s: WRITE successful lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+
+ usleep_range(10000, 11000);
+ return 0;
+}
+
+static int32_t ov5647_test(enum ov5647_test_mode_t mo)
+{
+ int32_t rc = 0;
+
+ if (mo != TEST_OFF)
+ rc = ov5647_i2c_write_b_sensor(0x0601, (uint8_t) mo);
+
+ return rc;
+}
+
+static void ov5647_reset_sensor(void)
+{
+ ov5647_i2c_write_b_sensor(0x103, 0x1);
+}
+
+
+static int32_t ov5647_sensor_setting(int update_type, int rt)
+{
+
+ int32_t rc = 0;
+ struct msm_camera_csi_params ov5647_csi_params;
+
+ ov5647_stop_stream();
+
+ /* wait for clk/data really stop */
+ if ((rt == RES_CAPTURE) || (CSI_CONFIG == 0))
+ msleep(66);
+ else
+ msleep(266);
+
+ CDBG("CAMERA_DBG1: 0x4800 regVal:0x25\r\n");
+ ov5647_i2c_write_b_sensor(0x4800, 0x25);/* streaming off */
+
+ usleep_range(10000, 11000);
+
+ if (update_type == REG_INIT) {
+ ov5647_reset_sensor();
+ ov5647_i2c_write_b_table(ov5647_regs.rec_settings,
+ ov5647_regs.rec_size);
+ CSI_CONFIG = 0;
+ } else if (update_type == UPDATE_PERIODIC) {
+ /* turn off flash when preview */
+
+ if (rt == RES_PREVIEW) {
+ ov5647_i2c_write_b_table(ov5647_regs.reg_prev,
+ ov5647_regs.reg_prev_size);
+ CDBG("CAMERA_DBG:preview settings...\r\n");
+ } else {
+ ov5647_i2c_write_b_table(ov5647_regs.reg_snap,
+ ov5647_regs.reg_snap_size);
+ CDBG("CAMERA_DBG:snapshot settings...\r\n");
+ }
+
+ msleep(20);
+ if (!CSI_CONFIG) {
+ msm_camio_vfe_clk_rate_set(192000000);
+ ov5647_csi_params.data_format = CSI_8BIT;
+ ov5647_csi_params.lane_cnt = 2;
+ ov5647_csi_params.lane_assign = 0xe4;
+ ov5647_csi_params.dpcm_scheme = 0;
+ ov5647_csi_params.settle_cnt = 10;
+ rc = msm_camio_csi_config(&ov5647_csi_params);
+ msleep(20);
+ CSI_CONFIG = 1;
+ /* exit powerdown state */
+ ov5647_i2c_write_b_sensor(0x0100, 0x01);
+ }
+ CDBG("CAMERA_DBG: 0x4800 regVal:0x04\r\n");
+ /* streaming on */
+ ov5647_i2c_write_b_sensor(0x4800, 0x04);
+ msleep(266);
+ ov5647_start_stream();
+ msleep(30);
+ }
+ return rc;
+}
+
+static int32_t ov5647_video_config(int mode)
+{
+ int32_t rc = 0;
+ int rt;
+ CDBG("video config\n");
+ /* change sensor resolution if needed */
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ rt = RES_PREVIEW;
+ else
+ rt = RES_CAPTURE;
+ if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+ return rc;
+ if (ov5647_ctrl->set_test) {
+ if (ov5647_test(ov5647_ctrl->set_test) < 0)
+ return rc;
+ }
+
+ ov5647_ctrl->curr_res = ov5647_ctrl->prev_res;
+ ov5647_ctrl->sensormode = mode;
+ return rc;
+}
+
+static int32_t ov5647_snapshot_config(int mode)
+{
+ int32_t rc = 0;
+ int rt;
+
+ /*change sensor resolution if needed */
+ if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ rt = RES_PREVIEW;
+ else
+ rt = RES_CAPTURE;
+ if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+ return rc;
+ }
+
+ ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
+ ov5647_ctrl->sensormode = mode;
+ return rc;
+}
+
+static int32_t ov5647_raw_snapshot_config(int mode)
+{
+ int32_t rc = 0;
+ int rt;
+
+ /* change sensor resolution if needed */
+ if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ rt = RES_PREVIEW;
+ else
+ rt = RES_CAPTURE;
+ if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+ return rc;
+ }
+
+ ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
+ ov5647_ctrl->sensormode = mode;
+ return rc;
+}
+
+static int32_t ov5647_set_sensor_mode(int mode,
+ int res)
+{
+ int32_t rc = 0;
+
+ switch (mode) {
+ case SENSOR_PREVIEW_MODE:
+ rc = ov5647_video_config(mode);
+ break;
+ case SENSOR_SNAPSHOT_MODE:
+ rc = ov5647_snapshot_config(mode);
+ break;
+ case SENSOR_RAW_SNAPSHOT_MODE:
+ rc = ov5647_raw_snapshot_config(mode);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+static int32_t ov5647_power_down(void)
+{
+ ov5647_stop_stream();
+ return 0;
+}
+
+static int ov5647_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+ CDBG("probe done\n");
+ gpio_direction_output(data->sensor_pwd, 1);
+ return 0;
+}
+
+static int ov5647_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+ int32_t rc = 0;
+ uint16_t regaddress1 = 0x300a;
+ uint16_t regaddress2 = 0x300b;
+ uint16_t chipid1 = 0;
+ uint16_t chipid2 = 0;
+
+ CDBG("%s: %d\n", __func__, __LINE__);
+
+ gpio_direction_output(data->sensor_pwd, 0);
+ usleep_range(4000, 4100);
+ gpio_direction_output(data->sensor_reset, 1);
+ usleep_range(2000, 2100);
+
+ ov5647_i2c_read(regaddress1, &chipid1);
+ if (chipid1 != 0x56) {
+ rc = -ENODEV;
+ pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
+ goto init_probe_fail;
+ }
+
+ ov5647_i2c_read(regaddress2, &chipid2);
+ if (chipid2 != 0x47) {
+ rc = -ENODEV;
+ pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
+ goto init_probe_fail;
+ }
+
+ pr_err("ID1: 0x%x\n", chipid1);
+ pr_err("ID2: 0x%x\n", chipid2);
+ goto init_probe_done;
+
+init_probe_fail:
+ pr_err(" ov5647_probe_init_sensor fails\n");
+ ov5647_probe_init_done(data);
+ return rc;
+init_probe_done:
+ pr_debug(" ov5647_probe_init_sensor finishes\n");
+ gpio_direction_output(data->sensor_pwd, 1);
+ return rc;
+}
+
+
+static int ov5647_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+ int32_t rc = 0;
+
+ CDBG("%s: %d\n", __func__, __LINE__);
+ CDBG("Calling ov5647_sensor_open_init\n");
+
+ ov5647_ctrl = kzalloc(sizeof(struct ov5647_ctrl_t), GFP_KERNEL);
+ if (!ov5647_ctrl) {
+ CDBG("ov5647_init failed!\n");
+ rc = -ENOMEM;
+ goto init_done;
+ }
+ ov5647_ctrl->fps_divider = 1 * 0x00000400;
+ ov5647_ctrl->pict_fps_divider = 1 * 0x00000400;
+ ov5647_ctrl->set_test = TEST_OFF;
+ ov5647_ctrl->prev_res = QTR_SIZE;
+ ov5647_ctrl->pict_res = FULL_SIZE;
+
+ if (data)
+ ov5647_ctrl->sensordata = data;
+
+ prev_frame_length_lines = 0x3d8;
+
+ prev_line_length_pck = 0x768*2;
+
+ snap_frame_length_lines = 0x7b0;
+
+ snap_line_length_pck = 0xa8c;
+
+ /* enable mclk first */
+ msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
+
+ gpio_direction_output(data->sensor_pwd, 1);
+ gpio_direction_output(data->sensor_reset, 0);
+ usleep_range(10000, 11000);
+ /* power on camera ldo and vreg */
+ if (ov5647_ctrl->sensordata->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
+ usleep_range(10000, 11000); /*waiting for ldo stable*/
+ gpio_direction_output(data->sensor_pwd, 0);
+ msleep(20);
+ gpio_direction_output(data->sensor_reset, 1);
+ msleep(25);
+
+ CDBG("init settings\n");
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ rc = ov5647_sensor_setting(REG_INIT, RES_PREVIEW);
+ else
+ rc = ov5647_sensor_setting(REG_INIT, RES_CAPTURE);
+ ov5647_ctrl->fps = 30 * Q8;
+
+ /* enable AF actuator */
+ if (ov5647_ctrl->sensordata->vcm_enable) {
+ CDBG("enable AF actuator, gpio = %d\n",
+ ov5647_ctrl->sensordata->vcm_pwd);
+ rc = gpio_request(ov5647_ctrl->sensordata->vcm_pwd,
+ "ov5647_af");
+ if (!rc)
+ gpio_direction_output(
+ ov5647_ctrl->sensordata->vcm_pwd,
+ 1);
+ else {
+ pr_err("ov5647_ctrl gpio request failed!\n");
+ goto init_fail;
+ }
+ msleep(20);
+ rc = ov5647_set_default_focus(0);
+ if (rc < 0) {
+ gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd,
+ 0);
+ gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
+ }
+ }
+ if (rc < 0)
+ goto init_fail;
+ else
+ goto init_done;
+init_fail:
+ CDBG("init_fail\n");
+ ov5647_probe_init_done(data);
+ /* No need to power OFF camera ldo and vreg
+ affects Display while resume */
+init_done:
+ CDBG("init_done\n");
+ return rc;
+}
+
+static int ov5647_i2c_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static int ov5647_init_client(struct i2c_client *client)
+{
+ /* Initialize the MSM_CAMI2C Chip */
+ init_waitqueue_head(&ov5647_wait_queue);
+ return 0;
+}
+
+static int ov5647_af_init_client(struct i2c_client *client)
+{
+ /* Initialize the MSM_CAMI2C Chip */
+ init_waitqueue_head(&ov5647_af_wait_queue);
+ return 0;
+}
+
+static const struct i2c_device_id ov5647_af_i2c_id[] = {
+ {"ov5647_af", 0},
+ { }
+};
+
+static int ov5647_af_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ CDBG("ov5647_af_probe called!\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ CDBG("i2c_check_functionality failed\n");
+ goto probe_failure;
+ }
+
+ ov5647_af_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
+ if (!ov5647_af_sensorw) {
+ CDBG("kzalloc failed.\n");
+ rc = -ENOMEM;
+ goto probe_failure;
+ }
+
+ i2c_set_clientdata(client, ov5647_af_sensorw);
+ ov5647_af_init_client(client);
+ ov5647_af_client = client;
+
+ msleep(50);
+
+ CDBG("ov5647_af_probe successed! rc = %d\n", rc);
+ return 0;
+
+probe_failure:
+ CDBG("ov5647_af_probe failed! rc = %d\n", rc);
+ return rc;
+}
+
+static const struct i2c_device_id ov5647_i2c_id[] = {
+ {"ov5647", 0}, {}
+};
+
+static int ov5647_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ CDBG("ov5647_probe called!\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ CDBG("i2c_check_functionality failed\n");
+ goto probe_failure;
+ }
+
+ ov5647_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
+ if (!ov5647_sensorw) {
+ CDBG("kzalloc failed.\n");
+ rc = -ENOMEM;
+ goto probe_failure;
+ }
+
+ i2c_set_clientdata(client, ov5647_sensorw);
+ ov5647_init_client(client);
+ ov5647_client = client;
+
+ msleep(50);
+
+ CDBG("ov5647_probe successed! rc = %d\n", rc);
+ return 0;
+
+probe_failure:
+ CDBG("ov5647_probe failed! rc = %d\n", rc);
+ return rc;
+}
+
+static int __devexit ov5647_remove(struct i2c_client *client)
+{
+ struct ov5647_work_t *sensorw = i2c_get_clientdata(client);
+ free_irq(client->irq, sensorw);
+ ov5647_client = NULL;
+ kfree(sensorw);
+ return 0;
+}
+
+static int __devexit ov5647_af_remove(struct i2c_client *client)
+{
+ struct ov5647_work_t *ov5647_af = i2c_get_clientdata(client);
+ free_irq(client->irq, ov5647_af);
+ ov5647_af_client = NULL;
+ kfree(ov5647_af);
+ return 0;
+}
+
+static struct i2c_driver ov5647_i2c_driver = {
+ .id_table = ov5647_i2c_id,
+ .probe = ov5647_i2c_probe,
+ .remove = ov5647_i2c_remove,
+ .driver = {
+ .name = "ov5647",
+ },
+};
+
+static struct i2c_driver ov5647_af_i2c_driver = {
+ .id_table = ov5647_af_i2c_id,
+ .probe = ov5647_af_i2c_probe,
+ .remove = __exit_p(ov5647_af_i2c_remove),
+ .driver = {
+ .name = "ov5647_af",
+ },
+};
+
+int ov5647_sensor_config(void __user *argp)
+{
+ struct sensor_cfg_data cdata;
+ long rc = 0;
+ if (copy_from_user(&cdata,
+ (void *)argp,
+ sizeof(struct sensor_cfg_data)))
+ return -EFAULT;
+ mutex_lock(&ov5647_mut);
+ CDBG("ov5647_sensor_config: cfgtype = %d\n",
+ cdata.cfgtype);
+ switch (cdata.cfgtype) {
+ case CFG_GET_PICT_FPS:
+ ov5647_get_pict_fps(
+ cdata.cfg.gfps.prevfps,
+ &(cdata.cfg.gfps.pictfps));
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PREV_L_PF:
+ cdata.cfg.prevl_pf =
+ ov5647_get_prev_lines_pf();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PREV_P_PL:
+ cdata.cfg.prevp_pl =
+ ov5647_get_prev_pixels_pl();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PICT_L_PF:
+ cdata.cfg.pictl_pf =
+ ov5647_get_pict_lines_pf();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PICT_P_PL:
+ cdata.cfg.pictp_pl =
+ ov5647_get_pict_pixels_pl();
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PICT_MAX_EXP_LC:
+ cdata.cfg.pict_max_exp_lc =
+ ov5647_get_pict_max_exp_lc();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_SET_FPS:
+ case CFG_SET_PICT_FPS:
+ rc = ov5647_set_fps(&(cdata.cfg.fps));
+ break;
+ case CFG_SET_EXP_GAIN:
+ rc = ov5647_write_exp_gain(cdata.cfg.exp_gain.gain,
+ cdata.cfg.exp_gain.line);
+ break;
+ case CFG_SET_PICT_EXP_GAIN:
+ rc = ov5647_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+ cdata.cfg.exp_gain.line);
+ break;
+ case CFG_SET_MODE:
+ rc = ov5647_set_sensor_mode(cdata.mode, cdata.rs);
+ break;
+ case CFG_PWR_DOWN:
+ rc = ov5647_power_down();
+ break;
+ case CFG_MOVE_FOCUS:
+ rc = ov5647_move_focus(cdata.cfg.focus.dir,
+ cdata.cfg.focus.steps);
+ break;
+ case CFG_SET_DEFAULT_FOCUS:
+ rc = ov5647_set_default_focus(cdata.cfg.focus.steps);
+ break;
+
+ case CFG_GET_AF_MAX_STEPS:
+ cdata.max_steps = OV5647_TOTAL_STEPS_NEAR_TO_FAR;
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_SET_EFFECT:
+ rc = ov5647_set_default_focus(cdata.cfg.effect);
+ break;
+ default:
+ rc = -EFAULT;
+ break;
+ }
+ mutex_unlock(&ov5647_mut);
+
+ return rc;
+}
+
+static int ov5647_sensor_release(void)
+{
+ int rc = -EBADF;
+ unsigned short rdata;
+
+ mutex_lock(&ov5647_mut);
+ ov5647_power_down();
+ msleep(20);
+ ov5647_i2c_read(0x3018, &rdata);
+ rdata |= 0x18; /*set bit 3 bit 4 to 1*/
+ ov5647_i2c_write_b_sensor(0x3018, rdata);/*write back*/
+ msleep(20);
+
+ gpio_set_value(ov5647_ctrl->sensordata->sensor_pwd, 1);
+ usleep_range(5000, 5100);
+ if (ov5647_ctrl->sensordata->vcm_enable) {
+ gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd, 0);
+ gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
+ }
+
+ /* No need to power OFF camera ldo and vreg
+ affects Display while resume */
+
+ kfree(ov5647_ctrl);
+ ov5647_ctrl = NULL;
+ CDBG("ov5647_release completed\n");
+ mutex_unlock(&ov5647_mut);
+
+ return rc;
+}
+
+static int ov5647_sensor_probe(const struct msm_camera_sensor_info *info,
+ struct msm_sensor_ctrl *s)
+{
+ int rc = 0;
+
+ CDBG("%s E\n", __func__);
+
+ gpio_direction_output(info->sensor_pwd, 1);
+ gpio_direction_output(info->sensor_reset, 0);
+ usleep_range(1000, 1100);
+ /* turn on ldo and vreg */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
+
+ rc = i2c_add_driver(&ov5647_i2c_driver);
+ if (rc < 0 || ov5647_client == NULL) {
+ rc = -ENOTSUPP;
+ CDBG("I2C add driver ov5647 failed");
+ goto probe_fail_2;
+ }
+ if (info->vcm_enable) {
+ rc = i2c_add_driver(&ov5647_af_i2c_driver);
+ if (rc < 0 || ov5647_af_client == NULL) {
+ rc = -ENOTSUPP;
+ CDBG("I2C add driver ov5647 af failed");
+ goto probe_fail_3;
+ }
+ }
+ msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
+
+ rc = ov5647_probe_init_sensor(info);
+ if (rc < 0)
+ goto probe_fail_1;
+
+ s->s_init = ov5647_sensor_open_init;
+ s->s_release = ov5647_sensor_release;
+ s->s_config = ov5647_sensor_config;
+ s->s_mount_angle = info->sensor_platform_info->mount_angle;
+ gpio_set_value(info->sensor_pwd, 1);
+ ov5647_probe_init_done(info);
+ /* turn off ldo and vreg */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
+
+ CDBG("%s X", __func__);
+ return rc;
+
+probe_fail_3:
+ i2c_del_driver(&ov5647_af_i2c_driver);
+probe_fail_2:
+ i2c_del_driver(&ov5647_i2c_driver);
+probe_fail_1:
+ /* turn off ldo and vreg */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
+ CDBG("ov5647_sensor_probe: SENSOR PROBE FAILS!\n");
+ CDBG("%s X", __func__);
+ return rc;
+}
+
+static int __devinit ov5647_probe(struct platform_device *pdev)
+{
+ return msm_camera_drv_start(pdev, ov5647_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+ .probe = ov5647_probe,
+ .driver = {
+ .name = "msm_camera_ov5647",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ov5647_init(void)
+{
+ return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov5647_init);
+MODULE_DESCRIPTION("Omnivision 5 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/ov5647.h b/drivers/media/video/msm/ov5647.h
new file mode 100644
index 0000000..b43f15c
--- /dev/null
+++ b/drivers/media/video/msm/ov5647.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#ifndef OV5647_H
+#define OV5647_H
+#include <linux/types.h>
+#include <mach/board.h>
+
+extern struct ov5647_reg ov5647_regs;
+extern int lcd_camera_power_onoff(int on);
+extern struct rw_semaphore leds_list_lock;
+extern struct list_head leds_list;
+
+struct ov5647_i2c_reg_conf {
+ unsigned short waddr;
+ unsigned short wdata;
+};
+
+enum ov5647_test_mode_t {
+ TEST_OFF,
+ TEST_1,
+ TEST_2,
+ TEST_3
+};
+
+enum ov5647_resolution_t {
+ QTR_SIZE,
+ FULL_SIZE,
+ INVALID_SIZE
+};
+enum ov5647_setting {
+ RES_PREVIEW,
+ RES_CAPTURE
+};
+enum ov5647_reg_update {
+ /* Sensor egisters that need to be updated during initialization */
+ REG_INIT,
+ /* Sensor egisters that needs periodic I2C writes */
+ UPDATE_PERIODIC,
+ /* All the sensor Registers will be updated */
+ UPDATE_ALL,
+ /* Not valid update */
+ UPDATE_INVALID
+};
+
+enum ov5647_reg_pll {
+ E013_VT_PIX_CLK_DIV,
+ E013_VT_SYS_CLK_DIV,
+ E013_PRE_PLL_CLK_DIV,
+ E013_PLL_MULTIPLIER,
+ E013_OP_PIX_CLK_DIV,
+ E013_OP_SYS_CLK_DIV
+};
+
+enum ov5647_reg_mode {
+ E013_X_ADDR_START,
+ E013_X_ADDR_END,
+ E013_Y_ADDR_START,
+ E013_Y_ADDR_END,
+ E013_X_OUTPUT_SIZE,
+ E013_Y_OUTPUT_SIZE,
+ E013_DATAPATH_SELECT,
+ E013_READ_MODE,
+ E013_ANALOG_CONTROL5,
+ E013_DAC_LD_4_5,
+ E013_SCALING_MODE,
+ E013_SCALE_M,
+ E013_LINE_LENGTH_PCK,
+ E013_FRAME_LENGTH_LINES,
+ E013_COARSE_INTEGRATION_TIME,
+ E013_FINE_INTEGRATION_TIME,
+ E013_FINE_CORRECTION
+};
+
+struct ov5647_reg {
+ const struct ov5647_i2c_reg_conf *rec_settings;
+ const unsigned short rec_size;
+ const struct ov5647_i2c_reg_conf *reg_prev;
+ const unsigned short reg_prev_size;
+ const struct ov5647_i2c_reg_conf *reg_snap;
+ const unsigned short reg_snap_size;
+};
+#endif /* OV5647_H */
diff --git a/drivers/media/video/msm/ov5647_reg.c b/drivers/media/video/msm/ov5647_reg.c
new file mode 100644
index 0000000..4a0fed4
--- /dev/null
+++ b/drivers/media/video/msm/ov5647_reg.c
@@ -0,0 +1,219 @@
+/* Copyright (c) 2012, 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 "ov5647.h"
+struct ov5647_i2c_reg_conf ov5647_prev_settings[] = {
+ /*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
+ for back to preview*/
+ {0x3035, 0x21},
+ {0x3036, 0x37},
+ {0x3821, 0x07},
+ {0x3820, 0x41},
+ {0x3612, 0x09},
+ {0x3618, 0x00},
+ {0x380c, 0x07},
+ {0x380d, 0x68},
+ {0x380e, 0x03},
+ {0x380f, 0xd8},
+ {0x3814, 0x31},
+ {0x3815, 0x31},
+ {0x3709, 0x52},
+ {0x3808, 0x05},
+ {0x3809, 0x00},
+ {0x380a, 0x03},
+ {0x380b, 0xc0},
+ {0x3800, 0x00},
+ {0x3801, 0x18},
+ {0x3802, 0x00},
+ {0x3803, 0x0e},
+ {0x3804, 0x0a},
+ {0x3805, 0x27},
+ {0x3806, 0x07},
+ {0x3807, 0x95},
+ {0x4004, 0x02},
+};
+
+struct ov5647_i2c_reg_conf ov5647_snap_settings[] = {
+ /*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
+ {0x3035, 0x21},
+ {0x3036, 0x4f},
+ {0x3821, 0x06},
+ {0x3820, 0x00},
+ {0x3612, 0x0b},
+ {0x3618, 0x04},
+ {0x380c, 0x0a},
+ {0x380d, 0x8c},
+ {0x380e, 0x07},
+ {0x380f, 0xb0},
+ {0x3814, 0x11},
+ {0x3815, 0x11},
+ {0x3709, 0x12},
+ {0x3808, 0x0a},
+ {0x3809, 0x30},
+ {0x380a, 0x07},
+ {0x380b, 0xa0},
+ {0x3800, 0x00},
+ {0x3801, 0x04},
+ {0x3802, 0x00},
+ {0x3803, 0x00},
+ {0x3804, 0x0a},
+ {0x3805, 0x3b},
+ {0x3806, 0x07},
+ {0x3807, 0xa3},
+ {0x4004, 0x04},
+};
+
+struct ov5647_i2c_reg_conf ov5647_recommend_settings[] = {
+ {0x3035, 0x11},
+ {0x303c, 0x11},
+ {0x370c, 0x03},
+ {0x5000, 0x06},
+ {0x5003, 0x08},
+ {0x5a00, 0x08},
+ {0x3000, 0xff},
+ {0x3001, 0xff},
+ {0x3002, 0xff},
+ {0x301d, 0xf0},
+ {0x3a18, 0x00},
+ {0x3a19, 0xf8},
+ {0x3c01, 0x80},
+ {0x3b07, 0x0c},
+ {0x3708, 0x64},
+ {0x3630, 0x2e},
+ {0x3632, 0xe2},
+ {0x3633, 0x23},
+ {0x3634, 0x44},
+ {0x3620, 0x64},
+ {0x3621, 0xe0},
+ {0x3600, 0x37},
+ {0x3704, 0xa0},
+ {0x3703, 0x5a},
+ {0x3715, 0x78},
+ {0x3717, 0x01},
+ {0x3731, 0x02},
+ {0x370b, 0x60},
+ {0x3705, 0x1a},
+ {0x3f05, 0x02},
+ {0x3f06, 0x10},
+ {0x3f01, 0x0a},
+ {0x3a08, 0x01},
+ {0x3a0f, 0x58},
+ {0x3a10, 0x50},
+ {0x3a1b, 0x58},
+ {0x3a1e, 0x50},
+ {0x3a11, 0x60},
+ {0x3a1f, 0x28},
+ {0x4001, 0x02},
+ {0x4000, 0x09},
+ {0x3000, 0x00},
+ {0x3001, 0x00},
+ {0x3002, 0x00},
+ {0x3017, 0xe0},
+ {0x301c, 0xfc},
+ {0x3636, 0x06},
+ {0x3016, 0x08},
+ {0x3827, 0xec},
+ {0x3018, 0x44},
+ {0x3035, 0x21},
+ {0x3106, 0xf5},
+ {0x3034, 0x18},
+ {0x301c, 0xf8},
+ /*lens setting*/
+ {0x5000, 0x86},
+ {0x5800, 0x11},
+ {0x5801, 0x0c},
+ {0x5802, 0x0a},
+ {0x5803, 0x0b},
+ {0x5804, 0x0d},
+ {0x5805, 0x13},
+ {0x5806, 0x09},
+ {0x5807, 0x05},
+ {0x5808, 0x03},
+ {0x5809, 0x03},
+ {0x580a, 0x06},
+ {0x580b, 0x08},
+ {0x580c, 0x05},
+ {0x580d, 0x01},
+ {0x580e, 0x00},
+ {0x580f, 0x00},
+ {0x5810, 0x02},
+ {0x5811, 0x06},
+ {0x5812, 0x05},
+ {0x5813, 0x01},
+ {0x5814, 0x00},
+ {0x5815, 0x00},
+ {0x5816, 0x02},
+ {0x5817, 0x06},
+ {0x5818, 0x09},
+ {0x5819, 0x05},
+ {0x581a, 0x04},
+ {0x581b, 0x04},
+ {0x581c, 0x06},
+ {0x581d, 0x09},
+ {0x581e, 0x11},
+ {0x581f, 0x0c},
+ {0x5820, 0x0b},
+ {0x5821, 0x0b},
+ {0x5822, 0x0d},
+ {0x5823, 0x13},
+ {0x5824, 0x22},
+ {0x5825, 0x26},
+ {0x5826, 0x26},
+ {0x5827, 0x24},
+ {0x5828, 0x24},
+ {0x5829, 0x24},
+ {0x582a, 0x22},
+ {0x582b, 0x20},
+ {0x582c, 0x22},
+ {0x582d, 0x26},
+ {0x582e, 0x22},
+ {0x582f, 0x22},
+ {0x5830, 0x42},
+ {0x5831, 0x22},
+ {0x5832, 0x02},
+ {0x5833, 0x24},
+ {0x5834, 0x22},
+ {0x5835, 0x22},
+ {0x5836, 0x22},
+ {0x5837, 0x26},
+ {0x5838, 0x42},
+ {0x5839, 0x26},
+ {0x583a, 0x06},
+ {0x583b, 0x26},
+ {0x583c, 0x24},
+ {0x583d, 0xce},
+ /* manual AWB,manual AE,close Lenc,open WBC*/
+ {0x3503, 0x03}, /*manual AE*/
+ {0x3501, 0x10},
+ {0x3502, 0x80},
+ {0x350a, 0x00},
+ {0x350b, 0x7f},
+ {0x5001, 0x01}, /*manual AWB*/
+ {0x5180, 0x08},
+ {0x5186, 0x04},
+ {0x5187, 0x00},
+ {0x5188, 0x04},
+ {0x5189, 0x00},
+ {0x518a, 0x04},
+ {0x518b, 0x00},
+ {0x5000, 0x06}, /*No lenc,WBC on*/
+};
+
+struct ov5647_reg ov5647_regs = {
+ .rec_settings = &ov5647_recommend_settings[0],
+ .rec_size = ARRAY_SIZE(ov5647_recommend_settings),
+ .reg_prev = &ov5647_prev_settings[0],
+ .reg_prev_size = ARRAY_SIZE(ov5647_prev_settings),
+ .reg_snap = &ov5647_snap_settings[0],
+ .reg_snap_size = ARRAY_SIZE(ov5647_snap_settings),
+};
diff --git a/drivers/media/video/msm/ov7692.h b/drivers/media/video/msm/ov7692.h
index e43a17d..fc9cf1c 100644
--- a/drivers/media/video/msm/ov7692.h
+++ b/drivers/media/video/msm/ov7692.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, 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
@@ -14,6 +14,11 @@
#include <linux/types.h>
#include <mach/board.h>
+#define INVMASK(v) (0xff-v)
+#define OV7692Core_WritePREG(pTbl) OV7692_WritePRegs \
+ (pTbl, sizeof(pTbl)/sizeof(pTbl[0]))
+
+extern int lcd_camera_power_onoff(int on);
struct reg_addr_val_pair_struct {
uint8_t reg_addr;
uint8_t reg_val;
@@ -46,5 +51,616 @@
/* Not valid update */
UPDATE_INVALID
};
+
+/*OV SENSOR SCCB*/
+struct OV7692_WREG {
+ uint8_t addr;
+ uint8_t data;
+ uint8_t mask;
+} OV7692_WREG;
+
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+/* 96MHz PCLK @ 24MHz MCLK */
+struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
+ {0x12, 0x80},
+ {0x0e, 0x08},
+ {0x69, 0x52},
+ {0x1e, 0xb3},
+ {0x48, 0x42},
+ {0xff, 0x01},
+ {0xae, 0xa0},
+ {0xa8, 0x26},
+ {0xb4, 0xc0},
+ {0xb5, 0x40},
+ {0xff, 0x00},
+ {0x0c, 0x00},
+ {0x62, 0x10},
+ {0x12, 0x00},
+ {0x17, 0x65},
+ {0x18, 0xa4},
+ {0x19, 0x0a},
+ {0x1a, 0xf6},
+ {0x3e, 0x30},
+ {0x64, 0x0a},
+ {0xff, 0x01},
+ {0xb4, 0xc0},
+ {0xff, 0x00},
+ {0x67, 0x20},
+ {0x81, 0x3f},
+ {0xcc, 0x02},
+ {0xcd, 0x80},
+ {0xce, 0x01},
+ {0xcf, 0xe0},
+ {0xc8, 0x02},
+ {0xc9, 0x80},
+ {0xca, 0x01},
+ {0xcb, 0xe0},
+ {0xd0, 0x48},
+ {0x82, 0x03},
+ /*{0x0e, 0x00},*/
+ {0x70, 0x00},
+ {0x71, 0x34},
+ {0x74, 0x28},
+ {0x75, 0x98},
+ {0x76, 0x00},
+ {0x77, 0x64},
+ {0x78, 0x01},
+ {0x79, 0xc2},
+ {0x7a, 0x4e},
+ {0x7b, 0x1f},
+ {0x7c, 0x00},
+ {0x11, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x23},
+ {0x50, 0x9a},
+ {0x51, 0x80},
+ {0x4c, 0x7d},
+ /*{0x0e, 0x00},*/
+ {0x85, 0x10},
+ {0x86, 0x00},
+ {0x87, 0x00},
+ {0x88, 0x00},
+ {0x89, 0x2a},
+ {0x8a, 0x26},
+ {0x8b, 0x22},
+ {0xbb, 0x7a},
+ {0xbc, 0x69},
+ {0xbd, 0x11},
+ {0xbe, 0x13},
+ {0xbf, 0x81},
+ {0xc0, 0x96},
+ {0xc1, 0x1e},
+ {0xb7, 0x05},
+ {0xb8, 0x09},
+ {0xb9, 0x00},
+ {0xba, 0x18},
+ {0x5a, 0x1f},
+ {0x5b, 0x9f},
+ {0x5c, 0x6a},
+ {0x5d, 0x42},
+ {0x24, 0x78},
+ {0x25, 0x68},
+ {0x26, 0xb3},
+ {0xa3, 0x0b},
+ {0xa4, 0x15},
+ {0xa5, 0x2a},
+ {0xa6, 0x51},
+ {0xa7, 0x63},
+ {0xa8, 0x74},
+ {0xa9, 0x83},
+ {0xaa, 0x91},
+ {0xab, 0x9e},
+ {0xac, 0xaa},
+ {0xad, 0xbe},
+ {0xae, 0xce},
+ {0xaf, 0xe5},
+ {0xb0, 0xf3},
+ {0xb1, 0xfb},
+ {0xb2, 0x06},
+ {0x8c, 0x5c},
+ {0x8d, 0x11},
+ {0x8e, 0x12},
+ {0x8f, 0x19},
+ {0x90, 0x50},
+ {0x91, 0x20},
+ {0x92, 0x96},
+ {0x93, 0x80},
+ {0x94, 0x13},
+ {0x95, 0x1b},
+ {0x96, 0xff},
+ {0x97, 0x00},
+ {0x98, 0x3d},
+ {0x99, 0x36},
+ {0x9a, 0x51},
+ {0x9b, 0x43},
+ {0x9c, 0xf0},
+ {0x9d, 0xf0},
+ {0x9e, 0xf0},
+ {0x9f, 0xff},
+ {0xa0, 0x68},
+ {0xa1, 0x62},
+ {0xa2, 0x0e},
+};
+#endif
+/* Exposure Compensation */
+struct OV7692_WREG ov7692_exposure_compensation_lv0_tbl[] = {
+ /*@@ +1.7EV*/
+ {0x24, 0xc0},
+ {0x25, 0xb8},
+ {0x26, 0xe6},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv1_tbl[] = {
+ /*@@ +1.0EV*/
+ {0x24, 0xa8},
+ {0x25, 0xa0},
+ {0x26, 0xc4},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv2_default_tbl[] = {
+ /*@@ default*/
+ {0x24, 0x86},
+ {0x25, 0x76},
+ {0x26, 0xb3},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv3_tbl[] = {
+ /*@@ -1.0EV*/
+ {0x24, 0x70},
+ {0x25, 0x60},
+ {0x26, 0xa2},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv4_tbl[] = {
+ /*@@ -1.7EV*/
+ {0x24, 0x50},
+ {0x25, 0x40},
+ {0x26, 0xa2},
+};
+
+struct OV7692_WREG ov7692_antibanding_off_tbl[] = {
+ {0x13, 0xE5, INVMASK(0x20)},
+};
+
+struct OV7692_WREG ov7692_antibanding_auto_tbl[] = {
+ {0x13, 0x20, INVMASK(0x20)},
+ {0x14, 0x14, INVMASK(0x17)},
+};
+
+struct OV7692_WREG ov7692_antibanding_50z_tbl[] = {
+ /*Band 50Hz*/
+ {0x13, 0x20, INVMASK(0x20)},
+ {0x14, 0x17, INVMASK(0x17)},
+};
+
+struct OV7692_WREG ov7692_antibanding_60z_tbl[] = {
+ /*Band 60Hz*/
+ {0x13, 0x20, INVMASK(0x20)},
+ {0x14, 0x16, INVMASK(0x17)},
+};
+
+/*Saturation*/
+struct OV7692_WREG ov7692_saturation_lv0_tbl[] = {
+ /*Saturation level 0*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x00, INVMASK(0xff)},
+ {0xd9, 0x00, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv1_tbl[] = {
+ /*Saturation level 1*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x10, INVMASK(0xff)},
+ {0xd9, 0x10, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv2_tbl[] = {
+ /*Saturation level 2*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x20, INVMASK(0xff)},
+ {0xd9, 0x20, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+
+};
+
+struct OV7692_WREG ov7692_saturation_lv3_tbl[] = {
+ /*Saturation level 3*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x30, INVMASK(0xff)},
+ {0xd9, 0x30, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+
+};
+
+struct OV7692_WREG ov7692_saturation_default_lv4_tbl[] = {
+ /*Saturation level 4 (default)*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x40, INVMASK(0xff)},
+ {0xd9, 0x40, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv5_tbl[] = {
+ /*Saturation level 5*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x50, INVMASK(0xff)},
+ {0xd9, 0x50, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv6_tbl[] = {
+ /*Saturation level 6*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x60, INVMASK(0xff)},
+ {0xd9, 0x60, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv7_tbl[] = {
+ /*Saturation level 7*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x70, INVMASK(0xff)},
+ {0xd9, 0x70, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv8_tbl[] = {
+ /*Saturation level 8*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x80, INVMASK(0xff)},
+ {0xd9, 0x80, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+/*EFFECT*/
+struct OV7692_WREG ov7692_effect_normal_tbl[] = {
+ {0x81, 0x00, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x00, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_mono_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_bw_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_sepia_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x40, },
+ {0xdb, 0xa0, },
+};
+
+struct OV7692_WREG ov7692_effect_bluish_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0xc0, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_reddish_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x80, },
+ {0xdb, 0xc0, },
+};
+
+struct OV7692_WREG ov7692_effect_greenish_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x60, },
+ {0xdb, 0x60, },
+};
+
+struct OV7692_WREG ov7692_effect_negative_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x80, },
+ {0xd2, 0x40, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+/*Contrast*/
+struct OV7692_WREG ov7692_contrast_lv0_tbl[] = {
+ /*Contrast -4*/
+ {0xb2, 0x29},
+ {0xa3, 0x55},
+ {0xa4, 0x5b},
+ {0xa5, 0x67},
+ {0xa6, 0x7e},
+ {0xa7, 0x89},
+ {0xa8, 0x93},
+ {0xa9, 0x9c},
+ {0xaa, 0xa4},
+ {0xab, 0xac},
+ {0xac, 0xb3},
+ {0xad, 0xbe},
+ {0xae, 0xc7},
+ {0xaf, 0xd5},
+ {0xb0, 0xdd},
+ {0xb1, 0xe1},
+};
+
+struct OV7692_WREG ov7692_contrast_lv1_tbl[] = {
+ /*Contrast -3*/
+ {0xb2, 0x20},
+ {0xa3, 0x43},
+ {0xa4, 0x4a},
+ {0xa5, 0x58},
+ {0xa6, 0x73},
+ {0xa7, 0x80},
+ {0xa8, 0x8b},
+ {0xa9, 0x96},
+ {0xaa, 0x9f},
+ {0xab, 0xa8},
+ {0xac, 0xb1},
+ {0xad, 0xbe},
+ {0xae, 0xc9},
+ {0xaf, 0xd8},
+ {0xb0, 0xe2},
+ {0xb1, 0xe8},
+};
+
+struct OV7692_WREG ov7692_contrast_lv2_tbl[] = {
+ /*Contrast -2*/
+ {0xb2, 0x18},
+ {0xa3, 0x31},
+ {0xa4, 0x39},
+ {0xa5, 0x4a},
+ {0xa6, 0x68},
+ {0xa7, 0x77},
+ {0xa8, 0x84},
+ {0xa9, 0x90},
+ {0xaa, 0x9b},
+ {0xab, 0xa5},
+ {0xac, 0xaf},
+ {0xad, 0xbe},
+ {0xae, 0xca},
+ {0xaf, 0xdc},
+ {0xb0, 0xe7},
+ {0xb1, 0xee},
+};
+
+struct OV7692_WREG ov7692_contrast_lv3_tbl[] = {
+ /*Contrast -1*/
+ {0xb2, 0x10},
+ {0xa3, 0x1f},
+ {0xa4, 0x28},
+ {0xa5, 0x3b},
+ {0xa6, 0x5d},
+ {0xa7, 0x6e},
+ {0xa8, 0x7d},
+ {0xa9, 0x8a},
+ {0xaa, 0x96},
+ {0xab, 0xa2},
+ {0xac, 0xad},
+ {0xad, 0xbe},
+ {0xae, 0xcc},
+ {0xaf, 0xe0},
+ {0xb0, 0xed},
+ {0xb1, 0xf4},
+};
+
+struct OV7692_WREG ov7692_contrast_default_lv4_tbl[] = {
+ /*Contrast 0*/
+ {0xb2, 0x6},
+ {0xa3, 0xb},
+ {0xa4, 0x15},
+ {0xa5, 0x2a},
+ {0xa6, 0x51},
+ {0xa7, 0x63},
+ {0xa8, 0x74},
+ {0xa9, 0x83},
+ {0xaa, 0x91},
+ {0xab, 0x9e},
+ {0xac, 0xaa},
+ {0xad, 0xbe},
+ {0xae, 0xce},
+ {0xaf, 0xe5},
+ {0xb0, 0xf3},
+ {0xb1, 0xfb},
+};
+
+struct OV7692_WREG ov7692_contrast_lv5_tbl[] = {
+ /*Contrast 1*/
+ {0xb2, 0xc},
+ {0xa3, 0x4},
+ {0xa4, 0xc},
+ {0xa5, 0x1f},
+ {0xa6, 0x45},
+ {0xa7, 0x58},
+ {0xa8, 0x6b},
+ {0xa9, 0x7c},
+ {0xaa, 0x8d},
+ {0xab, 0x9d},
+ {0xac, 0xac},
+ {0xad, 0xc3},
+ {0xae, 0xd2},
+ {0xaf, 0xe8},
+ {0xb0, 0xf2},
+ {0xb1, 0xf7},
+};
+
+struct OV7692_WREG ov7692_contrast_lv6_tbl[] = {
+ /*Contrast 2*/
+ {0xb2, 0x1},
+ {0xa3, 0x2},
+ {0xa4, 0x9},
+ {0xa5, 0x1a},
+ {0xa6, 0x3e},
+ {0xa7, 0x4a},
+ {0xa8, 0x59},
+ {0xa9, 0x6a},
+ {0xaa, 0x79},
+ {0xab, 0x8e},
+ {0xac, 0xa4},
+ {0xad, 0xc1},
+ {0xae, 0xdb},
+ {0xaf, 0xf4},
+ {0xb0, 0xff},
+ {0xb1, 0xff},
+};
+
+struct OV7692_WREG ov7692_contrast_lv7_tbl[] = {
+ /*Contrast 3*/
+ {0xb2, 0xc},
+ {0xa3, 0x4},
+ {0xa4, 0x8},
+ {0xa5, 0x17},
+ {0xa6, 0x27},
+ {0xa7, 0x3d},
+ {0xa8, 0x54},
+ {0xa9, 0x60},
+ {0xaa, 0x77},
+ {0xab, 0x85},
+ {0xac, 0xa4},
+ {0xad, 0xc6},
+ {0xae, 0xd2},
+ {0xaf, 0xe9},
+ {0xb0, 0xf0},
+ {0xb1, 0xf7},
+};
+
+struct OV7692_WREG ov7692_contrast_lv8_tbl[] = {
+ /*Contrast 4*/
+ {0xb2, 0x1},
+ {0xa3, 0x4},
+ {0xa4, 0x4},
+ {0xa5, 0x7},
+ {0xa6, 0xb},
+ {0xa7, 0x17},
+ {0xa8, 0x2a},
+ {0xa9, 0x41},
+ {0xaa, 0x59},
+ {0xab, 0x6b},
+ {0xac, 0x8b},
+ {0xad, 0xb1},
+ {0xae, 0xd2},
+ {0xaf, 0xea},
+ {0xb0, 0xf4},
+ {0xb1, 0xff},
+};
+
+ /*Sharpness*/
+struct OV7692_WREG ov7692_sharpness_lv0_tbl[] = {
+ /*Sharpness 0*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x00, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv1_tbl[] = {
+ /*Sharpness 1*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x01, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_default_lv2_tbl[] = {
+ /*Sharpness Auto (Default)*/
+ {0xb4, 0x00, INVMASK(0x20)},
+ {0xb6, 0x00, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv3_tbl[] = {
+ /*Sharpness 3*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x66, INVMASK(0x04)},
+};
+struct OV7692_WREG ov7692_sharpness_lv4_tbl[] = {
+ /*Sharpness 4*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x99, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv5_tbl[] = {
+ /*Sharpness 5*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0xcc, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv6_tbl[] = {
+ /*Sharpness 6*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0xff, INVMASK(0x1f)},
+};
+
+ /* ISO TYPE*/
+struct OV7692_WREG ov7692_iso_type_auto[] = {
+ /*@@ISO Auto*/
+ {0x14, 0x20, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_100[] = {
+ /*@@ISO 100*/
+ {0x14, 0x00, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_200[] = {
+ /*@@ISO 200*/
+ {0x14, 0x10, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_400[] = {
+ /*@@ISO 400*/
+ {0x14, 0x20, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_800[] = {
+ /*@@ISO 800*/
+ {0x14, 0x30, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_1600[] = {
+ /*@@ISO 1600*/
+ {0x14, 0x40, INVMASK(0x70)},
+};
+
+ /*Light Mode*/
+struct OV7692_WREG ov7692_wb_def[] = {
+ {0x13, 0xf7},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_custom[] = {
+ {0x13, 0xf5},
+ {0x01, 0x56},
+ {0x02, 0x50},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_inc[] = {
+ {0x13, 0xf5},
+ {0x01, 0x66},
+ {0x02, 0x40},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_daylight[] = {
+ {0x13, 0xf5},
+ {0x01, 0x43},
+ {0x02, 0x5d},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_cloudy[] = {
+ {0x13, 0xf5},
+ {0x01, 0x48},
+ {0x02, 0x63},
+ {0x15, 0x00},
+};
+
#endif
diff --git a/drivers/media/video/msm/ov7692_qrd.c b/drivers/media/video/msm/ov7692_qrd.c
index e558e57..d83f28e 100644
--- a/drivers/media/video/msm/ov7692_qrd.c
+++ b/drivers/media/video/msm/ov7692_qrd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -10,8 +10,6 @@
* GNU General Public License for more details.
*/
-/* #define DEBUG */
-
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/i2c.h>
@@ -52,129 +50,9 @@
/*============================================================================
- DATA DECLARATIONS
- ============================================================================*/
-/* 96MHz PCLK @ 24MHz MCLK */
-struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
- {0x12, 0x80},
- {0x0e, 0x08},
- {0x69, 0x52},
- {0x1e, 0xb3},
- {0x48, 0x42},
- {0xff, 0x01},
- {0xae, 0xa0},
- {0xa8, 0x26},
- {0xb4, 0xc0},
- {0xb5, 0x40},
- {0xff, 0x00},
- {0x0c, 0x00},
- {0x62, 0x10},
- {0x12, 0x00},
- {0x17, 0x65},
- {0x18, 0xa4},
- {0x19, 0x0a},
- {0x1a, 0xf6},
- {0x3e, 0x30},
- {0x64, 0x0a},
- {0xff, 0x01},
- {0xb4, 0xc0},
- {0xff, 0x00},
- {0x67, 0x20},
- {0x81, 0x3f},
- {0xcc, 0x02},
- {0xcd, 0x80},
- {0xce, 0x01},
- {0xcf, 0xe0},
- {0xc8, 0x02},
- {0xc9, 0x80},
- {0xca, 0x01},
- {0xcb, 0xe0},
- {0xd0, 0x48},
- {0x82, 0x03},
- {0x0e, 0x00},
- {0x70, 0x00},
- {0x71, 0x34},
- {0x74, 0x28},
- {0x75, 0x98},
- {0x76, 0x00},
- {0x77, 0x64},
- {0x78, 0x01},
- {0x79, 0xc2},
- {0x7a, 0x4e},
- {0x7b, 0x1f},
- {0x7c, 0x00},
- {0x11, 0x00},
- {0x20, 0x00},
- {0x21, 0x23},
- {0x50, 0x9a},
- {0x51, 0x80},
- {0x4c, 0x7d},
- {0x0e, 0x00},
- {0x85, 0x10},
- {0x86, 0x00},
- {0x87, 0x00},
- {0x88, 0x00},
- {0x89, 0x2a},
- {0x8a, 0x26},
- {0x8b, 0x22},
- {0xbb, 0x7a},
- {0xbc, 0x69},
- {0xbd, 0x11},
- {0xbe, 0x13},
- {0xbf, 0x81},
- {0xc0, 0x96},
- {0xc1, 0x1e},
- {0xb7, 0x05},
- {0xb8, 0x09},
- {0xb9, 0x00},
- {0xba, 0x18},
- {0x5a, 0x1f},
- {0x5b, 0x9f},
- {0x5c, 0x6a},
- {0x5d, 0x42},
- {0x24, 0x78},
- {0x25, 0x68},
- {0x26, 0xb3},
- {0xa3, 0x0b},
- {0xa4, 0x15},
- {0xa5, 0x2a},
- {0xa6, 0x51},
- {0xa7, 0x63},
- {0xa8, 0x74},
- {0xa9, 0x83},
- {0xaa, 0x91},
- {0xab, 0x9e},
- {0xac, 0xaa},
- {0xad, 0xbe},
- {0xae, 0xce},
- {0xaf, 0xe5},
- {0xb0, 0xf3},
- {0xb1, 0xfb},
- {0xb2, 0x06},
- {0x8c, 0x5c},
- {0x8d, 0x11},
- {0x8e, 0x12},
- {0x8f, 0x19},
- {0x90, 0x50},
- {0x91, 0x20},
- {0x92, 0x96},
- {0x93, 0x80},
- {0x94, 0x13},
- {0x95, 0x1b},
- {0x96, 0xff},
- {0x97, 0x00},
- {0x98, 0x3d},
- {0x99, 0x36},
- {0x9a, 0x51},
- {0x9b, 0x43},
- {0x9c, 0xf0},
- {0x9d, 0xf0},
- {0x9e, 0xf0},
- {0x9f, 0xff},
- {0xa0, 0x68},
- {0xa1, 0x62},
- {0xa2, 0x0e},
-};
+ DATA DECLARATIONS
+============================================================================*/
+
static bool OV7692_CSI_CONFIG;
/* 816x612, 24MHz MCLK 96MHz PCLK */
@@ -214,6 +92,10 @@
static struct ov7692_ctrl_t *ov7692_ctrl;
static DECLARE_WAIT_QUEUE_HEAD(ov7692_wait_queue);
DEFINE_MUTEX(ov7692_mut);
+static int effect_value;
+static int16_t ov7692_effect = CAMERA_EFFECT_OFF;
+static unsigned int SAT_U = 0x80;
+static unsigned int SAT_V = 0x80;
/*=============================================================*/
@@ -284,14 +166,33 @@
memset(buf, 0, sizeof(buf));
buf[0] = waddr;
buf[1] = bdata;
-
+ CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
rc = ov7692_i2c_txdata(ov7692_client->addr >> 1, buf, 2);
if (rc < 0)
CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
- waddr, bdata);
+ waddr, bdata);
+
return rc;
}
+static int32_t OV7692_WritePRegs(struct OV7692_WREG *pTb, int32_t len)
+{
+ int32_t i, ret = 0;
+ uint8_t regv;
+
+ for (i = 0; i < len; i++) {
+ if (pTb[i].mask == 0) {
+ ov7692_i2c_write_b_sensor(pTb[i].addr, pTb[i].data);
+ } else {
+ ov7692_i2c_read(pTb[i].addr, ®v, 1);
+ regv &= pTb[i].mask;
+ regv |= (pTb[i].data & (~pTb[i].mask));
+ ov7692_i2c_write_b_sensor(pTb[i].addr, regv);
+ }
+ }
+ return ret;
+}
+
static int32_t ov7692_sensor_setting(int update_type, int rt)
{
int32_t i, array_length;
@@ -314,8 +215,6 @@
ov7692_csi_params.dpcm_scheme = 0;
ov7692_csi_params.settle_cnt = 0x14;
- rc = msm_camio_csi_config(&ov7692_csi_params);
- msleep(20);
array_length = sizeof(ov7692_init_settings_array) /
sizeof(ov7692_init_settings_array[0]);
for (i = 0; i < array_length; i++) {
@@ -325,6 +224,10 @@
if (rc < 0)
return rc;
}
+ usleep_range(10000, 11000);
+ rc = msm_camio_csi_config(&ov7692_csi_params);
+ usleep_range(10000, 11000);
+ ov7692_i2c_write_b_sensor(0x0e, 0x00);
OV7692_CSI_CONFIG = 1;
msleep(20);
return rc;
@@ -371,6 +274,442 @@
return rc;
}
+static int ov7692_set_exposure_compensation(int compensation)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...exposure_compensation = %d\n",
+ __func__ , compensation);
+ switch (compensation) {
+ case CAMERA_EXPOSURE_COMPENSATION_LV0:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV0\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv0_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV1:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV1\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv1_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV2:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV2\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv2_default_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV3:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv3_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV4:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv4_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--ERROR CAMERA_EXPOSURE_COMPENSATION\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static long ov7692_set_antibanding(int antibanding)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...antibanding = %d\n", __func__, antibanding);
+ switch (antibanding) {
+ case CAMERA_ANTIBANDING_OFF:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_OFF\n");
+ break;
+ case CAMERA_ANTIBANDING_60HZ:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_60HZ\n");
+ rc = OV7692Core_WritePREG(ov7692_antibanding_60z_tbl);
+ break;
+ case CAMERA_ANTIBANDING_50HZ:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_50HZ\n");
+ rc = OV7692Core_WritePREG(ov7692_antibanding_50z_tbl);
+ break;
+ case CAMERA_ANTIBANDING_AUTO:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_AUTO\n");
+ rc = OV7692Core_WritePREG(ov7692_antibanding_auto_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_ERROR COMMAND\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_saturation(int saturation)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...saturation = %d\n", __func__ , saturation);
+
+ if (effect_value == CAMERA_EFFECT_OFF) {
+ switch (saturation) {
+ case CAMERA_SATURATION_LV0:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv0_tbl);
+ break;
+ case CAMERA_SATURATION_LV1:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv1_tbl);
+ break;
+ case CAMERA_SATURATION_LV2:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv2_tbl);
+ break;
+ case CAMERA_SATURATION_LV3:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv3_tbl);
+ break;
+ case CAMERA_SATURATION_LV4:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_saturation_default_lv4_tbl);
+ break;
+ case CAMERA_SATURATION_LV5:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv5_tbl);
+ break;
+ case CAMERA_SATURATION_LV6:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv6_tbl);
+ break;
+ case CAMERA_SATURATION_LV7:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv7_tbl);
+ break;
+ case CAMERA_SATURATION_LV8:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv8_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+ break;
+ }
+ }
+
+ /*for recover saturation level when change special effect*/
+ switch (saturation) {
+ case CAMERA_SATURATION_LV0:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+ SAT_U = 0x00;
+ SAT_V = 0x00;
+ break;
+ case CAMERA_SATURATION_LV1:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+ SAT_U = 0x10;
+ SAT_V = 0x10;
+ break;
+ case CAMERA_SATURATION_LV2:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+ SAT_U = 0x20;
+ SAT_V = 0x20;
+ break;
+ case CAMERA_SATURATION_LV3:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+ SAT_U = 0x30;
+ SAT_V = 0x30;
+ break;
+ case CAMERA_SATURATION_LV4:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+ SAT_U = 0x40;
+ SAT_V = 0x40;
+ break;
+ case CAMERA_SATURATION_LV5:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+ SAT_U = 0x50;
+ SAT_V = 0x50;
+ break;
+ case CAMERA_SATURATION_LV6:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+ SAT_U = 0x60;
+ SAT_V = 0x60;
+ break;
+ case CAMERA_SATURATION_LV7:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+ SAT_U = 0x70;
+ SAT_V = 0x70;
+ break;
+ case CAMERA_SATURATION_LV8:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+ SAT_U = 0x80;
+ SAT_V = 0x80;
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static long ov7692_set_effect(int mode, int effect)
+{
+ int rc = 0;
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+
+ switch (mode) {
+ case SENSOR_PREVIEW_MODE:
+ break;
+ case SENSOR_HFR_60FPS_MODE:
+ break;
+ case SENSOR_HFR_90FPS_MODE:
+ /* Context A Special Effects */
+ CDBG("-CAMERA- %s ...SENSOR_PREVIEW_MODE\n", __func__);
+ break;
+ case SENSOR_SNAPSHOT_MODE:
+ /* Context B Special Effects */
+ CDBG("-CAMERA- %s ...SENSOR_SNAPSHOT_MODE\n", __func__);
+ break;
+ default:
+ break;
+ }
+ effect_value = effect;
+ switch (effect) {
+ case CAMERA_EFFECT_OFF: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_OFF\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_normal_tbl);
+ /* for recover saturation level
+ when change special effect*/
+ ov7692_i2c_write_b_sensor(0xda, SAT_U);
+ /* for recover saturation level
+ when change special effect*/
+ ov7692_i2c_write_b_sensor(0xdb, SAT_V);
+ break;
+ }
+ case CAMERA_EFFECT_MONO: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_MONO\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_mono_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_BW: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BW\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_bw_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_BLUISH: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BLUISH\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_bluish_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_SOLARIZE: {
+ CDBG("%s ...CAMERA_EFFECT_NEGATIVE(No Support)!\n", __func__);
+ break;
+ }
+ case CAMERA_EFFECT_SEPIA: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_SEPIA\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_sepia_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_REDDISH: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_REDDISH\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_reddish_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_GREENISH: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_GREENISH\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_greenish_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_NEGATIVE: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_negative_tbl);
+ break;
+ }
+ default: {
+ CDBG("--CAMERA-- %s ...Default(Not Support)\n", __func__);
+ }
+ }
+ ov7692_effect = effect;
+ /*Refresh Sequencer */
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_contrast(int contrast)
+{
+ int rc = 0;
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...contrast = %d\n", __func__ , contrast);
+
+ if (effect_value == CAMERA_EFFECT_OFF) {
+ switch (contrast) {
+ case CAMERA_CONTRAST_LV0:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV0\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv0_tbl);
+ break;
+ case CAMERA_CONTRAST_LV1:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV1\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv1_tbl);
+ break;
+ case CAMERA_CONTRAST_LV2:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV2\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv2_tbl);
+ break;
+ case CAMERA_CONTRAST_LV3:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV3\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv3_tbl);
+ break;
+ case CAMERA_CONTRAST_LV4:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV4\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_contrast_default_lv4_tbl);
+ break;
+ case CAMERA_CONTRAST_LV5:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV5\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv5_tbl);
+ break;
+ case CAMERA_CONTRAST_LV6:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV6\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv6_tbl);
+ break;
+ case CAMERA_CONTRAST_LV7:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV7\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv7_tbl);
+ break;
+ case CAMERA_CONTRAST_LV8:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV8\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv8_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_CONTRAST_ERROR COMMAND\n");
+ break;
+ }
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_sharpness(int sharpness)
+{
+ int rc = 0;
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...sharpness = %d\n", __func__ , sharpness);
+
+ if (effect_value == CAMERA_EFFECT_OFF) {
+ switch (sharpness) {
+ case CAMERA_SHARPNESS_LV0:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV0\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv0_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV1:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV1\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv1_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV2:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV2\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_sharpness_default_lv2_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV3:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV3\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv3_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV4:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV4\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv4_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV5:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV5\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv5_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV6:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV6\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv6_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_ERROR COMMAND\n");
+ break;
+ }
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_iso(int8_t iso_type)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...iso_type = %d\n", __func__ , iso_type);
+ switch (iso_type) {
+ case CAMERA_ISO_TYPE_AUTO:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_AUTO\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
+ break;
+ case CAMEAR_ISO_TYPE_HJR:
+ CDBG("--CAMERA--CAMEAR_ISO_TYPE_HJR\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
+ break;
+ case CAMEAR_ISO_TYPE_100:
+ CDBG("--CAMERA--CAMEAR_ISO_TYPE_100\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_100);
+ break;
+ case CAMERA_ISO_TYPE_200:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_200\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_200);
+ break;
+ case CAMERA_ISO_TYPE_400:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_400\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_400);
+ break;
+ case CAMEAR_ISO_TYPE_800:
+ CDBG("--CAMERA--CAMEAR_ISO_TYPE_800\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_800);
+ break;
+ case CAMERA_ISO_TYPE_1600:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_1600\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_1600);
+ break;
+ default:
+ CDBG("--CAMERA--ERROR ISO TYPE\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_wb_oem(uint8_t param)
+{
+ int rc = 0;
+ CDBG("--CAMERA--%s runs\r\n", __func__);
+
+ switch (param) {
+ case CAMERA_WB_AUTO:
+ CDBG("--CAMERA--CAMERA_WB_AUTO\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_def);
+ break;
+ case CAMERA_WB_CUSTOM:
+ CDBG("--CAMERA--CAMERA_WB_CUSTOM\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_custom);
+ break;
+ case CAMERA_WB_INCANDESCENT:
+ CDBG("--CAMERA--CAMERA_WB_INCANDESCENT\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_inc);
+ break;
+ case CAMERA_WB_DAYLIGHT:
+ CDBG("--CAMERA--CAMERA_WB_DAYLIGHT\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_daylight);
+ break;
+ case CAMERA_WB_CLOUDY_DAYLIGHT:
+ CDBG("--CAMERA--CAMERA_WB_CLOUDY_DAYLIGHT\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_cloudy);
+ break;
+ default:
+ break;
+ }
+ return rc;
+}
+
static void ov7692_power_on(void)
{
CDBG("%s\n", __func__);
@@ -392,13 +731,12 @@
static void ov7692_hw_reset(void)
{
CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
- gpio_set_value(ov7692_reset_gpio, 1); /* reset camera reset pin */
- msleep(20);
+ gpio_set_value(ov7692_reset_gpio, 1); /*reset camera reset pin*/
+ usleep_range(5000, 5100);
gpio_set_value(ov7692_reset_gpio, 0);
- msleep(20);
+ usleep_range(5000, 5100);
gpio_set_value(ov7692_reset_gpio, 1);
- msleep(20);
-
+ usleep_range(1000, 1100);
CDBG("--CAMERA-- %s ... (End...)\n", __func__);
}
@@ -458,6 +796,9 @@
if (data)
ov7692_ctrl->sensordata = data;
+ /* turn on LDO for PVT */
+ if (data->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
/* enable mclk first */
@@ -465,7 +806,7 @@
msleep(20);
ov7692_power_on();
- msleep(20);
+ usleep_range(5000, 5100);
rc = ov7692_probe_init_sensor(data);
if (rc < 0) {
@@ -481,6 +822,8 @@
init_fail:
CDBG(" ov7692_sensor_open_init fail\n");
+ if (data->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
kfree(ov7692_ctrl);
init_done:
CDBG("ov7692_sensor_open_init done\n");
@@ -559,14 +902,160 @@
CDBG("ov7692_sensor_config: cfgtype = %d\n", cdata.cfgtype);
switch (cdata.cfgtype) {
case CFG_SET_MODE:
- rc = ov7692_set_sensor_mode(cdata.mode,
- cdata.rs);
+ rc = ov7692_set_sensor_mode(cdata.mode, cdata.rs);
+ break;
+ case CFG_SET_EFFECT:
+ CDBG("--CAMERA-- CFG_SET_EFFECT mode=%d, effect = %d !!\n",
+ cdata.mode, cdata.cfg.effect);
+ rc = ov7692_set_effect(cdata.mode, cdata.cfg.effect);
+ break;
+ case CFG_START:
+ CDBG("--CAMERA-- CFG_START (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_PWR_UP:
+ CDBG("--CAMERA-- CFG_PWR_UP (Not Support) !!\n");
+ /* Not Support */
break;
case CFG_PWR_DOWN:
+ CDBG("--CAMERA-- CFG_PWR_DOWN !!\n");
ov7692_power_down();
break;
+ case CFG_WRITE_EXPOSURE_GAIN:
+ CDBG("--CAMERA-- CFG_WRITE_EXPOSURE_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_DEFAULT_FOCUS:
+ CDBG("--CAMERA-- CFG_SET_DEFAULT_FOCUS (Not Implement) !!\n");
+ break;
+ case CFG_MOVE_FOCUS:
+ CDBG("--CAMERA-- CFG_MOVE_FOCUS (Not Implement) !!\n");
+ break;
+ case CFG_REGISTER_TO_REAL_GAIN:
+ CDBG("--CAMERA-- CFG_REGISTER_TO_REAL_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_REAL_TO_REGISTER_GAIN:
+ CDBG("--CAMERA-- CFG_REAL_TO_REGISTER_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_FPS:
+ CDBG("--CAMERA-- CFG_SET_FPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_PICT_FPS:
+ CDBG("--CAMERA-- CFG_SET_PICT_FPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_BRIGHTNESS:
+ CDBG("--CAMERA-- CFG_SET_BRIGHTNESS !!\n");
+ /* rc = ov7692_set_brightness(cdata.cfg.brightness); */
+ break;
+ case CFG_SET_CONTRAST:
+ CDBG("--CAMERA-- CFG_SET_CONTRAST !!\n");
+ rc = ov7692_set_contrast(cdata.cfg.contrast);
+ break;
+ case CFG_SET_ZOOM:
+ CDBG("--CAMERA-- CFG_SET_ZOOM (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_EXPOSURE_MODE:
+ CDBG("--CAMERA-- CFG_SET_EXPOSURE_MODE !!\n");
+ /* rc = ov7692_set_exposure_mode(cdata.cfg.ae_mode); */
+ break;
+ case CFG_SET_WB:
+ CDBG("--CAMERA-- CFG_SET_WB!!\n");
+ ov7692_set_wb_oem(cdata.cfg.wb_val);
+ rc = 0 ;
+ break;
+ case CFG_SET_ANTIBANDING:
+ CDBG("--CAMERA-- CFG_SET_ANTIBANDING antibanding = %d !!\n",
+ cdata.cfg.antibanding);
+ rc = ov7692_set_antibanding(cdata.cfg.antibanding);
+ break;
+ case CFG_SET_EXP_GAIN:
+ CDBG("--CAMERA-- CFG_SET_EXP_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_PICT_EXP_GAIN:
+ CDBG("--CAMERA-- CFG_SET_PICT_EXP_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_LENS_SHADING:
+ CDBG("--CAMERA-- CFG_SET_LENS_SHADING !!\n");
+ /* rc = ov7692_lens_shading_enable(cdata.cfg.lens_shading); */
+ break;
+ case CFG_GET_PICT_FPS:
+ CDBG("--CAMERA-- CFG_GET_PICT_FPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PREV_L_PF:
+ CDBG("--CAMERA-- CFG_GET_PREV_L_PF (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PREV_P_PL:
+ CDBG("--CAMERA-- CFG_GET_PREV_P_PL (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PICT_L_PF:
+ CDBG("--CAMERA-- CFG_GET_PICT_L_PF (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PICT_P_PL:
+ CDBG("--CAMERA-- CFG_GET_PICT_P_PL (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_AF_MAX_STEPS:
+ CDBG("--CAMERA-- CFG_GET_AF_MAX_STEPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PICT_MAX_EXP_LC:
+ CDBG("--CAMERA-- CFG_GET_PICT_MAX_EXP_LC (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SEND_WB_INFO:
+ CDBG("--CAMERA-- CFG_SEND_WB_INFO (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SENSOR_INIT:
+ CDBG("--CAMERA-- CFG_SENSOR_INIT (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_SATURATION:
+ CDBG("--CAMERA-- CFG_SET_SATURATION !!\n");
+ rc = ov7692_set_saturation(cdata.cfg.saturation);
+ break;
+ case CFG_SET_SHARPNESS:
+ CDBG("--CAMERA-- CFG_SET_SHARPNESS !!\n");
+ rc = ov7692_set_sharpness(cdata.cfg.sharpness);
+ break;
+ case CFG_SET_TOUCHAEC:
+ CDBG("--CAMERA-- CFG_SET_TOUCHAEC!!\n");
+ /* ov7692_set_touchaec(cdata.cfg.aec_cord.x,
+ cdata.cfg.aec_cord.y); */
+ rc = 0 ;
+ break;
+ case CFG_SET_AUTO_FOCUS:
+ CDBG("--CAMERA-- CFG_SET_AUTO_FOCUS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_AUTOFLASH:
+ CDBG("--CAMERA-- CFG_SET_AUTOFLASH (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_EXPOSURE_COMPENSATION:
+ CDBG("--CAMERA-- CFG_SET_EXPOSURE_COMPENSATION !\n");
+ rc = ov7692_set_exposure_compensation(
+ cdata.cfg.exp_compensation);
+ break;
+ case CFG_SET_ISO:
+ CDBG("--CAMERA-- CFG_SET_ISO !\n");
+ rc = ov7692_set_iso(cdata.cfg.iso_type);
+ break;
default:
- rc = -EFAULT;
+ CDBG("--CAMERA-- %s: Command=%d (Not Implement) !!\n",
+ __func__, cdata.cfgtype);
+ rc = -EINVAL;
break;
}
@@ -577,6 +1066,7 @@
static int ov7692_sensor_release(void)
{
int rc = -EBADF;
+
mutex_lock(&ov7692_mut);
ov7692_sw_reset();
ov7692_power_down();
@@ -614,20 +1104,23 @@
rc = -ENOTSUPP;
goto probe_fail;
}
-
+ pr_debug("%s: %d Entered\n", __func__, __LINE__);
rc = ov7692_probe_init_gpio(info);
if (rc < 0) {
CDBG("%s: gpio init failed\n", __func__);
goto probe_fail;
}
+ /* turn on LDO for PVT */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
ov7692_power_down();
msm_camio_clk_rate_set(24000000);
- msleep(20);
+ usleep_range(5000, 5100);
ov7692_power_on();
- msleep(20);
+ usleep_range(5000, 5100);
if (info->sensor_reset_enable)
ov7692_hw_reset();
@@ -645,12 +1138,18 @@
s->s_camera_type = FRONT_CAMERA_2D;
s->s_mount_angle = info->sensor_platform_info->mount_angle;
+ /* ov7692_sw_reset(); */
ov7692_power_down();
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
+
return rc;
probe_fail:
CDBG("ov7692_sensor_probe: SENSOR PROBE FAILS!\n");
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
i2c_del_driver(&ov7692_i2c_driver);
return rc;
}
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 7305e51..e0a04dc 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -765,8 +765,16 @@
#define CFG_GET_OUTPUT_INFO 32
#define CFG_GET_EEPROM_DATA 33
#define CFG_SET_ACTUATOR_INFO 34
-#define CFG_GET_ACTUATOR_INFO 35
-#define CFG_MAX 36
+#define CFG_GET_ACTUATOR_INFO 35
+/* TBD: QRD */
+#define CFG_SET_SATURATION 36
+#define CFG_SET_SHARPNESS 37
+#define CFG_SET_TOUCHAEC 38
+#define CFG_SET_AUTO_FOCUS 39
+#define CFG_SET_AUTOFLASH 40
+#define CFG_SET_EXPOSURE_COMPENSATION 41
+#define CFG_SET_ISO 42
+#define CFG_MAX 43
#define MOVE_NEAR 0
@@ -857,14 +865,6 @@
#define CAMERA_SETAE_AVERAGE 0
#define CAMERA_SETAE_CENWEIGHT 1
-#define CFG_SET_SATURATION 30
-#define CFG_SET_SHARPNESS 31
-#define CFG_SET_TOUCHAEC 32
-#define CFG_SET_AUTO_FOCUS 33
-#define CFG_SET_AUTOFLASH 34
-/* QRD */
-#define CFG_SET_EXPOSURE_COMPENSATION 35
-
#define CAMERA_WB_AUTO 1 /* This list must match aeecamera.h */
#define CAMERA_WB_CUSTOM 2
#define CAMERA_WB_INCANDESCENT 3
@@ -948,6 +948,14 @@
MSM_V4L2_POWER_LINE_AUTO,
};
+#define CAMERA_ISO_TYPE_AUTO 0
+#define CAMEAR_ISO_TYPE_HJR 1
+#define CAMEAR_ISO_TYPE_100 2
+#define CAMERA_ISO_TYPE_200 3
+#define CAMERA_ISO_TYPE_400 4
+#define CAMEAR_ISO_TYPE_800 5
+#define CAMERA_ISO_TYPE_1600 6
+
struct sensor_pict_fps {
uint16_t prevfps;
uint16_t pictfps;
@@ -1083,6 +1091,7 @@
uint16_t pictp_pl;
uint32_t pict_max_exp_lc;
uint16_t p_fps;
+ uint8_t iso_type;
struct sensor_init_cfg init_info;
struct sensor_pict_fps gfps;
struct exp_gain_cfg exp_gain;