blob: 23737bf8d8af03b1d8d7233eefcd2dadabacb5e8 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * All Rights Reserved
3 *
4 * MARVELL CONFIDENTIAL
5 * Copyright 2012 Marvell International Ltd All Rights Reserved.
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Marvell International Ltd or its
8 * suppliers or licensors. Title to the Material remains with Marvell International Ltd
9 * or its suppliers and licensors. The Material contains trade secrets and
10 * proprietary and confidential information of Marvell or its suppliers and
11 * licensors. The Material is protected by worldwide copyright and trade secret
12 * laws and treaty provisions. No part of the Material may be used, copied,
13 * reproduced, modified, published, uploaded, posted, transmitted, distributed,
14 * or disclosed in any way without Marvell's prior express written permission.
15 *
16 * No license under any patent, copyright, trade secret or other intellectual
17 * property right is granted to or conferred upon you by disclosure or delivery
18 * of the Materials, either expressly, by implication, inducement, estoppel or
19 * otherwise. Any license under such intellectual property rights must be
20 * express and approved by Marvell in writing.
21 *
22 */
23
24/*
25 * ac_thread.c: enabled for AUDIO_CALIBRATION only
26 */
27
28#define LOG_TAG "ac_thread"
29//#define LOG_NDEBUG 0
30
31#include <cutils/log.h>
32#include <cutils/properties.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/prctl.h>
36#include <sys/socket.h>
37#include <unistd.h>
38#include <pthread.h>
39#include <errno.h>
40
41#include "audioCalibration.h"
42#include "acm_aph.h"
43#include "acm_param.h"
44#include "ac_thread.h"
45#include "vcm.h"
46#include "adsp_ve.h"
47
48#define REG_BUFFER_SIZE 100
49#define PHY_VERSION_LEN 36
50static pthread_t ACM_Calibration_Server;
51
52int NVM_Calibration_IPC(AC_IPC_Package *package);
53void get_msa_gain_by_path_name(const char * out_path_name, const char * path_name, unsigned char volume,
54 signed char *ret_gain, signed char *ret_gain_wb, signed char *ret_sidetone_gain, signed char *ret_sidetone_gain_wb, bool use_extra_vol);
55ACM_ReturnCode AC_ReloadCalibrationData(AC_Digital_Gain *gain);
56void AC_EnablePath(AC_IPC_Package_Body *path_para, AC_Digital_Gain *gain);
57void AC_DisablePath(AC_IPC_Package_Body *path_para);
58void AC_MutePath(AC_IPC_Package_Body *path_para);
59void AC_SetPathVolume(AC_IPC_Package_Body *path_para, AC_Digital_Gain *gain);
60void AC_SwitchPath(AC_IPC_Package_Body *path_para, AC_Digital_Gain *gain);
61
62extern audio_mode_t ACMGetAudioMode(void);
63extern void get_pcm_config(int *p_role, int *p_rate);
64
65static int fd_server = -1;
66static int clientfd_server = -1;
67
68//client which send message to NVM server.
69int NVM_Calibration_IPC(AC_IPC_Package *package)
70{
71 int fd, len, value;
72 struct sockaddr_un un;
73
74 /* create a UNIX domain stream socket */
75 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
76 LOGE(NVM_Calibration_IPC, "[Audio NVM Calibration][%s][%d][create socket fail]\n", __FUNCTION__, __LINE__);
77 return 1;
78 }
79
80 /* fill socket address structure with server's address */
81 memset(&un, 0, sizeof(un));
82 un.sun_family = AF_UNIX;
83 switch (package->type)
84 {
85 case AUDIO_NVM_GetGainConfigure:
86 case AUDIO_NVM_ReloadCalibrationData:
87 case AUDIO_NVM_GetVEConfigure:
88 strcpy(un.sun_path, NVM_CALIBRATION_SOCKET);
89 len = offsetof(struct sockaddr_un, sun_path) + strlen(NVM_CALIBRATION_SOCKET);
90 break;
91
92 default:
93 LOGE(NVM_Calibration_IPC, "[Audio NVM Calibration Client][%d][IPC type error]\n", __LINE__);
94 close(fd);
95 return 3;
96 }
97 if (connect(fd, (struct sockaddr *)&un, len) < 0) {
98 LOGE(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][connect fail][error %d(%s)]\n", __LINE__,errno, strerror(errno));
99 close(fd);
100 return 4;
101 }
102
103 LOGI(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d]-[send type:%d]-[d1:%d][d2:%d][d3:%d][d4:%d]\n",
104 __LINE__,
105 package->type, package->body.d1, package->body.d2, package->body.d3, package->body.d4);
106
107 LOGI(NVM_Calibration_IPC,"NVM_Calibration_IPC:: un.sun_path=%s!", un.sun_path);
108
109 if(write(fd, package, sizeof(AC_IPC_Package)) == -1) {
110 LOGE(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][write fail]\n", __LINE__);
111 close(fd);
112 return 5;
113 }
114
115 /* get data from server when necessary */
116 switch (package->type)
117 {
118 case AUDIO_NVM_GetGainConfigure:
119 if(read(fd, package->ptr, sizeof(ACMCodec_GainT)) == -1) {
120 LOGE(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][read fail]\n", __LINE__);
121 close(fd);
122 return 11;
123 }
124 break;
125
126 case AUDIO_NVM_ReloadCalibrationData:
127 if(read(fd, &value, sizeof(int)) == -1) {
128 LOGE(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][read fail]\n", __LINE__);
129 close(fd);
130 return 12;
131 }
132 else {
133 if(value == -1) {
134 LOGI(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][AUDIO_NVM_ReloadCalibrationData Fail: no codec compiled]\n", __LINE__);
135 }
136 else if(value == 0) {
137 LOGI(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][AUDIO_NVM_ReloadCalibrationData Success: reload existing file]\n", __LINE__);
138 }
139 else if(value == 1) {
140 LOGI(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][AUDIO_NVM_ReloadCalibrationData Success: create new file]\n", __LINE__);
141 }
142 }
143 break;
144
145 case AUDIO_NVM_GetVEConfigure:
146 if(read(fd, package->ptr, sizeof(EnhanceParmsT)) == -1) {
147 LOGE(NVM_Calibration_IPC,"[Audio NVM Calibration Client][%d][read fail]\n", __LINE__);
148 close(fd);
149 return 13;
150 }
151 break;
152
153 default:
154 break;
155 }
156
157 close(fd);
158
159 return 0;
160}
161
162// get MSA gain from ACM NVM according to device path name
163void get_msa_gain_by_path_name(const char * out_path_name, const char * path_name, unsigned char volume,
164 signed char *ret_gain, signed char *ret_gain_wb, signed char *ret_sidetone_gain, signed char *ret_sidetone_gain_wb, bool use_extra_vol)
165{
166 int extra_volume = (use_extra_vol ? MSA_GAIN_EXTRA_MODE : MSA_GAIN_NORMAL_MODE);
167 ACM_MsaGain msa_gain = {0};
168 unsigned int size = sizeof(ACM_MsaGain);
169
170 msa_gain.volume = volume;
171 msa_gain.gain = 0;
172 msa_gain.wbGain = 0;
173 msa_gain.path_direction = 0;
174
175 // fix to VC mode here. only VC have msa gain
176 msa_gain.out_path_name = out_path_name;
177 msa_gain.path_name = path_name;
178
179 if (ACMSetParameter(ACM_MSA_GAIN_MODE, NULL, extra_volume) != ACM_RC_OK) {
180 LOGE(get_msa_gain_by_path_name, "set output msa gain mode failed, use the default normal mode ");
181 }
182
183 if (ACMGetParameter(ACM_MSA_GAIN, &msa_gain, &size) != ACM_RC_OK) {
184 LOGE(get_msa_gain_by_path_name, "get output msa gain failed, use default gain.");
185 }
186
187 *ret_gain = msa_gain.gain;
188 *ret_gain_wb = msa_gain.wbGain;
189 *ret_sidetone_gain = msa_gain.sidetone_gain;
190 *ret_sidetone_gain_wb = msa_gain.sidetone_wbGain;
191}
192
193//handle the message from NVM server, and recover the status using new config.
194ACM_ReturnCode AC_ReloadCalibrationData(AC_Digital_Gain *gain) {
195
196 int Rx_path_id = 0xFF;
197 int Tx_path_id = 0xFF;
198 int volume_Rx = 0;
199 int mute_Tx = 0;
200 const char* Rx_pathname = NULL;
201 const char* Tx_pathname = NULL;
202
203 signed char input_gain = 0;
204 signed char input_gain_wb = 0;
205 signed char output_gain = 0;
206 signed char output_gain_wb = 0;
207 signed char rx_sidetone_gain = 0;
208 signed char rx_sidetone_gain_wb = 0;
209 signed char tx_sidetone_gain = 0;
210 signed char tx_sidetone_gain_wb = 0;
211 unsigned char vc_output_vol = 0;
212 bool use_extra_vol = 0;
213
214 //Default: notify audioCalibration.c not to configure DSP gain
215 gain->path_direction_Rx = VCM_PATH_NOT_CONNECTED;
216 gain->path_direction_Tx = VCM_PATH_NOT_CONNECTED;
217
218 ACM_ReloadCalibrationData();
219
220 //get active path
221 ACM_GetEnabledPathId(&Rx_path_id, &Tx_path_id, &volume_Rx, &mute_Tx);
222
223 if ((0xFF == Rx_path_id) || (0xFF == Tx_path_id))
224 {
225 LOGE( AC_ReloadCalibrationData, "%s/L%d: no enabled path.",__FUNCTION__, __LINE__);
226 return ACM_RC_OK;
227 }
228
229 LOGI( AC_ReloadCalibrationData, "%s/L%d: Rx_path_id=%d, Tx_path_id=%d, volume_Rx=%d, mute_Tx=%d.",
230 __FUNCTION__, __LINE__, Rx_path_id, Tx_path_id, volume_Rx, mute_Tx);
231
232 //HIFI has no digital gain
233 if (ACM_RC_OK_VOICE_MATCHED != APHAudioPathCheckPathId(Rx_path_id, Tx_path_id))
234 {
235 LOGI( AC_ReloadCalibrationData, "%s/L%d: current mode is AUDIO_MODE_NORMAL.",__FUNCTION__, __LINE__);
236 return ACM_RC_OK;
237 }
238
239 Rx_pathname = ACM_GetPathName(Rx_path_id);
240 Tx_pathname = ACM_GetPathName(Tx_path_id);
241
242 if ((NULL == Rx_pathname) || (NULL == Tx_pathname))
243 {
244 LOGE( AC_ReloadCalibrationData, "%s/L%d: RX or TX pathname is NULL.",__FUNCTION__, __LINE__);
245 return ACM_RC_OK;
246 }
247
248 vc_output_vol = volume_Rx;
249
250 get_msa_gain_by_path_name(Rx_pathname, Tx_pathname, 100, &input_gain, &input_gain_wb, &tx_sidetone_gain, &tx_sidetone_gain_wb, use_extra_vol);
251 get_msa_gain_by_path_name(Rx_pathname, Rx_pathname, vc_output_vol, &output_gain, &output_gain_wb, &rx_sidetone_gain, &rx_sidetone_gain_wb, use_extra_vol);
252
253 LOGI(AC_ReloadCalibrationData, "%s/L%d: input_gain=0x%x, input_gain_wb=0x%x, output_gain=0x%x, output_gain_wb=0x%x.use_extra_vol=%d.\n",
254 __FUNCTION__, __LINE__, input_gain, input_gain_wb, output_gain, output_gain_wb, use_extra_vol);
255
256 gain->path_direction_Rx = VCM_PATH_OUT;
257 gain->digital_gain_Rx = output_gain | (output_gain_wb << 8);
258 gain->volume_Rx = vc_output_vol;
259
260 gain->path_direction_Tx = VCM_PATH_IN;
261 gain->digital_gain_Tx = input_gain | (input_gain_wb << 8);
262 gain->volume_Tx = vc_output_vol;
263
264 gain->path_direction_SideTone = VCM_PATH_SIDETONE;
265 gain->digital_gain_SideTone = rx_sidetone_gain | (rx_sidetone_gain_wb << 8);
266 gain->volume_SideTone = vc_output_vol;
267
268 LOGI(AC_ReloadCalibrationData, "%s/L%d: digital_gain_Rx=0x%x, volume_Rx=%d, digital_gain_Tx=0x%x, volume_Tx=%d, digital_gain_SideTone=%d.\n",
269 __FUNCTION__, __LINE__, gain->digital_gain_Rx, gain->volume_Rx, gain->digital_gain_Tx, gain->volume_Tx, gain->digital_gain_SideTone);
270
271
272 return ACM_RC_OK;
273}
274
275ACM_ReturnCode APHReloadNvm(void) {
276 AC_Digital_Gain gain;
277 ACM_ReturnCode ret;
278
279 LOGI(APHReloadNvm, "%s/L%d: ReloadCalibrationData", __FUNCTION__, __LINE__);
280 memset(&gain, 0x00, sizeof(AC_Digital_Gain));
281
282 ret = AC_ReloadCalibrationData(&gain);
283 if (ACM_RC_OK != ret) {
284 LOGI(APHReloadNvm, "%s/L%d: ReloadCalibrationData fail.", __FUNCTION__, __LINE__);
285 return ret;
286 }
287
288#ifdef PXA1826_AUDIO
289 ret = APHSetMSAGain(&gain);
290 if (ACM_RC_OK != ret) {
291 LOGI(APHReloadNvm, "%s/L%d: ReloadCalibrationData fail.", __FUNCTION__, __LINE__);
292 return ret;
293 }
294#endif
295
296 return ACM_RC_OK;
297}
298
299/*
300Function: enable the path which is disabled status.
301path_para.d1: Rx_path_id
302path_para.d2: Tx_path_id
303path_para.d3: volume
304 */
305void AC_EnablePath(AC_IPC_Package_Body *path_para, AC_Digital_Gain *gain)
306{
307 int Rx_path_id = path_para->d1;
308 int Tx_path_id = path_para->d2;
309 unsigned int Volume = path_para->d3;
310
311 signed char input_gain = 0;
312 signed char input_gain_wb = 0;
313 signed char output_gain = 0;
314 signed char output_gain_wb = 0;
315 signed char rx_sidetone_gain = 0;
316 signed char rx_sidetone_gain_wb = 0;
317 signed char tx_sidetone_gain = 0;
318 signed char tx_sidetone_gain_wb = 0;
319 unsigned char vc_output_vol = 0;
320 bool use_extra_vol = 0;
321
322 const char* Rx_pathname = ACM_GetPathName(Rx_path_id);
323 const char* Tx_pathname = ACM_GetPathName(Tx_path_id);
324
325 if ((NULL == Rx_pathname) || (NULL == Tx_pathname))
326 {
327 LOGE( AC_EnablePath, "%s/L%d: RX or TX pathname is NULL.",__FUNCTION__, __LINE__);
328 return;
329 }
330
331 vc_output_vol = Volume;
332
333 LOGI( AC_EnablePath, "%s/L%d: Rx_path_id = %d, Rx_pathname =%s, Tx_path_id = %d, Tx_pathname = %s, Volume =%d",
334 __FUNCTION__, __LINE__, Rx_path_id, Rx_pathname, Tx_path_id, Tx_pathname, Volume);
335
336 if ((ACM_RC_OK_HIFI_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname))
337 && (ACM_RC_OK_VOICE_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname)))
338 {
339 LOGE( AC_EnablePath, "%s/L%d: RX is not matched with TX.",__FUNCTION__, __LINE__);
340 return;
341 }
342
343 //Disable all enabled path, otherwise there may be several enabled path.
344 APHDisableAllPath();
345
346 ACMAudioPathEnable(Rx_pathname, Volume);
347 ACMAudioPathEnable(Tx_pathname, Volume);
348
349 //get the gain for voice
350 if (ACM_RC_OK_HIFI_MATCHED == APHAudioPathCheck (Rx_pathname, Tx_pathname))
351 {
352 LOGI( AC_EnablePath, "%s/L%d: RX is matched with TX about HIFI. Not need to get digital gain.",__FUNCTION__, __LINE__);
353 return;
354 }
355
356 get_msa_gain_by_path_name(Rx_pathname, Tx_pathname, 100, &input_gain, &input_gain_wb, &tx_sidetone_gain, &tx_sidetone_gain_wb, use_extra_vol);
357 get_msa_gain_by_path_name(Rx_pathname, Rx_pathname, vc_output_vol, &output_gain, &output_gain_wb, &rx_sidetone_gain, &rx_sidetone_gain_wb, use_extra_vol);
358
359 LOGI(AC_EnablePath, "%s/L%d: input_gain= 0x%x, input_gain_wb=0x%x, output_gain=0x%x, output_gain_wb=0x%x.use_extra_vol=%d.\n",
360 __FUNCTION__, __LINE__, input_gain, input_gain_wb, output_gain, output_gain_wb, use_extra_vol);
361
362 gain->path_direction_Rx = VCM_PATH_OUT;
363 gain->digital_gain_Rx = output_gain | (output_gain_wb << 8);
364 gain->volume_Rx = vc_output_vol;
365
366 gain->path_direction_Tx = VCM_PATH_IN;
367 gain->digital_gain_Tx = input_gain | (input_gain_wb << 8);
368 gain->volume_Tx = vc_output_vol;
369
370 gain->path_direction_SideTone = VCM_PATH_SIDETONE;
371 gain->digital_gain_SideTone = rx_sidetone_gain | (rx_sidetone_gain_wb << 8);
372 gain->volume_SideTone = vc_output_vol;
373
374 LOGI(AC_EnablePath, "%s/L%d: digital_gain_Rx=0x%x, volume_Rx=%d, digital_gain_Tx=0x%x, volume_Tx=%d, digital_gain_SideTone=%d.\n",
375 __FUNCTION__, __LINE__, gain->digital_gain_Rx, gain->volume_Rx, gain->digital_gain_Tx, gain->volume_Tx, gain->digital_gain_SideTone);
376
377}
378
379/*
380Function: Disable the path which is enabled.
381path_para.d1: Rx_path_id
382path_para.d2: Tx_path_id
383 */
384void AC_DisablePath(AC_IPC_Package_Body *path_para) {
385 int Rx_path_id = path_para->d1;
386 int Tx_path_id = path_para->d2;
387
388 const char* Rx_pathname = ACM_GetPathName(Rx_path_id);
389 const char* Tx_pathname = ACM_GetPathName(Tx_path_id);
390
391 if ((NULL == Rx_pathname) || (NULL == Tx_pathname))
392 {
393 LOGE( AC_DisablePath, "%s/L%d: RX or TX pathname is NULL.",__FUNCTION__, __LINE__);
394 return;
395 }
396
397 if ((ACM_RC_OK_HIFI_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname))
398 && (ACM_RC_OK_VOICE_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname)))
399 {
400 LOGE( AC_DisablePath, "%s/L%d: RX is not matched with TX.",__FUNCTION__, __LINE__);
401 return;
402 }
403
404 ACMAudioPathDisable(Rx_pathname);
405 ACMAudioPathDisable(Tx_pathname);
406
407 LOGI( AC_DisablePath, "%s/L%d: Rx_path_id = %d, Rx_pathname =%s, Tx_path_id = %d, Tx_pathname = %s",
408 __FUNCTION__, __LINE__, Rx_path_id, Rx_pathname, Tx_path_id, Tx_pathname);
409}
410
411/*
412Function: mute the path which is enabled and unmuted.
413path_para.d1: Rx_path_id
414path_para.d2: Tx_path_id
415path_para.d3: mute
416 */
417void AC_MutePath(AC_IPC_Package_Body *path_para) {
418 int Rx_path_id = path_para->d1;
419 int Tx_path_id = path_para->d2;
420 int mute = path_para->d3;
421
422 const char* Rx_pathname = ACM_GetPathName(Rx_path_id);
423 const char* Tx_pathname = ACM_GetPathName(Tx_path_id);
424
425 if ((NULL == Rx_pathname) || (NULL == Tx_pathname))
426 {
427 LOGE( AC_MutePath, "%s/L%d: RX or TX pathname is NULL.",__FUNCTION__, __LINE__);
428 return;
429 }
430
431 LOGI( AC_MutePath, "%s/L%d: Rx_path_id = %d, Rx_pathname =%s, Tx_path_id = %d, Tx_pathname = %s, mute =%d",
432 __FUNCTION__, __LINE__, Rx_path_id, Rx_pathname, Tx_path_id, Tx_pathname, mute);
433
434 if ((ACM_RC_OK_HIFI_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname))
435 && (ACM_RC_OK_VOICE_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname)))
436 {
437 LOGE( AC_MutePath, "%s/L%d: RX is not matched with TX.",__FUNCTION__, __LINE__);
438 return;
439 }
440
441 ACMAudioPathMute(Rx_pathname, mute);
442 ACMAudioPathMute(Tx_pathname, mute);
443}
444
445/*
446Function:set the volume for enabled path.
447path_para.d1: Rx_path_id
448path_para.d2: Tx_path_id
449path_para.d3: volume
450 */
451void AC_SetPathVolume(AC_IPC_Package_Body *path_para, AC_Digital_Gain *gain) {
452 int Rx_path_id = path_para->d1;
453 int Tx_path_id = path_para->d2;
454 unsigned int Volume = path_para->d3;
455
456 signed char input_gain = 0;
457 signed char input_gain_wb = 0;
458 signed char output_gain = 0;
459 signed char output_gain_wb = 0;
460 signed char rx_sidetone_gain = 0;
461 signed char rx_sidetone_gain_wb = 0;
462 signed char tx_sidetone_gain = 0;
463 signed char tx_sidetone_gain_wb = 0;
464 unsigned char vc_output_vol = Volume;
465 bool use_extra_vol = 0;
466
467 const char* Rx_pathname = ACM_GetPathName(Rx_path_id);
468 const char* Tx_pathname = ACM_GetPathName(Tx_path_id);
469
470 if ((NULL == Rx_pathname) || (NULL == Tx_pathname))
471 {
472 LOGE( AC_SetPathVolume, "%s/L%d: RX or TX pathname is NULL.",__FUNCTION__, __LINE__);
473 return;
474 }
475
476 LOGI( AC_SetPathVolume, "%s/L%d: Rx_path_id = %d, Rx_pathname =%s, Tx_path_id = %d, Tx_pathname = %s, Volume =%d",
477 __FUNCTION__, __LINE__, Rx_path_id, Rx_pathname, Tx_path_id, Tx_pathname, Volume);
478
479 if ((ACM_RC_OK_HIFI_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname))
480 && (ACM_RC_OK_VOICE_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname)))
481 {
482 LOGE( AC_SetPathVolume, "%s/L%d: RX is not matched with TX.",__FUNCTION__, __LINE__);
483 return;
484 }
485
486 ACMAudioPathVolumeSet(Rx_pathname, Volume);
487 ACMAudioPathVolumeSet(Tx_pathname, Volume);
488
489 //get the gain for voice
490 if (ACM_RC_OK_HIFI_MATCHED == APHAudioPathCheck (Rx_pathname, Tx_pathname))
491 {
492 LOGE( AC_SetPathVolume, "%s/L%d: RX is matched with TX about HIFI. Not need to get gain.",__FUNCTION__, __LINE__);
493 return;
494 }
495
496 get_msa_gain_by_path_name(Rx_pathname, Tx_pathname, 100, &input_gain, &input_gain_wb, &tx_sidetone_gain, &tx_sidetone_gain_wb, use_extra_vol);
497 get_msa_gain_by_path_name(Rx_pathname, Rx_pathname, vc_output_vol, &output_gain, &output_gain_wb, &rx_sidetone_gain, &rx_sidetone_gain_wb, use_extra_vol);
498
499 LOGI(AC_SetPathVolume, "%s/L%d: input_gain=0x%x, input_gain_wb=0x%x, output_gain=0x%x, output_gain_wb=0x%x.use_extra_vol=%d.\n",
500 __FUNCTION__, __LINE__, input_gain, input_gain_wb, output_gain, output_gain_wb, use_extra_vol);
501
502 gain->path_direction_Rx = VCM_PATH_OUT;
503 gain->digital_gain_Rx = output_gain | (output_gain_wb << 8);
504 gain->volume_Rx = vc_output_vol;
505
506 gain->path_direction_Tx = VCM_PATH_IN;
507 gain->digital_gain_Tx = input_gain | (input_gain_wb << 8);
508 gain->volume_Tx = vc_output_vol;
509
510 gain->path_direction_SideTone = VCM_PATH_SIDETONE;
511 gain->digital_gain_SideTone = rx_sidetone_gain | (rx_sidetone_gain_wb << 8);
512 gain->volume_SideTone = vc_output_vol;
513
514 LOGI(AC_SetPathVolume, "%s/L%d: digital_gain_Rx=0x%x, volume_Rx=%d, digital_gain_Tx=0x%x, volume_Tx=%d, digital_gain_SideTone=%d.\n",
515 __FUNCTION__, __LINE__, gain->digital_gain_Rx, gain->volume_Rx, gain->digital_gain_Tx, gain->volume_Tx, gain->digital_gain_SideTone);
516}
517
518/*
519Function: switch the path from enabled path list to another enabled path list.
520path_para.d1: Rx_path_id
521path_para.d2: Tx_path_id
522path_para.d3: Volume
523 */
524void AC_SwitchPath(AC_IPC_Package_Body *path_para, AC_Digital_Gain *gain) {
525 int Rx_path_id = path_para->d1;
526 int Tx_path_id = path_para->d2;
527 unsigned int Volume = path_para->d3;
528
529 signed char input_gain = 0;
530 signed char input_gain_wb = 0;
531 signed char output_gain = 0;
532 signed char output_gain_wb = 0;
533 signed char rx_sidetone_gain = 0;
534 signed char rx_sidetone_gain_wb = 0;
535 signed char tx_sidetone_gain = 0;
536 signed char tx_sidetone_gain_wb = 0;
537 unsigned char vc_output_vol = Volume;
538 bool use_extra_vol = 0;
539
540 //enable the pointed path
541 const char* Rx_pathname = ACM_GetPathName(Rx_path_id);
542 const char* Tx_pathname = ACM_GetPathName(Tx_path_id);
543
544 if ((NULL == Rx_pathname) || (NULL == Tx_pathname))
545 {
546 LOGE( AC_SwitchPath, "%s/L%d: RX or TX pathname is NULL.",__FUNCTION__, __LINE__);
547 return;
548 }
549
550 if ((ACM_RC_OK_HIFI_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname))
551 && (ACM_RC_OK_VOICE_MATCHED != APHAudioPathCheck (Rx_pathname, Tx_pathname)))
552 {
553 LOGE( AC_SwitchPath, "%s/L%d: RX is not matched with TX.",__FUNCTION__, __LINE__);
554 return;
555 }
556
557 LOGI( AC_SwitchPath, "%s/L%d: Rx_path_id = %d, Rx_pathname =%s, Tx_path_id = %d, Tx_pathname = %s, Volume =%d",
558 __FUNCTION__, __LINE__, Rx_path_id, Rx_pathname, Tx_path_id, Tx_pathname, Volume);
559
560 ACMAudioPathSwitch(Rx_pathname, Tx_pathname, Volume);
561
562 //get the gain for voice
563 if (ACM_RC_OK_HIFI_MATCHED == APHAudioPathCheck (Rx_pathname, Tx_pathname))
564 {
565 LOGE( AC_SwitchPath, "%s/L%d: RX is matched with TX about HIFI. Not need to get gain.",__FUNCTION__, __LINE__);
566 return;
567 }
568
569 get_msa_gain_by_path_name(Rx_pathname, Tx_pathname, 100, &input_gain, &input_gain_wb, &tx_sidetone_gain, &tx_sidetone_gain_wb, use_extra_vol);
570 get_msa_gain_by_path_name(Rx_pathname, Rx_pathname, vc_output_vol, &output_gain, &output_gain_wb, &rx_sidetone_gain, &rx_sidetone_gain_wb, use_extra_vol);
571
572 LOGI(AC_SwitchPath, "%s/L%d: input_gain = %d, input_gain_wb=%d, output_gain = %d, output_gain_wb=%d.use_extra_vol=%d.\n",
573 __FUNCTION__, __LINE__, input_gain, input_gain_wb, output_gain, output_gain_wb, use_extra_vol);
574
575 gain->path_direction_Rx = VCM_PATH_OUT;
576 gain->digital_gain_Rx = output_gain | (output_gain_wb << 8);
577 gain->volume_Rx = vc_output_vol;
578
579 gain->path_direction_Tx = VCM_PATH_IN;
580 gain->digital_gain_Tx = input_gain | (input_gain_wb << 8);
581 gain->volume_Tx = vc_output_vol;
582
583 gain->path_direction_SideTone = VCM_PATH_SIDETONE;
584 gain->digital_gain_SideTone = rx_sidetone_gain | (rx_sidetone_gain_wb << 8);
585 gain->volume_SideTone = vc_output_vol;
586
587 LOGI(AC_SwitchPath, "%s/L%d: digital_gain_Rx = %d, volume_Rx=%d, digital_gain_Tx = %d, volume_Tx=%d, digital_gain_SideTone=%d.\n",
588 __FUNCTION__, __LINE__, gain->digital_gain_Rx, gain->volume_Rx, gain->digital_gain_Tx, gain->volume_Tx, gain->digital_gain_SideTone);
589
590}
591
592#ifdef TARGET_mmp_asr1901_KSTR901
593extern void ACM_SendVEtoADSP(void);
594#endif
595
596//server to handle the message from client which is from CATSTUDIO tools ....
597static void ACM_Calibration_Socket_Server_Thread(void *data) {
598 (void)data;
599 unsigned int len;
600 struct sockaddr_un un;
601 AC_IPC_Package rcv_buf;
602
603 prctl(15,"ac_thread");
604 /* create a UNIX domain stream socket */
605 if ((fd_server = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) {
606 LOGE(ACM_Calibration_Socket_Server_Thread, "[Audio Calibration][%s][%d][create socket fail]\n", __FUNCTION__, __LINE__);
607 return;
608 }
609
610 unlink(ACM_CALIBRATION_SOCKET); /* in case it already exists */
611
612 /* fill in socket address structure */
613 memset(&un, 0, sizeof(un));
614 un.sun_family = AF_UNIX;
615 strcpy(un.sun_path, ACM_CALIBRATION_SOCKET);
616 len = offsetof(struct sockaddr_un, sun_path) + strlen(ACM_CALIBRATION_SOCKET);
617
618 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: addr=%s.\n", __FUNCTION__, __LINE__, un.sun_path);
619
620 /* bind the name to the descriptor */
621 if (bind(fd_server, (struct sockaddr *)&un, len) < 0) {
622
623 LOGE(ACM_Calibration_Socket_Server_Thread, "[Audio Calibration][%s][%d][bind fail][error %d (%s)]\n" \
624 , __FUNCTION__, __LINE__,errno, strerror(errno));
625 close(fd_server);
626 return;
627 }
628
629 if (chmod(ACM_CALIBRATION_SOCKET, 0666) < 0) {
630 LOGE(ACM_Calibration_Socket_Server_Thread, "[Audio Calibration][%s][%d]FAIL to chmod ACM_CALIBRATION_SOCKET to 0666\n", __FUNCTION__, __LINE__);
631 close(fd_server);
632 return;
633 }
634 if (listen(fd_server, QLEN) < 0) { /* tell kernel we're a server */
635 LOGE(ACM_Calibration_Socket_Server_Thread, "[Audio Calibration][%s][%d][listen fail]\n", __FUNCTION__, __LINE__);
636 close(fd_server);
637 return;
638 }
639
640 while(1) {
641 len = sizeof(un);
642 //close last connection
643 if (clientfd_server >= 0) {
644 close(clientfd_server);
645 clientfd_server = -1;
646 //usleep(10000);
647 }
648
649 if ((clientfd_server = accept(fd_server, (struct sockaddr *)&un, &len)) < 0) {
650 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Audio Calibration accept fail\n", __FUNCTION__, __LINE__);
651 continue;
652 }
653
654 if(read(clientfd_server, &rcv_buf, sizeof(rcv_buf))==-1) {
655 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: read fail\n", __FUNCTION__, __LINE__);
656 continue;
657 }
658
659 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: [receive type:0x%lx]-[d1:0x%lx][d2:0x%lx][d3:0x%lx][d4:0x%lx]\n",
660 __FUNCTION__, __LINE__,
661 rcv_buf.type, rcv_buf.body.d1, rcv_buf.body.d2, rcv_buf.body.d3, rcv_buf.body.d4);
662
663 switch (rcv_buf.type) {
664 case AUDIO_PHY_GetPathList:
665 {
666 PathsList paths_list;
667 int i = 0;
668 const ACMAPH_AudioPathID *path_config_table = NULL;
669
670 memset(&paths_list, 0x00, sizeof(paths_list));
671 path_config_table = ACM_GetPathConfigTable();
672
673 while (i < APH_PATH_ID_CNT)
674 {
675 strcpy(paths_list.path[paths_list.num++], (const char *)path_config_table[i].PathName);
676 i++;
677 }
678
679 if(write(clientfd_server, &paths_list, sizeof(paths_list)) == -1)
680 {
681 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Get paths list failed", __FUNCTION__, __LINE__);
682 continue;
683 }
684
685 for(i = 0; i < paths_list.num; i++)
686 {
687 LOGI(ACM_Calibration_Socket_Server_Thread, " : %s\n", paths_list.path[i]);
688 }
689
690 break;
691 }
692
693 case AUDIO_PHY_GetPathStatus:
694 {
695 char tmp_buffer[PATHSTATUS_MAX] = {0};
696
697 if (ACMGetPathStatus(tmp_buffer, PATHSTATUS_MAX) != ACM_RC_OK)
698 {
699 sprintf(tmp_buffer, "-> Fail to get status!\n");
700 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
701 continue;
702 }
703
704 LOGI(ACM_Calibration_Socket_Server_Thread, "%s.......", tmp_buffer);
705
706 if(write(clientfd_server, tmp_buffer, PATHSTATUS_MAX*sizeof(char)) == -1)
707 {
708 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
709 continue;
710 }
711
712 break;
713 }
714
715 case AUDIO_PHY_GetAudioMode:
716 {
717 audio_mode_t mode = AUDIO_MODE_INVALID;
718 int pcm_role = 0;
719 int pcm_rate = 0;
720
721 get_pcm_config(&pcm_role, &pcm_rate);
722 LOGI(ACM_Calibration_Socket_Server_Thread, "%s: modem_is_master=%s, modem_is_wb=%s.......", __FUNCTION__, pcm_role?"TRUE":"FALSE", pcm_rate?"WB":"NB");
723
724 mode = ACMGetAudioMode();
725
726 if ((mode != AUDIO_MODE_NORMAL) && (mode != AUDIO_MODE_IN_CALL))
727 {
728 LOGE(ACM_Calibration_Socket_Server_Thread, "mode is not AUDIO_MODE_NORMAL and AUDIO_MODE_IN_CALL");
729 continue;
730 }
731
732 LOGI(ACM_Calibration_Socket_Server_Thread, "mode = %s.......",
733 (mode == AUDIO_MODE_NORMAL) ? "AUDIO_MODE_NORMAL" : "AUDIO_MODE_IN_CALL");
734
735 if(write(clientfd_server, &mode, sizeof(audio_mode_t)) == -1)
736 {
737 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Get mode failed", __FUNCTION__, __LINE__);
738 continue;
739 }
740
741 break;
742 }
743 case AUDIO_PHY_ReloadCalibrationData:
744 {
745 AC_Digital_Gain gain;
746
747 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: ReloadCalibrationData", __FUNCTION__, __LINE__);
748 memset(&gain, 0x00, sizeof(AC_Digital_Gain));
749
750 AC_ReloadCalibrationData(&gain);
751
752 if(write(clientfd_server, &gain, sizeof(AC_Digital_Gain)) == -1) {
753 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Audio Calibration failed", __FUNCTION__, __LINE__);
754 continue;
755 }
756 }
757
758 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: ReloadCalibrationData", __FUNCTION__, __LINE__);
759 break;
760
761 case AUDIO_PHY_SetPathVolume:
762 {
763 AC_Digital_Gain gain;
764
765 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: SetPathVolume", __FUNCTION__, __LINE__);
766 memset(&gain, 0x00, sizeof(AC_Digital_Gain));
767 AC_SetPathVolume(&rcv_buf.body, &gain);
768
769 if(write(clientfd_server, &gain, sizeof(AC_Digital_Gain)) == -1) {
770 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Audio Calibration failed", __FUNCTION__, __LINE__);
771 continue;
772 }
773 }
774 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: SetPathVolume", __FUNCTION__, __LINE__);
775 break;
776
777 case AUDIO_PHY_EnablePath:
778 {
779 AC_Digital_Gain gain;
780
781 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: EnablePath", __FUNCTION__, __LINE__);
782 memset(&gain, 0x00, sizeof(AC_Digital_Gain));
783 AC_EnablePath(&rcv_buf.body, &gain);
784
785 if(write(clientfd_server, &gain, sizeof(AC_Digital_Gain)) == -1) {
786 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Audio Calibration failed", __FUNCTION__, __LINE__);
787 continue;
788 }
789 }
790
791 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: EnablePath", __FUNCTION__, __LINE__);
792 break;
793
794 case AUDIO_PHY_DisablePath:
795 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: DisablePath", __FUNCTION__, __LINE__);
796 AC_DisablePath(&rcv_buf.body);
797 break;
798
799 case AUDIO_PHY_MutePath:
800 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: MutePath", __FUNCTION__, __LINE__);
801 AC_MutePath(&rcv_buf.body);
802 break;
803
804 case AUDIO_PHY_SwitchPath:
805 {
806 AC_Digital_Gain gain;
807
808 memset(&gain, 0x00, sizeof(AC_Digital_Gain));
809 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: SwitchPath", __FUNCTION__, __LINE__);
810 AC_SwitchPath(&rcv_buf.body, &gain);
811
812 if(write(clientfd_server, &gain, sizeof(AC_Digital_Gain)) == -1) {
813 LOGE(ACM_Calibration_Socket_Server_Thread, "%s/L%d: Audio Calibration failed", __FUNCTION__, __LINE__);
814 continue;
815 }
816 }
817
818 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: SwitchPath", __FUNCTION__, __LINE__);
819 break;
820
821#ifdef TARGET_mmp_asr1901_KSTR901
822 case AUDIO_PHY_SendVEtoADSP:
823 LOGI(ACM_Calibration_Socket_Server_Thread, "%s/L%d: SendVEtoADSP", __FUNCTION__, __LINE__);
824 ACM_SendVEtoADSP();
825 break;
826#endif
827
828 default:
829 continue;
830 }
831 }
832
833 unlink(ACM_CALIBRATION_SOCKET);
834 return;
835}
836
837
838void ACM_Init_Calibration_IPC(void)
839{
840 pthread_create( &ACM_Calibration_Server, NULL, (void *)ACM_Calibration_Socket_Server_Thread, NULL);
841}
842
843void ACM_Cancel_Calibration_IPC(void)
844{
845 pthread_cancel(ACM_Calibration_Server);
846
847 if (pthread_join(ACM_Calibration_Server, NULL)) {
848 LOGE(ACM_Cancel_Calibration_IPC, "%s/L%d: fail to pthread_join() ACM_Calibration_Server", __FUNCTION__, __LINE__);
849 }
850
851 if (fd_server >= 0) {
852 close(fd_server);
853 fd_server = -1;
854 LOGE(ACM_Cancel_Calibration_IPC, "%s/L%d: close fd_server.", __FUNCTION__, __LINE__);
855 }
856
857 if (clientfd_server >= 0) {
858 close(clientfd_server);
859 clientfd_server = -1;
860 LOGE(ACM_Cancel_Calibration_IPC, "%s/L%d: close clientfd_server.", __FUNCTION__, __LINE__);
861 }
862
863 return;
864}