camera: ois: add aw86006 driver

[detail]
add aw86006 driver

Change-Id: I62ae76380aea2d239453d6abfc2c8a774293139b
Signed-off-by: liuwang2 <[email protected]>
Reviewed-on: https://gerrit.mot.com/2224040
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Zhichao Chen <[email protected]>
Submit-Approved: Jira Key
This commit is contained in:
liuwang2 2022-03-23 17:41:35 +08:00 • committed by zhaoji1
commit acc791f60f
7 changed files with 2242 additions and 2 deletions

View file

@ -163,6 +163,7 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \
cam_sensor_module/cam_ois/cam_ois_core.o \
cam_sensor_module/cam_ois/cam_ois_soc.o \
cam_sensor_module/cam_ois/cam_ois_dw9781.o \
cam_sensor_module/cam_ois/cam_ois_aw86006.o \
cam_sensor_module/cam_sensor/cam_sensor_dev.o \
cam_sensor_module/cam_sensor/cam_sensor_core.o \
cam_sensor_module/cam_sensor/cam_sensor_soc.o \

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,193 @@
#ifndef AW86006_OIS_H
#define AW86006_OIS_H
/* I2c address */
#define AW_SHUTDOWN_I2C_ADDR (0xC2 >> 1) /* 0x61 */
#define AW_WAKEUP_I2C_ADDR (0xD2 >> 1) /* 0x69 */
/* Register detail */
#define REG_CHIPID (0x0000)
#define REG_OIS_ENABLE (0x0001)
#define REG_OIS_STATUS (0x0002)
#define REG_PACKING_RST (0x0003)
#define REG_DATA_READY (0x0004)
#define REG_SAMPLE_TIME (0x0005)
#define REG_PACK_DATA (0x0006)
#define REG_SPI_GYRO (0x0007)
#define REG_SPI_CFG (0x0008)
#define REG_AF_CODE_H (0x0009)
#define REG_AF_CODE_L (0x000A)
#define REG_AF_ARCT (0x000B)
#define REG_AF_CFG (0x000C)
#define REG_AF_BUSY (0x000D)
#define REG_VERSION (0x0010)
#define REG_STANDBY (0xFF11)
/* Flag */
#define OIS_ENABLE (0x01)
#define OIS_DISABLE (0x00)
#define OIS_ERROR (-1)
#define OIS_SUCCESS (0)
#define AW_IC_STANDBY (1)
#define AW_FLASH_WRITE_CONNECT
/* Loop */
#define AW_STAY_ON_MOVE_LOOP (20)
#define AW_STAY_ON_BOOT_LOOP (20)
#define AW_ERROR_LOOP (5)
#define AW_FLASH_WRITE_ERROR_LOOP (2)
#define AW_FLASH_READ_ERROR_LOOP (2)
#define AW_FLASH_ERASE_ERROR_LOOP (2)
#define AW_JUMP_BOOT_LOOP (6)
#define AW_JUMP_MOVE_LOOP (6)
#define AW_STOP_CMD_LOOP (10)
/* Addr or data size */
#define AW_DATA_SHIFT_0_BIT (0)
#define AW_DATA_SHIFT_8_BIT (8)
#define AW_DATA_SHIFT_16_BIT (16)
#define AW_DATA_SHIFT_24_BIT (24)
#define AW_I2C_WRITE_BYTE_ZERO (0x00)
/* Delay */
#define AW_RESET_DELAY (50) /* ms */
#define AW_JUMP_MOVE_DELAY (9) /* ms */
#define AW_JUMP_MOVE_DELAY_MAX (16) /* ms */
#define AW_JUMP_BOOT_DELAY (2) /* ms */
#define AW_JUMP_BOOT_DELAY_MAX (6) /* ms */
#define AW_SHUTDOWN_DELAY (2000) /* us */
/* Flash and firmware */
#define AW_FLASH_BASE_ADDR (0x01000000)
#define AW_FLASH_APP_ADDR (0x01002000)
#define AW_FLASH_MOVE_LENGTH (AW_FLASH_APP_ADDR - AW_FLASH_BASE_ADDR)
#define AW_FLASH_FULL_SIZE (0x10000)
#define AW_FLASH_TOP_ADDR (AW_FLASH_BASE_ADDR + AW_FLASH_FULL_SIZE)
#define AW_FLASH_ERASE_LEN (512)
#define AW_FLASH_WRITE_LEN (64)
#define AW_FLASH_READ_LEN (64)
#define AW_FW_INFO_LENGTH (64)
#define AW_FW_SHIFT_IDENTIFY (AW_FLASH_MOVE_LENGTH)
#define AW_FW_SHIFT_CHECKSUM (AW_FW_SHIFT_IDENTIFY + 8)
#define AW_FW_SHIFT_APP_CHECKSUM (AW_FW_SHIFT_CHECKSUM + 4)
#define AW_FW_SHIFT_CHECKSUM_ADDR (AW_FW_SHIFT_APP_CHECKSUM)
#define AW_FW_SHIFT_APP_LENGTH (AW_FW_SHIFT_APP_CHECKSUM + 4)
#define AW_FW_SHIFT_APP_VERSION (AW_FW_SHIFT_APP_LENGTH + 4)
#define AW_FW_SHIFT_APP_ID (AW_FW_SHIFT_APP_VERSION + 4)
#define AW_FW_SHIFT_MOVE_CHECKSUM (AW_FW_SHIFT_APP_ID + 4)
#define AW_FW_SHIFT_MOVE_VERSION (AW_FW_SHIFT_MOVE_CHECKSUM + 4)
#define AW_FW_SHIFT_MOVE_LENGTH (AW_FW_SHIFT_MOVE_VERSION + 4)
#define AW_FW_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_MOVE_LENGTH + 8)
#define AW_ARRAY_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_UPDATE_FLAG - AW_FLASH_MOVE_LENGTH)
/* SOC */
enum soc_status {
SOC_OK = 0,
SOC_ADDR_ERROR,
SOC_PBUF_ERROR,
SOC_HANK_ERROR,
SOC_JUMP_ERROR,
SOC_FLASH_ERROR,
SOC_SPACE_ERROR,
};
enum soc_module {
SOC_HANK = 0x01,
SOC_SRAM = 0x02,
SOC_FLASH = 0x03,
SOC_END = 0x04,
};
enum soc_enum {
SOC_VERSION = 0x01,
SOC_CTL = 0x00,
SOC_ACK = 0x01,
SOC_ADDR = 0x84,
SOC_READ_ADDR = 0x48,
SOC_ERASE_STRUCT_LEN = 6,
SOC_READ_STRUCT_LEN = 6,
SOC_PROTOCAL_HEAD = 9,
SOC_CONNECT_WRITE_LEN = 9,
SOC_ERASE_WRITE_LEN = 15,
SOC_READ_WRITE_LEN = 15,
SOC_ERASE_BLOCK_DELAY = 8,
SOC_WRITE_BLOCK_HEAD = 13,
SOC_WRITE_BLOCK_DELAY = 1000, /* us */
SOC_READ_BLOCK_DELAY = 2000, /* us */
SOC_CONNECT_DELAY = 2000, /* us */
};
enum soc_flash_event {
SOC_FLASH_WRITE = 0x01,
SOC_FLASH_WRITE_ACK = 0x02,
SOC_FLASH_READ = 0x11,
SOC_FLASH_READ_ACK = 0x12,
SOC_FLASH_ERASE_BLOCK = 0x21,
SOC_FLASH_ERASE_BLOCK_ACK = 0x22,
SOC_FLASH_ERASE_CHIP = 0x23,
SOC_FLASH_ERASE_CHIP_ACK = 0x24,
};
enum soc_hank_event {
SOC_HANK_CONNECT = 0x01,
SOC_HANK_CONNECT_ACK = 0x02,
SOC_HANK_PROTICOL = 0x11,
SOC_HANK_PROTICOL_ACK = 0x12,
SOC_HANK_VERSION = 0x21,
SOC_HANK_VERSION_ACK = 0x22,
SOC_HANK_ID = 0x31,
SOC_HANK_ID_ACK = 0x32,
SOC_HANK_DATE = 0x33,
SOC_HANK_DATA_ACK = 0x34,
};
enum isp_enum {
ISP_READ_VERSION_DELAY = 500, /* us */
ISP_VERS_CONNECT_ACK = 0x01,
ISP_VERSION_ACK_LEN = 5,
ISP_EVENT_OK = 0x01,
};
enum awrw_flag {
AW_SEQ_WRITE = 0,
AW_SEQ_READ = 1,
};
/* Struct */
struct soc_protocol {
uint8_t checksum;
uint8_t protocol_ver;
uint8_t addr;
uint8_t module;
uint8_t event;
uint8_t len[2];
uint8_t ack;
uint8_t sum;
uint8_t reserved[3];
uint8_t ack_juge;
uint8_t *p_data;
};
struct aw86006_fw {
uint32_t checksum;
uint32_t app_checksum;
uint32_t app_length;
uint32_t app_version;
uint32_t app_id;
uint32_t move_checksum;
uint32_t move_version;
uint32_t move_length;
uint32_t update_flag;
uint32_t size;
uint8_t *data_p;
};
struct aw86006_info {
uint8_t already_update;
uint8_t checkinfo_fw[64];
uint8_t checkinfo_rd[64];
struct aw86006_fw fw;
};
#endif

