1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "audio_hw_utils"
18 //#define LOG_NDEBUG 0
19 
20 #include <errno.h>
21 #include <cutils/properties.h>
22 #include <cutils/config_utils.h>
23 #include <stdlib.h>
24 #include <dlfcn.h>
25 #include <cutils/str_parms.h>
26 #include <cutils/log.h>
27 #include <cutils/misc.h>
28 
29 #include "audio_hw.h"
30 #include "platform.h"
31 #include "platform_api.h"
32 #include "audio_extn.h"
33 
34 #define MAX_LENGTH_MIXER_CONTROL_IN_INT 128
35 
set_mixer_ctrl(struct audio_device * adev,int pcm_device_id,int app_type,int acdb_dev_id,int sample_rate,int stream_type)36 static int set_mixer_ctrl(struct audio_device *adev,
37                           int pcm_device_id, int app_type,
38                           int acdb_dev_id, int sample_rate, int stream_type)
39 {
40 
41     char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
42     struct mixer_ctl *ctl;
43     int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
44 
45     if (stream_type == PCM_PLAYBACK) {
46         snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
47              "Audio Stream %d App Type Cfg", pcm_device_id);
48     } else if (stream_type == PCM_CAPTURE) {
49         snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
50              "Audio Stream Capture %d App Type Cfg", pcm_device_id);
51     }
52 
53     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
54     if (!ctl) {
55         ALOGE("%s: Could not get ctl for mixer cmd - %s",
56              __func__, mixer_ctl_name);
57         rc = -EINVAL;
58         goto exit;
59     }
60     app_type_cfg[len++] = app_type;
61     app_type_cfg[len++] = acdb_dev_id;
62     app_type_cfg[len++] = sample_rate;
63     ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d sample rate %d",
64           __func__, stream_type, app_type, acdb_dev_id, sample_rate);
65     mixer_ctl_set_array(ctl, app_type_cfg, len);
66 
67 exit:
68     return rc;
69 }
70 
audio_extn_utils_send_default_app_type_cfg(void * platform,struct mixer * mixer)71 void audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer)
72 {
73     int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1};
74     int length = 0, app_type = 0,rc = 0;
75     struct mixer_ctl *ctl = NULL;
76     const char *mixer_ctl_name = "App Type Config";
77 
78     ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
79     if (!ctl) {
80         ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
81         return;
82     }
83     rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type);
84     if (rc == 0) {
85         app_type_cfg[length++] = 1;
86         app_type_cfg[length++] = app_type;
87         app_type_cfg[length++] = 48000;
88         app_type_cfg[length++] = 16;
89         mixer_ctl_set_array(ctl, app_type_cfg, length);
90     }
91     return;
92 }
93 
audio_extn_utils_send_app_type_cfg(struct audio_device * adev,struct audio_usecase * usecase)94 int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
95                                        struct audio_usecase *usecase)
96 {
97     struct mixer_ctl *ctl;
98     int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
99     int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
100     int app_type = 0, rc = 0;
101 
102     ALOGV("%s", __func__);
103 
104     if (usecase->type != PCM_HFP_CALL) {
105         ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
106         rc = 0;
107         goto exit_send_app_type_cfg;
108     }
109     if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
110         (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
111         ALOGV("%s: a playback path where app type cfg is not required", __func__);
112         rc = 0;
113         goto exit_send_app_type_cfg;
114     }
115 
116     snd_device = usecase->out_snd_device;
117     pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
118 
119     snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
120                  audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device;
121     acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
122     if (acdb_dev_id < 0) {
123         ALOGE("%s: Couldn't get the acdb dev id", __func__);
124         rc = -EINVAL;
125         goto exit_send_app_type_cfg;
126     }
127 
128     if (usecase->type == PCM_HFP_CALL) {
129 
130         /* config HFP session:1 playback path */
131         rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type);
132         if (rc < 0)
133             goto exit_send_app_type_cfg;
134 
135         sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
136         rc = set_mixer_ctrl(adev, pcm_device_id, app_type,
137                acdb_dev_id, sample_rate, PCM_PLAYBACK);
138         if (rc < 0)
139             goto exit_send_app_type_cfg;
140         /* config HFP session:1 capture path */
141         rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type);
142 
143         if (rc == 0) {
144             rc = set_mixer_ctrl(adev, pcm_device_id, app_type,
145                    acdb_dev_id, sample_rate, PCM_CAPTURE);
146             if (rc < 0)
147                 goto exit_send_app_type_cfg;
148         }
149         /* config HFP session:2 capture path */
150         pcm_device_id = HFP_ASM_RX_TX;
151         snd_device = usecase->in_snd_device;
152         acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
153         if (acdb_dev_id <= 0) {
154             ALOGE("%s: Couldn't get the acdb dev id", __func__);
155             rc = -EINVAL;
156             goto exit_send_app_type_cfg;
157         }
158         rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type);
159         if (rc == 0) {
160             rc = set_mixer_ctrl(adev, pcm_device_id, app_type,
161                    acdb_dev_id, sample_rate, PCM_CAPTURE);
162             if (rc < 0)
163                 goto exit_send_app_type_cfg;
164         }
165 
166         /* config HFP session:2 playback path */
167         rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type);
168         if (rc == 0) {
169             rc = set_mixer_ctrl(adev, pcm_device_id, app_type,
170                    acdb_dev_id, sample_rate, PCM_PLAYBACK);
171             if (rc < 0)
172                 goto exit_send_app_type_cfg;
173         }
174     }
175 
176     rc = 0;
177 exit_send_app_type_cfg:
178     return rc;
179 }
180