Loading drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +51 −14 Original line number Diff line number Diff line Loading @@ -177,13 +177,29 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, return rc; } static int32_t msm_cci_get_queue_free_size(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) { uint32_t read_val = 0; uint32_t reg_offset = master * 0x200 + queue * 0x100; read_val = msm_camera_io_r_mb(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d max %d\n", __func__, __LINE__, read_val, cci_dev->cci_i2c_queue_info[master][queue].max_queue_size); return (cci_dev-> cci_i2c_queue_info[master][queue].max_queue_size) - read_val; } static int32_t msm_cci_data_queue(struct cci_device *cci_dev, struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue) { uint16_t i = 0, j = 0, k = 0, h = 0, len = 0; int32_t rc = 0; int32_t rc = 0, free_size = 0, en_seq_write = 0; uint32_t cmd = 0, delay = 0; uint8_t data[11]; uint8_t data[12]; uint16_t reg_addr = 0; struct msm_camera_i2c_reg_setting *i2c_msg = &c_ctrl->cfg.cci_i2c_write_cfg; Loading Loading @@ -230,6 +246,7 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, if (c_ctrl->cmd == MSM_CCI_I2C_WRITE) reg_addr = i2c_cmd->reg_addr; if (en_seq_write == 0) { /* either byte or word addr */ if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) data[i++] = reg_addr; Loading @@ -237,27 +254,38 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, data[i++] = (reg_addr & 0xFF00) >> 8; data[i++] = reg_addr & 0x00FF; } } /* max of 10 data bytes */ do { if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) { data[i++] = i2c_cmd->reg_data; reg_addr++; } else { if ((i + 1) <= 10) { if ((i + 1) <= cci_dev->payload_size) { data[i++] = (i2c_cmd->reg_data & 0xFF00) >> 8; /* MSB */ data[i++] = i2c_cmd->reg_data & 0x00FF; /* LSB */ reg_addr += 2; reg_addr++; } else break; } i2c_cmd++; --cmd_size; } while ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) && (cmd_size > 0) && (i <= 10)); (cmd_size > 0) && (i <= cci_dev->payload_size)); free_size = msm_cci_get_queue_free_size(cci_dev, master, queue); if ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) && ((i-1) == MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11) && cci_dev->support_seq_write && cmd_size > 0 && free_size > BURST_MIN_FREE_SIZE) { data[0] |= 0xF0; en_seq_write = 1; } else { data[0] |= ((i-1) << 4); en_seq_write = 0; } len = ((i-1)/4) + 1; rc = msm_cci_validate_queue(cci_dev, len, master, queue); if (rc < 0) { Loading @@ -274,7 +302,8 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, CCI_I2C_M0_Q0_LOAD_DATA_ADDR + master * 0x200 + queue * 0x100); } if ((delay > 0) && (delay < CCI_MAX_DELAY)) { if ((delay > 0) && (delay < CCI_MAX_DELAY) && en_seq_write == 0) { cmd = (uint32_t)((delay * cci_dev->cycles_per_us) / 0x100); cmd <<= 4; Loading Loading @@ -834,6 +863,14 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, CCI_HW_VERSION_ADDR); pr_info("%s:%d: hw_version = 0x%x\n", __func__, __LINE__, cci_dev->hw_version); cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_10; cci_dev->support_seq_write = 0; if (cci_dev->hw_version >= 0x10020000) { cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11; cci_dev->support_seq_write = 1; } cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; msm_camera_io_w_mb(CCI_RESET_CMD_RMSK, cci_dev->base + CCI_RESET_CMD_ADDR); Loading drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h +6 −2 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, 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 Loading Loading @@ -33,7 +33,9 @@ #define CCI_NUM_CLK_MAX 16 #define CCI_NUM_CLK_CASES 5 #define CCI_CLK_SRC_NAME "cci_src_clk" #define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_10 10 #define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11 11 #define BURST_MIN_FREE_SIZE 8 enum cci_i2c_queue_t { QUEUE_0, Loading Loading @@ -154,6 +156,8 @@ struct cci_device { struct regulator *reg_ptr; uint32_t cycles_per_us; uint32_t cci_clk_src; uint8_t payload_size; uint8_t support_seq_write; }; enum msm_cci_i2c_cmd_type { Loading Loading
drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +51 −14 Original line number Diff line number Diff line Loading @@ -177,13 +177,29 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, return rc; } static int32_t msm_cci_get_queue_free_size(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) { uint32_t read_val = 0; uint32_t reg_offset = master * 0x200 + queue * 0x100; read_val = msm_camera_io_r_mb(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d max %d\n", __func__, __LINE__, read_val, cci_dev->cci_i2c_queue_info[master][queue].max_queue_size); return (cci_dev-> cci_i2c_queue_info[master][queue].max_queue_size) - read_val; } static int32_t msm_cci_data_queue(struct cci_device *cci_dev, struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue) { uint16_t i = 0, j = 0, k = 0, h = 0, len = 0; int32_t rc = 0; int32_t rc = 0, free_size = 0, en_seq_write = 0; uint32_t cmd = 0, delay = 0; uint8_t data[11]; uint8_t data[12]; uint16_t reg_addr = 0; struct msm_camera_i2c_reg_setting *i2c_msg = &c_ctrl->cfg.cci_i2c_write_cfg; Loading Loading @@ -230,6 +246,7 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, if (c_ctrl->cmd == MSM_CCI_I2C_WRITE) reg_addr = i2c_cmd->reg_addr; if (en_seq_write == 0) { /* either byte or word addr */ if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) data[i++] = reg_addr; Loading @@ -237,27 +254,38 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, data[i++] = (reg_addr & 0xFF00) >> 8; data[i++] = reg_addr & 0x00FF; } } /* max of 10 data bytes */ do { if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) { data[i++] = i2c_cmd->reg_data; reg_addr++; } else { if ((i + 1) <= 10) { if ((i + 1) <= cci_dev->payload_size) { data[i++] = (i2c_cmd->reg_data & 0xFF00) >> 8; /* MSB */ data[i++] = i2c_cmd->reg_data & 0x00FF; /* LSB */ reg_addr += 2; reg_addr++; } else break; } i2c_cmd++; --cmd_size; } while ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) && (cmd_size > 0) && (i <= 10)); (cmd_size > 0) && (i <= cci_dev->payload_size)); free_size = msm_cci_get_queue_free_size(cci_dev, master, queue); if ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) && ((i-1) == MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11) && cci_dev->support_seq_write && cmd_size > 0 && free_size > BURST_MIN_FREE_SIZE) { data[0] |= 0xF0; en_seq_write = 1; } else { data[0] |= ((i-1) << 4); en_seq_write = 0; } len = ((i-1)/4) + 1; rc = msm_cci_validate_queue(cci_dev, len, master, queue); if (rc < 0) { Loading @@ -274,7 +302,8 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, CCI_I2C_M0_Q0_LOAD_DATA_ADDR + master * 0x200 + queue * 0x100); } if ((delay > 0) && (delay < CCI_MAX_DELAY)) { if ((delay > 0) && (delay < CCI_MAX_DELAY) && en_seq_write == 0) { cmd = (uint32_t)((delay * cci_dev->cycles_per_us) / 0x100); cmd <<= 4; Loading Loading @@ -834,6 +863,14 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, CCI_HW_VERSION_ADDR); pr_info("%s:%d: hw_version = 0x%x\n", __func__, __LINE__, cci_dev->hw_version); cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_10; cci_dev->support_seq_write = 0; if (cci_dev->hw_version >= 0x10020000) { cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11; cci_dev->support_seq_write = 1; } cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; msm_camera_io_w_mb(CCI_RESET_CMD_RMSK, cci_dev->base + CCI_RESET_CMD_ADDR); Loading
drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h +6 −2 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, 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 Loading Loading @@ -33,7 +33,9 @@ #define CCI_NUM_CLK_MAX 16 #define CCI_NUM_CLK_CASES 5 #define CCI_CLK_SRC_NAME "cci_src_clk" #define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_10 10 #define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11 11 #define BURST_MIN_FREE_SIZE 8 enum cci_i2c_queue_t { QUEUE_0, Loading Loading @@ -154,6 +156,8 @@ struct cci_device { struct regulator *reg_ptr; uint32_t cycles_per_us; uint32_t cci_clk_src; uint8_t payload_size; uint8_t support_seq_write; }; enum msm_cci_i2c_cmd_type { Loading