1 /*
2  * Copyright (C) 2022 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 #ifdef HFP_ENABLED
17 
18 #define LOG_TAG "audio_hw_hfp"
19 #define LOG_NDDEBUG 0
20 
21 #include "audio_extn.h"
22 #include <cutils/log.h>
23 #include <cutils/str_parms.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 
27 #define AUDIO_PARAMETER_HFP_ENABLE "hfp_enable"
28 #define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
29 #define AUDIO_PARAMETER_HFP_VOLUME "hfp_volume"
30 #define AUDIO_PARAMETER_HFP_VALUE_MAX 128
31 
hfp_set_enable(struct generic_audio_device * adev,bool enable)32 static int hfp_set_enable(struct generic_audio_device *adev, bool enable) {
33   struct mixer_ctl *ctl;
34   ALOGD("%s: enter enable : %d", __func__, enable);
35 
36   ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_ENABLE);
37   if (!ctl) {
38     ALOGE("%s: Could not get mixer ctl for - %s", __func__,
39           AUDIO_PARAMETER_HFP_ENABLE);
40     return -EINVAL;
41   }
42 
43   if (mixer_ctl_set_value(ctl, 0, enable) < 0) {
44     ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
45           AUDIO_PARAMETER_HFP_ENABLE);
46     return -EINVAL;
47   }
48 
49   adev->hfp_running = enable;
50   ALOGD("%s: exit: status success", __func__);
51   return 0;
52 }
53 
hfp_set_sampling_rate(struct generic_audio_device * adev,int rate)54 static int hfp_set_sampling_rate(struct generic_audio_device *adev, int rate) {
55   struct mixer_ctl *ctl;
56   ALOGD("%s: enter rate = %d", __func__, rate);
57 
58   ctl =
59       mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
60   if (!ctl) {
61     ALOGE("%s: Could not get mixer ctl for - %s", __func__,
62           AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
63     return -EINVAL;
64   }
65 
66   if (mixer_ctl_set_value(ctl, 0, rate) < 0) {
67     ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
68           AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
69     return -EINVAL;
70   }
71 
72   ALOGD("%s: exit: status success", __func__);
73   return 0;
74 }
75 
hfp_set_volume(struct generic_audio_device * adev,int vol)76 static int hfp_set_volume(struct generic_audio_device *adev, int vol) {
77   struct mixer_ctl *ctl;
78   ALOGD("%s: enter vol = %d", __func__, vol);
79 
80   ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_VOLUME);
81   if (!ctl) {
82     ALOGE("%s: Could not get mixer ctl for - %s", __func__,
83           AUDIO_PARAMETER_HFP_VOLUME);
84     return -EINVAL;
85   }
86 
87   if (mixer_ctl_set_value(ctl, 0, vol) < 0) {
88     ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
89           AUDIO_PARAMETER_HFP_VOLUME);
90     return -EINVAL;
91   }
92 
93   ALOGD("%s: exit: status success", __func__);
94   return 0;
95 }
96 
audio_extn_hfp_set_parameters(struct generic_audio_device * adev,struct str_parms * parms)97 int audio_extn_hfp_set_parameters(struct generic_audio_device *adev,
98                                   struct str_parms *parms) {
99   int ret = 0, rate, vol;
100   char value[AUDIO_PARAMETER_HFP_VALUE_MAX] = {0};
101 
102   ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_ENABLE, value,
103                           sizeof(value));
104   if (ret >= 0) {
105     if (!strncmp(value, "true", sizeof(value))) {
106       if (!adev->hfp_running)
107         ret = hfp_set_enable(adev, true);
108       else
109         ALOGW("%s: HFP is already active.", __func__);
110     } else {
111       if (adev->hfp_running)
112         ret = hfp_set_enable(adev, false);
113       else
114         ALOGW("%s: ignore STOP, HFP not active", __func__);
115     }
116 
117     if (ret < 0)
118       goto exit;
119   }
120 
121   memset(value, 0, sizeof(value));
122   ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE, value,
123                           sizeof(value));
124   if (ret >= 0) {
125     rate = strtol(value, NULL, 10);
126     ret = hfp_set_sampling_rate(adev, rate);
127     if (ret < 0)
128       goto exit;
129   }
130 
131   memset(value, 0, sizeof(value));
132   ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_VOLUME, value,
133                           sizeof(value));
134   if (ret >= 0) {
135     vol = strtol(value, NULL, 10);
136     ret = hfp_set_volume(adev, vol);
137   }
138 
139 exit:
140   ALOGD("%s exit: status", __func__);
141   return ret;
142 }
143 #endif /*HFP_ENABLED*/
144