blob: dfa6b5fde9c354525b4ffbbe87ef652a3e9b3c08 [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#define LOG_TAG "acm_aph"
25#define LOG_NDEBUG 0
26
27#include <stdio.h>
28#include <unistd.h> //usleep
29#include <cutils/properties.h>
30#include <stdlib.h>
31#include <cutils/log.h>
32#include "acm_aph.h"
33#include "acm_param.h"
34#include <stdlib.h>
35
36#ifdef PXA1826_AUDIO
37#include "audio_stub.h"
38#include <sys/ioctl.h>
39#include <fcntl.h>
40#endif
41
42#ifdef TARGET_mmp_asr1901_KSTR901
43#include "audio_dsp.h"
44#include "adsp_ve.h"
45#endif
46
47#include "audioCalibration.h"
48
49//-----------------------------------------------------------------------------
50//Codec Definitions:
51// CODEC_PM812/CODEC_PM805/CODEC_NAU8810/CODEC_ALC5616/CODEC_NONE is defined in openwrt\package\libs\pxa1826_audio
52// CODEC_I2S_MASTER/CODEC_I2S_SLAVE/CODEC_PCM_MASTER/CODEC_PCM_SLAVE is defined in openwrt\package\libs\pxa1826_audio
53//-----------------------------------------------------------------------------
54#if defined(CODEC_PM812)
55//PM812 is connected
56#include "acm_pm812.h"
57static BOOL acm_codec_connected = TRUE;
58#elif defined(CODEC_PM805)
59//PM805 is connected
60#include "acm_pm805.h"
61static BOOL acm_codec_connected = TRUE;
62#elif defined(CODEC_NAU8810)
63//NAU8810 is connected
64#include "acm_nau8810.h"
65static BOOL acm_codec_connected = TRUE;
b.liub17525e2025-05-14 17:22:29 +080066#elif defined(CODEC_ES8311)
67#include "acm_es8311.h"
68static BOOL acm_codec_connected = TRUE;
69#elif defined(CODEC_TLV320AIC3X)
70#include "acm_tlv320aic3x.h"
71static BOOL acm_codec_connected = TRUE;
b.liue9582032025-04-17 19:18:16 +080072#elif defined(CODEC_ALC5616)
73//ALC5616 is connected
74#include "acm_alc5616.h"
75static BOOL acm_codec_connected = TRUE;
76#else
77//No codec is connected
78static BOOL acm_codec_connected = FALSE;
79static ACMAPH_Component ACM_Enable[APH_PATH_ID_CNT]={};
80static ACMAPH_Component ACM_Disable[APH_PATH_ID_CNT]={};
81static ACMAPH_Component ACM_Mute[APH_PATH_IN_CNT]={};
82static ACMAPH_Component ACM_UnMute[APH_PATH_IN_CNT]={};
83static ACMAPH_VolumeComponent ACM_Volume[APH_PATH_OUT_CNT]={};
84static APH_ACHComponent ACH_component_table[AUDIO_COMPONENT_CNT]={};
85//Sorted as APH_AudioComponent
86static char APH_AudioComponent_Name[AUDIO_COMPONENT_CNT][16]= {} ;
87#endif
88
89
90//--------------------------------------------------------------
91//-------- Global Information Tables
92//--------------------------------------------------------------
93
94static int modem_is_wb = 0, modem_is_master = 0;
95
96const ACMAPH_AudioPathID AUDIO_PATH_ID_MAPPING[APH_PATH_ID_CNT] = {
97 {APH_PATH_ID_HIFIPLAYTOEARPHONE, "HiFiPlayToEarphone" },
98 {APH_PATH_ID_HIFIPLAYTOSPKR, "HiFiPlayToSPKR" },
99 {APH_PATH_ID_HIFIPLAYTOHP, "HiFiPlayToHP" },
100 {APH_PATH_ID_HIFIRECORDFROMMIC1, "HiFiRecordFromMic1" },
101 {APH_PATH_ID_HIFIRECORDFROMHSMIC, "HiFiRecordFromHsMic" },
102 {APH_PATH_ID_VOICEPLAYTOEARPHONE, "VoicePlayToEarphone" },
103 {APH_PATH_ID_VOICEPLAYTOSPKR, "VoicePlayToSPKR" },
104 {APH_PATH_ID_VOICEPLAYTOHP, "VoicePlayToHP" },
105 {APH_PATH_ID_VOICERECORDFROMMIC1, "VoiceRecordFromMic1" },
106 {APH_PATH_ID_VOICERECORDFROMHSMIC, "VoiceRecordFromHsMic"},
107};
108
109APH_PathStatus path_status_table[APH_PATH_ID_CNT] = {
110 {0, 0, 0},
111 {0, 0, 0},
112 {0, 0, 0},
113 {0, 0, 0},
114 {0, 0, 0},
115 {0, 0, 0},
116 {0, 0, 0},
117 {0, 0, 0},
118 {0, 0, 0},
119 {0, 0, 0}
120};
121
122/* 1:on; 0:off */
123static int g_audio_if_debug_mode = 0;
124
125int get_debug_mode(void)
126{
127 return g_audio_if_debug_mode;
128}
129
130void set_debug_mode(int onoff)
131{
132 g_audio_if_debug_mode = onoff;
133}
134
135void configCodecGainfromNVM(APH_AudioComponent Component_NVM, unsigned char Address_NVM, unsigned short Value_NVM);
136extern int NVM_Calibration_IPC(AC_IPC_Package *package);
137
138const ACMAPH_AudioPathID *ACM_GetPathConfigTable() {
139 return AUDIO_PATH_ID_MAPPING ;
140}
141
142void get_pcm_config(int *p_role, int *p_rate)
143{
144 *p_role = modem_is_master;
145 *p_rate = modem_is_wb;
146 return;
147}
148
149void set_pcm_config(int role, int rate)
150{
151 modem_is_master = role;
152 modem_is_wb = rate;
153
154#if defined(CODEC_ALC5616)
155#ifdef TARGET_mmp_asr1901_KSTR901
156 if (3 == modem_is_wb) {
157 LOGI(set_pcm_config, "%s: modem switch to 48KHz for ALC5616 in Kestrel.", __FUNCTION__);
158 system("echo 3 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.1/i2c-1/1-001b/alc5616_switch_rate");
159 } else if (2 == modem_is_wb){
160 LOGI(set_pcm_config, "%s: modem switch to 32KHz for ALC5616 in Kestrel.", __FUNCTION__);
161 system("echo 2 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.1/i2c-1/1-001b/alc5616_switch_rate");
162 } else if (1 == modem_is_wb) {
163 LOGI(set_pcm_config, "%s: modem switch to WB for ALC5616 in Kestrel.", __FUNCTION__);
164 system("echo 1 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.1/i2c-1/1-001b/alc5616_switch_rate");
165 } else if (0 == modem_is_wb) {
166 LOGI(set_pcm_config, "%s: modem switch to NB for ALC5616 in Kestrel.", __FUNCTION__);
167 system("echo 0 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.1/i2c-1/1-001b/alc5616_switch_rate");
168 } else {
169 LOGI(set_pcm_config, "%s: modem switch to NB for ALC5616 in Kestrel.", __FUNCTION__);
170 system("echo 0 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.1/i2c-1/1-001b/alc5616_switch_rate");
171 }
172#else
173 if (1 == modem_is_wb) {
174 LOGI(set_pcm_config, "%s: modem switch to WB for ALC5616.", __FUNCTION__);
175 system("echo 1 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.0/i2c-0/0-001b/alc5616_switch_rate");
176 } else {
177 LOGI(set_pcm_config, "%s: modem switch to NB for ALC5616.", __FUNCTION__);
178 system("echo 0 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.0/i2c-0/0-001b/alc5616_switch_rate");
179 }
180#endif
181#endif
182
183 LOGI(set_pcm_config, "%s: modem_is_master=%s, modem_is_wb=%s.", __FUNCTION__, modem_is_master?"TRUE":"FALSE", modem_is_wb?"WB":"NB");
184 return;
185}
186
187static int _get_path_id(const char *path) {
188 const ACMAPH_AudioPathID *ptr;
189 const char *PathName;
190 unsigned int i = 0, size;
191
192 if(path == NULL)
193 return INVALID_PATH_ID;
194
195 size = sizeof(AUDIO_PATH_ID_MAPPING)/sizeof(ACMAPH_AudioPathID);
196 ptr = &AUDIO_PATH_ID_MAPPING[0];
197 while (i < size) {
198 PathName = ptr->PathName;
199 if (strcmp((const char *)path, (const char *)PathName) == 0) {
200 LOGI(_get_path_id, "%s: path=%s, PathName=%s,PathID=%d, i=%d", __FUNCTION__, path, PathName,ptr->PathID, i);
201 return ptr->PathID;
202 }
203
204 ptr++;
205 i++;
206 }
207
208 return INVALID_PATH_ID;
209}
210
211static ACMAPH_Component *_get_APHTable(APH_PATH_ID path_id, ACMAPH_Component *pTable, unsigned char max) {
212 int i = 0;
213
214 for (i = 0; i < max; i++) {
215 if (pTable[i].PathID == path_id) {
216 LOGI(_get_APHTable, "%s: path_id=%d", __FUNCTION__, path_id);
217 return &pTable[i];
218 }
219 }
220
221 return NULL;
222}
223
b.liub17525e2025-05-14 17:22:29 +0800224#if !defined(CODEC_PM805) && !defined(CODEC_PM812) && !defined(CODEC_NAU8810) && !defined(CODEC_ALC5616)&&!defined(CODEC_TLV320AIC3X)&& !defined(CODEC_ES8311)
b.liue9582032025-04-17 19:18:16 +0800225static ACMAPH_VolumeComponent *_get_APHVolumeTable(APH_PATH_ID path_id, ACMAPH_VolumeComponent *pTable, unsigned char max) {
226 int i = 0;
227
228 for (i = 0; i < max; i++) {
229 if (pTable[i].PathID == path_id) {
230 LOGI(_get_APHVolumeTable, "%s: path_id=%d", __FUNCTION__, path_id);
231 return &pTable[i];
232 }
233 }
234
235 return NULL;
236}
237#endif
238
239static ACH_ComponentHandler *_get_component_handler(APH_AudioComponent component_id) {
240 int size = sizeof(ACH_component_table) / sizeof(ACH_component_table[0]);
241 int i = 0;
242
243 for (i = 0; i < size; i++) {
244 if (ACH_component_table[i].component_id == component_id) {
245 LOGI(_get_component_handler, "%s: component_id=%d", __FUNCTION__, component_id);
246 return ACH_component_table[i].component_handler;
247 }
248 }
249
250 return NULL;
251}
252
253static void _reset_components_registers() {
254 int size = sizeof(ACH_component_table) / sizeof(ACH_component_table[0]);
255 int i = 0;
256
257 /* Disable all components when init.*/
258 for (i = 0; i < size; i++) {
259 if (ACH_component_table[i].component_handler) {
260 ACH_component_table[i].component_handler->ACH_Reset();
261 }
262 }
263}
264
265static void _reset_components_status() {
266 int size = sizeof(ACH_component_table) / sizeof(ACH_component_table[0]);
267 int i = 0;
268
269 for (i = 0; i < size; i++) {
270 ACH_component_table[i].component_handler->active = COMPONENT_INACTIVE;
271 ACH_component_table[i].component_handler->ref_count = 0;
272 }
273
274 /* Disable all components when init.*/
275 for (i = 0; i < size; i++) {
276 ACH_component_table[i].component_handler->ACH_Disable();
277 }
278}
279
280static ACM_ReturnCode _get_path_direction(const char *path, unsigned char *path_direction) {
281 ACM_ReturnCode ret = ACM_RC_INVALID_PARAMETER;
282 if(path != NULL) {
283 if(strstr((const char *)path, "PlayTo") != NULL) {
284 *path_direction = PATH_DIRECTION_OUT;
285 ret = ACM_RC_OK;
286 }
287 if(strstr((const char *)path, "RecordFrom") != NULL) {
288 *path_direction = PATH_DIRECTION_IN;
289 ret = ACM_RC_OK;
290 }
291 }
292 return ret;
293}
294
295char * ACM_GetPathName(int PathID) {
296 const ACMAPH_AudioPathID *ptr;
297 unsigned int i = 0, size;
298
299 if(PathID >= APH_PATH_ID_CNT) {
300 return NULL;
301 }
302
303 size = sizeof(AUDIO_PATH_ID_MAPPING)/sizeof(ACMAPH_AudioPathID);
304 ptr = &AUDIO_PATH_ID_MAPPING[0];
305 while (i < size) {
306 if (PathID == ptr->PathID) {
307 LOGI(_get_PathName, "%s: PathName=%s, PathID=%d, i=%d", __FUNCTION__, ptr->PathName,ptr->PathID, i);
308 return ptr->PathName;
309 }
310
311 ptr++;
312 i++;
313 }
314
315 return NULL;
316}
317
318ACM_ReturnCode APHAudioPathEnable(const char * path, unsigned int value) {
319 int path_id = INVALID_PATH_ID;
320 APH_AudioComponent component;
321 ACMAPH_Register *RegisterList;
322 unsigned int i, size;
323 ACH_ComponentParameter param;
324 ACH_ComponentHandler *component_handler = NULL;
325 ACMAPH_Component *pTable = NULL;
326
327 LOGI(APHAudioPathEnable, "%s/L%d: modem_is_wb=%d, modem_is_master=%d, value=0x%x", __FUNCTION__, __LINE__, modem_is_wb, modem_is_master, value);
328
329 if(acm_codec_connected == TRUE){
330 LOGI(APHAudioPathEnable, "%s/L%d: path=%s, value=0x%x", __FUNCTION__, __LINE__, path, value);
331 }
332 else {
333 LOGE(APHAudioPathEnable, "%s/L%d: path=%s, no codec connected!", __FUNCTION__, __LINE__, path);
334 return ACM_RC_INVALID_PARAMETER;
335 }
336
337 path_id = _get_path_id(path);
338 if(path_id == INVALID_PATH_ID){
339 LOGE(APHAudioPathEnable, "%s/L%d: Error path_id=%d", __FUNCTION__, __LINE__, path_id);
340 return ACM_RC_INVALID_PATH;
341 }
342
343 pTable = _get_APHTable(path_id, ACM_Enable, APH_PATH_ID_CNT);
344 if(pTable == NULL){
345 LOGE(APHAudioPathEnable, "%s/L%d: Error pTable=%d", __FUNCTION__, __LINE__, pTable);
346 return ACM_RC_INVALID_PATH;
347 }
348
349 if(path_status_table[path_id].enabled != 0){
350 LOGE(APHAudioPathEnable, "%s/L%d: Already enable path %s(%d)", __FUNCTION__, __LINE__, path, path_id);
351 return ACM_RC_PATH_ALREADY_ENABLED;
352 }
353 else{
354 path_status_table[path_id].enabled = 1;
355 }
356
357 size = pTable->RegisterNum;
358 RegisterList = pTable->RegisterList;
359
360 for(i = 0; i < size; i++){
361 // get matched component
362 component = RegisterList[i].Component;
363 if(component == DELAY){
364 usleep(RegisterList[i].Value * 1000);
365 continue;
366 }
367
368 if(_get_component_handler(component) != component_handler ){
369 component_handler = _get_component_handler(component);
370
371 ///update component_handler-->ref_count: it depends on registers sorting style
372 component_handler->ref_count++;
373 LOGI(APHAudioPathEnable, "%s/L%d: component=%s, ref_count=%d", __FUNCTION__, __LINE__, APH_AudioComponent_Name[component], component_handler->ref_count);
374 }
375
376 //firstly enable component
377 if(component_handler->active == COMPONENT_INACTIVE){
378 component_handler->ACH_Enable();
379 component_handler->active = COMPONENT_ACTIVE;
380 }
381
382 /*
383 * Set value according to modem_is_wb & modem_is_master
384 *
385 */
386 //The registers of PM812 are identical with PM805
387#if defined(CODEC_PM812)
388 if( RegisterList[i].Address == CODEC_PM812_VOICE_REG35){
389 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_master?"master":"slave");
390 if (1 == modem_is_master)
391 RegisterList[i].Value = CODEC_PM812_VOICE_SLAVE;
392 else
393 RegisterList[i].Value = CODEC_PM812_VOICE_MASTER;
394 }
395
396 if( RegisterList[i].Address == CODEC_PM812_VOICE_REG36){
397 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_wb?"16KHz":"8KHz");
398 if (1 == modem_is_wb)
399 RegisterList[i].Value = CODEC_PM812_VOICE_WB;
400 else
401 RegisterList[i].Value = CODEC_PM812_VOICE_NB;
402 }
403#elif defined(CODEC_PM805)
404 if( RegisterList[i].Address == CODEC_PM805_AUDIO_REG30){
405 #if defined(CODEC_I2S_MASTER)
406 RegisterList[i].Value = CODEC_PM805_AUDIO_MASTER;
407 LOGI(APHAudioPathEnable, "%s/L%d: CODEC_PM805_AUDIO_MASTER.", __FUNCTION__, __LINE__);
408 #endif
409
410 #if defined(CODEC_I2S_SLAVE)
411 RegisterList[i].Value = CODEC_PM805_AUDIO_SLAVE;
412 LOGI(APHAudioPathEnable, "%s/L%d: CODEC_PM805_AUDIO_SLAVE.", __FUNCTION__, __LINE__);
413 #endif
414 }
415
416 if( RegisterList[i].Address == CODEC_PM805_VOICE_REG35){
417 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_master?"master":"slave");
418 if (1 == modem_is_master)
419 RegisterList[i].Value = CODEC_PM805_VOICE_SLAVE;
420 else
421 RegisterList[i].Value = CODEC_PM805_VOICE_MASTER;
422 }
423
424 if( RegisterList[i].Address == CODEC_PM805_VOICE_REG36){
425 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_wb?"16KHz":"8KHz");
426 if (1 == modem_is_wb)
427 RegisterList[i].Value = CODEC_PM805_VOICE_WB;
428 else
429 RegisterList[i].Value = CODEC_PM805_VOICE_NB;
430 }
431#elif defined(CODEC_NAU8810)
432 if( RegisterList[i].Address == CODEC_NAU8810_VOICE_REG06){
433 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_master?"master":"slave");
434 if (1 == modem_is_master)
435 RegisterList[i].Value = CODEC_NAU8810_VOICE_SLAVE;
436 else
437 RegisterList[i].Value = CODEC_NAU8810_VOICE_MASTER;
438 }
439
440 if( RegisterList[i].Address == CODEC_NAU8810_VOICE_REG07){
441 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_wb?"16KHz":"8KHz");
442 if (1 == modem_is_wb)
443 RegisterList[i].Value = CODEC_NAU8810_VOICE_WB;
444 else
445 RegisterList[i].Value = CODEC_NAU8810_VOICE_NB;
446 }
b.liub17525e2025-05-14 17:22:29 +0800447#elif defined(CODEC_ES8311)
448 /* es8311 customer codec always as slave and fix 256fs , we have config it in enable path */
449#elif defined(CODEC_TLV320AIC3X)
450
451
b.liue9582032025-04-17 19:18:16 +0800452#elif defined(CODEC_ALC5616)
453 if( RegisterList[i].Address == CODEC_ALC5616_VOICE_REG70){
454 LOGI(APHAudioPathEnable, "%s/L%d: modem PCM is %s", __FUNCTION__, __LINE__, modem_is_master?"master":"slave");
455 if (1 == modem_is_master)
456 RegisterList[i].Value = CODEC_ALC5616_VOICE_SLAVE;
457 else
458 RegisterList[i].Value = CODEC_ALC5616_VOICE_MASTER;
459 }
460
461 //WB/NB is set in kernel file driver/mfd/alc5616.c.
462#endif
463 //fill param
464 param.i2c.reg_index = RegisterList[i].Address;
465 param.i2c.reg_value = &RegisterList[i].Value;
466 param.i2c.reg_mask = 0xffff;
467 param.i2c.reg_shift = 0;
468 param.i2c.length = sizeof(short);
469
470 //configure component
471 component_handler->ACH_Handle(&param);
472 }
473
b.liub17525e2025-05-14 17:22:29 +0800474#if defined(CODEC_ES8311)
475 LOGE(APHAudioPathDisable, "%s wil enable audio pa\n", __FUNCTION__);
476
477 system("echo 1 > /sys/bus/i2c/devices/0-0018/opa_gpio_op");
478#endif
479
b.liue9582032025-04-17 19:18:16 +0800480 return ACM_RC_OK;
481}
482
483ACM_ReturnCode APHAudioPathDisable(const char * path) {
484 int path_id = INVALID_PATH_ID;
485 APH_AudioComponent component;
486 ACMAPH_Register *RegisterList;
487 unsigned int i, size;
488 ACH_ComponentParameter param;
489 ACH_ComponentHandler *component_handler = NULL;
490 ACMAPH_Component *pTable = NULL;
491
492 if(acm_codec_connected == TRUE){
493 LOGI(APHAudioPathDisable, "%s/L%d: path=%s", __FUNCTION__, __LINE__, path);
494 }
495 else {
496 LOGE(APHAudioPathDisable, "%s/L%d: path=%s, no codec connected!", __FUNCTION__, __LINE__, path);
497 return ACM_RC_INVALID_PARAMETER;
498 }
499
500 path_id = _get_path_id(path);
501 if(path_id == INVALID_PATH_ID){
502 LOGE(APHAudioPathDisable, "%s/L%d: Error path_id=%d", __FUNCTION__, __LINE__, path_id);
503 return ACM_RC_INVALID_PATH;
504 }
505
506 pTable = _get_APHTable(path_id, ACM_Disable, APH_PATH_ID_CNT);
507 if(pTable == NULL){
508 LOGE(APHAudioPathDisable, "%s/L%d: Error pTable=%d", __FUNCTION__, __LINE__, pTable);
509 return ACM_RC_INVALID_PATH;
510 }
511
512 if(path_status_table[path_id].enabled == 0){
513 LOGE(APHAudioPathDisable, "%s/L%d: Already disable path %s(%d)", __FUNCTION__, __LINE__, path, path_id);
514 return ACM_RC_PATH_ALREADY_DISABLED;
515 }
516 else{
517 path_status_table[path_id].enabled = 0;
518 ////path_status_table[path_id].value = 0; // Save volume even after disabled
519 path_status_table[path_id].mute = 0;
520 }
b.liub17525e2025-05-14 17:22:29 +0800521#if defined(CODEC_ES8311)
522
523 LOGE(APHAudioPathDisable, "%s will disable audio ap! \n", __FUNCTION__);
524 system("echo 0 > /sys/bus/i2c/devices/0-0018/opa_gpio_op");
525
526#endif
b.liue9582032025-04-17 19:18:16 +0800527
528 size = pTable->RegisterNum;
529 RegisterList = pTable->RegisterList;
530
531 for(i = 0; i < size; i++){
532 // get matched component
533 component = RegisterList[i].Component;
534 if(component == DELAY){
535 usleep(RegisterList[i].Value * 1000);
536 continue;
537 }
538
539 if(_get_component_handler(component) != component_handler ){
540 component_handler = _get_component_handler(component);
541
542 ///update component_handler-->ref_count: it depends on registers sorting style
543 component_handler->ref_count--;
544 LOGI(APHAudioPathDisable, "%s/L%d: component=%s, ref_count=%d", __FUNCTION__, __LINE__, APH_AudioComponent_Name[component], component_handler->ref_count);
545 }
546
547 //fill param
548 param.i2c.reg_index = RegisterList[i].Address;
549 param.i2c.reg_value = &RegisterList[i].Value;
550 param.i2c.reg_mask = 0xffff;
551 param.i2c.reg_shift = 0;
552 param.i2c.length = sizeof(short);
553
554 //configure component
555 component_handler->ACH_Handle(&param);
556
557 //Last: if this component is not referred anymore,disable component
558 if(component_handler->ref_count == 0){
559 if(component_handler->active == COMPONENT_ACTIVE){
560 component_handler->ACH_Disable();
561 component_handler->active = COMPONENT_INACTIVE;
562 }
563 }
564 }
565
566 return ACM_RC_OK;
567}
568
569ACM_ReturnCode APHAudioPathCheckPathId (int path_id_Rx, int path_id_Tx) {
570
571 if ((path_id_Rx == INVALID_PATH_ID) || (path_id_Tx == INVALID_PATH_ID))
572 {
573 LOGE(APHAudioPathCheckPathId, "%s/L%d: Error", __FUNCTION__, __LINE__);
574 return ACM_RC_INVALID_PATH;
575 }
576
577 if (((APH_PATH_ID_HIFIPLAYTOEARPHONE == path_id_Rx) ||(APH_PATH_ID_HIFIPLAYTOSPKR == path_id_Rx))
578 && (APH_PATH_ID_HIFIRECORDFROMMIC1 == path_id_Tx))
579 {
580 return ACM_RC_OK_HIFI_MATCHED;
581 }
582 else if ((APH_PATH_ID_HIFIPLAYTOHP == path_id_Rx) && (APH_PATH_ID_HIFIRECORDFROMHSMIC == path_id_Tx))
583 {
584 return ACM_RC_OK_HIFI_MATCHED;
585 }
586 else if (((APH_PATH_ID_VOICEPLAYTOEARPHONE == path_id_Rx) ||(APH_PATH_ID_VOICEPLAYTOSPKR == path_id_Rx)
587 || (APH_PATH_ID_VOICEPLAYTOHP == path_id_Rx))
588 && (APH_PATH_ID_VOICERECORDFROMMIC1 == path_id_Tx))
589 {
590 return ACM_RC_OK_VOICE_MATCHED;
591 }
592 else if ((APH_PATH_ID_VOICEPLAYTOHP == path_id_Rx) && (APH_PATH_ID_VOICERECORDFROMHSMIC == path_id_Tx))
593 {
594 return ACM_RC_OK_VOICE_MATCHED;
595 }
596 else
597 {
598 return ACM_RC_PATH_CONFIG_NOT_EXIST;
599 }
600
601 return ACM_RC_OK;
602}
603
604ACM_ReturnCode APHAudioPathCheck (const char * path_Rx, const char * path_Tx) {
605
606 int path_id_Rx = INVALID_PATH_ID;
607 int path_id_Tx = INVALID_PATH_ID;
608
609 if ((NULL == path_Rx) || (NULL == path_Tx))
610 {
611 LOGE(APHAudioPathCheck, "%s/L%d: Rx path or Tx path is NULL, please check it.", __FUNCTION__, __LINE__);
612 return ACM_RC_PATH_CONFIG_NOT_EXIST;
613 }
614
615 path_id_Rx = _get_path_id(path_Rx);
616 path_id_Tx = _get_path_id(path_Tx);
617
618 if((path_id_Rx == INVALID_PATH_ID) || (path_id_Tx == INVALID_PATH_ID) )
619 {
620 LOGE(APHAudioPathCheck, "%s/L%d: Error", __FUNCTION__, __LINE__);
621 return ACM_RC_INVALID_PATH;
622 }
623
624 if (((APH_PATH_ID_HIFIPLAYTOEARPHONE == path_id_Rx) ||(APH_PATH_ID_HIFIPLAYTOSPKR == path_id_Rx))
625 && (APH_PATH_ID_HIFIRECORDFROMMIC1 == path_id_Tx))
626 {
627 return ACM_RC_OK_HIFI_MATCHED;
628 }
629 else if ((APH_PATH_ID_HIFIPLAYTOHP == path_id_Rx) && (APH_PATH_ID_HIFIRECORDFROMHSMIC == path_id_Tx))
630 {
631 return ACM_RC_OK_HIFI_MATCHED;
632 }
633 else if (((APH_PATH_ID_VOICEPLAYTOEARPHONE == path_id_Rx) ||(APH_PATH_ID_VOICEPLAYTOSPKR == path_id_Rx)
634 || (APH_PATH_ID_VOICEPLAYTOHP == path_id_Rx))
635 && (APH_PATH_ID_VOICERECORDFROMMIC1 == path_id_Tx))
636 {
637 return ACM_RC_OK_VOICE_MATCHED;
638 }
639 else if ((APH_PATH_ID_VOICEPLAYTOHP == path_id_Rx) && (APH_PATH_ID_VOICERECORDFROMHSMIC == path_id_Tx))
640 {
641 return ACM_RC_OK_VOICE_MATCHED;
642 }
643 else
644 {
645 return ACM_RC_PATH_CONFIG_NOT_EXIST;
646 }
647
648 return ACM_RC_OK;
649}
650
651void APHDisableAllPath(void)
652{
653 int i = 0;
654
655 //disable the enabled path
656 for (i=0; i<APH_PATH_ID_CNT; i++)
657 {
658 //disable the enabled path
659 if ( path_status_table[i].enabled)
660 {
661 LOGI(APHDisableAllPath, "disable the path:%s.......", AUDIO_PATH_ID_MAPPING[i].PathName);
662 ACMAudioPathDisable(AUDIO_PATH_ID_MAPPING[i].PathName);
663 }
664 }
665
666 return;
667}
668
669ACM_ReturnCode APHAudioPathSwitch (const char * path_Rx, const char * path_Tx, unsigned int value) {
670
671 char tmp_buffer[PATHSTATUS_MAX] = {0};
672 int i = 0;
673
674 if ((APHAudioPathCheck(path_Rx, path_Tx) != ACM_RC_OK_HIFI_MATCHED)
675 && (APHAudioPathCheck(path_Rx, path_Tx) != ACM_RC_OK_VOICE_MATCHED))
676 {
677 LOGE(APHAudioPathSwitch, "%s/L%d: Rx path is not matched with Tx path.", __FUNCTION__, __LINE__);
678 return ACM_RC_PATH_CONFIG_NOT_EXIST;
679 }
680
681 if (ACM_GetPathStatus(tmp_buffer, PATHSTATUS_MAX) != ACM_RC_OK)
682 {
683 LOGE(APHAudioPathSwitch, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
684 return ACM_RC_PATH_CONFIG_NOT_EXIST;
685 }
686
687 //before switch, before disable, list the path status
688 LOGI(APHAudioPathSwitch, "before switch, before disable, current every path status is:%s.......", tmp_buffer);
689
690 //disable the enabled path
691 for (i=0; i<APH_PATH_ID_CNT; i++)
692 {
693 //disable the enabled path
694 if ( path_status_table[i].enabled)
695 {
696 LOGI(APHAudioPathSwitch, "disable the path:%s.......", AUDIO_PATH_ID_MAPPING[i].PathName);
697 ACMAudioPathDisable(AUDIO_PATH_ID_MAPPING[i].PathName);
698 }
699 }
700
701 memset(tmp_buffer, 0x00, sizeof(tmp_buffer));
702
703 if (ACM_GetPathStatus(tmp_buffer, PATHSTATUS_MAX) != ACM_RC_OK)
704 {
705 LOGE(APHAudioPathSwitch, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
706 return ACM_RC_PATH_CONFIG_NOT_EXIST;
707 }
708
709 //before switch, after disable, list the path status
710 LOGI(APHAudioPathSwitch, "before switch, after disable, current every path status is:%s.......", tmp_buffer);
711
712 //enable the Rx path, and Tx path
713 ACMAudioPathEnable(path_Rx, value);
714 ACMAudioPathEnable(path_Tx, value);
715
716 memset(tmp_buffer, 0x00, sizeof(tmp_buffer));
717
718 if (ACM_GetPathStatus(tmp_buffer, PATHSTATUS_MAX) != ACM_RC_OK)
719 {
720 LOGE(APHAudioPathSwitch, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
721 return ACM_RC_PATH_CONFIG_NOT_EXIST;
722 }
723
724 //before switch, after disable, list the path status
725 LOGI(APHAudioPathSwitch, "after switch, after disable, current every path status is:%s.......", tmp_buffer);
726
727 return ACM_RC_OK;
728}
729
730ACM_ReturnCode APHAudioPathMute(const char * path, unsigned int value) {
731 int path_id = INVALID_PATH_ID;
732 APH_AudioComponent component;
733 ACMAPH_Register *RegisterList;
734 unsigned int i, size;
735 ACH_ComponentParameter param;
736 ACH_ComponentHandler *component_handler = NULL;
737 ACMAPH_Component *pTable = NULL;
738
739 if(acm_codec_connected == TRUE){
740 LOGI(APHAudioPathMute, "%s/L%d: path=%s, %s", __FUNCTION__, __LINE__, path, value?"Mute":"UnMute");
741 }
742 else {
743 LOGE(APHAudioPathMute, "%s/L%d: path=%s, no codec connected!", __FUNCTION__, __LINE__, path);
744 return ACM_RC_INVALID_PARAMETER;
745 }
746
747 path_id = _get_path_id(path);
748 if(path_id == INVALID_PATH_ID){
749 LOGE(APHAudioPathMute, "%s/L%d: Error path_id=%d", __FUNCTION__, __LINE__, path_id);
750 return ACM_RC_INVALID_PATH;
751 }
752
753 if(value == 0)
754 pTable = _get_APHTable(path_id, ACM_UnMute, APH_PATH_IN_CNT);
755 else
756 pTable = _get_APHTable(path_id, ACM_Mute, APH_PATH_IN_CNT);
757 if(pTable == NULL){
758 LOGE(APHAudioPathMute, "%s/L%d: not in pTable{ACM_Mute,ACM_UnMute}=%d, path=%s", __FUNCTION__, __LINE__, pTable, path);
759 return ACM_RC_INVALID_PATH;
760 }
761
762 if(path_status_table[path_id].enabled == 0){
763 LOGE(APHAudioPathMute, "%s/L%d: Count not operate on disabled path %s(%d)", __FUNCTION__, __LINE__, path, path_id);
764 return ACM_RC_PATH_ALREADY_DISABLED;
765 }
766
767 if(path_status_table[path_id].mute == value){
768 LOGE(APHAudioPathMute, "%s/L%d: path %s(%d) is already %", __FUNCTION__, __LINE__, path, path_id, value?"Mute":"UnMute");
769 return ACM_RC_NO_MUTE_CHANGE_NEEDED;
770 }
771 path_status_table[path_id].mute = value;
772
773 size = pTable->RegisterNum;
774 RegisterList = pTable->RegisterList;
775
776 for(i = 0; i < size; i++){
777 // get matched component
778 component = RegisterList[i].Component;
779 if(component == DELAY){
780 usleep(RegisterList[i].Value * 1000);
781 continue;
782 }
783
784 if(_get_component_handler(component) != component_handler ){
785 component_handler = _get_component_handler(component);
786
787 ///update component_handler-->ref_count: it depends on registers sorting style
788 component_handler->ref_count--;
789 LOGI(APHAudioPathMute, "%s/L%d: component=%s, ref_count=%d", __FUNCTION__, __LINE__, APH_AudioComponent_Name[component], component_handler->ref_count);
790 }
791
792 //fill param
793 param.i2c.reg_index = RegisterList[i].Address;
794 param.i2c.reg_value = &RegisterList[i].Value;
795 param.i2c.reg_mask = 0xffff;
796 param.i2c.reg_shift = 0;
797 param.i2c.length = sizeof(short);
798
799 //configure component
800 component_handler->ACH_Handle(&param);
801 }
802
803 return ACM_RC_OK;
804}
805
806void configCodecGainfromNVM(APH_AudioComponent Component_NVM, unsigned char Address_NVM, unsigned short Value_NVM)
807{
808 ACH_ComponentHandler *component_handler = NULL;
809 APH_AudioComponent component;
810 ACH_ComponentParameter param;
811
812 LOGI(configCodecGainfromNVM,"%s/L%d:: Component=[%d], Address_NVM=[0X%x], Value_NVM=[0X%x] !",
813 __FUNCTION__, __LINE__, Component_NVM, Address_NVM, Value_NVM);
814
815 //if(volume == RegisterList[i].Volume ){
816 // get matched component
817 component = Component_NVM;
818 //component = RegisterList[i].Component;
819 if(component == DELAY)
820 {
821 //usleep(RegisterList[i].Value * 1000);
822 usleep(Value_NVM * 1000);
823 return;
824 }
825
826 if(_get_component_handler(component) != component_handler )
827 {
828 component_handler = _get_component_handler(component);
829
830 ///update component_handler-->ref_count: it depends on registers sorting style
831 component_handler->ref_count--;
832 LOGI(configCodecGainfromNVM, "%s/L%d: component=%s, ref_count=%d", __FUNCTION__, __LINE__, APH_AudioComponent_Name[component], component_handler->ref_count);
833 }
834
835 //fill param
836 param.i2c.reg_index = Address_NVM;
837 param.i2c.reg_value = &Value_NVM;
838 param.i2c.reg_mask = 0xffff;
839 param.i2c.reg_shift = 0;
840 param.i2c.length = sizeof(short);
841
842 LOGI(configCodecGainfromNVM,"%s/L%d:: Address = 0X%x, .Value=0X%x!", __FUNCTION__, __LINE__, Address_NVM, Value_NVM);
843
844 //configure component
845 component_handler->ACH_Handle(&param);
846
847 return;
848}
849
850ACM_ReturnCode APHAudioPathVolumeSet(const char * path, unsigned int value) {
851 int path_id = INVALID_PATH_ID;
852 unsigned char volume = 0;
853 unsigned int i;
854 unsigned char index_volume = 0;
855
b.liub17525e2025-05-14 17:22:29 +0800856#if defined(CODEC_PM805) || defined(CODEC_PM812) || defined(CODEC_NAU8810) || defined(CODEC_ALC5616) || defined(CODEC_TLV320AIC3X)|| defined(CODEC_ES8311)
b.liue9582032025-04-17 19:18:16 +0800857 AC_IPC_Package package;
858 ACMCodec_GainT buffer;
859 AUDIO_PROFILE_ID cur_Profile_id = HIFI_HANDSET;
860
861 APH_AudioComponent Component_NVM;
862 unsigned char Address_NVM;
863 unsigned short Value_NVM;
864
865 memset(&package, 0x00, sizeof(AC_IPC_Package));
866 memset(&buffer, 0x00, sizeof(ACMCodec_GainT));
867#else
868 ACMAPH_VolumeComponent *pTable = NULL;
869#endif
870
871 if(acm_codec_connected == TRUE){
872 LOGI(APHAudioPathVolumeSet, "%s/L%d: path=%s, value=0x%x", __FUNCTION__, __LINE__, path, value);
873 }
874 else {
875 LOGE(APHAudioPathVolumeSet, "%s/L%d: path=%s, no codec connected!", __FUNCTION__, __LINE__, path);
876 return ACM_RC_INVALID_PARAMETER;
877 }
878
879 path_id = _get_path_id(path);
880 if(path_id == INVALID_PATH_ID){
881 LOGE(APHAudioPathVolumeSet, "%s/L%d: Error path_id=%d", __FUNCTION__, __LINE__, path_id);
882 return ACM_RC_INVALID_PATH;
883 }
884
b.liub17525e2025-05-14 17:22:29 +0800885#if defined(CODEC_PM805) || defined(CODEC_PM812) || defined(CODEC_NAU8810) || defined(CODEC_TLV320AIC3X)|| defined(CODEC_ALC5616) || defined(CODEC_ES8311)
b.liue9582032025-04-17 19:18:16 +0800886 if ((APH_PATH_ID_HIFIRECORDFROMMIC1 == path_id) || (APH_PATH_ID_HIFIRECORDFROMHSMIC == path_id)
887 || (APH_PATH_ID_VOICERECORDFROMMIC1 == path_id) ||(APH_PATH_ID_VOICERECORDFROMHSMIC == path_id))
888 {
889 LOGI(APHAudioPathVolumeSet, "===%s/L%d: PATH ID=%d, no need to config Tx gain! ===", __FUNCTION__, __LINE__, path_id);
890 return ACM_RC_OK;
891 }
892
893 //RX path is mapping to PROFILE.
894 switch (path_id)
895 {
896 case APH_PATH_ID_HIFIPLAYTOEARPHONE:
897 cur_Profile_id = HIFI_HANDSET;
898 break;
899
900 case APH_PATH_ID_HIFIPLAYTOSPKR:
901 cur_Profile_id = HIFI_SPEAKER;
902 break;
903
904 case APH_PATH_ID_HIFIPLAYTOHP:
905 cur_Profile_id = HIFI_HEADSET;
906 break;
907
908 case APH_PATH_ID_VOICEPLAYTOEARPHONE:
909 cur_Profile_id = VC_HANDSET;
910 break;
911
912 case APH_PATH_ID_VOICEPLAYTOSPKR:
913 cur_Profile_id = VC_HANDSFREE;
914 break;
915
916 case APH_PATH_ID_VOICEPLAYTOHP:
917 cur_Profile_id = VC_HEADSET;
918 break;
919
920 default:
921 LOGI(APHAudioPathVolumeSet, "%s/L%d: PATH ID=%d, PATH is %s.", __FUNCTION__, __LINE__, path_id, path);
922 break;
923 }
924
925 package.type = AUDIO_NVM_GetGainConfigure;
926 package.body.d1 = 0;
927 package.body.d2 = cur_Profile_id; //path ID (unsigned short)
928 package.ptr = &buffer;
929
930 NVM_Calibration_IPC(&package);
931
932 LOGI(APHAudioPathVolumeSet,"APHAudioPathVolumeSet:: profile=%d, Tx_DSPGain=%d, sizeof(AUDIO_PROFILE_ID)=%d!",
933 buffer.Profile_id, buffer.Tx_DSPGain, sizeof(AUDIO_PROFILE_ID));
934
935 for (i=0; i<AUDIOHAL_SPK_VOL_QTY; i++)
936 {
937 LOGI(APHAudioPathVolumeSet,"Rx_CodecGain[%d]:: Component_1=0x%x, RegAddr_1=0x%x, RegVal_1=0x%x !",
938 i, buffer.Rx_CodecGain[i].Component_1, buffer.Rx_CodecGain[i].RegAddr_1, buffer.Rx_CodecGain[i].RegVal_1);
939
940 LOGI(APHAudioPathVolumeSet,"Rx_CodecGain[%d]:: Component_2=0x%x, RegAddr_2=0x%x, RegVal_2=0x%x !",
941 i, buffer.Rx_CodecGain[i].Component_2, buffer.Rx_CodecGain[i].RegAddr_2, buffer.Rx_CodecGain[i].RegVal_2);
942
943 LOGI(APHAudioPathVolumeSet,"Rx_CodecGain[%d]:: Component_3=0x%x, RegAddr_3=0x%x, RegVal_3=0x%x !\n",
944 i, buffer.Rx_CodecGain[i].Component_3, buffer.Rx_CodecGain[i].RegAddr_3, buffer.Rx_CodecGain[i].RegVal_3);
945
946 LOGI(APHAudioPathVolumeSet,"Rx_CodecGain[%d]:: Component_4=0x%x, RegAddr_4=0x%x, RegVal_4=0x%x !\n",
947 i, buffer.Rx_CodecGain[i].Component_4, buffer.Rx_CodecGain[i].RegAddr_4, buffer.Rx_CodecGain[i].RegVal_4);
948 }
949
950#endif
951
b.liub17525e2025-05-14 17:22:29 +0800952#if !defined(CODEC_PM805) && !defined(CODEC_PM812) && !defined(CODEC_NAU8810) && !defined(CODEC_TLV320AIC3X) && !defined(CODEC_ALC5616)&& !defined(CODEC_ES8311)
b.liue9582032025-04-17 19:18:16 +0800953 pTable = _get_APHVolumeTable(path_id, ACM_Volume, APH_PATH_OUT_CNT);
954 if(pTable == NULL){
955 LOGE(APHAudioPathVolumeSet, "%s/L%d: Error pTable=%d", __FUNCTION__, __LINE__, pTable);
956 return ACM_RC_INVALID_PATH;
957 }
958#endif
959
960 if(path_status_table[path_id].enabled == 0){
961 LOGE(APHAudioPathVolumeSet, "%s/L%d: Path %s(%d) is not enabled", __FUNCTION__, __LINE__, path, path_id);
962 return ACM_RC_PATH_NOT_ENABLED;
963 }
964
965 if(path_status_table[path_id].value == value){
966 LOGE(APHAudioPathVolumeSet, "%s/L%d: Path %s(%d), value=%d.", __FUNCTION__, __LINE__, path, path_id, value);
967 /* when modify the value of NVM and reload the modification, need to complete the following procedure. */
968 //return ACM_RC_INVALID_VOLUME_CHANGE;
969 }
970
971 LOGI(APHAudioPathVolumeSet,"%s/L%d:: path_status_table[%d].value = %d!", __FUNCTION__, __LINE__, path_id, path_status_table[path_id].value);
972
973 path_status_table[path_id].value = value;
974 volume = (unsigned char)(value & VOLUME_MASK);
975 volume = (volume + 5) /10;
976 index_volume = volume;
977 volume *= 10;
978
979 LOGI(APHAudioPathVolumeSet,"%s/L%d:: volume = %d!", __FUNCTION__, __LINE__, volume);
980
981 if (volume > MAX_VOLUME_INDEX) {
982 LOGE(APHAudioPathVolumeSet,"%s/L%d:: too big volume = %d!", __FUNCTION__, __LINE__, volume);
983 return ACM_RC_INVALID_VOLUME_CHANGE;
984 }
985
b.liub17525e2025-05-14 17:22:29 +0800986#if defined(CODEC_PM805) || defined(CODEC_PM812) || defined(CODEC_NAU8810) || defined(CODEC_TLV320AIC3X) || defined(CODEC_ALC5616) || defined(CODEC_ES8311)
b.liue9582032025-04-17 19:18:16 +0800987
988 if (0xFFFF != buffer.Rx_CodecGain[index_volume].RegAddr_1)
989 {
990 Component_NVM = buffer.Rx_CodecGain[index_volume].Component_1;
991 Address_NVM = buffer.Rx_CodecGain[index_volume].RegAddr_1;
992 Value_NVM = buffer.Rx_CodecGain[index_volume].RegVal_1;
993
994 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
995 }
996
997 if (0xFFFF != buffer.Rx_CodecGain[index_volume].RegAddr_2)
998 {
999 Component_NVM = buffer.Rx_CodecGain[index_volume].Component_2;
1000 Address_NVM = buffer.Rx_CodecGain[index_volume].RegAddr_2;
1001 Value_NVM = buffer.Rx_CodecGain[index_volume].RegVal_2;
1002
1003 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1004 }
1005
1006 if (0xFFFF != buffer.Rx_CodecGain[index_volume].RegAddr_3)
1007 {
1008 Component_NVM = buffer.Rx_CodecGain[index_volume].Component_3;
1009 Address_NVM = buffer.Rx_CodecGain[index_volume].RegAddr_3;
1010 Value_NVM = buffer.Rx_CodecGain[index_volume].RegVal_3;
1011
1012 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1013 }
1014
1015 if (0xFFFF != buffer.Rx_CodecGain[index_volume].RegAddr_4)
1016 {
1017 Component_NVM = buffer.Rx_CodecGain[index_volume].Component_4;
1018 Address_NVM = buffer.Rx_CodecGain[index_volume].RegAddr_4;
1019 Value_NVM = buffer.Rx_CodecGain[index_volume].RegVal_4;
1020
1021 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1022 }
1023
1024 LOGI(APHAudioPathVolumeSet,"Tx_CodecGain:: Component_1=0x%x, RegAddr_1=0x%x, RegVal_1=0x%x !\n",
1025 buffer.Tx_CodecGain.Component_1, buffer.Tx_CodecGain.RegAddr_1, buffer.Tx_CodecGain.RegVal_1);
1026
1027 LOGI(APHAudioPathVolumeSet,"Tx_CodecGain:: Component_2=0x%x, RegAddr_2=0x%x, RegVal_2=0x%x !\n",
1028 buffer.Tx_CodecGain.Component_2, buffer.Tx_CodecGain.RegAddr_2, buffer.Tx_CodecGain.RegVal_2);
1029
1030 LOGI(APHAudioPathVolumeSet,"Tx_CodecGain:: Component_3=0x%x, RegAddr_3=0x%x, RegVal_3=0x%x !\n",
1031 buffer.Tx_CodecGain.Component_3, buffer.Tx_CodecGain.RegAddr_3, buffer.Tx_CodecGain.RegVal_3);
1032
1033 LOGI(APHAudioPathVolumeSet,"Tx_CodecGain:: Component_4=0x%x, RegAddr_4=0x%x, RegVal_4=0x%x !\n",
1034 buffer.Tx_CodecGain.Component_4, buffer.Tx_CodecGain.RegAddr_4, buffer.Tx_CodecGain.RegVal_4);
1035 //config Tx_CodecGain of acm_nvm.h here.
1036 if (0xFFFF != buffer.Tx_CodecGain.RegAddr_1)
1037 {
1038 Component_NVM = buffer.Tx_CodecGain.Component_1;
1039 Address_NVM = buffer.Tx_CodecGain.RegAddr_1;
1040 Value_NVM = buffer.Tx_CodecGain.RegVal_1;
1041
1042 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1043 }
1044
1045 if (0xFFFF != buffer.Tx_CodecGain.RegAddr_2)
1046 {
1047 Component_NVM = buffer.Tx_CodecGain.Component_2;
1048 Address_NVM = buffer.Tx_CodecGain.RegAddr_2;
1049 Value_NVM = buffer.Tx_CodecGain.RegVal_2;
1050
1051 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1052 }
1053
1054 if (0xFFFF != buffer.Tx_CodecGain.RegAddr_3)
1055 {
1056 Component_NVM = buffer.Tx_CodecGain.Component_3;
1057 Address_NVM = buffer.Tx_CodecGain.RegAddr_3;
1058 Value_NVM = buffer.Tx_CodecGain.RegVal_3;
1059
1060 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1061 }
1062
1063 if (0xFFFF != buffer.Tx_CodecGain.RegAddr_4)
1064 {
1065 Component_NVM = buffer.Tx_CodecGain.Component_4;
1066 Address_NVM = buffer.Tx_CodecGain.RegAddr_4;
1067 Value_NVM = buffer.Tx_CodecGain.RegVal_4;
1068
1069 configCodecGainfromNVM( Component_NVM, Address_NVM, Value_NVM);
1070 }
1071 return ACM_RC_OK;
1072#else
1073 return ACM_RC_OK;
1074#endif
1075}
1076
1077
1078ACM_ReturnCode ACM_GetPathStatus(char *buff, unsigned int maxsize) {
1079 unsigned int index = 0, size = 0, total = 0;
1080 char *ptr = buff;
1081
1082 for(index = 0; index < APH_PATH_ID_CNT; index++){
1083 //Prevent buff overwritten: reserve 100 bytes for this time
1084 if(total > maxsize - 100)
1085 return ACM_RC_INVALID_PARAMETER;
1086
1087 size = sprintf(ptr, " : %-30s:%9s,%8s, volume=%d\n", AUDIO_PATH_ID_MAPPING[index].PathName, path_status_table[index].enabled?"enabled":"disabled", path_status_table[index].mute?"muted":"unmuted", path_status_table[index].value);
1088 if(size > 0)
1089 ptr += size;
1090 else
1091 return ACM_RC_INVALID_PARAMETER;
1092 total += size;
1093 }
1094
1095 return ACM_RC_OK;
1096}
1097
1098unsigned int ACM_GetEnabledPathVolume(void)
1099{
1100 int i;
1101 unsigned int enabled_path_id_Rx = INVALID_PATH_ID;
1102 unsigned int enabled_path_id_Tx = INVALID_PATH_ID;
1103 unsigned int enabled_volume_Rx = 80;//refer to the value: madev->voice_volume = 0.8f;
1104 unsigned int enabled_mute_Tx = 0;
1105
1106 for (i=0; i<APH_PATH_ID_CNT; i++)
1107 {
1108 //save the enabled path.
1109 if ( path_status_table[i].enabled)
1110 {
1111 if ((i != APH_PATH_ID_HIFIRECORDFROMMIC1) && (i != APH_PATH_ID_HIFIRECORDFROMHSMIC)
1112 && (i !=APH_PATH_ID_VOICERECORDFROMMIC1) && (i !=APH_PATH_ID_VOICERECORDFROMHSMIC))
1113 {
1114 enabled_path_id_Rx = i;//record Rx path.
1115 enabled_volume_Rx = path_status_table[i].value;
1116 }
1117 else
1118 {
1119 enabled_path_id_Tx = i;//record Tx path.
1120 enabled_mute_Tx = path_status_table[i].mute;
1121 }
1122 }
1123 }
1124
1125 LOGI(ACM_GetEnabledPathVolume, "%s/L%d: enabled_path_id_Rx=%d, enabled_path_id_Tx=%d, enabled_volume_Rx=%d, enabled_mute_Tx=%d,",
1126 __FUNCTION__, __LINE__,enabled_path_id_Rx,enabled_path_id_Tx, enabled_volume_Rx, enabled_mute_Tx);
1127
1128 return enabled_volume_Rx;
1129}
1130
1131ACM_ReturnCode ACM_GetPathDirection(const char *path, unsigned char *path_direction) {
1132 return _get_path_direction(path, path_direction);
1133}
1134
1135ACM_ReturnCode APHGetMSAGain(const char *out_path, const char *path, unsigned char *volume, unsigned short id, signed short *gain, signed short *sidetone_gain) {
1136
b.liub17525e2025-05-14 17:22:29 +08001137#if defined(CODEC_PM805) || defined(CODEC_PM812) || defined(CODEC_NAU8810)|| defined(CODEC_TLV320AIC3X) || defined(CODEC_ALC5616) || defined(CODEC_ES8311)
b.liue9582032025-04-17 19:18:16 +08001138 int path_id = INVALID_PATH_ID;
1139 AC_IPC_Package package;
1140 ACMCodec_GainT buffer;
1141 unsigned char Volume_value;
1142 unsigned char index_volume;
1143 AUDIO_PROFILE_ID cur_Profile_id = HIFI_HANDSET;
1144
1145 memset(&package, 0x00, sizeof(AC_IPC_Package));
1146 memset(&buffer, 0x00, sizeof(ACMCodec_GainT));
1147
1148 LOGI(APHGetMSAGain, "%s/L%d: out_path=%s, path=%s, volume=%d, id=%d", __FUNCTION__, __LINE__, out_path, path, *volume, id);
1149
1150 //If not equal between out_path and path, it is input device, we need to use out_path to get gain from NVM.
1151 path_id = _get_path_id(out_path);
1152 if(path_id == INVALID_PATH_ID)
1153 {
1154 LOGE(APHGetMSAGain, "%s: ERROR: can not find matched path id", __FUNCTION__);
1155 return ACM_RC_INVALID_PATH;
1156 }
1157
1158 //RX path is mapping to PROFILE.
1159 switch (path_id)
1160 {
1161 case APH_PATH_ID_HIFIPLAYTOEARPHONE:
1162 cur_Profile_id = HIFI_HANDSET;
1163 break;
1164
1165 case APH_PATH_ID_HIFIPLAYTOSPKR:
1166 cur_Profile_id = HIFI_SPEAKER;
1167 break;
1168
1169 case APH_PATH_ID_HIFIPLAYTOHP:
1170 cur_Profile_id = HIFI_HEADSET;
1171 break;
1172
1173 case APH_PATH_ID_VOICEPLAYTOEARPHONE:
1174 cur_Profile_id = VC_HANDSET;
1175 break;
1176
1177 case APH_PATH_ID_VOICEPLAYTOSPKR:
1178 cur_Profile_id = VC_HANDSFREE;
1179 break;
1180
1181 case APH_PATH_ID_VOICEPLAYTOHP:
1182 cur_Profile_id = VC_HEADSET;
1183 break;
1184
1185 default:
1186 LOGI(APHGetMSAGain, "%s/L%d: PATH ID=%d, PATH is %s.", __FUNCTION__, __LINE__, path_id, path);
1187 break;
1188 }
1189
1190 package.type = AUDIO_NVM_GetGainConfigure;
1191 package.body.d1 = 0;
1192 package.body.d2 = cur_Profile_id; //path ID (unsigned short)
1193 package.ptr = &buffer;
1194
1195 NVM_Calibration_IPC(&package);
1196
1197 Volume_value = (unsigned char)((*volume) & VOLUME_MASK);
1198 Volume_value = (Volume_value + 5) /10;
1199 index_volume = Volume_value;
1200 Volume_value *= 10;
1201
1202 if (strcmp(out_path, path))
1203 {//MIC, HSMIC...
1204 *gain = buffer.Tx_DSPGain;
1205 *sidetone_gain = 0;
1206 LOGI(APHGetMSAGain,"APHGetMSAGain::profile=%d, Tx DSP gain = 0x%hx, sidetone = 0x%hx!", buffer.Profile_id, *gain, *sidetone_gain);
1207 }
1208 else
1209 {//EARPHONE, SPEAKER...
1210 *gain = buffer.Rx_DSPGain[index_volume];
1211 *sidetone_gain = buffer.Rx_DSPSideToneGain;
1212 LOGI(APHGetMSAGain,"APHGetMSAGain::profile=%d, Rx DSP gain = 0x%hx, sidetone = 0x%hx!", buffer.Profile_id, *gain, *sidetone_gain);
1213 }
1214
1215 return ACM_RC_OK;
1216
1217#else
1218
1219 *gain = 0;
1220 *sidetone_gain = 0x8080;//0x8080=disable sidetone
1221 LOGI(APHGetMSAGain,"Not supported codec! APHGetMSAGain:: DSP gain = 0x%hx, sidetone = 0x%hx!", *gain, *sidetone_gain);
1222 return ACM_RC_OK;
1223
1224#endif
1225
1226}
1227
b.liub17525e2025-05-14 17:22:29 +08001228
1229#ifdef MBTK_AUDIO_GAIN_SAVE_SUPPORT
1230ACM_ReturnCode MBTK_ACMSaveMSAGain(unsigned char *gain, int gain_num) {
1231#if defined(CODEC_ES8311)
1232 AC_IPC_Package package;
1233
1234 memset(&package, 0x00, sizeof(AC_IPC_Package));
1235
1236 LOGI(APHGetMSAGain, "%s/L%d start.", __FUNCTION__, __LINE__);
1237
1238 package.type = AUDIO_NVM_SaveCalibrationData;
1239 memcpy(&(package.body), gain, gain_num);
1240 package.ptr = NULL;
1241
1242 NVM_Calibration_IPC(&package);
1243
1244 return ACM_RC_OK;
1245
1246#else
1247 LOGI(APHGetMSAGain,"Not supported codec! APHSaveMSAGain!");
1248 return ACM_RC_OK;
1249#endif
1250}
1251#endif
1252
b.liue9582032025-04-17 19:18:16 +08001253#ifdef PXA1826_AUDIO
1254ACM_ReturnCode APHSetMSAGain(AC_Digital_Gain *gain) {
1255 VolumeCtlMsg volume_cmd;
1256 int ioctl_fd;
1257
1258 // If no voice path actived, will not configure DSP
1259 if((gain->path_direction_Rx > 1) || (gain->path_direction_Tx > 1))
1260 {
1261 LOGI(APHSetMSAGain, "no voice path actived, will not configure DSP: Rx=%d,Tx=%d", gain->path_direction_Rx, gain->path_direction_Tx);
1262 return ACM_RC_OK;
1263 }
1264
1265 ioctl_fd = open("/dev/audiostub_ctl", O_RDONLY);
1266 if(ioctl_fd < 0)
1267 {
1268 LOGI(APHSetMSAGain, "failed to open audiostub_ctl: %s", strerror(errno));
1269 return ACM_RC_PATH_NOT_ENABLED;
1270 }
1271
1272 //Rx
1273 memset(&volume_cmd, 0, sizeof(volume_cmd));
1274 volume_cmd.direction = gain->path_direction_Rx;
1275 volume_cmd.gain = gain->digital_gain_Rx;
1276 volume_cmd.misc_volume = gain->volume_Rx;
1277 if(ioctl(ioctl_fd, AUDIOSTUB_VOLUMECTL, &volume_cmd) < 0)
1278 {
1279 LOGI(APHSetMSAGain, "audio_stub ioctl error: %s", strerror(errno));
1280 close(ioctl_fd);
1281 return ACM_RC_INVALID_PARAMETER;
1282 }
1283
1284 //Tx
1285 memset(&volume_cmd, 0, sizeof(volume_cmd));
1286 volume_cmd.direction = gain->path_direction_Tx;
1287 volume_cmd.gain = gain->digital_gain_Tx;
1288 volume_cmd.misc_volume = gain->volume_Tx;
1289 if(ioctl(ioctl_fd, AUDIOSTUB_VOLUMECTL, &volume_cmd) < 0)
1290 {
1291 LOGI(APHSetMSAGain, "audio_stub ioctl error: %s", strerror(errno));
1292 close(ioctl_fd);
1293 return ACM_RC_INVALID_PARAMETER;
1294 }
1295
1296 //SideTone
1297 memset(&volume_cmd, 0, sizeof(volume_cmd));
1298 volume_cmd.direction = gain->path_direction_SideTone;
1299 volume_cmd.gain = gain->digital_gain_SideTone;
1300 volume_cmd.misc_volume = gain->volume_SideTone;
1301 if(ioctl(ioctl_fd, AUDIOSTUB_VOLUMECTL, &volume_cmd) < 0)
1302 {
1303 LOGI(APHSetMSAGain, "audio_stub ioctl error: %s", strerror(errno));
1304 close(ioctl_fd);
1305 return ACM_RC_INVALID_PARAMETER;
1306 }
1307
1308 close(ioctl_fd);
1309 LOGI(APHSetMSAGain, "APHSetMSAGain success!");
1310
1311 return ACM_RC_OK;
1312}
1313#endif
1314
1315#ifdef TARGET_mmp_asr1901_KSTR901
1316extern int audio_dsp_send_ve(void* ve);
1317
1318void ACM_SendVEtoADSP(void) {
1319 AC_IPC_Package package;
1320 EnhanceParmsT buffer;
1321
1322 memset(&package, 0x00, sizeof(AC_IPC_Package));
1323 memset(&buffer, 0x00, sizeof(EnhanceParmsT));
1324
1325 LOGI(ACM_SendVEtoADSP, "%s/%d\n", __FUNCTION__, __LINE__);
1326
1327 package.type = AUDIO_NVM_GetVEConfigure;
1328 package.body.d1 = 0;
1329 package.body.d2 = 0;
1330 package.ptr = &buffer;
1331
1332 NVM_Calibration_IPC(&package);
1333 audio_dsp_send_ve(&buffer);
1334}
1335#endif
1336
1337ACM_ReturnCode ACM_GetEnabledPathId(int *path_id_Rx, int *path_id_Tx, int *volume_Rx, int *mute_Tx)
1338{
1339 int i;
1340
1341 int enabled_path_id_Rx = INVALID_PATH_ID;
1342 int enabled_path_id_Tx = INVALID_PATH_ID;
1343 int enabled_volume_Rx = 0;
1344 int enabled_mute_Tx = 0;
1345
1346 for (i=0; i<APH_PATH_ID_CNT; i++)
1347 {
1348 //save the enabled path.
1349 if ( path_status_table[i].enabled)
1350 {
1351 if ((i != APH_PATH_ID_HIFIRECORDFROMMIC1) && (i != APH_PATH_ID_HIFIRECORDFROMHSMIC)
1352 && (i !=APH_PATH_ID_VOICERECORDFROMMIC1) && (i !=APH_PATH_ID_VOICERECORDFROMHSMIC))
1353 {
1354 enabled_path_id_Rx = i;//record Rx path.
1355 enabled_volume_Rx = path_status_table[i].value;
1356 }
1357 else
1358 {
1359 enabled_path_id_Tx = i;//record Tx path.
1360 enabled_mute_Tx = path_status_table[i].mute;
1361 }
1362 }
1363 }
1364
1365 LOGI(ACM_GetEnabledPathId, "%s/L%d: enabled_path_id_Rx=%d, enabled_path_id_Tx=%d, enabled_volume_Rx=%d, enabled_mute_Tx=%d,",
1366 __FUNCTION__, __LINE__,enabled_path_id_Rx,enabled_path_id_Tx, enabled_volume_Rx, enabled_mute_Tx);
1367
1368 *path_id_Rx = enabled_path_id_Rx;
1369 *path_id_Tx = enabled_path_id_Tx;
1370 *volume_Rx = enabled_volume_Rx;
1371 *mute_Tx = enabled_mute_Tx;
1372
1373 return ACM_RC_OK;
1374}
1375
1376ACM_ReturnCode ACM_ReloadCalibrationData(void) {
1377 char tmp_buffer[PATHSTATUS_MAX] = {0};
1378 int i = 0, value;
1379 int path_id_Rx = INVALID_PATH_ID;
1380 int path_id_Tx = INVALID_PATH_ID;
1381 int volume_Rx = 0;
1382 char mute_Tx = 0;
1383 AUDIO_PROFILE_ID cur_Profile_id = HIFI_HANDSET;
1384 AC_IPC_Package package;
1385
1386 /*
1387 First: send message "AUDIO_NVM_ReloadCalibrationData" to NVM server, trigger reload nvm.
1388 No matter whether there is enabled path.
1389 */
1390 memset(&package, 0x00, sizeof(AC_IPC_Package));
1391 package.type = AUDIO_NVM_ReloadCalibrationData;
1392 package.body.d1 = 0;
1393 package.body.d2 = 0;
1394 package.ptr = &value;
1395 NVM_Calibration_IPC(&package);
1396
1397 //Second: get path status.
1398 if (ACM_GetPathStatus(tmp_buffer, PATHSTATUS_MAX) != ACM_RC_OK)
1399 {
1400 LOGE(ACM_ReloadCalibrationData, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
1401 return ACM_RC_PATH_CONFIG_NOT_EXIST;
1402 }
1403
1404 //list the path status, before ReloadCalibrationData
1405 LOGI(ACM_ReloadCalibrationData, "before ReloadCalibrationData, record the path status, current every path status is:\n%s.......", tmp_buffer);
1406
1407 for (i=0; i<APH_PATH_ID_CNT; i++)
1408 {
1409 //save the enabled path.
1410 if ( path_status_table[i].enabled)
1411 {
1412 if ((i != APH_PATH_ID_HIFIRECORDFROMMIC1) && (i != APH_PATH_ID_HIFIRECORDFROMHSMIC)
1413 && (i !=APH_PATH_ID_VOICERECORDFROMMIC1) && (i !=APH_PATH_ID_VOICERECORDFROMHSMIC))
1414 {
1415 path_id_Rx = i;//record Rx path.
1416 volume_Rx = path_status_table[i].value;
1417 }
1418 else
1419 {
1420 path_id_Tx = i;//record Tx path.
1421 mute_Tx = path_status_table[i].mute;
1422 }
1423 }
1424 }
1425
1426 if ((INVALID_PATH_ID == path_id_Rx) || (INVALID_PATH_ID == path_id_Tx))
1427 {
1428 LOGI(ACM_ReloadCalibrationData, "%s/L%d: no enabled path.", __FUNCTION__, __LINE__);
1429 return ACM_RC_OK;
1430 }
1431
1432 LOGI(ACM_ReloadCalibrationData, "%s/L%d: actived path:Rx path:%s, Tx path:%s",
1433 __FUNCTION__, __LINE__, AUDIO_PATH_ID_MAPPING[path_id_Rx].PathName, AUDIO_PATH_ID_MAPPING[path_id_Tx].PathName);
1434
1435 if ((APHAudioPathCheck(AUDIO_PATH_ID_MAPPING[path_id_Rx].PathName, AUDIO_PATH_ID_MAPPING[path_id_Tx].PathName) != ACM_RC_OK_HIFI_MATCHED)
1436 && (APHAudioPathCheck(AUDIO_PATH_ID_MAPPING[path_id_Rx].PathName, AUDIO_PATH_ID_MAPPING[path_id_Tx].PathName) != ACM_RC_OK_VOICE_MATCHED))
1437 {
1438 LOGE(ACM_ReloadCalibrationData, "%s/L%d: Rx path is not matched with Tx path.", __FUNCTION__, __LINE__);
1439 return ACM_RC_PATH_CONFIG_NOT_EXIST;
1440 }
1441
1442 //RX path is mapping to PROFILE.
1443 switch (path_id_Rx)
1444 {
1445 case APH_PATH_ID_HIFIPLAYTOEARPHONE:
1446 cur_Profile_id = HIFI_HANDSET;
1447 break;
1448
1449 case APH_PATH_ID_HIFIPLAYTOSPKR:
1450 cur_Profile_id = HIFI_SPEAKER;
1451 break;
1452
1453 case APH_PATH_ID_HIFIPLAYTOHP:
1454 cur_Profile_id = HIFI_HEADSET;
1455 break;
1456
1457 case APH_PATH_ID_VOICEPLAYTOEARPHONE:
1458 cur_Profile_id = VC_HANDSET;
1459 break;
1460
1461 case APH_PATH_ID_VOICEPLAYTOSPKR:
1462 cur_Profile_id = VC_HANDSFREE;
1463 break;
1464
1465 case APH_PATH_ID_VOICEPLAYTOHP:
1466 cur_Profile_id = VC_HEADSET;
1467 break;
1468
1469 default:
1470 LOGI(ACM_ReloadCalibrationData, "%s/L%d.", __FUNCTION__, __LINE__);
1471 break;
1472 }
1473
1474 LOGI(ACM_ReloadCalibrationData,"AUDIO_NVM_ReloadCalibrationData:: profile=%d, sizeof(AUDIO_PROFILE_ID)=%d!",
1475 cur_Profile_id, sizeof(AUDIO_PROFILE_ID));
1476
1477 //Third:enable the saved path using new config.
1478 APHAudioPathDisable(AUDIO_PATH_ID_MAPPING[path_id_Rx].PathName);
1479 APHAudioPathDisable(AUDIO_PATH_ID_MAPPING[path_id_Tx].PathName);
1480
1481 ACMAudioPathEnable(AUDIO_PATH_ID_MAPPING[path_id_Rx].PathName, volume_Rx);
1482 ACMAudioPathEnable(AUDIO_PATH_ID_MAPPING[path_id_Tx].PathName, volume_Rx);
1483 APHAudioPathMute(AUDIO_PATH_ID_MAPPING[path_id_Tx].PathName, mute_Tx);
1484
1485 //Forth: List the path status.
1486 memset(tmp_buffer, 0x00, sizeof(tmp_buffer));
1487
1488 if (ACM_GetPathStatus(tmp_buffer, PATHSTATUS_MAX) != ACM_RC_OK)
1489 {
1490 LOGE(ACM_ReloadCalibrationData, "%s/L%d: Get paths status failed", __FUNCTION__, __LINE__);
1491 return ACM_RC_PATH_CONFIG_NOT_EXIST;
1492 }
1493
1494 //After recover the enabled path, list the path status
1495 LOGI(ACM_ReloadCalibrationData, "After recover the enabled path, list the path status is:%s.......", tmp_buffer);
1496
1497 return ACM_RC_OK;
1498}
1499
1500void ACM_enable_headset_detection_ALC5616(void)
1501{
1502#ifdef TARGET_mmp_asr1901_KSTR901
1503 system("echo 1 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.1/i2c-1/1-001b/alc5616-headset/enable_headset_detection");
1504#else
1505 system("echo 1 > /sys/devices/platform/soc/d4000000.apb/pxa2xx-i2c.0/i2c-0/0-001b/alc5616-headset/enable_headset_detection");
1506#endif
1507 return;
1508}
1509
1510void ACM_APHInit(void) {
1511#ifdef PXA1826_AUDIO
1512 int ret = 0;
1513 int err, ioctl_fd, status = 0;
1514#endif
1515 int value;
1516 AC_IPC_Package package;
1517
1518 if (0 == get_debug_mode())
1519 {
1520 /* 1:on; 0:off, default. if g_audio_if_debug_mode is on, no need to send msg to NVMProxy. */
1521
1522 //Reload AP Audio NVM
1523 package.type = AUDIO_NVM_ReloadCalibrationData;
1524 package.body.d1 = 0;
1525 package.body.d2 = 0;
1526 package.ptr = &value;
1527 NVM_Calibration_IPC(&package);
1528 }
1529
1530 //reset components status
1531 if(acm_codec_connected == TRUE){
1532 _reset_components_status();
1533 _reset_components_registers();
1534 }
1535
1536 /*
1537 * From audio_stub, get the properties of nb/wb, master/slave
1538 */
1539#ifdef PXA1826_AUDIO
1540 ioctl_fd = open("/dev/audiostub_ctl", O_RDONLY);
1541 if (ioctl_fd < 0) {
1542 err = errno;
1543 ALOGE(ACM_APHInit9, "failed to open audiostub_ctl:%s\n", strerror(err));
1544 return;
1545 }
1546
1547 ret = ioctl(ioctl_fd, AUDIOSTUB_GET_STATUS, &status);
1548 if (ret < 0) {
1549 ALOGE(ACM_APHInit10, "Warning, audio_stub ioctl error: %s", strerror(errno));
1550 }
1551 modem_is_wb = IS_WB(status);
1552 modem_is_master = IS_PCM_MASTER(status);
1553
1554 LOGI(ACM_APHInit, "%s/L%d: modem_is_wb=%d, modem_is_master=%d", __FUNCTION__, __LINE__, modem_is_wb, modem_is_master);
1555
1556 //close the file after got status report
1557 close(ioctl_fd);
1558#endif
1559}
1560
1561void ACM_APHDeInit(void) {
1562}
1563
1564
1565/* Audio uses PROPERTY_AUDIO_CODEC which is not created by PXA1826 init
1566 * Call from ACMInit() to set property with default value "1"
1567 * depending upon the AUDIO package is better than in init.rc
1568 * (No other setprop are present for now)
1569 */
1570void ACM_Init_Property(void)
1571{
1572 char property_value[PROPERTY_VALUE_MAX];
1573 int i = property_get(PROPERTY_AUDIO_CODEC, property_value, NULL);
1574 if (i <= 0) {
1575 LOGD(ACM_Init_Property, "Not found %s. Create with default value=%d", PROPERTY_AUDIO_CODEC, (modem_is_master == 0)?1:0);
1576 if(modem_is_master == 0)
1577 property_set(PROPERTY_AUDIO_CODEC, "1"); //persist.audio.codecmaster = 1
1578 else
1579 property_set(PROPERTY_AUDIO_CODEC, "0"); //persist.audio.codecmaster = 0
1580 }
1581 else
1582 LOGD(ACM_Init_Property, "Found %s. value=%s", PROPERTY_AUDIO_CODEC, property_value);
1583}
1584