View file

@ -17,6 +17,7 @@
extern int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize);
extern void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize);
extern int aw_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw);
int32_t cam_ois_construct_default_power_setting(
struct cam_sensor_power_ctrl_t *power_info)
@ -413,6 +414,12 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl)
}
CAM_INFO(CAM_OIS, "Firmware download started.");
}
else if (strstr(o_ctrl->ois_name, "aw86006")) {
mutex_lock(&o_ctrl->ois_mutex_aw);
rc = aw_firmware_update(o_ctrl, fw);
mutex_unlock(&o_ctrl->ois_mutex_aw);
return rc;
}
total_bytes = fw->size;
if(o_ctrl->ois_fw_txn_data_sz == 0)
@ -509,8 +516,8 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl)
return -EINVAL;
}
if (strstr(o_ctrl->ois_name, "dw9781")) {
CAM_DBG(CAM_OIS, "not need download coeff fw!");
if (strstr(o_ctrl->ois_name, "dw9781") || strstr(o_ctrl->ois_name, "aw86006")) {
CAM_DBG(CAM_OIS, "not need download coeff fw for %s.", o_ctrl->ois_name);
return 0;
}

View file

@ -10,6 +10,9 @@
#include "cam_debug_util.h"
#include "camera_main.h"
extern int aw_ois_init(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */
extern int aw_ois_exit(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */
static int cam_ois_clear_data_ready(struct cam_ois_ctrl_t *o_ctrl)
{
struct cam_sensor_i2c_reg_setting i2c_reg_setting = {NULL,1,CAMERA_SENSOR_I2C_TYPE_WORD,CAMERA_SENSOR_I2C_TYPE_WORD,0};
@ -511,6 +514,9 @@ static int cam_ois_component_bind(struct device *dev,
mutex_init(&(o_ctrl->vsync_mutex));
init_completion(&o_ctrl->ois_data_complete);
if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006"))
aw_ois_init(o_ctrl);
if (o_ctrl->is_ois_vsync_irq_supported) {
o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0);
@ -564,6 +570,9 @@ static void cam_ois_component_unbind(struct device *dev,
}
CAM_INFO(CAM_OIS, "platform driver remove invoked");
if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006"))
aw_ois_exit(o_ctrl);
soc_info = &o_ctrl->soc_info;
for (i = 0; i < soc_info->num_clk; i++)
devm_clk_put(soc_info->dev, soc_info->clk[i]);

View file

@ -166,6 +166,13 @@ struct cam_ois_ctrl_t {
int ois_data_size;
uint16_t q_timer_cnt;
uint64_t mono_timestamp;
/* awinic_add */
const char *ic_name;
struct work_struct fw_update_work;
uint32_t awrw_flag;
uint32_t reg_num;
uint8_t *reg_data;
struct mutex ois_mutex_aw;
};
/**

View file

@ -41,6 +41,12 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl)
o_ctrl->is_ois_vsync_irq_supported = true;
}
rc = of_property_read_string(of_node, "ois-name", &o_ctrl->ic_name);
if (rc) {
CAM_DBG(CAM_OIS, "ois-name is not available in the node: %d", rc);
o_ctrl->ic_name = NULL;
}
#ifdef CONFIG_CAMERA_DISABLE_VSYNC_IRQ
o_ctrl->is_ois_vsync_irq_supported = false;
CAM_WARN(CAM_OIS, "disable ois vsync irq in factory build");