summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorTerence Ho <terenceh@codeaurora.org>2015-12-10 10:55:42 -0500
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:17:15 -0700
commitfd9c7c7b8d734aa59dc3d687757deeeed97f6e9e (patch)
tree8f7fca9b92ec47d0273992956f7a74bd3a73756a /drivers/media
parentbbadb94caf09b75ed1f64d0f80f1e643159b930f (diff)
msm: camera: add slave write array support
Add support for slave_write_array and to pass addr_type with slave_read. Change-Id: Ia530dcf684739f43e36fc67fec83bc0be0c8cf78 Signed-off-by: Terence Ho <terenceh@codeaurora.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c145
1 files changed, 139 insertions, 6 deletions
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index fa591576b3c4..6802016158ce 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, The Linux Foundation. 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
@@ -233,10 +233,11 @@ int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl)
return rc;
}
- CDBG("%s: read id: 0x%x expected id 0x%x:\n", __func__, chipid,
- slave_info->sensor_id);
+ pr_debug("%s: read id: 0x%x expected id 0x%x:\n",
+ __func__, chipid, slave_info->sensor_id);
if (msm_sensor_id_by_mask(s_ctrl, chipid) != slave_info->sensor_id) {
- pr_err("msm_sensor_match_id chip id doesnot match\n");
+ pr_err("%s chip id %x does not match %x\n",
+ __func__, chipid, slave_info->sensor_id);
return -ENODEV;
}
return rc;
@@ -482,6 +483,7 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
struct msm_camera_i2c_read_config *read_config_ptr = NULL;
uint16_t local_data = 0;
uint16_t orig_slave_addr = 0, read_slave_addr = 0;
+ uint16_t orig_addr_type = 0, read_addr_type = 0;
if (s_ctrl->is_csid_tg_mode)
goto DONE;
@@ -497,6 +499,8 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
break;
}
read_slave_addr = read_config.slave_addr;
+ read_addr_type = read_config.addr_type;
+
CDBG("%s:CFG_SLAVE_READ_I2C:", __func__);
CDBG("%s:slave_addr=0x%x reg_addr=0x%x, data_type=%d\n",
__func__, read_config.slave_addr,
@@ -519,6 +523,10 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
CDBG("%s:orig_slave_addr=0x%x, new_slave_addr=0x%x",
__func__, orig_slave_addr,
read_slave_addr >> 1);
+
+ orig_addr_type = s_ctrl->sensor_i2c_client->addr_type;
+ s_ctrl->sensor_i2c_client->addr_type = read_addr_type;
+
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client,
read_config.reg_addr,
@@ -530,6 +538,11 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
s_ctrl->sensor_i2c_client->client->addr =
orig_slave_addr;
}
+ s_ctrl->sensor_i2c_client->addr_type = orig_addr_type;
+
+ pr_debug("slave_read %x %x %x\n", read_slave_addr,
+ read_config.reg_addr, local_data);
+
if (rc < 0) {
pr_err("%s:%d: i2c_read failed\n", __func__, __LINE__);
break;
@@ -537,6 +550,114 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
read_config_ptr->data = local_data;
break;
}
+ case CFG_SLAVE_WRITE_I2C_ARRAY: {
+ struct msm_camera_i2c_array_write_config32 write_config32;
+ struct msm_camera_i2c_array_write_config write_config;
+ struct msm_camera_i2c_reg_array *reg_setting = NULL;
+ uint16_t orig_slave_addr = 0, write_slave_addr = 0;
+ uint16_t orig_addr_type = 0, write_addr_type = 0;
+
+ if (s_ctrl->is_csid_tg_mode)
+ goto DONE;
+
+ if (copy_from_user(&write_config32,
+ (void *)compat_ptr(cdata->cfg.setting),
+ sizeof(
+ struct msm_camera_i2c_array_write_config32))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ write_config.slave_addr = write_config32.slave_addr;
+ write_config.conf_array.addr_type =
+ write_config32.conf_array.addr_type;
+ write_config.conf_array.data_type =
+ write_config32.conf_array.data_type;
+ write_config.conf_array.delay =
+ write_config32.conf_array.delay;
+ write_config.conf_array.size =
+ write_config32.conf_array.size;
+ write_config.conf_array.reg_setting =
+ compat_ptr(write_config32.conf_array.reg_setting);
+
+ pr_debug("%s:CFG_SLAVE_WRITE_I2C_ARRAY:\n", __func__);
+ pr_debug("%s:slave_addr=0x%x, array_size=%d addr_type=%d data_type=%d\n",
+ __func__,
+ write_config.slave_addr,
+ write_config.conf_array.size,
+ write_config.conf_array.addr_type,
+ write_config.conf_array.data_type);
+
+ if (!write_config.conf_array.size ||
+ write_config.conf_array.size > I2C_REG_DATA_MAX) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ reg_setting = kzalloc(write_config.conf_array.size *
+ (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
+ if (!reg_setting) {
+ rc = -ENOMEM;
+ break;
+ }
+ if (copy_from_user(reg_setting,
+ (void *)(write_config.conf_array.reg_setting),
+ write_config.conf_array.size *
+ sizeof(struct msm_camera_i2c_reg_array))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(reg_setting);
+ rc = -EFAULT;
+ break;
+ }
+ write_config.conf_array.reg_setting = reg_setting;
+ write_slave_addr = write_config.slave_addr;
+ write_addr_type = write_config.conf_array.addr_type;
+
+ if (s_ctrl->sensor_i2c_client->cci_client) {
+ orig_slave_addr =
+ s_ctrl->sensor_i2c_client->cci_client->sid;
+ s_ctrl->sensor_i2c_client->cci_client->sid =
+ write_slave_addr >> 1;
+ } else if (s_ctrl->sensor_i2c_client->client) {
+ orig_slave_addr =
+ s_ctrl->sensor_i2c_client->client->addr;
+ s_ctrl->sensor_i2c_client->client->addr =
+ write_slave_addr >> 1;
+ } else {
+ pr_err("%s: error: no i2c/cci client found.",
+ __func__);
+ kfree(reg_setting);
+ rc = -EFAULT;
+ break;
+ }
+
+ pr_debug("%s:orig_slave_addr=0x%x, new_slave_addr=0x%x\n",
+ __func__, orig_slave_addr,
+ write_slave_addr >> 1);
+ orig_addr_type = s_ctrl->sensor_i2c_client->addr_type;
+ s_ctrl->sensor_i2c_client->addr_type = write_addr_type;
+ rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
+ s_ctrl->sensor_i2c_client, &(write_config.conf_array));
+
+ s_ctrl->sensor_i2c_client->addr_type = orig_addr_type;
+ if (s_ctrl->sensor_i2c_client->cci_client) {
+ s_ctrl->sensor_i2c_client->cci_client->sid =
+ orig_slave_addr;
+ } else if (s_ctrl->sensor_i2c_client->client) {
+ s_ctrl->sensor_i2c_client->client->addr =
+ orig_slave_addr;
+ } else {
+ pr_err("%s: error: no i2c/cci client found.\n",
+ __func__);
+ kfree(reg_setting);
+ rc = -EFAULT;
+ break;
+ }
+ kfree(reg_setting);
+ break;
+ }
case CFG_WRITE_I2C_SEQ_ARRAY: {
struct msm_camera_i2c_seq_reg_setting32 conf_array32;
struct msm_camera_i2c_seq_reg_setting conf_array;
@@ -882,6 +1003,7 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
struct msm_camera_i2c_read_config *read_config_ptr = NULL;
uint16_t local_data = 0;
uint16_t orig_slave_addr = 0, read_slave_addr = 0;
+ uint16_t orig_addr_type = 0, read_addr_type = 0;
if (s_ctrl->is_csid_tg_mode)
goto DONE;
@@ -895,6 +1017,7 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
break;
}
read_slave_addr = read_config.slave_addr;
+ read_addr_type = read_config.addr_type;
CDBG("%s:CFG_SLAVE_READ_I2C:", __func__);
CDBG("%s:slave_addr=0x%x reg_addr=0x%x, data_type=%d\n",
__func__, read_config.slave_addr,
@@ -917,6 +1040,10 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
CDBG("%s:orig_slave_addr=0x%x, new_slave_addr=0x%x",
__func__, orig_slave_addr,
read_slave_addr >> 1);
+
+ orig_addr_type = s_ctrl->sensor_i2c_client->addr_type;
+ s_ctrl->sensor_i2c_client->addr_type = read_addr_type;
+
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client,
read_config.reg_addr,
@@ -928,6 +1055,8 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
s_ctrl->sensor_i2c_client->client->addr =
orig_slave_addr;
}
+ s_ctrl->sensor_i2c_client->addr_type = orig_addr_type;
+
if (rc < 0) {
pr_err("%s:%d: i2c_read failed\n", __func__, __LINE__);
break;
@@ -938,8 +1067,8 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
case CFG_SLAVE_WRITE_I2C_ARRAY: {
struct msm_camera_i2c_array_write_config write_config;
struct msm_camera_i2c_reg_array *reg_setting = NULL;
- uint16_t write_slave_addr = 0;
- uint16_t orig_slave_addr = 0;
+ uint16_t orig_slave_addr = 0, write_slave_addr = 0;
+ uint16_t orig_addr_type = 0, write_addr_type = 0;
if (s_ctrl->is_csid_tg_mode)
goto DONE;
@@ -981,6 +1110,7 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
}
write_config.conf_array.reg_setting = reg_setting;
write_slave_addr = write_config.slave_addr;
+ write_addr_type = write_config.conf_array.addr_type;
if (s_ctrl->sensor_i2c_client->cci_client) {
orig_slave_addr =
s_ctrl->sensor_i2c_client->cci_client->sid;
@@ -1000,8 +1130,11 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
CDBG("%s:orig_slave_addr=0x%x, new_slave_addr=0x%x",
__func__, orig_slave_addr,
write_slave_addr >> 1);
+ orig_addr_type = s_ctrl->sensor_i2c_client->addr_type;
+ s_ctrl->sensor_i2c_client->addr_type = write_addr_type;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
s_ctrl->sensor_i2c_client, &(write_config.conf_array));
+ s_ctrl->sensor_i2c_client->addr_type = orig_addr_type;
if (s_ctrl->sensor_i2c_client->cci_client) {
s_ctrl->sensor_i2c_client->cci_client->sid =
orig_slave_addr;