mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
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:
parent
543572a53a
commit
acc791f60f
7 changed files with 2242 additions and 2 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
2017
drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c
Normal file
2017
drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c
Normal file
File diff suppressed because it is too large
Load diff
193
drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h
Normal file
193
drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h
Normal 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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in a new issue