blob: a74308e423c2a637bf036e8dec66fdc7a59b9e7c [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2018 Cadence Design Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to use this Software with Cadence processor cores only and
* not with any other processors and platforms, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
#include <stdarg.h>
#include <stdlib.h>
#include "dsp_debug.h"
#include "dsp_memory_config.h"
#include "dsp_driver_mailbox.h"
#include "dsp_comm.h"
#include "dsp_pcm_gain.h"
extern int g_pcm_gain;
extern int MsgFlag;
extern int InpBuf[HOLD_BUF_SIZE]; // assumes 32 bit samples.
extern int OutBuf[HOLD_BUF_SIZE]; // assumes 32 bit samples.
static int hex2asc(int n)
{
n &= 15;
if(n > 9){
return ('a' - 10) + n;
} else {
return '0' + n;
}
}
static void xputs(const char *s, void (*xputc)(unsigned n, void *cookie), void *cookie)
{
while (*s) {
xputc(*s++, cookie);
}
}
void __xprintf(const char *fmt, va_list ap,void (*xputc)(unsigned n, void *cookie), void *cookie)
{
char scratch[32];
for(;;){
switch(*fmt){
case 0:
va_end(ap);
return;
case '%':
switch(fmt[1]) {
case 'c': {
unsigned n = va_arg(ap, unsigned);
xputc(n, cookie);
fmt += 2;
continue;
}
case 'h': {
unsigned n = va_arg(ap, unsigned);
xputc(hex2asc(n >> 12), cookie);
xputc(hex2asc(n >> 8), cookie);
xputc(hex2asc(n >> 4), cookie);
xputc(hex2asc(n >> 0), cookie);
fmt += 2;
continue;
}
case 'b': {
unsigned n = va_arg(ap, unsigned);
xputc(hex2asc(n >> 4), cookie);
xputc(hex2asc(n >> 0), cookie);
fmt += 2;
continue;
}
case 'p':
case 'X':
case 'x': {
unsigned n = va_arg(ap, unsigned);
char *p = scratch + 15;
*p = 0;
do {
*--p = hex2asc(n);
n = n >> 4;
} while(n != 0);
while(p > (scratch + 7)) *--p = '0';
xputs(p, xputc, cookie);
fmt += 2;
continue;
}
case 'd': {
int n = va_arg(ap, int);
char *p = scratch + 15;
*p = 0;
if(n < 0) {
xputc('-', cookie);
n = -n;
}
do {
*--p = (n % 10) + '0';
n /= 10;
} while(n != 0);
xputs(p, xputc, cookie);
fmt += 2;
continue;
}
case 'f': {
double fnum = va_arg(ap, double);
unsigned long long ipart, fpart;
int i=4;
char *p = scratch + 31;
*p = '\0';
if(fnum < 0.0)
{
xputc('-', cookie);
fnum = -fnum;
}
ipart = (unsigned long long)fnum;
fpart = ((fnum-ipart)*10000); //10^i = 10000
while(i>0)
{
*--p = (fpart % 10) + '0';
fpart /= 10;
i--;
}
*--p = '.';
while(ipart > 0)
{
*--p = (ipart % 10) + '0';
ipart /= 10;
}
xputs(p, xputc, cookie);
fmt += 2;
continue;
}
case 'u': {
unsigned n = va_arg(ap, unsigned);
char *p = scratch + 15;
*p = 0;
do {
*--p = (n % 10) + '0';
n /= 10;
} while(n != 0);
xputs(p, xputc, cookie);
fmt += 2;
continue;
}
case 's': {
char *s = (char *)va_arg(ap, char*);
if(s == 0) s = "(null)";
xputs(s, xputc, cookie);
fmt += 2;
continue;
}
case 'l': {
if (fmt[2] == 'x') {
unsigned long long n = va_arg(ap, unsigned long long);
char *p = scratch + 23;
*p = 0;
do {
*--p = hex2asc((int)n);
n = n >> 4;
} while(n != 0);
while(p > (scratch + 7)) *--p = '0';
xputs(p, xputc, cookie);
fmt += 3;
continue;
}
}
}
xputc(*fmt++, cookie);
break;
case '\n':
xputc('\r', cookie);
default:
xputc(*fmt++, cookie);
}
}
}
static char* log_to_mem_head = 0;
void dsp_debug_init()
{
log_to_mem_head = (char *)(*((unsigned int *)DRV_DSP_UART_TO_MEM_CUR_ADDR) + DRV_DSP_UART_TO_MEM);
}
static void log_write_to_mem(const char c_data)
{
*log_to_mem_head = c_data;
log_to_mem_head++;
if ((unsigned int)log_to_mem_head >= (DRV_DSP_UART_TO_MEM + DRV_DSP_UART_TO_MEM_SIZE - 1))
log_to_mem_head = (char *)DRV_DSP_UART_TO_MEM + DRV_DSP_UART_TO_MEM_RESERVE_SIZE;
*((unsigned int *)DRV_DSP_UART_TO_MEM_CUR_ADDR) = (unsigned int)log_to_mem_head - DRV_DSP_UART_TO_MEM;
}
static void print_char(const char c_data)
{
if (c_data == '\n')
log_write_to_mem('\r');
log_write_to_mem(c_data);
}
typedef void (*xputc_type)(unsigned n, void *cookie);
void print_log(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
__xprintf(fmt, args, (xputc_type)print_char, 0);
va_end(args);
}
#ifdef HIKEY_XAF_IPC_COMMENT_OUT
#define ISSPACE(c) (c == ' ' || c == 0x09 || c == 0x0A || c == 0x0D || c == 0)
char* dsp_om_trim_zero(char* str)
{
char *str_begin = 0;
char *str_end = 0;
if (!str)
return 0;
str_begin = str;
str_end = str + strlen(str);
while (str_begin < str_end) {
if (ISSPACE(*str_begin)) {
*str_begin = 0;
str_begin++;
} else {
break;
}
}
while (str_begin < str_end) {
if (ISSPACE(*str_end)) {
*str_end = 0;
str_end--;
} else {
break;
}
}
return str_begin;
}
char * dsp_om_split_str(char* str, char** split_str)
{
char *str_begin = 0;
char *str_end = 0;
if ((!str) || (!split_str)) {
DSP_LOGE("input param is null\n");
return str;
}
str_end = str + strlen(str);
str_begin = dsp_om_trim_zero(str);
if (str_begin == str_end) {
DSP_LOGE("input str all space\n");
return 0;
}
*split_str = dsp_om_trim_zero(strchr(str_begin, ' '));
return str_begin;
}
#ifdef GJB_CHANGE
void send_msg_data_to_ap()
{
struct hikey_msg_with_content hikey_msg;
DSP_LOGE("%s\n", __func__);
hikey_msg.msg_info.msg_id=HIKEY_AUDIO_DSP_AP_OM_CMD;
hikey_msg.msg_info.msg_len=HIKEY_AP_DSP_MSG_MAX_LEN;
strncpy(hikey_msg.msg_info.msg_content,"pcm_gain",HIKEY_AP_DSP_MSG_MAX_LEN);
dsp_mailbox_write(&hikey_msg);
DSP_LOGE("Exit %s\n", __func__);
}
void send_pcm_data_to_ap()
{
struct hikey_ap_dsp_msg_body msg_info;
DSP_LOGE("Enter %s\n", __func__);
msg_info.msg_id = ID_XAF_DSP_TO_AP;
msg_info.msg_len = sizeof(msg_info);
msg_info.xf_dsp_msg.id= 0;
msg_info.xf_dsp_msg.opcode = 0xc;
msg_info.xf_dsp_msg.length = 0x400;
msg_info.xf_dsp_msg.address = 0x8B432000;
dsp_mailbox_write(&msg_info);
DSP_LOGE("Exit %s\n", __func__);
}
#else
void send_msg_data_to_ap()
{
xf_proxy_message_t hikey_msg;
DSP_LOGE("%s\n", __func__);
hikey_msg.id=HIKEY_AUDIO_DSP_AP_OM_CMD;
hikey_msg.length=HIKEY_AP_DSP_MSG_MAX_LEN;
strncpy(hikey_msg.address,"pcm_gain",HIKEY_AP_DSP_MSG_MAX_LEN);
dsp_mailbox_write(&hikey_msg);
DSP_LOGE("Exit %s\n", __func__);
}
void send_pcm_data_to_ap()
{
xf_proxy_message_t msg_info;
DSP_LOGE("Enter %s\n", __func__);
msg_info.id = ID_XAF_DSP_TO_AP;
msg_info.opcode = 0xc;
msg_info.length = 0x400;
msg_info.address = 0x8B432000;
dsp_mailbox_write(&msg_info);
DSP_LOGE("Exit %s\n", __func__);
}
#endif
static void dsp_om_read_mem(char *str)
{
unsigned int addr = 0;
unsigned int val = 0;
if (!str) {
DSP_LOGE("str is null\n");
return;
}
addr = strtoul(str, 0, 16);
DSP_LOGD("str:%s addr:0x%x\n", str, addr);
val = *(unsigned int*)addr;
send_pcm_data_to_ap();
//send_msg_data_to_ap();
dsp_ipc_send_irq_to_ap();
DSP_LOGI("read addr:0x%x value:0x%x\n", addr, val);
return;
}
static void dsp_om_write_mem(char *str)
{
char* str_addr = 0;
char* str_val = 0;
unsigned int addr = 0;
unsigned int val = 0;
if (!str) {
DSP_LOGE("str is null\n");
return;
}
str_addr = dsp_om_split_str(str, &str_val);
if(!str_addr || !str_val) {
DSP_LOGE("str:%s str_addr:%s strValue:%s\n", str, str_addr ? str_addr : "null", str_val ? str_val : "null");
return;
}
addr = strtoul(str_addr, 0, 16);
val= strtoul(str_val, 0, 16);
DSP_LOGI("str_addr:%s addr:%x str_val:%s val:%x\n", str_addr ? str_addr : "null", addr, str_val ? str_val : "null", val);
*(unsigned int *)addr = val;
return;
}
static void dsp_om_pcm_gain(char *str)
{
char* str_addr = 0;
char* str_val = 0;
unsigned int addr = 0;
unsigned int val = 0;
if (!str) {
DSP_LOGE("str is null\n");
return;
}
str_addr = dsp_om_split_str(str, &str_val);
if(!str_addr || !str_val) {
DSP_LOGE("str:%s str_addr:%s strValue:%s\n", str, str_addr ? str_addr : "null", str_val ? str_val : "null");
return;
}
addr = strtoul(str_addr, 0, 16);
val= strtoul(str_val, 0, 16);
DSP_LOGI("str_addr:%s addr:%x str_val:%s val:%x\n", str_addr ? str_addr : "null", addr, str_val ? str_val : "null", val);
if(ReadData((char*)InpBuf, val) ){
processAudio(OutBuf, InpBuf, (val/4));
if(WriteData((char*)OutBuf, val)) {
MsgFlag = MSG_PROC; // indicate that the msg is processed.
DSP_LOGI("PCM gain processed\n");
send_msg_data_to_ap();
dsp_ipc_send_irq_to_ap(); // Indicate data is ready to pickup... Maybe you need to send a msg to AP.
}
else {
DSP_LOGI("PCM gain Write error\n");
MsgFlag = MSG_INCOMP;
dsp_ipc_send_irq_to_ap();// Report error..
}
}
else {
DSP_LOGI("PCM gain Read error\n");
MsgFlag = MSG_INCOMP;
dsp_ipc_send_irq_to_ap();
}
return;
}
typedef void (*om_proc_func)(char *str);
struct om_proc_info {
char *om_proc_name;
om_proc_func func;
};
struct om_proc_info om_proc_table[] = {
{"read_mem", dsp_om_read_mem},
{"write_mem", dsp_om_write_mem},
{"pcm_gain", dsp_om_pcm_gain},
};
om_proc_func dsp_om_get_func_by_name(char *name)
{
unsigned int i = 0;
unsigned int func_num = sizeof(om_proc_table) / sizeof(om_proc_table[0]);
if (!name) {
DSP_LOGE("name is null\n");
return 0;
}
for (i = 0; i < func_num; i++)
if (!strncmp((char *)om_proc_table[i].om_proc_name, name, strlen((char *)om_proc_table[i].om_proc_name)))
return om_proc_table[i].func;
return 0;
}
void dsp_om_func_proc(char *om_str, unsigned int str_len)
{
char * cmd_name = 0;
char * str_param = 0;
om_proc_func proc_func = 0;
cmd_name = dsp_om_split_str((char *)om_str, &str_param);
DSP_LOGI("cmd_name:%s\n", cmd_name);
proc_func = dsp_om_get_func_by_name(cmd_name);
if (proc_func)
proc_func(str_param);
else
DSP_LOGE("do not find func\n");
}
#endif