1 /*
2 * Copyright (C) 2015 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_extn"
18 /*#define LOG_NDEBUG 0*/
19 #define LOG_NDDEBUG 0
20
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <dlfcn.h>
24 #include <cutils/properties.h>
25 #include <log/log.h>
26
27 #include "audio_hw.h"
28 #include "audio_extn.h"
29 #include "platform.h"
30 #include "platform_api.h"
31
32 struct snd_card_split cur_snd_card_split = {
33 .device = {0},
34 .snd_card = {0},
35 .form_factor = {0},
36 };
37
audio_extn_get_snd_card_split()38 struct snd_card_split *audio_extn_get_snd_card_split()
39 {
40 return &cur_snd_card_split;
41 }
42
audio_extn_set_snd_card_split(const char * in_snd_card_name)43 void audio_extn_set_snd_card_split(const char* in_snd_card_name)
44 {
45 /* sound card name follows below mentioned convention
46 <target name>-<sound card name>-<form factor>-snd-card
47 parse target name, sound card name and form factor
48 */
49 char *snd_card_name = strdup(in_snd_card_name);
50 char *tmp = NULL;
51 char *device = NULL;
52 char *snd_card = NULL;
53 char *form_factor = NULL;
54
55 if (in_snd_card_name == NULL) {
56 ALOGE("%s: snd_card_name passed is NULL", __func__);
57 goto on_error;
58 }
59
60 device = strtok_r(snd_card_name, "-", &tmp);
61 if (device == NULL) {
62 ALOGE("%s: called on invalid snd card name", __func__);
63 goto on_error;
64 }
65 strlcpy(cur_snd_card_split.device, device, HW_INFO_ARRAY_MAX_SIZE);
66
67 snd_card = strtok_r(NULL, "-", &tmp);
68 if (snd_card == NULL) {
69 ALOGE("%s: called on invalid snd card name", __func__);
70 goto on_error;
71 }
72 strlcpy(cur_snd_card_split.snd_card, snd_card, HW_INFO_ARRAY_MAX_SIZE);
73
74 form_factor = strtok_r(NULL, "-", &tmp);
75 if (form_factor == NULL) {
76 ALOGE("%s: called on invalid snd card name", __func__);
77 goto on_error;
78 }
79 strlcpy(cur_snd_card_split.form_factor, form_factor, HW_INFO_ARRAY_MAX_SIZE);
80
81 ALOGI("%s: snd_card_name(%s) device(%s) snd_card(%s) form_factor(%s)",
82 __func__, in_snd_card_name, device, snd_card, form_factor);
83
84 on_error:
85 if (snd_card_name)
86 free(snd_card_name);
87 }
88
89 #ifdef KPI_OPTIMIZE_ENABLED
90 typedef int (*perf_lock_acquire_t)(int, int, int*, int);
91 typedef int (*perf_lock_release_t)(int);
92
93 static void *qcopt_handle;
94 static perf_lock_acquire_t perf_lock_acq;
95 static perf_lock_release_t perf_lock_rel;
96
97 static int perf_lock_handle;
98 char opt_lib_path[PROPERTY_VALUE_MAX] = {0};
99
100 int perf_lock_opts[] = {0x101, 0x20E, 0x30E};
101
audio_extn_perf_lock_init(void)102 int audio_extn_perf_lock_init(void)
103 {
104 int ret = 0;
105 if (qcopt_handle == NULL) {
106 if (property_get("ro.vendor.extension_library",
107 opt_lib_path, NULL) <= 0) {
108 ALOGE("%s: Failed getting perf property", __func__);
109 ret = -EINVAL;
110 goto err;
111 }
112 if ((qcopt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
113 ALOGE("%s: Failed to open perf handle", __func__);
114 ret = -EINVAL;
115 goto err;
116 } else {
117 perf_lock_acq = (perf_lock_acquire_t)dlsym(qcopt_handle,
118 "perf_lock_acq");
119 if (perf_lock_acq == NULL) {
120 ALOGE("%s: Perf lock Acquire NULL", __func__);
121 dlclose(qcopt_handle);
122 qcopt_handle = NULL;
123 ret = -EINVAL;
124 goto err;
125 }
126 perf_lock_rel = (perf_lock_release_t)dlsym(qcopt_handle,
127 "perf_lock_rel");
128 if (perf_lock_rel == NULL) {
129 ALOGE("%s: Perf lock Release NULL", __func__);
130 dlclose(qcopt_handle);
131 qcopt_handle = NULL;
132 ret = -EINVAL;
133 goto err;
134 }
135 ALOGD("%s: Perf lock handles Success", __func__);
136 }
137 }
138 err:
139 return ret;
140 }
141
audio_extn_perf_lock_acquire(void)142 void audio_extn_perf_lock_acquire(void)
143 {
144 if (perf_lock_acq) {
145 perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 3);
146 ALOGV("%s: Perf lock acquired", __func__);
147 } else {
148 ALOGE("%s: Perf lock acquire error", __func__);
149 }
150 }
151
audio_extn_perf_lock_release(void)152 void audio_extn_perf_lock_release(void)
153 {
154 if (perf_lock_rel && perf_lock_handle) {
155 perf_lock_rel(perf_lock_handle);
156 perf_lock_handle = 0;
157 ALOGV("%s: Perf lock released", __func__);
158 } else {
159 ALOGE("%s: Perf lock release error", __func__);
160 }
161 }
162 #endif /* KPI_OPTIMIZE_ENABLED */
163