mcu_hi3321_watch/application/audio/vendor/aw88166/aw883xx.c
2025-05-26 20:15:20 +08:00

2048 lines
48 KiB
C

/*
* aw883xx.c aw883xx codec driver
*
* Copyright (c) 2021 AWINIC Technology CO., LTD
*
* Author: <zhaolei@awinic.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "aw883xx.h"
#include "aw883xx_base.h"
#include "aw883xx_device.h"
#include "aw883xx_init.h"
#include "aw883xx_calib.h"
#define AW883XX_DRIVER_VERSION "v0.4.0"
#define AW883xx_I2C_NAME "aw883xx_smartpa"
#define AW_READ_CHIPID_RETRIES 5 /* 5 times */
unsigned int g_aw883xx_dev_cnt = 0;
struct aw883xx *g_aw883xx[AW_DEV_MAX];
/******************************************************
*
* aw883xx i2c write/read
*
******************************************************/
int aw883xx_i2c_writes(struct aw883xx *aw883xx,
uint8_t reg_addr, uint8_t *buf, uint16_t len)
{
int ret = -1;
ret = aw883xx->i2c_write_func(aw883xx->i2c_addr, reg_addr, buf, len);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error");
}
return ret;
}
static int aw883xx_i2c_reads(struct aw883xx *aw883xx,
uint8_t reg_addr, uint8_t *data_buf, uint16_t data_len)
{
int ret = -1;
ret = aw883xx->i2c_read_func(aw883xx->i2c_addr, reg_addr, data_buf, data_len);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c read error");
}
return ret;
}
int aw883xx_i2c_write(struct aw883xx *aw883xx,
uint8_t reg_addr, uint16_t reg_data)
{
int ret = -1;
uint8_t cnt = 0;
uint8_t buf[2] = {0};
buf[0] = (reg_data & 0xff00) >> 8;
buf[1] = (reg_data & 0x00ff) >> 0;
while (cnt < AW_I2C_RETRIES) {
ret = aw883xx_i2c_writes(aw883xx, reg_addr, buf, 2);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c_write cnt=%d error=%d",
cnt, ret);
} else {
break;
}
cnt++;
}
if (aw883xx->i2c_log_en) {
aw_dev_info(aw883xx->dev, "write: reg = 0x%02x, val = 0x%04x",
reg_addr, reg_data);
}
return ret;
}
int aw883xx_i2c_read(struct aw883xx *aw883xx,
uint8_t reg_addr, uint16_t *reg_data)
{
int ret = -1;
uint8_t cnt = 0;
uint8_t buf[2] = {0};
while (cnt < AW_I2C_RETRIES) {
ret = aw883xx_i2c_reads(aw883xx, reg_addr, buf, 2);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c_read cnt=%d error=%d",
cnt, ret);
} else {
*reg_data = (buf[0] << 8) | (buf[1] << 0);
break;
}
cnt++;
}
if (aw883xx->i2c_log_en) {
aw_dev_info(aw883xx->dev, "read: reg = 0x%02x, val = 0x%04x",
reg_addr, *reg_data);
}
return ret;
}
static int aw883xx_i2c_write_bits(struct aw883xx *aw883xx,
uint8_t reg_addr, uint16_t mask,
uint16_t reg_data)
{
int ret = -1;
uint16_t reg_val = 0;
ret = aw883xx_i2c_read(aw883xx, reg_addr, &reg_val);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c read error, ret=%d", ret);
return ret;
}
reg_val &= mask;
reg_val |= reg_data & (~mask);
ret = aw883xx_i2c_write(aw883xx, reg_addr, reg_val);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c read error, ret=%d", ret);
return ret;
}
return 0;
}
int aw883xx_reg_write(struct aw883xx *aw883xx,
uint8_t reg_addr, uint16_t reg_data)
{
int ret = -1;
aw_mutex_lock();
ret = aw883xx_i2c_write(aw883xx, reg_addr, reg_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev,
"write fail, reg = 0x%02x, val = 0x%04x, ret=%d",
reg_addr, reg_data, ret);
}
aw_mutex_unlock();
return ret;
}
int aw883xx_reg_read(struct aw883xx *aw883xx,
uint8_t reg_addr, uint16_t *reg_data)
{
int ret = -1;
aw_mutex_lock();
ret = aw883xx_i2c_read(aw883xx, reg_addr, reg_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev,
"read fail: reg = 0x%02x, val = 0x%04x, ret=%d",
reg_addr, *reg_data, ret);
}
aw_mutex_unlock();
return ret;
}
int aw883xx_reg_write_bits(struct aw883xx *aw883xx,
uint8_t reg_addr, uint16_t mask, uint16_t reg_data)
{
int ret = -1;
aw_mutex_lock();
ret = aw883xx_i2c_write_bits(aw883xx, reg_addr, mask, reg_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev,
"aw883xx_reg_write_bits fail, ret=%d", ret);
}
aw_mutex_unlock();
return ret;
}
static int aw883xx_dsp_write_16bit(struct aw883xx *aw883xx,
uint16_t dsp_addr, uint32_t dsp_data)
{
int ret = -1;
struct aw_dsp_mem_desc *desc = &aw883xx->aw_pa->dsp_mem_desc;
ret = aw883xx_i2c_write(aw883xx, desc->dsp_madd_reg, dsp_addr);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
ret = aw883xx_i2c_write(aw883xx, desc->dsp_mdat_reg, (uint16_t)dsp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
return 0;
}
static int aw883xx_dsp_write_32bit(struct aw883xx *aw883xx,
uint16_t dsp_addr, uint32_t dsp_data)
{
int ret = -1;
uint16_t temp_data = 0;
struct aw_dsp_mem_desc *desc = &aw883xx->aw_pa->dsp_mem_desc;
ret = aw883xx_i2c_write(aw883xx, desc->dsp_madd_reg, dsp_addr);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
temp_data = dsp_data & AW883XX_DSP_16_DATA_MASK;
ret = aw883xx_i2c_write(aw883xx, desc->dsp_mdat_reg, temp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
temp_data = dsp_data >> 16;
ret = aw883xx_i2c_write(aw883xx, desc->dsp_mdat_reg, temp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
return 0;
}
/******************************************************
* aw883xx clear dsp chip select state
******************************************************/
int aw883xx_get_version(char *buf, int size)
{
if (size > strlen(AW883XX_DRIVER_VERSION)) {
memcpy(buf, AW883XX_DRIVER_VERSION, strlen(AW883XX_DRIVER_VERSION));
return strlen(AW883XX_DRIVER_VERSION);
} else {
return -ENOMEM;
}
}
static void aw883xx_clear_dsp_sel_st(struct aw883xx *aw883xx)
{
uint16_t reg_value;
uint8_t reg = aw883xx->aw_pa->soft_rst.reg;
aw883xx_i2c_read(aw883xx, reg, &reg_value);
}
int aw883xx_dsp_write(struct aw883xx *aw883xx,
uint16_t dsp_addr, uint32_t dsp_data, uint8_t data_type)
{
int ret = -1;
aw_mutex_lock();
if (data_type == AW_DSP_16_DATA) {
ret = aw883xx_dsp_write_16bit(aw883xx, dsp_addr, dsp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "write dsp_addr[0x%04x] 16 bit dsp_data[%04x] failed",
(uint32_t)dsp_addr, dsp_data);
goto exit;
}
} else if (data_type == AW_DSP_32_DATA) {
ret = aw883xx_dsp_write_32bit(aw883xx, dsp_addr, dsp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "write dsp_addr[0x%04x] 32 bit dsp_data[%08x] failed",
(uint32_t)dsp_addr, dsp_data);
goto exit;
}
} else {
aw_dev_err(aw883xx->dev, "data type[%d] unsupported", data_type);
ret = -EINVAL;
goto exit;
}
exit:
aw883xx_clear_dsp_sel_st(aw883xx);
aw_mutex_unlock();
return ret;
}
static int aw883xx_dsp_read_16bit(struct aw883xx *aw883xx,
uint16_t dsp_addr, uint32_t *dsp_data)
{
int ret = -1;
uint16_t temp_data = 0;
struct aw_dsp_mem_desc *desc = &aw883xx->aw_pa->dsp_mem_desc;
ret = aw883xx_i2c_write(aw883xx, desc->dsp_madd_reg, dsp_addr);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
ret = aw883xx_i2c_read(aw883xx, desc->dsp_mdat_reg, &temp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
*dsp_data = temp_data;
return 0;
}
static int aw883xx_dsp_read_32bit(struct aw883xx *aw883xx,
uint16_t dsp_addr, uint32_t *dsp_data)
{
int ret = -1;
uint16_t temp_data = 0;
struct aw_dsp_mem_desc *desc = &aw883xx->aw_pa->dsp_mem_desc;
/*write dsp addr*/
ret = aw883xx_i2c_write(aw883xx, desc->dsp_madd_reg, dsp_addr);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c write error, ret=%d", ret);
return ret;
}
/*get Low 16 bit data*/
ret = aw883xx_i2c_read(aw883xx, desc->dsp_mdat_reg, &temp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c read error, ret=%d", ret);
return ret;
}
*dsp_data = temp_data;
/*get high 16 bit data*/
ret = aw883xx_i2c_read(aw883xx, desc->dsp_mdat_reg, &temp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "i2c read error, ret=%d", ret);
return ret;
}
*dsp_data |= (temp_data << 16);
return 0;
}
int aw883xx_dsp_read(struct aw883xx *aw883xx,
uint16_t dsp_addr, uint32_t *dsp_data, uint8_t data_type)
{
int ret = -1;
aw_mutex_lock();
if (data_type == AW_DSP_16_DATA) {
ret = aw883xx_dsp_read_16bit(aw883xx, dsp_addr, dsp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "read dsp_addr[0x%04x] 16 bit dsp_data[%04x] failed",
(uint32_t)dsp_addr, *dsp_data);
goto exit;
}
} else if (data_type == AW_DSP_32_DATA) {
ret = aw883xx_dsp_read_32bit(aw883xx, dsp_addr, dsp_data);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "read dsp_addr[0x%04x] 32 bit dsp_data[%08x] failed",
(uint32_t)dsp_addr, *dsp_data);
goto exit;
}
} else {
aw_dev_err(aw883xx->dev, "data type[%d] unsupported", data_type);
ret = -EINVAL;
goto exit;
}
exit:
aw883xx_clear_dsp_sel_st(aw883xx);
aw_mutex_unlock();
return ret;
}
int aw883xx_dsp_write_bits(struct aw883xx *aw883xx, uint16_t dsp_addr,
uint32_t dsp_mask, uint32_t dsp_data, uint8_t data_type)
{
int ret = -1;
uint32_t read_val = 0;
uint32_t write_val = 0;
aw_mutex_lock();
if (data_type == AW_DSP_16_DATA) {
ret = aw883xx_dsp_read_16bit(aw883xx, dsp_addr, &read_val);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "read dsp_addr[0x%04x] 16 bit dsp_data[%04x] failed",
(uint32_t)dsp_addr, read_val);
goto exit;
}
} else if (data_type == AW_DSP_32_DATA) {
ret = aw883xx_dsp_read_32bit(aw883xx, dsp_addr, &read_val);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "read dsp_addr[0x%04x] 32 bit dsp_data[%08x] failed",
(uint32_t)dsp_addr, read_val);
goto exit;
}
}
write_val = read_val & dsp_mask;
write_val |= dsp_data & (~dsp_mask);
if (data_type == AW_DSP_16_DATA) {
ret = aw883xx_dsp_write_16bit(aw883xx, dsp_addr, write_val);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "write dsp_addr[0x%04x] 16 bit dsp_data[%04x] failed",
(uint32_t)dsp_addr, write_val);
goto exit;
}
} else if (data_type == AW_DSP_32_DATA) {
ret = aw883xx_dsp_write_32bit(aw883xx, dsp_addr, write_val);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "write dsp_addr[0x%04x] 32 bit dsp_data[%08x] failed",
(uint32_t)dsp_addr, write_val);
goto exit;
}
}
exit:
aw883xx_clear_dsp_sel_st(aw883xx);
aw_mutex_unlock();
return ret;
}
/******************************************************
* aw883xx interface
******************************************************/
int aw883xx_get_dev_num(void)
{
return g_aw883xx_dev_cnt;
}
struct aw883xx *aw883xx_get_dev(uint8_t dev)
{
return g_aw883xx[dev];
}
static void aw883xx_start_pa(struct aw883xx *aw883xx)
{
int ret = -1;
int i;
aw_dev_info(aw883xx->dev, "enter");
if (aw883xx->allow_pw == false) {
aw_dev_info(aw883xx->dev, "dev can not allow power");
return;
}
if (aw883xx->pstream == AW_STREAM_CLOSE) {
aw_dev_info(aw883xx->dev, "pstream is close");
return;
}
for (i = 0; i < AW_START_RETRIES; i++) {
ret = aw883xx_device_start(aw883xx->aw_pa);
if (ret) {
aw_dev_err(aw883xx->dev, "start failed");
ret = aw883xx_device_fw_update(aw883xx->aw_pa, AW_DSP_FW_UPDATE_ON, true);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "fw update failed");
continue;
}
} else {
aw_dev_info(aw883xx->dev, "start success");
break;
}
}
}
static void aw883xx_start(struct aw883xx *aw883xx)
{
int ret = -1;
int i;
bool sync_start = 0;
aw_dev_info(aw883xx->dev,"enter");
if (aw883xx->aw_pa->fw_status == AW_DEV_FW_OK) {
if (aw883xx->allow_pw == false) {
aw_dev_info(aw883xx->dev, "dev can not allow power");
return;
}
if (aw883xx->aw_pa->status == AW_DEV_PW_ON) {
aw_dev_info(aw883xx->dev, "pa already start");
return;
}
for (i = 0; i < AW_START_RETRIES; i++) {
ret = aw883xx_device_fw_update(aw883xx->aw_pa, AW_DSP_FW_UPDATE_OFF,
aw883xx->phase_sync);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "fw update failed");
continue;
} else {
if (sync_start == AW_SYNC_START) {
aw883xx_start_pa(aw883xx);
}
return;
}
}
}
}
static void aw883xx_stop_pa(struct aw883xx *aw883xx)
{
aw883xx_device_stop(aw883xx->aw_pa);
}
static int aw883xx_hw_reset(struct aw883xx *aw883xx)
{
aw_dev_info(aw883xx->dev, "enter");
aw883xx->reset_gpio_ctl(AW_PIN_RESET);
aw_dev_info(aw883xx->dev, "gpio_ctl=%d", AW_PIN_RESET);
AW_MS_DELAY(1);
aw883xx->reset_gpio_ctl(AW_PIN_SET);
aw_dev_info(aw883xx->dev, "gpio_ctl=%d", AW_PIN_SET);
AW_MS_DELAY(2);
return 0;
}
#ifdef AW_DEBUG
int aw883xx_hw_reset_by_index(aw_dev_index_t dev)
{
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx_hw_reset(g_aw883xx[dev]);
return 0;
}
int aw883xx_soft_reset(aw_dev_index_t dev)
{
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx_device_status(g_aw883xx[dev]->aw_pa, AW_DEV_SOFT_RESET_STATUS, AW_SET_DEV_STATUS);
return 0;
}
int aw883xx_reg_store(aw_dev_index_t dev, uint8_t reg_addr, uint16_t reg_data)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_err("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
aw883xx_i2c_write(aw883xx, reg_addr, reg_data);
return 0;
}
int aw883xx_reg_show(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
aw883xx_device_status(aw883xx->aw_pa, AW_DEV_REG_DUMP_STATUS, AW_SET_DEV_STATUS);
return 0;
}
static int aw883xx_dsp_log_info(struct aw883xx *aw883xx, unsigned int base_addr,
uint32_t data_len, char *format)
{
uint16_t reg_val = 0;
char *dsp_reg_info = NULL;
uint32_t dsp_info_len = 0;
int i;
dsp_reg_info = calloc(1, AW_NAME_BUF_MAX);
if (dsp_reg_info == NULL) {
aw_dev_err(aw883xx->dev, "dsp_reg_info calloc failed");
return -1;
}
aw_mutex_lock();
aw883xx_i2c_write(aw883xx, aw883xx->aw_pa->dsp_mem_desc.dsp_madd_reg, base_addr);
for (i = 0; i < data_len; i+=2) {
aw883xx_i2c_read(aw883xx, aw883xx->aw_pa->dsp_mem_desc.dsp_mdat_reg, &reg_val);
dsp_info_len += snprintf(dsp_reg_info + dsp_info_len, AW_NAME_BUF_MAX - dsp_info_len,
"%02x,%02x,", (reg_val >> 0) & 0xff,
(reg_val >> 8) & 0xff);
if ((i / 2 + 1) % 8 == 0) {
aw_dev_info(aw883xx->dev, "%s: %s", format, dsp_reg_info);
dsp_info_len = 0;
memset(dsp_reg_info, 0, AW_NAME_BUF_MAX);
}
if (((data_len) % 8 != 0) &&
(i == (data_len - 2))) {
aw_dev_info(aw883xx->dev, "%s: %s", format, dsp_reg_info);
dsp_info_len = 0;
memset(dsp_reg_info, 0, AW_NAME_BUF_MAX);
}
}
dsp_info_len = 0;
memset(dsp_reg_info, 0, AW_NAME_BUF_MAX);
free(dsp_reg_info);
dsp_reg_info = NULL;
aw_mutex_unlock();
return 0;
}
int aw883xx_dsp_info_show(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
struct aw_dsp_st *dsp_st_desc = NULL;
uint32_t data_len;
bool status = false;
int ret = -1;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
dsp_st_desc = &aw883xx->aw_pa->dsp_st_desc;
if (aw883xx->aw_pa->dsp_cfg == AW_DEV_DSP_BYPASS) {
aw_dev_info(aw883xx->dev, "dsp bypass");
} else {
aw_dev_info(aw883xx->dev, "dsp working");
status = aw883xx_device_status(aw883xx->aw_pa, AW_DEV_PLL_WDT_STATUS,
AW_GET_DEV_STATUS);
if (!status) {
aw_dev_err(aw883xx->dev, "PA status abnormal");
return -EINVAL;
}
aw_dev_info(aw883xx->dev, "dsp_firmware_len:%d", aw883xx->aw_pa->dsp_fw_len);
ret = aw883xx_dsp_log_info(aw883xx, aw883xx->aw_pa->dsp_mem_desc.dsp_fw_base_addr,
aw883xx->aw_pa->dsp_fw_len, "dsp_fw");
if (ret < 0) {
aw_dev_err(aw883xx->dev, "dsp_fw display failed");
return -EINVAL;
}
aw_dev_info(aw883xx->dev, "dsp_config_len:%d", aw883xx->aw_pa->dsp_cfg_len);
ret = aw883xx_dsp_log_info(aw883xx, aw883xx->aw_pa->dsp_mem_desc.dsp_cfg_base_addr,
aw883xx->aw_pa->dsp_cfg_len, "dsp_config");
if (ret < 0) {
aw_dev_err(aw883xx->dev, "dsp_config display failed");
return -EINVAL;
}
aw_dev_info(aw883xx->dev, "dsp_config:0x%04x-0x%04x",
dsp_st_desc->dsp_reg_s1, dsp_st_desc->dsp_reg_e1);
data_len = 2 * (dsp_st_desc->dsp_reg_e1 - dsp_st_desc->dsp_reg_s1);
ret = aw883xx_dsp_log_info(aw883xx, dsp_st_desc->dsp_reg_s1,
data_len, "dsp_st");
if (ret < 0) {
aw_dev_err(aw883xx->dev, "dsp_config:0x%04x-0x%04x display failed",
dsp_st_desc->dsp_reg_s1, dsp_st_desc->dsp_reg_e1);
return -EINVAL;
}
aw_dev_info(aw883xx->dev, "dsp_config:0x%04x-0x%04x",
dsp_st_desc->dsp_reg_s2, dsp_st_desc->dsp_reg_e2);
data_len = 2 * (dsp_st_desc->dsp_reg_e2 - dsp_st_desc->dsp_reg_s2);
ret = aw883xx_dsp_log_info(aw883xx, dsp_st_desc->dsp_reg_s2,
data_len , "dsp_st");
if (ret < 0) {
aw_dev_err(aw883xx->dev, "dsp_config:0x%04x-0x%04x display failed",
dsp_st_desc->dsp_reg_s2, dsp_st_desc->dsp_reg_e2);
return -EINVAL;
}
}
return 0;
}
#endif
#ifdef AW_FADE
static int aw883xx_dev_set_fade_vol_step(struct aw883xx *aw883xx, uint32_t step)
{
int ret = -1;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
ret = aw883xx_device_params(aw_dev, AW_DEV_FADE_STEP_PARAMS,
(void *)&step, msg_len, AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "write_params failed");
return ret;
}
return 0;
}
static int aw883xx_dev_get_fade_vol_step(struct aw883xx *aw883xx, uint32_t *step)
{
int ret = -1;
int step_val = 0;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
if (step == NULL) {
aw_pr_err("step is NULL");
return -EINVAL;
}
ret = aw883xx_device_params(aw_dev, AW_DEV_FADE_STEP_PARAMS,
(void *)&step_val, msg_len, AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "read_params failed");
return ret;
}
*step = step_val;
return 0;
}
static int aw883xx_dev_set_fade_in_time(struct aw883xx *aw883xx, uint32_t time)
{
int ret = -1;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
ret = aw883xx_device_params(aw_dev, AW_DEV_FADE_IN_TIME_PARAMS,
(void *)&time, msg_len, AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "write_params failed");
return ret;
}
return 0;
}
static int aw883xx_dev_get_fade_in_time(struct aw883xx *aw883xx, uint32_t *time)
{
int ret = -1;
int time_val = 0;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
if (time == NULL) {
aw_pr_err("time is NULL");
return -EINVAL;
}
ret = aw883xx_device_params(aw_dev, AW_DEV_FADE_IN_TIME_PARAMS,
(void *)&time_val, msg_len, AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "read_params failed");
return ret;
}
*time = time_val;
return 0;
}
static int aw883xx_dev_set_fade_out_time(struct aw883xx *aw883xx, uint32_t time)
{
int ret = -1;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
ret = aw883xx_device_params(aw_dev, AW_DEV_FADE_OUT_TIME_PARAMS,
(void *)&time, msg_len, AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "write_params failed");
return ret;
}
return 0;
}
static int aw883xx_dev_get_fade_out_time(struct aw883xx *aw883xx, uint32_t *time)
{
int ret = -1;
int time_val = 0;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
if (time == NULL) {
aw_pr_err("time is NULL");
return -EINVAL;
}
ret = aw883xx_device_params(aw_dev, AW_DEV_FADE_OUT_TIME_PARAMS,
(void *)&time_val, msg_len, AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "read_params failed");
return ret;
}
*time = time_val;
return 0;
}
int aw883xx_set_fade_step(aw_dev_index_t dev, uint32_t step)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
aw883xx_dev_set_fade_vol_step(aw883xx, step);
aw_dev_info(aw883xx->dev, "set step %d DB Done", step);
return 0;
}
int aw883xx_get_fade_step(aw_dev_index_t dev, uint32_t *step)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if ((g_aw883xx[dev] == NULL) || (step == NULL)) {
aw_pr_err("g_aw883xx[%d] is NULL or step is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
aw883xx_dev_get_fade_vol_step(aw883xx, step);
aw_dev_info(aw883xx->dev, "get step %d Done", *step);
return 0;
}
int aw883xx_set_fade_time(aw_fade_dir_t fade_dir, uint32_t time)
{
struct aw883xx *aw883xx = NULL;
if (g_aw883xx[AW_DEV_0] == NULL) {
aw_pr_err("g_aw883xx[%d] is NULL or step is NULL", AW_DEV_0);
return -EINVAL;
}
aw883xx = g_aw883xx[AW_DEV_0];
if (fade_dir == AW_FADE_IN) {
aw883xx_dev_set_fade_in_time(aw883xx, time);
} else if (fade_dir == AW_FADE_OUT){
aw883xx_dev_set_fade_out_time(aw883xx, time);
} else {
aw_dev_err(aw883xx->dev, "unsupported fade type %d", fade_dir);
}
return 0;
}
int aw883xx_get_fade_time(aw_fade_dir_t fade_dir, uint32_t *time)
{
struct aw883xx *aw883xx = NULL;
if ((g_aw883xx[AW_DEV_0] == NULL) || (time == NULL)) {
aw_pr_err("g_aw883xx[%d] is NULL or step is NULL", AW_DEV_0);
return -EINVAL;
}
aw883xx = g_aw883xx[AW_DEV_0];
if (fade_dir == AW_FADE_IN) {
aw883xx_dev_get_fade_in_time(aw883xx, time);
} else if (fade_dir == AW_FADE_OUT){
aw883xx_dev_get_fade_out_time(aw883xx, time);
} else {
aw_dev_err(aw883xx->dev, "unsupported fade type %d", fade_dir);
}
return 0;
}
#endif
#ifdef AW_VOLUME
static int aw883xx_dev_get_volume(struct aw883xx *aw883xx, uint32_t *volume)
{
int ret = -1;
int vol_val = 0;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
if (volume == NULL) {
aw_pr_err("volume is NULL");
return -EINVAL;
}
ret = aw883xx_device_params(aw_dev, AW_DEV_VOLUME_PARAMS,
(void *)&vol_val, msg_len, AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "read_params failed");
return ret;
}
*volume = vol_val;
return 0;
}
static int aw883xx_dev_set_volume(struct aw883xx *aw883xx, uint32_t volume)
{
int ret = -1;
uint32_t compared_vol = 0;
uint32_t msg_len = sizeof(uint32_t);
struct aw_device *aw_dev = aw883xx->aw_pa;
struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
vol_desc->ctl_volume = volume;
/*get smaller dB*/
compared_vol = AW_GET_MAX_VALUE(vol_desc->ctl_volume,
vol_desc->monitor_volume);
ret = aw883xx_device_params(aw_dev, AW_DEV_VOLUME_PARAMS,
(void *)&compared_vol, msg_len, AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "write_params failed");
return ret;
}
return 0;
}
int aw883xx_get_volume(aw_dev_index_t dev, uint32_t *volume)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if ((g_aw883xx[dev] == NULL) || (volume == NULL)) {
aw_pr_err("g_aw883xx[%d] is NULL or volume is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
aw883xx_dev_get_volume(aw883xx, volume);
aw_dev_info(aw883xx->dev, "get volume %d", *volume);
return 0;
}
int aw883xx_set_volume(aw_dev_index_t dev, uint32_t volume)
{
struct aw883xx *aw883xx = NULL;
int ret = -1;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_err("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
ret = aw883xx_dev_set_volume(aw883xx, volume);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "set volume failed");
return ret;
}
aw_dev_info(aw883xx->dev, "set volume %d", volume);
return 0;
}
#endif
int aw883xx_ctrl_state(aw_dev_index_t dev, aw_ctrl_t aw_ctrl)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_err("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (aw_ctrl) {
aw883xx->pstream = AW_STREAM_CLOSE;
aw883xx_stop_pa(aw883xx);
} else {
aw883xx->pstream = AW_STREAM_OPEN;
aw883xx_start(aw883xx);
}
return 0;
}
int aw883xx_set_profile_byname(aw_dev_index_t dev, char *prof_name)
{
int ret = -1;
char *cur_name = NULL;
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_err("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
cur_name = aw883xx_dev_get_profile_name(aw883xx->aw_pa);
if (strncmp(cur_name, prof_name, AW_PROF_NAME_MAX) == 0) {
aw_dev_info(aw883xx->dev, "profile no change");
return 0;
}
ret = aw883xx_dev_set_profile_name(aw883xx->aw_pa, prof_name);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "set profile [%s] failed", prof_name);
return -EINVAL;
}
aw_dev_info(aw883xx->dev, "set prof name %s", prof_name);
return 0;
}
static int aw883xx_check_init_info(struct aw_init_info *init_info)
{
int ret = -1;
/*check dev index*/
if (init_info->dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", init_info->dev);
return -EINVAL;
}
if (g_aw883xx[init_info->dev] != NULL) {
aw_pr_err("dev:%d exist", init_info->dev);
return -EINVAL;
}
/*check i2c funtion*/
if ((init_info->i2c_read_func == NULL) ||
(init_info->i2c_write_func == NULL)) {
aw_dev_err(init_info->dev, "i2c funtion is NULL");
return -EINVAL;
}
ret = aw883xx_dev_check_prof(init_info->dev, init_info->prof_info);
if (ret < 0) {
aw_dev_err(init_info->dev, "check prof failed");
return ret;
}
return 0;
}
static struct aw883xx *aw883xx_malloc_init(struct aw_init_info *init_info)
{
struct aw883xx *aw883xx = calloc(1, sizeof(struct aw883xx));
if (aw883xx == NULL) {
aw_dev_err(init_info->dev, "calloc aw883xx failed.");
return NULL;
}
aw883xx->init_info = init_info;
aw883xx->aw_pa = NULL;
aw883xx->dev = init_info->dev;
aw883xx->i2c_addr = init_info->i2c_addr;
aw883xx->i2c_read_func = init_info->i2c_read_func;
aw883xx->i2c_write_func = init_info->i2c_write_func;
if (init_info->phase_sync) {
aw883xx->phase_sync = init_info->phase_sync;
} else {
aw883xx->phase_sync = AW_PHASE_SYNC_DISABLE;
}
if (init_info->reset_gpio_ctl) {
aw883xx->reset_gpio_ctl = init_info->reset_gpio_ctl;
} else {
aw883xx->reset_gpio_ctl = NULL;
}
aw883xx->allow_pw = true;
aw883xx->i2c_log_en = false;
return aw883xx;
}
static int aw883xx_read_chipid(struct aw883xx *aw883xx)
{
int ret = -1;
unsigned int cnt = 0;
uint16_t reg_value = 0;
while (cnt < AW_READ_CHIPID_RETRIES) {
ret = aw883xx_i2c_read(aw883xx, AW883xx_CHIP_ID_REG, &reg_value);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "failed to read REG_ID: %d", ret);
return -EIO;
}
switch (reg_value) {
case PID_2049_ID: {
aw_dev_info(aw883xx->dev, "aw883xx 2049 detected");
aw883xx->chip_id = reg_value;
return 0;
}
case PID_2066_ID: {
aw_dev_info(aw883xx->dev, "aw883xx 2066 detected");
aw883xx->chip_id = reg_value;
return 0;
}
case PID_2183_ID: {
aw_dev_info(aw883xx->dev, "aw883xx 2183 detected");
aw883xx->chip_id = reg_value;
return 0;
}
default:
aw_dev_info(aw883xx->dev, "unsupported device revision (0x%x)",
reg_value);
break;
}
cnt++;
AW_MS_DELAY(AW_READ_CHIPID_RETRY_DELAY);
}
return -EINVAL;
}
static int aw883xx_init(struct aw883xx *aw883xx)
{
int i = 0;
int ret;
struct aw_init_info *init_info = aw883xx->init_info;
for (i = 0; i < init_info->mix_chip_count; i++) {
aw_dev_dbg(aw883xx->dev, "%d enter", i);
if (init_info->dev_init_ops[i] == NULL) {
aw_dev_err(aw883xx->dev, "init_info->dev_init_ops[%d] is null", i);
return -EINVAL;
}
ret = init_info->dev_init_ops[i]((void *)aw883xx);
if (ret < 0) {
aw_dev_dbg(aw883xx->dev, "%d enter", i);
continue;
} else {
aw_dev_dbg(aw883xx->dev, "%d init success", i);
break;
}
}
return ret;
}
int aw883xx_smartpa_init(void *aw_info)
{
int ret = -1;
struct aw_init_info *aw_init_info = NULL;
struct aw883xx *aw883xx = NULL;
aw_pr_info("enter");
if (aw_info == NULL) {
aw_pr_err("aw_info is NULL");
return -ENOMEM;
}
aw_init_info = (struct aw_init_info *)aw_info;
ret = aw883xx_check_init_info(aw_init_info);
if (ret < 0) {
return ret;
}
aw883xx = aw883xx_malloc_init(aw_init_info);
if (aw883xx == NULL) {
aw_dev_err(aw_init_info->dev, "malloc aw883xx failed");
return -ENOMEM;
}
/* hardware reset */
aw883xx_hw_reset(aw883xx);
/* aw883xx chip id */
ret = aw883xx_read_chipid(aw883xx);
if (ret < 0) {
aw_dev_err(aw_init_info->dev, "aw883xx_read_chipid failed ret=%d", ret);
goto read_chip_failed;
}
/*aw pa init*/
ret = aw883xx_init(aw883xx);
if (ret) {
goto init_failed;
}
aw883xx->aw_pa->status = AW_DEV_PW_OFF;
aw883xx->aw_pa->fw_status = AW_DEV_FW_OK;
if (aw_init_info->fade_en) {
aw883xx->aw_pa->fade_en = aw_init_info->fade_en;
} else {
aw883xx->aw_pa->fade_en = AW_FADE_DISABLE;
}
if (aw_init_info->re_min) {
aw883xx->aw_pa->re_range.re_min = aw_init_info->re_min;
} else {
aw883xx->aw_pa->re_range.re_min = AW_RE_MIN;
}
if (aw_init_info->re_max) {
aw883xx->aw_pa->re_range.re_max = aw_init_info->re_max;
} else {
aw883xx->aw_pa->re_range.re_max = AW_RE_MAX;
}
if (aw_init_info->cali_check_st) {
aw883xx->aw_pa->cali_desc.cali_check_st = aw_init_info->cali_check_st;
} else {
aw883xx->aw_pa->cali_desc.cali_check_st = CALI_CHECK_DISABLE;
}
aw883xx->aw_pa->cali_desc.cali_result = CALI_RESULT_NONE;
g_aw883xx[aw_init_info->dev] = aw883xx;
g_aw883xx_dev_cnt++;
aw_dev_info(aw_init_info->dev, "dev:%d init success",
aw_init_info->dev);
return 0;
init_failed:
read_chip_failed:
free(aw883xx);
aw883xx = NULL;
return ret;
}
void aw883xx_smartpa_deinit(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev_index:%d", dev);
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
}
aw883xx = g_aw883xx[dev];
if (aw883xx->aw_pa->ops.aw_monitor_deinit != NULL) {
aw883xx->aw_pa->ops.aw_monitor_deinit((void *)aw883xx->aw_pa);
}
if (aw883xx->aw_pa != NULL) {
free(aw883xx->aw_pa);
aw883xx->aw_pa = NULL;
}
if (aw883xx != NULL) {
free(aw883xx);
aw883xx = NULL;
}
}
int aw883xx_dsp_bypass_ctrl(aw_dev_index_t dev, aw_dsp_ctrl_t dsp_ctrl)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_err("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_err("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dsp_ctrl) {
aw883xx->aw_pa->dsp_cfg = AW_DEV_DSP_BYPASS;
} else {
aw883xx->aw_pa->dsp_cfg = AW_DEV_DSP_WORK;
}
return 0;
}
/***************************************************************************
*aw883xx irq
***************************************************************************/
#ifdef AW_IRQ
aw_hw_irq_handle_t aw883xx_get_hw_irq_status(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
}
aw883xx = g_aw883xx[dev];
aw_dev_info(aw883xx->dev, "irq_handle=%d", aw883xx->irq_handle);
return aw883xx->irq_handle;
}
void aw883xx_irq_handler(aw_dev_index_t dev)
{
int ret = -1;
uint32_t crc_switch_status = 0;
uint32_t crc_check_abnormal = 0;
uint32_t mask_value = AW_DEV_UNMASK_INT_VAL;
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return;
}
aw883xx = g_aw883xx[dev];
if (aw883xx->irq_handle == AW_HW_IRQ_HANDLE_ON){
/*awinic:Add operations after interrupt triggering*/
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_REALTIME_CRC_GET_PARAMS,
(void *)&crc_switch_status, sizeof(crc_switch_status), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "get crc_status failed");
}
if (crc_switch_status) {
ret = aw883xx_crc_realtime_check(aw883xx->aw_pa, &crc_check_abnormal);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "crc_realtime_check failed");
}
if (crc_check_abnormal) {
/*pa stop or stopping just set profile*/
if (aw883xx->pstream) {
aw883xx_device_stop(aw883xx->aw_pa);
ret = aw883xx_device_fw_update(aw883xx->aw_pa, AW_DSP_FW_UPDATE_ON, true);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "fw update failed");
}
aw883xx_start(aw883xx);
}
}
}
aw883xx_device_status(aw883xx->aw_pa, AW_DEV_INTERRUPT_CLEAR_STATUS,
AW_SET_DEV_STATUS);
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_INT_PARAMS,
(void *)&mask_value, sizeof(mask_value), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "write_params failed");
}
aw883xx->irq_handle = AW_HW_IRQ_HANDLE_OFF;
aw_dev_info(aw883xx->dev, "irq_handle=%d",aw883xx->irq_handle);
}
}
void aw883xx_irq_trigger(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return;
}
aw883xx = g_aw883xx[dev];
aw883xx->irq_handle = AW_HW_IRQ_HANDLE_ON;
aw_dev_info(aw883xx->dev, "irq_handle=%d",aw883xx->irq_handle);
}
#endif
/***********************************************************************
* aw883xx monitor
***********************************************************************/
#ifdef AW_MONITOR
void aw883xx_monitor_work(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return;
}
aw883xx = g_aw883xx[dev];
if (aw883xx->aw_pa->ops.aw_monitor_work_func) {
aw883xx->aw_pa->ops.aw_monitor_work_func((void *)aw883xx->aw_pa);
}
}
void aw883xx_monitor_set_status(aw_dev_index_t dev)
{
struct aw883xx *aw883xx = NULL;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return;
}
aw883xx = g_aw883xx[dev];
if (aw883xx->aw_pa->ops.aw_monitor_set_handle) {
aw883xx->aw_pa->ops.aw_monitor_set_handle((void *)aw883xx->aw_pa);
}
}
#endif
/***********************************************************************
* aw883xx cali
***********************************************************************/
#ifdef AW_CALIB
int aw883xx_cali_re(aw_dev_index_t dev, aw_single_t is_single, uint32_t *re)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr cali_msg = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (re == NULL) {
aw_pr_info("g_aw883xx[%d] re is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (is_single == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_RE_PARAMS,
(void *)&dev_type, sizeof(dev_type), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali re failed");
return ret;
}
cali_msg.opcode_id = is_single;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_RE_PARAMS,
(void *)&cali_msg, sizeof(cali_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali re show failed");
return ret;
}
memcpy(re, &cali_msg.msg, dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_cali_f0(aw_dev_index_t dev, aw_single_t is_single, uint32_t *f0)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr cali_msg = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (f0 == NULL) {
aw_pr_info("g_aw883xx[%d] f0 is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_F0_Q_PARAMS,
(void *)&dev_type, sizeof(dev_type), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali f0 failed");
return ret;
}
cali_msg.opcode_id = is_single;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_F0_PARAMS,
(void *)&cali_msg, sizeof(cali_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali f0 show failed");
return ret;
}
memcpy(f0, &cali_msg.msg, dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_cali_f0_q(aw_dev_index_t dev, aw_single_t is_single, uint32_t *f0, uint32_t *q)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr f0_msg = { 0 };
struct cali_msg_hdr q_msg = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if ((f0 == NULL) || (q == NULL)) {
aw_pr_info("g_aw883xx[%d] f0/q is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_F0_Q_PARAMS,
(void *)&dev_type, sizeof(dev_type), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali f0 failed");
return ret;
}
f0_msg.opcode_id = is_single;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_F0_PARAMS,
(void *)&f0_msg, sizeof(f0_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali f0 show failed");
return ret;
}
memcpy(f0, &f0_msg.msg, dev_cnt * sizeof(uint32_t));
q_msg.opcode_id = is_single;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_Q_PARAMS,
(void *)&q_msg, sizeof(q_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali q show failed");
return ret;
}
memcpy(q, &q_msg.msg, dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_cali_re_f0(aw_dev_index_t dev, aw_single_t is_single, uint32_t *re, uint32_t *f0)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr re_msg = { 0 };
struct cali_msg_hdr f0_msg = { 0 };
uint32_t dev_type = is_single;
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if ((f0 == NULL) || (re == NULL)) {
aw_pr_info("g_aw883xx[%d] f0/re is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_RE_F0_PARAMS,
(void *)&dev_type, sizeof(dev_type), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali re_f0 failed");
return ret;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_RE_PARAMS,
(void *)&re_msg, sizeof(re_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali re show failed");
return ret;
}
memcpy(re, &re_msg.msg, dev_cnt * sizeof(uint32_t));
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_F0_PARAMS,
(void *)&f0_msg, sizeof(f0_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali f0 show failed");
return ret;
}
memcpy(f0, &f0_msg.msg, dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_get_re_range(aw_dev_index_t dev, aw_single_t is_single, uint32_t *range_buf)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr re_range_msg = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (range_buf == NULL) {
aw_pr_info("g_aw883xx[%d] range_buf is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
re_range_msg.opcode_id = dev_type;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_RE_RANGE_PARAMS,
(void *)&re_range_msg, sizeof(re_range_msg), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "get re range failed");
return ret;
}
memcpy(range_buf, &re_range_msg.msg, RE_RANGE_NUM * dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_get_r0(aw_dev_index_t dev, aw_single_t is_single, uint32_t *r0_data)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr msg_hdr = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (r0_data == NULL) {
aw_pr_info("g_aw883xx[%d] r0_data is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
msg_hdr.opcode_id = dev_type;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_R0_PARAMS,
(void *)&msg_hdr, sizeof(msg_hdr), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "get r0 failed");
return ret;
}
memcpy(r0_data, &msg_hdr.msg, dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_get_f0(aw_dev_index_t dev, aw_single_t is_single, uint32_t *f0_data)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr msg_hdr = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (f0_data == NULL) {
aw_pr_info("g_aw883xx[%d] f0_data is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
msg_hdr.opcode_id = dev_type;
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_F0_PARAMS,
(void *)&msg_hdr, sizeof(msg_hdr), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "get r0 failed");
return ret;
}
memcpy(f0_data, &msg_hdr.msg, dev_cnt * sizeof(uint32_t));
return 0;
}
int aw883xx_get_te(aw_dev_index_t dev, aw_single_t is_single, int32_t *te_data)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr msg_hdr = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (te_data == NULL) {
aw_pr_info("g_aw883xx[%d] te_data is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
msg_hdr.opcode_id = is_single;
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_TE_PARAMS,
(void *)&msg_hdr, sizeof(msg_hdr), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "get te failed");
return ret;
}
memcpy(te_data, &msg_hdr.msg, dev_cnt * sizeof(int32_t));
return 0;
}
int aw883xx_cali_re_store(aw_dev_index_t dev, aw_single_t is_single, uint32_t *set_re)
{
struct aw883xx *aw883xx = NULL;
struct cali_msg_hdr msg_hdr = { 0 };
int ret = -1;
int dev_cnt = aw883xx_get_dev_num();
uint32_t dev_type = is_single;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (set_re == NULL) {
aw_pr_info("g_aw883xx[%d] set_re is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
msg_hdr.opcode_id = dev_type;
if (dev_type == IS_SINGLE) {
dev_cnt = AW_SINGLE_DEV_COUNT;
}
memcpy(&msg_hdr.msg, set_re, dev_cnt * sizeof(uint32_t));
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_STORE_CALI_RE_PARAMS,
(void *)&msg_hdr, sizeof(msg_hdr), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "cali re store failed");
}
return ret;
}
int aw883xx_read_re_from_dsp(aw_dev_index_t dev, uint32_t *re)
{
struct aw883xx *aw883xx = NULL;
int ret = -1;
if (dev >= AW_DEV_MAX) {
aw_pr_info("unsupported dev:%d", dev);
return -EINVAL;
}
if (g_aw883xx[dev] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", dev);
return -EINVAL;
}
if (re == NULL) {
aw_pr_info("g_aw883xx[%d] re is NULL", dev);
return -EINVAL;
}
aw883xx = g_aw883xx[dev];
if (aw883xx->pstream == AW_STREAM_OPEN) {
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_DSP_RE_PARAMS,
(void *)re, sizeof(uint32_t), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_dev_err(aw883xx->dev, "read re from dsp failed");
}
} else {
aw_dev_err(aw883xx->dev, "PA not work, please work and retry");
}
return ret;
}
int aw883xx_cali_time_show(uint32_t *time)
{
uint32_t time_val = 0;
int ret = -1;
struct aw883xx *aw883xx = NULL;
if (g_aw883xx[AW_DEV_0] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", AW_DEV_0);
return -EINVAL;
}
aw883xx = g_aw883xx[AW_DEV_0];
if (time == NULL) {
aw_pr_err("time is NULL");
return -EINVAL;
}
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_TIME_PARAMS,
(void *)&time_val, sizeof(uint32_t), AW_GET_DEV_PARAMS);
if (ret < 0) {
aw_pr_err("set cali_time failed");
return -EINVAL;
}
*time = time_val;
return 0;
}
int aw883xx_cali_time_store(uint32_t time)
{
int ret = -1;
struct aw883xx *aw883xx = NULL;
if (g_aw883xx[AW_DEV_0] == NULL) {
aw_pr_info("g_aw883xx[%d] is NULL", AW_DEV_0);
return -EINVAL;
}
aw883xx = g_aw883xx[AW_DEV_0];
ret = aw883xx_device_params(aw883xx->aw_pa, AW_DEV_CALI_TIME_PARAMS,
(void *)&time, sizeof(uint32_t), AW_SET_DEV_PARAMS);
if (ret < 0) {
aw_pr_err("set cali_time failed");
return -EINVAL;
}
return 0;
}
#endif