10499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent/* 20499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * Copyright (C) 2014 The Android Open Source Project 30499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * 40499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 50499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * you may not use this file except in compliance with the License. 60499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * You may obtain a copy of the License at 70499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * 80499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 90499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * 100499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * Unless required by applicable law or agreed to in writing, software 110499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 120499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * See the License for the specific language governing permissions and 140499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent * limitations under the License. 150499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent */ 160499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 170499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent#define LOG_TAG "ext_speaker" 180499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent/*#define LOG_NDEBUG 0*/ 19e6e2d441c567d5da185b787d6c10ca2c8b36a694Haynes Mathew George#include <log/log.h> 200499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 217c685a1267affc6f96a26f81164b913cd60a3924Vineeta Srivastava#include <stdlib.h> 220499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent#include <audio_hw.h> 230499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent#include <dlfcn.h> 240499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 257ddf867a1a20700aa3242c5d1ab3c621a69ef3e7Andy Hung#ifdef __LP64__ 268c83e0ad02470d53917fd1b24ed35e813f345451Diego Wilson#define LIB_SPEAKER_BUNDLE "/vendor/lib64/soundfx/libspeakerbundle.so" 277ddf867a1a20700aa3242c5d1ab3c621a69ef3e7Andy Hung#else 288c83e0ad02470d53917fd1b24ed35e813f345451Diego Wilson#define LIB_SPEAKER_BUNDLE "/vendor/lib/soundfx/libspeakerbundle.so" 297ddf867a1a20700aa3242c5d1ab3c621a69ef3e7Andy Hung#endif 300499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 310499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurenttypedef void (*set_mode_t)(int); 320499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurenttypedef void (*set_speaker_on_t)(bool); 330499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurenttypedef void (*set_earpiece_on_t)(bool); 344cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurenttypedef void (*set_voice_vol_t)(float); 350499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 360499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentstruct speaker_data { 370499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct audio_device *adev; 380499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent void *speaker_bundle; 390499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent set_mode_t set_mode; 400499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent set_speaker_on_t set_speaker_on; 410499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent set_earpiece_on_t set_earpiece_on; 420499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent set_voice_vol_t set_voice_vol; 430499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent}; 440499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 450499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentstatic struct speaker_data* open_speaker_bundle() 460499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent{ 470499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct speaker_data *sd = calloc(1, sizeof(struct speaker_data)); 480499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 490499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent sd->speaker_bundle = dlopen(LIB_SPEAKER_BUNDLE, RTLD_NOW); 500499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (sd->speaker_bundle == NULL) { 510499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent ALOGE("%s: DLOPEN failed for %s", __func__, LIB_SPEAKER_BUNDLE); 520499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent goto error; 530499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } else { 540499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent ALOGV("%s: DLOPEN successful for %s", __func__, LIB_SPEAKER_BUNDLE); 550499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 560499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent sd->set_mode = (set_mode_t)dlsym(sd->speaker_bundle, 570499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent "set_mode"); 580499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (sd->set_mode == NULL) { 590499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent ALOGE("%s: dlsym error %s for set_mode", __func__, 600499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent dlerror()); 610499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent goto error; 620499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 630499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent sd->set_speaker_on = (set_speaker_on_t)dlsym(sd->speaker_bundle, 640499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent "set_speaker_on"); 650499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (sd->set_speaker_on == NULL) { 660499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent ALOGE("%s: dlsym error %s for set_speaker_on", __func__, 670499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent dlerror()); 680499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent goto error; 690499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 700499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent sd->set_earpiece_on = (set_earpiece_on_t)dlsym(sd->speaker_bundle, 710499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent "set_earpiece_on"); 720499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (sd->set_earpiece_on == NULL) { 730499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent ALOGE("%s: dlsym error %s for set_earpiece_on", __func__, 740499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent dlerror()); 750499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent goto error; 760499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 770499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent sd->set_voice_vol = (set_voice_vol_t)dlsym(sd->speaker_bundle, 780499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent "set_voice_volume"); 790499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (sd->set_voice_vol == NULL) { 800499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent ALOGE("%s: dlsym error %s for set_voice_volume", 810499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent __func__, dlerror()); 820499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent goto error; 830499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 840499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 850499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent return sd; 860499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 870499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurenterror: 880499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent free(sd); 890499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent return 0; 900499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent} 910499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 920499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentstatic void close_speaker_bundle(struct speaker_data *sd) 930499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent{ 940499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (sd != NULL) { 950499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent dlclose(sd->speaker_bundle); 960499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent free(sd); 970499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent sd = NULL; 980499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 990499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent} 1000499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1010499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentvoid *audio_extn_extspk_init(struct audio_device *adev) 1020499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent{ 1030499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct speaker_data *data = open_speaker_bundle(); 1040499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1050499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (data) 1060499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent data->adev = adev; 1070499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1080499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent return data; 1090499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent} 1100499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1110499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentvoid audio_extn_extspk_deinit(void *extn) 1120499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent{ 1130499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct speaker_data *data = (struct speaker_data*)extn; 1140499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent close_speaker_bundle(data); 1150499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent} 1160499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1170499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentvoid audio_extn_extspk_update(void* extn) 1180499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent{ 1190499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct speaker_data *data = (struct speaker_data*)extn; 1200499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1210499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (data) { 1220499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent bool speaker_on = false; 1230499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent bool earpiece_on = false; 1240499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct listnode *node; 1250499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct audio_usecase *usecase; 1260499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent list_for_each(node, &data->adev->usecase_list) { 1270499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent usecase = node_to_item(node, struct audio_usecase, list); 1280499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (usecase->devices & AUDIO_DEVICE_OUT_EARPIECE) { 1290499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if(data->adev->snd_dev_ref_cnt[usecase->out_snd_device] != 0) { 1300499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent earpiece_on = true; 1310499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 1320499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 1330499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) { 1340499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if(data->adev->snd_dev_ref_cnt[usecase->out_snd_device] != 0) { 1350499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent speaker_on = true; 1360499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 1370499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 1380499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 1390499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent data->set_earpiece_on(earpiece_on); 1400499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent data->set_speaker_on(speaker_on); 1410499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent } 1420499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent} 1430499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1440499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurentvoid audio_extn_extspk_set_mode(void* extn, audio_mode_t mode) 1450499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent{ 1460499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent struct speaker_data *data = (struct speaker_data*)extn; 1470499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent 1480499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent if (data) 1490499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent data->set_mode(mode); 1500499d4fc40cafb9fbb0e8eace1657cfaf79c5699Eric Laurent} 1514cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent 1524cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurentvoid audio_extn_extspk_set_voice_vol(void* extn, float vol) 1534cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent{ 1544cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent struct speaker_data *data = (struct speaker_data*)extn; 1554cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent 1564cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent if (data) 1574cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent data->set_voice_vol(vol); 1584cc4ce1a92a47fa1d98c884a33e5e93d3d468b15Eric Laurent} 159