1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <ulog/ulog.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <aos/list.h>
9 #include "audio_rtos.h"
10 #include "control.h"
11 #include "drv/gpio.h"
12 #include "audio_internel.h"
13
14 #define LOG_TAG "[haas200_audio]"
15
16 pcm_stream_handler_t audio_stream_hdl = NULL;
17 pcm_stream_handler_t playback_stream_hdl = NULL;
18 pcm_stream_handler_t capture_stream_hdl = NULL;
19 static int codec_hw_vol_get(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol);
20 static int codec_hw_vol_put(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol);
21 static int codec_hw_mute_state_get(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol);
22 static int codec_hw_mute_state_put(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol);
23
24
25 static const struct audio_kcontrol_new master_codec_controls[] = {
26 SOC_SINGLE_EXT("Master Volume TX", /* master volume attribute name: defined in sound_mixer.h */
27 0,
28 0, /* codec volume minimum value */
29 100, /* codec volume maxmum value */
30 0,
31 codec_hw_vol_get, /* get codec volume api */
32 codec_hw_vol_put), /* set codec volume api */
33 SOC_SINGLE_EXT("Master Mute State", /* master mute attribute name: defined in sound_mixer.h */
34 0,
35 0, /* codec mute state minimum value */
36 1, /* codec mute state maxmum value */
37 0,
38 codec_hw_mute_state_get, /* get codec mute state */
39 codec_hw_mute_state_put), /* put codec mute state */
40 };
41
codec_hw_mute_state_get(struct audio_kcontrol * kcontrol,struct audio_ctl_elem_value * ucontrol)42 static int codec_hw_mute_state_get(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol)
43 {
44 int mute = 0;
45 if(!kcontrol || !ucontrol) {
46 LOGE(LOG_TAG, "%s:%d: invalid params. \r\n", __func__, __LINE__);
47 return -1;
48 }
49 mute = rl6548_get_mute();
50 LOGD(LOG_TAG, "%s:%d: get mute state %d \r\n", __func__, __LINE__, mute);
51 ucontrol->value.integer.value[0] = mute;
52 return 0;
53 }
54
codec_hw_mute_state_put(struct audio_kcontrol * kcontrol,struct audio_ctl_elem_value * ucontrol)55 static int codec_hw_mute_state_put(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol)
56 {
57 int mute = 0;
58 if(!kcontrol || !ucontrol) {
59 LOGE(LOG_TAG, "%s:%d: invalid params. \r\n", __func__, __LINE__);
60 return -1;
61 }
62 mute = ucontrol->value.integer.value[0];
63 LOGD(LOG_TAG, "%s:%d: set mute state %d \r\n", __func__, __LINE__, mute);
64 rl6548_set_mute(mute);
65 return 0;
66 }
67
68
codec_hw_vol_get(struct audio_kcontrol * kcontrol,struct audio_ctl_elem_value * ucontrol)69 static int codec_hw_vol_get(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol)
70 {
71 int volume = 0;
72 if(!kcontrol || !ucontrol) {
73 LOGE(LOG_TAG, "%s:%d: invalid params. \r\n", __func__, __LINE__);
74 return -1;
75 }
76 // TBD: get codec volume, e.g. volume = ac97_get_vol();
77 volume = rl6548_volume_get();
78 LOGD(LOG_TAG, "%s:%d: get volume %d \r\n", __func__, __LINE__, volume);
79 ucontrol->value.integer.value[0] = volume;
80 return 0;
81 }
82
codec_hw_vol_put(struct audio_kcontrol * kcontrol,struct audio_ctl_elem_value * ucontrol)83 static int codec_hw_vol_put(struct audio_kcontrol *kcontrol, struct audio_ctl_elem_value *ucontrol)
84 {
85 int volume = 0, dac_vol = 0;
86 if(!kcontrol || !ucontrol) {
87 LOGE(LOG_TAG, "%s:%d: invalid params. \r\n", __func__, __LINE__);
88 return -1;
89 }
90 volume = ucontrol->value.integer.value[0];
91 if (volume < 0)
92 {
93 volume = 0;
94 }
95 if (volume > 100)
96 {
97 volume = 100;
98 }
99 LOGD(LOG_TAG, "%s:%d: set volume %d \r\n", __func__, __LINE__, volume);
100 // dac_vol = volume_step[volume];
101 // alsa_volume_set(volume, dac_vol);
102 rl6548_volume_set(volume);
103 return 0;
104 }
105
106
codec_pcm_stream_open(int mode,int sampleRate,int channels,pcm_stream_format_t format,aos_hdl_t * event_hdl)107 static pcm_stream_handler_t codec_pcm_stream_open(int mode, int sampleRate, int channels, pcm_stream_format_t format, aos_hdl_t *event_hdl)
108 {
109 int word_len = WL_16;
110 if(format == PCM_STREAM_FORMAT_S8 ) {
111 word_len = WL_8;
112 } else if(format == PCM_STREAM_FORMAT_S16_LE) {
113 word_len = WL_16;
114 } else if(format == PCM_STREAM_FORMAT_S24_LE) {
115 word_len = WL_24;
116 }
117
118 if(audio_stream_hdl == NULL) {
119 audio_stream_hdl = (pcm_stream_handler_t) rl6548_audio_init(sampleRate, channels, word_len);
120 }
121
122 if(mode == PCM_STREAM_IN) {
123 capture_stream_hdl = (char*)audio_stream_hdl + 1;
124 LOGD(LOG_TAG, "%s:%d: capture_stream_hdl 0x%x, mode %d, sampleRate %d, channels %d, format %d \r\n", __func__, __LINE__,
125 capture_stream_hdl, PCM_STREAM_OUT, sampleRate, channels, format);
126 } else if (mode == PCM_STREAM_OUT) {
127 playback_stream_hdl = (char*)audio_stream_hdl + 2;
128 LOGD(LOG_TAG, "%s:%d: playback_stream_hdl 0x%x, mode %d, sampleRate %d, channels %d, format %d \r\n", __func__, __LINE__,
129 playback_stream_hdl, PCM_STREAM_OUT, sampleRate, channels, format);
130 }
131 return audio_stream_hdl;
132 }
133
134
135
codec_pcm_stream_start(pcm_stream_handler_t hdl)136 static int codec_pcm_stream_start(pcm_stream_handler_t hdl)
137 {
138 int ret = 0;
139 if(NULL == hdl) {
140 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
141 return ret;
142 }
143
144 if(hdl == capture_stream_hdl) {
145 rl6548_capture_start();
146 LOGD(LOG_TAG, "rx codec_pcm_stream_start");
147 } else if (hdl == playback_stream_hdl) {
148 rl6548_playback_start();
149 LOGD(LOG_TAG, "tx codec_pcm_stream_start");
150 }
151
152 // LOGD(LOG_TAG, "%s:%d, ret = %d.", __func__, __LINE__, ret);
153 return ret;
154 }
155
codec_pcm_stream_write(pcm_stream_handler_t hdl,void * buf,unsigned int len)156 static int codec_pcm_stream_write(pcm_stream_handler_t hdl, void *buf, unsigned int len)
157 {
158 int ret = -1;
159 if(NULL == hdl) {
160 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
161 return ret;
162 }
163 if(hdl == capture_stream_hdl) {
164 LOGE(LOG_TAG, "%s:%d, write operation not allowed on capture stream.", __func__, __LINE__);
165 } else
166 if (hdl == playback_stream_hdl) {
167 ret = rl6548_audio_write(playback_stream_hdl, (uint8_t *)buf, len);
168 }
169 return ret;
170 }
171
codec_pcm_stream_read(pcm_stream_handler_t hdl,void * buf,unsigned int len)172 static int codec_pcm_stream_read(pcm_stream_handler_t hdl, void *buf, unsigned int len)
173 {
174 int ret = -1, i = 0, j = 0;
175 int channel_num = 3, sample_bytes = 2, frame_size;
176 char *tempBuf = NULL;
177 if(NULL == hdl) {
178 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
179 return ret;
180 }
181 if(hdl == playback_stream_hdl) {
182 LOGE(LOG_TAG, "%s:%d, read operation not allowed on playback stream.", __func__, __LINE__);
183 } else
184 if (hdl == capture_stream_hdl) {
185 // TBD: read capture stream, get last channel data
186 frame_size = channel_num * sample_bytes;
187 ret = rl6548_data_read(hdl, buf, len);
188 LOGD(LOG_TAG, "%s:%d, data_dump_read %d bytes", __func__, __LINE__, ret);
189 }
190 return ret;
191 }
192
codec_pcm_stream_pause(pcm_stream_handler_t hdl,int enable)193 static int codec_pcm_stream_pause(pcm_stream_handler_t hdl, int enable)
194 {
195 int ret = -1;
196 if(NULL == hdl) {
197 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
198 return ret;
199 }
200 if(hdl == playback_stream_hdl) {
201 // TBD: pause playback stream
202 } else if (hdl == capture_stream_hdl) {
203 // TBD: pause capture stream
204 }
205 LOGD(LOG_TAG, "%s:%d, ret = %d.", __func__, __LINE__, ret);
206 return ret;
207 }
208
codec_pcm_stream_suspend(pcm_stream_handler_t hdl)209 static int codec_pcm_stream_suspend(pcm_stream_handler_t hdl)
210 {
211 int ret = 0;
212 if(hdl == &playback_stream_hdl) {
213 // TBD: put playback stream into lowpower/suspend mode
214 } else if (hdl == &capture_stream_hdl) {
215 // TBD: put capture stream into lowpower/suspend mode
216 }
217 return ret;
218 }
219
codec_pcm_stream_resume(pcm_stream_handler_t hdl)220 static int codec_pcm_stream_resume(pcm_stream_handler_t hdl)
221 {
222 int ret = 0;
223 if(hdl == &playback_stream_hdl) {
224 // TBD: put playback stream into active mode
225 } else if (hdl == &capture_stream_hdl) {
226 // TBD: put playback stream into active mode
227 }
228 return ret;
229 }
230
codec_pcm_stream_stop(pcm_stream_handler_t hdl)231 static int codec_pcm_stream_stop(pcm_stream_handler_t hdl)
232 {
233 int ret = 0;
234 if(NULL == hdl) {
235 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
236 return ret;
237 }
238 if(hdl == capture_stream_hdl) {
239 rl6548_capture_stop();
240 } else if (hdl == playback_stream_hdl) {
241 rl6548_playback_stop();
242 }
243 // LOGD(LOG_TAG, "%s:%d, ret = %d.", __func__, __LINE__, ret);
244 LOGD(LOG_TAG, "codec_pcm_stream_stop");
245 return ret;
246 }
247
codec_pcm_stream_close(pcm_stream_handler_t hdl)248 static int codec_pcm_stream_close(pcm_stream_handler_t hdl)
249 {
250 int ret = 0;
251 if(NULL == hdl) {
252 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
253 return ret;
254 }
255
256 if(audio_stream_hdl == NULL) {
257 playback_stream_hdl = capture_stream_hdl = NULL;
258 return ret;
259 }
260
261 if(hdl == capture_stream_hdl) {
262 rl6548_audio_deinit();
263 capture_stream_hdl = audio_stream_hdl = NULL;
264 } else if (hdl == playback_stream_hdl) {
265 rl6548_audio_deinit();
266 playback_stream_hdl = audio_stream_hdl = NULL;
267 }
268 LOGD(LOG_TAG, "%s:%d, ret = %d.", __func__, __LINE__, ret);
269 return ret;
270 }
271
codec_pcm_stream_recover(pcm_stream_handler_t hdl)272 static int codec_pcm_stream_recover(pcm_stream_handler_t hdl)
273 {
274 int ret = -1;
275 if(NULL == hdl) {
276 LOGE(LOG_TAG, "%s:%d, invalid hdl.", __func__, __LINE__);
277 return ret;
278 }
279 if(hdl == capture_stream_hdl) {
280 // TBD: recover capture stream
281 } else if (hdl == playback_stream_hdl) {
282 // TBD: recover playback stream
283 }
284 LOGD(LOG_TAG, "%s:%d, ret = %d.", __func__, __LINE__, ret);
285 return ret;
286 }
287
288 pcm_stream_ops_t codec_pcm_ops = {
289 .open = codec_pcm_stream_open,
290 .start = codec_pcm_stream_start,
291 .read = codec_pcm_stream_read,
292 .write = codec_pcm_stream_write,
293 // .pause = codec_pcm_stream_pause,
294 .stop = codec_pcm_stream_stop,
295 .close = codec_pcm_stream_close,
296 // .recover = codec_pcm_stream_recover,
297 // .suspend = codec_pcm_stream_suspend,
298 // .resume = codec_pcm_stream_resume,
299 };
300
301 /* Application shall call this API to install codec driver instance. */
audio_install_codec_driver()302 int audio_install_codec_driver()
303 {
304 int pb_stream_num = 1;
305 int cap_stream_num = 1;
306 LOGD(LOG_TAG, "%s:%d, install RTOS codec driver %d Capture %d Playback", __func__, __LINE__, cap_stream_num, pb_stream_num);
307 return audio_native_card_register(cap_stream_num, pb_stream_num, &codec_pcm_ops, master_codec_controls, sizeof(master_codec_controls)/sizeof(master_codec_controls[0]));
308 }
309 //FINSH_FUNCTION_EXPORT_CMD(audio_install_codec_driver, insmod_audio_drv, RTOS Codec Driver Test)