314 lines
6.5 KiB
C
314 lines
6.5 KiB
C
/*
|
|
* aw87xxx_dsp.c
|
|
*
|
|
* Copyright (c) 2021 AWINIC Technology CO., LTD
|
|
*
|
|
* Author: Barry <zhaozhongbo@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 <linux/uaccess.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/device.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/of.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/hrtimer.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/init.h>
|
|
#include "aw_log.h"
|
|
#include "aw_dsp.h"
|
|
|
|
static DEFINE_MUTEX(g_dsp_lock);
|
|
|
|
#ifdef AW_MTK_OPEN_DSP_PLATFORM
|
|
extern int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer,
|
|
uint32_t data_size);
|
|
extern int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer,
|
|
int16_t size, uint32_t *buf_len);
|
|
/*
|
|
static int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer,
|
|
uint32_t data_size)
|
|
{
|
|
AW_LOGI("enter");
|
|
return 0;
|
|
}
|
|
|
|
static int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer,
|
|
int16_t size, uint32_t *buf_len)
|
|
{
|
|
AW_LOGI("enter");
|
|
return 0;
|
|
}
|
|
*/
|
|
#elif defined AW_QCOM_OPEN_DSP_PLATFORM
|
|
extern int afe_get_topology(int port_id);
|
|
extern int aw_send_afe_cal_apr(uint32_t param_id,
|
|
void *buf, int cmd_size, bool write);
|
|
/*
|
|
static int afe_get_topology(int port_id)
|
|
{
|
|
return -EPERM;
|
|
}
|
|
|
|
static int aw_send_afe_cal_apr(uint32_t param_id,
|
|
void *buf, int cmd_size, bool write)
|
|
{
|
|
AW_LOGI("enter, no define AWINIC_ADSP_ENABLE", __func__);
|
|
return 0;
|
|
}
|
|
*/
|
|
#endif
|
|
|
|
uint8_t aw_dsp_isEnable(void)
|
|
{
|
|
#if (defined AW_QCOM_OPEN_DSP_PLATFORM) || (defined AW_MTK_OPEN_DSP_PLATFORM)
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
/*****************mtk dsp communication function start**********************/
|
|
#ifdef AW_MTK_OPEN_DSP_PLATFORM
|
|
static int aw_mtk_write_data_to_dsp(int32_t param_id,
|
|
void *data, int size)
|
|
{
|
|
int32_t *dsp_data = NULL;
|
|
mtk_dsp_hdr_t *hdr = NULL;
|
|
int ret;
|
|
|
|
dsp_data = kzalloc(sizeof(mtk_dsp_hdr_t) + size, GFP_KERNEL);
|
|
if (!dsp_data) {
|
|
AW_LOGE("kzalloc dsp_msg error");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
hdr = (mtk_dsp_hdr_t *)dsp_data;
|
|
hdr->type = DSP_MSG_TYPE_DATA;
|
|
hdr->opcode_id = param_id;
|
|
hdr->version = AW_DSP_MSG_HDR_VER;
|
|
|
|
memcpy(((char *)dsp_data) + sizeof(mtk_dsp_hdr_t),
|
|
data, size);
|
|
|
|
ret = mtk_spk_send_ipi_buf_to_dsp(dsp_data,
|
|
sizeof(mtk_dsp_hdr_t) + size);
|
|
if (ret < 0) {
|
|
AW_LOGE("write data failed");
|
|
kfree(dsp_data);
|
|
dsp_data = NULL;
|
|
return ret;
|
|
}
|
|
|
|
kfree(dsp_data);
|
|
dsp_data = NULL;
|
|
return 0;
|
|
}
|
|
|
|
static int aw_mtk_read_data_from_dsp(int32_t param_id, void *data,
|
|
int data_size)
|
|
{
|
|
int ret;
|
|
mtk_dsp_hdr_t hdr;
|
|
|
|
mutex_lock(&g_dsp_lock);
|
|
hdr.type = DSP_MSG_TYPE_CMD;
|
|
hdr.opcode_id = param_id;
|
|
hdr.version = AW_DSP_MSG_HDR_VER;
|
|
|
|
ret = mtk_spk_send_ipi_buf_to_dsp(&hdr, sizeof(mtk_dsp_hdr_t));
|
|
if (ret < 0)
|
|
goto failed;
|
|
|
|
ret = mtk_spk_recv_ipi_buf_from_dsp(data, data_size, &data_size);
|
|
if (ret < 0)
|
|
goto failed;
|
|
|
|
mutex_unlock(&g_dsp_lock);
|
|
return 0;
|
|
|
|
failed:
|
|
mutex_unlock(&g_dsp_lock);
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
/********************mtk dsp communication function end***********************/
|
|
|
|
/******************qcom dsp communication function start**********************/
|
|
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
|
static int aw_check_dsp_ready(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = afe_get_topology(AFE_PORT_ID_AWDSP_RX);
|
|
AW_LOGD("topo_id 0x%x", ret);
|
|
|
|
if (ret <= 0)
|
|
return 0;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
static int aw_qcom_write_data_to_dsp(int32_t param_id,
|
|
void *data, int data_size)
|
|
{
|
|
int ret = 0;
|
|
int try = 0;
|
|
|
|
AW_LOGI("enter");
|
|
mutex_lock(&g_dsp_lock);
|
|
while (try < AW_DSP_TRY_TIME) {
|
|
if (aw_check_dsp_ready()) {
|
|
ret = aw_send_afe_cal_apr(param_id, data,
|
|
data_size, true);
|
|
mutex_unlock(&g_dsp_lock);
|
|
return ret;
|
|
} else {
|
|
try++;
|
|
msleep(AW_DSP_SLEEP_TIME);
|
|
AW_LOGD("afe not ready try again");
|
|
}
|
|
}
|
|
mutex_unlock(&g_dsp_lock);
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int aw_qcom_read_data_from_dsp(int32_t param_id,
|
|
void *data, int data_size)
|
|
{
|
|
int ret = 0;
|
|
int try = 0;
|
|
|
|
AW_LOGI("enter");
|
|
|
|
mutex_lock(&g_dsp_lock);
|
|
while (try < AW_DSP_TRY_TIME) {
|
|
if (aw_check_dsp_ready()) {
|
|
ret = aw_send_afe_cal_apr(param_id, data,
|
|
data_size, false);
|
|
mutex_unlock(&g_dsp_lock);
|
|
return ret;
|
|
} else {
|
|
try++;
|
|
msleep(AW_DSP_SLEEP_TIME);
|
|
AW_LOGD("afe not ready try again");
|
|
}
|
|
}
|
|
mutex_unlock(&g_dsp_lock);
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
#endif
|
|
/*****************qcom dsp communication function end*********************/
|
|
|
|
int aw_dsp_get_rx_module_enable(int *enable)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (!enable) {
|
|
AW_LOGE("enable is NULL");
|
|
return -EINVAL;
|
|
}
|
|
|
|
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
|
ret = aw_qcom_read_data_from_dsp(AWDSP_RX_SET_ENABLE,
|
|
(void *)enable, sizeof(uint32_t));
|
|
#elif defined AW_MTK_OPEN_DSP_PLATFORM
|
|
ret = aw_mtk_read_data_from_dsp(AWDSP_RX_SET_ENABLE,
|
|
(void *)enable, sizeof(uint32_t));
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
int aw_dsp_set_rx_module_enable(int enable)
|
|
{
|
|
int ret = 0;
|
|
|
|
switch (enable) {
|
|
case AW_RX_MODULE_DISENABLE:
|
|
AW_LOGD("set enable=%d", enable);
|
|
break;
|
|
case AW_RX_MODULE_ENABLE:
|
|
AW_LOGD("set enable=%d", enable);
|
|
break;
|
|
default:
|
|
AW_LOGE("unsupport enable=%d", enable);
|
|
return -EINVAL;
|
|
}
|
|
|
|
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
|
ret = aw_qcom_write_data_to_dsp(AWDSP_RX_SET_ENABLE,
|
|
&enable, sizeof(uint32_t));
|
|
#elif defined AW_MTK_OPEN_DSP_PLATFORM
|
|
ret = aw_mtk_write_data_to_dsp(AWDSP_RX_SET_ENABLE,
|
|
&enable, sizeof(uint32_t));
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int aw_dsp_get_vmax(uint32_t *vmax, int dev_index)
|
|
{
|
|
int ret = 0;
|
|
int32_t param_id = 0;
|
|
|
|
switch (dev_index % AW_DSP_CHANNEL_MAX) {
|
|
case AW_DSP_CHANNEL_0:
|
|
param_id = AWDSP_RX_VMAX_0;
|
|
break;
|
|
case AW_DSP_CHANNEL_1:
|
|
param_id = AWDSP_RX_VMAX_1;
|
|
break;
|
|
default:
|
|
AW_LOGE("algo only support double PA channel:%d unsupport",
|
|
dev_index);
|
|
return -EINVAL;
|
|
}
|
|
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
|
ret = aw_qcom_read_data_from_dsp(param_id,
|
|
(void *)vmax, sizeof(uint32_t));
|
|
#elif defined AW_MTK_OPEN_DSP_PLATFORM
|
|
ret = aw_mtk_read_data_from_dsp(param_id,
|
|
(void *)vmax, sizeof(uint32_t));
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
int aw_dsp_set_vmax(uint32_t vmax, int dev_index)
|
|
{
|
|
int ret = 0;
|
|
int32_t param_id = 0;
|
|
|
|
switch (dev_index % AW_DSP_CHANNEL_MAX) {
|
|
case AW_DSP_CHANNEL_0:
|
|
param_id = AWDSP_RX_VMAX_0;
|
|
break;
|
|
case AW_DSP_CHANNEL_1:
|
|
param_id = AWDSP_RX_VMAX_1;
|
|
break;
|
|
default:
|
|
AW_LOGE("algo only support double PA channel:%d unsupport",
|
|
dev_index);
|
|
return -EINVAL;
|
|
}
|
|
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
|
ret = aw_qcom_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t));
|
|
#elif defined AW_MTK_OPEN_DSP_PLATFORM
|
|
ret = aw_mtk_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t));
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|