diff options
| author | Sureshnaidu Laveti <lsuresh@codeaurora.org> | 2016-04-27 17:25:11 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-14 14:45:00 -0700 |
| commit | f0c5be8a96d56845c9ad2ef04f348195d4611827 (patch) | |
| tree | 616aeff02d1146ea66500a67696d01e07c603c0a | |
| parent | 4e9f522a76cf1a109dd1cbfa02eef13d4a27d46e (diff) | |
msm: sensor: Add support for downloading OIS coefficient and framework
Add OIS framework and coefficient download in OIS driver.
Change-Id: Iff8e1c0367d13bb0d89946d81fb79427b6ef070e
Signed-off-by: Sureshnaidu Laveti <lsuresh@codeaurora.org>
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c | 181 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.h | 7 | ||||
| -rw-r--r-- | include/uapi/media/msm_cam_sensor.h | 25 |
3 files changed, 204 insertions, 9 deletions
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c index 82c9e5c5befa..5a891592b44f 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c @@ -13,6 +13,7 @@ #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ #include <linux/module.h> +#include <linux/firmware.h> #include "msm_sd.h" #include "msm_ois.h" #include "msm_cci.h" @@ -32,6 +33,124 @@ static int32_t msm_ois_power_down(struct msm_ois_ctrl_t *o_ctrl); static struct i2c_driver msm_ois_i2c_driver; +static int32_t msm_ois_download(struct msm_ois_ctrl_t *o_ctrl) +{ + uint16_t bytes_in_tx = 0; + uint16_t total_bytes = 0; + uint8_t *ptr = NULL; + int32_t rc = 0; + const struct firmware *fw = NULL; + const char *fw_name_prog = NULL; + const char *fw_name_coeff = NULL; + char name_prog[MAX_SENSOR_NAME] = {0}; + char name_coeff[MAX_SENSOR_NAME] = {0}; + struct device *dev = &(o_ctrl->pdev->dev); + enum msm_camera_i2c_reg_addr_type save_addr_type; + + CDBG("Enter\n"); + save_addr_type = o_ctrl->i2c_client.addr_type; + o_ctrl->i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR; + + snprintf(name_coeff, MAX_SENSOR_NAME, "%s.coeff", + o_ctrl->oboard_info->ois_name); + + snprintf(name_prog, MAX_SENSOR_NAME, "%s.prog", + o_ctrl->oboard_info->ois_name); + + /* cast pointer as const pointer*/ + fw_name_prog = name_prog; + fw_name_coeff = name_coeff; + + /* Load FW */ + rc = request_firmware(&fw, fw_name_prog, dev); + if (rc) { + dev_err(dev, "Failed to locate %s\n", fw_name_prog); + o_ctrl->i2c_client.addr_type = save_addr_type; + return rc; + } + + total_bytes = fw->size; + for (ptr = (uint8_t *)fw->data; total_bytes; + total_bytes -= bytes_in_tx, ptr += bytes_in_tx) { + bytes_in_tx = (total_bytes > 10) ? 10 : total_bytes; + rc = o_ctrl->i2c_client.i2c_func_tbl->i2c_write_seq( + &o_ctrl->i2c_client, o_ctrl->oboard_info->opcode.prog, + ptr, bytes_in_tx); + if (rc < 0) { + pr_err("Failed:remaining bytes to be downloaded:%d\n", + bytes_in_tx); + /* abort download fw and return error*/ + goto release_firmware; + } + } + release_firmware(fw); + + rc = request_firmware(&fw, fw_name_coeff, dev); + if (rc) { + dev_err(dev, "Failed to locate %s\n", fw_name_coeff); + o_ctrl->i2c_client.addr_type = save_addr_type; + return rc; + } + total_bytes = fw->size; + for (ptr = (uint8_t *)fw->data; total_bytes; + total_bytes -= bytes_in_tx, ptr += bytes_in_tx) { + bytes_in_tx = (total_bytes > 10) ? 10 : total_bytes; + rc = o_ctrl->i2c_client.i2c_func_tbl->i2c_write_seq( + &o_ctrl->i2c_client, o_ctrl->oboard_info->opcode.coeff, + ptr, bytes_in_tx); + if (rc < 0) { + pr_err("Failed:remaining bytes to be downloaded:%d\n", + total_bytes); + /* abort download fw*/ + break; + } + } +release_firmware: + release_firmware(fw); + o_ctrl->i2c_client.addr_type = save_addr_type; + + return rc; +} + +static int32_t msm_ois_data_config(struct msm_ois_ctrl_t *o_ctrl, + struct msm_ois_slave_info *slave_info) +{ + int rc = 0; + struct msm_camera_cci_client *cci_client = NULL; + + CDBG("Enter\n"); + if (!slave_info) { + pr_err("failed : invalid slave_info\n"); + return -EINVAL; + } + /* fill ois slave info*/ + if (strlcpy(o_ctrl->oboard_info->ois_name, slave_info->ois_name, + sizeof(o_ctrl->oboard_info->ois_name)) < 0) { + pr_err("failed: copy_from_user\n"); + return -EFAULT; + } + memcpy(&(o_ctrl->oboard_info->opcode), &(slave_info->opcode), + sizeof(struct msm_ois_opcode)); + o_ctrl->oboard_info->i2c_slaveaddr = slave_info->i2c_addr; + + /* config cci_client*/ + if (o_ctrl->ois_device_type == MSM_CAMERA_PLATFORM_DEVICE) { + cci_client = o_ctrl->i2c_client.cci_client; + cci_client->sid = + o_ctrl->oboard_info->i2c_slaveaddr >> 1; + cci_client->retries = 3; + cci_client->id_map = 0; + cci_client->cci_i2c_master = o_ctrl->cci_master; + } else { + o_ctrl->i2c_client.client->addr = + o_ctrl->oboard_info->i2c_slaveaddr; + } + o_ctrl->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR; + + CDBG("Exit\n"); + return rc; +} + static int32_t msm_ois_write_settings(struct msm_ois_ctrl_t *o_ctrl, uint16_t size, struct reg_settings_ois_t *settings) { @@ -370,6 +489,40 @@ static int32_t msm_ois_config(struct msm_ois_ctrl_t *o_ctrl, return rc; } +static int32_t msm_ois_config_download(struct msm_ois_ctrl_t *o_ctrl, + void __user *argp) +{ + struct msm_ois_cfg_download_data *cdata = + (struct msm_ois_cfg_download_data *)argp; + int32_t rc = 0; + + if (!o_ctrl || !cdata) { + pr_err("failed: Invalid data\n"); + return -EINVAL; + } + mutex_lock(o_ctrl->ois_mutex); + CDBG("Enter\n"); + CDBG("%s type %d\n", __func__, cdata->cfgtype); + switch (cdata->cfgtype) { + case CFG_OIS_DATA_CONFIG: + rc = msm_ois_data_config(o_ctrl, &cdata->slave_info); + if (rc < 0) + pr_err("Failed ois data config %d\n", rc); + break; + case CFG_OIS_DOWNLOAD: + rc = msm_ois_download(o_ctrl); + if (rc < 0) + pr_err("Failed ois download %d\n", rc); + break; + default: + break; + } + mutex_unlock(o_ctrl->ois_mutex); + CDBG("Exit\n"); + return rc; +} + + static int32_t msm_ois_get_subdev_id(struct msm_ois_ctrl_t *o_ctrl, void *arg) { @@ -454,6 +607,8 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd, return msm_ois_get_subdev_id(o_ctrl, argp); case VIDIOC_MSM_OIS_CFG: return msm_ois_config(o_ctrl, argp); + case VIDIOC_MSM_OIS_CFG_DOWNLOAD: + return msm_ois_config_download(o_ctrl, argp); case MSM_SD_SHUTDOWN: if (!o_ctrl->i2c_client.i2c_func_tbl) { pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n"); @@ -696,22 +851,28 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev) pr_err("%s:%d failed no memory\n", __func__, __LINE__); return -ENOMEM; } + + msm_ois_t->oboard_info = kzalloc(sizeof( + struct msm_ois_board_info), GFP_KERNEL); + if (!msm_ois_t->oboard_info) { + kfree(msm_ois_t); + return -ENOMEM; + } + rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); CDBG("cell-index %d, rc %d\n", pdev->id, rc); if (rc < 0) { - kfree(msm_ois_t); pr_err("failed rc %d\n", rc); - return rc; + goto release_memory; } rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master", &msm_ois_t->cci_master); CDBG("qcom,cci-master %d, rc %d\n", msm_ois_t->cci_master, rc); if (rc < 0 || msm_ois_t->cci_master >= MASTER_MAX) { - kfree(msm_ois_t); pr_err("failed rc %d\n", rc); - return rc; + goto release_memory; } if (of_find_property((&pdev->dev)->of_node, @@ -720,9 +881,8 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev) rc = msm_camera_get_dt_vreg_data((&pdev->dev)->of_node, &vreg_cfg->cam_vreg, &vreg_cfg->num_vreg); if (rc < 0) { - kfree(msm_ois_t); pr_err("failed rc %d\n", rc); - return rc; + goto release_memory; } } @@ -753,9 +913,8 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev) struct msm_camera_cci_client), GFP_KERNEL); if (!msm_ois_t->i2c_client.cci_client) { kfree(msm_ois_t->vreg_cfg.cam_vreg); - kfree(msm_ois_t); - pr_err("failed no memory\n"); - return -ENOMEM; + rc = -ENOMEM; + goto release_memory; } cci_client = msm_ois_t->i2c_client.cci_client; @@ -784,6 +943,10 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev) CDBG("Exit\n"); return rc; +release_memory: + kfree(msm_ois_t->oboard_info); + kfree(msm_ois_t); + return rc; } static const struct of_device_id msm_ois_i2c_dt_match[] = { diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.h b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.h index b9f8d4a0c3c8..614cc6c8cd5d 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.h +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.h @@ -41,6 +41,12 @@ struct msm_ois_vreg { int num_vreg; }; +struct msm_ois_board_info { + char ois_name[MAX_OIS_NAME_SIZE]; + uint32_t i2c_slaveaddr; + struct msm_ois_opcode opcode; +}; + struct msm_ois_ctrl_t { struct i2c_driver *i2c_driver; struct platform_driver *pdriver; @@ -61,6 +67,7 @@ struct msm_ois_ctrl_t { struct msm_camera_gpio_conf *gconf; struct msm_pinctrl_info pinctrl_info; uint8_t cam_pinctrl_status; + struct msm_ois_board_info *oboard_info; }; #endif diff --git a/include/uapi/media/msm_cam_sensor.h b/include/uapi/media/msm_cam_sensor.h index d83e00876fd5..5d340b9a2523 100644 --- a/include/uapi/media/msm_cam_sensor.h +++ b/include/uapi/media/msm_cam_sensor.h @@ -342,6 +342,13 @@ enum msm_actuator_cfg_type_t { CFG_ACTUATOR_INIT, }; +struct msm_ois_opcode { + uint32_t prog; + uint32_t coeff; + uint32_t pheripheral; + uint32_t memory; +}; + enum msm_ois_cfg_type_t { CFG_OIS_INIT, CFG_OIS_POWERDOWN, @@ -350,6 +357,11 @@ enum msm_ois_cfg_type_t { CFG_OIS_I2C_WRITE_SEQ_TABLE, }; +enum msm_ois_cfg_download_type_t { + CFG_OIS_DOWNLOAD, + CFG_OIS_DATA_CONFIG, +}; + enum msm_ois_i2c_operation { MSM_OIS_WRITE = 0, MSM_OIS_POLL, @@ -448,6 +460,11 @@ enum af_camera_name { ACTUATOR_WEB_CAM_2, }; +struct msm_ois_slave_info { + char ois_name[MAX_OIS_NAME_SIZE]; + uint32_t i2c_addr; + struct msm_ois_opcode opcode; +}; struct msm_ois_cfg_data { int cfgtype; union { @@ -456,6 +473,11 @@ struct msm_ois_cfg_data { } cfg; }; +struct msm_ois_cfg_download_data { + int cfgtype; + struct msm_ois_slave_info slave_info; +}; + struct msm_actuator_set_position_t { uint16_t number_of_steps; uint32_t hw_params; @@ -560,5 +582,8 @@ struct sensor_init_cfg_data { #define VIDIOC_MSM_FLASH_CFG \ _IOWR('V', BASE_VIDIOC_PRIVATE + 13, struct msm_flash_cfg_data_t) +#define VIDIOC_MSM_OIS_CFG_DOWNLOAD \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct msm_ois_cfg_download_data) + #endif |
