diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index 92c80bd1..de1c04da 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,9 @@ #include "audio_extn.h" #include "voice_extn.h" #include "sound/compress_params.h" +#include "sound/msmcal-hwdep.h" +#define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100) #define MIXER_XML_PATH "/system/etc/mixer_paths.xml" #define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml" #define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml" @@ -98,6 +101,13 @@ #define EVENT_EXTERNAL_SPK_1 "qc_ext_spk_1" #define EVENT_EXTERNAL_SPK_2 "qc_ext_spk_2" #define EVENT_EXTERNAL_MIC "qc_ext_mic" +#define MAX_CAL_NAME 20 + +char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = { + [WCD9XXX_ANC_CAL] = "anc_cal", + [WCD9XXX_MBHC_CAL] = "mbhc_cal", + [WCD9XXX_MAD_CAL] = "mad_cal", +}; enum { VOICE_FEATURE_SET_DEFAULT, @@ -117,6 +127,8 @@ typedef void (*acdb_send_audio_cal_t)(int, int, int , int); typedef void (*acdb_send_voice_cal_t)(int, int); typedef int (*acdb_reload_vocvoltable_t)(int); typedef int (*acdb_get_default_app_type_t)(void); +typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data); +acdb_loader_get_calibration_t acdb_loader_get_calibration; struct platform_data { struct audio_device *adev; @@ -740,6 +752,92 @@ done: return; } +static int hw_util_open(int card_no) +{ + int fd = -1; + char dev_name[256]; + + snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u", + card_no, WCD9XXX_CODEC_HWDEP_NODE); + ALOGD("%s Opening device %s\n", __func__, dev_name); + fd = open(dev_name, O_WRONLY); + if (fd < 0) { + ALOGE("%s: cannot open device '%s'\n", __func__, dev_name); + return fd; + } + ALOGD("%s success", __func__); + return fd; +} + +struct param_data { + int use_case; + int acdb_id; + int get_size; + int buff_size; + int data_size; + void *buff; +}; + +static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration, int fd) +{ + int ret = 0, type; + + for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) { + struct wcdcal_ioctl_buffer codec_buffer; + struct param_data calib; + + if (!strcmp(cal_name_info[type], "mad_cal")) + calib.acdb_id = SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID; + calib.get_size = 1; + ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data), + &calib); + if (ret < 0) { + ALOGE("%s get_calibration failed\n", __func__); + return ret; + } + calib.get_size = 0; + calib.buff = malloc(calib.buff_size); + ret = acdb_loader_get_calibration(cal_name_info[type], + sizeof(struct param_data), &calib); + if (ret < 0) { + ALOGE("%s get_calibration failed\n", __func__); + free(calib.buff); + return ret; + } + codec_buffer.buffer = calib.buff; + codec_buffer.size = calib.data_size; + codec_buffer.cal_type = type; + if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0) + ALOGE("Failed to call ioctl for %s err=%d", + cal_name_info[type], errno); + ALOGD("%s cal sent for %s", __func__, cal_name_info[type]); + free(calib.buff); + } + return ret; +} + +static void audio_hwdep_send_cal(struct platform_data *plat_data) +{ + int fd; + + fd = hw_util_open(plat_data->adev->snd_card); + if (fd == -1) { + ALOGE("%s error open\n", __func__); + return; + } + + acdb_loader_get_calibration = (acdb_loader_get_calibration_t) + dlsym(plat_data->acdb_handle, "acdb_loader_get_calibration"); + + if (acdb_loader_get_calibration == NULL) { + ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__, + dlerror()); + return; + } + if (send_codec_cal(acdb_loader_get_calibration, fd) < 0) + ALOGE("%s: Could not send anc cal", __FUNCTION__); +} + void *platform_init(struct audio_device *adev) { char platform[PROPERTY_VALUE_MAX]; @@ -948,6 +1046,7 @@ acdb_init_fail: audio_extn_spkr_prot_init(adev); audio_extn_dolby_set_license(adev); + audio_hwdep_send_cal(my_data); /* init audio device arbitration */ audio_extn_dev_arbi_init();