1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************************/
22 
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include "dsp_debug.h"
26 #include "dsp_memory_config.h"
27 #include "dsp_driver_mailbox.h"
28 #include "dsp_comm.h"
29 #include "dsp_pcm_gain.h"
30 extern int g_pcm_gain;
31 extern int MsgFlag;
32 extern int InpBuf[HOLD_BUF_SIZE];					// assumes 32 bit samples.
33 extern int OutBuf[HOLD_BUF_SIZE];				// assumes 32 bit samples.
34 
hex2asc(int n)35 static int hex2asc(int n)
36 {
37 	n &= 15;
38 	if(n > 9){
39 		return ('a' - 10) + n;
40 	} else {
41 		return '0' + n;
42 	}
43 }
44 
xputs(const char * s,void (* xputc)(unsigned n,void * cookie),void * cookie)45 static void xputs(const char *s, void (*xputc)(unsigned n, void *cookie), void *cookie)
46 {
47 	while (*s) {
48 		xputc(*s++, cookie);
49 	}
50 }
51 
__xprintf(const char * fmt,va_list ap,void (* xputc)(unsigned n,void * cookie),void * cookie)52 void __xprintf(const char *fmt, va_list ap,void (*xputc)(unsigned n, void *cookie), void *cookie)
53 {
54 	char scratch[32];
55 	for(;;){
56 		switch(*fmt){
57 		case 0:
58 			va_end(ap);
59 			return;
60 		case '%':
61 			switch(fmt[1]) {
62 			case 'c': {
63 				unsigned n = va_arg(ap, unsigned);
64 				xputc(n, cookie);
65 			fmt += 2;
66 				continue;
67 		}
68 			case 'h': {
69 				unsigned n = va_arg(ap, unsigned);
70 			xputc(hex2asc(n >> 12), cookie);
71 				xputc(hex2asc(n >> 8), cookie);
72 				xputc(hex2asc(n >> 4), cookie);
73 				xputc(hex2asc(n >> 0), cookie);
74 				fmt += 2;
75 				continue;
76 			}
77 			case 'b': {
78 				unsigned n = va_arg(ap, unsigned);
79 			xputc(hex2asc(n >> 4), cookie);
80 				xputc(hex2asc(n >> 0), cookie);
81 				fmt += 2;
82 				continue;
83 			}
84 			case 'p':
85 			case 'X':
86 			case 'x': {
87 				unsigned n = va_arg(ap, unsigned);
88 				char *p = scratch + 15;
89 				*p = 0;
90 				do {
91 					*--p = hex2asc(n);
92 				n = n >> 4;
93 				} while(n != 0);
94 				while(p > (scratch + 7)) *--p = '0';
95 				xputs(p, xputc, cookie);
96 				fmt += 2;
97 				continue;
98 			}
99   	case 'd': {
100 				int n = va_arg(ap, int);
101 				char *p = scratch + 15;
102 				*p = 0;
103 				if(n < 0) {
104 					xputc('-', cookie);
105 				n = -n;
106 				}
107 				do {
108 					*--p = (n % 10) + '0';
109 					n /= 10;
110 				} while(n != 0);
111 				xputs(p, xputc, cookie);
112 				fmt += 2;
113 				continue;
114 			}
115 
116         case 'f': {
117                 double fnum = va_arg(ap, double);
118                 unsigned long long ipart, fpart;
119                 int i=4;
120                 char *p = scratch + 31;
121                 *p = '\0';
122 
123             	if(fnum < 0.0)
124                 {
125         		    xputc('-', cookie);
126         		    fnum = -fnum;
127                 }
128                 ipart = (unsigned long long)fnum;
129                 fpart = ((fnum-ipart)*10000); //10^i = 10000
130 
131         		while(i>0)
132                 {
133 		            *--p = (fpart % 10) + '0';
134 	        	    fpart /= 10;
135                     i--;
136 		        }
137                 *--p = '.';
138 		        while(ipart > 0)
139                 {
140     		        *--p = (ipart % 10) + '0';
141 	    	        ipart /= 10;
142 		        }
143 
144                 xputs(p, xputc, cookie);
145                 fmt += 2;
146                 continue;
147             }
148 
149 			case 'u': {
150 				unsigned n = va_arg(ap, unsigned);
151 				char *p = scratch + 15;
152 			*p = 0;
153 				do {
154 					*--p = (n % 10) + '0';
155 					n /= 10;
156 				} while(n != 0);
157 				xputs(p, xputc, cookie);
158 				fmt += 2;
159 				continue;
160 		}
161 			case 's': {
162 				char *s = (char *)va_arg(ap, char*);
163 				if(s == 0) s = "(null)";
164 				xputs(s, xputc, cookie);
165 				fmt += 2;
166 				continue;
167 			}
168 			case 'l': {
169 				if (fmt[2] == 'x') {
170 					unsigned long long n = va_arg(ap, unsigned long long);
171 					char *p = scratch + 23;
172 					*p = 0;
173 					do {
174 						*--p = hex2asc((int)n);
175 						n = n >> 4;
176 					} while(n != 0);
177 				while(p > (scratch + 7)) *--p = '0';
178 					xputs(p, xputc, cookie);
179 					fmt += 3;
180 				continue;
181 				}
182 			}
183 			}
184 			xputc(*fmt++, cookie);
185 			break;
186 		case '\n':
187 			xputc('\r', cookie);
188 		default:
189 			xputc(*fmt++, cookie);
190 		}
191 	}
192 }
193 
194 static char* log_to_mem_head = 0;
dsp_debug_init()195 void dsp_debug_init()
196 {
197 	log_to_mem_head = (char *)(*((unsigned int *)DRV_DSP_UART_TO_MEM_CUR_ADDR) + DRV_DSP_UART_TO_MEM);
198 
199 }
200 
log_write_to_mem(const char c_data)201 static void log_write_to_mem(const char c_data)
202 {
203 	*log_to_mem_head = c_data;
204 
205 	log_to_mem_head++;
206 	if ((unsigned int)log_to_mem_head >= (DRV_DSP_UART_TO_MEM + DRV_DSP_UART_TO_MEM_SIZE - 1))
207 		log_to_mem_head = (char *)DRV_DSP_UART_TO_MEM + DRV_DSP_UART_TO_MEM_RESERVE_SIZE;
208 
209 	*((unsigned int *)DRV_DSP_UART_TO_MEM_CUR_ADDR) = (unsigned int)log_to_mem_head - DRV_DSP_UART_TO_MEM;
210 }
211 
212 
print_char(const char c_data)213 static void print_char(const char c_data)
214 {
215 	if (c_data == '\n')
216 		log_write_to_mem('\r');
217 	log_write_to_mem(c_data);
218 }
219 
220 typedef void (*xputc_type)(unsigned n, void *cookie);
221 
print_log(const char * fmt,...)222 void print_log(const char *fmt, ...)
223 {
224 	va_list args;
225 va_start(args, fmt);
226 	__xprintf(fmt, args, (xputc_type)print_char, 0);
227 	va_end(args);
228 }
229 #ifdef HIKEY_XAF_IPC_COMMENT_OUT
230 #define ISSPACE(c) (c == ' ' || c == 0x09 || c == 0x0A || c == 0x0D || c == 0)
231 
dsp_om_trim_zero(char * str)232 char* dsp_om_trim_zero(char* str)
233 {
234 	char *str_begin = 0;
235 	char *str_end = 0;
236 
237 	if (!str)
238 		return 0;
239 
240 	str_begin = str;
241 	str_end = str + strlen(str);
242 
243 	while (str_begin < str_end) {
244 		if (ISSPACE(*str_begin)) {
245 			*str_begin = 0;
246 			str_begin++;
247 		} else {
248 			break;
249 		}
250 	}
251 	while (str_begin < str_end) {
252 		if (ISSPACE(*str_end)) {
253 			*str_end = 0;
254 			str_end--;
255 		} else {
256 			break;
257 		}
258 	}
259 
260 	return str_begin;
261 }
262 
dsp_om_split_str(char * str,char ** split_str)263 char * dsp_om_split_str(char* str, char** split_str)
264 {
265 	char *str_begin = 0;
266 	char *str_end = 0;
267 
268 	if ((!str) || (!split_str)) {
269 		DSP_LOGE("input param is null\n");
270 		return str;
271 	}
272 
273 	str_end = str + strlen(str);
274 	str_begin = dsp_om_trim_zero(str);
275 
276 	if (str_begin == str_end) {
277 		DSP_LOGE("input str all space\n");
278 		return 0;
279 	}
280 
281 	*split_str = dsp_om_trim_zero(strchr(str_begin, ' '));
282 
283 	return str_begin;
284 }
285 
286 #ifdef GJB_CHANGE
send_msg_data_to_ap()287 void send_msg_data_to_ap()
288 {
289 
290     struct hikey_msg_with_content hikey_msg;
291     DSP_LOGE("%s\n", __func__);
292     hikey_msg.msg_info.msg_id=HIKEY_AUDIO_DSP_AP_OM_CMD;
293     hikey_msg.msg_info.msg_len=HIKEY_AP_DSP_MSG_MAX_LEN;
294     strncpy(hikey_msg.msg_info.msg_content,"pcm_gain",HIKEY_AP_DSP_MSG_MAX_LEN);
295     dsp_mailbox_write(&hikey_msg);
296     DSP_LOGE("Exit %s\n", __func__);
297 }
298 
send_pcm_data_to_ap()299 void send_pcm_data_to_ap()
300 {
301     struct hikey_ap_dsp_msg_body msg_info;
302     DSP_LOGE("Enter %s\n", __func__);
303     msg_info.msg_id = ID_XAF_DSP_TO_AP;
304     msg_info.msg_len = sizeof(msg_info);
305     msg_info.xf_dsp_msg.id= 0;
306     msg_info.xf_dsp_msg.opcode = 0xc;
307     msg_info.xf_dsp_msg.length = 0x400;
308     msg_info.xf_dsp_msg.address = 0x8B432000;
309     dsp_mailbox_write(&msg_info);
310     DSP_LOGE("Exit %s\n", __func__);
311 }
312 #else
send_msg_data_to_ap()313 void send_msg_data_to_ap()
314 {
315     xf_proxy_message_t hikey_msg;
316     DSP_LOGE("%s\n", __func__);
317     hikey_msg.id=HIKEY_AUDIO_DSP_AP_OM_CMD;
318     hikey_msg.length=HIKEY_AP_DSP_MSG_MAX_LEN;
319     strncpy(hikey_msg.address,"pcm_gain",HIKEY_AP_DSP_MSG_MAX_LEN);
320     dsp_mailbox_write(&hikey_msg);
321     DSP_LOGE("Exit %s\n", __func__);
322 }
323 
send_pcm_data_to_ap()324 void send_pcm_data_to_ap()
325 {
326     xf_proxy_message_t msg_info;
327     DSP_LOGE("Enter %s\n", __func__);
328     msg_info.id = ID_XAF_DSP_TO_AP;
329     msg_info.opcode = 0xc;
330     msg_info.length = 0x400;
331     msg_info.address = 0x8B432000;
332     dsp_mailbox_write(&msg_info);
333     DSP_LOGE("Exit %s\n", __func__);
334 }
335 #endif
dsp_om_read_mem(char * str)336 static void dsp_om_read_mem(char *str)
337 {
338 	unsigned int addr  = 0;
339 	unsigned int val = 0;
340 	if (!str) {
341 		DSP_LOGE("str is null\n");
342 		return;
343 	}
344 
345 	addr = strtoul(str, 0, 16);
346 	DSP_LOGD("str:%s addr:0x%x\n", str, addr);
347 
348 	val = *(unsigned int*)addr;
349     send_pcm_data_to_ap();
350 //send_msg_data_to_ap();
351     dsp_ipc_send_irq_to_ap();
352 	DSP_LOGI("read addr:0x%x value:0x%x\n", addr, val);
353 	return;
354 }
355 
dsp_om_write_mem(char * str)356 static void dsp_om_write_mem(char *str)
357 {
358 	char* str_addr  = 0;
359 	char* str_val = 0;
360 	unsigned int addr  = 0;
361 	unsigned int val = 0;
362 	if (!str) {
363 	DSP_LOGE("str is null\n");
364 		return;
365 	}
366 
367 	str_addr = dsp_om_split_str(str, &str_val);
368 
369 	if(!str_addr || !str_val) {
370 		DSP_LOGE("str:%s str_addr:%s strValue:%s\n", str, str_addr ? str_addr : "null", str_val ? str_val : "null");
371 		return;
372 	}
373 	addr = strtoul(str_addr, 0, 16);
374 	val= strtoul(str_val, 0, 16);
375 	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);
376 
377 	*(unsigned int *)addr = val;
378 
379 	return;
380 
381 }
382 
dsp_om_pcm_gain(char * str)383 static void dsp_om_pcm_gain(char *str)
384 {
385 	char* str_addr  = 0;
386 	char* str_val = 0;
387 	unsigned int addr  = 0;
388 	unsigned int val = 0;
389 	if (!str) {
390 	DSP_LOGE("str is null\n");
391 		return;
392 	}
393 	str_addr = dsp_om_split_str(str, &str_val);
394 	if(!str_addr || !str_val) {
395 		DSP_LOGE("str:%s str_addr:%s strValue:%s\n", str, str_addr ? str_addr : "null", str_val ? str_val : "null");
396 		return;
397 	}
398 	addr = strtoul(str_addr, 0, 16);
399 	val= strtoul(str_val, 0, 16);
400 	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);
401     if(ReadData((char*)InpBuf, val) ){
402         processAudio(OutBuf, InpBuf, (val/4));
403         if(WriteData((char*)OutBuf, val)) {
404             MsgFlag = MSG_PROC; // indicate that the msg is processed.
405             DSP_LOGI("PCM gain processed\n");
406             send_msg_data_to_ap();
407             dsp_ipc_send_irq_to_ap(); // Indicate data is ready  to pickup...  Maybe you need to send a msg to AP.
408         }
409         else {
410             DSP_LOGI("PCM gain Write error\n");
411             MsgFlag = MSG_INCOMP;
412             dsp_ipc_send_irq_to_ap();// Report error..
413         }
414     }
415     else {
416         DSP_LOGI("PCM gain Read error\n");
417         MsgFlag = MSG_INCOMP;
418         dsp_ipc_send_irq_to_ap();
419     }
420 	return;
421 }
422 typedef void (*om_proc_func)(char *str);
423 
424 struct om_proc_info {
425 	char *om_proc_name;
426 	om_proc_func func;
427 };
428 
429 struct om_proc_info om_proc_table[] = {
430 	{"read_mem", dsp_om_read_mem},
431 	{"write_mem", dsp_om_write_mem},
432 	{"pcm_gain", dsp_om_pcm_gain},
433 };
434 
dsp_om_get_func_by_name(char * name)435 om_proc_func dsp_om_get_func_by_name(char *name)
436 {
437 	unsigned int i = 0;
438 	unsigned int func_num = sizeof(om_proc_table) / sizeof(om_proc_table[0]);
439 
440 	if (!name) {
441 		DSP_LOGE("name is null\n");
442 		return 0;
443 	}
444 
445 	for (i = 0; i < func_num; i++)
446 		if (!strncmp((char *)om_proc_table[i].om_proc_name, name, strlen((char *)om_proc_table[i].om_proc_name)))
447 			return om_proc_table[i].func;
448 
449 	return 0;
450 }
451 
dsp_om_func_proc(char * om_str,unsigned int str_len)452 void dsp_om_func_proc(char *om_str, unsigned int str_len)
453 {
454 	char * cmd_name = 0;
455 	char * str_param = 0;
456 	om_proc_func proc_func = 0;
457 
458 	cmd_name = dsp_om_split_str((char *)om_str, &str_param);
459 
460 	DSP_LOGI("cmd_name:%s\n", cmd_name);
461 	proc_func = dsp_om_get_func_by_name(cmd_name);
462 	if (proc_func)
463 		proc_func(str_param);
464 	else
465 		DSP_LOGE("do not find func\n");
466 }
467 #endif
468 
469