xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/aw87xxx/aw_dsp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * aw87xxx_dsp.c
3  *
4  * Copyright (c) 2021 AWINIC Technology CO., LTD
5  *
6  * Author: Barry <zhaozhongbo@awinic.com>
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  */
13 
14 #include <linux/uaccess.h>
15 #include <linux/delay.h>
16 #include <linux/device.h>
17 #include <linux/kernel.h>
18 #include <linux/of.h>
19 #include <linux/slab.h>
20 #include <linux/hrtimer.h>
21 #include <linux/proc_fs.h>
22 #include <linux/init.h>
23 #include "aw_log.h"
24 #include "aw_dsp.h"
25 
26 static DEFINE_MUTEX(g_dsp_lock);
27 
28 #ifdef AW_MTK_OPEN_DSP_PLATFORM
29 extern int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer,
30 				uint32_t data_size);
31 extern int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer,
32 				int16_t size, uint32_t *buf_len);
33 /*
34 static int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer,
35 				uint32_t data_size)
36 {
37 	AW_LOGI("enter");
38 	return 0;
39 }
40 
41 static int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer,
42 				int16_t size, uint32_t *buf_len)
43 {
44 	AW_LOGI("enter");
45 	return 0;
46 }
47 */
48 #elif defined AW_QCOM_OPEN_DSP_PLATFORM
49 extern int afe_get_topology(int port_id);
50 extern int aw_send_afe_cal_apr(uint32_t param_id,
51 	void *buf, int cmd_size, bool write);
52 /*
53 static int afe_get_topology(int port_id)
54 {
55 	return -EPERM;
56 }
57 
58 static int aw_send_afe_cal_apr(uint32_t param_id,
59 	void *buf, int cmd_size, bool write)
60 {
61 	AW_LOGI("enter, no define AWINIC_ADSP_ENABLE", __func__);
62 	return 0;
63 }
64 */
65 #endif
66 
aw_dsp_isEnable(void)67 uint8_t aw_dsp_isEnable(void)
68 {
69 #if (defined AW_QCOM_OPEN_DSP_PLATFORM) || (defined AW_MTK_OPEN_DSP_PLATFORM)
70 	return true;
71 #else
72 	return false;
73 #endif
74 }
75 
76 /*****************mtk dsp communication function start**********************/
77 #ifdef AW_MTK_OPEN_DSP_PLATFORM
aw_mtk_write_data_to_dsp(int32_t param_id,void * data,int size)78 static int aw_mtk_write_data_to_dsp(int32_t param_id,
79 			void *data, int size)
80 {
81 	int32_t *dsp_data = NULL;
82 	mtk_dsp_hdr_t *hdr = NULL;
83 	int ret;
84 
85 	dsp_data = kzalloc(sizeof(mtk_dsp_hdr_t) + size, GFP_KERNEL);
86 	if (!dsp_data) {
87 		AW_LOGE("kzalloc dsp_msg error");
88 		return -ENOMEM;
89 	}
90 
91 	hdr = (mtk_dsp_hdr_t *)dsp_data;
92 	hdr->type = DSP_MSG_TYPE_DATA;
93 	hdr->opcode_id = param_id;
94 	hdr->version = AW_DSP_MSG_HDR_VER;
95 
96 	memcpy(((char *)dsp_data) + sizeof(mtk_dsp_hdr_t),
97 		data, size);
98 
99 	ret = mtk_spk_send_ipi_buf_to_dsp(dsp_data,
100 				sizeof(mtk_dsp_hdr_t) + size);
101 	if (ret < 0) {
102 		AW_LOGE("write data failed");
103 		kfree(dsp_data);
104 		dsp_data = NULL;
105 		return ret;
106 	}
107 
108 	kfree(dsp_data);
109 	dsp_data = NULL;
110 	return 0;
111 }
112 
aw_mtk_read_data_from_dsp(int32_t param_id,void * data,int data_size)113 static int aw_mtk_read_data_from_dsp(int32_t param_id, void *data,
114 					int data_size)
115 {
116 	int ret;
117 	mtk_dsp_hdr_t hdr;
118 
119 	mutex_lock(&g_dsp_lock);
120 	hdr.type = DSP_MSG_TYPE_CMD;
121 	hdr.opcode_id = param_id;
122 	hdr.version = AW_DSP_MSG_HDR_VER;
123 
124 	ret = mtk_spk_send_ipi_buf_to_dsp(&hdr, sizeof(mtk_dsp_hdr_t));
125 	if (ret < 0)
126 		goto failed;
127 
128 	ret = mtk_spk_recv_ipi_buf_from_dsp(data, data_size, &data_size);
129 	if (ret < 0)
130 		goto failed;
131 
132 	mutex_unlock(&g_dsp_lock);
133 	return 0;
134 
135 failed:
136 	mutex_unlock(&g_dsp_lock);
137 	return ret;
138 }
139 
140 #endif
141 /********************mtk dsp communication function end***********************/
142 
143 /******************qcom dsp communication function start**********************/
144 #ifdef AW_QCOM_OPEN_DSP_PLATFORM
aw_check_dsp_ready(void)145 static int aw_check_dsp_ready(void)
146 {
147 	int ret;
148 
149 	ret = afe_get_topology(AFE_PORT_ID_AWDSP_RX);
150 	AW_LOGD("topo_id 0x%x", ret);
151 
152 	if (ret <= 0)
153 		return 0;
154 	else
155 		return 1;
156 }
157 
aw_qcom_write_data_to_dsp(int32_t param_id,void * data,int data_size)158 static int aw_qcom_write_data_to_dsp(int32_t param_id,
159 				void *data, int data_size)
160 {
161 	int ret = 0;
162 	int try = 0;
163 
164 	AW_LOGI("enter");
165 	mutex_lock(&g_dsp_lock);
166 	while (try < AW_DSP_TRY_TIME) {
167 		if (aw_check_dsp_ready()) {
168 			ret = aw_send_afe_cal_apr(param_id, data,
169 				data_size, true);
170 			mutex_unlock(&g_dsp_lock);
171 			return ret;
172 		} else {
173 			try++;
174 			msleep(AW_DSP_SLEEP_TIME);
175 			AW_LOGD("afe not ready try again");
176 		}
177 	}
178 	mutex_unlock(&g_dsp_lock);
179 
180 	return -EINVAL;
181 }
182 
aw_qcom_read_data_from_dsp(int32_t param_id,void * data,int data_size)183 static int aw_qcom_read_data_from_dsp(int32_t param_id,
184 				void *data, int data_size)
185 {
186 	int ret = 0;
187 	int try = 0;
188 
189 	AW_LOGI("enter");
190 
191 	mutex_lock(&g_dsp_lock);
192 	while (try < AW_DSP_TRY_TIME) {
193 		if (aw_check_dsp_ready()) {
194 			ret = aw_send_afe_cal_apr(param_id, data,
195 					data_size, false);
196 			mutex_unlock(&g_dsp_lock);
197 			return ret;
198 		} else {
199 			try++;
200 			msleep(AW_DSP_SLEEP_TIME);
201 			AW_LOGD("afe not ready try again");
202 		}
203 	}
204 	mutex_unlock(&g_dsp_lock);
205 
206 	return -EINVAL;
207 }
208 
209 #endif
210 /*****************qcom dsp communication function end*********************/
211 
aw_dsp_get_rx_module_enable(int * enable)212 int aw_dsp_get_rx_module_enable(int *enable)
213 {
214 	int ret = 0;
215 
216 	if (!enable) {
217 		AW_LOGE("enable is NULL");
218 		return -EINVAL;
219 	}
220 
221 #ifdef AW_QCOM_OPEN_DSP_PLATFORM
222 	ret = aw_qcom_read_data_from_dsp(AWDSP_RX_SET_ENABLE,
223 			(void *)enable, sizeof(uint32_t));
224 #elif defined AW_MTK_OPEN_DSP_PLATFORM
225 	ret = aw_mtk_read_data_from_dsp(AWDSP_RX_SET_ENABLE,
226 			(void *)enable, sizeof(uint32_t));
227 #endif
228 
229 	return ret;
230 }
231 
aw_dsp_set_rx_module_enable(int enable)232 int aw_dsp_set_rx_module_enable(int enable)
233 {
234 	int ret = 0;
235 
236 	switch (enable) {
237 	case AW_RX_MODULE_DISENABLE:
238 		AW_LOGD("set enable=%d", enable);
239 		break;
240 	case AW_RX_MODULE_ENABLE:
241 		AW_LOGD("set enable=%d", enable);
242 		break;
243 	default:
244 		AW_LOGE("unsupport enable=%d", enable);
245 		return -EINVAL;
246 	}
247 
248 #ifdef AW_QCOM_OPEN_DSP_PLATFORM
249 	ret = aw_qcom_write_data_to_dsp(AWDSP_RX_SET_ENABLE,
250 			&enable, sizeof(uint32_t));
251 #elif defined AW_MTK_OPEN_DSP_PLATFORM
252 	ret = aw_mtk_write_data_to_dsp(AWDSP_RX_SET_ENABLE,
253 			&enable, sizeof(uint32_t));
254 #endif
255 
256 	return ret;
257 }
258 
259 
aw_dsp_get_vmax(uint32_t * vmax,int dev_index)260 int aw_dsp_get_vmax(uint32_t *vmax, int dev_index)
261 {
262 	int ret  = 0;
263 	int32_t param_id = 0;
264 
265 	switch (dev_index % AW_DSP_CHANNEL_MAX) {
266 	case AW_DSP_CHANNEL_0:
267 		param_id = AWDSP_RX_VMAX_0;
268 		break;
269 	case AW_DSP_CHANNEL_1:
270 		param_id = AWDSP_RX_VMAX_1;
271 		break;
272 	default:
273 		AW_LOGE("algo only support double PA channel:%d unsupport",
274 			dev_index);
275 		return -EINVAL;
276 	}
277 #ifdef AW_QCOM_OPEN_DSP_PLATFORM
278 	ret = aw_qcom_read_data_from_dsp(param_id,
279 			(void *)vmax, sizeof(uint32_t));
280 #elif defined AW_MTK_OPEN_DSP_PLATFORM
281 	ret = aw_mtk_read_data_from_dsp(param_id,
282 			(void *)vmax, sizeof(uint32_t));
283 #endif
284 
285 	return ret;
286 }
287 
aw_dsp_set_vmax(uint32_t vmax,int dev_index)288 int aw_dsp_set_vmax(uint32_t vmax, int dev_index)
289 {
290 	int ret = 0;
291 	int32_t param_id = 0;
292 
293 	switch (dev_index % AW_DSP_CHANNEL_MAX) {
294 	case AW_DSP_CHANNEL_0:
295 		param_id = AWDSP_RX_VMAX_0;
296 		break;
297 	case AW_DSP_CHANNEL_1:
298 		param_id = AWDSP_RX_VMAX_1;
299 		break;
300 	default:
301 		AW_LOGE("algo only support double PA channel:%d unsupport",
302 			dev_index);
303 		return -EINVAL;
304 	}
305 #ifdef AW_QCOM_OPEN_DSP_PLATFORM
306 	ret = aw_qcom_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t));
307 #elif defined AW_MTK_OPEN_DSP_PLATFORM
308 	ret = aw_mtk_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t));
309 #endif
310 
311 	return ret;
312 }
313 
314