sar sensor bring up -aw

1.sar sensor bring up
2.add aw driver

Change-Id: I42564cc4393fdbe30a63722d544b7e84c578a177
Signed-off-by: tnyangc <ramiel.yang@tinno.com>
Reviewed-on: https://gerrit.mot.com/2554436
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: <yangyi31@motorola.com>
Reviewed-by: Yuchang Guo <guoyc1@lenovo.com>
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
tnyangc 2023-03-27 15:24:51 +08:00 • committed by yangyi31
commit 5540075a2b
18 changed files with 11049 additions and 0 deletions

View file

@ -0,0 +1,28 @@
DLKM_DIR := motorola/kernel/modules
LOCAL_PATH := $(call my-dir)
ifeq ($(AW96XX_MTK_CHARGER),true)
KERNEL_CFLAGS += CONFIG_AW96XX_MTK_CHARGER=y
endif
ifeq ($(AW96XX_USB_USE_ONLINE),true)
KERNEL_CFLAGS += CONFIG_AW96XX_POWER_SUPPLY_ONLINE=y
endif
ifeq ($(AW96XX_MTK_KERNEL419_CHARGER_TYPE), true)
KERNEL_CFLAGS += CONFIG_AW96XX_MTK_KERNEL419_CHARGER_TYPE=y
endif
ifeq ($(AW96XX_MTK_KERNEL5XX_CHARGER_TYPE),true)
KERNEL_CFLAGS += CONFIG_AW96XX_MTK_KERNEL5XX_CHARGER_TYPE=y
endif
include $(CLEAR_VARS)
LOCAL_MODULE := awinic_sar.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
LOCAL_ADDITIONAL_DEPENDENCIES := $(KERNEL_MODULES_OUT)/sensors_class.ko
#LOCAL_REQUIRED_MODULES := sensors_class.ko
KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki
include $(DLKM_DIR)/AndroidKernelModule.mk

View file

@ -0,0 +1,30 @@
# add -Wall to try to catch everything we can.
#MTK have kernel-4.14 and kernel-4.19 and kernel-5.10 in the same dir,so we can't use below method
#KERNEL_DIR_PATH = $(shell find $(TOP)/kernel* -type d -name "kernel-*" | head -1)
KERNEL_VERSION_NAME = $(shell basename $(KERNEL_DIR_PATH))
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include/linux/input/awinic
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/$(KERNEL_VERSION_NAME)/drivers/base
ifneq ($(filter m y,$(CONFIG_AW96XX_POWER_SUPPLY_ONLINE)),)
EXTRA_CFLAGS += -DCONFIG_USE_POWER_SUPPLY_ONLINE
endif
ifneq ($(filter m y,$(CONFIG_AW96XX_MTK_CHARGER)),)
EXTRA_CFLAGS += -DCONFIG_AW96XX_MTK_CHARGER
endif
ifneq ($(filter m y,$(CONFIG_AW96XX_MTK_KERNEL419_CHARGER_TYPE)),)
EXTRA_CFLAGS += -DCONFIG_AW96XX_MTK_KERNEL419_CHARGER_TYPE
endif
ifneq ($(filter m y,$(CONFIG_AW96XX_MTK_KERNEL5XX_CHARGER_TYPE)),)
EXTRA_CFLAGS += -DCONFIG_AW96XX_MTK_KERNEL5XX_CHARGER_TYPE
endif
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../../../sensors/$(GKI_OBJ_MODULE_DIR)/Module.symvers
obj-m := awinic_sar.o
awinic_sar-objs := ./comm/aw_sar_comm_interface.o aw_sar.o ./aw9610x/aw9610x.o ./aw9620x/aw9620x.o ./aw9620x/aw_update_fw.o ./aw963xx/aw963xx.o

View file

@ -0,0 +1,11 @@
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
modules_install:
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean

View file

@ -0,0 +1,875 @@
#include "aw9610x.h"
#define AW9610X_I2C_NAME "aw9610x_sar"
#define AW9610X_DRIVER_VERSION "v2.3.3"
#define AW9610X_RETRIES (3)
static struct aw_sar *g_aw_sar = NULL;
//#define AW_INPUT_TRIGGER_TH1
//#define AW_INPUT_TRIGGER_TH2
//#define AW_INPUT_TRIGGER_TH3
static int32_t aw9610x_baseline_filter(struct aw_sar *p_sar)
{
uint8_t i = 0;
uint32_t status0 = 0;
uint32_t status1 = 0;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
aw_sar_i2c_read(p_sar->i2c, REG_STAT1, &status1);
aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &status0);
for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
if (((status1 >> i) & 0x01) == 1) {
if (aw9610x->satu_flag[i] == 0) {
aw_sar_i2c_read(p_sar->i2c, REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS, &aw9610x->satu_data[i]);
aw_sar_i2c_write(p_sar->i2c, REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS, ((aw9610x->satu_data[i] | 0x1fc) & 0x3fffffff));
aw9610x->satu_flag[i] = 1;
}
} else if (((status1 >> i) & 0x01) == 0) {
if (aw9610x->satu_flag[i] == 1) {
if (((status0 >> (i + 24)) & 0x01) == 0) {
aw_sar_i2c_write(p_sar->i2c, REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS, aw9610x->satu_data[i]);
aw9610x->satu_flag[i] = 0;
}
}
}
}
return AW_OK;
}
static void aw9610x_saturat_release_handle(struct aw_sar *p_sar)
{
uint32_t satu_irq = 0;
uint8_t i = 0;
uint32_t status0 = 0;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
AWLOGD(p_sar->dev, "enter");
satu_irq = (aw9610x->irq_status >> 7) & 0x01;
if (satu_irq == 1) {
aw9610x_baseline_filter(p_sar);
} else {
aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &status0);
for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
if (aw9610x->satu_flag[i] == 1) {
if (((status0 >> (i + 24)) & 0x01) == 0) {
aw_sar_i2c_write(p_sar->i2c, REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS, aw9610x->satu_data[i]);
aw9610x->satu_flag[i] = 0;
}
}
}
}
AWLOGI(p_sar->dev, "satu_irq handle over!");
}
static void aw9610x_irq_handle(struct aw_sar *p_sar)
{
uint8_t i = 0;
uint32_t curr_status = 0;
uint32_t curr_status_val = 0;
AWLOGD(p_sar->dev, "enter");
aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &curr_status_val);
AWLOGD(p_sar->dev, "channel = 0x%08x", curr_status_val);
if (p_sar->channels_arr == NULL) {
AWLOGE(p_sar->dev, "input err!!!");
return;
}
for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
curr_status =
(((uint8_t)(curr_status_val >> (24 + i)) & 0x1))
#ifdef AW_INPUT_TRIGGER_TH1
| (((uint8_t)(curr_status_val >> (16 + i)) & 0x1) << 1)
#endif
#ifdef AW_INPUT_TRIGGER_TH2
| (((uint8_t)(curr_status_val >> (8 + i)) & 0x1) << 2)
#endif
#ifdef AW_INPUT_TRIGGER_TH3
| (((uint8_t)(curr_status_val >> (i)) & 0x1) << 3)
#endif
;
//AWLOGI(p_sar->dev, "curr_state[%d] = 0x%x", i, curr_status);
if (p_sar->channels_arr[i].used == AW_FALSE) {
//AWLOGD(p_sar->dev, "channels_arr[%d] no user", i);
continue;
}
if (p_sar->channels_arr[i].last_channel_info == curr_status) {
continue;
}
switch (curr_status) {
case AW9610X_FAR:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 0);
break;
case AW9610X_TRIGGER_TH0:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 1);
break;
#ifdef AW_INPUT_TRIGGER_TH1
case AW9610X_TRIGGER_TH1:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 2);
break;
#endif
#ifdef AW_INPUT_TRIGGER_TH2
case AW9610X_TRIGGER_TH2:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 3);
break;
#endif
#ifdef AW_INPUT_TRIGGER_TH3
case AW9610X_TRIGGER_TH3:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 4);
break;
#endif
default:
AWLOGE(p_sar->dev, "error abs distance");
return;
}
input_sync(p_sar->channels_arr[i].input);
p_sar->channels_arr[i].last_channel_info = curr_status;
}
}
static void aw9610x_version_aw9610x_private(struct aw_sar *p_sar)
{
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
AWLOGD(p_sar->dev, "AW9610X enter");
if (aw9610x->satu_release == AW9610X_FUNC_ON)
aw9610x_saturat_release_handle(p_sar);
}
static void aw9610x_irq_handle_func(uint32_t irq_status, void *data)
{
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
AWLOGD(p_sar->dev, "enter");
AWLOGI(p_sar->dev, "IRQSRC = 0x%x", irq_status);
switch (aw9610x->vers) {
case AW9610X:
aw9610x_version_aw9610x_private(p_sar);
break;
case AW9610XA:
break;
default:
break;
}
aw9610x_irq_handle(p_sar);
}
int32_t aw9610x_check_chipid(void *data)
{
int32_t ret = -1;
uint32_t reg_val = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
if (p_sar == NULL) {
return -AW_BIN_PARA_INVALID;
}
ret = aw_sar_i2c_read(p_sar->i2c, REG_CHIPID, &reg_val);
if (ret < 0) {
AWLOGE(p_sar->dev, "read CHIP ID failed: %d", ret);
} else {
reg_val = reg_val >> 16;
}
if (reg_val == AW9610X_CHIP_ID) {
AWLOGI(p_sar->dev, "aw9610x detected, 0x%04x", reg_val);
return AW_OK;
} else {
AWLOGE(p_sar->dev, "unsupport dev, chipid is (0x%04x)", reg_val);
}
return -AW_ERR;
}
static const struct aw_sar_check_chipid_t g_aw9610x_check_chipid = {
.p_check_chipid_fn = aw9610x_check_chipid,
};
static ssize_t aw9610x_operation_mode_get(void *data, char *buf)
{
ssize_t len = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
if (p_sar->last_mode == AW9610X_ACTIVE_MODE)
len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Active\n");
else if (p_sar->last_mode == AW9610X_SLEEP_MODE)
len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Sleep\n");
else if ((p_sar->last_mode == AW9610X_DEEPSLEEP_MODE) && (aw9610x->vers == AW9610XA))
len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: DeepSleep\n");
else
len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Unconfirmed\n");
return len;
}
static void aw9610x_chip_info_get(void *data, char *buf, ssize_t *p_len)
{
uint32_t reg_data = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "sar%d, aw9610x chip driver version %s\n", p_sar->dts_info.sar_num, AW9610X_DRIVER_VERSION);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "The driver supports UI\n");
aw_sar_i2c_read(p_sar->i2c, REG_CHIPID, &reg_data);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "chipid is 0x%08x\n", reg_data);
aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &reg_data);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "REG_HOSTIRQEN is 0x%08x\n", reg_data);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "chip_name:%s bin_prase_chip_name:%s\n",
aw9610x->chip_name, aw9610x->chip_type);
}
static const struct aw_sar_get_chip_info_t g_aw9610x_get_chip_info = {
.p_get_chip_info_node_fn = aw9610x_chip_info_get,
};
static void aw9610x_reg_version_comp(struct aw_sar *p_sar, struct aw_bin *aw_bin)
{
uint8_t i = 0;
uint32_t blfilt1_data = 0;
uint32_t blfilt1_tmp = 0;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
if ((aw9610x->chip_name[7] == 'A') &&
(aw_bin->header_info[0].chip_type[7] == '\0')) {
AWLOGI(p_sar->dev, "enter");
for (i = 0; i < 6; i++) {
aw_sar_i2c_read(p_sar->i2c, REG_BLFILT_CH0 + (0x3c * i), &blfilt1_data);
AWLOGD(p_sar->dev, "addr 0x%04x val: 0x%08x", REG_BLFILT_CH0 + (0x3c * i), blfilt1_data);
blfilt1_tmp = (blfilt1_data >> 25) & 0x1;
if (blfilt1_tmp == 1) {
AWLOGD(p_sar->dev, "ablfilt1_tmp is 1");
aw_sar_i2c_write_bits(p_sar->i2c, REG_BLRSTRNG_CH0 + (0x3c * i), ~(0x3f), 1 << i);
}
}
}
}
static int32_t aw9610x_load_reg_bin(struct aw_bin *aw_bin, struct aw_sar *p_sar)
{
int32_t ret = 0;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
snprintf(aw9610x->chip_type, sizeof(aw9610x->chip_type), "%s", aw_bin->header_info[0].chip_type);
AWLOGE(p_sar->dev, "chip name: %s", aw9610x->chip_type);
ret = aw_sar_load_reg(aw_bin, p_sar->i2c);
aw9610x_reg_version_comp(p_sar, aw_bin);
return ret;
}
static ssize_t aw9610x_get_self_cap_offset(void *data, char *buf)
{
ssize_t len = 0;
uint8_t i = 0;
uint32_t reg_val = 0;
uint32_t coff_data = 0;
uint32_t coff_data_int = 0;
uint32_t coff_data_dec = 0;
uint8_t temp_data[20] = { 0 };
struct aw_sar *p_sar = (struct aw_sar *)data;
for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
aw_sar_i2c_read(p_sar->i2c,
REG_AFECFG1_CH0 + i * AW_CL1SPE_CALI_OS, &reg_val);
coff_data = (reg_val >> 24) * 900 +
((reg_val >> 16) & 0xff) * 13;
coff_data_int = coff_data / 1000;
coff_data_dec = coff_data % 1000;
snprintf(temp_data, sizeof(temp_data), "%d.%d", coff_data_int,
coff_data_dec);
len += snprintf(buf+len, PAGE_SIZE-len,
"PARASITIC_DATA_CH%d = %s pf\n", i, temp_data);
}
return len;
}
static const struct aw_sar_offset_t g_aw9610x_offset = {
.p_get_offset_node_fn = aw9610x_get_self_cap_offset,
};
static uint32_t attr_buf[] = {
8, 10,
9, 100,
10, 1000,
};
static void aw9610x_addrblock_load(struct aw_sar *p_sar, const char *buf)
{
uint32_t addrbuf[4] = { 0 };
uint8_t temp_buf[2] = { 0 };
uint32_t i = 0;
struct aw9610x *aw9610x = p_sar->priv_data;
uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
for (i = 0; i < addr_bytes; i++) {
if (reg_num < attr_buf[1]) {
temp_buf[0] = buf[attr_buf[0] + i * 5];
temp_buf[1] = buf[attr_buf[0] + i * 5 + 1];
} else if (reg_num >= attr_buf[1] && reg_num < attr_buf[3]) {
temp_buf[0] = buf[attr_buf[2] + i * 5];
temp_buf[1] = buf[attr_buf[2] + i * 5 + 1];
} else if (reg_num >= attr_buf[3] && reg_num < attr_buf[5]) {
temp_buf[0] = buf[attr_buf[4] + i * 5];
temp_buf[1] = buf[attr_buf[4] + i * 5 + 1];
}
if (sscanf(temp_buf, "%02x", &addrbuf[i]) == 1)
aw9610x->aw_i2c_package.init_addr[i] = (uint8_t)addrbuf[i];
}
}
static int32_t aw9610x_awrw_write_seq(struct aw_sar *p_sar)
{
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
uint8_t w_buf[228];
uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
uint8_t msg_cnt = 0;
uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
uint8_t *p_reg_data = aw9610x->aw_i2c_package.p_reg_data;
uint32_t msg_idx = 0;
for (msg_idx = 0; msg_idx < addr_bytes; msg_idx++) {
w_buf[msg_idx] = aw9610x->aw_i2c_package.init_addr[msg_idx];
AWLOGI(p_sar->dev, "w_buf_addr[%d] = 0x%02x", msg_idx, w_buf[msg_idx]);
}
msg_cnt = addr_bytes;
for (msg_idx = 0; msg_idx < data_bytes * reg_num; msg_idx++) {
w_buf[msg_cnt] = *p_reg_data++;
msg_cnt++;
}
return aw_sar_i2c_write_seq(p_sar->i2c, w_buf, msg_cnt);
}
static void aw9610x_datablock_load(struct aw_sar *p_sar, const char *buf)
{
uint32_t i = 0;
uint8_t reg_data[220] = { 0 };
uint32_t databuf[220] = { 0 };
uint8_t temp_buf[2] = { 0 };
struct aw9610x *aw9610x = p_sar->priv_data;
uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
for (i = 0; i < data_bytes * reg_num; i++) {
if (reg_num < attr_buf[1]) {
temp_buf[0] = buf[attr_buf[0] + (addr_bytes + i) * 5];
temp_buf[1] =
buf[attr_buf[0] + (addr_bytes + i) * 5 + 1];
} else if (reg_num >= attr_buf[1] && reg_num < attr_buf[3]) {
temp_buf[0] = buf[attr_buf[2] + (addr_bytes + i) * 5];
temp_buf[1] =
buf[attr_buf[2] + (addr_bytes + i) * 5 + 1];
} else if (reg_num >= attr_buf[3] && reg_num < attr_buf[5]) {
temp_buf[0] = buf[attr_buf[4] + (addr_bytes + i) * 5];
temp_buf[1] =
buf[attr_buf[4] + (addr_bytes + i) * 5 + 1];
}
sscanf(temp_buf, "%02x", &databuf[i]);
reg_data[i] = (uint8_t)databuf[i];
}
aw9610x->aw_i2c_package.p_reg_data = reg_data;
aw9610x_awrw_write_seq(p_sar);
}
static int32_t aw9610x_awrw_read_seq(struct aw_sar *p_sar, uint8_t *reg_data)
{
struct aw9610x *aw9610x= (struct aw9610x *)p_sar->priv_data;
int32_t ret = 0;
uint8_t w_buf[4];
uint8_t buf[228];
uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
uint32_t msg_idx = 0;
uint32_t msg_cnt = data_bytes * reg_num;
for (msg_idx = 0; msg_idx < addr_bytes; msg_idx++) {
w_buf[msg_idx] = aw9610x->aw_i2c_package.init_addr[msg_idx];
AWLOGD(p_sar->dev, "w_buf_addr[%d] = 0x%02x",
msg_idx, w_buf[msg_idx]);
}
ret = aw_sar_i2c_read_seq(p_sar->i2c, w_buf, 2, (uint8_t *)buf, msg_cnt);
for (msg_idx = 0; msg_idx < msg_cnt; msg_idx++) {
reg_data[msg_idx] = buf[msg_idx];
AWLOGD(p_sar->dev, "buf = 0x%02x", buf[msg_idx]);
}
return ret;
}
static ssize_t aw9610x_awrw_get(void *data, char *buf)
{
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x= (struct aw9610x *)p_sar->priv_data;
uint8_t reg_data[228] = { 0 };
uint8_t i = 0;
ssize_t len = 0;
uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
aw9610x_awrw_read_seq(p_sar, reg_data);
for (i = 0; i < reg_num * data_bytes; i++) {
len += snprintf(buf + len, PAGE_SIZE - len,
"0x%02x,", reg_data[i]);
}
snprintf(buf + len - 1, PAGE_SIZE - len, "\n");
return len;
};
static ssize_t aw9610x_awrw_set(void *data, const char *buf, size_t count)
{
uint32_t datatype[3] = { 0 };
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x= (struct aw9610x *)p_sar->priv_data;
if (sscanf(buf, "%d %d %d", &datatype[0], &datatype[1], &datatype[2]) == 3) {
aw9610x->aw_i2c_package.addr_bytes = (uint8_t)datatype[0];
aw9610x->aw_i2c_package.data_bytes = (uint8_t)datatype[1];
aw9610x->aw_i2c_package.reg_num = (uint8_t)datatype[2];
aw9610x_addrblock_load(p_sar, buf);
if (count > 7 + 5 * aw9610x->aw_i2c_package.addr_bytes)
aw9610x_datablock_load(p_sar, buf);
}
return count;
}
static int32_t aw9610x_get_chip_version(void *data)
{
uint32_t fw_ver = 0;
int32_t ret = 0;
uint32_t firmvers = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
aw_sar_i2c_read(p_sar->i2c, REG_FWVER, &firmvers);
AWLOGD(p_sar->dev, "REG_FWVER = 0x%08x", firmvers);
ret = aw_sar_i2c_read(p_sar->i2c, REG_FWVER2, &fw_ver);
if (ret < 0) {
AWLOGE(p_sar->dev, "read REG_FWVER2 err!");
return -AW_ERR;
}
snprintf(aw9610x->chip_name, sizeof(aw9610x->chip_name), "AW9610X");
p_sar->chip_type = AW_SAR_NONE_CHECK_CHIP;
AWLOGD(p_sar->dev, "REG_FWVER2 : 0x%08x", fw_ver);
if (fw_ver == AW_CHIP_AW9610XA) {
aw9610x->vers = AW9610XA;
memcpy(aw9610x->chip_name + strlen(aw9610x->chip_name), "A", 2);
p_sar->chip_type = SAR_AW9610XA;
} else {
aw9610x->vers = AW9610X;
p_sar->chip_type = SAR_AW9610X;
aw9610x->chip_name[7] = '\0';
}
AWLOGI(p_sar->dev, "the IC is = %s", aw9610x->chip_name);
return AW_OK;
}
#ifdef AW9610X_TVS_ABNORMAL_CAIL
static ssize_t aw9610x_set_aot(void *data)
{
struct aw_sar *p_sar = (struct aw_sar *)data;
struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
uint32_t i = 0;
uint32_t irqen_reg_val = 0;
uint32_t reg_val_tmp = 0;
uint32_t max_delay_ms = AW9610X_AOT_OVER_DELAY_MAX_MS;
uint32_t scan_over_cnt = 0;
uint32_t ch_en = 0;
uint32_t scan_over_en = 0;
//1. disable chip irq
aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &irqen_reg_val);
aw_sar_i2c_write(p_sar->i2c, REG_IRQEN, AW_REG_IRQEN_CLOSE);
//2. aot cail
aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL0, ~(AW9610X_AOT_MASK << AW9610X_AOT_BIT),
AW9610X_AOT_MASK << AW9610X_AOT_BIT);
// aot over
for (i = 0; i < max_delay_ms; i++) {
aw_sar_i2c_read(p_sar->i2c, REG_IRQSRC, &reg_val_tmp);
if (((reg_val_tmp >> AW_REG_IRQSRC_AOT_OVER_BIT) & 0x01) == 1) {
AWLOGD(p_sar->dev, "aot over i = %d REG_IRQSRC:0X%X", i, reg_val_tmp);
break;
}
AWLOGD(p_sar->dev, "aot over i = %d REG_IRQSRC:0X%X", i, reg_val_tmp);
msleep(1);
}
//3. scan 8 cnt over
aw_sar_i2c_read(p_sar->i2c, REG_SCANCTRL0, &ch_en);
aw_sar_i2c_read(p_sar->i2c, REG_CHINTEN, &scan_over_en);
if ((ch_en & AW9610X_AOT_MASK) != (scan_over_en & AW9610X_AOT_MASK)) {
aw_sar_i2c_write_bits(p_sar->i2c, REG_CHINTEN, ~(AW9610X_AOT_MASK), ch_en & (AW9610X_AOT_MASK));
}
for (scan_over_cnt = 0; scan_over_cnt < AW9610X_AOT_SCAN_OVER_CNT; scan_over_cnt++) {
for (i = 0; i < max_delay_ms; i++) {
aw_sar_i2c_read(p_sar->i2c, REG_IRQSRC, &reg_val_tmp);
if (((reg_val_tmp >> REG_IRQSRC_SCAN_OVER_BIT) & 0x01) == 1) {
//AWLOGD(p_sar->dev, "scan %d cnt over REG_IRQSRC %d:0X%X", scan_over_cnt, i, reg_val_tmp);
break;
}
msleep(1);
}
}
if ((ch_en & AW9610X_AOT_MASK) != (scan_over_en & AW9610X_AOT_MASK)) {
aw_sar_i2c_write_bits(p_sar->i2c, REG_CHINTEN, ~(AW9610X_AOT_MASK), ch_en & (AW9610X_AOT_MASK));
}
if (aw9610x->vers == AW9610XA) {
//4. chip set sleep mode
aw_sar_i2c_write(p_sar->i2c, REG_CMD, AW9610X_SLEEP_MODE);
} else if (aw9610x->vers == AW9610X) {
aw_sar_i2c_write(p_sar->i2c, REG_CMD, AW9610X_DEEPSLEEP_MODE); //set aw9610x sleep mode
}
for (i = 0; i < max_delay_ms; i++) {
aw_sar_i2c_read(p_sar->i2c, REG_WST, &reg_val_tmp);
if ((reg_val_tmp & 0xFF) == REG_REG_WST_SLEEP_MODE) {
AWLOGD(p_sar->dev, "sleep i = %d REG_WST:0X%X", i, reg_val_tmp);
break;
}
msleep(1);
}
//5. write baseline data
for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
aw_sar_i2c_read(p_sar->i2c, REG_COMP_CH0 + i * AW9610X_REG_OFFSET_STEP, &reg_val_tmp);
aw_sar_i2c_write(p_sar->i2c, REG_BASELINE_CH0 + i *AW9610X_REG_OFFSET_STEP, reg_val_tmp);
}
//6. chip set active, irq recovery
aw_sar_i2c_write(p_sar->i2c, REG_CMD, AW9610X_ACTIVE_MODE);
aw_sar_i2c_write(p_sar->i2c, REG_IRQEN, irqen_reg_val);
AWLOGD(p_sar->dev, "AW9610X_TVS_ABNORMAL_CAIL OVER!");
return AW_OK;
}
#else
static ssize_t aw9610x_set_aot(void *data)
{
struct aw_sar *p_sar = (struct aw_sar *)data;
aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL0, ~(AW9610X_AOT_MASK << AW9610X_AOT_BIT),
(AW9610X_AOT_MASK) << AW9610X_AOT_BIT);
return AW_OK;
}
#endif
static const struct aw_sar_aot_t g_aw9610x_aot = {
.p_set_aot_node_fn = aw9610x_set_aot,
};
/**********************mode operation start*******************************/
static void aw9610x_enable_clock(void *i2c)
{
aw_sar_i2c_write(i2c, REG_OSCEN, AW9610X_CPU_WORK_MASK);
}
static uint32_t aw9610x_rc_irqscr(void *i2c)
{
uint32_t val = 0;
aw_sar_i2c_read(i2c, REG_IRQSRC, &val);
return val;
}
//Note: TVS exceptions need to be handled after active
static void aw9610x_set_active_cmd(void *i2c)
{
aw_sar_i2c_write(i2c, REG_CMD, AW9610X_ACTIVE_MODE);
#ifdef AW9610X_TVS_ABNORMAL_CAIL
AWLOGD(g_aw_sar->dev, "AW9610X_TVS_ABNORMAL_CAIL");
if (g_aw_sar != NULL) {
aw9610x_set_aot(g_aw_sar);
}
#endif
}
static void aw9610x_set_sleep_cmd(void *i2c)
{
aw_sar_i2c_write(i2c, REG_CMD, AW9610X_SLEEP_MODE);
}
static void aw9610x_set_deepsleep_cmd(void *i2c)
{
aw_sar_i2c_write(i2c, REG_CMD, AW9610X_DEEPSLEEP_MODE);
}
static const struct aw_sar_mode_set_t g_aw9610x_mode_set[] = {
{
.chip_id = SAR_AW9610XA | SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_ACTIVE_MODE,
.last_mode = AW9610X_DEEPSLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = aw9610x_enable_clock,
.rc_irqscr = NULL,
.mode_update = aw9610x_set_active_cmd,
},
},
{
.chip_id = SAR_AW9610XA | SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_ACTIVE_MODE,
.last_mode = AW9610X_SLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9610x_set_active_cmd,
},
},
{
.chip_id = SAR_AW9610XA | SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_ACTIVE_MODE,
.last_mode = AW9610X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9610x_set_active_cmd,
},
},
{
.chip_id = SAR_AW9610XA | SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_SLEEP_MODE,
.last_mode = AW9610X_DEEPSLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = aw9610x_enable_clock,
.rc_irqscr = NULL,
.mode_update = aw9610x_set_sleep_cmd,
},
},
{
.chip_id = SAR_AW9610XA | SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_SLEEP_MODE,
.last_mode = AW9610X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9610x_set_sleep_cmd,
},
},
{
.chip_id = SAR_AW9610XA | SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_DEEPSLEEP_MODE,
.last_mode = AW9610X_SLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9610x_set_deepsleep_cmd,
},
},
{
.chip_id = SAR_AW9610XA,
.chip_mode = {
.curr_mode = AW9610X_DEEPSLEEP_MODE,
.last_mode = AW9610X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = aw9610x_rc_irqscr,
.mode_update = aw9610x_set_deepsleep_cmd,
},
},
{
.chip_id = SAR_AW9610X,
.chip_mode = {
.curr_mode = AW9610X_DEEPSLEEP_MODE,
.last_mode = AW9610X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = NULL,
},
},
};
/**********************mode operation end*******************************/
static const struct aw_sar_irq_init_t g_aw9610x_irq_init = {
.flags = GPIOF_DIR_IN | GPIOF_INIT_HIGH,
.irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
.handler = NULL,
.thread_fn = NULL,
.rc_irq_fn = aw9610x_rc_irqscr,
.irq_spec_handler_fn = aw9610x_irq_handle_func,
};
static const struct aw_sar_soft_rst_t g_aw9610x_soft_rst = {
.reg_rst = REG_RESET,
.reg_rst_val = 0,
.delay_ms = 20,
};
static const struct aw_sar_init_over_irq_t g_aw9610x_init_over_irq = {
.wait_times = 20,
.daley_step = 1,
.reg_irqsrc = REG_IRQSRC,
.irq_offset_bit = 0,
.irq_mask = 0x1,
.irq_flag = 0x1,
};
static const struct aw_sar_load_bin_t g_aw9610x_load_reg_bin = {
.bin_name = "aw9610x",
.bin_opera_func = (aw_sar_bin_opera_t)aw9610x_load_reg_bin,
.p_update_fn = NULL,
};
static const struct aw_sar_para_load_t g_aw9610x_reg_arr_para = {
.reg_arr = aw9610x_reg_default,
.reg_arr_len = (sizeof(aw9610x_reg_default) / sizeof(aw9610x_reg_default[0])),
};
static const struct aw_sar_diff_t g_aw9610x_diff = {
.diff0_reg = REG_DIFF_CH0,
.diff_step = 4,
.rm_float = AW9610x_DATA_PROCESS_FACTOR,
};
static const struct aw_sar_mode_t g_aw9610x_mode = {
.mode_set_arr = &g_aw9610x_mode_set[0],
.mode_set_arr_len = sizeof(g_aw9610x_mode_set) / sizeof(g_aw9610x_mode_set[0]),
.p_set_mode_node_fn = NULL,
.p_get_mode_node_fn = aw9610x_operation_mode_get,
};
static const struct aw_sar_reg_list_t g_aw9610x_reg_list = {
.reg_none_access = REG_NONE_ACCESS,
.reg_rd_access = REG_RD_ACCESS,
.reg_wd_access = REG_WR_ACCESS,
.reg_perm = (struct aw_sar_reg_data *)&g_aw9610x_reg_access[0],
.reg_num = sizeof(g_aw9610x_reg_access) / sizeof(g_aw9610x_reg_access[0]),
};
static const struct aw_sar_pm_t g_aw9610x_pm_chip_mode = {
.suspend_set_mode = AW9610X_SLEEP_MODE,
.resume_set_mode = AW9610X_ACTIVE_MODE,
.shutdown_set_mode = AW9610X_SLEEP_MODE,
};
static const struct aw_sar_chip_mode_t g_aw9610x_chip_mode = {
.init_mode = AW9610X_ACTIVE_MODE,
.active = AW9610X_ACTIVE_MODE,
.pre_init_mode = AW9610X_SLEEP_MODE,
};
static const struct aw_sar_regulator_config_t g_regulator_config = {
.vcc_name = "vcc",
.min_uV = AW9610X_SAR_VCC_MIN_UV,
.max_uV = AW9610X_SAR_VCC_MAX_UV,
};
struct aw_sar_awrw_t g_aw9610x_awrw = {
.p_set_awrw_node_fn = aw9610x_awrw_set,
.p_get_awrw_node_fn = aw9610x_awrw_get,
};
static const struct aw_sar_platform_config g_aw9610x_platform_config = {
.p_regulator_config = &g_regulator_config,
.p_irq_init = &g_aw9610x_irq_init,
.p_pm_chip_mode = &g_aw9610x_pm_chip_mode,
};
static const struct aw_sar_chip_config g_aw9610x_chip_config = {
.ch_num_max = AW9610X_CHANNEL_MAX,
.p_platform_config = &g_aw9610x_platform_config,
.p_check_chipid = &g_aw9610x_check_chipid,
.p_soft_rst = &g_aw9610x_soft_rst,
.p_init_over_irq = &g_aw9610x_init_over_irq,
.p_fw_bin = NULL,
.p_reg_bin = &g_aw9610x_load_reg_bin,
.p_chip_mode = &g_aw9610x_chip_mode,
//Node usage parameters
.p_reg_list = &g_aw9610x_reg_list,
.p_reg_arr = &g_aw9610x_reg_arr_para,
.p_aot = &g_aw9610x_aot,
.p_diff = &g_aw9610x_diff,
.p_offset = &g_aw9610x_offset,
.p_mode = &g_aw9610x_mode,
.p_prox_fw = NULL,
.p_get_chip_info = &g_aw9610x_get_chip_info,
.p_aw_sar_awrw = &g_aw9610x_awrw,
.p_boot_bin = NULL,
.p_other_operation = aw9610x_get_chip_version,
.p_other_opera_free = NULL,
};
int32_t aw9610x_init(struct aw_sar *p_sar)
{
if (p_sar == NULL) {
AWLOGE(p_sar->dev, "para is NULL, error!");
return -AW_ERR;
}
g_aw_sar = p_sar;
p_sar->priv_data = devm_kzalloc(p_sar->dev, sizeof(struct aw9610x), GFP_KERNEL);
if (p_sar->priv_data == NULL) {
AWLOGE(p_sar->dev, "priv_data failed to malloc memory!");
return -AW_ERR;
}
//Chip private function operation
p_sar->p_sar_para = &g_aw9610x_chip_config;
return AW_OK;
}
void aw9610x_deinit(struct aw_sar *p_sar)
{
if (p_sar->priv_data != NULL) {
devm_kfree(p_sar->dev, p_sar->priv_data);
}
}

