#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h>
+/* 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
struct gpio_desc *enable_gpio;
struct gpio_desc *rst_gpio;
+
+ struct v4l2_subdev *cci;
};
static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd)
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);
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);
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) {
}
exit:
+ if (!on)
+ msm_cci_ctrl_release();
+
mutex_unlock(&ov5645->power_lock);
return ret;
#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
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;