Tizen 2.1 base
[platform/core/multimedia/avsystem.git] / avsys-audio-path.c
1 /*
2  * avsystem
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <stdlib.h>
30 #include <linux/input.h>
31 #include <iniparser.h>
32
33 #include "avsys-audio-shm.h"
34 #include "avsys-audio-sync.h"
35 #include "avsys-audio-path.h"
36 #include "avsys-audio-shm.h"
37 #include "avsys-debug.h"
38 #include "avsys-common.h"
39 #include "avsys-audio-handle.h"
40 #include "avsys-audio-logical-volume.h"
41 #include "avsys-audio-alsa.h"
42 #include "avsys-audio-ascenario.h"
43
44 #define EXPORT_API __attribute__((__visibility__("default")))
45
46 #define RET_IO_CTL_ERR_IF_FAIL(SECTION) { if(AVSYS_FAIL(SECTION)) { \
47                                                                         avsys_error_r(AVAUDIO,"%s %d\n",__func__,__LINE__); \
48                                                                         return AVSYS_STATE_ERR_IO_CONTROL; \
49                                                                         } }
50
51 static int g_playback_path_select_data[AVSYS_AUDIO_PLAYBACK_GAIN_MAX][AVSYS_AUDIO_PATH_EX_OUTMAX] = {
52                 { /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
53                         /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI DOCK USBAUDIO */
54                                 0,      1,      0,      1,      0,      0,      0,      1,  1,  0
55                 },
56                 { /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
57                         /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */
58                                 1,      1,      0,      1,      0,      1,      0,      0,  0,  0
59                 },
60                 { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
61                         /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */
62                                 1,      1,      1,      1,      1,      0,      0,      0,  0,  0
63                 },
64                 { /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
65                         /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */
66                                 1,      1,      1,      1,      1,      0,      0,      0,  0,  0
67                 },
68                 { /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
69                         /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */
70                                 0,      1,      1,      1,      1,      0,      0,      0,  0,  0
71                 }
72 };
73
74 static int g_capture_path_select_data[AVSYS_AUDIO_CAPTURE_GAIN_MAX][AVSYS_AUDIO_PATH_EX_INMAX] = {
75                 { /* AVSYS_AUDIO_CAPTURE_GAIN_AP */
76                         /* NONE MIC HMIC BMIC FMIN HFREE */
77                                 1,      1,      1,      1,      0,      0
78                 },
79                 { /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */
80                         /* NONE MIC HMIC BMIC FMIN HFREE */
81                                 1,      0,      0,      0,      1,      0
82                 },
83                 { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */
84                         /* NONE MIC HMIC BMIC FMIN HFREE */
85                                 1,      1,      1,      1,      0,      0
86                 },
87                 { /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */
88                         /* NONE MIC HMIC BMIC FMIN HFREE */
89                                 1,      1,      1,      1,      0,      0
90                 },
91 };
92
93 static int g_playback_gain_select_data[AVSYS_AUDIO_PLAYBACK_GAIN_MAX][AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = {
94                 {       /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
95                                 AVSYS_AUDIO_PLAYBACK_GAIN_AP,                           /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
96                                 AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO,                      /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
97                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
98                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
99                                 AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT,            /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
100                 },
101                 {       /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
102                                 AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO,                      /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
103                                 AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO,                      /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
104                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
105                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
106                                 AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO,                      /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
107                 },
108                 {       /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
109                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
110                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
111                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
112                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
113                                 AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT,            /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
114                 },
115                 {       /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
116                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
117                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
118                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
119                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
120                                 AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT,            /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
121                 },
122                 {       /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
123                                 AVSYS_AUDIO_PLAYBACK_GAIN_AP,                           /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */
124                                 AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO,                      /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */
125                                 AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */
126                                 AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL,            /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */
127                                 AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT,            /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */
128                 },
129 };
130
131 static int g_capture_gain_select_data[AVSYS_AUDIO_CAPTURE_GAIN_MAX][AVSYS_AUDIO_CAPTURE_GAIN_MAX] = {
132                 {       /* AVSYS_AUDIO_CAPTURE_GAIN_AP */
133                                 AVSYS_AUDIO_CAPTURE_GAIN_AP,                    /* AVSYS_AUDIO_CAPTURE_GAIN_AP */
134                                 AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO,               /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */
135                                 AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */
136                                 AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */
137                 },
138                 {       /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */
139                                 AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO,               /* AVSYS_AUDIO_CAPTURE_GAIN_AP */
140                                 AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO,               /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */
141                                 AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */
142                                 AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */
143                 },
144                 {       /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */
145                                 AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_AP */
146                                 AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */
147                                 AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */
148                                 AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */
149                 },
150                 {       /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */
151                                 AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_AP */
152                                 AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */
153                                 AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */
154                                 AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL,             /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */
155                 },
156 };
157
158
159 static int __avsys_audio_path_set_ascn_ap_playback(avsys_audio_path_ex_info_t *control);
160 static int __avsys_audio_path_set_ascn_voicecall(avsys_audio_path_ex_info_t *control);
161 static int __avsys_audio_path_set_ascn_videocall(avsys_audio_path_ex_info_t *control);
162 static int __avsys_audio_path_set_ascn_fmradio(avsys_audio_path_ex_info_t *control);
163 static int __avsys_audio_path_set_ascn_ap_capture(avsys_audio_path_ex_info_t *control);
164 static int __avsys_audio_path_set_hw_controls(avsys_audio_path_ex_info_t *control);
165 static int __avsys_audio_path_get_earjack_type(void);
166
167 #define AUDIOSYSTEM_CONF        "/opt/etc/audio_system.conf"
168 #define CONF_ITEM_COUNT 2
169 #define INPUT_DEV_MAX 20
170
171 #define EARJACK_EVENT_PATH      "/dev/input/event"
172
173 #define AVSYS_AUDIO_INI_DEFAULT_PATH "/usr/etc/mmfw_avsystem.ini"
174 #define AVSYS_AUDIO_DEFAULT_CONTROL_AIF_BEFORE_PATH_SET         0
175 #define AVSYS_AUDIO_DEFAULT_GAIN_DEBUG_MODE                                     0
176
177 #define CP_STATUS "/sys/class/audio/caps/cp_caps"
178 #define CP_WB_STRING "wb"
179
180 static char *conf_string[] = {
181         "headset_detection",
182         "headset_node",
183 };
184
185 typedef struct {
186         char headset_detection;
187         char headset_node_number;
188         bool control_aif_before_path_set;
189         bool gain_debug_mode;
190 } avsys_audio_conf;
191
192 static int __load_conf(avsys_audio_conf *data)
193 {
194         dictionary *dict = NULL;
195
196 #if defined(_MMFW_I386_ALL_SIMULATOR)
197         if (data == NULL)
198                 return AVSYS_STATE_ERR_NULL_POINTER;
199
200         data->headset_detection = 1;
201         data->headset_node_number = 4;
202 #else
203         FILE *fp = NULL;
204         int i = 0;
205         char buffer[64] = { 0, };
206         char conf_data[CONF_ITEM_COUNT] = { 1, 0 };
207
208         if (data == NULL)
209                 return AVSYS_STATE_ERR_NULL_POINTER;
210
211         fp = fopen(AUDIOSYSTEM_CONF, "r");
212         if (fp == NULL) {
213                 char filename[128] = { 0, };
214                 char readBuffer[32] = { 0, };
215                 char headset_find = 0;
216                 int num = 0, headset_num = -1;
217
218                 for (num = 0; num < INPUT_DEV_MAX; num++) {
219                         FILE *sfp = NULL;
220                         memset(filename, '\0', sizeof(filename));
221                         snprintf(filename, sizeof(filename), "/sys/class/input/input%01d/name", num);
222                         if (NULL == (sfp = fopen(filename, "r")))
223                                 continue;
224                         memset(readBuffer, '\0', sizeof(readBuffer));
225                         if (NULL == fgets(readBuffer, sizeof(readBuffer) - 1, sfp)) {
226                                 fclose(sfp);
227                                 continue;
228                         }
229                         if (strstr(readBuffer, "Headset")) {
230                                 headset_find = 1;
231                                 headset_num = num;
232                         }
233
234                         fclose(sfp);
235                         if (headset_num != -1) {
236                                 break;
237                         }
238                 }
239                 if (headset_num == -1)
240                         return AVSYS_STATE_ERR_INTERNAL;
241
242                 if (NULL == (fp = fopen(AUDIOSYSTEM_CONF, "w"))) {
243                         return AVSYS_STATE_ERR_INTERNAL;
244                 }
245
246                 fprintf(fp, "%s:1\n", conf_string[0]);
247                 fprintf(fp, "%s:%d\n", conf_string[1], headset_num);
248                 fflush(fp);
249                 fclose(fp);
250                 fp = NULL;
251                 sync();
252                 data->headset_detection = 1;
253                 data->headset_node_number = headset_num;
254                 return AVSYS_STATE_SUCCESS;
255         }
256
257         while (fgets(buffer, sizeof(buffer) - 1, fp) != NULL) {
258                 if ((strlen(buffer) < 3) || (buffer[0] == '#') || (buffer[0] == '!'))
259                         continue;
260                 if (buffer[strlen(buffer) - 1] == '\n')
261                         buffer[strlen(buffer) - 1] = '\0';
262                 for (i = 0; i < CONF_ITEM_COUNT; i++) {
263                         if (0 == strncmp(buffer, conf_string[i], strlen(conf_string[i]))) {
264                                 char *ptr = NULL;
265                                 if (NULL == (ptr = strstr(buffer, ":")))
266                                         break;
267                                 conf_data[i] = atoi(ptr + 1);
268                                 avsys_warning(AVAUDIO, "%s[%d]\n", buffer, conf_data[i]);
269                         }
270                 }
271         }
272         fclose(fp);
273         data->headset_detection = conf_data[0];
274         data->headset_node_number = conf_data[1];
275 #endif
276
277         /* first, try to load existing ini file */
278         dict = iniparser_load(AVSYS_AUDIO_INI_DEFAULT_PATH);
279         if (dict) { /* if dict is available */
280                 data->control_aif_before_path_set = iniparser_getboolean(dict, "aif:control aif before path set", AVSYS_AUDIO_DEFAULT_CONTROL_AIF_BEFORE_PATH_SET);
281                 data->gain_debug_mode = iniparser_getboolean(dict, "debug:gain debug mode", AVSYS_AUDIO_DEFAULT_GAIN_DEBUG_MODE);
282
283                 /* free dict as we got our own structure */
284                 iniparser_freedict (dict);
285         } else { /* if no file exists. create one with set of default values */
286                 data->control_aif_before_path_set = AVSYS_AUDIO_DEFAULT_CONTROL_AIF_BEFORE_PATH_SET;
287                 data->gain_debug_mode = AVSYS_AUDIO_DEFAULT_GAIN_DEBUG_MODE;
288         }
289
290         return AVSYS_STATE_SUCCESS;
291 }
292
293 static bool __is_cp_wb ()
294 {
295         bool ret = false;
296         char str[10] = { 0, };
297         FILE* fp = NULL;
298
299         avsys_info(AVAUDIO, "Checking [%s] for WB capability...\n", CP_STATUS);
300         fp = fopen (CP_STATUS, "r");
301         if (fp) {
302                 if (fgets (str, sizeof(str)-1, fp)) {
303                         if (strstr (str, CP_WB_STRING)) {
304                                 ret = true;
305                         }
306                 }
307                 fclose(fp);
308         } else {
309                 avsys_warning (AVAUDIO, "failed to open [%s]...errno=[%d]\n", CP_STATUS, errno);
310         }
311
312         avsys_info(AVAUDIO, "Result [%d] : [%s] capability!!!\n", ret, (ret)? "WB" : "NB");
313         return ret;
314 }
315
316 EXPORT_API
317 int avsys_audio_path_ex_init(void)
318 {
319         avsys_audio_path_ex_info_t *control = NULL;
320         avsys_audio_path_ex_info_t **temp = NULL;
321         gain_info_t default_gain = { AVSYS_AUDIO_PLAYBACK_GAIN_AP, AVSYS_AUDIO_CAPTURE_GAIN_AP };
322         path_info_t default_path = { AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_MIC };
323         option_info_t default_option = { AVSYS_AUDIO_PATH_OPTION_NONE, AVSYS_AUDIO_PATH_OPTION_NONE };
324         int index = 0;
325         int err = AVSYS_STATE_SUCCESS;
326         avsys_audio_conf conf = { 0, };
327
328         /* Check root user */
329         err = avsys_check_root_privilege();
330         if (AVSYS_FAIL(err)) {
331                 return err;
332         }
333
334         temp = &control;
335         avsys_assert(AVSYS_SUCCESS(avsys_audio_create_sync(AVSYS_AUDIO_SYNC_IDEN_PATH)));
336         avsys_assert(AVSYS_SUCCESS(avsys_audio_create_shm(AVSYS_AUDIO_SHM_IDEN_PATH)));
337
338         avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp)));
339         if (control == NULL)
340                 return AVSYS_STATE_ERR_NULL_POINTER;
341
342         /* init values */
343         control->pregain = default_gain;
344         control->gain = default_gain;
345         control->reqgain = default_gain;
346         control->path = default_path;
347         control->backup_gain = default_gain;
348         control->backup_path = default_path;
349         control->option = default_option;
350
351         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
352         control->inserted = AVSYS_AUDIO_INSERTED_NONE;
353
354         if (AVSYS_FAIL(__load_conf(&conf)))
355                 avsys_error_r(AVAUDIO, "Can not load audio system configuration file\n");
356
357         if (conf.headset_detection) {
358                 control->inserted = __avsys_audio_path_get_earjack_type();
359                 if (control->inserted == AVSYS_AUDIO_INSERTED_NONE)
360                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
361                 else
362                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET;
363         } else {
364                 avsys_warning(AVAUDIO, "Ignore headset detection. Use speaker device\n");
365                 control->inserted = AVSYS_AUDIO_INSERTED_NONE;
366                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
367         }
368
369         avsys_error_r(AVAUDIO, "Earjack init value is %d\n", control->inserted);
370
371         control->control_aif_before_path_set = conf.control_aif_before_path_set;
372         control->wb_enabled = __is_cp_wb();
373         control->gain_debug_mode = conf.gain_debug_mode;
374
375         control->mute = AVSYS_AUDIO_UNMUTE;
376         control->path_fixed = PATH_FIXED_NONE;
377
378         index = 0;
379         do {
380                 control->pathlock_pid[index] = -1;
381                 index++;
382         } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
383
384         index = 0;
385         do {
386                 control->path_fixed_pid[index] = -1;
387                 index++;
388         } while (index < PATH_FIXED_TYPE_MAX);
389
390         /* call path control */
391         err = __avsys_audio_path_set_ascn_ap_playback(control);
392         if (AVSYS_SUCCESS(err))
393                 err = __avsys_audio_path_set_hw_controls(control);
394
395         if (AVSYS_SUCCESS(err))
396                 err = __avsys_audio_path_set_ascn_ap_capture(control);
397
398         return err;
399 }
400
401 EXPORT_API
402 int avsys_audio_path_ex_fini(void)
403 {
404         if (AVSYS_FAIL(avsys_audio_remove_shm(AVSYS_AUDIO_SHM_IDEN_PATH))) {
405                 avsys_error_r(AVAUDIO, "avsys_audio_remove_shm() failed in %s\n", __func__);
406                 return AVSYS_STATE_ERR_INTERNAL;
407         }
408         if (AVSYS_FAIL(avsys_audio_remove_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
409                 avsys_error_r(AVAUDIO, "avsys_audio_remove_sync() failed in %s\n", __func__);
410                 return AVSYS_STATE_ERR_INTERNAL;
411         }
412         return AVSYS_STATE_SUCCESS;
413 }
414
415 EXPORT_API
416 int avsys_audio_path_ex_reset(int forced)
417 {
418         avsys_audio_path_ex_info_t *control = NULL;
419         avsys_audio_path_ex_info_t **temp = NULL;
420         gain_info_t default_gain = { AVSYS_AUDIO_PLAYBACK_GAIN_AP, AVSYS_AUDIO_CAPTURE_GAIN_AP };
421         path_info_t default_path = { AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_MIC };
422         option_info_t default_option = { AVSYS_AUDIO_PATH_OPTION_NONE, AVSYS_AUDIO_PATH_OPTION_NONE };
423         int index = 0;
424         int err = AVSYS_STATE_SUCCESS;
425         int backup_debug = 0;
426         avsys_audio_conf conf = { 0, };
427
428         /* Check root user */
429         err = avsys_check_root_privilege();
430         if (AVSYS_FAIL(err)) {
431                 return err;
432         }
433
434         temp = &control;
435         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
436                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
437                 return AVSYS_STATE_ERR_INTERNAL;
438         }
439         if (control == NULL)
440                 return AVSYS_STATE_ERR_NULL_POINTER;
441
442         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
443                 avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
444                 return AVSYS_STATE_ERR_INTERNAL;
445         }
446
447         /* init values */
448         control->pregain = default_gain;
449         control->gain = default_gain;
450         control->reqgain = default_gain;
451         control->path = default_path;
452         control->backup_gain = default_gain;
453         control->backup_path = default_path;
454         control->option = default_option;
455
456         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
457         control->inserted = AVSYS_AUDIO_INSERTED_NONE;
458
459         if (AVSYS_FAIL(__load_conf(&conf)))
460                 avsys_error_r(AVAUDIO, "Can not load audio system configuration file\n");
461
462         if (conf.headset_detection) {
463                 control->inserted = __avsys_audio_path_get_earjack_type();
464                 if (control->inserted == AVSYS_AUDIO_INSERTED_NONE)
465                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
466                 else {
467                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET;
468                         control->path.playback = AVSYS_AUDIO_PATH_EX_HEADSET;
469
470                         if (control->inserted == AVSYS_AUDIO_INSERTED_4)
471                                 control->path.capture = AVSYS_AUDIO_PATH_EX_HEADSETMIC;
472                 }
473         } else {
474                 avsys_warning(AVAUDIO, "Ignore headset detection. Use speaker device\n");
475                 control->inserted = AVSYS_AUDIO_INSERTED_NONE;
476                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
477         }
478
479         avsys_error_r(AVAUDIO, "Earjack init value is %d\n", control->inserted);
480
481         control->control_aif_before_path_set = conf.control_aif_before_path_set;
482         control->gain_debug_mode = conf.gain_debug_mode;
483
484         control->mute = AVSYS_AUDIO_UNMUTE;
485         control->path_fixed = PATH_FIXED_NONE;
486
487         index = 0;
488         do {
489                 control->pathlock_pid[index] = -1;
490                 index++;
491         } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
492
493         index = 0;
494         do {
495                 control->path_fixed_pid[index] = -1;
496                 index++;
497         } while (index < PATH_FIXED_TYPE_MAX);
498
499         if (forced) {
500                 backup_debug = control->gain_debug_mode;
501                 control->gain_debug_mode = 1;
502         }
503         /* call path control */
504         err = __avsys_audio_path_set_ascn_ap_playback(control);
505         if (AVSYS_SUCCESS(err))
506                 err = __avsys_audio_path_set_hw_controls(control);
507
508         if (AVSYS_SUCCESS(err))
509                 err = __avsys_audio_path_set_ascn_ap_capture(control);
510
511         if (forced) {
512                 control->gain_debug_mode = backup_debug;
513         }
514
515         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
516                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
517                 return AVSYS_STATE_ERR_INTERNAL;
518         }
519
520         return err;
521 }
522
523 EXPORT_API
524 int avsys_audio_path_ex_dump(void)
525 {
526         avsys_audio_path_ex_info_t *control = NULL;
527         avsys_audio_path_ex_info_t **temp = NULL;
528         const static char *str_earType[] = { "None", "EarOnly", "EarMic", "TVout" };
529         const static char *str_yn[] = { "NO", "YES" };
530         const static char *str_ear[] = { "MANUAL", "AUTO_MUTE", "AUTO_NOMUTE" };
531         const static char *str_out[AVSYS_AUDIO_PATH_EX_OUTMAX] = {
532                 "NONE", "SPK", "RECV", "HEADSET", "BTHEADSET", "A2DP", "HANSFREE", "HDMI", "DOCK", "USBAUDIO"
533         };
534         const static char *str_in[AVSYS_AUDIO_PATH_EX_INMAX] = {
535                 "NONE", "MIC", "HEADMIC", "BTMIC", "FMINPUT", "HANSFREEMIC"
536         };
537         const static char *str_route[AVSYS_AUDIO_ROUTE_POLICY_MAX] = {
538                 "DEFAULT", "IGN_A2DP", "HANDSET"
539         };
540         /*
541         const static char *str_gain[AVSYS_AUDIO_GAIN_EX_MAX] = {
542                 "KEYTONE", "RINGTONE", "ALARMTONE", "CALLTONE", "AUDIOPLAYER", "VIDEOPLAYER",
543                 "VOICECALL", "VIDEOCALL", "FMRADIO", "VOICEREC", "CAMCORDER", "CAMERA", "GAME"};
544         */
545         const static char *str_playback_gain[AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = {
546                 "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", "CALLALERT",
547         };
548         const static char *str_capture_gain[AVSYS_AUDIO_CAPTURE_GAIN_MAX] = {
549                 "AP", "FMRADIO", "VOICECALL", "VIDEOCALL",
550         };
551
552         int index = 0;
553
554         temp = &control;
555
556         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
557                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
558                 return AVSYS_STATE_ERR_INTERNAL;
559         }
560         if (control == NULL)
561                 return AVSYS_STATE_ERR_NULL_POINTER;
562
563         fprintf(stdout, "======================================================================\n");
564         fprintf(stdout, "               Avsystem Audio Path Control Information                \n");
565         fprintf(stdout, "======================================================================\n");
566 #if defined(_MMFW_I386_ALL_SIMULATOR)
567         fprintf(stdout, " In simulator, follow informations don`t have means.\n");
568 #endif
569
570         fprintf(stdout, " GAIN                          : P (%-s / %-s) - R (%-s / %-s) - C (%-s / %-s)\n",
571                         str_playback_gain[control->pregain.playback], str_capture_gain[control->pregain.capture],
572                         str_playback_gain[control->reqgain.playback], str_capture_gain[control->reqgain.capture],
573                         str_playback_gain[control->gain.playback], str_capture_gain[control->gain.capture]);
574         fprintf(stdout, " Current Out / In              : %-s / %-s\n", str_out[control->path.playback], str_in[control->path.capture] );
575         fprintf(stdout, " Gain debug mode               : 0x%-x\n", control->gain_debug_mode);
576         fprintf(stdout, " Auto EarJack Control          : %-s\n", str_ear[control->ear_auto]);
577         fprintf(stdout, " Physical Earjack? [type]      : %-s [%-s]\n", str_yn[control->inserted != AVSYS_AUDIO_INSERTED_NONE], str_earType[control->inserted]);
578         fprintf(stdout, " Path Fixed State              : 0x%-x\n", control->path_fixed);
579         fprintf(stdout, " Mute status                   : %d\n", control->mute);
580         if (control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] != -1)
581                 fprintf(stdout, " FM Radio path pid             : %d\n", control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO]);
582         if (control->path_fixed_pid[PATH_FIXED_TYPE_CALL] != -1)
583                 fprintf(stdout, " Call  path pid                : %d\n", control->path_fixed_pid[PATH_FIXED_TYPE_CALL]);
584
585         index = 0;
586         do {
587                 if (control->pathlock_pid[index] != -1)
588                         fprintf(stdout, " Path sync lock required PIDs   : %d\n", control->pathlock_pid[index]);
589                 index++;
590         } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
591         fprintf(stdout, " Option Dual out               : %-s\n", str_yn[(control->option.playback & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) ? 1 : 0]);
592         fprintf(stdout, " Option Forced                 : %-s\n", str_yn[(control->option.playback & AVSYS_AUDIO_PATH_OPTION_FORCED) ? 1 : 0]);
593
594         return AVSYS_STATE_SUCCESS;
595 }
596
597 static int __avsys_audio_path_get_earjack_type (void)
598 {
599         int fd = 0;
600         char readval = AVSYS_AUDIO_INSERTED_NONE;
601         fd = open("/sys/devices/platform/jack/earjack_online", O_RDONLY);
602
603         if (fd == -1) {
604                 avsys_error_r(AVAUDIO, "Can not get initial jack type\n");
605                 return AVSYS_AUDIO_INSERTED_NONE;
606         }
607         read(fd, &readval, sizeof(readval));
608         switch (readval) {
609         case '0':
610                 readval = AVSYS_AUDIO_INSERTED_NONE;
611                 break;
612         case '1':
613                 readval = AVSYS_AUDIO_INSERTED_3;
614                 break;
615         case '3':
616                 readval = AVSYS_AUDIO_INSERTED_4;
617                 break;
618         case '8':
619                 readval = AVSYS_AUDIO_INSERTED_AV;
620                 break;
621         case '2':
622                 if (1 == read(fd, &readval, sizeof(readval))) {
623                         if (readval == '0') {
624                                 readval = AVSYS_AUDIO_INSERTED_AV;
625                         } else {
626                                 avsys_error(AVAUDIO, "Unknown jack type value...2%d\n", readval);
627                                 readval = AVSYS_AUDIO_INSERTED_NONE;
628                         }
629                 } else {
630                         avsys_error(AVAUDIO, "jack type read error...\n");
631                         readval = AVSYS_AUDIO_INSERTED_NONE;
632                 }
633                 break;
634         default:
635                 avsys_error(AVAUDIO, "jack type unknown value...%c\n", readval);
636                 readval = AVSYS_AUDIO_INSERTED_NONE;
637                 break;
638         }
639
640         close(fd);
641         return readval;
642 }
643
644 int avsys_audio_path_earjack_init(int *init_type, int *outfd)
645 {
646 #if !defined(_MMFW_I386_ALL_SIMULATOR)
647         char eventnode_filename[32] = { 0, };
648         int fd = 0;
649         avsys_audio_conf conf = { 0, };
650
651         if (outfd == NULL || init_type == NULL) {
652                 avsys_error(AVAUDIO, "input parameter is null\n");
653                 return AVSYS_STATE_ERR_NULL_POINTER;
654         }
655
656         if (AVSYS_FAIL(__load_conf(&conf))) {
657                 avsys_error_r(AVAUDIO, "Can not load audio system configuration file\n");
658         }
659
660         if (!conf.headset_detection) {
661                 avsys_error(AVAUDIO, "Earjack control daemon will be closed by user option...\n");
662                 return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
663         }
664
665         snprintf(eventnode_filename, sizeof(eventnode_filename), "%s%01d", EARJACK_EVENT_PATH, conf.headset_node_number);
666
667         fd = open(eventnode_filename, O_RDONLY);
668         if (fd == -1) {
669                 avsys_error_r(AVAUDIO, "Device file open error\n");
670                 return AVSYS_STATE_ERR_INTERNAL;
671         } else {
672                 avsys_audio_path_ex_info_t *control = NULL;
673                 avsys_audio_path_ex_info_t **temp = NULL;
674                 void *vol_data = NULL;
675                 void *handle_data = NULL;
676                 temp = &control;
677
678                 if(AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, &vol_data))) {
679                         avsys_error(AVAUDIO,"attach logical volume shared memory failed\n");
680                         close(fd);
681                         return AVSYS_STATE_ERR_ALLOCATION;
682                 }
683                 if(AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, &handle_data))) {
684                         avsys_error(AVAUDIO,"attach handle shared memory failed\n");
685                         close(fd);
686                         return AVSYS_STATE_ERR_ALLOCATION;
687                 }
688                 if(AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void**)temp))) {
689                         avsys_error_r(AVAUDIO,"avsys_audio_get_shm() failed in %s\n", __func__);
690                         close(fd);
691                         return AVSYS_STATE_ERR_INTERNAL;
692                 }
693
694                 *init_type = control->inserted;
695                 *outfd = fd;
696                 return AVSYS_STATE_SUCCESS;
697         }
698 #else
699         return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
700 #endif
701 }
702
703 int avsys_audio_path_earjack_wait(int fd, int *current_type, int *new_type, int *is_auto_mute)
704 {
705 #if !defined(_MMFW_I386_ALL_SIMULATOR)
706         fd_set set;
707         int readtemp;
708         int select_ret = 0;
709         struct input_event jevent;
710         int res = AVSYS_STATE_SUCCESS;
711         int cur_type = -1;
712
713         if (new_type == NULL || is_auto_mute == NULL)
714                 return AVSYS_STATE_ERR_NULL_POINTER;
715
716         FD_ZERO(&set);
717         FD_SET(fd, &set);
718
719         cur_type = *current_type;
720
721         select_ret = select(fd + 1, &set, NULL, NULL, NULL);
722         avsys_info(AVAUDIO, "SELECT returns......\n");
723
724         if (select_ret != 1) {
725                 if (select_ret == 0) {
726                         avsys_error_r(AVAUDIO, "Earjack timeout in autocontrol\n");
727                 } else if (select_ret == -1) {
728                         avsys_error_r(AVAUDIO, "Earjack detect unknown error: %d\n", errno);
729                 }
730                 return AVSYS_STATE_WAR_INVALID_VALUE;
731         }
732 #ifdef EARJACK_LOCK             /* currently this is disabled to avoid semapore value increase */
733         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
734                 avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
735                 return AVSYS_STATE_ERR_INTERNAL;
736         }
737 #endif
738         if (read(fd, &jevent, sizeof(jevent)) < 0) {
739                 avsys_error(AVAUDIO, "read fd failed with 0x%x\n", errno);
740                 return AVSYS_STATE_WAR_INVALID_MODE;
741         }
742         avsys_info(AVAUDIO, "*** JEVENT : code=%d, value=%d\n", jevent.code, jevent.value);
743         if (jevent.type != TYPE_EVENT_SWITCH) {
744                 avsys_info(AVAUDIO, "Not a switch event\n");
745                 return AVSYS_STATE_WAR_INVALID_MODE;
746         }
747
748         switch (jevent.code) {
749         case CODE_HEADPHONE_INSERT:
750         case CODE_LINEOUT_INSERT:
751         case CODE_JACK_PHYSICAL_INSERT:
752                 if (jevent.value == 1) {
753                         readtemp = __avsys_audio_path_get_earjack_type();
754                 } else {
755                         readtemp = 0;
756                 }
757                 break;
758         default:
759                 readtemp = cur_type; /* same value */
760                 break;
761         }
762
763         *new_type = readtemp;
764
765         avsys_audio_path_ex_info_t *control = NULL;
766         avsys_audio_path_ex_info_t **temp = NULL;
767         temp = &control;
768
769         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
770                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
771                 return AVSYS_STATE_ERR_INTERNAL;
772         }
773
774         avsys_info(AVAUDIO, "control->ear_auto = %d\n", control->ear_auto);
775         if (control->ear_auto == AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE) {
776                 *current_type = control->inserted;
777                 *is_auto_mute = 1;
778                 res = AVSYS_STATE_SUCCESS;
779         } else if (control->ear_auto == AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE) {
780                 *current_type = control->inserted;
781                 *is_auto_mute = 0;
782                 res = AVSYS_STATE_SUCCESS;
783         }
784
785         return res;
786
787 #else
788         return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
789 #endif
790 }
791
792 int avsys_audio_path_earjack_process(int new_type)
793 {
794 #if !defined(_MMFW_I386_ALL_SIMULATOR)
795         avsys_audio_path_ex_info_t *control = NULL;
796         avsys_audio_path_ex_info_t **temp = NULL;
797         int err = AVSYS_STATE_SUCCESS;
798         temp = &control;
799
800         avsys_info(AVAUDIO, "new_type = %d\n", new_type);
801         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
802                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
803                 return AVSYS_STATE_ERR_INTERNAL;
804         }
805
806         control->inserted = new_type;
807
808         return err;
809 #else
810         return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
811 #endif
812 }
813
814 int avsys_audio_path_earjack_deinit(int fd)
815 {
816 #if !defined(_MMFW_I386_ALL_SIMULATOR)
817         close(fd);
818         return AVSYS_STATE_SUCCESS;
819 #else
820         return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
821 #endif
822 }
823
824 int avsys_audio_path_earjack_unlock()
825 {
826 #ifdef EARJACK_LOCK             /* currently this is disabled to avoid semapore value increase */
827         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
828                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
829                 return AVSYS_STATE_ERR_INTERNAL;
830         }
831 #endif
832         return AVSYS_STATE_SUCCESS;
833 };
834
835 #define DO_IF_VALID(c, p) { if(c > -1) p; }
836 #define DO_IF_INVALID(c, p) { if(c == -1) p; }
837 #define CHECK_VALID(c) (c>-1 ? 1 : 0)
838
839 enum {
840         CMD_DEVICE_NONE = 0,
841         CMD_DEVICE_OPEN,
842         CMD_DEVICE_CLOSE,       /* Not used */
843         CMD_DEVICE_MAX
844 };
845
846 avsys_audio_alsa_aif_handle_t *g_hAIF[AIF_DEVICE_MAX] = { NULL, NULL, NULL, NULL, NULL };
847 char *strAIF[AIF_DEVICE_MAX] = { "AIF CP Capture", "AIF CP Playback", "AIF BT Capture", "AIF BT Playback", "AIF RADIO Playback" };
848
849 #define SET_AIF(index) do {     AIF_control[index] = CMD_DEVICE_OPEN; } while (0)
850
851 static int __is_cp_aif (int type)
852 {
853         return ((type == AIF_CP_PLAYBACK || type == AIF_CP_CAPTURE));
854 }
855
856 static int __avsys_open_aif(char AIF_control[], bool wb_enabled)
857 {
858         int iAIF = 0;
859         int err = AVSYS_STATE_SUCCESS;
860         bool bt_enabled = 0;
861         aif_rate_t rate = 0;
862
863         /* Check If BT is enabled */
864         for (iAIF = 0; iAIF < AIF_DEVICE_MAX; iAIF++) {
865                 if (AIF_control[iAIF] == CMD_DEVICE_OPEN && (iAIF == AIF_BT_PLAYBACK || iAIF== AIF_BT_CAPTURE)) {
866                         bt_enabled = true;
867                         break;
868                 }
869         }
870
871         /* Iterate control command */
872         avsys_info(AVAUDIO, "================== Close if reopen is needed (bt[%d] wb[%d]) ================== \n", bt_enabled, wb_enabled);
873         for (iAIF = 0; iAIF < AIF_DEVICE_MAX; iAIF++) {
874                 /* check command */
875                 if (AIF_control[iAIF] != CMD_DEVICE_OPEN)
876                         continue;
877
878                 avsys_info(AVAUDIO, "%d. [%s]\n", iAIF, strAIF[iAIF]);
879
880                 /* check handle exists */
881                 if (g_hAIF[iAIF]) {
882                         /* Handle is already opened.
883                          * Check if WB is supported and CP handle case */
884                         if (wb_enabled && __is_cp_aif(g_hAIF[iAIF]->type)) {
885                                 /* CP Handle is already opened with WB enabled .
886                                  * Determine whether re-open is needed */
887                                 if ((bt_enabled &&  g_hAIF[iAIF]->rate != AIF_NB_RATE) ||
888                                         (!bt_enabled &&  g_hAIF[iAIF]->rate == AIF_NB_RATE)) {
889                                         /* CP handle exists and BT enabled with not NB opened => close for reopen
890                                            CP handle exists and BT disabled with NB opened => close for reopen */
891                                         avsys_info(AVAUDIO, "=> Close device for reopen :: %s\n", strAIF[iAIF]);
892                                         if (AVSYS_FAIL(avsys_audio_alsa_close_AIF_device(g_hAIF[iAIF]))) {
893                                                 avsys_error_r(AVAUDIO, "close %s device failed\n", strAIF[iAIF]);
894                                         }
895                                         free(g_hAIF[iAIF]);
896                                         g_hAIF[iAIF] = NULL;
897                                 } else {
898                                         /* CP handle exists and BT enabled with NB opened ||
899                                            CP handle exists and BT disabled with not NB opened */
900                                         avsys_info(AVAUDIO, "=> Skip device :: %s\n", strAIF[iAIF]);
901                                         continue;
902                                 }
903
904                         } else {
905                                 /* Not CP case or WB is disabled. No need to reopen */
906                                 avsys_info(AVAUDIO, "=> Skip device :: %s\n", strAIF[iAIF]);
907                                 continue;
908                         }
909                 }
910         }
911
912         avsys_info(AVAUDIO, "================== Open & Set Param ================== \n");
913         /* Iterate control command */
914         for (iAIF = 0; iAIF < AIF_DEVICE_MAX; iAIF++) {
915                 /* check command */
916                 if (AIF_control[iAIF] != CMD_DEVICE_OPEN)
917                         continue;
918
919                 avsys_info(AVAUDIO, "%d. [%s]\n", iAIF, strAIF[iAIF]);
920
921                 /* check handle exists */
922                 if (g_hAIF[iAIF]) {
923                         /* Not CP case or WB is disabled. No need to reopen */
924                         avsys_info(AVAUDIO, "=> Skip device Already opened!!! :: %s\n", strAIF[iAIF]);
925                         continue;
926                 }
927
928                 /* memory allocation for handle */
929                 avsys_warning(AVAUDIO, "=> [%s] handle alloc", strAIF[iAIF]);
930                 g_hAIF[iAIF] = calloc(sizeof(avsys_audio_handle_t), 1);
931                 if (!g_hAIF[iAIF]) {
932                         avsys_error_r(AVAUDIO, "=> Can not alloc memory for [%s] device handle", strAIF[iAIF]);
933                         err = AVSYS_STATE_ERR_ALLOCATION;
934                         continue;
935                 }
936
937                 if (AVSYS_FAIL(avsys_audio_alsa_open_AIF_device(iAIF, g_hAIF[iAIF]))) {
938                         avsys_error_r(AVAUDIO, "=> open [%s] device failed\n", strAIF[iAIF]);
939                         err = AVSYS_STATE_ERR_INVALID_HANDLE;
940                 } else {
941                         avsys_warning(AVAUDIO, "=> open [%s] device success\n", strAIF[iAIF]);
942
943                         /* Select RATE */
944                         if (__is_cp_aif(g_hAIF[iAIF]->type)) {
945                                 rate = (wb_enabled && !bt_enabled)? AIF_WB_RATE : AIF_NB_RATE;
946                         } else {
947                                 rate = AIF_CONF_RATE;
948                         }
949
950                         if (AVSYS_FAIL(avsys_audio_alsa_set_AIF_params(g_hAIF[iAIF],rate))) {
951                                 avsys_error_r(AVAUDIO, "=> [%s] device set parameter failed\n", strAIF[iAIF]);
952                                 err = AVSYS_STATE_ERR_INVALID_PARAMETER;
953                         } else {
954                                 avsys_warning(AVAUDIO, "=> [%s] device set parameter success\n", strAIF[iAIF]);
955                         }
956                 }
957         }
958         return err;
959 }
960
961 static void __avsys_close_aif ()
962 {
963         int iAIF = 0;
964
965         for (iAIF = 0; iAIF < AIF_DEVICE_MAX; iAIF++) {
966                 if (g_hAIF[iAIF]) {
967                         avsys_info(AVAUDIO, "close device :: %s\n", strAIF[iAIF]);
968                         if (AVSYS_FAIL(avsys_audio_alsa_close_AIF_device(g_hAIF[iAIF]))) {
969                                 avsys_error_r(AVAUDIO, "close %s device failed\n", strAIF[iAIF]);
970                         }
971                         free(g_hAIF[iAIF]);
972                         g_hAIF[iAIF] = NULL;
973                         avsys_warning(AVAUDIO, "%s device handle free\n", strAIF[iAIF]);
974                 } else {
975                         avsys_info(AVAUDIO, "skip closing device :: %s\n", strAIF[iAIF]);
976                 }
977         }
978 }
979
980 static int __avsys_audio_release_path (gain_info_t local_gain, avsys_audio_path_ex_info_t *control)
981 {
982         int err = AVSYS_STATE_SUCCESS;
983         int iAIF = 0;
984         bool close_aif_later = false;
985
986         avsys_warning(AVAUDIO, "Release path for %d %d\n", local_gain.playback, local_gain.capture);
987
988         switch (local_gain.playback) {
989         case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL:
990         case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL:
991                 if (getpid() == control->path_fixed_pid[PATH_FIXED_TYPE_CALL]) {
992                         if (!control->control_aif_before_path_set) {
993                                 __avsys_close_aif();
994                         } else {
995                                 close_aif_later = true;
996                         }
997
998                         if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_CODEC_DISABLE_ON_SUSPEND))) {
999                                 avsys_error_r(AVAUDIO, "[%s] failed to set codec_disable_on_suspend\n", __func__);
1000                         }
1001                 } else {
1002                         if (control->path_fixed_pid[PATH_FIXED_TYPE_CALL] < 0) {
1003                                 avsys_warning(AVAUDIO, "Sound path for call released already\n");
1004                         } else {
1005                                 avsys_warning(AVAUDIO, "Try to close call path from other process.. original pid[%d]\n", control->path_fixed_pid[PATH_FIXED_TYPE_CALL]);
1006                                 avsys_warning(AVAUDIO, "Just mark handle as off\n");
1007                         }
1008                 }
1009
1010                 if ((control->path_fixed & PATH_FIXED_WITH_CALL) == 0) {
1011                         avsys_error(AVAUDIO, "Call path release without call path request\n");
1012                 }
1013                 control->path_fixed &= ~PATH_FIXED_WITH_CALL;
1014                 control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = -1;
1015
1016                 break;
1017
1018         case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO:
1019                 /* TODO: Reset & Codec disable on suspend script */
1020                 if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_CODEC_DISABLE_ON_SUSPEND))) {
1021                         avsys_error_r(AVAUDIO, "[%s] failed to set codec_disable_on_suspend\n", __func__);
1022                 }
1023
1024                 if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET_CAPTURE))) {
1025                         avsys_error_r(AVAUDIO, "[%s] failed to set reset\n", __func__);
1026                 }
1027
1028                 break;
1029
1030         default:
1031                 avsys_warning(AVAUDIO, "unexpected path release\n");
1032                 break;
1033         }
1034
1035         if (control->path_fixed != PATH_FIXED_NONE) {
1036                 avsys_error(AVAUDIO, "Still remain another path_fixed request : 0x%08X\n", control->path_fixed);
1037                 avsys_error(AVAUDIO, "This is not expected condition\n");
1038         } else {
1039                 avsys_warning(AVAUDIO, "Path Release to default condition....\n");
1040                 control->gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP;
1041                 control->gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP;
1042                 control->path.playback = AVSYS_AUDIO_PATH_EX_SPK;
1043                 control->path.capture = AVSYS_AUDIO_PATH_EX_MIC;
1044                 if (control->inserted != AVSYS_AUDIO_INSERTED_NONE) {
1045                         control->path.playback = AVSYS_AUDIO_PATH_EX_HEADSET;
1046                         if (control->inserted == AVSYS_AUDIO_INSERTED_4)
1047                                 control->path.capture = AVSYS_AUDIO_PATH_EX_HEADSETMIC;
1048                 }
1049
1050                 /* Playback */
1051                 err = __avsys_audio_path_set_ascn_ap_playback(control);
1052                 if (AVSYS_SUCCESS(err)) {
1053                         err = __avsys_audio_path_set_hw_controls(control);
1054                         if (AVSYS_FAIL(err)) {
1055                                 avsys_error(AVAUDIO, "Update logical volume failure\n");
1056                         }
1057                 } else {
1058                         avsys_error(AVAUDIO, "Set ap playback failure\n");
1059                 }
1060
1061                 /* Capture */
1062                 err = __avsys_audio_path_set_ascn_ap_capture(control);
1063                 if (AVSYS_FAIL(err)) {
1064                         avsys_error(AVAUDIO, "Set ap capture failure\n");
1065                 }
1066         }
1067
1068         if (close_aif_later == true) {
1069                 __avsys_close_aif();
1070         }
1071
1072         return err;
1073 }
1074
1075 int avsys_audio_path_earjack_get_type()
1076 {
1077         avsys_audio_path_ex_info_t *control = NULL;
1078         avsys_audio_path_ex_info_t **temp = NULL;
1079         int err = AVSYS_STATE_SUCCESS;
1080         int ret = 0;
1081
1082         temp = &control;
1083         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
1084                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
1085                 return AVSYS_STATE_ERR_INTERNAL;
1086         }
1087         if (control == NULL)
1088                 return AVSYS_STATE_ERR_NULL_POINTER;
1089
1090         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1091                 avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
1092                 return AVSYS_STATE_ERR_INTERNAL;
1093         }
1094
1095         ret = control->inserted;
1096
1097         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1098                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
1099                 return AVSYS_STATE_ERR_INTERNAL;
1100         }
1101
1102         return ret;
1103 }
1104
1105 int avsys_audio_path_ex_set_path(int gain, int out, int in, int option)
1106 {
1107         avsys_audio_path_ex_info_t *control = NULL;
1108         avsys_audio_path_ex_info_t **temp = NULL;
1109         gain_info_t local_gain = { -1, -1 };
1110         gain_info_t req_gain = { -1, -1 };
1111         pid_t current_pid;
1112         int err = AVSYS_STATE_SUCCESS;
1113         char req_release_path = 0;
1114         char AIF_control[AIF_DEVICE_MAX] = { CMD_DEVICE_NONE, CMD_DEVICE_NONE, CMD_DEVICE_NONE, CMD_DEVICE_NONE, CMD_DEVICE_NONE };
1115         int iAIF = 0;
1116
1117         avsys_warning(AVAUDIO, "=================== [Input Param] gain %d, out %d, in %d, opt 0x%x ====================\n", gain, out, in, option);
1118
1119         /* Determine REQUESTs */
1120         switch (gain) {
1121         case AVSYS_AUDIO_GAIN_EX_KEYTONE:
1122         case AVSYS_AUDIO_GAIN_EX_ALARMTONE:
1123         case AVSYS_AUDIO_GAIN_EX_AUDIOPLAYER:
1124         case AVSYS_AUDIO_GAIN_EX_VIDEOPLAYER:
1125         case AVSYS_AUDIO_GAIN_EX_CAMERA:
1126         case AVSYS_AUDIO_GAIN_EX_GAME:
1127                 req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP;
1128                 req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP;
1129                 break;
1130
1131         case AVSYS_AUDIO_GAIN_EX_RINGTONE:
1132         case AVSYS_AUDIO_GAIN_EX_CALLTONE:
1133                 req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT;
1134                 break;
1135
1136         case AVSYS_AUDIO_GAIN_EX_VOICEREC:
1137         case AVSYS_AUDIO_GAIN_EX_CAMCORDER:
1138                 req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP;
1139                 break;
1140
1141         case AVSYS_AUDIO_GAIN_EX_VOICECALL:
1142                 req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL;
1143                 req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL;
1144                 if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE)
1145                         req_release_path = 1;
1146                 break;
1147
1148         case AVSYS_AUDIO_GAIN_EX_VIDEOCALL:
1149                 req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL;
1150                 req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL;
1151                 if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE)
1152                         req_release_path = 1;
1153                 break;
1154
1155         case AVSYS_AUDIO_GAIN_EX_FMRADIO:
1156                 req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO;
1157                 req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO;
1158                 if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE)
1159                         req_release_path = 1;
1160                 break;
1161         }
1162
1163         /* Get avsys shared memeory */
1164         temp = &control;
1165         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
1166                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
1167                 return AVSYS_STATE_ERR_INTERNAL;
1168         }
1169         /* LOCK */
1170         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1171                 avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
1172                 return AVSYS_STATE_ERR_INTERNAL;
1173         }
1174
1175         current_pid = getpid(); /* moved from below */
1176
1177         /* Check FORCED option */
1178         if (option & AVSYS_AUDIO_PATH_OPTION_FORCED) {
1179                 DO_IF_VALID(req_gain.playback, local_gain.playback = req_gain.playback)
1180                 DO_IF_VALID(req_gain.capture, local_gain.capture = req_gain.capture)
1181         } else {
1182                 DO_IF_VALID(req_gain.playback, local_gain.playback = g_playback_gain_select_data[control->gain.playback][req_gain.playback])
1183                 DO_IF_VALID(req_gain.capture, local_gain.capture = g_capture_gain_select_data[control->gain.capture][req_gain.capture])
1184         }
1185
1186         avsys_info(AVAUDIO, "Gain : req(%d,%d)  local(%d,%d)\n", req_gain.playback, req_gain.capture, local_gain.playback, local_gain.capture);
1187
1188         /* Check path fixed process alive. */
1189         if (control->path_fixed & PATH_FIXED_WITH_CALL) {
1190                 if (AVSYS_FAIL(avsys_check_process(control->path_fixed_pid[PATH_FIXED_TYPE_CALL]))) {
1191                         control->path_fixed &= ~PATH_FIXED_WITH_CALL;
1192                 }
1193         }
1194         if (control->path_fixed == PATH_FIXED_NONE) {
1195                 /* forced gain setting when path fixed by dead process */
1196                 if (req_gain.playback != local_gain.playback) {
1197                         local_gain.playback = req_gain.playback;
1198                 }
1199                 if (req_gain.capture != local_gain.capture) {
1200                         local_gain.capture = req_gain.capture;
1201                 }
1202         }
1203
1204         if (CHECK_VALID(local_gain.playback)) {
1205                 if (g_playback_path_select_data[local_gain.playback][out] == 0) {
1206                         avsys_error(AVAUDIO, "[PLAYBACK] Does not support request sound path : conv gain %d, out path %d\n", local_gain.playback, out);
1207                         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1208                                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
1209                                 return AVSYS_STATE_ERR_INTERNAL;
1210                         }
1211                         return AVSYS_STATE_ERR_INVALID_STATE;
1212                 }
1213         }
1214         if (CHECK_VALID(local_gain.capture)) {
1215                 if (g_capture_path_select_data[local_gain.capture][in] == 0) {
1216                         avsys_error(AVAUDIO, "[CAPTURE] Does not support request sound path : conv gain %d, in path %d\n", local_gain.capture, in);
1217                         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1218                                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
1219                                 return AVSYS_STATE_ERR_INTERNAL;
1220                         }
1221                         return AVSYS_STATE_ERR_INVALID_STATE;
1222                 }
1223         }
1224         /* overwrite local_gain with current gain if it is simplex sound path */
1225         DO_IF_INVALID(local_gain.playback, local_gain.playback = control->gain.playback)
1226         DO_IF_INVALID(local_gain.capture, local_gain.capture = control->gain.capture)
1227         control->pregain = control->gain;
1228         control->gain = local_gain;
1229
1230         DO_IF_VALID(req_gain.playback, control->reqgain.playback = req_gain.playback)
1231         DO_IF_VALID(req_gain.capture, control->reqgain.capture = req_gain.capture)
1232         DO_IF_VALID(local_gain.playback, control->option.playback = option)
1233         DO_IF_VALID(local_gain.capture, control->option.capture = option)
1234
1235         /* Check for Release PATH */
1236         if (req_release_path && (req_gain.playback == local_gain.playback) && (req_gain.capture == local_gain.capture)) {
1237                 avsys_warning(AVAUDIO,"Release path for %d %d\n", local_gain.playback, local_gain.capture);
1238
1239                 err = __avsys_audio_release_path(local_gain, control);
1240                 goto FINISHED;
1241         }
1242         if (CHECK_VALID(req_gain.playback)) {
1243                 if(req_gain.playback != local_gain.playback) {
1244                         avsys_warning(AVAUDIO, "Sound Path is protected. use current configuration (playback_gain %d, out %d, opt 0x%x)\n",
1245                                         local_gain.playback, control->path.playback, control->option.playback);
1246                         if (req_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_AP) {
1247                                 control->backup_gain.playback = control->reqgain.playback;
1248                                 control->backup_path.playback = out;
1249                         }
1250                 } else {
1251                         control->path.playback = out;
1252                         control->backup_gain.playback = local_gain.playback;
1253                         control->backup_path.playback = out;
1254
1255                         switch (local_gain.playback) {
1256                         case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT:
1257                                 if (control->path.playback == AVSYS_AUDIO_PATH_EX_BTHEADSET) {
1258                                         SET_AIF(AIF_BT_PLAYBACK);
1259                                         SET_AIF(AIF_BT_CAPTURE);
1260                                 }
1261                                 break;
1262
1263                         case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL:
1264                         case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL:
1265                                 /* Set CP only for voicecall */
1266                                 if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL) {
1267                                         SET_AIF(AIF_CP_PLAYBACK);
1268                                 }
1269
1270                                 /* Voicecall / Videocall Common setting */
1271                                 control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid;
1272                                 if (control->path.playback == AVSYS_AUDIO_PATH_EX_BTHEADSET) {
1273                                         SET_AIF(AIF_BT_PLAYBACK);
1274                                 }
1275                                 break;
1276
1277                         case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO:
1278                                 control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid;
1279                                 SET_AIF(AIF_RADIO_PLAYBACK);
1280                                 break;
1281                         }
1282                 }
1283         }
1284
1285         if (CHECK_VALID(req_gain.capture)) {
1286                 if (req_gain.capture != local_gain.capture) {
1287                         avsys_warning(AVAUDIO, "Sound Path is protected. use current configuration (capture_gain %d, in %d, opt 0x%x)\n",
1288                                         local_gain.capture, control->path.capture, control->option.capture);
1289                         if (req_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_AP) {
1290                                 control->backup_gain.capture = control->reqgain.capture;
1291                                 control->backup_path.capture = in;
1292                         }
1293                 } else {
1294                         control->path.capture = in;
1295                         control->backup_gain.capture = local_gain.capture;
1296                         control->backup_path.capture = in;
1297
1298                         switch (local_gain.capture) {
1299                         case AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL:
1300                         case AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL:
1301                                 /* Set CP only for voicecall */
1302                                 if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL) {
1303                                         SET_AIF(AIF_CP_CAPTURE);
1304                                 }
1305
1306                                 /* Voicecall / Videocall Common setting */
1307                                 control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid;
1308                                 if (control->path.capture == AVSYS_AUDIO_PATH_EX_BTMIC) {
1309                                         SET_AIF(AIF_BT_CAPTURE);
1310                                 }
1311                                 break;
1312
1313                         case AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO:
1314                                 control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid;
1315                                 break;
1316                         }
1317                 }
1318         }
1319
1320         /* Open AIFs */
1321         if (control->control_aif_before_path_set) {
1322                 err = __avsys_open_aif(AIF_control, control->wb_enabled);
1323         }
1324
1325         /* Do ALSA scenario control based on gain */
1326         /* Playback */
1327         if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_AP) {
1328                 avsys_warning(AVAUDIO, "playback gain : ap\n");
1329                 err = __avsys_audio_path_set_ascn_ap_playback(control);
1330                 if (AVSYS_SUCCESS(err)) {
1331                         err = __avsys_audio_path_set_hw_controls(control);
1332                 }
1333         } else if(local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT) {
1334                 avsys_warning(AVAUDIO,"playback gain : callalert\n");
1335                 err = __avsys_audio_path_set_ascn_ap_playback(control);
1336                 if (AVSYS_SUCCESS(err)) {
1337                         err = __avsys_audio_path_set_hw_controls(control);
1338                 }
1339         } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO &&
1340                            local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO) {
1341                 avsys_warning(AVAUDIO, "fmradio gain\n");
1342                 err = __avsys_audio_path_set_ascn_fmradio(control);
1343         } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL &&
1344                            local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL) {
1345                 avsys_warning(AVAUDIO, "voicecall gain\n");
1346                 err = __avsys_audio_path_set_ascn_voicecall(control);
1347         } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL &&
1348                            local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL) {
1349                 avsys_warning(AVAUDIO, "videocall gain\n");
1350                 err = __avsys_audio_path_set_ascn_videocall(control);
1351         }
1352         /* Capture */
1353         if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_AP) {
1354                 avsys_warning(AVAUDIO, "capture gain : ap\n");
1355                 err = __avsys_audio_path_set_ascn_ap_capture(control);
1356         }
1357
1358         if (!control->control_aif_before_path_set) {
1359                 err = __avsys_open_aif(AIF_control, control->wb_enabled);
1360         }
1361
1362 FINISHED:
1363         /* UnLOCK */
1364         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1365                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
1366                 return AVSYS_STATE_ERR_INTERNAL;
1367         }
1368         avsys_info(AVAUDIO, "------------------------------------------------\n");
1369         return err;
1370 }
1371
1372 int avsys_audio_path_ex_get_path(int *gain, int *out, int *in, int *option)
1373 {
1374         avsys_audio_path_ex_info_t *control = NULL;
1375         avsys_audio_path_ex_info_t ** temp = NULL;
1376
1377         if(gain == NULL || out == NULL || in == NULL || option == NULL) {
1378                 avsys_error(AVAUDIO,"Invalid parameter\n");
1379                 return AVSYS_STATE_ERR_NULL_POINTER;
1380         }
1381
1382         temp = &control;
1383
1384         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
1385                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
1386                 return AVSYS_STATE_ERR_INTERNAL;
1387         }
1388         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1389                 avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
1390                 return AVSYS_STATE_ERR_INTERNAL;
1391         }
1392
1393         switch (control->gain.playback) {
1394         case AVSYS_AUDIO_PLAYBACK_GAIN_AP:
1395                 *gain = AVSYS_AUDIO_GAIN_EX_KEYTONE;
1396                 *out = control->path.playback;
1397                 *in = AVSYS_AUDIO_PATH_EX_NONE;
1398                 *option = control->option.playback;
1399                 break;
1400         case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT:
1401                 *gain = AVSYS_AUDIO_GAIN_EX_RINGTONE;
1402                 *out = control->path.playback;
1403                 *in = AVSYS_AUDIO_PATH_EX_NONE;
1404                 *option = control->option.playback;
1405                 break;
1406         case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL:
1407                 *gain = AVSYS_AUDIO_GAIN_EX_VOICECALL;
1408                 *out = control->path.playback;
1409                 *in = control->path.capture;
1410                 *option = control->option.playback;
1411                 break;
1412         case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL:
1413                 *gain = AVSYS_AUDIO_GAIN_EX_VIDEOCALL;
1414                 *out = control->path.playback;
1415                 *in = control->path.capture;
1416                 *option = control->option.playback;
1417                 break;
1418         case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO:
1419                 *gain = AVSYS_AUDIO_GAIN_EX_FMRADIO;
1420                 *out = control->path.playback;
1421                 *in = control->path.capture;
1422                 *option = control->option.playback;
1423                 break;
1424         }
1425
1426         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1427                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
1428                 return AVSYS_STATE_ERR_INTERNAL;
1429         }
1430
1431         return AVSYS_STATE_SUCCESS;
1432 }
1433
1434 int avsys_audio_path_ex_set_amp(const int onoff)
1435 {
1436         //not yet implemented.
1437         return AVSYS_STATE_SUCCESS;
1438 }
1439
1440 int avsys_audio_path_ex_set_mute(const int mute)
1441 {
1442         avsys_audio_path_ex_info_t *control = NULL;
1443         avsys_audio_path_ex_info_t **temp = NULL;
1444
1445         temp = &control;
1446
1447         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
1448                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
1449                 return AVSYS_STATE_ERR_INTERNAL;
1450         }
1451
1452         if (control == NULL) {
1453                 return AVSYS_STATE_ERR_NULL_POINTER;
1454         }
1455
1456         if (mute == AVSYS_AUDIO_UNMUTE || mute == AVSYS_AUDIO_MUTE) {
1457                 if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1458                         avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
1459                         return AVSYS_STATE_ERR_INTERNAL;
1460                 }
1461
1462                 if (control->mute == mute) {
1463                         avsys_info(AVAUDIO, "[Path Mute] skip mute ctrl op: %d\n", mute);
1464                         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1465                                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 2 failed in %s\n", __func__);
1466                                 return AVSYS_STATE_ERR_INTERNAL;
1467                         }
1468                         return AVSYS_STATE_SUCCESS;
1469                 } else {
1470                         control->mute = mute;
1471                         avsys_warning(AVAUDIO, "[Path Mute] run mute ctrl op: %d\n", mute);
1472                 }
1473
1474                 if (control->mute) {
1475                         if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_MUTE))) {
1476                                 if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1477                                         avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 1 failed in %s\n", __func__);
1478                                         return AVSYS_STATE_ERR_INTERNAL;
1479                                 }
1480                                 avsys_error(AVAUDIO, "Mute fail %s\n", __func__);
1481                                 return AVSYS_STATE_ERR_IO_CONTROL;
1482                         }
1483                 } else {
1484                         if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) {
1485                                 if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1486                                         avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 1 failed in %s\n", __func__);
1487                                         return AVSYS_STATE_ERR_INTERNAL;
1488                                 }
1489                                 avsys_error(AVAUDIO, "Unmute fail %s\n", __func__);
1490                                 return AVSYS_STATE_ERR_IO_CONTROL;
1491                         }
1492                 }
1493
1494                 if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1495                         avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 2 failed in %s\n", __func__);
1496                         return AVSYS_STATE_ERR_INTERNAL;
1497                 }
1498         } else {
1499                 int mute_nolock;
1500                 if (mute == AVSYS_AUDIO_UNMUTE_NOLOCK)  /* set nomalize */
1501                         mute_nolock = AVSYS_AUDIO_UNMUTE;
1502                 else
1503                         mute_nolock = AVSYS_AUDIO_MUTE;
1504
1505                 if (control->mute == mute_nolock) {
1506                         avsys_info(AVAUDIO, "[Path Mute] skip mute ctrl op: %d\n", mute);
1507                         return AVSYS_STATE_SUCCESS;
1508                 } else {
1509                         control->mute = mute_nolock;
1510                         avsys_warning(AVAUDIO, "[Path Mute] run mute ctrl op: %d\n", mute);
1511                 }
1512
1513                 if (control->mute) {
1514                         if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_MUTE))) {
1515                                 avsys_error(AVAUDIO, "Mute fail %s\n", __func__);
1516                                 return AVSYS_STATE_ERR_IO_CONTROL;
1517                         }
1518                 } else {
1519                         if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) {
1520                                 avsys_error(AVAUDIO, "Unmute fail %s\n", __func__);
1521                                 return AVSYS_STATE_ERR_IO_CONTROL;
1522                         }
1523                 }
1524         }
1525
1526         if (mute == AVSYS_AUDIO_UNMUTE || mute == AVSYS_AUDIO_UNMUTE_NOLOCK)
1527                 avsys_info_r(AVAUDIO, "Global Mute Disabled\n");
1528         else if (mute == AVSYS_AUDIO_MUTE || mute == AVSYS_AUDIO_MUTE_NOLOCK)
1529                 avsys_info_r(AVAUDIO, "Global Mute Enabled\n");
1530         return AVSYS_STATE_SUCCESS;
1531 }
1532
1533 int avsys_audio_path_ex_get_mute(int *mute)
1534 {
1535         avsys_audio_path_ex_info_t *control = NULL;
1536         avsys_audio_path_ex_info_t **temp = NULL;
1537
1538         temp = &control;
1539
1540         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
1541                 avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
1542                 return AVSYS_STATE_ERR_INTERNAL;
1543         }
1544
1545         if (control == NULL) {
1546                 return AVSYS_STATE_ERR_NULL_POINTER;
1547         }
1548
1549         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1550                 avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__);
1551                 return AVSYS_STATE_ERR_INTERNAL;
1552         }
1553
1554         *mute = control->mute;
1555
1556         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) {
1557                 avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__);
1558                 return AVSYS_STATE_ERR_INTERNAL;
1559         }
1560
1561         return AVSYS_STATE_SUCCESS;
1562 }
1563
1564 static int __avsys_audio_path_set_ascn_ap_playback(avsys_audio_path_ex_info_t *control)
1565 {
1566         int cmd_gain[2] = { 0, 0 };
1567         int cmd_path[3] = { 0, 0, 0 };
1568         char callalert_mode = 0;
1569
1570         avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d, inserted = %d\n",
1571                                 control->path.playback, control->option.playback, control->gain.playback, control->inserted);
1572
1573         callalert_mode = (control->gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT) ? 1 : 0;
1574         control->path_fixed = PATH_FIXED_NONE;
1575
1576         switch (control->path.playback) {
1577         case AVSYS_AUDIO_PATH_EX_SPK:
1578                 if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) {
1579                         if (callalert_mode) {
1580                                 cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_CALLALERT;
1581                                 cmd_gain[1] = INPUT_AP | OUTPUT_HEADSET | GAIN_CALLALERT;
1582                         } else {
1583                                 cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE;
1584                                 cmd_gain[1] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE;
1585                         }
1586
1587                         cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK;
1588                         cmd_path[1] = INPUT_AP | OUTPUT_HEADSET;
1589
1590                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1591                 } else {
1592                         if (callalert_mode) {
1593                                 cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_CALLALERT;
1594                         } else {
1595                                 cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE;
1596                         }
1597                         control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE;
1598                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1599
1600                         cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK;
1601                 }
1602                 break;
1603
1604         case AVSYS_AUDIO_PATH_EX_RECV:
1605                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1606                 cmd_gain[0] = INPUT_AP | OUTPUT_RECV | GAIN_MODE;
1607                 cmd_path[0] = INPUT_AP | OUTPUT_RECV;
1608                 break;
1609
1610         case AVSYS_AUDIO_PATH_EX_HEADSET:
1611                 if (callalert_mode) {
1612                         cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_CALLALERT;
1613                 } else {
1614                         cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE;
1615                 }
1616                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET;
1617                 cmd_path[0] = INPUT_AP | OUTPUT_HEADSET;
1618                 break;
1619
1620         case AVSYS_AUDIO_PATH_EX_HDMI:
1621                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1622                 cmd_gain[0] = INPUT_AP | OUTPUT_HDMI | GAIN_MODE;
1623                 cmd_path[0] = INPUT_AP | OUTPUT_HDMI;
1624                 break;
1625
1626         case AVSYS_AUDIO_PATH_EX_DOCK:
1627                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1628                 cmd_gain[0] = INPUT_AP | OUTPUT_DOCK | GAIN_MODE;
1629                 cmd_path[0] = INPUT_AP | OUTPUT_DOCK;
1630                 break;
1631
1632         case AVSYS_AUDIO_PATH_EX_BTHEADSET:
1633                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET;
1634                 cmd_gain[0] = INPUT_AP | OUTPUT_BT_HEADSET | GAIN_MODE;
1635                 cmd_path[0] = INPUT_AP | OUTPUT_BT_HEADSET;
1636                 break;
1637         case AVSYS_AUDIO_PATH_EX_HANDSFREE:
1638         default:                /* DEFAULT PATH CONTROL TO NONE */
1639                 control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1640                 break;
1641         }
1642
1643         avsys_warning(AVAUDIO, "Run Alsa Scenario Script\n");
1644         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 2, ASCN_RESET_PLAYBACK))
1645         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 2, ASCN_RESET_NONE))
1646
1647         avsys_info(AVAUDIO, ">> leave");
1648         return AVSYS_STATE_SUCCESS;
1649 }
1650
1651 static int __avsys_audio_path_set_ascn_voicecall(avsys_audio_path_ex_info_t *control)
1652 {
1653         int cmd_gain[6] = { 0, 0, 0, 0, 0, 0 };
1654         int cmd_path[6] = { 0, 0, 0, 0, 0, 0 };
1655         int gain_idx = 0;
1656         int path_idx = 0;
1657         control->path_fixed = PATH_FIXED_WITH_CALL;
1658
1659         avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d, inserted = %d\n",
1660                                 control->path.playback, control->option.playback, control->gain.playback, control->inserted);
1661
1662         /* PLAYBACK */
1663         switch (control->path.playback) {
1664         case AVSYS_AUDIO_PATH_EX_NONE:
1665                 avsys_warning(AVAUDIO, "[SZ] playback AVSYS_AUDIO_PATH_EX_NONE\n");
1666                 break;
1667
1668         case AVSYS_AUDIO_PATH_EX_SPK:
1669                 if (control->reqgain.playback == control->gain.playback) {
1670                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE;
1671                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK;
1672                         cmd_gain[gain_idx++] = INPUT_CP | OUTPUT_STEREO_SPK | GAIN_VOICE_CALL;
1673                         cmd_path[path_idx++] = INPUT_CP | OUTPUT_STEREO_SPK;
1674                 } else {
1675                         avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n");
1676                 }
1677                 break;
1678
1679         case AVSYS_AUDIO_PATH_EX_RECV:
1680                 if (control->gain.playback == control->reqgain.playback) {
1681                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_RECV | GAIN_MODE;
1682                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_RECV;
1683                         cmd_gain[gain_idx++] = INPUT_CP | OUTPUT_RECV | GAIN_VOICE_CALL;
1684                         cmd_path[path_idx++] = INPUT_CP | OUTPUT_RECV;
1685                 } else {
1686                         avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n");
1687                 }
1688                 break;
1689
1690         case AVSYS_AUDIO_PATH_EX_HEADSET:
1691                 if (control->reqgain.playback == control->gain.playback) {
1692                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE;
1693                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET;
1694                         cmd_gain[gain_idx++] = INPUT_CP | OUTPUT_HEADSET | GAIN_VOICE_CALL;
1695                         cmd_path[path_idx++] = INPUT_CP | OUTPUT_HEADSET;
1696                 } else {
1697                         avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n");
1698                 }
1699                 break;
1700
1701         case AVSYS_AUDIO_PATH_EX_BTHEADSET:
1702
1703                 if (control->reqgain.playback == control->gain.playback) {
1704                         control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE;
1705                         cmd_gain[gain_idx++] = INPUT_CP | OUTPUT_BT_HEADSET | GAIN_MODE;
1706                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_BT_HEADSET;
1707                         cmd_path[path_idx++] = INPUT_CP | OUTPUT_BT_HEADSET;
1708                 } else {
1709                         avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n");
1710                 }
1711                 break;
1712
1713         case AVSYS_AUDIO_PATH_EX_HANDSFREE:
1714         default:
1715                 if (control->reqgain.playback == control->gain.playback) {
1716                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1717                 }
1718                 break;
1719         }
1720
1721
1722         /* Add sound path CP to AP (Rx recording) */
1723         if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC) {
1724                 avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC\n");
1725                 //cmd_path[path_idx++] = INPUT_CP | OUTPUT_AP;
1726         }
1727
1728
1729         /* CAPTURE */
1730         switch (control->path.capture) {
1731         case AVSYS_AUDIO_PATH_EX_NONE:
1732                 avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_EX_NONE\n");
1733                 break;
1734
1735         case AVSYS_AUDIO_PATH_EX_MIC:
1736                 if (control->reqgain.capture == control->gain.capture) {
1737                         if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) {
1738                                 cmd_gain[gain_idx++] = INPUT_SUB_MIC | OUTPUT_CP | GAIN_MODE;
1739                                 cmd_path[path_idx++] = INPUT_SUB_MIC | OUTPUT_CP;
1740                                 if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC) {
1741                                         avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC\n");
1742                                         //cmd_path[path_idx++] = INPUT_SUB_MIC | OUTPUT_AP;
1743                                 }
1744                         } else {
1745                                 cmd_gain[gain_idx++] = INPUT_MAIN_MIC | OUTPUT_CP | GAIN_MODE;
1746                                 cmd_path[path_idx++] = INPUT_MAIN_MIC | OUTPUT_CP;
1747                                 if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC) {
1748                                         avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC\n");
1749                                         //cmd_path[path_idx++] = INPUT_MAIN_MIC | OUTPUT_AP;
1750                                 }
1751                         }
1752                 }
1753                 break;
1754
1755         case AVSYS_AUDIO_PATH_EX_HEADSETMIC:
1756                 if (control->reqgain.capture == control->gain.capture) {
1757                         cmd_gain[gain_idx++] = INPUT_EAR_MIC | OUTPUT_CP | GAIN_MODE;
1758                         cmd_path[path_idx++] = INPUT_EAR_MIC | OUTPUT_CP;
1759                         if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC) {
1760                                 avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC\n");
1761                                 //cmd_path[path_idx++] = INPUT_EAR_MIC | OUTPUT_AP;
1762                         }
1763                 }
1764                 break;
1765
1766         case AVSYS_AUDIO_PATH_EX_BTMIC:
1767                 if (control->reqgain.capture == control->gain.capture) {
1768                         cmd_gain[gain_idx++] = INPUT_BT_MIC | OUTPUT_CP | GAIN_MODE;
1769                         cmd_path[path_idx++] = INPUT_BT_MIC | OUTPUT_CP;
1770                         if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC) {
1771                                 avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC\n");
1772                                 //avsys_error(AVAUDIO, "BT Call recording is not supported");
1773                         }
1774                 }
1775                 break;
1776         case AVSYS_AUDIO_PATH_EX_HANDSFREE:
1777         default:
1778                 break;
1779         }
1780
1781         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET));
1782         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 6, ASCN_RESET_NONE));
1783         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 6, ASCN_RESET_NONE));
1784
1785         avsys_info(AVAUDIO, ">> leave");
1786         return AVSYS_STATE_SUCCESS;
1787 }
1788
1789 static int __avsys_audio_path_set_ascn_videocall(avsys_audio_path_ex_info_t *control)
1790 {
1791         int cmd_gain[2] = { 0, 0 };
1792         int cmd_path[3] = { 0, 0, 0 };
1793         int gain_idx = 0;
1794         int path_idx = 0;
1795
1796         control->path_fixed = PATH_FIXED_WITH_CALL;
1797         switch (control->path.playback) {
1798         case AVSYS_AUDIO_PATH_EX_NONE:
1799                 avsys_warning(AVAUDIO, "[SZ] playback AVSYS_AUDIO_PATH_EX_NONE\n");
1800                 break;
1801
1802         case AVSYS_AUDIO_PATH_EX_SPK:
1803                 if (control->reqgain.playback == control->gain.playback) {
1804                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE;
1805                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK;
1806                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1807                 } else {
1808                         avsys_warning(AVAUDIO, "Sound Path request during VT call ignored.");
1809                 }
1810                 break;
1811
1812         case AVSYS_AUDIO_PATH_EX_RECV:
1813                 if (control->gain.playback == control->reqgain.playback) {
1814                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_RECV | GAIN_MODE;
1815                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_RECV;
1816                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1817                 } else {
1818                         avsys_warning(AVAUDIO, "Sound Path request during VT call ignored.");
1819                 }
1820                 break;
1821
1822         case AVSYS_AUDIO_PATH_EX_HEADSET:
1823                 if (control->reqgain.playback == control->gain.playback) {
1824                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE;
1825                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET;
1826                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET;
1827                 } else {
1828                         avsys_warning(AVAUDIO, "Sound Path request during VT call ignored.");
1829                 }
1830                 break;
1831
1832         case AVSYS_AUDIO_PATH_EX_BTHEADSET:
1833                 if (control->reqgain.playback == control->gain.playback) {
1834                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_BT_HEADSET | GAIN_MODE;
1835                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_BT_HEADSET;
1836                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET;
1837                 } else {
1838                         avsys_warning(AVAUDIO, "Sound Path request during VT call ignored.");
1839                 }
1840                 break;
1841
1842         case AVSYS_AUDIO_PATH_EX_HANDSFREE:
1843         default:
1844                 if (control->reqgain.playback == control->gain.playback) {
1845                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1846                 }
1847                 break;
1848         }
1849
1850         switch (control->path.capture) {
1851         case AVSYS_AUDIO_PATH_EX_NONE:
1852                 avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_EX_NONE\n");
1853                 break;
1854
1855         case AVSYS_AUDIO_PATH_EX_MIC:
1856                 if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) {
1857                         cmd_gain[gain_idx++] = INPUT_SUB_MIC | OUTPUT_AP | GAIN_MODE;
1858                         cmd_path[path_idx++] = INPUT_SUB_MIC | OUTPUT_AP;
1859                 } else {
1860                         cmd_gain[gain_idx++] = INPUT_MAIN_MIC | OUTPUT_AP | GAIN_MODE;
1861                         cmd_path[path_idx++] = INPUT_MAIN_MIC | OUTPUT_AP;
1862                 }
1863                 break;
1864
1865         case AVSYS_AUDIO_PATH_EX_HEADSETMIC:
1866                 cmd_gain[gain_idx++] = INPUT_EAR_MIC | OUTPUT_AP | GAIN_MODE;
1867                 cmd_path[path_idx++] = INPUT_EAR_MIC | OUTPUT_AP;
1868                 break;
1869
1870         case AVSYS_AUDIO_PATH_EX_BTMIC:
1871                 cmd_gain[gain_idx++] = INPUT_BT_MIC | OUTPUT_AP | GAIN_MODE;
1872                 cmd_path[path_idx++] = INPUT_BT_MIC | OUTPUT_AP;
1873
1874                 break;
1875         case AVSYS_AUDIO_PATH_EX_HANDSFREE:
1876         default:
1877                 break;
1878         }
1879
1880         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET));
1881         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 2, ASCN_RESET_NONE));
1882         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 2, ASCN_RESET_NONE));
1883
1884         return AVSYS_STATE_SUCCESS;
1885 }
1886
1887
1888 static int __avsys_audio_path_set_ascn_fmradio(avsys_audio_path_ex_info_t *control)
1889 {
1890         int cmd_gain[2] = { 0, 0 };
1891         int cmd_path[3] = { 0, 0, 0 };
1892         int skip_clear = 0;
1893         int skip_clear_record = 0;
1894         int gain_idx = 0;
1895         int path_idx = 0;
1896
1897         avsys_warning(AVAUDIO, "req gain playback [%x], control gain playback [%x]\n",
1898                         control->reqgain.playback, control->gain.playback);
1899         avsys_warning(AVAUDIO, "req gain capture [%x], control gain capture [%x]\n",
1900                                 control->reqgain.capture, control->gain.capture);
1901
1902         switch (control->path.playback) {
1903         case AVSYS_AUDIO_PATH_EX_NONE:
1904                 avsys_warning(AVAUDIO, "[SZ] playback AVSYS_AUDIO_PATH_EX_NONE\n");
1905                 break;
1906
1907         case AVSYS_AUDIO_PATH_EX_SPK:
1908                 if (control->reqgain.playback == control->gain.playback) {
1909                         avsys_warning(AVAUDIO, "req gain playback == control gain playback\n");
1910                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE;
1911                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK;
1912                 } else {
1913                         avsys_warning(AVAUDIO, "req gain playback != control gain playback\n");
1914                         /* append ap playback sound path */
1915                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
1916                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK;
1917                         skip_clear = 1;
1918                 }
1919                 break;
1920
1921         case AVSYS_AUDIO_PATH_EX_HEADSET:
1922                 if (control->reqgain.playback == control->gain.playback) {
1923                         avsys_warning(AVAUDIO, "req gain playback  == control gain playback\n");
1924                         cmd_gain[gain_idx++] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE;
1925                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET;
1926                 } else {
1927                         //append ap playback
1928                         avsys_warning(AVAUDIO, "req gain playback != control gain playback\n");
1929                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET;
1930                         cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET;
1931                         skip_clear = 1;
1932                 }
1933                 break;
1934
1935         case AVSYS_AUDIO_PATH_EX_A2DP:
1936                 if (control->reqgain.playback == control->gain.playback) {
1937                         avsys_warning(AVAUDIO, "req gain playback == control gain playback\n");
1938                         //control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL;
1939                 } else {
1940                         avsys_warning(AVAUDIO, "req gain playback != control gain playback\n");
1941                         control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET;
1942                         skip_clear = 1;
1943                 }
1944                 break;
1945
1946         default:
1947                 break;
1948         }
1949
1950         switch (control->path.capture) {
1951         case AVSYS_AUDIO_PATH_EX_FMINPUT:
1952                 if (control->reqgain.capture == control->gain.capture) {
1953                         avsys_warning(AVAUDIO, "req gain capture == control gain capture\n");
1954                         cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_AP | GAIN_MODE;
1955                         cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_AP;
1956                         if (control->reqgain.capture == control->pregain.capture) {
1957                                 avsys_warning(AVAUDIO, "req gain capture == control pregain capture\n");
1958                                 skip_clear_record = 1;
1959                         }
1960                 }
1961                 break;
1962         default:
1963                 break;
1964         }
1965
1966         if (skip_clear_record) {
1967                 RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET_PLAYBACK))
1968         } else if (!skip_clear) {
1969                 RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET))
1970         }
1971         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, gain_idx, ASCN_RESET_NONE))
1972         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, path_idx, ASCN_RESET_NONE))
1973
1974         return AVSYS_STATE_SUCCESS;
1975 }
1976
1977 static int __avsys_audio_path_set_ascn_ap_capture(avsys_audio_path_ex_info_t *control)
1978 {
1979         int cmd_gain[2] = { 0, 0 };
1980         int cmd_path[3] = { 0, 0, 0 };
1981
1982         avsys_info(AVAUDIO, "<< path.capture = %d, option = %x, gain.capture = %d, inserted = %d\n",
1983                                 control->path.capture, control->option.capture, control->gain.capture, control->inserted);
1984         switch(control->path.capture) {
1985         case AVSYS_AUDIO_PATH_EX_MIC:
1986                 control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE;
1987                 if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) {
1988                         cmd_gain[0] = INPUT_SUB_MIC | OUTPUT_AP | GAIN_MODE;
1989                         cmd_path[0] = INPUT_SUB_MIC | OUTPUT_AP;
1990                 } else if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC) {
1991                         cmd_gain[0] = INPUT_STEREO_MIC | OUTPUT_AP | GAIN_MODE;
1992                         cmd_path[0] = INPUT_STEREO_MIC | OUTPUT_AP;
1993                 } else {
1994                         cmd_gain[0] = INPUT_MAIN_MIC | OUTPUT_AP | GAIN_MODE;
1995                         cmd_path[0] = INPUT_MAIN_MIC | OUTPUT_AP;
1996                 }
1997                 break;
1998
1999         case AVSYS_AUDIO_PATH_EX_HEADSETMIC:
2000                 cmd_gain[0] = INPUT_EAR_MIC | OUTPUT_AP | GAIN_MODE;
2001                 cmd_path[0] = INPUT_EAR_MIC | OUTPUT_AP;
2002                 break;
2003
2004         default:
2005                 break;
2006         }
2007
2008         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 2, ASCN_RESET_CAPTURE))
2009         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 2, ASCN_RESET_NONE))
2010
2011         avsys_info (AVAUDIO, ">> leave");
2012
2013         return AVSYS_STATE_SUCCESS;
2014 }
2015
2016
2017 static int __avsys_audio_path_set_hw_controls(avsys_audio_path_ex_info_t *control)
2018 {
2019         avsys_audio_handle_info_t *handle_control = NULL;
2020         avsys_audio_handle_info_t **temp = NULL;
2021         int ret = AVSYS_STATE_SUCCESS;
2022         avsys_info(AVAUDIO, "global mute %d\n", control->mute);
2023         avsys_info(AVAUDIO, "path_fixed mute %d\n", control->path_fixed);
2024
2025         /* update logical volume table - about output device - information for open handles */
2026         avsys_info(AVAUDIO, "Control handle informations\n");
2027         {
2028                 avsys_audio_handle_t *ptr = NULL;
2029                 int handle = -1;
2030                 int out_device = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK;
2031
2032                 temp = &handle_control;
2033                 if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void**)temp))) {
2034                         avsys_error(AVAUDIO, "avsys_audio_get_shm() failed in %s\n",__func__);
2035                         return AVSYS_STATE_ERR_INTERNAL;
2036                 }
2037
2038                 if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) {
2039                         avsys_error(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n",__func__);
2040                         return AVSYS_STATE_ERR_INTERNAL;
2041                 }
2042
2043                 while (++handle < AVSYS_AUDIO_HANDLE_MAX) {
2044                         long long int flag = 0x01;
2045                         flag <<= handle;
2046
2047                         if (handle_control->allocated & flag)
2048                         {
2049                                 ptr = &(handle_control->handles[handle]);
2050
2051                                 if (ptr->mode != AVSYS_AUDIO_MODE_OUTPUT && ptr->mode != AVSYS_AUDIO_MODE_OUTPUT_CLOCK
2052                                                         && ptr->mode != AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY && ptr->mode != AVSYS_AUDIO_MODE_OUTPUT_AP_CALL) {
2053                                         continue;
2054                                 }
2055                                 ptr->path_off = 0;
2056                                 out_device = control->lvol_dev_type;
2057                                 avsys_audio_logical_volume_update_table(out_device, &ptr->gain_setting);
2058                                 avsys_audio_logical_volume_convert(&ptr->setting_vol, &ptr->working_vol, &ptr->gain_setting);
2059                         }
2060                 }
2061
2062                 if(AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) {
2063                         avsys_error(AVAUDIO,"avsys_audio_unlock_sync() failed in %s\n",__func__);
2064                         return AVSYS_STATE_ERR_INTERNAL;
2065                 }
2066         }
2067         return AVSYS_STATE_SUCCESS;
2068 }
2069
2070 static bool __avsys_audio_path_check_cp_audio(int gain)
2071 {
2072         /*If video call uses CP audio, add AVSYS_AUDIO_GAIN_EX_VIDEOCALL to following code. */
2073         if (gain == AVSYS_AUDIO_GAIN_EX_VOICECALL)
2074                 return true;
2075         else
2076                 return false;
2077 }
2078
2079 int avsys_audio_path_set_volume(int handle)
2080 {
2081         avsys_audio_path_ex_info_t *control = NULL;
2082         avsys_audio_path_ex_info_t **temp = NULL;
2083         avsys_audio_handle_t *ptr = NULL;
2084         int err;
2085         int vol_conf, vol_conf_type;
2086         int out_device = AVSYS_AUDIO_DEVICE_TYPE_SPK;
2087
2088         err = avsys_audio_handle_get_ptr(handle, &ptr, HANDLE_PTR_MODE_NORMAL);
2089         if (AVSYS_FAIL(err)) {
2090                 avsys_error(AVAUDIO, "Handle is not allocated\n");
2091                 avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL);
2092                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
2093         }
2094
2095         temp = &control;
2096         avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp)));
2097         avsys_assert(control != NULL);
2098         avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH)));
2099
2100         if (__avsys_audio_path_check_cp_audio(control->gain.playback))
2101                 ptr->during_cp_audio = 1;
2102         else
2103                 ptr->during_cp_audio = 0;
2104
2105         vol_conf = ptr->gain_setting.volume_config;
2106         vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(vol_conf);
2107         out_device = control->lvol_dev_type;
2108         avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH)));
2109         avsys_warning(AVAUDIO, "set path volume  : gain(%d), out_dev(%d)\n", vol_conf_type, out_device);
2110         err = avsys_audio_logical_volume_set_table(vol_conf, out_device, &ptr->gain_setting);
2111         avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL);
2112         return err;
2113 }
2114
2115 int avsys_audio_path_set_route_policy(avsys_audio_route_policy_t route)
2116 {
2117         /* Deprecated */
2118         return 0;
2119 }
2120
2121 int avsys_audio_path_get_route_policy(avsys_audio_route_policy_t *route)
2122 {
2123         /* Deprecated */
2124         return 0;
2125 }
2126
2127 int avsys_audio_path_check_cp_audio(bool *cpaudio, bool *btpath)
2128 {
2129         avsys_audio_path_ex_info_t *control = NULL;
2130         avsys_audio_path_ex_info_t **temp = NULL;
2131
2132         if (!cpaudio || !btpath)
2133                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
2134
2135         temp = &control;
2136         avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp)));
2137         avsys_assert(control != NULL);
2138         avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH)));
2139
2140         if (__avsys_audio_path_check_cp_audio(control->gain.playback))
2141                 *cpaudio = true;
2142         else
2143                 *cpaudio = false;
2144
2145         if (control->path.playback == AVSYS_AUDIO_PATH_EX_BTHEADSET)
2146                 *btpath = true;
2147         else
2148                 *btpath = false;
2149
2150         avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH)));
2151         return AVSYS_STATE_SUCCESS;
2152 }
2153
2154 int avsys_audio_path_set_single_ascn(char *str)
2155 {
2156         if (!str)
2157                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
2158
2159         RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(str))
2160
2161         return AVSYS_STATE_SUCCESS;
2162 }