blob: 88de2f279f3a3b40b94e151fc2ca0a5b9ec02622 [file] [log] [blame]
jasmine cha75fa6f02018-03-30 15:41:33 +08001/*
Vatsal Bucha7fe95a82019-05-06 15:25:58 +05302 * Copyright (C) 2018 The Android Open Source Project
jasmine cha75fa6f02018-03-30 15:41:33 +08003 *
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_waves"
18/*#define LOG_NDEBUG 0*/
19
jasmine cha75fa6f02018-03-30 15:41:33 +080020#include <audio_hw.h>
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -080021#include <cutils/str_parms.h>
22#include <dlfcn.h>
23#include <log/log.h>
jasmine cha75fa6f02018-03-30 15:41:33 +080024#include <math.h>
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -080025#include <platform_api.h>
26#include <pthread.h>
27#include <stdlib.h>
28#include <string.h>
29#include <system/audio.h>
30#include <unistd.h>
31
jasmine cha75fa6f02018-03-30 15:41:33 +080032#include "audio_extn.h"
33#include "maxxaudio.h"
34
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -080035#define LIB_MA_PARAM "libmaxxaudioqdsp.so"
jasmine cha75fa6f02018-03-30 15:41:33 +080036#define LIB_MA_PATH "vendor/lib/"
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -080037#define PRESET_PATH "/vendor/etc"
38#define MPS_BASE_STRING "default"
jasmine cha75fa6f02018-03-30 15:41:33 +080039#define USER_PRESET_PATH ""
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -080040#define CONFIG_BASE_STRING "maxx_conf"
jasmine cha75fa6f02018-03-30 15:41:33 +080041#define CAL_PRESIST_STR "cal_persist"
42#define CAL_SAMPLERATE_STR "cal_samplerate"
43
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080044#define MA_QDSP_PARAM_INIT "maxxaudio_qdsp_initialize"
45#define MA_QDSP_PARAM_DEINIT "maxxaudio_qdsp_uninitialize"
justinwengbbffa622019-01-11 14:38:06 +080046#define MA_QDSP_IS_FEATURE_USED "maxxaudio_qdsp_is_feature_supported"
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080047#define MA_QDSP_SET_LR_SWAP "maxxaudio_qdsp_set_lr_swap"
justinwengbbffa622019-01-11 14:38:06 +080048#define MA_QDSP_SET_ORIENTATION "maxxaudio_qdsp_set_orientation"
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080049#define MA_QDSP_SET_MODE "maxxaudio_qdsp_set_sound_mode"
50#define MA_QDSP_SET_VOL "maxxaudio_qdsp_set_volume"
51#define MA_QDSP_SET_VOLT "maxxaudio_qdsp_set_volume_table"
52#define MA_QDSP_SET_PARAM "maxxaudio_qdsp_set_parameter"
jasmine cha75fa6f02018-03-30 15:41:33 +080053
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080054#define SUPPORT_DEV "18d1:5033" // Blackbird usbid
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -080055#define SUPPORTED_USB 0x01
jasmine cha75fa6f02018-03-30 15:41:33 +080056
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080057typedef unsigned int effective_scope_flag_t;
58const effective_scope_flag_t EFFECTIVE_SCOPE_RTC = 1 << 0; /* RTC */
59const effective_scope_flag_t EFFECTIVE_SCOPE_ACDB = 1 << 1; /* ACDB */
60const effective_scope_flag_t EFFECTIVE_SCOPE_ALL = EFFECTIVE_SCOPE_RTC | EFFECTIVE_SCOPE_ACDB;
61const effective_scope_flag_t EFFECTIVE_SCOPE_NONE = 0;
62const effective_scope_flag_t EFFECTIVE_SCOPE_DEFAULT = EFFECTIVE_SCOPE_NONE;
jasmine cha75fa6f02018-03-30 15:41:33 +080063
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080064const unsigned int AUDIO_CAL_SETTINGS_VERSION_MAJOR = 2;
65const unsigned int AUDIO_CAL_SETTINGS_VERSION_MINOR = 0;
66const unsigned int AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT = AUDIO_CAL_SETTINGS_VERSION_MAJOR;
67const unsigned int AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT = AUDIO_CAL_SETTINGS_VERSION_MINOR;
68
69const unsigned int VALUE_AUTO = 0xFFFFFFFF;
70const unsigned int APP_TYPE_AUTO = VALUE_AUTO;
71const unsigned int APP_TYPE_DEFAULT = APP_TYPE_AUTO;
72const unsigned int DEVICE_AUTO = VALUE_AUTO;
73const unsigned int DEVICE_DEFAULT = DEVICE_AUTO;
74
75const unsigned int MAAP_OUTPUT_GAIN = 27;
jasmine cha75fa6f02018-03-30 15:41:33 +080076
77typedef enum MA_STREAM_TYPE {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080078 STREAM_MIN_TYPES = 0,
79 STREAM_VOICE = STREAM_MIN_TYPES,
jasmine cha75fa6f02018-03-30 15:41:33 +080080 STREAM_SYSTEM,
81 STREAM_RING,
82 STREAM_MUSIC,
83 STREAM_ALARM,
84 STREAM_NOTIFICATION ,
85 STREAM_MAX_TYPES,
86} ma_stream_type_t;
87
88typedef enum MA_CMD {
89 MA_CMD_VOL,
90 MA_CMD_SWAP_ENABLE,
91 MA_CMD_SWAP_DISABLE,
justinwengbbffa622019-01-11 14:38:06 +080092 MA_CMD_ROTATE_ENABLE,
93 MA_CMD_ROTATE_DISABLE,
jasmine cha75fa6f02018-03-30 15:41:33 +080094} ma_cmd_t;
95
Arun Mirpurib1bec9c2019-01-29 16:42:45 -080096typedef struct ma_audio_cal_version {
97 unsigned int major;
98 unsigned int minor;
99} ma_audio_cal_version_t;
100
101typedef struct ma_audio_cal_common_settings {
102 unsigned int app_type;
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800103 struct listnode devices;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800104} ma_audio_cal_common_settings_t;
105
106struct ma_audio_cal_settings {
107 ma_audio_cal_version_t version;
108 ma_audio_cal_common_settings_t common;
109 effective_scope_flag_t effect_scope_flag;
110};
111
112struct ma_state {
113 float vol;
114 bool active;
115};
116
jasmine cha75fa6f02018-03-30 15:41:33 +0800117typedef void *ma_audio_cal_handle_t;
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800118typedef int (*set_audio_cal_t)(const char *);
jasmine cha75fa6f02018-03-30 15:41:33 +0800119
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800120typedef bool (*ma_param_init_t)(ma_audio_cal_handle_t *, const char *,
121 const char *, const char *, set_audio_cal_t);
jasmine cha75fa6f02018-03-30 15:41:33 +0800122
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800123typedef bool (*ma_param_deinit_t)(ma_audio_cal_handle_t *);
jasmine cha75fa6f02018-03-30 15:41:33 +0800124
justinwengbbffa622019-01-11 14:38:06 +0800125typedef bool (*ma_is_feature_used_t)(ma_audio_cal_handle_t, const char *);
126
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800127typedef bool (*ma_set_lr_swap_t)(ma_audio_cal_handle_t,
128 const struct ma_audio_cal_settings *, bool);
jasmine cha75fa6f02018-03-30 15:41:33 +0800129
justinwengbbffa622019-01-11 14:38:06 +0800130typedef bool (*ma_set_orientation_t)(ma_audio_cal_handle_t,
131 const struct ma_audio_cal_settings *, int);
132
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800133typedef bool (*ma_set_sound_mode_t)(ma_audio_cal_handle_t,
134 const struct ma_audio_cal_settings *,
135 unsigned int);
jasmine cha75fa6f02018-03-30 15:41:33 +0800136
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800137typedef bool (*ma_set_volume_t)(ma_audio_cal_handle_t,
138 const struct ma_audio_cal_settings *, double);
jasmine cha75fa6f02018-03-30 15:41:33 +0800139
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800140typedef bool (*ma_set_volume_table_t)(ma_audio_cal_handle_t,
141 const struct ma_audio_cal_settings *,
142 size_t, struct ma_state *);
jasmine cha75fa6f02018-03-30 15:41:33 +0800143
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800144typedef bool (*ma_set_param_t)(ma_audio_cal_handle_t,
145 const struct ma_audio_cal_settings *,
146 unsigned int, double);
147
jasmine cha75fa6f02018-03-30 15:41:33 +0800148struct ma_platform_data {
149 void *waves_handle;
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800150 void *platform;
jasmine cha75fa6f02018-03-30 15:41:33 +0800151 pthread_mutex_t lock;
152 ma_param_init_t ma_param_init;
153 ma_param_deinit_t ma_param_deinit;
justinwengbbffa622019-01-11 14:38:06 +0800154 ma_is_feature_used_t ma_is_feature_used;
jasmine cha75fa6f02018-03-30 15:41:33 +0800155 ma_set_lr_swap_t ma_set_lr_swap;
justinwengbbffa622019-01-11 14:38:06 +0800156 ma_set_orientation_t ma_set_orientation;
jasmine cha75fa6f02018-03-30 15:41:33 +0800157 ma_set_sound_mode_t ma_set_sound_mode;
158 ma_set_volume_t ma_set_volume;
159 ma_set_volume_table_t ma_set_volume_table;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800160 ma_set_param_t ma_set_param;
161 bool speaker_lr_swap;
justinwengbbffa622019-01-11 14:38:06 +0800162 bool orientation_used;
163 int dispaly_orientation;
jasmine cha75fa6f02018-03-30 15:41:33 +0800164};
165
166ma_audio_cal_handle_t g_ma_audio_cal_handle = NULL;
167static uint16_t g_supported_dev = 0;
168static struct ma_state ma_cur_state_table[STREAM_MAX_TYPES];
169static struct ma_platform_data *my_data = NULL;
Arun Mirpurid750ac52019-04-12 18:33:55 -0700170// --- external function dependency ---
171fp_platform_set_parameters_t fp_platform_set_parameters;
172fp_audio_extn_get_snd_card_split_t fp_audio_extn_get_snd_card_split;
jasmine cha75fa6f02018-03-30 15:41:33 +0800173
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800174static int set_audio_cal(const char *audio_cal)
jasmine cha75fa6f02018-03-30 15:41:33 +0800175{
176 ALOGV("set_audio_cal: %s", audio_cal);
177
Arun Mirpurid750ac52019-04-12 18:33:55 -0700178 return fp_platform_set_parameters(my_data->platform,
jasmine cha75fa6f02018-03-30 15:41:33 +0800179 str_parms_create_str(audio_cal));
180}
181
182static bool ma_set_lr_swap_l(
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800183 const struct ma_audio_cal_settings *audio_cal_settings, bool swap)
jasmine cha75fa6f02018-03-30 15:41:33 +0800184{
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800185 return my_data->ma_set_lr_swap(g_ma_audio_cal_handle,
186 audio_cal_settings, swap);
jasmine cha75fa6f02018-03-30 15:41:33 +0800187}
188
justinwengbbffa622019-01-11 14:38:06 +0800189static bool ma_set_orientation_l(
190 const struct ma_audio_cal_settings *audio_cal_settings, int orientation)
191{
192 return my_data->ma_set_orientation(g_ma_audio_cal_handle,
193 audio_cal_settings, orientation);
194}
195
jasmine cha75fa6f02018-03-30 15:41:33 +0800196static bool ma_set_volume_table_l(
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800197 const struct ma_audio_cal_settings *audio_cal_settings,
198 size_t num_streams, struct ma_state *volume_table)
jasmine cha75fa6f02018-03-30 15:41:33 +0800199{
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800200 return my_data->ma_set_volume_table(g_ma_audio_cal_handle,
201 audio_cal_settings, num_streams,
202 volume_table);
jasmine cha75fa6f02018-03-30 15:41:33 +0800203}
204
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800205static bool ma_set_param_l(
206 const struct ma_audio_cal_settings *audio_cal_settings,
207 unsigned int index, double value)
208{
209 return my_data->ma_set_param(g_ma_audio_cal_handle,
210 audio_cal_settings, index, value);
211}
212
Jasmine Cha0ad09772019-02-25 20:09:34 +0800213static void print_state_log()
214{
215 ALOGD("%s: send volume table -(%i,%f,%s),(%i,%f,%s),(%i,%f,%s),(%i,%f,%s),"
216 "(%i,%f,%s),(%i,%f,%s)", __func__,
217 STREAM_VOICE, ma_cur_state_table[STREAM_VOICE].vol,
218 ma_cur_state_table[STREAM_VOICE].active ? "T" : "F",
219 STREAM_SYSTEM, ma_cur_state_table[STREAM_SYSTEM].vol,
220 ma_cur_state_table[STREAM_SYSTEM].active ? "T" : "F",
221 STREAM_RING, ma_cur_state_table[STREAM_RING].vol,
222 ma_cur_state_table[STREAM_RING].active ? "T" : "F",
223 STREAM_MUSIC, ma_cur_state_table[STREAM_MUSIC].vol,
224 ma_cur_state_table[STREAM_MUSIC].active ? "T" : "F",
225 STREAM_ALARM, ma_cur_state_table[STREAM_ALARM].vol,
226 ma_cur_state_table[STREAM_ALARM].active ? "T" : "F",
227 STREAM_NOTIFICATION, ma_cur_state_table[STREAM_NOTIFICATION].vol,
228 ma_cur_state_table[STREAM_NOTIFICATION].active ? "T" : "F");
229
230}
231
jasmine cha75fa6f02018-03-30 15:41:33 +0800232static inline bool valid_usecase(struct audio_usecase *usecase)
233{
234 if ((usecase->type == PCM_PLAYBACK) &&
235 /* supported usecases */
236 ((usecase->id == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER) ||
237 (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) ||
238 (usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
239 /* support devices */
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800240 (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_SPEAKER) ||
241 compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
242 (is_usb_out_device_type(&usecase->device_list) &&
Arun Mirpurid750ac52019-04-12 18:33:55 -0700243 ma_supported_usb())))
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800244 /* TODO: enable A2DP when it is ready */
jasmine cha75fa6f02018-03-30 15:41:33 +0800245
246 return true;
247
248 ALOGV("%s: not support type %d usecase %d device %d",
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800249 __func__, usecase->type, usecase->id, get_device_types(&usecase->device_list));
jasmine cha75fa6f02018-03-30 15:41:33 +0800250
251 return false;
252}
253
254// already hold lock
255static inline bool is_active()
256{
257 ma_stream_type_t i = 0;
258
259 for (i = 0; i < STREAM_MAX_TYPES; i++)
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800260 if (ma_cur_state_table[i].active)
jasmine cha75fa6f02018-03-30 15:41:33 +0800261 return true;
262
263 return false;
264}
265
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800266static void ma_cal_init(struct ma_audio_cal_settings *ma_cal)
267{
268 ma_cal->version.major = AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT;
269 ma_cal->version.minor = AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT;
270 ma_cal->common.app_type = APP_TYPE_DEFAULT;
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800271 list_init(&ma_cal->common.devices);
272 update_device_list(&ma_cal->common.devices, DEVICE_DEFAULT,
273 "", true);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800274 ma_cal->effect_scope_flag = EFFECTIVE_SCOPE_ALL;
275}
276
jasmine cha75fa6f02018-03-30 15:41:33 +0800277static bool check_and_send_all_audio_cal(struct audio_device *adev, ma_cmd_t cmd)
278{
279 int i = 0;
280 bool ret = false;
jasmine cha75fa6f02018-03-30 15:41:33 +0800281 struct listnode *node;
282 struct audio_usecase *usecase;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800283 struct ma_audio_cal_settings ma_cal;
jasmine cha75fa6f02018-03-30 15:41:33 +0800284
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800285 ma_cal_init(&ma_cal);
jasmine cha75fa6f02018-03-30 15:41:33 +0800286
287 list_for_each(node, &adev->usecase_list) {
288 usecase = node_to_item(node, struct audio_usecase, list);
Sujin Panicker390724d2019-04-26 10:43:36 +0530289 if (usecase->stream.out && valid_usecase(usecase)) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800290 ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800291 assign_devices(&ma_cal.common.devices, &usecase->stream.out->device_list);
jasmine cha75fa6f02018-03-30 15:41:33 +0800292 ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800293 __func__, usecase->id, ma_cal.common.app_type,
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800294 get_device_types(&ma_cal.common.devices));
jasmine cha75fa6f02018-03-30 15:41:33 +0800295
296 switch (cmd) {
297 case MA_CMD_VOL:
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800298 ret = ma_set_volume_table_l(&ma_cal, STREAM_MAX_TYPES,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800299 ma_cur_state_table);
jasmine cha75fa6f02018-03-30 15:41:33 +0800300 if (ret)
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800301 ALOGV("ma_set_volume_table_l success");
jasmine cha75fa6f02018-03-30 15:41:33 +0800302 else
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800303 ALOGE("ma_set_volume_table_l returned with error.");
Jasmine Cha0ad09772019-02-25 20:09:34 +0800304 print_state_log();
jasmine cha75fa6f02018-03-30 15:41:33 +0800305 break;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800306
jasmine cha75fa6f02018-03-30 15:41:33 +0800307 case MA_CMD_SWAP_ENABLE:
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800308 /* lr swap only enable for speaker path */
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800309 if (compare_device_type(&ma_cal.common.devices,
310 AUDIO_DEVICE_OUT_SPEAKER)) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800311 ret = ma_set_lr_swap_l(&ma_cal, true);
312 if (ret)
313 ALOGV("ma_set_lr_swap_l enable returned with success.");
314 else
315 ALOGE("ma_set_lr_swap_l enable returned with error.");
316 }
jasmine cha75fa6f02018-03-30 15:41:33 +0800317 break;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800318
jasmine cha75fa6f02018-03-30 15:41:33 +0800319 case MA_CMD_SWAP_DISABLE:
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800320 ret = ma_set_lr_swap_l(&ma_cal, false);
jasmine cha75fa6f02018-03-30 15:41:33 +0800321 if (ret)
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800322 ALOGV("ma_set_lr_swap_l disable returned with success.");
jasmine cha75fa6f02018-03-30 15:41:33 +0800323 else
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800324 ALOGE("ma_set_lr_swap_l disable returned with error.");
jasmine cha75fa6f02018-03-30 15:41:33 +0800325 break;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800326
justinwengbbffa622019-01-11 14:38:06 +0800327 case MA_CMD_ROTATE_ENABLE:
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800328 if (compare_device_type(&ma_cal.common.devices,
329 AUDIO_DEVICE_OUT_SPEAKER)) {
justinwengbbffa622019-01-11 14:38:06 +0800330 ret = ma_set_orientation_l(&ma_cal, my_data->dispaly_orientation);
331 if (ret)
Jasmine Cha0ad09772019-02-25 20:09:34 +0800332 ALOGV("ma_set_orientation_l %d returned with success.",
333 my_data->dispaly_orientation);
justinwengbbffa622019-01-11 14:38:06 +0800334 else
Jasmine Cha0ad09772019-02-25 20:09:34 +0800335 ALOGE("ma_set_orientation_l %d returned with error.",
336 my_data->dispaly_orientation);
justinwengbbffa622019-01-11 14:38:06 +0800337 }
338 break;
339
340 case MA_CMD_ROTATE_DISABLE:
341 ret = ma_set_orientation_l(&ma_cal, 0);
342 if (ret)
343 ALOGV("ma_set_orientation_l 0 returned with success.");
344 else
345 ALOGE("ma_set_orientation_l 0 returned with error.");
346 break;
347
jasmine cha75fa6f02018-03-30 15:41:33 +0800348 default:
349 ALOGE("%s: unsupported cmd %d", __func__, cmd);
350 }
jasmine cha75fa6f02018-03-30 15:41:33 +0800351 }
352 }
jasmine cha75fa6f02018-03-30 15:41:33 +0800353
354 return ret;
355}
356
357static bool find_sup_dev(char *name)
358{
Weiyin Jiang0d985872019-06-13 15:47:21 +0800359 char *token, *saveptr = NULL;
jasmine cha75fa6f02018-03-30 15:41:33 +0800360 const char s[2] = ",";
361 bool ret = false;
362 char sup_devs[128];
363
364 // the rule of comforming suppored dev's name
365 // 1. Both string len are equal
366 // 2. Both string content are equal
367
368 strncpy(sup_devs, SUPPORT_DEV, sizeof(sup_devs));
Weiyin Jiang0d985872019-06-13 15:47:21 +0800369 token = strtok_r(sup_devs, s, &saveptr);
jasmine cha75fa6f02018-03-30 15:41:33 +0800370 while (token != NULL) {
371 if (strncmp(token, name, strlen(token)) == 0 &&
372 strlen(token) == strlen(name)) {
373 ALOGD("%s: support dev %s", __func__, token);
374 ret = true;
375 break;
376 }
Weiyin Jiang0d985872019-06-13 15:47:21 +0800377 token = strtok_r(NULL, s, &saveptr);
jasmine cha75fa6f02018-03-30 15:41:33 +0800378 }
379
380 return ret;
381}
382
383static void ma_set_swap_l(struct audio_device *adev, bool enable)
384{
jasmine cha75fa6f02018-03-30 15:41:33 +0800385 if (enable)
386 check_and_send_all_audio_cal(adev, MA_CMD_SWAP_ENABLE);
387 else
388 check_and_send_all_audio_cal(adev, MA_CMD_SWAP_DISABLE);
389}
390
justinwengbbffa622019-01-11 14:38:06 +0800391static void ma_set_rotation_l(struct audio_device *adev, int orientation)
392{
393 if (orientation != 0)
394 check_and_send_all_audio_cal(adev, MA_CMD_ROTATE_ENABLE);
395 else
396 check_and_send_all_audio_cal(adev, MA_CMD_ROTATE_DISABLE);
397}
398
jasmine cha75fa6f02018-03-30 15:41:33 +0800399static void ma_support_usb(bool enable, int card)
400{
401 char path[128];
402 char id[32];
403 int ret = 0;
404 int32_t fd = -1;
405 char *idd;
Weiyin Jiang0d985872019-06-13 15:47:21 +0800406 char *saveptr = NULL;
jasmine cha75fa6f02018-03-30 15:41:33 +0800407
408 if (enable) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800409 ret = snprintf(path, sizeof(path), "/proc/asound/card%u/usbid", card);
jasmine cha75fa6f02018-03-30 15:41:33 +0800410 if (ret < 0) {
411 ALOGE("%s: failed on snprintf (%d) to path %s\n",
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800412 __func__, ret, path);
jasmine cha75fa6f02018-03-30 15:41:33 +0800413 goto done;
414 }
415 fd = open(path, O_RDONLY);
416 if (fd < 0) {
417 ALOGE("%s: error failed to open id file %s error: %d\n",
418 __func__, path, errno);
419 goto done;
420 }
421 if (read(fd, id, sizeof(id)) < 0) {
422 ALOGE("%s: file read error", __func__);
423 goto done;
424 }
425 //replace '\n' to '\0'
Weiyin Jiang0d985872019-06-13 15:47:21 +0800426 idd = strtok_r(id, "\n", &saveptr);
jasmine cha75fa6f02018-03-30 15:41:33 +0800427
428 if (find_sup_dev(idd)) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800429 ALOGV("%s: support usbid is %s", __func__, id);
jasmine cha75fa6f02018-03-30 15:41:33 +0800430 g_supported_dev |= SUPPORTED_USB;
431 } else
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800432 ALOGV("%s: usbid %s isn't found from %s", __func__, id, SUPPORT_DEV);
jasmine cha75fa6f02018-03-30 15:41:33 +0800433 } else {
434 g_supported_dev &= ~SUPPORTED_USB;
435 }
436
437done:
438 if (fd >= 0) close(fd);
439}
440
441// adev_init lock held
Arun Mirpurid750ac52019-04-12 18:33:55 -0700442void ma_init(void *platform, maxx_audio_init_config_t init_config)
jasmine cha75fa6f02018-03-30 15:41:33 +0800443{
444 ma_stream_type_t i = 0;
445 int ret = 0;
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800446 char lib_path[128] = {0};
447 char mps_path[128] = {0};
448 char cnf_path[128] = {0};
449 struct snd_card_split *snd_split_handle = NULL;
Arun Mirpurid750ac52019-04-12 18:33:55 -0700450
451 fp_platform_set_parameters = init_config.fp_platform_set_parameters;
452 fp_audio_extn_get_snd_card_split = init_config.fp_audio_extn_get_snd_card_split;
453
454 snd_split_handle = fp_audio_extn_get_snd_card_split();
jasmine cha75fa6f02018-03-30 15:41:33 +0800455
456 if (platform == NULL) {
457 ALOGE("%s: platform is NULL", __func__);
458 goto error;
459 }
460
461 if (my_data) { free(my_data); }
462 my_data = calloc(1, sizeof(struct ma_platform_data));
463 if (my_data == NULL) {
464 ALOGE("%s: ma_cal alloct fail", __func__);
465 goto error;
466 }
467
468 pthread_mutex_init(&my_data->lock, NULL);
469
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800470 my_data->platform = platform;
jasmine cha75fa6f02018-03-30 15:41:33 +0800471 ret = snprintf(lib_path, sizeof(lib_path), "%s/%s", LIB_MA_PATH, LIB_MA_PARAM);
472 if (ret < 0) {
473 ALOGE("%s: snprintf failed for lib %s, ret %d", __func__, LIB_MA_PARAM, ret);
474 goto error;
475 }
476
477 my_data->waves_handle = dlopen(lib_path, RTLD_NOW);
478 if (my_data->waves_handle == NULL) {
Jasmine Cha0ad09772019-02-25 20:09:34 +0800479 ALOGE("%s: DLOPEN failed for %s, %s", __func__, LIB_MA_PARAM, dlerror());
jasmine cha75fa6f02018-03-30 15:41:33 +0800480 goto error;
481 } else {
482 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
483
484 my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800485 MA_QDSP_PARAM_INIT);
jasmine cha75fa6f02018-03-30 15:41:33 +0800486 if (!my_data->ma_param_init) {
487 ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
488 goto error;
489 }
490
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800491 my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(
492 my_data->waves_handle, MA_QDSP_PARAM_DEINIT);
jasmine cha75fa6f02018-03-30 15:41:33 +0800493 if (!my_data->ma_param_deinit) {
494 ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
495 goto error;
496 }
497
justinwengbbffa622019-01-11 14:38:06 +0800498 my_data->ma_is_feature_used = (ma_is_feature_used_t)dlsym(my_data->waves_handle,
499 MA_QDSP_IS_FEATURE_USED);
500 if (!my_data->ma_is_feature_used) {
501 ALOGV("%s: dlsym error %s for ma_is_feature_used", __func__, dlerror());
502 }
503
504 my_data->ma_set_orientation = (ma_set_orientation_t)dlsym(my_data->waves_handle,
505 MA_QDSP_SET_ORIENTATION);
506 if (!my_data->ma_set_orientation) {
507 ALOGV("%s: dlsym error %s for ma_set_orientation", __func__, dlerror());
508 }
509
jasmine cha75fa6f02018-03-30 15:41:33 +0800510 my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800511 MA_QDSP_SET_LR_SWAP);
jasmine cha75fa6f02018-03-30 15:41:33 +0800512 if (!my_data->ma_set_lr_swap) {
513 ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
514 goto error;
515 }
516
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800517 my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(
518 my_data->waves_handle, MA_QDSP_SET_MODE);
jasmine cha75fa6f02018-03-30 15:41:33 +0800519 if (!my_data->ma_set_sound_mode) {
520 ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
521 goto error;
522 }
523
524 my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800525 MA_QDSP_SET_VOL);
jasmine cha75fa6f02018-03-30 15:41:33 +0800526 if (!my_data->ma_set_volume) {
527 ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
528 goto error;
529 }
530
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800531 my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(
532 my_data->waves_handle, MA_QDSP_SET_VOLT);
jasmine cha75fa6f02018-03-30 15:41:33 +0800533 if (!my_data->ma_set_volume_table) {
534 ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
535 goto error;
536 }
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800537
538 my_data->ma_set_param = (ma_set_param_t)dlsym(
539 my_data->waves_handle, MA_QDSP_SET_PARAM);
540 if (!my_data->ma_set_param) {
541 ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
542 goto error;
543 }
jasmine cha75fa6f02018-03-30 15:41:33 +0800544 }
545
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800546 /* get preset table */
547 if (snd_split_handle == NULL) {
548 snprintf(mps_path, sizeof(mps_path), "%s/%s.mps",
549 PRESET_PATH, MPS_BASE_STRING);
550 } else {
551 snprintf(mps_path, sizeof(mps_path), "%s/%s_%s.mps",
552 PRESET_PATH, MPS_BASE_STRING, snd_split_handle->form_factor);
jasmine cha75fa6f02018-03-30 15:41:33 +0800553 }
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800554
555 /* get config files */
556 if (snd_split_handle == NULL) {
557 snprintf(cnf_path, sizeof(cnf_path), "%s/%s.ini",
558 PRESET_PATH, CONFIG_BASE_STRING);
559 } else {
560 snprintf(cnf_path, sizeof(cnf_path), "%s/%s_%s.ini",
561 PRESET_PATH, CONFIG_BASE_STRING, snd_split_handle->form_factor);
562 }
563
564 /* check file */
565 if (access(mps_path, R_OK) < 0) {
566 ALOGW("%s: file %s isn't existed.", __func__, mps_path);
567 goto error;
568 } else
569 ALOGD("%s: Loading mps file: %s", __func__, mps_path);
570
jasmine cha75fa6f02018-03-30 15:41:33 +0800571 /* TODO: check user preset table once the feature is enabled
572 if (access(USER_PRESET_PATH, F_OK) < 0 ){
573 ALOGW("%s: file %s isn't existed.", __func__, USER_PRESET_PATH);
574 goto error;
575 }
576 */
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800577
578 if (access(cnf_path, R_OK) < 0) {
579 ALOGW("%s: file %s isn't existed.", __func__, cnf_path);
jasmine cha75fa6f02018-03-30 15:41:33 +0800580 goto error;
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800581 } else
582 ALOGD("%s: Loading ini file: %s", __func__, cnf_path);
jasmine cha75fa6f02018-03-30 15:41:33 +0800583
584 /* init ma parameter */
585 if (my_data->ma_param_init(&g_ma_audio_cal_handle,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800586 mps_path,
587 USER_PRESET_PATH, /* unused */
588 cnf_path,
589 &set_audio_cal)) {
jasmine cha75fa6f02018-03-30 15:41:33 +0800590 if (!g_ma_audio_cal_handle) {
591 ALOGE("%s: ma parameters initialize failed", __func__);
592 my_data->ma_param_deinit(&g_ma_audio_cal_handle);
593 goto error;
594 }
595 ALOGD("%s: ma parameters initialize successful", __func__);
596 } else {
597 ALOGE("%s: ma parameters initialize failed", __func__);
598 goto error;
599 }
600
601 /* init volume table */
602 for (i = 0; i < STREAM_MAX_TYPES; i++) {
603 ma_cur_state_table[i].vol = 0.0;
604 ma_cur_state_table[i].active = false;
605 }
606
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800607 my_data->speaker_lr_swap = false;
justinwengbbffa622019-01-11 14:38:06 +0800608 my_data->orientation_used = false;
609 my_data->dispaly_orientation = 0;
610
611 if (g_ma_audio_cal_handle && my_data->ma_is_feature_used) {
Jasmine Cha0ad09772019-02-25 20:09:34 +0800612 my_data->orientation_used = my_data->ma_is_feature_used(
613 g_ma_audio_cal_handle, "SET_ORIENTATION");
justinwengbbffa622019-01-11 14:38:06 +0800614 }
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800615
jasmine cha75fa6f02018-03-30 15:41:33 +0800616 return;
617
618error:
619 if (my_data) { free(my_data); }
620 my_data = NULL;
621}
622
623//adev_init lock held
Arun Mirpurid750ac52019-04-12 18:33:55 -0700624void ma_deinit()
jasmine cha75fa6f02018-03-30 15:41:33 +0800625{
626 if (my_data) {
627 /* deinit ma parameter */
628 if (my_data->ma_param_deinit &&
629 my_data->ma_param_deinit(&g_ma_audio_cal_handle))
630 ALOGD("%s: ma parameters uninitialize successful", __func__);
631 else
632 ALOGD("%s: ma parameters uninitialize failed", __func__);
633
634 pthread_mutex_destroy(&my_data->lock);
635 free(my_data);
636 my_data = NULL;
637 }
638}
639
640// adev_init and adev lock held
Arun Mirpurid750ac52019-04-12 18:33:55 -0700641bool ma_set_state(struct audio_device *adev, int stream_type,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800642 float vol, bool active)
jasmine cha75fa6f02018-03-30 15:41:33 +0800643{
644 bool ret = false;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800645 struct ma_state pr_mstate;
jasmine cha75fa6f02018-03-30 15:41:33 +0800646
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800647 if (stream_type >= STREAM_MAX_TYPES ||
648 stream_type < STREAM_MIN_TYPES) {
649 ALOGE("%s: stream_type %d out of range.", __func__, stream_type);
650 return ret;
651 }
jasmine cha75fa6f02018-03-30 15:41:33 +0800652
653 if (!my_data) {
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800654 ALOGV("%s: maxxaudio isn't initialized.", __func__);
jasmine cha75fa6f02018-03-30 15:41:33 +0800655 return ret;
656 }
657
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800658 ALOGV("%s: stream[%d] vol[%f] active[%s]",
659 __func__, stream_type, vol, active ? "true" : "false");
jasmine cha75fa6f02018-03-30 15:41:33 +0800660
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800661 pr_mstate.vol = ma_cur_state_table[(ma_stream_type_t)stream_type].vol;
662 pr_mstate.active = ma_cur_state_table[(ma_stream_type_t)stream_type].active;
663
664 // update condition: vol or active state changes
665 if (pr_mstate.vol != vol || pr_mstate.active != active) {
666
667 pthread_mutex_lock(&my_data->lock);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800668
669 ma_cur_state_table[(ma_stream_type_t)stream_type].vol = vol;
670 ma_cur_state_table[(ma_stream_type_t)stream_type].active = active;
671
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800672 ret = check_and_send_all_audio_cal(adev, MA_CMD_VOL);
jasmine cha75fa6f02018-03-30 15:41:33 +0800673
674 pthread_mutex_unlock(&my_data->lock);
675 }
676
677 return ret;
678}
679
Arun Mirpurid750ac52019-04-12 18:33:55 -0700680void ma_set_device(struct audio_usecase *usecase)
jasmine cha75fa6f02018-03-30 15:41:33 +0800681{
682 int i = 0;
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800683 struct ma_audio_cal_settings ma_cal;
jasmine cha75fa6f02018-03-30 15:41:33 +0800684
685 if (!my_data) {
686 ALOGV("%s: maxxaudio isn't initialized.", __func__);
687 return;
688 }
689
690 if (!valid_usecase(usecase)) {
691 ALOGV("%s: %d is not supported usecase", __func__, usecase->id);
692 return;
693 }
694
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800695 ma_cal_init(&ma_cal);
jasmine cha75fa6f02018-03-30 15:41:33 +0800696
697 /* update audio_cal and send it */
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800698 ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800699 assign_devices(&ma_cal.common.devices, &usecase->stream.out->device_list);
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800700 ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
701 __func__, usecase->id, ma_cal.common.app_type,
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800702 get_device_types(&ma_cal.common.devices));
jasmine cha75fa6f02018-03-30 15:41:33 +0800703
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800704 pthread_mutex_lock(&my_data->lock);
jasmine cha75fa6f02018-03-30 15:41:33 +0800705
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800706 if (is_active()) {
justinwengbbffa622019-01-11 14:38:06 +0800707
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800708 if (compare_device_type(&ma_cal.common.devices,
709 AUDIO_DEVICE_OUT_SPEAKER)) {
justinwengbbffa622019-01-11 14:38:06 +0800710 if (my_data->orientation_used)
Jasmine Cha0ad09772019-02-25 20:09:34 +0800711 ma_set_rotation_l(usecase->stream.out->dev,
712 my_data->dispaly_orientation);
justinwengbbffa622019-01-11 14:38:06 +0800713 else
714 ma_set_swap_l(usecase->stream.out->dev, my_data->speaker_lr_swap);
715 } else {
716 if (my_data->orientation_used)
717 ma_set_rotation_l(usecase->stream.out->dev, 0);
718 else
719 ma_set_swap_l(usecase->stream.out->dev, false);
720 }
jasmine cha75fa6f02018-03-30 15:41:33 +0800721
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800722 if (!ma_set_volume_table_l(&ma_cal,
723 STREAM_MAX_TYPES,
724 ma_cur_state_table))
725 ALOGE("ma_set_volume_table_l returned with error.");
726 else
727 ALOGV("ma_set_volume_table_l success");
Jasmine Cha0ad09772019-02-25 20:09:34 +0800728 print_state_log();
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800729
jasmine cha75fa6f02018-03-30 15:41:33 +0800730 }
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800731 pthread_mutex_unlock(&my_data->lock);
jasmine cha75fa6f02018-03-30 15:41:33 +0800732}
733
Arun Mirpurid750ac52019-04-12 18:33:55 -0700734void ma_set_parameters(struct audio_device *adev,
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800735 struct str_parms *parms)
jasmine cha75fa6f02018-03-30 15:41:33 +0800736{
737 int ret;
jasmine cha75fa6f02018-03-30 15:41:33 +0800738 int val;
739 char value[128];
740
741 // do LR swap and usb recognition
742 ret = str_parms_get_int(parms, "rotation", &val);
743 if (ret >= 0) {
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800744 if (!my_data) {
745 ALOGV("%s: maxxaudio isn't initialized.", __func__);
746 return;
747 }
748
jasmine cha75fa6f02018-03-30 15:41:33 +0800749 switch (val) {
750 case 270:
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800751 my_data->speaker_lr_swap = true;
jasmine cha75fa6f02018-03-30 15:41:33 +0800752 break;
753 case 0:
754 case 90:
755 case 180:
Arun Mirpurib1bec9c2019-01-29 16:42:45 -0800756 my_data->speaker_lr_swap = false;
jasmine cha75fa6f02018-03-30 15:41:33 +0800757 break;
758 }
justinwengbbffa622019-01-11 14:38:06 +0800759 my_data->dispaly_orientation = val;
760
761 if (my_data->orientation_used)
762 ma_set_rotation_l(adev, my_data->dispaly_orientation);
763 else
764 ma_set_swap_l(adev, my_data->speaker_lr_swap);
jasmine cha75fa6f02018-03-30 15:41:33 +0800765 }
766
767 // check connect status
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800768 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
769 sizeof(value));
jasmine cha75fa6f02018-03-30 15:41:33 +0800770 if (ret >= 0) {
771 audio_devices_t device = (audio_devices_t)strtoul(value, NULL, 10);
772 if (audio_is_usb_out_device(device)) {
773 ret = str_parms_get_str(parms, "card", value, sizeof(value));
774 if (ret >= 0) {
775 const int card = atoi(value);
776 ma_support_usb(true, card);
777 }
778 }
779 }
780
781 // check disconnect status
Aalique Grahame5ce7fbe2019-01-28 12:08:13 -0800782 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
783 sizeof(value));
jasmine cha75fa6f02018-03-30 15:41:33 +0800784 if (ret >= 0) {
785 audio_devices_t device = (audio_devices_t)strtoul(value, NULL, 10);
786 if (audio_is_usb_out_device(device)) {
787 ret = str_parms_get_str(parms, "card", value, sizeof(value));
788 if (ret >= 0) {
789 const int card = atoi(value);
790 ma_support_usb(false, card /*useless*/);
791 }
792 }
793 }
794}
795
Arun Mirpurid750ac52019-04-12 18:33:55 -0700796bool ma_supported_usb()
jasmine cha75fa6f02018-03-30 15:41:33 +0800797{
798 ALOGV("%s: current support 0x%x", __func__, g_supported_dev);
799 return (g_supported_dev & SUPPORTED_USB) ? true : false;
800}