View file

@ -0,0 +1,655 @@
#include "aw9620x.h"
#include "aw_update_fw_interface.h"
#define AW9620X_DRIVER_VERSION "v0.0.8"
static uint32_t aw9620x_rc_irqscr(void *i2c);
static void aw9620x_irq_handle_func(uint32_t irq_status, void *data)
{
int32_t ret = 0;
uint32_t curr_status_val = 0;
uint32_t curr_status = 0;
uint8_t i = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
AWLOGD(p_sar->dev, "IRQSRC = 0x%x", irq_status);
ret = aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &curr_status_val);
if (ret < 0) {
AWLOGE(p_sar->dev, "i2c IO error");
return;
}
AWLOGD(p_sar->dev, "STAT0 = 0x%x", curr_status_val);
for (i = 0; i < AW9620X_CHANNEL_NUM_MAX; i++) {
curr_status = (((curr_status_val >> (OFFSET_BIT_8 + i)) & 0x1) << 1) |
(((curr_status_val >> (i)) & 0x1));
if (p_sar->channels_arr[i].used == AW_FALSE) {
continue;
}
if (p_sar->channels_arr[i].last_channel_info == curr_status) {
continue;
}
switch (curr_status) {
case AW9620X_TRIGGER_FAR:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, AW9620X_TRIGGER_FAR);
break;
case AW9620X_TRIGGER_TH0:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, AW9620X_TRIGGER_TH0);
break;
case AW9620X_TRIGGER_TH1:
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, AW9620X_TRIGGER_TH1);
break;
default:
AWLOGD(p_sar->dev, "error abs distance");
return;
}
input_sync(p_sar->channels_arr[i].input);
p_sar->channels_arr[i].last_channel_info = curr_status;
}
}
int32_t aw9620x_check_chipid(void *data)
{
int32_t ret = -AW_ERR;
uint32_t reg_val = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
if ((p_sar == NULL) && ( p_sar->priv_data == NULL)) {
return -AW_BIN_PARA_INVALID;
}
AWLOGD(p_sar->dev, "enter");
ret = aw_sar_i2c_read(p_sar->i2c, REG_CHIP_ID, &reg_val);
if (ret < 0) {
AWLOGE(p_sar->dev, "read CHIP ID failed: %d", ret);
return -AW_ERR;
}
switch (reg_val)
{
case AW96203CSR_CHIP_ID:
memcpy(p_sar->chip_name, "aw96203", 8);
AWLOGD(p_sar->dev, "AW96203CSR CHIP ID : 0x%x", reg_val);
break;
case AW96205DNR_CHIP_ID:
memcpy(p_sar->chip_name, "aw96205", 8);
AWLOGD(p_sar->dev, "AW96205DNR CHIP ID : 0x%x", reg_val);
break;
case AW96208CSR_CHIP_ID:
memcpy(p_sar->chip_name, "aw96208", 8);
AWLOGD(p_sar->dev, "AW96208CSR CHIP ID : 0x%x", reg_val);
break;
default:
AWLOGD(p_sar->dev, "no chipid,need update root and frimware,CHIP ID : 0x%x", reg_val);
return -AW_ERR_CHIPID;
break;
}
p_sar->chip_type = AW_SAR_NONE_CHECK_CHIP;
return AW_OK;
}
static int32_t aw9620x_soft_reset(void *data)
{
int32_t ret = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
AWLOGD(p_sar->dev, "enter");
ret = aw_sar_i2c_write(p_sar->i2c, REG_ACCESSEN, REG_OPEN_APB_ACCESS_EN);
if (ret < 0) {
AWLOGE(p_sar->dev, "read REG_APB_ACCESS_EN err: %d", ret);
return -AW_ERR;
}
ret = aw_sar_i2c_write(p_sar->i2c, AW_REG_FLASH_WAKE_UP, AW_REG_FLASH_WAKE_UP_ON);
if (ret < 0) {
AWLOGE(p_sar->dev, "read REG_APB_ACCESS_EN err: %d", ret);
return -AW_ERR;
}
msleep(1);
ret = aw_sar_i2c_write(p_sar->i2c, REG_MCFG, REG_SET_MCFG00);
if (ret != AW_OK) {
AWLOGD(p_sar->dev, "REG_MCFG err");
return ret;
}
msleep(AW9620X_REG_MCFG_DELAY_MS);
ret = aw_sar_i2c_write(p_sar->i2c, REG_RSTNALL, AW9620X_REG_RSTNALL_VAL);
if (ret < 0) {
AWLOGE(p_sar->dev, "read soft_reset err: %d", ret);
return -AW_ERR;
}
msleep(AW9620X_POWER_ON_DELAY_MS);
ret = aw_sar_i2c_write(p_sar->i2c, AW_REG_FLASH_WAKE_UP, AW_REG_FLASH_WAKE_UP_OFF);
if (ret < 0) {
AWLOGE(p_sar->dev, "read REG_APB_ACCESS_EN err: %d", ret);
return -AW_ERR;
}
return AW_OK;
}
static int32_t aw9620x_load_reg_bin(struct aw_bin *aw_bin, void *load_bin_para)
{
int32_t ret = 0;
struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
/*
if (p_sar->chip_name == NULL) {
AWLOGE(p_sar->dev, "p_sar->chip_name is NULL, error!");
return -AW_ERR;
}
*/
AWLOGE(p_sar->dev, "reg chip name: %s, soc chip name: %s, len = %d",
p_sar->chip_name, aw_bin->header_info[0].chip_type, aw_bin->info.len);
ret = strncmp(p_sar->chip_name, aw_bin->header_info[0].chip_type, sizeof(aw_bin->header_info[0].chip_type));
if (ret != 0) {
AWLOGE(p_sar->dev,
"load_binname(%s) incompatible with chip type(%s)",
p_sar->chip_name, aw_bin->header_info[0].chip_type);
//return -AW_ERR;
}
ret = aw_sar_load_reg(aw_bin, p_sar->i2c);
return ret;
}
/*************************fw update start************************/
static int32_t aw9620x_reg_update_firmware(struct aw_bin *aw_bin, void *load_bin_para)
{
uint32_t start_index = aw_bin->header_info[0].valid_data_addr;
int32_t ret = 0;
struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
ret = aw9620x_reg_update_fw(p_sar->i2c,
&(aw_bin->info.data[start_index]), aw_bin->header_info[0].valid_data_len);
if (ret != AW_OK) {
AWLOGE(p_sar->dev, "reg update fw error");
}
ret = aw9620x_soft_reset(p_sar);
aw9620x_rc_irqscr(p_sar->i2c);
return ret;
}
//BOOT update
static int32_t aw9620x_reg_update_bt(struct aw_bin *aw_bin, void *load_bin_para)
{
uint32_t start_index = aw_bin->header_info[0].valid_data_addr;
struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
return aw9620x_reg_update_boot(p_sar->i2c,
&(aw_bin->info.data[start_index]), aw_bin->header_info[0].valid_data_len);
}
static int32_t aw9620x_prot_update_firmware(struct aw_bin *aw_bin,void *load_bin_para)
{
uint32_t start_index = aw_bin->header_info[0].valid_data_addr;
uint32_t fw_bin_version = aw_bin->header_info[0].app_version;
struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
//If the verification of flash firmware area fails, the version number will not be compared, and it will be loaded directly
uint8_t direct_updata_flag = p_sar->fw_fail_flag;
return aw9620x_prot_update_fw(p_sar->i2c, direct_updata_flag,
&(aw_bin->info.data[start_index]), aw_bin->header_info[0].valid_data_len, fw_bin_version);
}
static int32_t aw9620x_prox_direct_upgrade_firmware(struct aw_bin *aw_bin, void *load_bin_para)
{
uint32_t start_index = aw_bin->header_info[0].valid_data_addr;
uint32_t fw_bin_version = aw_bin->header_info[0].app_version;
struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
return aw9620x_prot_update_fw(p_sar->i2c, AW_TRUE,
&(aw_bin->info.data[start_index]), aw_bin->header_info[0].valid_data_len, fw_bin_version);
}
/*************************fw update end************************/
/**********************mode operation start*******************************/
static void aw9620x_enable_clock(void *i2c)
{
aw_sar_i2c_write(i2c, REG_HOSTCTRL, REG_HOSTCTRL_EN);
}
static uint32_t aw9620x_rc_irqscr(void *i2c)
{
uint32_t val = 0;
aw_sar_i2c_read(i2c, REG_IRQSRC, &val);
return val;
}
static void aw9620x_set_active_cmd(void *i2c)
{
aw_sar_i2c_write(i2c, REG_CMD, AW9620X_ACTIVE_MODE);
}
static void aw9620x_set_sleep_cmd(void *i2c)
{
aw_sar_i2c_write(i2c, REG_CMD, AW9620X_SLEEP_MODE);
}
static void aw9620x_set_deepsleep_cmd(void *i2c)
{
aw_sar_i2c_write(i2c, REG_CMD, AW9620X_DEEPSLEEP_MODE);
}
static ssize_t aw9620x_mode_operation_get(void *data, char *buf)
{
uint32_t reg_val = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
aw_sar_i2c_read(p_sar->i2c, REG_WST, &reg_val);
return snprintf(buf, PAGE_SIZE, "mode : %d, REG_WST :0x%x \n",
p_sar->last_mode, reg_val);
}
static void aw9620x_mul_cap_parasitic_data_get(struct aw_sar *p_sar,
char *buf, uint32_t ch, uint32_t *p_len, uint32_t reg_data)
{
uint32_t j = 0;
uint32_t reg_data_cfg_val = 0;
uint32_t off_m = 0;
uint32_t fine_off_f_temp = 0;
uint32_t off_f = 0;
uint32_t off_c = 0;
int32_t s_off_c = 0;
int32_t parasitic_data_temp = 0;
int32_t parasitic_data_int = 0;
int32_t parasitic_data_float = 0;
if (((reg_data >> AW9620X_AFECFG3_CVOFF2X) & 0x1) == 0) {
aw_sar_i2c_read(p_sar->i2c, REG_AFECFG1_CH0 + AW9620X_CFG_REG_STEP * ch, &reg_data_cfg_val);
off_m = (reg_data_cfg_val >> 16) & 0xff;
off_f = reg_data_cfg_val & 0xff;
fine_off_f_temp = off_f * AW9620X_FINE_ADJUST_STEP0;
off_c = (reg_data_cfg_val >> 8) & 0xff;
for (j = 0; j < 8; j++) {
s_off_c += ((1 - 2 * ((off_m >> j) & 0x1)) * ((off_c >> j) & 0x1) * aw_sar_pow2(j)) * AW9620X_COARSE_ADJUST_STEP0;
}
parasitic_data_temp = AW_SAR_ABS((int32_t)fine_off_f_temp + s_off_c);
parasitic_data_int = parasitic_data_temp / AW9620X_PARA_TIMES;
parasitic_data_float = parasitic_data_temp % AW9620X_PARA_TIMES;
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "ch%d parasitic_data %d.%d pf\n", ch, parasitic_data_int, parasitic_data_float);
} else {
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "ch%d Mutual tolerance mode does not allow 2x to be configured", ch);
}
}
static void aw9620x_self_cap_parasitic_data_get(struct aw_sar *p_sar,
char *buf, uint32_t ch, uint32_t *p_len, uint32_t reg_data)
{
uint32_t reg_data_cfg = 0;
uint32_t reg_data_cfg_val = 0;
uint32_t reg_data_cfg_tmp0 = 0;
uint32_t reg_data_cfg_tmp1 = 0;
uint32_t cfg_int = 0;
uint32_t cfg_float = 0;
aw_sar_i2c_read(p_sar->i2c, REG_AFECFG1_CH0 + AW9620X_CFG_REG_STEP * ch, &reg_data_cfg_val);
if (((reg_data >> AW9620X_AFECFG3_CVOFF2X) & 0x1) == 0) {
reg_data_cfg_tmp0 = (reg_data_cfg_val & 0xff) * AW9620X_FINE_ADJUST_STEP0;
reg_data_cfg_tmp1 = ((reg_data_cfg_val >> 8) & 0xff) * AW9620X_COARSE_ADJUST_STEP0;
} else {
reg_data_cfg_tmp0 = (reg_data_cfg_val & 0xff) * AW9620X_FINE_ADJUST_STEP1;
reg_data_cfg_tmp1 = ((reg_data_cfg_val >> 8) & 0xff) * AW9620X_COARSE_ADJUST_STEP1;
}
reg_data_cfg = reg_data_cfg_tmp0 + reg_data_cfg_tmp1;
cfg_int = reg_data_cfg / AW9620X_PARA_TIMES;
cfg_float = reg_data_cfg % AW9620X_PARA_TIMES;
*p_len+= snprintf(buf + *p_len, PAGE_SIZE - *p_len, "ch%d parasitic_data %d.%d pf\n", ch, cfg_int, cfg_float);
}
static ssize_t aw9620x_offset_get(void *data, char *buf)
{
uint32_t len = 0;
uint32_t i = 0;
uint32_t reg_data = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
for (i = 0; i < AW9620X_CHANNEL_NUM_MAX; i++) {
aw_sar_i2c_read(p_sar->i2c, REG_AFECFG3_CH0 + AW9620X_CFG_REG_STEP * i, &reg_data);
if (((reg_data >> AW9620X_AFECFG3_CVMULTUALMOD) & 0x1) != 1) {
//self contained
aw9620x_self_cap_parasitic_data_get(p_sar, buf, i, &len, reg_data);
} else {
//mutual compatibility
aw9620x_mul_cap_parasitic_data_get(p_sar, buf, i, &len, reg_data);
}
}
return len;
}
static void aw9620x_sar_chip_info_get(void *data, char *buf, ssize_t *p_len)
{
uint32_t reg_data = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "sar%d, aw9620x chip driver version:%s\n",
p_sar->dts_info.sar_num, AW9620X_DRIVER_VERSION);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "The driver supports UI\n");
aw_sar_i2c_read(p_sar->i2c, REG_CHIP_ID, &reg_data);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "chipid is 0x%08x\n", reg_data);
aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &reg_data);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "REG_HOSTIRQEN is 0x%08x\n", reg_data);
}
static void aw9620x_get_firmware_version(void *data, char *buf, ssize_t *p_len)
{
uint32_t fw_ver = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
aw_sar_i2c_read(p_sar->i2c, REG_FWVER, &fw_ver);
*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "current firmware version is 0x%08x\n", fw_ver);
}
static int32_t aw9320x_get_err_info(void *data)
{
uint32_t err_code = 0;
uint32_t boot_mode = 0;
uint32_t jump_info = 0;
struct aw_sar *p_sar = (struct aw_sar *)data;
aw_sar_i2c_write(p_sar->i2c, REG_ACCESSEN, REG_ACCESSEN_OPEN);
//Get error check code,(0x09: Firmware verification failed.0x7:boot verification failed)
aw_sar_i2c_read(p_sar->i2c, AW9320X_SRAM_ERROR_CODE, &err_code);
//The bit[31:24] must be 0, otherwise the boot cannot be jumped out actively
aw_sar_i2c_read(p_sar->i2c, REG_UPDATA_DIS, &jump_info);
//bit8 0:Boot from ROM, 1: Boot from RAM
aw_sar_i2c_read(p_sar->i2c, REG_MCFG, &boot_mode);
AWLOGE(p_sar->dev, "0x1c00:0x%x, 0x4744:0x%x, 0x4444:0x%x", err_code, jump_info, boot_mode);
aw_sar_i2c_write(p_sar->i2c, REG_ACCESSEN, REG_ACCESSEN_CLOSE);
return AW_OK;
}
static const struct aw_sar_mode_set_t g_aw9620x_mode_set[] = {
//0
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_ACTIVE_MODE,
.last_mode = AW9620X_DEEPSLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = aw9620x_enable_clock,
.rc_irqscr = NULL,
.mode_update = aw9620x_set_active_cmd,
},
},
//1
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_ACTIVE_MODE,
.last_mode = AW9620X_SLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9620x_set_active_cmd,
},
},
//1
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_ACTIVE_MODE,
.last_mode = AW9620X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9620x_set_active_cmd,
},
},
//2
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_SLEEP_MODE,
.last_mode = AW9620X_DEEPSLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = aw9620x_enable_clock,
.rc_irqscr = NULL,
.mode_update = aw9620x_set_sleep_cmd,
},
},
//3
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_SLEEP_MODE,
.last_mode = AW9620X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9620x_set_sleep_cmd,
},
},
//4
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_DEEPSLEEP_MODE,
.last_mode = AW9620X_SLEEP_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = NULL,
.mode_update = aw9620x_set_deepsleep_cmd,
},
},
//5
{
.chip_id = AW_SAR_NONE_CHECK_CHIP,
.chip_mode = {
.curr_mode = AW9620X_DEEPSLEEP_MODE,
.last_mode = AW9620X_ACTIVE_MODE,
},
.mode_switch_ops = {
.enable_clock = NULL,
.rc_irqscr = aw9620x_rc_irqscr,
.mode_update = aw9620x_set_deepsleep_cmd,
},
},
};
static const struct aw_sar_check_chipid_t g_aw9620x_check_chipid = {
.p_check_chipid_fn = aw9620x_check_chipid,
};
static const struct aw_sar_soft_rst_t g_aw9620x_soft_rst = {
.p_soft_reset_fn = aw9620x_soft_reset,
};
static const struct aw_sar_get_chip_info_t g_aw9620x_get_chip_info = {
.p_get_chip_info_node_fn = aw9620x_sar_chip_info_get,
};
#define AW9620X_MODE_SET_ARR_LEN (sizeof(g_aw9620x_mode_set) / sizeof(g_aw9620x_mode_set[0]))
static const struct aw_sar_irq_init_t g_aw9620x_irq_init = {
.flags = GPIOF_DIR_IN | GPIOF_INIT_HIGH,
.irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
.handler = NULL,
.thread_fn = NULL,
.rc_irq_fn = aw9620x_rc_irqscr,
.irq_spec_handler_fn = aw9620x_irq_handle_func,
};
static const struct aw_sar_init_over_irq_t g_aw9620x_init_over_irq = {
.wait_times = 100,
.daley_step = 1,
.reg_irqsrc = REG_IRQSRC,
.irq_offset_bit = 0,
.irq_mask = 0x1,
.irq_flag = 0x1,
.p_check_init_over_irq_fn = NULL,
.p_get_err_type_fn = aw9320x_get_err_info,
};
static const struct aw_sar_load_bin_t g_aw9620x_load_reg_bin = {
.bin_name = "aw9620x_reg",
.bin_opera_func = aw9620x_load_reg_bin,
.bin_load_fail_opera = NULL,
.p_update_fn = NULL,
};
static const struct aw_sar_load_bin_t g_aw9620x_load_boot_bin = {
.bin_name = "aw9620x_boot",
.bin_opera_func = aw9620x_reg_update_bt,
.bin_load_fail_opera = NULL,
};
static const struct aw_sar_load_bin_t g_aw9620x_load_fw_bin = {
.bin_name = "aw9620x_fw",
.bin_opera_func = aw9620x_prot_update_firmware,
.bin_load_fail_opera = aw9620x_reg_update_firmware,
};
//Node prox upgrade firmware
static const struct aw_sar_load_bin_t g_aw9620x_node_prox_load_fw_bin = {
.bin_name = "aw9620x_fw",
.bin_opera_func = aw9620x_prox_direct_upgrade_firmware,
.p_get_prot_update_fw_node_fn = aw9620x_get_firmware_version,
.bin_load_fail_opera = NULL,
};
//Node reg upgrade firmware
static const struct aw_sar_load_bin_t g_aw9620x_node_reg_load_fw_bin = {
.bin_name = "aw9620x_fw",
.bin_opera_func = aw9620x_reg_update_firmware,
.bin_load_fail_opera = NULL,
};
static const struct aw_sar_para_load_t g_aw9620x_reg_arr_para = {
.reg_arr = aw9620x_reg_default,
.reg_arr_len = sizeof(aw9620x_reg_default) / sizeof(aw9620x_reg_default[0]),
};
static const struct aw_sar_aot_t g_aw9620x_aot = {
.aot_reg = REG_SCANCTRL0,
.aot_mask = ~(0xff << 8),
.aot_flag = 0xff << 8,
};
static const struct aw_sar_diff_t g_aw9620x_diff = {
.diff0_reg = REG_DIFF_CH0,
.diff_step = AW9620X_REG_STEP,
.rm_float = AW9620X_REMOVE_FLOAT_COEF,
};
static const struct aw_sar_offset_t g_aw9620x_offset = {
.p_get_offset_node_fn = aw9620x_offset_get,
};
static const struct aw_sar_mode_t g_aw9620x_mode = {
.mode_set_arr = &g_aw9620x_mode_set[0],
.mode_set_arr_len = AW9620X_MODE_SET_ARR_LEN,
.p_get_mode_node_fn = aw9620x_mode_operation_get,
};
static const struct aw_sar_reg_list_t g_aw9620x_reg_list = {
.reg_none_access = REG_NONE_ACCESS,
.reg_rd_access = REG_RD_ACCESS,
.reg_wd_access = REG_WR_ACCESS,
.reg_perm = (struct aw_sar_reg_data *)&g_aw9620x_reg_access[0],
.reg_num = sizeof(g_aw9620x_reg_access) / sizeof(g_aw9620x_reg_access[0]),
};
static const struct aw_sar_pm_t g_aw9620x_pm_chip_mode = {
.suspend_set_mode = AW9620X_SLEEP_MODE,
.resume_set_mode = AW9620X_ACTIVE_MODE,
.shutdown_set_mode = AW9620X_SLEEP_MODE,
};
static const struct aw_sar_chip_mode_t g_aw9620x_chip_mode = {
.init_mode = AW9620X_ACTIVE_MODE,
.active = AW9620X_ACTIVE_MODE,
.pre_init_mode = AW9620X_SLEEP_MODE,
};
static const struct aw_sar_regulator_config_t g_aw9620x_regulator_config = {
.vcc_name = "vcc",
.min_uV = AW9620X_SAR_VCC_MIN_UV,
.max_uV = AW9620X_SAR_VCC_MAX_UV,
};
static const struct aw_sar_platform_config g_aw9620x_platform_config = {
.p_regulator_config = &g_aw9620x_regulator_config,
.p_irq_init = &g_aw9620x_irq_init,
.p_pm_chip_mode = &g_aw9620x_pm_chip_mode,
};
static const struct aw_sar_chip_config g_aw9620x_chip_config = {
.ch_num_max = AW9620X_CHANNEL_NUM_MAX,
.p_platform_config = &g_aw9620x_platform_config,
.p_check_chipid = &g_aw9620x_check_chipid,
.p_soft_rst = &g_aw9620x_soft_rst,
.p_init_over_irq = &g_aw9620x_init_over_irq,
.p_fw_bin = &g_aw9620x_load_fw_bin,
.p_reg_bin = &g_aw9620x_load_reg_bin,
.p_chip_mode = &g_aw9620x_chip_mode,
//Node usage parameters
.p_reg_list = &g_aw9620x_reg_list,
.p_reg_arr = &g_aw9620x_reg_arr_para,
.p_aot = &g_aw9620x_aot,
.p_diff = &g_aw9620x_diff,
.p_offset = &g_aw9620x_offset,
.p_mode = &g_aw9620x_mode,
.p_prox_fw = &g_aw9620x_node_prox_load_fw_bin,
.p_reg_fw = &g_aw9620x_node_reg_load_fw_bin,
.p_get_chip_info = &g_aw9620x_get_chip_info,
.p_aw_sar_awrw = NULL,
.p_boot_bin = &g_aw9620x_load_boot_bin,
};
int32_t aw9620x_init(struct aw_sar *p_sar)
{
if (p_sar == NULL) {
AWLOGE(p_sar->dev, "para is NULL, error!");
return -AW_ERR;
}
//Chip private function operation
p_sar->p_sar_para = &g_aw9620x_chip_config;
return AW_OK;
}
void aw9620x_deinit(struct aw_sar *p_sar)
{
if (p_sar->priv_data != NULL) {
devm_kfree(p_sar->dev, p_sar->priv_data);
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,786 @@
#include "aw_sar_comm_interface.h"
#define AW_I2C_RW_RETRY_TIME_MIN (2000)
#define AW_I2C_RW_RETRY_TIME_MAX (3000)
#define AW_RETRIES (5)
static int32_t awinic_i2c_write(struct i2c_client *i2c, uint8_t *tr_data, uint16_t len)
{
struct i2c_msg msg;
msg.addr = i2c->addr;
msg.flags = 0;
msg.len = len;
msg.buf = tr_data;
return i2c_transfer(i2c->adapter, &msg, 1);
}
static int32_t awinic_i2c_read(struct i2c_client *i2c, uint8_t *addr,
uint8_t addr_len, uint8_t *data, uint16_t data_len)
{
struct i2c_msg msg[2];
msg[0].addr = i2c->addr;
msg[0].flags = 0;
msg[0].len = addr_len;
msg[0].buf = addr;
msg[1].addr = i2c->addr;
msg[1].flags = 1;
msg[1].len = data_len;
msg[1].buf = data;
return i2c_transfer(i2c->adapter, msg, 2);
}
/**
* @brief Read register interface
*
* @param i2c: i2c client.
* @param reg_addr16: 16 bit register address.
* @param *reg_data32: 32 bit register data.
* @return AW_OK 0 if init successed. -AW_ERR -1 if error.
*/
int32_t aw_sar_i2c_read(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t *reg_data32)
{
int8_t cnt = 5;
int32_t ret = -1;
uint8_t r_buf[6] = { 0 };
if (i2c == NULL) {
AWLOGE(&i2c->dev, "i2c_dev is null error!");
return -AW_ERR;
}
r_buf[0] = (unsigned char)(reg_addr16 >> OFFSET_BIT_8);
r_buf[1] = (unsigned char)(reg_addr16);
do {
ret = awinic_i2c_read(i2c, r_buf, 2, &r_buf[2], 4);
if (ret < 0) {
AWLOGE(&i2c->dev, "i2c read error reg: 0x%04x, ret= %d cnt= %d", reg_addr16, ret, cnt);
} else {
break;
}
usleep_range(2000, 3000);
} while (cnt--);
if (cnt < 0) {
AWLOGE(&i2c->dev, "i2c read error!");
return -AW_ERR;
}
*reg_data32 = ((uint32_t)r_buf[5] << OFFSET_BIT_0) | ((uint32_t)r_buf[4] << OFFSET_BIT_8) |
((uint32_t)r_buf[3] << OFFSET_BIT_16) | ((uint32_t)r_buf[2] << OFFSET_BIT_24);
return AW_OK;
}
/**
* @brief write register interface
*
* @param i2c: i2c client.
* @param reg_addr16: 16 bit register address.
* @param reg_data32: 32 bit register data.
* @return AW_OK 0 if init successed. -AW_ERR -1 if error.
*/
int32_t aw_sar_i2c_write(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t reg_data32)
{
int8_t cnt = 5;
int32_t ret = -1;
uint8_t w_buf[6] = { 0 };
if (i2c == NULL) {
AWLOGE(&i2c->dev, "i2c_dev is null error!");
return -AW_ERR;
}
/*reg_addr*/
w_buf[0] = (uint8_t)(reg_addr16 >> OFFSET_BIT_8);
w_buf[1] = (uint8_t)(reg_addr16);
/*data*/
w_buf[2] = (uint8_t)(reg_data32 >> OFFSET_BIT_24);
w_buf[3] = (uint8_t)(reg_data32 >> OFFSET_BIT_16);
w_buf[4] = (uint8_t)(reg_data32 >> OFFSET_BIT_8);
w_buf[5] = (uint8_t)(reg_data32);
do {
ret = awinic_i2c_write(i2c, w_buf, ARRAY_SIZE(w_buf));
if (ret < 0) {
AWLOGE(&i2c->dev, "i2c write error reg: 0x%04x data: 0x%08x, ret= %d cnt= %d",
reg_addr16, reg_data32, ret, cnt);
} else {
break;
}
} while (cnt--);
if (cnt < 0) {
AWLOGE(&i2c->dev, "i2c write error!");
return -AW_ERR;
}
return AW_OK;
}
/**
* @brief Write the corresponding bit of the register
*
* @param i2c:i2c client.
* @param reg_addr16: 16 bit register address.
* @param mask: Write the corresponding bit as 0
* @param val: Write corresponding data to the register
* @return AW_OK 0 if init successed. -AW_ERR -1 if error.
*/
int32_t aw_sar_i2c_write_bits(struct i2c_client *i2c, uint16_t reg_addr16,
uint32_t mask, uint32_t val)
{
uint32_t reg_val;
aw_sar_i2c_read(i2c, reg_addr16, &reg_val);
reg_val &= mask;
reg_val |= (val & (~mask));
aw_sar_i2c_write(i2c, reg_addr16, reg_val);
return AW_OK;
}
/**
* @brief Continuously write data to the chip
*
* @param i2c:i2c client.
* @param *tr_data: Data written
* @param len: Length of data written
* @return AW_OK 0 if init successed. -AW_ERR -1 if error.
*/
int32_t aw_sar_i2c_write_seq(struct i2c_client *i2c, uint8_t *tr_data, uint16_t len)
{
int8_t cnt = AW_RETRIES;
int32_t ret = -AW_ERR;
do {
ret = awinic_i2c_write(i2c, tr_data, len);
if (ret < 0)
AWLOGE(&i2c->dev, "awinic i2c write seq error %d", ret);
else
break;
usleep_range(AW_I2C_RW_RETRY_TIME_MIN, AW_I2C_RW_RETRY_TIME_MAX);
} while (cnt--);
if (cnt < 0) {
AWLOGE(&i2c->dev, "awinic i2c write error!");
return -AW_ERR;
}
return AW_OK;
}
/**
* @brief Continuously Read data from chip
*
* @param i2c:i2c client.
* @param *addr: Read address
* @param addr_len: Length of read address (byte)
* @param *data: Data written
* @param data_len: Length of data written
* @return AW_OK 0 if init successed. -AW_ERR -1 if error.
*/
int32_t aw_sar_i2c_read_seq(struct i2c_client *i2c, uint8_t *addr,
uint8_t addr_len, uint8_t *data, uint16_t data_len)
{
int8_t cnt = AW_RETRIES;
int32_t ret = -AW_ERR;
do {
ret = awinic_i2c_read(i2c, addr, addr_len, data, data_len);
if (ret < 0) {
AWLOGE(&i2c->dev, "awinic sar i2c write error %d", ret);
} else {
break;
}
usleep_range(AW_I2C_RW_RETRY_TIME_MIN, AW_I2C_RW_RETRY_TIME_MAX);
} while (cnt--);
if (cnt < 0) {
AWLOGE(&i2c->dev, "awinic sar i2c read error!");
return -AW_ERR;
}
return AW_OK;
}
/*********************************Parse bin file code start**************************************************/
#define AWINIC_CODE_VERSION "V0.0.7-V1.0.4" /* "code version"-"excel version" */
enum bin_header_version_enum {
HEADER_VERSION_1_0_0 = 0x01000000,
};
enum data_type_enum {
DATA_TYPE_REGISTER = 0x00000000,
DATA_TYPE_DSP_REG = 0x00000010,
DATA_TYPE_DSP_CFG = 0x00000011,
DATA_TYPE_SOC_REG = 0x00000020,
DATA_TYPE_SOC_APP = 0x00000021,
DATA_TYPE_MULTI_BINS = 0x00002000,
};
enum data_version_enum {
DATA_VERSION_V1 = 0X00000001, /*default little edian */
DATA_VERSION_MAX,
};
#define DEBUG_LOG_LEVEL
#ifdef DEBUG_LOG_LEVEL
#define DBG(fmt, arg...) do {\
printk("AWINIC_BIN %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
} while (0)
#define DBG_ERR(fmt, arg...) do {\
printk("AWINIC_BIN_ERR %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
} while (0)
#else
#define DBG(fmt, arg...) do {} while (0)
#define DBG_ERR(fmt, arg...) do {} while (0)
#endif
#define printing_data_code
typedef unsigned short int aw_uint16;
typedef unsigned long int aw_uint32;
#define BigLittleSwap16(A) ((((aw_uint16)(A) & 0xff00) >> 8) | \
(((aw_uint16)(A) & 0x00ff) << 8))
#define BigLittleSwap32(A) ((((aw_uint32)(A) & 0xff000000) >> 24) | \
(((aw_uint32)(A) & 0x00ff0000) >> 8) | \
(((aw_uint32)(A) & 0x0000ff00) << 8) | \
(((aw_uint32)(A) & 0x000000ff) << 24))
static int aw_parse_bin_header_1_0_0(struct aw_bin *bin);
/**
*
* Interface function
*
* return value:
* value = 0 :success;
* value = -1 :check bin header version
* value = -2 :check bin data type
* value = -3 :check sum or check bin data len error
* value = -4 :check data version
* value = -5 :check register num
* value = -6 :check dsp reg num
* value = -7 :check soc app num
* value = -8 :bin is NULL point
*
**/
/********************************************************
*
* check sum data
*
********************************************************/
static int aw_check_sum(struct aw_bin *bin, int bin_num)
{
unsigned int i = 0;
unsigned int sum_data = 0;
unsigned int check_sum = 0;
char *p_check_sum = NULL;
DBG("enter\n");
p_check_sum =
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr -
bin->header_info[bin_num].header_len)]);
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
check_sum = AW_SAR_GET_32_DATA(*(p_check_sum + 3),
*(p_check_sum + 2),
*(p_check_sum + 1), *(p_check_sum));
for (i = 4;
i <
bin->header_info[bin_num].bin_data_len +
bin->header_info[bin_num].header_len; i++) {
sum_data += *(p_check_sum + i);
}
DBG("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n",
bin_num, check_sum, sum_data);
if (sum_data != check_sum) {
p_check_sum = NULL;
DBG_ERR("aw_bin_parse check sum or check bin data len error\n");
DBG_ERR("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n", bin_num, check_sum, sum_data);
return -3;
}
p_check_sum = NULL;
return 0;
}
static int aw_check_data_version(struct aw_bin *bin, int bin_num)
{
int i = 0;
DBG("enter\n");
for (i = DATA_VERSION_V1; i < DATA_VERSION_MAX; i++) {
if (bin->header_info[bin_num].bin_data_ver == i) {
return 0;
}
}
DBG_ERR("aw_bin_parse Unrecognized this bin data version\n");
return -4;
}
static int aw_check_register_num_v1(struct aw_bin *bin, int bin_num)
{
unsigned int check_register_num = 0;
unsigned int parse_register_num = 0;
char *p_check_sum = NULL;
DBG("enter\n");
p_check_sum =
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
parse_register_num = AW_SAR_GET_32_DATA(*(p_check_sum + 3),
*(p_check_sum + 2),
*(p_check_sum + 1), *(p_check_sum));
check_register_num = (bin->header_info[bin_num].bin_data_len - 4) /
(bin->header_info[bin_num].reg_byte_len +
bin->header_info[bin_num].data_byte_len);
DBG
("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n",
bin_num, parse_register_num, check_register_num);
if (parse_register_num != check_register_num) {
p_check_sum = NULL;
DBG_ERR("aw_bin_parse register num is error\n");
DBG_ERR("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n", bin_num, parse_register_num, check_register_num);
return -5;
}
bin->header_info[bin_num].reg_num = parse_register_num;
bin->header_info[bin_num].valid_data_len =
bin->header_info[bin_num].bin_data_len - 4;
p_check_sum = NULL;
bin->header_info[bin_num].valid_data_addr =
bin->header_info[bin_num].valid_data_addr + 4;
return 0;
}
static int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num)
{
unsigned int check_dsp_reg_num = 0;
unsigned int parse_dsp_reg_num = 0;
char *p_check_sum = NULL;
DBG("enter\n");
p_check_sum =
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
parse_dsp_reg_num = AW_SAR_GET_32_DATA(*(p_check_sum + 7),
*(p_check_sum + 6),
*(p_check_sum + 5),
*(p_check_sum + 4));
bin->header_info[bin_num].reg_data_byte_len =
AW_SAR_GET_32_DATA(*(p_check_sum + 11), *(p_check_sum + 10),
*(p_check_sum + 9), *(p_check_sum + 8));
check_dsp_reg_num =
(bin->header_info[bin_num].bin_data_len -
12) / bin->header_info[bin_num].reg_data_byte_len;
DBG
("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n",
bin_num, parse_dsp_reg_num, check_dsp_reg_num);
if (parse_dsp_reg_num != check_dsp_reg_num) {
p_check_sum = NULL;
DBG_ERR("aw_bin_parse dsp reg num is error\n");
DBG_ERR("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n", bin_num, parse_dsp_reg_num, check_dsp_reg_num);
return -6;
}
bin->header_info[bin_num].download_addr =
AW_SAR_GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
*(p_check_sum + 1), *(p_check_sum));
bin->header_info[bin_num].reg_num = parse_dsp_reg_num;
bin->header_info[bin_num].valid_data_len =
bin->header_info[bin_num].bin_data_len - 12;
p_check_sum = NULL;
bin->header_info[bin_num].valid_data_addr =
bin->header_info[bin_num].valid_data_addr + 12;
return 0;
}
static int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num)
{
unsigned int check_soc_app_num = 0;
unsigned int parse_soc_app_num = 0;
char *p_check_sum = NULL;
DBG("enter\n");
p_check_sum =
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
bin->header_info[bin_num].app_version = AW_SAR_GET_32_DATA(*(p_check_sum + 3),
*(p_check_sum + 2),
*(p_check_sum + 1),
*(p_check_sum));
parse_soc_app_num = AW_SAR_GET_32_DATA(*(p_check_sum + 11),
*(p_check_sum + 10),
*(p_check_sum + 9), *(p_check_sum + 8));
check_soc_app_num = bin->header_info[bin_num].bin_data_len - 12;
DBG
("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n",
bin_num, parse_soc_app_num, check_soc_app_num);
if (parse_soc_app_num != check_soc_app_num) {
p_check_sum = NULL;
DBG_ERR("aw_bin_parse soc app num is error\n");
DBG_ERR("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n", bin_num, parse_soc_app_num, check_soc_app_num);
return -7;
}
bin->header_info[bin_num].reg_num = parse_soc_app_num;
bin->header_info[bin_num].download_addr =
AW_SAR_GET_32_DATA(*(p_check_sum + 7), *(p_check_sum + 6),
*(p_check_sum + 5), *(p_check_sum + 4));
bin->header_info[bin_num].valid_data_len =
bin->header_info[bin_num].bin_data_len - 12;
p_check_sum = NULL;
bin->header_info[bin_num].valid_data_addr =
bin->header_info[bin_num].valid_data_addr + 12;
return 0;
}
/************************
***
***bin header 1_0_0
***
************************/
static void aw_get_single_bin_header_1_0_0(struct aw_bin *bin)
{
int i;
DBG("enter %s\n", __func__);
bin->header_info[bin->all_bin_parse_num].header_len = 60;
bin->header_info[bin->all_bin_parse_num].check_sum =
AW_SAR_GET_32_DATA(*(bin->p_addr + 3), *(bin->p_addr + 2),
*(bin->p_addr + 1), *(bin->p_addr));
bin->header_info[bin->all_bin_parse_num].header_ver =
AW_SAR_GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
*(bin->p_addr + 5), *(bin->p_addr + 4));
bin->header_info[bin->all_bin_parse_num].bin_data_type =
AW_SAR_GET_32_DATA(*(bin->p_addr + 11), *(bin->p_addr + 10),
*(bin->p_addr + 9), *(bin->p_addr + 8));
bin->header_info[bin->all_bin_parse_num].bin_data_ver =
AW_SAR_GET_32_DATA(*(bin->p_addr + 15), *(bin->p_addr + 14),
*(bin->p_addr + 13), *(bin->p_addr + 12));
bin->header_info[bin->all_bin_parse_num].bin_data_len =
AW_SAR_GET_32_DATA(*(bin->p_addr + 19), *(bin->p_addr + 18),
*(bin->p_addr + 17), *(bin->p_addr + 16));
bin->header_info[bin->all_bin_parse_num].ui_ver =
AW_SAR_GET_32_DATA(*(bin->p_addr + 23), *(bin->p_addr + 22),
*(bin->p_addr + 21), *(bin->p_addr + 20));
bin->header_info[bin->all_bin_parse_num].reg_byte_len =
AW_SAR_GET_32_DATA(*(bin->p_addr + 35), *(bin->p_addr + 34),
*(bin->p_addr + 33), *(bin->p_addr + 32));
bin->header_info[bin->all_bin_parse_num].data_byte_len =
AW_SAR_GET_32_DATA(*(bin->p_addr + 39), *(bin->p_addr + 38),
*(bin->p_addr + 37), *(bin->p_addr + 36));
bin->header_info[bin->all_bin_parse_num].device_addr =
AW_SAR_GET_32_DATA(*(bin->p_addr + 43), *(bin->p_addr + 42),
*(bin->p_addr + 41), *(bin->p_addr + 40));
for (i = 0; i < 8; i++) {
bin->header_info[bin->all_bin_parse_num].chip_type[i] =
*(bin->p_addr + 24 + i);
}
// bin->header_info[bin->all_bin_parse_num].chip_type[i] = '\0';
// DBG("%s : enter chip_type is %s\n", __func__,
// bin->header_info[bin->all_bin_parse_num].chip_type);
bin->header_info[bin->all_bin_parse_num].reg_num = 0x00000000;
bin->header_info[bin->all_bin_parse_num].reg_data_byte_len = 0x00000000;
bin->header_info[bin->all_bin_parse_num].download_addr = 0x00000000;
bin->header_info[bin->all_bin_parse_num].app_version = 0x00000000;
bin->header_info[bin->all_bin_parse_num].valid_data_len = 0x00000000;
bin->all_bin_parse_num += 1;
}
static int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num,
struct aw_bin *bin)
{
int ret = 0;
unsigned int bin_start_addr = 0;
unsigned int valid_data_len = 0;
DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
if (!bin_serial_num) {
bin_start_addr = AW_SAR_GET_32_DATA(*(bin->p_addr + 67),
*(bin->p_addr + 66),
*(bin->p_addr + 65),
*(bin->p_addr + 64));
bin->p_addr += (60 + bin_start_addr);
bin->header_info[bin->all_bin_parse_num].valid_data_addr =
bin->header_info[bin->all_bin_parse_num -
1].valid_data_addr + 4 + 8 * bin_num + 60;
} else {
valid_data_len =
bin->header_info[bin->all_bin_parse_num - 1].bin_data_len;
bin->p_addr += (60 + valid_data_len);
bin->header_info[bin->all_bin_parse_num].valid_data_addr =
bin->header_info[bin->all_bin_parse_num -
1].valid_data_addr +
bin->header_info[bin->all_bin_parse_num - 1].bin_data_len +
60;
}
ret = aw_parse_bin_header_1_0_0(bin);
return ret;
}
/* Get the number of bins in multi bins, and set a for loop, loop processing each bin data */
static int aw_get_multi_bin_header_1_0_0(struct aw_bin *bin)
{
int i = 0;
int ret = 0;
unsigned int bin_num = 0;
DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
bin_num = AW_SAR_GET_32_DATA(*(bin->p_addr + 63),
*(bin->p_addr + 62),
*(bin->p_addr + 61), *(bin->p_addr + 60));
if (bin->multi_bin_parse_num == 1) {
bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
}
aw_get_single_bin_header_1_0_0(bin);
for (i = 0; i < bin_num; i++) {
DBG("aw_bin_parse enter multi bin for is %d\n", i);
ret = aw_parse_each_of_multi_bins_1_0_0(bin_num, i, bin);
if (ret < 0) {
return ret;
}
}
return 0;
}
/********************************************************
*
* If the bin framework header version is 1.0.0,
determine the data type of bin, and then perform different processing
according to the data type
If it is a single bin data type, write the data directly into the structure array
If it is a multi-bin data type, first obtain the number of bins,
and then recursively call the bin frame header processing function
according to the bin number to process the frame header information of each bin separately
*
********************************************************/
static int aw_parse_bin_header_1_0_0(struct aw_bin *bin)
{
int ret = 0;
unsigned int bin_data_type;
DBG("enter %s\n", __func__);
bin_data_type = AW_SAR_GET_32_DATA(*(bin->p_addr + 11),
*(bin->p_addr + 10),
*(bin->p_addr + 9), *(bin->p_addr + 8));
DBG("aw_bin_parse bin_data_type 0x%x\n", bin_data_type);
switch (bin_data_type) {
case DATA_TYPE_REGISTER:
case DATA_TYPE_DSP_REG:
case DATA_TYPE_SOC_APP:
/* Divided into two processing methods,
one is single bin processing,
and the other is single bin processing in multi bin */
DBG("aw_bin_parse enter single bin branch\n");
bin->single_bin_parse_num += 1;
DBG("%s bin->single_bin_parse_num is %d\n", __func__,
bin->single_bin_parse_num);
if (!bin->multi_bin_parse_num) {
bin->header_info[bin->
all_bin_parse_num].valid_data_addr =
60;
}
aw_get_single_bin_header_1_0_0(bin);
break;
case DATA_TYPE_MULTI_BINS:
/* Get the number of times to enter multi bins */
DBG("aw_bin_parse enter multi bin branch\n");
bin->multi_bin_parse_num += 1;
DBG("%s bin->multi_bin_parse_num is %d\n", __func__,
bin->multi_bin_parse_num);
ret = aw_get_multi_bin_header_1_0_0(bin);
if (ret < 0) {
return ret;
}
break;
default:
DBG_ERR("aw_bin_parse Unrecognized this bin data type\n");
return -2;
}
return 0;
}
/* get the bin's header version */
static int aw_check_bin_header_version(struct aw_bin *bin)
{
int ret = 0;
unsigned int header_version = 0;
header_version = AW_SAR_GET_32_DATA(*(bin->p_addr + 7),
*(bin->p_addr + 6),
*(bin->p_addr + 5), *(bin->p_addr + 4));
DBG("aw_bin_parse header_version 0x%x\n", header_version);
/* Write data to the corresponding structure array
according to different formats of the bin frame header version */
switch (header_version) {
case HEADER_VERSION_1_0_0:
ret = aw_parse_bin_header_1_0_0(bin);
return ret;
default:
DBG_ERR("aw_bin_parse Unrecognized this bin header version \n");
return -1;
}
}
/**
* @brief Parse bin file
*
* @param bin: Store the contents of the parsed bin file
* @return 0 if init successed, other if error
*/
int aw_sar_parsing_bin_file(struct aw_bin *bin)
{
int i = 0;
int ret = 0;
DBG("aw_bin_parse code version:%s\n", AWINIC_CODE_VERSION);
if (!bin) {
DBG_ERR("aw_bin_parse bin is NULL\n");
return -8;
}
bin->p_addr = bin->info.data;
bin->all_bin_parse_num = 0;
bin->multi_bin_parse_num = 0;
bin->single_bin_parse_num = 0;
/* filling bins header info */
ret = aw_check_bin_header_version(bin);
if (ret < 0) {
DBG_ERR("aw_bin_parse check bin header version error\n");
return ret;
}
bin->p_addr = NULL;
/* check bin header info */
for (i = 0; i < bin->all_bin_parse_num; i++) {
/* check sum */
ret = aw_check_sum(bin, i);
if (ret < 0) {
DBG_ERR("aw_bin_parse check sum data error\n");
return ret;
}
/* check bin data version */
ret = aw_check_data_version(bin, i);
if (ret < 0) {
DBG_ERR("aw_bin_parse check data version error\n");
return ret;
}
/* check valid data */
if (bin->header_info[i].bin_data_ver == DATA_VERSION_V1) {
/* check register num */
if (bin->header_info[i].bin_data_type ==
DATA_TYPE_REGISTER) {
ret = aw_check_register_num_v1(bin, i);
if (ret < 0) {
DBG_ERR
("aw_bin_parse check register num error\n");
return ret;
}
/* check dsp reg num */
} else if (bin->header_info[i].bin_data_type ==
DATA_TYPE_DSP_REG) {
ret = aw_check_dsp_reg_num_v1(bin, i);
if (ret < 0) {
DBG_ERR
("aw_bin_parse check dsp reg num error\n");
return ret;
}
/* check soc app num */
} else if (bin->header_info[i].bin_data_type ==
DATA_TYPE_SOC_APP) {
ret = aw_check_soc_app_num_v1(bin, i);
if (ret < 0) {
DBG_ERR
("aw_bin_parse check soc app num error\n");
return ret;
}
} else {
bin->header_info[i].valid_data_len =
bin->header_info[i].bin_data_len;
}
}
}
DBG("aw_bin_parse parsing success\n");
return 0;
}
/*********************************Parse bin file code end**************************************************/
/**
* @brief Calculate the second power
*
* @param cnt: ifrequency
* @return the second power
*/
uint32_t aw_sar_pow2(uint32_t cnt)
{
uint32_t i = 0;
uint32_t sum = 1;
if (cnt == 0) {
sum = 1;
} else {
for (i = 0; i < cnt; i++) {
sum *= 2;
}
}
return sum;
}
/**
* @brief Calculate the second power
*
* @param *aw_bin: Information after parsing bin file
* @param *i2c: i2c client.
* @return AW_OK 0 if init successed. -AW_ERR -1 if error
*/
int32_t aw_sar_load_reg(struct aw_bin *aw_bin, struct i2c_client *i2c)
{
uint32_t i = 0;
int32_t ret = 0;
uint16_t reg_addr = 0;
uint32_t reg_data = 0;
uint32_t start_addr = aw_bin->header_info[0].valid_data_addr;
for (i = 0; i < aw_bin->header_info[0].valid_data_len;
i += 6, start_addr += 6) {
reg_addr = (aw_bin->info.data[start_addr]) |
aw_bin->info.data[start_addr + 1] << OFFSET_BIT_8;
reg_data = aw_bin->info.data[start_addr + 2] |
(aw_bin->info.data[start_addr + 3] << OFFSET_BIT_8) |
(aw_bin->info.data[start_addr + 4] << OFFSET_BIT_16) |
(aw_bin->info.data[start_addr + 5] << OFFSET_BIT_24);
ret = aw_sar_i2c_write(i2c, reg_addr, reg_data);
if (ret < 0) {
AWLOGE(&i2c->dev, "i2c write err");
return -AW_ERR;
}
AWLOGD(&i2c->dev, "reg_addr = 0x%04x, reg_data = 0x%08x", reg_addr, reg_data);
}
return AW_OK;
}
void aw_sar_delay_ms(uint32_t ms)
{
mdelay(ms);
}

