Loading hal/audio_extn/audio_extn.c +120 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <stdlib.h> #include <errno.h> #include <dlfcn.h> #include <fcntl.h> #include <cutils/properties.h> #include <cutils/log.h> Loading Loading @@ -82,6 +83,124 @@ static struct audio_extn_module aextnmod = { #define AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE "offload_num_active" #define AUDIO_PARAMETER_HPX "HPX" /* * update sysfs node hdmi_audio_cb to enable notification acknowledge feature * bit(5) set to 1 to enable this feature * bit(4) set to 1 to enable acknowledgement * this is done only once at the first connect event * * bit(0) set to 1 when HDMI cable is connected * bit(0) set to 0 when HDMI cable is disconnected * this is done when device switch happens by setting audioparamter */ #define HDMI_PLUG_STATUS_NOTIFY_ENABLE 0x30 static ssize_t update_sysfs_node(const char *path, const char *data, size_t len) { ssize_t err = 0; int fd = -1; err = access(path, W_OK); if (!err) { fd = open(path, O_WRONLY); errno = 0; err = write(fd, data, len); if (err < 0) { err = -errno; } close(fd); } else { ALOGE("%s: Failed to access path: %s error: %s", __FUNCTION__, path, strerror(errno)); err = -errno; } return err; } static int get_hdmi_sysfs_node_index() { static int node_index = -1; char fbvalue[80] = {0}; char fbpath[80] = {0}; int i = 0; FILE *hdmi_fp = NULL; if(node_index >= 0) { //hdmi sysfs node will not change so we just need to get the index once. ALOGV("HDMI sysfs node is at fb%d", node_index); return node_index; } for(i = 0; i < 3; i++) { snprintf(fbpath, sizeof(fbpath), "/sys/class/graphics/fb%d/msm_fb_type", i); hdmi_fp = fopen(fbpath, "r"); if(hdmi_fp) { fread(fbvalue, sizeof(char), 80, hdmi_fp); if(strncmp(fbvalue, "dtv panel", strlen("dtv panel")) == 0) { node_index = i; ALOGV("HDMI is at fb%d",i); fclose(hdmi_fp); return node_index; } fclose(hdmi_fp); } else { ALOGE("Failed to open fb node %d",i); } } return -1; } static int update_hdmi_sysfs_node(int node_value) { char hdmi_ack_path[80] = {0}; char hdmi_ack_value[3] = {0}; int index, ret = -1; index = get_hdmi_sysfs_node_index(); if (index >= 0) { snprintf(hdmi_ack_value, sizeof(hdmi_ack_value), "%d", node_value); snprintf(hdmi_ack_path, sizeof(hdmi_ack_path), "/sys/class/graphics/fb%d/hdmi_audio_cb", index); ret = update_sysfs_node(hdmi_ack_path, hdmi_ack_value, sizeof(hdmi_ack_value)); ALOGI("update hdmi_audio_cb at fb[%d] to:[%d] %s", index, node_value, (ret >= 0) ? "success":"fail"); } return ret; } static void check_and_set_hdmi_connection_status(struct str_parms *parms) { char value[32] = {0}; static bool is_hdmi_sysfs_node_init = false; if (str_parms_get_str(parms, "connect", value, sizeof(value)) >= 0 && (atoi(value) & AUDIO_DEVICE_OUT_HDMI)) { //params = "connect=1024" for HDMI connection. if (is_hdmi_sysfs_node_init == false) { is_hdmi_sysfs_node_init = true; update_hdmi_sysfs_node(HDMI_PLUG_STATUS_NOTIFY_ENABLE); } update_hdmi_sysfs_node(1); } else if(str_parms_get_str(parms, "disconnect", value, sizeof(value)) >= 0 && (atoi(value) & AUDIO_DEVICE_OUT_HDMI)){ //params = "disconnect=1024" for HDMI disconnection. update_hdmi_sysfs_node(0); } else { // handle hdmi devices only return; } } #ifndef FM_POWER_OPT #define audio_extn_fm_set_parameters(adev, parms) (0) #else Loading Loading @@ -574,6 +693,7 @@ void audio_extn_set_parameters(struct audio_device *adev, audio_extn_hpx_set_parameters(adev, parms); audio_extn_pm_set_parameters(parms); audio_extn_source_track_set_parameters(adev, parms); check_and_set_hdmi_connection_status(parms); if (adev->offload_effects_set_parameters != NULL) adev->offload_effects_set_parameters(parms); } Loading Loading
hal/audio_extn/audio_extn.c +120 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <stdlib.h> #include <errno.h> #include <dlfcn.h> #include <fcntl.h> #include <cutils/properties.h> #include <cutils/log.h> Loading Loading @@ -82,6 +83,124 @@ static struct audio_extn_module aextnmod = { #define AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE "offload_num_active" #define AUDIO_PARAMETER_HPX "HPX" /* * update sysfs node hdmi_audio_cb to enable notification acknowledge feature * bit(5) set to 1 to enable this feature * bit(4) set to 1 to enable acknowledgement * this is done only once at the first connect event * * bit(0) set to 1 when HDMI cable is connected * bit(0) set to 0 when HDMI cable is disconnected * this is done when device switch happens by setting audioparamter */ #define HDMI_PLUG_STATUS_NOTIFY_ENABLE 0x30 static ssize_t update_sysfs_node(const char *path, const char *data, size_t len) { ssize_t err = 0; int fd = -1; err = access(path, W_OK); if (!err) { fd = open(path, O_WRONLY); errno = 0; err = write(fd, data, len); if (err < 0) { err = -errno; } close(fd); } else { ALOGE("%s: Failed to access path: %s error: %s", __FUNCTION__, path, strerror(errno)); err = -errno; } return err; } static int get_hdmi_sysfs_node_index() { static int node_index = -1; char fbvalue[80] = {0}; char fbpath[80] = {0}; int i = 0; FILE *hdmi_fp = NULL; if(node_index >= 0) { //hdmi sysfs node will not change so we just need to get the index once. ALOGV("HDMI sysfs node is at fb%d", node_index); return node_index; } for(i = 0; i < 3; i++) { snprintf(fbpath, sizeof(fbpath), "/sys/class/graphics/fb%d/msm_fb_type", i); hdmi_fp = fopen(fbpath, "r"); if(hdmi_fp) { fread(fbvalue, sizeof(char), 80, hdmi_fp); if(strncmp(fbvalue, "dtv panel", strlen("dtv panel")) == 0) { node_index = i; ALOGV("HDMI is at fb%d",i); fclose(hdmi_fp); return node_index; } fclose(hdmi_fp); } else { ALOGE("Failed to open fb node %d",i); } } return -1; } static int update_hdmi_sysfs_node(int node_value) { char hdmi_ack_path[80] = {0}; char hdmi_ack_value[3] = {0}; int index, ret = -1; index = get_hdmi_sysfs_node_index(); if (index >= 0) { snprintf(hdmi_ack_value, sizeof(hdmi_ack_value), "%d", node_value); snprintf(hdmi_ack_path, sizeof(hdmi_ack_path), "/sys/class/graphics/fb%d/hdmi_audio_cb", index); ret = update_sysfs_node(hdmi_ack_path, hdmi_ack_value, sizeof(hdmi_ack_value)); ALOGI("update hdmi_audio_cb at fb[%d] to:[%d] %s", index, node_value, (ret >= 0) ? "success":"fail"); } return ret; } static void check_and_set_hdmi_connection_status(struct str_parms *parms) { char value[32] = {0}; static bool is_hdmi_sysfs_node_init = false; if (str_parms_get_str(parms, "connect", value, sizeof(value)) >= 0 && (atoi(value) & AUDIO_DEVICE_OUT_HDMI)) { //params = "connect=1024" for HDMI connection. if (is_hdmi_sysfs_node_init == false) { is_hdmi_sysfs_node_init = true; update_hdmi_sysfs_node(HDMI_PLUG_STATUS_NOTIFY_ENABLE); } update_hdmi_sysfs_node(1); } else if(str_parms_get_str(parms, "disconnect", value, sizeof(value)) >= 0 && (atoi(value) & AUDIO_DEVICE_OUT_HDMI)){ //params = "disconnect=1024" for HDMI disconnection. update_hdmi_sysfs_node(0); } else { // handle hdmi devices only return; } } #ifndef FM_POWER_OPT #define audio_extn_fm_set_parameters(adev, parms) (0) #else Loading Loading @@ -574,6 +693,7 @@ void audio_extn_set_parameters(struct audio_device *adev, audio_extn_hpx_set_parameters(adev, parms); audio_extn_pm_set_parameters(parms); audio_extn_source_track_set_parameters(adev, parms); check_and_set_hdmi_connection_status(parms); if (adev->offload_effects_set_parameters != NULL) adev->offload_effects_set_parameters(parms); } Loading