From e8da1c2b25d18ead904ba129ffd0b57a8da283bb Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Thu, 31 Mar 2016 11:16:11 +0300 Subject: [PATCH] OV5645: Hack: Use CCI This will be fixed when CCI driver is implemented. Signed-off-by: Todor Tomov --- drivers/media/i2c/ov5645.c | 40 ++++---- drivers/media/platform/msm/cci/msm_cci.c | 113 ++++++++++++++++++++++- drivers/media/platform/msm/cci/msm_cci.h | 6 ++ 3 files changed, 140 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 97031b10621a..4a7bf2448c16 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -42,6 +42,15 @@ #include #include +/* HACKs here! */ + +#include <../drivers/media/platform/msm/cci/msm_cci.h> + +#ifdef dev_dbg + #undef dev_dbg + #define dev_dbg dev_err +#endif + #define OV5645_VOLTAGE_ANALOG 2800000 #define OV5645_VOLTAGE_DIGITAL_CORE 1500000 #define OV5645_VOLTAGE_DIGITAL_IO 1800000 @@ -124,6 +133,8 @@ struct ov5645 { struct gpio_desc *enable_gpio; struct gpio_desc *rst_gpio; + + struct v4l2_subdev *cci; }; static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd) @@ -594,14 +605,9 @@ static void ov5645_regulators_disable(struct ov5645 *ov5645) static int ov5645_write_reg(struct ov5645 *ov5645, u16 reg, u8 val) { - u8 regbuf[3]; int ret; - regbuf[0] = reg >> 8; - regbuf[1] = reg & 0xff; - regbuf[2] = val; - - ret = i2c_master_send(ov5645->i2c_client, regbuf, 3); + ret = msm_cci_ctrl_write(reg, &val, 1); if (ret < 0) dev_err(ov5645->dev, "%s: write reg error %d: reg=%x, val=%x\n", __func__, ret, reg, val); @@ -611,21 +617,10 @@ static int ov5645_write_reg(struct ov5645 *ov5645, u16 reg, u8 val) static int ov5645_read_reg(struct ov5645 *ov5645, u16 reg, u8 *val) { - u8 regbuf[2]; u8 tmpval; int ret; - regbuf[0] = reg >> 8; - regbuf[1] = reg & 0xff; - - ret = i2c_master_send(ov5645->i2c_client, regbuf, 2); - if (ret < 0) { - dev_err(ov5645->dev, "%s: write reg error %d: reg=%x\n", - __func__, ret, reg); - return ret; - } - - ret = i2c_master_recv(ov5645->i2c_client, &tmpval, 1); + ret = msm_cci_ctrl_read(reg, &tmpval, 1); if (ret < 0) { dev_err(ov5645->dev, "%s: read reg error %d: reg=%x\n", __func__, ret, reg); @@ -770,6 +765,12 @@ static int ov5645_s_power(struct v4l2_subdev *sd, int on) mutex_lock(&ov5645->power_lock); + if (on) { + ret = msm_cci_ctrl_init(); + if (ret < 0) + goto exit; + } + if (ov5645->power == !on) { /* Power state changes. */ if (on) { @@ -803,6 +804,9 @@ static int ov5645_s_power(struct v4l2_subdev *sd, int on) } exit: + if (!on) + msm_cci_ctrl_release(); + mutex_unlock(&ov5645->power_lock); return ret; diff --git a/drivers/media/platform/msm/cci/msm_cci.c b/drivers/media/platform/msm/cci/msm_cci.c index de3cfb825d28..fbcd2b54f9ef 100644 --- a/drivers/media/platform/msm/cci/msm_cci.c +++ b/drivers/media/platform/msm/cci/msm_cci.c @@ -34,7 +34,7 @@ #define MSM_CCI_DRV_NAME "msm_cci" #undef CDBG -#define CDBG(fmt, args...) pr_err(fmt, ##args) +#define CDBG(fmt, args...) pr_debug(fmt, ##args) /* Max bytes that can be read per CCI read transaction */ #define CCI_READ_MAX 12 @@ -1119,6 +1119,117 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd, return rc; } +int32_t msm_cci_ctrl_init(void) +{ + struct v4l2_subdev *sd = msm_cci_get_subdev(); + struct msm_camera_cci_ctrl cci_ctrl = { 0 }; + struct msm_camera_cci_client cci_info = { 0 }; + int rc; + + CDBG("%s: Enter\n", __func__); + + if (!sd) { + return -EPROBE_DEFER; + } + + cci_ctrl.cci_info = &cci_info; + cci_ctrl.cci_info->cci_i2c_master = MASTER_0; + cci_ctrl.cci_info->i2c_freq_mode = I2C_STANDARD_MODE; + cci_ctrl.cmd = MSM_CCI_INIT; + + rc = msm_cci_config(sd, &cci_ctrl); + + CDBG("%s: Exit rc = %d", __func__, rc); + return rc; +} + +int32_t msm_cci_ctrl_release(void) +{ + struct v4l2_subdev *sd = msm_cci_get_subdev(); + struct msm_camera_cci_ctrl cci_ctrl = { 0 }; + struct msm_camera_cci_client cci_info = { 0 }; + int rc; + + CDBG("%s: Enter\n", __func__); + + cci_ctrl.cci_info = &cci_info; + cci_ctrl.cmd = MSM_CCI_RELEASE; + + rc = msm_cci_config(sd, &cci_ctrl); + + CDBG("%s: Exit rc = %d", __func__, rc); + return rc; +} + +int32_t msm_cci_ctrl_read(u16 addr, const char *buf, int count) +{ + struct v4l2_subdev *sd = msm_cci_get_subdev(); + struct msm_camera_cci_ctrl cci_ctrl = { 0 }; + struct msm_camera_cci_client cci_info = { 0 }; + struct msm_camera_cci_i2c_read_cfg *read_cfg; + int rc; + + CDBG("%s: Enter\n", __func__); + + cci_ctrl.cci_info = &cci_info; + cci_ctrl.cci_info->cci_i2c_master = MASTER_0; + cci_ctrl.cci_info->sid = 0x78 >> 1; + cci_ctrl.cci_info->retries = 3; + cci_ctrl.cci_info->id_map = 0; + cci_ctrl.cci_info->i2c_freq_mode = I2C_STANDARD_MODE; + + read_cfg = &cci_ctrl.cfg.cci_i2c_read_cfg; + read_cfg->addr = addr; + read_cfg->addr_type = MSM_CAMERA_I2C_WORD_ADDR; + read_cfg->data = (uint8_t *) buf; + read_cfg->num_byte = count; + + cci_ctrl.cmd = MSM_CCI_I2C_READ; + + rc = msm_cci_config(sd, &cci_ctrl); + + CDBG("%s: Exit rc = %d, reg = 0x%04x, data = 0x%02x", + __func__, rc, addr, *((uint8_t *)buf) ); + return rc; +} + +int32_t msm_cci_ctrl_write(u16 addr, const char *buf, int count) +{ + struct v4l2_subdev *sd = msm_cci_get_subdev(); + struct msm_camera_cci_ctrl cci_ctrl = { 0 }; + struct msm_camera_cci_client cci_info = { 0 }; + struct msm_camera_i2c_reg_setting *i2c_msg; + struct msm_camera_i2c_reg_array i2c_cmd = { 0 }; + int rc; + + CDBG("%s: Enter\n", __func__); + + cci_ctrl.cci_info = &cci_info; + cci_ctrl.cci_info->cci_i2c_master = MASTER_0; + cci_ctrl.cci_info->sid = 0x78 >> 1; + cci_ctrl.cci_info->retries = 3; + cci_ctrl.cci_info->id_map = 0; + + i2c_msg = &cci_ctrl.cfg.cci_i2c_write_cfg; + i2c_msg->reg_setting = &i2c_cmd; + + i2c_msg->size = 1; + i2c_msg->addr_type = MSM_CAMERA_I2C_WORD_ADDR; + i2c_msg->data_type = MSM_CAMERA_I2C_BYTE_DATA; + + i2c_cmd.reg_addr = addr; + i2c_cmd.reg_data = *((uint8_t *) buf); + i2c_cmd.delay = 0; + + cci_ctrl.cmd = MSM_CCI_I2C_WRITE; + + rc = msm_cci_config(sd, &cci_ctrl); + + CDBG("%s: Exit rc = %d, reg = 0x%04x, data = 0x%02x", + __func__, rc, addr, *((uint8_t *)buf) ); + return rc; +} + static irqreturn_t msm_cci_irq(int irq_num, void *data) { uint32_t irq; diff --git a/drivers/media/platform/msm/cci/msm_cci.h b/drivers/media/platform/msm/cci/msm_cci.h index 781691141f61..26b8c9459956 100644 --- a/drivers/media/platform/msm/cci/msm_cci.h +++ b/drivers/media/platform/msm/cci/msm_cci.h @@ -194,6 +194,12 @@ enum msm_cci_gpio_cmd_type { #ifdef CONFIG_MSM_CCI struct v4l2_subdev *msm_cci_get_subdev(void); + +int32_t msm_cci_ctrl_init(void); +int32_t msm_cci_ctrl_release(void); +int32_t msm_cci_ctrl_read(u16 addr, const char *buf, int count); +int32_t msm_cci_ctrl_write(u16 addr, const char *buf, int count); + #else static inline struct v4l2_subdev *msm_cci_get_subdev(void) { return NULL; -- 2.39.2