View file

@ -0,0 +1,582 @@
#ifndef _AW9610X_H_
#define _AW9610X_H_
#include "aw_sar_type.h"
//#define AW9610X_TVS_ABNORMAL_CAIL
#define AW9610X_AOT_SCAN_OVER_CNT (32)
#define AW9610X_CHIP_ID (0xa961)
#define AW9610x_DATA_PROCESS_FACTOR (1024)
#define AW_CHIP_AW9610XA (0x03000b00)
#define AW9610X_CPU_WORK_MASK (1)
#define AW9610X_SAR_VCC_MIN_UV (1700000)
#define AW9610X_SAR_VCC_MAX_UV (3600000)
#define AW_REG_IRQEN_CLOSE (0)
#define AW_REG_IRQSRC_AOT_OVER_BIT (3)
#define REG_IRQSRC_SCAN_OVER_BIT (4)
#define REG_REG_WST_SLEEP_MODE (0x3)
#define AW9610X_AOT_OVER_DELAY_MAX_MS (6000)
#define AW9610X_AOT_MASK (0x3f)
#define AW9610X_AOT_BIT (8)
#define AW9610X_REG_OFFSET_STEP (4)
enum aw9610x_sar_vers {
AW9610X = 2,
AW9610XA = 6,
AW9610XB = 0xa,
};
enum aw9610x_operation_mode {
AW9610X_ACTIVE_MODE = 1,
AW9610X_SLEEP_MODE,
AW9610X_DEEPSLEEP_MODE,
AW9610XB_DEEPSLEEP_MODE,
};
/**********************************************
*spereg addr offset
**********************************************/
enum aw9610x_spereg_addr_offset {
AW_CL1SPE_CALI_OS = 20,
AW_CL1SPE_DEAL_OS = 60,
AW_CL2SPE_CALI_OS = 4,
AW_CL2SPE_DEAL_OS = 4,
};
/**********************************************
*the flag of i2c read/write
**********************************************/
enum aw9610x_function_flag {
AW9610X_FUNC_OFF,
AW9610X_FUNC_ON,
};
/**********************************************
* mutiple sar define
**********************************************/
enum aw9610x_multiple_sar {
AW_SAR0,
AW_SAR1,
AW_SAR_MAX,
};
#define AW9610X_CHANNEL_MAX (6)
enum aw9610x_irq_trigger_position {
AW9610X_FAR,
AW9610X_TRIGGER_TH0,
AW9610X_TRIGGER_TH1 = 0x03,
AW9610X_TRIGGER_TH2 = 0x07,
AW9610X_TRIGGER_TH3 = 0x0f,
};
struct aw_i2c_package {
uint8_t addr_bytes;
uint8_t data_bytes;
uint8_t reg_num;
uint8_t init_addr[4];
uint8_t *p_reg_data;
};
struct aw9610x {
uint8_t vers;
uint8_t channel;
uint32_t irq_status;
uint8_t chip_name[9];
uint8_t chip_type[9];
bool satu_release;
struct aw_i2c_package aw_i2c_package;
uint8_t satu_flag[6];
uint32_t satu_data[6];
};
/********************************************
* Register List
********************************************/
#define AFE_BASE_ADDR (0x0000)
#define DSP_BASE_ADDR (0x0000)
#define STAT_BASE_ADDR (0x0000)
#define SFR_BASE_ADDR (0x0000)
#define DATA_BASE_ADDR (0x0000)
/* registers list */
//AW96105A_UI_REGISTER_AFE MAP
#define REG_SCANCTRL0 ((0x0000) + AFE_BASE_ADDR)
#define REG_SCANCTRL1 ((0x0004) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH0 ((0x0010) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH0 ((0x0014) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH0 ((0x001C) + AFE_BASE_ADDR)
#define REG_AFECFG4_CH0 ((0x0020) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH1 ((0x0024) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH1 ((0x0028) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH1 ((0x0030) + AFE_BASE_ADDR)
#define REG_AFECFG4_CH1 ((0x0034) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH2 ((0x0038) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH2 ((0x003C) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH2 ((0x0044) + AFE_BASE_ADDR)
#define REG_AFECFG4_CH2 ((0x0048) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH3 ((0x004C) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH3 ((0x0050) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH3 ((0x0058) + AFE_BASE_ADDR)
#define REG_AFECFG4_CH3 ((0x005C) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH4 ((0x0060) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH4 ((0x0064) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH4 ((0x006C) + AFE_BASE_ADDR)
#define REG_AFECFG4_CH4 ((0x0070) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH5 ((0x0074) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH5 ((0x0078) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH5 ((0x0080) + AFE_BASE_ADDR)
#define REG_AFECFG4_CH5 ((0x0084) + AFE_BASE_ADDR)
/* registers list */
//AW96105A_UI_REGISTER_DSP MAP
#define REG_DSPCFG0_CH0 ((0x00A0) + DSP_BASE_ADDR)
#define REG_DSPCFG1_CH0 ((0x00A4) + DSP_BASE_ADDR)
#define REG_BLFILT_CH0 ((0x00A8) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH0 ((0x00B0) + DSP_BASE_ADDR)
#define REG_BLRSTRNG_CH0 ((0x00B4) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH0 ((0x00B8) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH0 ((0x00BC) + DSP_BASE_ADDR)
#define REG_PROXTH2_CH0 ((0x00C0) + DSP_BASE_ADDR)
#define REG_PROXTH3_CH0 ((0x00C4) + DSP_BASE_ADDR)
#define REG_STDDET_CH0 ((0x00C8) + DSP_BASE_ADDR)
#define REG_INITPROX0_CH0 ((0x00CC) + DSP_BASE_ADDR)
#define REG_INITPROX1_CH0 ((0x00D0) + DSP_BASE_ADDR)
#define REG_DATAOFFSET_CH0 ((0x00D4) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH0 ((0x00D8) + DSP_BASE_ADDR)
#define REG_DSPCFG0_CH1 ((0x00DC) + DSP_BASE_ADDR)
#define REG_DSPCFG1_CH1 ((0x00E0) + DSP_BASE_ADDR)
#define REG_BLFILT_CH1 ((0x00E4) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH1 ((0x00EC) + DSP_BASE_ADDR)
#define REG_BLRSTRNG_CH1 ((0x00F0) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH1 ((0x00F4) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH1 ((0x00F8) + DSP_BASE_ADDR)
#define REG_PROXTH2_CH1 ((0x00FC) + DSP_BASE_ADDR)
#define REG_PROXTH3_CH1 ((0x0100) + DSP_BASE_ADDR)
#define REG_STDDET_CH1 ((0x0104) + DSP_BASE_ADDR)
#define REG_INITPROX0_CH1 ((0x0108) + DSP_BASE_ADDR)
#define REG_INITPROX1_CH1 ((0x010C) + DSP_BASE_ADDR)
#define REG_RAWOFFSET_CH1 ((0x0110) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH1 ((0x0114) + DSP_BASE_ADDR)
#define REG_DSPCFG0_CH2 ((0x0118) + DSP_BASE_ADDR)
#define REG_DSPCFG1_CH2 ((0x011C) + DSP_BASE_ADDR)
#define REG_BLFILT_CH2 ((0x0120) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH2 ((0x0128) + DSP_BASE_ADDR)
#define REG_BLRSTRNG_CH2 ((0x012C) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH2 ((0x0130) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH2 ((0x0134) + DSP_BASE_ADDR)
#define REG_PROXTH2_CH2 ((0x0138) + DSP_BASE_ADDR)
#define REG_PROXTH3_CH2 ((0x013C) + DSP_BASE_ADDR)
#define REG_STDDET_CH2 ((0x0140) + DSP_BASE_ADDR)
#define REG_INITPROX0_CH2 ((0x0144) + DSP_BASE_ADDR)
#define REG_INITPROX1_CH2 ((0x0148) + DSP_BASE_ADDR)
#define REG_DATAOFFSET_CH2 ((0x014C) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH2 ((0x0150) + DSP_BASE_ADDR)
#define REG_DSPCFG0_CH3 ((0x0154) + DSP_BASE_ADDR)
#define REG_DSPCFG1_CH3 ((0x0158) + DSP_BASE_ADDR)
#define REG_BLFILT_CH3 ((0x015C) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH3 ((0x0164) + DSP_BASE_ADDR)
#define REG_BLRSTRNG_CH3 ((0x0168) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH3 ((0x016C) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH3 ((0x0170) + DSP_BASE_ADDR)
#define REG_PROXTH2_CH3 ((0x0174) + DSP_BASE_ADDR)
#define REG_PROXTH3_CH3 ((0x0178) + DSP_BASE_ADDR)
#define REG_STDDET_CH3 ((0x017C) + DSP_BASE_ADDR)
#define REG_INITPROX0_CH3 ((0x0180) + DSP_BASE_ADDR)
#define REG_INITPROX1_CH3 ((0x0184) + DSP_BASE_ADDR)
#define REG_DATAOFFSET_CH3 ((0x0188) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH3 ((0x018C) + DSP_BASE_ADDR)
#define REG_DSPCFG0_CH4 ((0x0190) + DSP_BASE_ADDR)
#define REG_DSPCFG1_CH4 ((0x0194) + DSP_BASE_ADDR)
#define REG_BLFILT_CH4 ((0x0198) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH4 ((0x01A0) + DSP_BASE_ADDR)
#define REG_BLRSTRNG_CH4 ((0x01A4) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH4 ((0x01A8) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH4 ((0x01AC) + DSP_BASE_ADDR)
#define REG_PROXTH2_CH4 ((0x01B0) + DSP_BASE_ADDR)
#define REG_PROXTH3_CH4 ((0x01B4) + DSP_BASE_ADDR)
#define REG_STDDET_CH4 ((0x01B8) + DSP_BASE_ADDR)
#define REG_INITPROX0_CH4 ((0x01BC) + DSP_BASE_ADDR)
#define REG_INITPROX1_CH4 ((0x01C0) + DSP_BASE_ADDR)
#define REG_DATAOFFSET_CH4 ((0x01C4) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH4 ((0x01C8) + DSP_BASE_ADDR)
#define REG_DSPCFG0_CH5 ((0x01CC) + DSP_BASE_ADDR)
#define REG_DSPCFG1_CH5 ((0x01D0) + DSP_BASE_ADDR)
#define REG_BLFILT_CH5 ((0x01D4) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH5 ((0x01DC) + DSP_BASE_ADDR)
#define REG_BLRSTRNG_CH5 ((0x01E0) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH5 ((0x01E4) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH5 ((0x01E8) + DSP_BASE_ADDR)
#define REG_PROXTH2_CH5 ((0x01EC) + DSP_BASE_ADDR)
#define REG_PROXTH3_CH5 ((0x01F0) + DSP_BASE_ADDR)
#define REG_STDDET_CH5 ((0x01F4) + DSP_BASE_ADDR)
#define REG_INITPROX0_CH5 ((0x01F8) + DSP_BASE_ADDR)
#define REG_INITPROX1_CH5 ((0x01FC) + DSP_BASE_ADDR)
#define REG_DATAOFFSET_CH5 ((0x0200) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH5 ((0x0204) + DSP_BASE_ADDR)
#define REG_ATCCR0 ((0x0208) + DSP_BASE_ADDR)
#define REG_ATCCR1 ((0x020C) + DSP_BASE_ADDR)
/* registers list */
//AW96105A_UI_REGISTER_STAT MAP
#define REG_FWVER ((0x0088) + STAT_BASE_ADDR)
#define REG_WST ((0x008C) + STAT_BASE_ADDR)
#define REG_STAT0 ((0x0090) + STAT_BASE_ADDR)
#define REG_STAT1 ((0x0094) + STAT_BASE_ADDR)
#define REG_STAT2 ((0x0098) + STAT_BASE_ADDR)
#define REG_CHINTEN ((0x009C) + STAT_BASE_ADDR)
/* registers list */
//AW96105A_UI_REGISTER_SFR MAP
#define REG_CMD ((0xF008) + SFR_BASE_ADDR)
#define REG_IRQSRC ((0xF080) + SFR_BASE_ADDR)
#define REG_IRQEN ((0xF084) + SFR_BASE_ADDR)
#define REG_I2CADDR ((0xF0F0) + SFR_BASE_ADDR)
#define REG_OSCEN ((0xFF00) + SFR_BASE_ADDR)
#define REG_RESET ((0xFF0C) + SFR_BASE_ADDR)
#define REG_CHIPID ((0xFF10) + SFR_BASE_ADDR)
/* registers list */
//AW96105A_UI_REGISTER_DATA MAP
#define REG_COMP_CH0 ((0x0210) + DATA_BASE_ADDR)
#define REG_COMP_CH1 ((0x0214) + DATA_BASE_ADDR)
#define REG_COMP_CH2 ((0x0218) + DATA_BASE_ADDR)
#define REG_COMP_CH3 ((0x021C) + DATA_BASE_ADDR)
#define REG_COMP_CH4 ((0x0220) + DATA_BASE_ADDR)
#define REG_COMP_CH5 ((0x0224) + DATA_BASE_ADDR)
#define REG_BASELINE_CH0 ((0x0228) + DATA_BASE_ADDR)
#define REG_BASELINE_CH1 ((0x022C) + DATA_BASE_ADDR)
#define REG_BASELINE_CH2 ((0x0230) + DATA_BASE_ADDR)
#define REG_BASELINE_CH3 ((0x0234) + DATA_BASE_ADDR)
#define REG_BASELINE_CH4 ((0x0238) + DATA_BASE_ADDR)
#define REG_BASELINE_CH5 ((0x023C) + DATA_BASE_ADDR)
#define REG_DIFF_CH0 ((0x0240) + DATA_BASE_ADDR)
#define REG_DIFF_CH1 ((0x0244) + DATA_BASE_ADDR)
#define REG_DIFF_CH2 ((0x0248) + DATA_BASE_ADDR)
#define REG_DIFF_CH3 ((0x024C) + DATA_BASE_ADDR)
#define REG_DIFF_CH4 ((0x0250) + DATA_BASE_ADDR)
#define REG_DIFF_CH5 ((0x0254) + DATA_BASE_ADDR)
#define REG_FWVER2 ((0x0410) + DATA_BASE_ADDR)
struct aw_reg_data {
unsigned char rw;
unsigned short reg;
};
/********************************************
* Register Access
*******************************************/
#define REG_NONE_ACCESS (0)
#define REG_RD_ACCESS (1 << 0)
#define REG_WR_ACCESS (1 << 1)
static const struct aw_reg_data g_aw9610x_reg_access[] = {
//AFE MAP
{ .reg = REG_SCANCTRL0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_SCANCTRL1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG4_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG4_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG4_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG4_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG4_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG4_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
//DSP MAP
{ .reg = REG_DSPCFG0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG1_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLRSTRNG_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH2_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH3_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_STDDET_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX1_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DATAOFFSET_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG1_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLRSTRNG_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH2_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH3_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_STDDET_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX1_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_RAWOFFSET_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG1_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLRSTRNG_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH2_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH3_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_STDDET_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX1_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DATAOFFSET_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG1_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLRSTRNG_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH2_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH3_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_STDDET_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX1_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DATAOFFSET_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG1_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLRSTRNG_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH2_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH3_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_STDDET_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX1_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DATAOFFSET_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DSPCFG1_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLRSTRNG_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH2_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH3_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_STDDET_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_INITPROX1_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_DATAOFFSET_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_ATCCR0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_ATCCR1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
//STAT MAP
{ .reg = REG_FWVER, .rw = REG_RD_ACCESS, },
{ .reg = REG_WST, .rw = REG_RD_ACCESS, },
{ .reg = REG_STAT0, .rw = REG_RD_ACCESS, },
{ .reg = REG_STAT1, .rw = REG_RD_ACCESS, },
{ .reg = REG_STAT2, .rw = REG_RD_ACCESS, },
{ .reg = REG_CHINTEN, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
//SFR MAP
{ .reg = REG_CMD, .rw = REG_NONE_ACCESS, },
{ .reg = REG_IRQSRC, .rw = REG_RD_ACCESS, },
{ .reg = REG_IRQEN, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_I2CADDR, .rw = REG_RD_ACCESS, },
{ .reg = REG_OSCEN, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_RESET, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_CHIPID, .rw = REG_RD_ACCESS, },
//DATA MAP
{ .reg = REG_COMP_CH0, .rw = REG_RD_ACCESS, },
{ .reg = REG_COMP_CH1, .rw = REG_RD_ACCESS, },
{ .reg = REG_COMP_CH2, .rw = REG_RD_ACCESS, },
{ .reg = REG_COMP_CH3, .rw = REG_RD_ACCESS, },
{ .reg = REG_COMP_CH4, .rw = REG_RD_ACCESS, },
{ .reg = REG_COMP_CH5, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH0, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH1, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH2, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH3, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH4, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH5, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH0, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH1, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH2, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH3, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH4, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH5, .rw = REG_RD_ACCESS, },
{ .reg = REG_FWVER2, .rw = REG_RD_ACCESS, },
};
/******************************************************
* Register Detail
******************************************************/
const static uint32_t aw9610x_reg_default[] = {
0x0000, 0x00003f3f,
0x0004, 0x00000064,
0x0008, 0x0017c11e,
0x000c, 0x05000000,
0x0010, 0x00093ffd,
0x0014, 0x19240009,
0x0018, 0xd81c0207,
0x001c, 0xff000000,
0x0020, 0x00241900,
0x0024, 0x00093ff7,
0x0028, 0x58020009,
0x002c, 0xd81c0207,
0x0030, 0xff000000,
0x0034, 0x00025800,
0x0038, 0x00093fdf,
0x003c, 0x7d3b0009,
0x0040, 0xd81c0207,
0x0044, 0xff000000,
0x0048, 0x003b7d00,
0x004c, 0x00093f7f,
0x0050, 0xe9310009,
0x0054, 0xd81c0207,
0x0058, 0xff000000,
0x005c, 0x0031e900,
0x0060, 0x00093dff,
0x0064, 0x1a0c0009,
0x0068, 0xd81c0207,
0x006c, 0xff000000,
0x0070, 0x000c1a00,
0x0074, 0x80093fff,
0x0078, 0x043d0009,
0x007c, 0xd81c0207,
0x0080, 0xff000000,
0x0084, 0x003d0400,
0x00a0, 0xe6400000,
0x00a4, 0x00000000,
0x00a8, 0x010408d2,
0x00ac, 0x00000000,
0x00b0, 0x00000000,
0x00b8, 0x00005fff,
0x00bc, 0x00000000,
0x00c0, 0x00000000,
0x00c4, 0x00000000,
0x00c8, 0x00000000,
0x00cc, 0x00000000,
0x00d0, 0x00000000,
0x00d4, 0x00000000,
0x00d8, 0x00000000,
0x00dc, 0xe6447800,
0x00e0, 0x78000000,
0x00e4, 0x010408d2,
0x00e8, 0x00000000,
0x00ec, 0x00000000,
0x00f4, 0x00005fff,
0x00f8, 0x00000000,
0x00fc, 0x00000000,
0x0100, 0x00000000,
0x0104, 0x00000000,
0x0108, 0x00000000,
0x010c, 0x02000000,
0x0110, 0x00000000,
0x0114, 0x00000000,
0x0118, 0xe6447800,
0x011c, 0x78000000,
0x0120, 0x010408d2,
0x0124, 0x00000000,
0x0128, 0x00000000,
0x0130, 0x00005fff,
0x0134, 0x00000000,
0x0138, 0x00000000,
0x013c, 0x00000000,
0x0140, 0x00000000,
0x0144, 0x00000000,
0x0148, 0x02000000,
0x014c, 0x00000000,
0x0150, 0x00000000,
0x0154, 0xe6447800,
0x0158, 0x78000000,
0x015c, 0x010408d2,
0x0160, 0x00000000,
0x0164, 0x00000000,
0x016c, 0x00005fff,
0x0170, 0x00000000,
0x0174, 0x00000000,
0x0178, 0x00000000,
0x017c, 0x00000000,
0x0180, 0x00000000,
0x0184, 0x02000000,
0x0188, 0x00000000,
0x018c, 0x00000000,
0x0190, 0xe6447800,
0x0194, 0x78000000,
0x0198, 0x010408d2,
0x019c, 0x00000000,
0x01a0, 0x00000000,
0x01a8, 0x00005fff,
0x01ac, 0x00000000,
0x01b0, 0x00000000,
0x01b4, 0x00000000,
0x01b8, 0x00000000,
0x01bc, 0x00000000,
0x01c0, 0x02000000,
0x01c4, 0x00000000,
0x01c8, 0x00000000,
0x01cc, 0xe6407800,
0x01d0, 0x78000000,
0x01d4, 0x010408d2,
0x01d8, 0x00000000,
0x01dc, 0x00000000,
0x01e4, 0x00005fff,
0x01e8, 0x00000000,
0x01ec, 0x00000000,
0x01f0, 0x00000000,
0x01f4, 0x00000000,
0x01f8, 0x00000000,
0x01fc, 0x02000000,
0x0200, 0x00000000,
0x0204, 0x00000000,
0x0208, 0x00000008,
0x020c, 0x0000000d,
0x41fc, 0x00000000,
0x4400, 0x00000000,
0x4410, 0x00000000,
0x4420, 0x00000000,
0x4430, 0x00000000,
0x4440, 0x00000000,
0x4450, 0x00000000,
0x4460, 0x00000000,
0x4470, 0x00000000,
0xf080, 0x00003018,
0xf084, 0x00000fff,
0xf800, 0x00000000,
0xf804, 0x00002e00,
0xf8d0, 0x00000001,
0xf8d4, 0x00000000,
0xff00, 0x00000301,
0xff0c, 0x01000000,
0xffe0, 0x00000000,
0xfff4, 0x00004011,
0x0090, 0x00000000,
0x0094, 0x00000000,
0x0098, 0x00000000,
0x009c, 0x3f3f3f3f,
};
#endif

View file

@ -0,0 +1,453 @@
#ifndef AW9620X_H_
#define AW9620X_H_
#include "aw_sar_type.h"
#define AW9620X_CHANNEL_NUM_MAX (8)
#define AW9620X_FINE_ADJUST_STEP0 (165)
#define AW9620X_COARSE_ADJUST_STEP0 (9900)
#define AW9620X_FINE_ADJUST_STEP1 (330)
#define AW9620X_COARSE_ADJUST_STEP1 (19800)
#define AW9620X_CFG_REG_STEP (0x8c)
#define AW9620X_PARA_TIMES (10000)
#define AW9620X_PROT_STOP_WAIT_IRQ_CYCLES (100)
#define AW9620X_REG_UPDATA_DIS_MASK (0x00ffffff)
#define AW9620X_AFECFG3_CVMULTUALMOD (11)
#define AW9620X_AFECFG3_CVOFF2X (10)
#define AW9620X_REMOVE_FLOAT_COEF (1024)
#define AW9620X_REG_MCFG_DELAY_MS (20)
#define AW9620X_REG_RSTNALL_VAL (0x3c)
#define AW9620X_POWER_ON_DELAY_MS (25)
#define AW9620X_REG_STEP (0x8c)
#define AW9620X_REMOVE_FLOAT_COEF (1024)
#define AW9620X_SAR_VCC_MIN_UV (1700000)
#define AW9620X_SAR_VCC_MAX_UV (3600000)
#define AW9320X_SRAM_ERROR_CODE (0x1c00)
enum aw_sar_irq_trigger_position {
AW9620X_TRIGGER_FAR,
AW9620X_TRIGGER_TH0,
AW9620X_TRIGGER_TH1 = 0x03,
};
enum AW9620X_CHIP_ID_VALUE {
AW96203CSR_CHIP_ID = 0x20226203,
AW96205DNR_CHIP_ID = 0x20226205,
AW96208CSR_CHIP_ID = 0x20226208,
};
enum AW9620X_OPERAION_MODE {
AW9620X_ACTIVE_MODE = 1,
AW9620X_SLEEP_MODE,
AW9620X_DEEPSLEEP_MODE,
};
/********************************************
* Register List
********************************************/
#define AFE_BASE_ADDR (0x1A00)
#define DSP_BASE_ADDR (0x1A00)
#define STAT_BASE_ADDR (0x1A00)
#define DATA_BASE_ADDR (0x1A00)
#define SFR_BASE_ADDR (0x0000)
/* registers list */
//96208_0917_AFE MAP
#define REG_SCANCTRL0 ((0x0000) + AFE_BASE_ADDR)
#define REG_SCANCTRL1 ((0x0004) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH0 ((0x0040) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH0 ((0x0044) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH0 ((0x004C) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH1 ((0x00CC) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH1 ((0x00D0) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH1 ((0x00D8) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH2 ((0x0158) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH2 ((0x015C) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH2 ((0x0164) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH3 ((0x01E4) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH3 ((0x01E8) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH3 ((0x01F0) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH4 ((0x0270) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH4 ((0x0274) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH4 ((0x027C) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH5 ((0x02FC) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH5 ((0x0300) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH5 ((0x0308) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH6 ((0x0388) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH6 ((0x038C) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH6 ((0x0394) + AFE_BASE_ADDR)
#define REG_AFECFG0_CH7 ((0x0414) + AFE_BASE_ADDR)
#define REG_AFECFG1_CH7 ((0x0418) + AFE_BASE_ADDR)
#define REG_AFECFG3_CH7 ((0x0420) + AFE_BASE_ADDR)
/* registers list */
//96208_0917_DSP MAP
#define REG_FILTCTRL0_CH0 ((0x0050) + DSP_BASE_ADDR)
#define REG_BLFILT_CH0 ((0x0078) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH0 ((0x008C) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH0 ((0x0090) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH0 ((0x0094) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH0 ((0x0098) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH0 ((0x009C) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH1 ((0x00DC) + DSP_BASE_ADDR)
#define REG_BLFILT_CH1 ((0x0104) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH1 ((0x0118) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH1 ((0x011C) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH1 ((0x0120) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH1 ((0x0124) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH1 ((0x0128) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH2 ((0x0168) + DSP_BASE_ADDR)
#define REG_BLFILT_CH2 ((0x0190) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH2 ((0x01A4) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH2 ((0x01A8) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH2 ((0x01AC) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH2 ((0x01B0) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH2 ((0x01B4) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH3 ((0x01F4) + DSP_BASE_ADDR)
#define REG_BLFILT_CH3 ((0x021C) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH3 ((0x0230) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH3 ((0x0234) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH3 ((0x0238) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH3 ((0x023C) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH3 ((0x0240) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH4 ((0x0280) + DSP_BASE_ADDR)
#define REG_BLFILT_CH4 ((0x02A8) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH4 ((0x02BC) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH4 ((0x02C0) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH4 ((0x02C4) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH4 ((0x02C8) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH4 ((0x02CC) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH5 ((0x030C) + DSP_BASE_ADDR)
#define REG_BLFILT_CH5 ((0x0334) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH5 ((0x0348) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH5 ((0x034C) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH5 ((0x0350) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH5 ((0x0354) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH5 ((0x0358) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH6 ((0x0398) + DSP_BASE_ADDR)
#define REG_BLFILT_CH6 ((0x03C0) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH6 ((0x03D4) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH6 ((0x03D8) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH6 ((0x03DC) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH6 ((0x03E0) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH6 ((0x03E4) + DSP_BASE_ADDR)
#define REG_FILTCTRL0_CH7 ((0x0424) + DSP_BASE_ADDR)
#define REG_BLFILT_CH7 ((0x044C) + DSP_BASE_ADDR)
#define REG_BLERRAOT_CH7 ((0x0460) + DSP_BASE_ADDR)
#define REG_PROXCTRL_CH7 ((0x0464) + DSP_BASE_ADDR)
#define REG_PROXTH0_CH7 ((0x0468) + DSP_BASE_ADDR)
#define REG_PROXTH1_CH7 ((0x046C) + DSP_BASE_ADDR)
#define REG_AOTTAR_CH7 ((0x0470) + DSP_BASE_ADDR)
/* registers list */
//96208_0917_STAT MAP
#define REG_FWVER ((0x000C) + STAT_BASE_ADDR)
#define REG_WST ((0x0010) + STAT_BASE_ADDR)
#define REG_STAT0 ((0x0014) + STAT_BASE_ADDR)
#define REG_STAT1 ((0x0018) + STAT_BASE_ADDR)
/* registers list */
//96208_0917_DATA MAP
#define REG_TEMPERATURE ((0x001C) + DATA_BASE_ADDR)
#define REG_BASELINE_CH0 ((0x00AC) + DATA_BASE_ADDR)
#define REG_DIFF_CH0 ((0x00B0) + DATA_BASE_ADDR)
#define REG_BASELINE_CH1 ((0x0138) + DATA_BASE_ADDR)
#define REG_DIFF_CH1 ((0x013C) + DATA_BASE_ADDR)
#define REG_BASELINE_CH2 ((0x01C4) + DATA_BASE_ADDR)
#define REG_DIFF_CH2 ((0x01C8) + DATA_BASE_ADDR)
#define REG_BASELINE_CH3 ((0x0250) + DATA_BASE_ADDR)
#define REG_DIFF_CH3 ((0x0254) + DATA_BASE_ADDR)
#define REG_BASELINE_CH4 ((0x02DC) + DATA_BASE_ADDR)
#define REG_DIFF_CH4 ((0x02E0) + DATA_BASE_ADDR)
#define REG_BASELINE_CH5 ((0x0368) + DATA_BASE_ADDR)
#define REG_DIFF_CH5 ((0x036C) + DATA_BASE_ADDR)
#define REG_BASELINE_CH6 ((0x03F4) + DATA_BASE_ADDR)
#define REG_DIFF_CH6 ((0x03F8) + DATA_BASE_ADDR)
#define REG_BASELINE_CH7 ((0x0480) + DATA_BASE_ADDR)
#define REG_DIFF_CH7 ((0x0484) + DATA_BASE_ADDR)
/* registers list */
//96208_0917_SFR MAP
#define REG_IRQSRC ((0x4410) + SFR_BASE_ADDR)
#define REG_IRQEN ((0x4414) + SFR_BASE_ADDR)
#define REG_I2CDEVID ((0x4440) + SFR_BASE_ADDR)
#define REG_CHIP_ID ((0xFF00) + SFR_BASE_ADDR)
#define REG_CHIPSTAT ((0xFF04) + SFR_BASE_ADDR)
#define REG_HOSTCTRL ((0xFF10) + SFR_BASE_ADDR)
#define REG_RSTNALL ((0xFF18) + SFR_BASE_ADDR)
//driver user
#define REG_ACCESSEN ((0xFF20) + SFR_BASE_ADDR)
#define REG_MCFG ((0x4444) + SFR_BASE_ADDR)
#define REG_ISPGO ((0x4714) + SFR_BASE_ADDR)
#define REG_PMU_CFG ((0x4820) + SFR_BASE_ADDR)
#define REG_ARRAY2_EW_EN ((0x4794) + SFR_BASE_ADDR)
#define REG_ISPADR ((0x4704) + SFR_BASE_ADDR)
#define REG_ISPWDATA ((0x4708) + SFR_BASE_ADDR)
#define REG_ISPRDATA ((0x470C) + SFR_BASE_ADDR)
#define REG_ISPCMD ((0x4710) + SFR_BASE_ADDR)
#define REG_T_RCV ((0x472C) + SFR_BASE_ADDR)
#define REG_CMD ((0x4408) + SFR_BASE_ADDR)
#define REG_BOOT_LOADER_ACTIVE ((0x4748) + SFR_BASE_ADDR)
#define REG_OPEN_APB_ACCESS_EN (0x3c00f091)
#define REG_SET_PMU_CFG (0x6)
#define REG_SET_BTROM_EW_EN (0x5a637955)
#define REG_ISP_CMD_CONFIG (0x0c)
#define REG_SET_ISP_GO (0x1)
#define REG_ENSET_PMU_CFG (0x4)
#define REG_ACCESS_MAIN_ARR (0x05)
#define REG_SET_T_RCV (0xf0)
#define REG_SET_T_RCV_EN (0x16)
#define REG_OPEN_REG_ACCESS_EN (0x3c00ffff)
#define REG_OPEN_MCFG_EN (0x10000)
#define REG_ENSET_BTROM_EW_EN (0x0)
#define REG_SET_MCFG00 (0x0)
#define REG_ISP_CMD_MAIN_ARR (0X03)
#define REG_HOSTCTRL_EN (0x1)
#define REG_ACCESSEN_OPEN (0x3c00F091)
#define REG_ACCESSEN_CLOSE (0x3c00f011)
#define AW_REG_FLASH_WAKE_UP (0x4700)
#define REG_UPDATA_DIS (0x4744)
#define AW_REG_FLASH_WAKE_UP_ON (0x110)
#define AW_REG_FLASH_WAKE_UP_OFF (0x102)
#define AW_BT_HOST2CPU_TRIG_ONLINE_UPGRADE_CMD (0x14)
#define AW_BT_STATE_INFO_ERR (0x1c00)
#define AW_BT_STATE_INFO_PST (0x1C04)
#define AW_BT_STATE_INFO_FLAG (0x1C08)
#define AW_BT_PROT_CMD_PACK_ADDR (0x1C10)
#define AW_BT_PROT_ACK_PACK_ADDR (0x1C14)
#define AW_BT_MESSAGE_MSG0 (0x1C20)
#define AW_BT_MESSAGE_MSG1 (0x1C24)
#define AW_BT_MESSAGE_MSG_FLAG (0x1C28)
#define AW_BT_VER_INF_VERSION (0x1C30)
#define AW_BT_VER_INF_DATE (0x1C34)
#define AW_BT_HOST2CPU_TRIG (0x4408)
#define AW_BTCPU2HOST_TRIG (0x4410)
#define AW_SRAM_FIRST_DETECT (0x20000800)
struct aw_reg_data {
unsigned char rw;
unsigned short reg;
};
/********************************************
* Register Access
*******************************************/
#define REG_NONE_ACCESS (0)
#define REG_RD_ACCESS (1 << 0)
#define REG_WR_ACCESS (1 << 1)
static const struct aw_reg_data g_aw9620x_reg_access[] = {
//AFE MAP
{ .reg = REG_SCANCTRL0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_SCANCTRL1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG0_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG1_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AFECFG3_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
//DSP MAP
{ .reg = REG_FILTCTRL0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH0, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH2, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH3, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH4, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH5, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH6, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_FILTCTRL0_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLFILT_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_BLERRAOT_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXCTRL_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH0_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_PROXTH1_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_AOTTAR_CH7, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
//STAT MAP
{ .reg = REG_FWVER, .rw = REG_RD_ACCESS, },
{ .reg = REG_WST, .rw = REG_RD_ACCESS, },
{ .reg = REG_STAT0, .rw = REG_RD_ACCESS, },
{ .reg = REG_STAT1, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
//DATA MAP
{ .reg = REG_TEMPERATURE, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH0, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH0, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH1, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH1, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH2, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH2, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH3, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH3, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH4, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH4, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH5, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH5, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH6, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH6, .rw = REG_RD_ACCESS, },
{ .reg = REG_BASELINE_CH7, .rw = REG_RD_ACCESS, },
{ .reg = REG_DIFF_CH7, .rw = REG_RD_ACCESS, },
//SFR MAP
{ .reg = REG_IRQSRC, .rw = REG_RD_ACCESS, },
{ .reg = REG_IRQEN, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_I2CDEVID, .rw = REG_RD_ACCESS, },
{ .reg = REG_CHIP_ID, .rw = REG_RD_ACCESS, },
{ .reg = REG_CHIPSTAT, .rw = REG_RD_ACCESS, },
{ .reg = REG_HOSTCTRL, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
{ .reg = REG_RSTNALL, .rw = REG_RD_ACCESS | REG_WR_ACCESS, },
};
//aw96208 reg config
static const uint32_t aw9620x_reg_default[] = {
0x1A00, 0x003FFFFF,
0x1A04, 0x00000032,
0x1A40, 0x09500001,
0x1A44, 0x3F000000,
0x1A4C, 0x00000000,
0x1ACC, 0x09500004,
0x1AD0, 0x3F000000,
0x1AD8, 0x00000000,
0x1B58, 0x09500010,
0x1B5C, 0x3F000000,
0x1B64, 0x00000000,
0x1BE4, 0x09500040,
0x1BE8, 0x3F000000,
0x1BF0, 0x00000000,
0x1C70, 0x09500100,
0x1C74, 0x3F000000,
0x1C7C, 0x00000000,
0x1CFC, 0x09500400,
0x1D00, 0x3F000000,
0x1D08, 0x00000000,
0x1D88, 0x09501000,
0x1D8C, 0x3F000000,
0x1D94, 0x00000000,
0x1E14, 0x09504000,
0x1E18, 0x3F000000,
0x1E20, 0x00000000,
0x1A50, 0x00000004,
0x1A78, 0x00640000,
0x1A8C, 0xFF000001,
0x1A90, 0x00000000,
0x1A94, 0x00002710,
0x1A98, 0x00004E20,
0x1A9C, 0x00000000,
0x1ADC, 0x00000004,
0x1B04, 0x00640000,
0x1B18, 0xFF000001,
0x1B1C, 0x00000000,
0x1B20, 0x00002710,
0x1B24, 0x00004E20,
0x1B28, 0x00000000,
0x1B68, 0x00000004,
0x1B90, 0x00640000,
0x1BA4, 0xFF000001,
0x1BA8, 0x00000000,
0x1BAC, 0x00002710,
0x1BB0, 0x00004E20,
0x1BB4, 0x00000000,
0x1BF4, 0x00000004,
0x1C1C, 0x00640000,
0x1C30, 0xFF000001,
0x1C34, 0x00000000,
0x1C38, 0x00002710,
0x1C3C, 0x00004E20,
0x1C40, 0x00000000,
0x1C80, 0x00000004,
0x1CA8, 0x00640000,
0x1CBC, 0xFF000001,
0x1CC0, 0x00000000,
0x1CC4, 0x00002710,
0x1CC8, 0x00004E20,
0x1CCC, 0x00000000,
0x1D0C, 0x00000004,
0x1D34, 0x00640000,
0x1D48, 0xFF000001,
0x1D4C, 0x00000000,
0x1D50, 0x00002710,
0x1D54, 0x00004E20,
0x1D58, 0x00000000,
0x1D98, 0x00000004,
0x1DC0, 0x00640000,
0x1DD4, 0xFF000001,
0x1DD8, 0x00000000,
0x1DDC, 0x00002710,
0x1DE0, 0x00004E20,
0x1DE4, 0x00000000,
0x1E24, 0x00000004,
0x1E4C, 0x00640000,
0x1E60, 0xFF000001,
0x1E64, 0x00000000,
0x1E68, 0x00002710,
0x1E6C, 0x00004E20,
0x1E70, 0x00000000,
0x4414, 0x0000081F,
0x1A18, 0x00FFFFFF,
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
#ifndef AW_SAR_H_
#define AW_SAR_H_
void aw_sar_disable_irq(struct aw_sar *p_sar);
void aw_sar_enable_irq(struct aw_sar *p_sar);
int32_t aw_sar_soft_reset(struct aw_sar *p_sar);
int32_t aw_sar_check_init_over_irq(struct aw_sar *p_sar);
int32_t aw_sar_update_fw(struct aw_sar *p_sar);
int32_t aw_sar_load_def_reg_bin(struct aw_sar *p_sar);
void aw_sar_mode_set(struct aw_sar *p_sar, uint8_t curr_mode);
int32_t aw_sar_update_reg_set_func(struct aw_sar *p_sar);
#endif

View file

@ -0,0 +1,33 @@
#ifndef _SAR_SUPPORT_CHIP_H_
#define _SAR_SUPPORT_CHIP_H_
#include "aw_sar_type.h"
enum aw_sar_driver_list_t {
AW_SAR_AW9610X,
AW_SAR_AW9620X,
AW_SAR_AW963XX,
AW_SAR_DRIVER_MAX,
};
int32_t aw9610x_check_chipid(void *data);
int32_t aw9610x_init(struct aw_sar *p_sar);
void aw9610x_deinit(struct aw_sar *p_sar);
int32_t aw9620x_check_chipid(void *data);
int32_t aw9620x_init(struct aw_sar *p_sar);
void aw9620x_deinit(struct aw_sar *p_sar);
int32_t aw963xx_check_chipid(void *data);
int32_t aw963xx_init(struct aw_sar *p_sar);
void aw963xx_deinit(struct aw_sar *p_sar);
static const struct aw_sar_driver_type g_aw_sar_driver_list[] = {
{ AW_SAR_AW9610X, aw9610x_check_chipid, aw9610x_init, aw9610x_deinit },
{ AW_SAR_AW9620X, aw9620x_check_chipid, aw9620x_init, aw9620x_deinit },
{ AW_SAR_AW963XX, aw963xx_check_chipid, aw963xx_init, aw963xx_deinit },
};
#endif

View file

@ -0,0 +1,221 @@
#ifndef _AW_SAR_PLAT_HW_INTERFACE_H_
#define _AW_SAR_PLAT_HW_INTERFACE_H_
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/syscalls.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/kern_levels.h>
#include <linux/regulator/consumer.h>
#include <linux/power_supply.h>
#include <linux/decompress/mm.h>
#include <linux/notifier.h>
#include <linux/usb.h>
enum aw_sar_chip_list_t {
AW_SAR_NONE_CHECK_CHIP,
SAR_AW9610X = 1 << 1,
SAR_AW9610XA = 1 << 2,
SAR_AW96203 = 1 << 3,
SAR_AW96205 = 1 << 4,
SAR_AW96208 = 1 << 5,
SAR_AW96303 = 1 << 6,
SAR_AW96305 = 1 << 7,
SAR_AW96308 = 1 << 8,
SAR_AW96310 = 1 << 9,
SAR_AW96312 = 1 << 10,
};
enum AW_SAR_UPDATE_FW_MODE {
PROT_UPDATE_FW,
REG_UPDATE_FW,
};
#define AW_SAR_LABLE " "
#define AW_SAR_FILENAME(x) strrchr((x), '/') ? (strrchr((x), '/') + 1) : (x)
//dev_dbg
#define AW_SAR_DEBUG_LOG
#ifdef AW_SAR_DEBUG_LOG
#define AWLOGD(dev, format, arg...) \
do {\
dev_dbg(dev, \
AW_SAR_LABLE"[%s:%s:%d] "format"\n", AW_SAR_FILENAME(__FILE__), __func__, __LINE__, ##arg);\
} while (0)
#else
#define AWLOGD(dev, format, arg...)
#endif
#define AW_SAR_INFO_LOG
#ifdef AW_SAR_INFO_LOG
#define AWLOGI(dev, format, arg...) \
do {\
dev_info(dev, \
AW_SAR_LABLE"[%s:%s:%d] "format"\n", AW_SAR_FILENAME(__FILE__), __func__, __LINE__, ##arg);\
} while (0)
#else
#define AWLOGI(dev, format, arg...)
#endif
#define AW_SAR_ERR_LOG
#ifdef AW_SAR_ERR_LOG
#define AWLOGE(dev, format, arg...) \
do {\
dev_err(dev, \
AW_SAR_LABLE"[%s:%s:%d] "format"\n", AW_SAR_FILENAME(__FILE__), __func__, __LINE__, ##arg);\
} while (0)
#else
#define AWLOGE(dev, format, arg...)
#endif
#ifndef AW_TRUE
#define AW_TRUE (1)
#endif
#ifndef AW_FALSE
#define AW_FALSE (0)
#endif
/*
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef uint8_t bool;
*/
enum aw_sar_rst_val {
AW_OK,
AW_ERR,
AW_PARA_ERR,
AW_VERS_ERR,
AW_ERR_CHIPID,
AW_ERR_IRQ_INIT_OVER,
AW_PROT_UPDATE_ERR,
AW_REG_LOAD_ERR,
AW_INVALID_PARA,
AW_BIN_PARA_INVALID,
AW_FW_CHECK_ERR,
AW_BT_CHECK_ERR,
AW_OTEHR_CHECK_ERR,
AW_BIN_NAME_CHECK_ERR,
};
#define AW_SAR_FLIP_U16(value) ((((value) & (0x00FF)) << (8)) | (((value) & (0xFF00)) >> (8)))
#define AW_SAR_FLIP_U32(value) ((((value) & (0x000000FF)) << (24)) | ((((value) & (0x0000FF00))) << (8)) | (((value) & (0x00FF0000)) >> (8)) | (((value) & (0xFF000000)) >> (24)))
#ifndef OFFSET_BIT_0
#define OFFSET_BIT_0 (0)
#endif
#ifndef OFFSET_BIT_8
#define OFFSET_BIT_8 (8)
#endif
#ifndef OFFSET_BIT_16
#define OFFSET_BIT_16 (16)
#endif
#ifndef OFFSET_BIT_24
#define OFFSET_BIT_24 (24)
#endif
#ifndef WORD_LEN
#define WORD_LEN (4)
#endif
#ifndef GET_BITS_7_0
#define GET_BITS_7_0 (0x00FF)
#endif
#ifndef GET_BITS_15_8
#define GET_BITS_15_8 (0xFF00)
#endif
#ifndef GET_BITS_24_16
#define GET_BITS_24_16 (0x00FF0000)
#endif
#ifndef GET_BITS_31_25
#define GET_BITS_31_25 (0xFF000000)
#endif
#define AW_SAR_ABS(x) (((x) > 0) ? (x) : (-(x)))
#define AW_SAR_GET_32_DATA(w, x, y, z) ((unsigned int)(((w) << 24) | ((x) << 16) | ((y) << 8) | (z)))
#define AW_SAR_GET_16_DATA(a, b) (((uint32_t)(a) << (8)) | ((uint32_t)(b) << (0)))
enum AW_SAR_HOST_IRQ_STAT {
IRQ_ENABLE,
IRQ_DISABLE,
};
#define AW_SAR_BIN_NUM_MAX 100
#define AW_SAR_HEADER_LEN 60
struct bin_header_info {
unsigned int header_len; /* Frame header length */
unsigned int check_sum; /* Frame header information-Checksum */
unsigned int header_ver; /* Frame header information-Frame header version */
unsigned int bin_data_type; /* Frame header information-Data type */
unsigned int bin_data_ver; /* Frame header information-Data version */
unsigned int bin_data_len; /* Frame header information-Data length */
unsigned int ui_ver; /* Frame header information-ui version */
unsigned char chip_type[8]; /* Frame header information-chip type */
unsigned int reg_byte_len; /* Frame header information-reg byte len */
unsigned int data_byte_len; /* Frame header information-data byte len */
unsigned int device_addr; /* Frame header information-device addr */
unsigned int valid_data_len; /* Length of valid data obtained after parsing */
unsigned int valid_data_addr; /* The offset address of the valid data obtained after parsing relative to info */
unsigned int reg_num; /* The number of registers obtained after parsing */
unsigned int reg_data_byte_len; /* The byte length of the register obtained after parsing */
unsigned int download_addr; /* The starting address or download address obtained after parsing */
unsigned int app_version; /* The software version number obtained after parsing */
};
struct bin_container {
unsigned int len; /* The size of the bin file obtained from the firmware */
unsigned char data[]; /* Store the bin file obtained from the firmware */
};
struct aw_bin {
char *p_addr; /* Offset pointer (backward offset pointer to obtain frame header information and important information) */
unsigned int all_bin_parse_num; /* The number of all bin files */
unsigned int multi_bin_parse_num; /* The number of single bin files */
unsigned int single_bin_parse_num; /* The number of multiple bin files */
struct bin_header_info header_info[AW_SAR_BIN_NUM_MAX]; /* Frame header information and other important data obtained after parsing */
struct bin_container info; /* Obtained bin file data that needs to be parsed */
};
//I2C communication API
extern int32_t aw_sar_i2c_read(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t *reg_data32);
extern int32_t aw_sar_i2c_write(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t reg_data32);
extern int32_t aw_sar_i2c_write_bits(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t mask, uint32_t val);
extern int32_t aw_sar_i2c_write_seq(struct i2c_client *i2c, uint8_t *tr_data, uint16_t len);
extern int32_t aw_sar_i2c_read_seq(struct i2c_client *i2c, uint8_t *addr, uint8_t addr_len, uint8_t *data, uint16_t data_len);
extern void aw_sar_delay_ms(uint32_t ms);
extern int aw_sar_parsing_bin_file(struct aw_bin *bin);
extern uint32_t aw_sar_pow2(uint32_t cnt);
extern int32_t aw_sar_load_reg(struct aw_bin *aw_bin, struct i2c_client *i2c);
#endif

View file

@ -0,0 +1,359 @@
#ifndef _SAR_TYPE_H_
#define _SAR_TYPE_H_
#include "aw_sar_comm_interface.h"
typedef int32_t (*aw_sar_chip_other_operation_t)(void *data);
typedef void (*aw_sar_chip_other_opera_free_t)(void *data);
enum aw_i2c_flags {
AW_SAR_I2C_WR,
AW_SAR_I2C_RD,
AW_SAR_PACKAGE_RD,
};
typedef int32_t (*aw_sar_bin_opera_t)(struct aw_bin *aw_bin, void *load_bin_para);
typedef int32_t (*aw_sar_bin_load_fail_opera_t)(struct aw_bin *aw_bin, void *load_bin_para);
struct aw_sar_get_chip_info_t {
void (*p_get_chip_info_node_fn)(void *data, char *buf, ssize_t *p_len);
};
struct aw_sar_load_bin_t {
const uint8_t *bin_name;
aw_sar_bin_opera_t bin_opera_func;
aw_sar_bin_load_fail_opera_t bin_load_fail_opera;
void (*p_get_prot_update_fw_node_fn)(void *data, char *buf, ssize_t *p_len);
/*Perform different operations to update parameters*/
int32_t (*p_update_fn)(void *data);
};
struct aw_sar_reg_data {
unsigned char rw;
unsigned short reg;
};
struct aw_sar_awrw_t {
ssize_t (*p_set_awrw_node_fn)(void *data, const char *buf, size_t count);
ssize_t (*p_get_awrw_node_fn)(void *data, char *buf);
};
struct aw_sar_reg_list_t {
uint8_t reg_none_access;
uint8_t reg_rd_access;
uint8_t reg_wd_access;
const struct aw_sar_reg_data *reg_perm;
uint32_t reg_num;
};
typedef void (*aw_sar_update_work_t)(struct work_struct *work);
struct aw_sar_update_static_t {
aw_sar_update_work_t update_work_func;
uint32_t delay_ms;
};
typedef irqreturn_t (*aw_sar_irq_t)(int irq, void *data);
typedef uint32_t (*sar_rc_irqscr_t)(void *i2c);
//If the return value is 1, there is an initialization completion interrupt; if the return value is 0, there is no
typedef uint32_t (*aw_sar_is_init_over_irq)(uint32_t irq_status);
typedef void (*aw_sar_irq_spec_handler_t)(uint32_t irq_status, void *data);
struct aw_sar_check_chipid_t {
/*Read chipid and check chipid, Must be implemented externally*/
int32_t (*p_check_chipid_fn)(void *data);
};
struct aw_sar_irq_init_t {
unsigned long flags;
unsigned long irq_flags;
irq_handler_t handler;
irq_handler_t thread_fn;
/*Interrupt processing parameters*/
sar_rc_irqscr_t rc_irq_fn;
//aw_sar_is_init_over_irq is_init_over_irq_fn;
aw_sar_irq_spec_handler_t irq_spec_handler_fn;
/*Use a different initialization interrupt to initialize the operation*/
int32_t (*p_irq_init_fn)(void *data);
/*Release interrupt resource*/
// void const (*p_irq_deinit_fn)(void *data);
int (*p_irq_deinit_fn)(void *data);
};
struct aw_sar_pm_t {
uint32_t suspend_set_mode;
uint32_t resume_set_mode;
uint32_t shutdown_set_mode;
//system api
int32_t (*p_suspend_fn)(void *data);
int32_t (*p_resume_fn)(void *data);
int32_t (*p_shutdown_fn)(void *data);
};
struct aw_sar_chip_mode_t {
uint32_t init_mode;
uint32_t active;
uint32_t pre_init_mode;
};
struct aw_sar_regulator_config_t {
//Note that "_sar_num" after VCC name is defined by SAR C auto add
const uint8_t *vcc_name;
int32_t min_uV;
int32_t max_uV;
};
struct aw_channels_info {
uint16_t used;
uint32_t last_channel_info;
struct input_dev *input;
uint8_t name[20];
};
struct aw_sar_dts_info {
uint32_t sar_num;
int32_t irq_gpio;
uint32_t channel_use_flag;
bool use_regulator_flag;
bool use_inter_pull_up;
bool use_pm;
bool update_fw_flag;
bool use_plug_cail_flag;
};
struct aw_sar_irq_init_comm_t {
int32_t to_irq;
uint8_t host_irq_stat;
void *data;
uint8_t label[30];
uint8_t dev_id[30];
};
struct aw_sar_load_bin_comm_t {
uint8_t bin_name[30];
aw_sar_bin_opera_t bin_opera_func;
aw_sar_bin_load_fail_opera_t bin_load_fail_opera_func;
};
struct aw_awrw_info {
uint8_t rw_flag;
uint8_t addr_len;
uint8_t data_len;
uint8_t reg_num;
uint32_t i2c_tranfar_data_len;
uint8_t *p_i2c_tranfar_data;
};
/****************mode set start******************/
typedef void (*sar_enable_clock_t)(void *i2c);
typedef void (*sar_operation_irq_t)(int to_irq);
typedef void (*sar_mode_update_t)(void *i2c);
struct aw_sar_mode_switch_ops {
sar_enable_clock_t enable_clock;
sar_rc_irqscr_t rc_irqscr;
sar_mode_update_t mode_update;
};
struct aw_sar_chip_mode {
uint8_t curr_mode;
uint8_t last_mode;
};
struct aw_sar_mode_set_t {
uint8_t chip_id;
struct aw_sar_chip_mode chip_mode;
struct aw_sar_mode_switch_ops mode_switch_ops;
};
struct aw_sar_mode_t {
const struct aw_sar_mode_set_t *mode_set_arr;
uint8_t mode_set_arr_len;
ssize_t (*p_set_mode_node_fn)(void *data, uint8_t curr_mode);
ssize_t (*p_get_mode_node_fn)(void *data, char *buf);
};
/********************mode set end****************/
struct aw_sar_init_over_irq_t {
int16_t wait_times;
uint8_t daley_step;
uint32_t reg_irqsrc;
uint32_t irq_offset_bit;
uint32_t irq_mask;
uint32_t irq_flag;
/*Perform different verification initialization to complete the interrupt operation*/
int32_t (*p_check_init_over_irq_fn)(void *data);
/*When initialization fails, get the corresponding error type and apply it to the chip with flash*/
int32_t (*p_get_err_type_fn)(void *data);
};
struct aw_sar_soft_rst_t {
uint16_t reg_rst;
uint32_t reg_rst_val;
uint32_t delay_ms;
/*Perform different soft reset operations*/
int32_t (*p_soft_reset_fn)(void *data);
};
struct aw_sar_aot_t {
uint32_t aot_reg;
uint32_t aot_mask;
uint32_t aot_flag;
ssize_t (*p_set_aot_node_fn)(void *data);
};
struct aw_sar_diff_t {
uint16_t diff0_reg;
uint16_t diff_step;
//Data format:S21.10, Floating point types generally need to be removed
uint32_t rm_float;
ssize_t (*p_get_diff_node_fn)(void *data, char *buf);
};
struct aw_sar_offset_t {
ssize_t (*p_get_offset_node_fn)(void *data, char *buf);
};
struct aw_sar_pinctrl {
struct pinctrl *pinctrl;
struct pinctrl_state *default_sta;
struct pinctrl_state *int_out_high;
struct pinctrl_state *int_out_low;
};
//update reg node
struct aw_sar_para_load_t {
const uint32_t *reg_arr;
uint32_t reg_arr_len;
};
struct aw_sar_platform_config {
/*The chip needs to parse more DTS contents for addition*/
int32_t (*p_add_parse_dts_fn)(void *data);
const struct aw_sar_regulator_config_t *p_regulator_config;
/*The chip needs to add more nodes*/
int32_t (*p_add_node_create_fn)(void *data);
/*Release the added node*/
int32_t (*p_add_node_free_fn)(void *data);
/*Use a different initialization interrupt to initialize the operation*/
int32_t (*p_input_init_fn)(void *data);
/*Release input resource*/
int32_t (*p_input_deinit_fn)(void *data);
//The parameters passed in are required for interrupt initialization
const struct aw_sar_irq_init_t *p_irq_init;
//The chip is set to different modes in different power management interfaces
const struct aw_sar_pm_t *p_pm_chip_mode;
};
/*Parameter passed in by different SAR sensors.
It must be implemented in each sensor code.
If it is not necessary that some members can be assigned null,
the corresponding function will not be implemented
*/
struct aw_sar_chip_config {
uint8_t ch_num_max; //Number of channels of the chip
//Chip related platform content configuration
const struct aw_sar_platform_config *p_platform_config;
//Parameters required for verification of chipid
const struct aw_sar_check_chipid_t *p_check_chipid;
//Parameters required for soft reset
const struct aw_sar_soft_rst_t *p_soft_rst;
//Verify the parameters required to initialize a complete interrupt
const struct aw_sar_init_over_irq_t *p_init_over_irq;
//Parameters required for load boot bin file,
//If the chip does not have flash, please ignore and assign the value to null
const struct aw_sar_load_bin_t *p_fw_bin;
//Parameters required for load register bin file
const struct aw_sar_load_bin_t *p_reg_bin;
//The mode set before and after the initialization of the chip
const struct aw_sar_chip_mode_t *p_chip_mode;
//Node usage parameters
//Register permission table
const struct aw_sar_reg_list_t *p_reg_list;
//Default register table
const struct aw_sar_para_load_t *p_reg_arr;
//Parameters required for set Auto-Offset-Tuning(aot)
const struct aw_sar_aot_t *p_aot;
//Parameters required for get chip diff val
const struct aw_sar_diff_t *p_diff;
//Parameters required for get chip offset val
const struct aw_sar_offset_t *p_offset;
//Set the parameters of different working modes of the chip
const struct aw_sar_mode_t *p_mode;
//Upgrading firmware using the debug node protocol
const struct aw_sar_load_bin_t *p_prox_fw;
//Upgrading firmware using the debug node reg
const struct aw_sar_load_bin_t *p_reg_fw;
//Obtain the necessary information of the chip
const struct aw_sar_get_chip_info_t *p_get_chip_info;
//Continuous read/write register interface
const struct aw_sar_awrw_t *p_aw_sar_awrw;
//Parameters required for load boot bin file,
//If the chip does not have flash, please ignore and assign the value to null
const struct aw_sar_load_bin_t *p_boot_bin;
/*Other operations during initialization, Add according to different usage*/
aw_sar_chip_other_operation_t p_other_operation;
/*If requested by resources, please release*/
aw_sar_chip_other_opera_free_t p_other_opera_free;
};
struct aw_sar {
struct i2c_client *i2c;
struct device *dev;
struct regulator *vcc;
struct delayed_work update_work;
//Set pin pull-up mode
struct aw_sar_pinctrl pinctrl;
struct work_struct ps_notify_work;
struct notifier_block ps_notif;
bool ps_is_present;
uint8_t chip_type;
uint8_t chip_name[20];
bool power_enable;
bool fw_fail_flag;
uint8_t last_mode;
uint8_t ret_val;
uint8_t curr_use_driver_type;
int32_t prot_update_state;
uint8_t intrrupt_init_state;
//Parameters related to platform logic
struct aw_sar_dts_info dts_info;
struct aw_sar_load_bin_comm_t load_bin;
struct aw_sar_irq_init_comm_t irq_init;
struct aw_awrw_info awrw_info;
struct aw_channels_info *channels_arr;
//Private arguments required for public functions
const struct aw_sar_chip_config *p_sar_para;
//Private arguments required for private functions
void *priv_data;
};
//Determine whether the chip exists by verifying chipid
typedef int32_t (*aw_sar_who_am_i_t)(void *data);
typedef int32_t (*aw_sar_chip_init_t)(struct aw_sar *p_sar);
typedef void (*aw_sar_chip_deinit_t)(struct aw_sar *p_sar);
struct aw_sar_driver_type {
uint8_t driver_type;
aw_sar_who_am_i_t p_who_am_i;
aw_sar_chip_init_t p_chip_init;
aw_sar_chip_deinit_t p_chip_deinit;
};
#endif

View file

@ -0,0 +1,335 @@
#ifndef __AW_UPDATE_H_
#define __AW_UPDATE_H_
#include "aw_sar_comm_interface.h"
#include "aw_sar_type.h"
#include "aw_update_fw_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
#define AW_SAR_LOG_TAG "awinic sar "
#define AW_FW_UPDATE_DEBUG_LOG
#ifdef AW_FW_UPDATE_DEBUG_LOG
#define AWLOGD_FW(format, arg...) \
do {\
pr_info(AW_SAR_LOG_TAG "[%s:%d] "format"\n", __func__, __LINE__, ##arg);\
} while (0)
#else
#define AWLOGD_FW(format, arg...)
#endif
#define AW_FW_UPDATE_DEBUG_LOG
#ifdef AW_FW_UPDATE_DEBUG_LOG
#define AWLOGI_FW(format, arg...) \
do {\
pr_info(AW_SAR_LOG_TAG "[%s:%d] "format"\n", __func__, __LINE__, ##arg);\
} while (0)
#else
#define AWLOGI_FW(format, arg...)
#endif
#define AW_FW_UPDATE_DEBUG_LOG
#ifdef AW_FW_UPDATE_DEBUG_LOG
#define AWLOGE_FW(format, arg...) \
do {\
pr_err(AW_SAR_LOG_TAG "[%s:%d] "format"\n", __func__, __LINE__, ##arg);\
} while (0)
#else
#define AWLOGE_FW(format, arg...)
#endif
#define REG_IRQSRC (0x4410)
//driver user
#define REG_ACCESSEN (0xFF20)
#define REG_MCFG (0x4444)
#define REG_ISPGO (0x4714)
#define REG_PMU_CFG (0x4820)
#define REG_ARRAY2_EW_EN (0x4794)
#define REG_ISPADR (0x4704)
#define REG_ISPWDATA (0x4708)
#define REG_ISPRDATA (0x470C)
#define REG_ISPCMD (0x4710)
#define REG_T_RCV (0x472C)
#define REG_CMD (0x4408)
#define REG_BOOT_LOADER_ACTIVE (0x4748)
#define REG_OPEN_APB_ACCESS_EN (0x3c00f091)
#define REG_SET_PMU_CFG (0x6)
#define REG_SET_BTROM_EW_EN (0x5a637955)
#define REG_ISP_CMD_CONFIG (0x0c)
#define REG_SET_ISP_GO (0x1)
#define REG_ENSET_PMU_CFG (0x4)
#define REG_ACCESS_MAIN_ARR (0x05)
#define REG_SET_T_RCV (0xf0)
#define REG_SET_T_RCV_EN (0x16)
#define REG_OPEN_REG_ACCESS_EN (0x3c00ffff)
#define REG_OPEN_MCFG_EN (0x10000)
#define REG_ENSET_BTROM_EW_EN (0x0)
#define REG_SET_MCFG00 (0x0)
#define REG_ISP_CMD_MAIN_ARR (0X03)
#define REG_HOSTCTRL_EN (0x1)
#define REG_ACCESSEN_OPEN (0x3c00F091)
#define REG_ACCESSEN_CLOSE (0x3c00f011)
#define AW_REG_FLASH_WAKE_UP (0x4700)
#define REG_UPDATA_DIS (0x4744)
#define AW_REG_FLASH_WAKE_UP_ON (0x110)
#define AW_REG_FLASH_WAKE_UP_OFF (0x102)
#define AW_BT_HOST2CPU_TRIG_ONLINE_UPGRADE_CMD (0x14)
#define AW_BT_STATE_INFO_ERR (0x1c00)
#define AW_BT_STATE_INFO_PST (0x1C04)
#define AW_BT_STATE_INFO_FLAG (0x1C08)
#define AW_BT_PROT_CMD_PACK_ADDR (0x1C10)
#define AW_BT_PROT_ACK_PACK_ADDR (0x1C14)
#define AW_BT_MESSAGE_MSG0 (0x1C20)
#define AW_BT_MESSAGE_MSG1 (0x1C24)
#define AW_BT_MESSAGE_MSG_FLAG (0x1C28)
#define AW_BT_VER_INF_VERSION (0x1C30)
#define AW_BT_VER_INF_DATE (0x1C34)
#define AW_BT_HOST2CPU_TRIG (0x4408)
#define AW_BTCPU2HOST_TRIG (0x4410)
#define AW_SRAM_FIRST_DETECT (0x20000800)
#define AW_POWER_ON_DELAY_MS (25)
#define REG_MCFG_DELAY_MS (20)
#define AW_IRQ_DELAY_MS (100)
#define REG_RSTNALL_VAL (0x3c)
#define INIT_OVER_IRQ (1)
#define CMD_SLEEP_MODE (2)
#define AW_WORD_LEN (4)
#define AW_REG_DATA_LEN (4)
#define AW_REG_ADDR_LEN (2)
#define AW_TX_BUF_LEN (AW_REG_DATA_LEN + AW_REG_ADDR_LEN)
#define AW_RETRIES (5)
#define TRANSFER_SEQ_LEN (4)
#define TRANSFER_DTS_ADDR_LEN (4)
#define AW_FLASH_DEFAULT_VAL (0xffffffff)
#define AW_PROT_STOP_WAIT_IRQ_CYCLES (100)
#define AW_REG_UPDATA_DIS_MASK (0x00ffffff)
#define AW_AFECFG3_CVMULTUALMOD (11)
#define AW_AFECFG3_CVOFF2X (10)
#define AW_REG_MCFG (0x4444)
#define AW_REG_ACESS_EN (0xff20)
#define AW_REG_BOOTLOADER_ACTIVER (0x4748)
#define AW_REG_MCFG (0x4444)
#define AW_REG_RSTNALL (0xff18)
#define AW_CPU_HALT (0x00010000)
#define AW_ACC_PERI (0x3c00ffff)
#define AWDIS_HARD_BT_MODE (0x00000000)
#define AW_CPU_RUN (0x00000000)
#define AW_RSTNALL (0x0000003c)
enum AW_UPDATE_RET {
AW_FW_OK,
AW_FW_ERR,
};
enum AW9620X_UPDATE_MODE {
BOOT_UPDATE,
FIRMWARE_UPDATE,
};
#define PROT_SEND_ADDR (0x0800)
#define SEND_ADDR_LEN (2)
#define AW_ACK_ADDR (0x1800)
#define AW_PACK_FIXED_SIZE (12)
#define AW_ADDR_SIZE (2)
//hecksum_en host->slave
#define AW_HEADER_VAL (0x02)
#define REG_H2C_TRIG_PARSE_CMD (0x15)
#define AW_WAIT_IRQ_CYCLES (10)
#define AW_WAIT_ENTER_SLEEP_MODE (100)
#define AW_WAIT_ENTER_TR_MODE (100)
#define INIT_OVER_IRQ_OK (1)
#define TRANSFER_SEQ_LEN (4)
#define TRANSFER_DTS_ADDR_LEN (4)
#define AW_BT_CHECK_SUM_ADDR (0x07fc)
#define AW_START_CMD_ACK_STATUS (2)
#define AW_START_CMD_ACK_ADDR_LEN (2)
#define P_AW_START_CMD_SEND_VALUE (NULL)
#define AW_START_CMD_SEND_VALUE_LEN (0)
#define P_AW_ERASE_CHIP_CMD_SEND_VALUE (NULL)
#define AW_ERASE_CHIP_CMD_SEND_VALUE_LEN (0)
#define P_AW_RESTORE_CMD_SEND_VALUE (NULL)
#define AW_RESTORE_CMD_SEND_VALUE_LEN (0)
#define AW_EN_TR_CHECK_VALUE_LEN (16)
#define AW_FLASH_ERASE_CHIO_CMD_ACK_LEN (4)
#define AW_REG_WST_MODE_SLEEP (0x03000000)
enum AW9620X_FLASH_ADDR {
FLASH_ADDR_BOOT,
FLASH_ADDR_FW,
};
enum AW9620X_CMP_VAL {
BIN_VER_EQUALS_SOC_VER,
BIN_VER_NOT_EQUALS_SOC_VER,
};
enum AW_MODULE {
UPDATE_MODULE = 0x01,
FLASH_MODULE,
QUERY_MODULE,
};
enum AW_UPDATE_COMMAND {
UPDATE_START_CMD = 0X01,
UPDATE_TRANSFER_CMD,
UPDATE_STOP_CMD,
UPDATE_RESTORE_FLASHBT_CMD,
};
enum AW_UPDATE_COMMAND_ACK {
UPDATE_START_CMD_ACK = 0X01,
UPDATE_RANSFER_CMD_ACK,
UPDATE_STOP_CMD_ACK,
UPDATE_RESTORE_FLASHBT_CMD_ACK,
};
enum AW_FLASH_COMMAND {
FLASH_ERASE_CHIP_CMD = 0X01,
FLASH_ERASE_SECTOR_CMD,
};
enum AW_FLASH_COMMAND_ACK {
FLASH_ERASE_CHIP_CMD_ACK = 0X01,
FLASH_ERASE_SECTOR_CMD_ACK,
};
enum AW_QUERY_COMMAND {
QUERY_BT_VER_CMD = 0X01,
QUERY_BT_DATE_CMD,
QUERY_ERR_CODE_CMD,
QUERY_PST_CMD,
QUERY_CACHE_CMD,
};
enum AW_QUERY_COMMAND_ACK {
QUERY_BT_VER_CMD_ACK = 0X01,
QUERY_BT_DATE_CMD_ACK,
QUERY_ERR_CODE_CMD_ACK,
QUERY_PST_CMD_ACK,
QUERY_CACHE_CMD_ACK,
};
struct aw_soc_protocol {
uint16_t header;
uint16_t size;
uint32_t checksum;
uint8_t module;
uint8_t command;
uint16_t length;
uint8_t value[0];
};
enum AW_UPDATE_FW_STATE {
SEND_UPDTAE_CMD,
SEND_START_CMD,
SEND_ERASE_SECTOR_CMD,
SEND_UPDATE_FW_CMD,
SEND_UPDATE_CHECK_CODE_CMD,
SEND_RESTORE_CMD,
SEND_STOP_CMD,
};
enum AW_PROT_UPDATE_FW_DELAY_TIME{
SEND_UPDTAE_CMD_DELAY_MS = 1,
SEND_START_CMD_DELAY_MS = 3,
SEND_ERASE_SECTOR_CMD_DELAY_MS = 5,
SEND_UPDATE_FW_CMD_DELAY_MS = 100,
SEND_UPDATE_CHECK_CODE_CMD_DELAY_MS = 1,
SEND_RESTORE_CMD_DELAY_MS = 27,
SEND_STOP_CMD_DELAY_MS = 25,
};
enum AW_PROT_RECV_LEN {
SEND_START_CMD_RECV_LEN = 8,
SEND_ERASE_CHIP_CMD_RECV_LEN = 4,
SEND_UPDATE_FW_CMD_RECV_LEN = 8,
SEND_UPDATE_CHECK_CODE_CMD_RECV_LEN = 4,
SEND_RESTORE_CMD_RECV_LEN = 4,
};
/********************reg update end****************/
struct aw_flash_update_info {
uint32_t tr_start_addr;
uint32_t check_len;//The verification code is calculated by the verification length and the firmware chip
uint32_t check_en_addr;
uint32_t check_code_addr;
uint32_t check_en_val;
uint32_t erase_start_addr;
uint32_t erase_sector_cnt;
uint32_t sector_size;
};
enum chip_select_flag {
CHIP_AW9620X,
//CHIP_AW9320X,
//CHIP_AW9328XQNR,
};
struct aw_fw_data_info {
const uint8_t *data_start_offset;
uint32_t update_data_len;
uint32_t fw_version;
};
struct aw_update_chip_diff {
uint16_t fwver_reg_addr;
//uint16_t wst_reg_addr;
uint16_t cmd_reg_addr;
uint32_t cmd_sleep_mode;
enum chip_select_flag chip_flag;
};
struct aw_fw_info {
uint32_t single_wr_len;
const struct aw_flash_update_info *flash_info;
};
struct aw_update_para {
uint8_t direct_update_flag; //Upgrade without comparing version numbers
const struct aw_update_chip_diff *aw_update_diff; //Differences in chip updates
};
struct aw_update_fw {
struct aw_fw_info *fw_info;
struct aw_update_para *update_para;
struct aw_fw_data_info *fw_data_info; //Firmware information
};
struct aw_update_common {
uint8_t update_flag;
const uint8_t *w_bin_offset;
uint32_t update_data_len;
const struct aw_flash_update_info *flash_info;
};
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,14 @@
#ifndef __AW_UPDATE_FW_INTERFAACE_H_
#define __AW_UPDATE_FW_INTERFAACE_H_
#define AW_SAR_I2C_TYPE struct i2c_client *
int32_t aw9620x_prot_update_fw(AW_SAR_I2C_TYPE i2c, uint8_t direct_update_flag,
const uint8_t *data_start_offset, uint32_t update_data_len ,uint32_t fw_version);
int32_t aw9620x_reg_update_fw(AW_SAR_I2C_TYPE i2c,
const uint8_t *data_start_offset, uint32_t update_data_len);
int32_t aw9620x_reg_update_boot(AW_SAR_I2C_TYPE i2c,
const uint8_t *data_start_offset, uint32_t update_data_len);
#endif