blob: 9007da7c79a1ccff4a1b3333a9f4081da1e14797 [file] [log] [blame]
jasmine cha270b7762018-03-30 15:41:33 +08001/*
2 * Copyright (C) 2018 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_waves"
18/*#define LOG_NDEBUG 0*/
19
jasmine cha270b7762018-03-30 15:41:33 +080020#include <audio_hw.h>
Jasmine Cha70771b62018-05-15 15:02:43 +080021#include <cutils/str_parms.h>
22#include <dlfcn.h>
23#include <log/log.h>
jasmine cha270b7762018-03-30 15:41:33 +080024#include <math.h>
Jasmine Cha70771b62018-05-15 15:02:43 +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 cha270b7762018-03-30 15:41:33 +080032#include "audio_extn.h"
33#include "maxxaudio.h"
34
Jasmine Cha70771b62018-05-15 15:02:43 +080035#define LIB_MA_PARAM "libmaxxaudioqdsp.so"
jasmine cha270b7762018-03-30 15:41:33 +080036#define LIB_MA_PATH "vendor/lib/"
Jasmine Cha70771b62018-05-15 15:02:43 +080037#define PRESET_PATH "/vendor/etc"
38#define MPS_BASE_STRING "default"
jasmine cha270b7762018-03-30 15:41:33 +080039#define USER_PRESET_PATH ""
40#define CONFIG_PATH "/vendor/etc/maxx_conf.ini"
41#define CAL_PRESIST_STR "cal_persist"
42#define CAL_SAMPLERATE_STR "cal_samplerate"
43
Jasmine Cha70771b62018-05-15 15:02:43 +080044#define MA_QDSP_PARAM_INIT "maxxaudio_qdsp_initialize"
45#define MA_QDSP_PARAM_DEINIT "maxxaudio_qdsp_uninitialize"
jasmine cha270b7762018-03-30 15:41:33 +080046#define MA_QDSP_SET_LR_SWAP "maxxaudio_qdsp_set_lr_swap"
47#define MA_QDSP_SET_MODE "maxxaudio_qdsp_set_sound_mode"
48#define MA_QDSP_SET_VOL "maxxaudio_qdsp_set_volume"
49#define MA_QDSP_SET_VOLT "maxxaudio_qdsp_set_volume_table"
50
51#define SUPPORT_DEV "Blackbird"
Jasmine Cha70771b62018-05-15 15:02:43 +080052#define SUPPORTED_USB 0x01
jasmine cha270b7762018-03-30 15:41:33 +080053
54struct ma_audio_cal_settings {
jasmine cha270b7762018-03-30 15:41:33 +080055 int app_type;
56 audio_devices_t device;
57};
58
59struct ma_state {
60 float vol;
61 bool active;
62};
63
64typedef enum MA_STREAM_TYPE {
65 STREAM_MIN_STREAM_TYPES,
66 STREAM_VOICE = STREAM_MIN_STREAM_TYPES,
67 STREAM_SYSTEM,
68 STREAM_RING,
69 STREAM_MUSIC,
70 STREAM_ALARM,
71 STREAM_NOTIFICATION ,
72 STREAM_MAX_TYPES,
73} ma_stream_type_t;
74
75typedef enum MA_CMD {
76 MA_CMD_VOL,
77 MA_CMD_SWAP_ENABLE,
78 MA_CMD_SWAP_DISABLE,
79} ma_cmd_t;
80
81typedef void *ma_audio_cal_handle_t;
Jasmine Cha70771b62018-05-15 15:02:43 +080082typedef int (*set_audio_cal_t)(const char *);
jasmine cha270b7762018-03-30 15:41:33 +080083
Jasmine Cha70771b62018-05-15 15:02:43 +080084typedef bool (*ma_param_init_t)(ma_audio_cal_handle_t *, const char *,
85 const char *, const char *, set_audio_cal_t);
jasmine cha270b7762018-03-30 15:41:33 +080086
Jasmine Cha70771b62018-05-15 15:02:43 +080087typedef bool (*ma_param_deinit_t)(ma_audio_cal_handle_t *);
jasmine cha270b7762018-03-30 15:41:33 +080088
Jasmine Cha70771b62018-05-15 15:02:43 +080089typedef bool (*ma_set_lr_swap_t)(ma_audio_cal_handle_t,
90 const struct ma_audio_cal_settings *, bool);
jasmine cha270b7762018-03-30 15:41:33 +080091
Jasmine Cha70771b62018-05-15 15:02:43 +080092typedef bool (*ma_set_sound_mode_t)(ma_audio_cal_handle_t,
93 const struct ma_audio_cal_settings *,
94 unsigned int);
jasmine cha270b7762018-03-30 15:41:33 +080095
Jasmine Cha70771b62018-05-15 15:02:43 +080096typedef bool (*ma_set_volume_t)(ma_audio_cal_handle_t,
97 const struct ma_audio_cal_settings *, double);
jasmine cha270b7762018-03-30 15:41:33 +080098
Jasmine Cha70771b62018-05-15 15:02:43 +080099typedef bool (*ma_set_volume_table_t)(ma_audio_cal_handle_t,
100 const struct ma_audio_cal_settings *,
101 size_t, struct ma_state *);
jasmine cha270b7762018-03-30 15:41:33 +0800102
103struct ma_platform_data {
104 void *waves_handle;
Jasmine Cha70771b62018-05-15 15:02:43 +0800105 void *platform;
jasmine cha270b7762018-03-30 15:41:33 +0800106 pthread_mutex_t lock;
107 ma_param_init_t ma_param_init;
108 ma_param_deinit_t ma_param_deinit;
109 ma_set_lr_swap_t ma_set_lr_swap;
110 ma_set_sound_mode_t ma_set_sound_mode;
111 ma_set_volume_t ma_set_volume;
112 ma_set_volume_table_t ma_set_volume_table;
113};
114
115ma_audio_cal_handle_t g_ma_audio_cal_handle = NULL;
116static uint16_t g_supported_dev = 0;
117static struct ma_state ma_cur_state_table[STREAM_MAX_TYPES];
118static struct ma_platform_data *my_data = NULL;
119
Jasmine Cha70771b62018-05-15 15:02:43 +0800120static int set_audio_cal(const char *audio_cal)
jasmine cha270b7762018-03-30 15:41:33 +0800121{
122 ALOGV("set_audio_cal: %s", audio_cal);
123
Jasmine Cha70771b62018-05-15 15:02:43 +0800124 return platform_set_parameters(my_data->platform,
jasmine cha270b7762018-03-30 15:41:33 +0800125 str_parms_create_str(audio_cal));
126}
127
128static bool ma_set_lr_swap_l(
Jasmine Cha70771b62018-05-15 15:02:43 +0800129 const struct ma_audio_cal_settings *audio_cal_settings, bool swap)
jasmine cha270b7762018-03-30 15:41:33 +0800130{
Jasmine Cha70771b62018-05-15 15:02:43 +0800131 return my_data->ma_set_lr_swap(g_ma_audio_cal_handle,
132 audio_cal_settings, swap);
jasmine cha270b7762018-03-30 15:41:33 +0800133}
134
135static bool ma_set_sound_mode_l(
Jasmine Cha70771b62018-05-15 15:02:43 +0800136 const struct ma_audio_cal_settings *audio_cal_settings, int sound_mode)
jasmine cha270b7762018-03-30 15:41:33 +0800137{
138 return my_data->ma_set_sound_mode(g_ma_audio_cal_handle,
Jasmine Cha70771b62018-05-15 15:02:43 +0800139 audio_cal_settings, sound_mode);
jasmine cha270b7762018-03-30 15:41:33 +0800140}
141
142static bool ma_set_volume_l(
Jasmine Cha70771b62018-05-15 15:02:43 +0800143 const struct ma_audio_cal_settings *audio_cal_settings, double volume)
jasmine cha270b7762018-03-30 15:41:33 +0800144{
Jasmine Cha70771b62018-05-15 15:02:43 +0800145 return my_data->ma_set_volume(g_ma_audio_cal_handle, audio_cal_settings,
146 volume);
jasmine cha270b7762018-03-30 15:41:33 +0800147}
148
149static bool ma_set_volume_table_l(
Jasmine Cha70771b62018-05-15 15:02:43 +0800150 const struct ma_audio_cal_settings *audio_cal_settings,
151 size_t num_streams, struct ma_state *volume_table)
jasmine cha270b7762018-03-30 15:41:33 +0800152{
Jasmine Cha70771b62018-05-15 15:02:43 +0800153 return my_data->ma_set_volume_table(g_ma_audio_cal_handle,
154 audio_cal_settings, num_streams,
155 volume_table);
jasmine cha270b7762018-03-30 15:41:33 +0800156}
157
158static inline bool valid_usecase(struct audio_usecase *usecase)
159{
160 if ((usecase->type == PCM_PLAYBACK) &&
161 /* supported usecases */
162 ((usecase->id == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER) ||
163 (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) ||
164 (usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
165 /* support devices */
166 ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
167 (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
Jasmine Cha70771b62018-05-15 15:02:43 +0800168 /* TODO: enable A2DP when it is ready */
jasmine cha270b7762018-03-30 15:41:33 +0800169 (usecase->devices & AUDIO_DEVICE_OUT_ALL_USB)))
170
171 return true;
172
173 ALOGV("%s: not support type %d usecase %d device %d",
174 __func__, usecase->type, usecase->id, usecase->devices);
175
176 return false;
177}
178
179// already hold lock
180static inline bool is_active()
181{
182 ma_stream_type_t i = 0;
183
184 for (i = 0; i < STREAM_MAX_TYPES; i++)
185 if (ma_cur_state_table[i].active &&
186 (ma_cur_state_table[i].vol != 0))
187 return true;
188
189 return false;
190}
191
192static bool check_and_send_all_audio_cal(struct audio_device *adev, ma_cmd_t cmd)
193{
194 int i = 0;
195 bool ret = false;
196 float vol = 0;
197 struct listnode *node;
198 struct audio_usecase *usecase;
199 struct ma_audio_cal_settings *ma_cal = NULL;
200
201 // alloct
202 ma_cal = (struct ma_audio_cal_settings *)malloc(sizeof(struct ma_audio_cal_settings));
203
204 if (ma_cal == NULL) {
205 ALOGE("%s: ma_cal alloct fail", __func__);
206 return ret;
207 }
208
209 list_for_each(node, &adev->usecase_list) {
210 usecase = node_to_item(node, struct audio_usecase, list);
211 if (valid_usecase(usecase)) {
jasmine cha270b7762018-03-30 15:41:33 +0800212 ma_cal->app_type = usecase->stream.out->app_type_cfg.app_type;
213 ma_cal->device = usecase->stream.out->devices;
214 ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
215 __func__, usecase->id, ma_cal->app_type, ma_cal->device);
216
217 switch (cmd) {
218 case MA_CMD_VOL:
219 ret = ma_set_volume_table_l(ma_cal, STREAM_MAX_TYPES,
Jasmine Cha70771b62018-05-15 15:02:43 +0800220 ma_cur_state_table);
jasmine cha270b7762018-03-30 15:41:33 +0800221 if (ret)
222 ALOGV("Waves: ma_set_volume_table_l success");
223 else
224 ALOGE("Waves: ma_set_volume_table_l %f returned with error.", vol);
225
226 ALOGV("%s: send volume table === Start", __func__);
227 for (i = 0; i < STREAM_MAX_TYPES; i++)
Jasmine Cha70771b62018-05-15 15:02:43 +0800228 ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__,
229 i, ma_cur_state_table[i].vol,
230 ma_cur_state_table[i].active ? "T" : "F");
jasmine cha270b7762018-03-30 15:41:33 +0800231 ALOGV("%s: send volume table === End", __func__);
232 break;
233 case MA_CMD_SWAP_ENABLE:
234 ret = ma_set_lr_swap_l(ma_cal, true);
235 if (ret)
236 ALOGV("Waves: ma_set_lr_swap_l enable returned with success.");
237 else
238 ALOGE("Waves: ma_set_lr_swap_l enable returned with error.");
239 break;
240 case MA_CMD_SWAP_DISABLE:
241 ret = ma_set_lr_swap_l(ma_cal, false);
242 if (ret)
243 ALOGV("Waves: ma_set_lr_swap_l disable returned with success.");
244 else
245 ALOGE("Waves: ma_set_lr_swap_l disable returned with error.");
246 break;
247 default:
248 ALOGE("%s: unsupported cmd %d", __func__, cmd);
249 }
jasmine cha270b7762018-03-30 15:41:33 +0800250 }
251 }
252 free(ma_cal);
253
254 return ret;
255}
256
257static bool find_sup_dev(char *name)
258{
259 char *token;
260 const char s[2] = ",";
261 bool ret = false;
262 char sup_devs[128];
263
264 // the rule of comforming suppored dev's name
265 // 1. Both string len are equal
266 // 2. Both string content are equal
267
268 strncpy(sup_devs, SUPPORT_DEV, sizeof(sup_devs));
269 token = strtok(sup_devs, s);
270 while (token != NULL) {
271 if (strncmp(token, name, strlen(token)) == 0 &&
272 strlen(token) == strlen(name)) {
273 ALOGD("%s: support dev %s", __func__, token);
274 ret = true;
275 break;
276 }
277 token = strtok(NULL, s);
278 }
279
280 return ret;
281}
282
283static void ma_set_swap_l(struct audio_device *adev, bool enable)
284{
Jasmine Cha70771b62018-05-15 15:02:43 +0800285 // do platform LR swap if it enables on Waves effect
286 // but there is no Waves implementation
jasmine cha270b7762018-03-30 15:41:33 +0800287 if (!my_data) {
Jasmine Cha70771b62018-05-15 15:02:43 +0800288 platform_check_and_set_swap_lr_channels(adev, enable);
289 ALOGV("%s: maxxaudio isn't initialized.", __func__);
jasmine cha270b7762018-03-30 15:41:33 +0800290 return;
291 }
Jasmine Cha70771b62018-05-15 15:02:43 +0800292
jasmine cha270b7762018-03-30 15:41:33 +0800293 if (enable)
294 check_and_send_all_audio_cal(adev, MA_CMD_SWAP_ENABLE);
295 else
296 check_and_send_all_audio_cal(adev, MA_CMD_SWAP_DISABLE);
297}
298
299static void ma_support_usb(bool enable, int card)
300{
301 char path[128];
302 char id[32];
303 int ret = 0;
304 int32_t fd = -1;
305 char *idd;
306
307 if (enable) {
308 ret = snprintf(path, sizeof(path), "/proc/asound/card%u/id", card);
309 if (ret < 0) {
310 ALOGE("%s: failed on snprintf (%d) to path %s\n",
Jasmine Cha70771b62018-05-15 15:02:43 +0800311 __func__, ret, path);
jasmine cha270b7762018-03-30 15:41:33 +0800312 goto done;
313 }
314 fd = open(path, O_RDONLY);
315 if (fd < 0) {
316 ALOGE("%s: error failed to open id file %s error: %d\n",
317 __func__, path, errno);
318 goto done;
319 }
320 if (read(fd, id, sizeof(id)) < 0) {
321 ALOGE("%s: file read error", __func__);
322 goto done;
323 }
324 //replace '\n' to '\0'
325 idd = strtok(id, "\n");
326
327 if (find_sup_dev(idd)) {
328 ALOGV("%s: support device name is %s", __func__, id);
329 g_supported_dev |= SUPPORTED_USB;
330 } else
331 ALOGV("%s: device %s isn't found from %s", __func__, id, SUPPORT_DEV);
332 } else {
333 g_supported_dev &= ~SUPPORTED_USB;
334 }
335
336done:
337 if (fd >= 0) close(fd);
338}
339
340// adev_init lock held
341void audio_extn_ma_init(void *platform)
342{
343 ma_stream_type_t i = 0;
344 int ret = 0;
Jasmine Cha70771b62018-05-15 15:02:43 +0800345 char lib_path[128] = {0};
346 char mps_path[128] = {0};
347 struct snd_card_split *snd_split_handle = NULL;
348 snd_split_handle = audio_extn_get_snd_card_split();
jasmine cha270b7762018-03-30 15:41:33 +0800349
350 if (platform == NULL) {
351 ALOGE("%s: platform is NULL", __func__);
352 goto error;
353 }
354
355 if (my_data) { free(my_data); }
356 my_data = calloc(1, sizeof(struct ma_platform_data));
357 if (my_data == NULL) {
358 ALOGE("%s: ma_cal alloct fail", __func__);
359 goto error;
360 }
361
362 pthread_mutex_init(&my_data->lock, NULL);
363
Jasmine Cha70771b62018-05-15 15:02:43 +0800364 my_data->platform = platform;
jasmine cha270b7762018-03-30 15:41:33 +0800365 ret = snprintf(lib_path, sizeof(lib_path), "%s/%s", LIB_MA_PATH, LIB_MA_PARAM);
366 if (ret < 0) {
367 ALOGE("%s: snprintf failed for lib %s, ret %d", __func__, LIB_MA_PARAM, ret);
368 goto error;
369 }
370
371 my_data->waves_handle = dlopen(lib_path, RTLD_NOW);
372 if (my_data->waves_handle == NULL) {
373 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_MA_PARAM);
374 goto error;
375 } else {
376 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
377
378 my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle,
Jasmine Cha70771b62018-05-15 15:02:43 +0800379 MA_QDSP_PARAM_INIT);
jasmine cha270b7762018-03-30 15:41:33 +0800380 if (!my_data->ma_param_init) {
381 ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
382 goto error;
383 }
384
Jasmine Cha70771b62018-05-15 15:02:43 +0800385 my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(
386 my_data->waves_handle, MA_QDSP_PARAM_DEINIT);
jasmine cha270b7762018-03-30 15:41:33 +0800387 if (!my_data->ma_param_deinit) {
388 ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
389 goto error;
390 }
391
392 my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
Jasmine Cha70771b62018-05-15 15:02:43 +0800393 MA_QDSP_SET_LR_SWAP);
jasmine cha270b7762018-03-30 15:41:33 +0800394 if (!my_data->ma_set_lr_swap) {
395 ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
396 goto error;
397 }
398
Jasmine Cha70771b62018-05-15 15:02:43 +0800399 my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(
400 my_data->waves_handle, MA_QDSP_SET_MODE);
jasmine cha270b7762018-03-30 15:41:33 +0800401 if (!my_data->ma_set_sound_mode) {
402 ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
403 goto error;
404 }
405
406 my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle,
Jasmine Cha70771b62018-05-15 15:02:43 +0800407 MA_QDSP_SET_VOL);
jasmine cha270b7762018-03-30 15:41:33 +0800408 if (!my_data->ma_set_volume) {
409 ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
410 goto error;
411 }
412
Jasmine Cha70771b62018-05-15 15:02:43 +0800413 my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(
414 my_data->waves_handle, MA_QDSP_SET_VOLT);
jasmine cha270b7762018-03-30 15:41:33 +0800415 if (!my_data->ma_set_volume_table) {
416 ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
417 goto error;
418 }
419 }
420
Jasmine Cha70771b62018-05-15 15:02:43 +0800421 /* get preset table */
422 if (snd_split_handle == NULL) {
423 snprintf(mps_path, sizeof(mps_path), "%s/%s.mps",
424 PRESET_PATH, MPS_BASE_STRING);
425 } else {
426 snprintf(mps_path, sizeof(mps_path), "%s/%s_%s.mps",
427 PRESET_PATH, MPS_BASE_STRING, snd_split_handle->form_factor);
jasmine cha270b7762018-03-30 15:41:33 +0800428 }
Jasmine Cha70771b62018-05-15 15:02:43 +0800429
430 /* check file */
431 if (access(mps_path, F_OK) < 0) {
432 ALOGW("%s: file %s isn't existed.", __func__, mps_path);
433 goto error;
434 } else
435 ALOGD("%s: Loading mps file: %s", __func__, mps_path);
436
jasmine cha270b7762018-03-30 15:41:33 +0800437 /* TODO: check user preset table once the feature is enabled
438 if (access(USER_PRESET_PATH, F_OK) < 0 ){
439 ALOGW("%s: file %s isn't existed.", __func__, USER_PRESET_PATH);
440 goto error;
441 }
442 */
443 if (access(CONFIG_PATH, F_OK) < 0) {
444 ALOGW("%s: file %s isn't existed.", __func__, CONFIG_PATH);
445 goto error;
446 }
447
448 /* init ma parameter */
449 if (my_data->ma_param_init(&g_ma_audio_cal_handle,
Jasmine Cha70771b62018-05-15 15:02:43 +0800450 mps_path,
451 USER_PRESET_PATH, /* unused */
452 CONFIG_PATH,
453 &set_audio_cal)) {
jasmine cha270b7762018-03-30 15:41:33 +0800454 if (!g_ma_audio_cal_handle) {
455 ALOGE("%s: ma parameters initialize failed", __func__);
456 my_data->ma_param_deinit(&g_ma_audio_cal_handle);
457 goto error;
458 }
459 ALOGD("%s: ma parameters initialize successful", __func__);
460 } else {
461 ALOGE("%s: ma parameters initialize failed", __func__);
462 goto error;
463 }
464
465 /* init volume table */
466 for (i = 0; i < STREAM_MAX_TYPES; i++) {
467 ma_cur_state_table[i].vol = 0.0;
468 ma_cur_state_table[i].active = false;
469 }
470
471 return;
472
473error:
474 if (my_data) { free(my_data); }
475 my_data = NULL;
476}
477
478//adev_init lock held
479void audio_extn_ma_deinit()
480{
481 if (my_data) {
482 /* deinit ma parameter */
483 if (my_data->ma_param_deinit &&
484 my_data->ma_param_deinit(&g_ma_audio_cal_handle))
485 ALOGD("%s: ma parameters uninitialize successful", __func__);
486 else
487 ALOGD("%s: ma parameters uninitialize failed", __func__);
488
489 pthread_mutex_destroy(&my_data->lock);
490 free(my_data);
491 my_data = NULL;
492 }
493}
494
495// adev_init and adev lock held
Jasmine Cha70771b62018-05-15 15:02:43 +0800496bool audio_extn_ma_set_state(struct audio_device *adev, int stream_type,
497 float vol, bool active)
jasmine cha270b7762018-03-30 15:41:33 +0800498{
499 bool ret = false;
500 ma_stream_type_t stype = (ma_stream_type_t)stream_type;
501
502 ALOGV("%s: stream[%d] vol[%f] active[%s]",
503 __func__, stream_type, vol, active ? "true" : "false");
504
505 if (!my_data) {
Jasmine Cha70771b62018-05-15 15:02:43 +0800506 ALOGV("%s: maxxaudio isn't initialized.", __func__);
jasmine cha270b7762018-03-30 15:41:33 +0800507 return ret;
508 }
509
510 // update condition
511 // 1. start track: active and volume isn't zero
512 // 2. stop track: no tracks are active
513 if ((active && vol != 0) ||
Jasmine Cha70771b62018-05-15 15:02:43 +0800514 (!active)) {
jasmine cha270b7762018-03-30 15:41:33 +0800515 pthread_mutex_lock(&my_data->lock);
516
517 ma_cur_state_table[stype].vol = vol;
518 ma_cur_state_table[stype].active = active;
519 if (is_active())
520 ret = check_and_send_all_audio_cal(adev, MA_CMD_VOL);
521
522 pthread_mutex_unlock(&my_data->lock);
523 }
524
525 return ret;
526}
527
Jasmine Cha70771b62018-05-15 15:02:43 +0800528void audio_extn_ma_set_device(struct audio_usecase *usecase)
jasmine cha270b7762018-03-30 15:41:33 +0800529{
530 int i = 0;
531 int u_index = -1;
532 float vol = 0;
533 struct ma_audio_cal_settings *ma_cal = NULL;
534
535 if (!my_data) {
536 ALOGV("%s: maxxaudio isn't initialized.", __func__);
537 return;
538 }
539
540 if (!valid_usecase(usecase)) {
541 ALOGV("%s: %d is not supported usecase", __func__, usecase->id);
542 return;
543 }
544
545 ma_cal = (struct ma_audio_cal_settings *)malloc(sizeof(struct ma_audio_cal_settings));
546
547 /* update audio_cal and send it */
548 if (ma_cal != NULL){
jasmine cha270b7762018-03-30 15:41:33 +0800549 ma_cal->app_type = usecase->stream.out->app_type_cfg.app_type;
550 ma_cal->device = usecase->stream.out->devices;
551 ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
552 __func__, usecase->id, ma_cal->app_type, ma_cal->device);
553
554 pthread_mutex_lock(&my_data->lock);
555
556 if (is_active()) {
557 ALOGV("%s: send volume table === Start", __func__);
558 for (i = 0; i < STREAM_MAX_TYPES; i++)
559 ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__, i,
560 ma_cur_state_table[i].vol,
561 ma_cur_state_table[i].active ? "T" : "F");
562 ALOGV("%s: send volume table === End", __func__);
563
564 if (!ma_set_volume_table_l(ma_cal,
Jasmine Cha70771b62018-05-15 15:02:43 +0800565 STREAM_MAX_TYPES,
566 ma_cur_state_table))
jasmine cha270b7762018-03-30 15:41:33 +0800567 ALOGE("Waves: ma_set_volume_table_l %f returned with error.", vol);
568 else
569 ALOGV("Waves: ma_set_volume_table_l success");
570
571 }
572 pthread_mutex_unlock(&my_data->lock);
573 free(ma_cal);
574 } else {
575 ALOGE("%s: ma_cal alloct fail", __func__);
576 }
577}
578
Jasmine Cha70771b62018-05-15 15:02:43 +0800579void audio_extn_ma_set_parameters(struct audio_device *adev,
580 struct str_parms *parms)
jasmine cha270b7762018-03-30 15:41:33 +0800581{
582 int ret;
583 bool ret_b;
584 int val;
585 char value[128];
586
587 // do LR swap and usb recognition
588 ret = str_parms_get_int(parms, "rotation", &val);
589 if (ret >= 0) {
590 switch (val) {
591 case 270:
592 ma_set_swap_l(adev, true);
593 break;
594 case 0:
595 case 90:
596 case 180:
597 ma_set_swap_l(adev, false);
598 break;
599 }
600 }
601
602 // check connect status
Jasmine Cha70771b62018-05-15 15:02:43 +0800603 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
604 sizeof(value));
jasmine cha270b7762018-03-30 15:41:33 +0800605 if (ret >= 0) {
606 audio_devices_t device = (audio_devices_t)strtoul(value, NULL, 10);
607 if (audio_is_usb_out_device(device)) {
608 ret = str_parms_get_str(parms, "card", value, sizeof(value));
609 if (ret >= 0) {
610 const int card = atoi(value);
611 ma_support_usb(true, card);
612 }
613 }
614 }
615
616 // check disconnect status
Jasmine Cha70771b62018-05-15 15:02:43 +0800617 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
618 sizeof(value));
jasmine cha270b7762018-03-30 15:41:33 +0800619 if (ret >= 0) {
620 audio_devices_t device = (audio_devices_t)strtoul(value, NULL, 10);
621 if (audio_is_usb_out_device(device)) {
622 ret = str_parms_get_str(parms, "card", value, sizeof(value));
623 if (ret >= 0) {
624 const int card = atoi(value);
625 ma_support_usb(false, card /*useless*/);
626 }
627 }
628 }
629}
630
631bool audio_extn_ma_supported_usb()
632{
633 ALOGV("%s: current support 0x%x", __func__, g_supported_dev);
634 return (g_supported_dev & SUPPORTED_USB) ? true : false;
635}