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
36static 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
67exit:
68    return rc;
69}
70
71void 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
94int 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;
177exit_send_app_type_cfg:
178    return rc;
179}
180