Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f293674 authored by Derek Chen's avatar Derek Chen
Browse files

hal: support snd card status with set parameters

Support snd card status string with set parameters
API for audio HAL dev and input/output streams.
Remove hostless session control in auto hal as it
is managed in audiod.

Change-Id: I3390ca26cf49cef86df116d8e28c5c558f9afee6
parent 2d82b84b
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -1274,8 +1274,6 @@ int audio_extn_utils_get_license_params(const struct audio_device *adev, struct
#ifndef AUDIO_EXTN_AUTO_HAL_ENABLED
#define audio_extn_auto_hal_init(adev)                (0)
#define audio_extn_auto_hal_deinit()                  (0)
#define audio_extn_auto_hal_enable_hostless()         (0)
#define audio_extn_auto_hal_disable_hostless()        (0)
#define audio_extn_auto_hal_create_audio_patch(dev, num_sources,\
    sources, num_sinks, sinks, handle) (0)
#define audio_extn_auto_hal_release_audio_patch(dev, handle) (0)
@@ -1289,8 +1287,6 @@ int audio_extn_utils_get_license_params(const struct audio_device *adev, struct
#else
int32_t audio_extn_auto_hal_init(struct audio_device *adev);
void audio_extn_auto_hal_deinit(void);
int32_t audio_extn_auto_hal_enable_hostless(void);
void audio_extn_auto_hal_disable_hostless(void);
int audio_extn_auto_hal_create_audio_patch(struct audio_hw_device *dev,
                                unsigned int num_sources,
                                const struct audio_port_config *sources,
+0 −106
Original line number Diff line number Diff line
@@ -47,15 +47,9 @@

#ifdef AUDIO_EXTN_AUTO_HAL_ENABLED

struct hostless_config {
    struct pcm *pcm_tx;
    struct pcm *pcm_rx;
};

typedef struct auto_hal_module {
    struct audio_device *adev;
    card_status_t card_status;
    struct hostless_config hostless;
} auto_hal_module_t;

/* Auto hal module struct */
@@ -71,104 +65,6 @@ static const audio_usecase_t bus_device_usecases[] = {
    USECASE_AUDIO_PLAYBACK_PHONE,
};

/* Note: Due to ADP H/W design, SoC TERT/SEC TDM CLK and FSYNC lines are
 * both connected with CODEC and a single master is needed to provide
 * consistent CLK and FSYNC to slaves, hence configuring SoC TERT TDM as
 * single master and bring up a dummy hostless from TERT to SEC to ensure
 * both slave SoC SEC TDM and CODEC are driven upon system boot. */
int32_t audio_extn_auto_hal_enable_hostless(void)
{
    int32_t ret = 0;
    char mixer_path[MIXER_PATH_MAX_LENGTH];

    ALOGD("%s: Enable TERT -> SEC Hostless", __func__);

    if (auto_hal == NULL) {
        ALOGE("%s: Invalid device", __func__);
        return -EINVAL;
    }

    strlcpy(mixer_path, "dummy-hostless", MIXER_PATH_MAX_LENGTH);
    ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
    if (audio_route_apply_and_update_path(auto_hal->adev->audio_route,
            mixer_path)) {
        ALOGD("%s: %s not supported, continue", __func__, mixer_path);
        return ret;
    }

    /* TERT TDM TX 7 HOSTLESS to SEC TDM RX 7 HOSTLESS */
    int pcm_dev_rx = 48, pcm_dev_tx = 49;
    struct pcm_config pcm_config_lb = {
        .channels = 1,
        .rate = 48000,
        .period_size = 240,
        .period_count = 2,
        .format = PCM_FORMAT_S16_LE,
        .start_threshold = 0,
        .stop_threshold = INT_MAX,
        .avail_min = 0,
    };

    auto_hal->hostless.pcm_tx = pcm_open(auto_hal->adev->snd_card,
                                   pcm_dev_tx,
                                   PCM_IN, &pcm_config_lb);
    if (auto_hal->hostless.pcm_tx &&
        !pcm_is_ready(auto_hal->hostless.pcm_tx)) {
        ALOGE("%s: %s", __func__,
            pcm_get_error(auto_hal->hostless.pcm_tx));
        ret = -EIO;
        goto error;
    }
    auto_hal->hostless.pcm_rx = pcm_open(auto_hal->adev->snd_card,
                                   pcm_dev_rx,
                                   PCM_OUT, &pcm_config_lb);
    if (auto_hal->hostless.pcm_rx &&
        !pcm_is_ready(auto_hal->hostless.pcm_rx)) {
        ALOGE("%s: %s", __func__,
            pcm_get_error(auto_hal->hostless.pcm_rx));
        ret = -EIO;
        goto error;
    }

    if (pcm_start(auto_hal->hostless.pcm_tx) < 0) {
        ALOGE("%s: pcm start for pcm tx failed", __func__);
        ret = -EIO;
        goto error;
    }
    if (pcm_start(auto_hal->hostless.pcm_rx) < 0) {
        ALOGE("%s: pcm start for pcm rx failed", __func__);
        ret = -EIO;
        goto error;
    }
    return ret;

error:
    if (auto_hal->hostless.pcm_rx)
        pcm_close(auto_hal->hostless.pcm_rx);
    if (auto_hal->hostless.pcm_tx)
        pcm_close(auto_hal->hostless.pcm_tx);
    return ret;
}

void audio_extn_auto_hal_disable_hostless(void)
{
    ALOGD("%s: Disable TERT -> SEC Hostless", __func__);

    if (auto_hal == NULL) {
        ALOGE("%s: Invalid device", __func__);
        return;
    }

    if (auto_hal->hostless.pcm_tx) {
        pcm_close(auto_hal->hostless.pcm_tx);
        auto_hal->hostless.pcm_tx = NULL;
    }
    if (auto_hal->hostless.pcm_rx) {
        pcm_close(auto_hal->hostless.pcm_rx);
        auto_hal->hostless.pcm_rx = NULL;
    }
}

#define MAX_SOURCE_PORTS_PER_PATCH 1
#define MAX_SINK_PORTS_PER_PATCH 1

@@ -575,11 +471,9 @@ void audio_extn_auto_hal_set_parameters(struct audio_device *adev __unused,
        ALOGV("%s: snd card status %s", __func__, snd_card_status);
        if (strstr(snd_card_status, "OFFLINE")) {
            auto_hal->card_status = CARD_STATUS_OFFLINE;
            audio_extn_auto_hal_disable_hostless();
        }
        else if (strstr(snd_card_status, "ONLINE")) {
            auto_hal->card_status = CARD_STATUS_ONLINE;
            audio_extn_auto_hal_enable_hostless();
        }
    }

+0 −84
Original line number Diff line number Diff line
@@ -77,85 +77,6 @@ struct ext_hw_plugin_data {
/* This can be defined in platform specific file or use compile flag */
#define LIB_PLUGIN_DRIVER "libaudiohalplugin.so"

/* Note: Due to ADP H/W design, SoC TERT/SEC TDM CLK and FSYNC lines are
 * both connected with CODEC and a single master is needed to provide
 * consistent CLK and FSYNC to slaves, hence configuring SoC TERT TDM as
 * single master and bring up a dummy hostless from TERT to SEC to ensure
 * both slave SoC SEC TDM and CODEC are driven upon system boot. */
static void ext_hw_plugin_enable_adev_hostless(void *plugin)
{
    struct ext_hw_plugin_data *my_plugin =
        (struct ext_hw_plugin_data *)plugin;
    char mixer_path[MIXER_PATH_MAX_LENGTH];

    ALOGI("%s: Enable TERT -> SEC Hostless", __func__);

    strlcpy(mixer_path, "dummy-hostless", MIXER_PATH_MAX_LENGTH);
    ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
    if (audio_route_apply_and_update_path(my_plugin->adev->audio_route,
            mixer_path)) {
        ALOGE("%s: %s not supported, continue", __func__, mixer_path);
        return;
    }

    /* TERT TDM TX 7 HOSTLESS to SEC TDM RX 7 HOSTLESS */
    int pcm_dev_rx = 48, pcm_dev_tx = 49;
    struct pcm_config pcm_config_lb = {
        .channels = 1,
        .rate = 48000,
        .period_size = 240,
        .period_count = 2,
        .format = PCM_FORMAT_S16_LE,
        .start_threshold = 0,
        .stop_threshold = INT_MAX,
        .avail_min = 0,
    };

    my_plugin->adev_hostless.pcm_tx = pcm_open(my_plugin->adev->snd_card,
                                   pcm_dev_tx,
                                   PCM_IN, &pcm_config_lb);
    if (my_plugin->adev_hostless.pcm_tx &&
        !pcm_is_ready(my_plugin->adev_hostless.pcm_tx)) {
        ALOGE("%s: %s", __func__,
            pcm_get_error(my_plugin->adev_hostless.pcm_tx));
        return;
    }
    my_plugin->adev_hostless.pcm_rx = pcm_open(my_plugin->adev->snd_card,
                                   pcm_dev_rx,
                                   PCM_OUT, &pcm_config_lb);
    if (my_plugin->adev_hostless.pcm_rx &&
        !pcm_is_ready(my_plugin->adev_hostless.pcm_rx)) {
        ALOGE("%s: %s", __func__,
            pcm_get_error(my_plugin->adev_hostless.pcm_rx));
        return;
    }

    if (pcm_start(my_plugin->adev_hostless.pcm_tx) < 0) {
        ALOGE("%s: pcm start for pcm tx failed", __func__);
        return;
    }
    if (pcm_start(my_plugin->adev_hostless.pcm_rx) < 0) {
        ALOGE("%s: pcm start for pcm rx failed", __func__);
        return;
    }
}

static void ext_hw_plugin_disable_adev_hostless(void *plugin)
{
    struct ext_hw_plugin_data *my_plugin = (struct ext_hw_plugin_data *)plugin;

    ALOGI("%s: Disable TERT -> SEC Hostless", __func__);

    if (my_plugin->adev_hostless.pcm_tx) {
        pcm_close(my_plugin->adev_hostless.pcm_tx);
        my_plugin->adev_hostless.pcm_tx = NULL;
    }
    if (my_plugin->adev_hostless.pcm_rx) {
        pcm_close(my_plugin->adev_hostless.pcm_rx);
        my_plugin->adev_hostless.pcm_rx = NULL;
    }
}

void* ext_hw_plugin_init(struct audio_device *adev, ext_hw_plugin_init_config_t init_config)
{
    int32_t ret = 0;
@@ -170,7 +91,6 @@ void* ext_hw_plugin_init(struct audio_device *adev, ext_hw_plugin_init_config_t

    my_plugin->adev = adev;
    fp_audio_route_apply_and_update_path = init_config.fp_audio_route_apply_and_update_path;
    (void)audio_extn_auto_hal_enable_hostless();

    my_plugin->plugin_handle = dlopen(LIB_PLUGIN_DRIVER, RTLD_NOW);
    if (my_plugin->plugin_handle == NULL) {
@@ -209,7 +129,6 @@ void* ext_hw_plugin_init(struct audio_device *adev, ext_hw_plugin_init_config_t
            goto plugin_init_fail;
        }
    }
    ext_hw_plugin_enable_adev_hostless(my_plugin);
    my_plugin->mic_mute = false;
    return my_plugin;

@@ -229,7 +148,6 @@ int32_t ext_hw_plugin_deinit(void *plugin)
        ALOGE("[%s] NULL plugin pointer",__func__);
        return -EINVAL;
    }
    ext_hw_plugin_disable_adev_hostless(my_plugin);
    if (my_plugin->audio_hal_plugin_deinit) {
        ret = my_plugin->audio_hal_plugin_deinit();
        if (ret) {
@@ -240,8 +158,6 @@ int32_t ext_hw_plugin_deinit(void *plugin)
    if(my_plugin->plugin_handle != NULL)
        dlclose(my_plugin->plugin_handle);

    audio_extn_auto_hal_disable_hostless();

    free(my_plugin);
    return ret;
}
+34 −29
Original line number Diff line number Diff line
@@ -274,10 +274,42 @@ static int populate_usecase(struct audio_hal_usecase *usecase,

static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
{
    audio_event_info_t event;
    char value[32];
    int ret = 0;

    if (!parms)
        return;

    audio_extn_sound_trigger_set_parameters(NULL, parms);
    ret = str_parms_get_str(parms, "SND_CARD_STATUS", value,
                            sizeof(value));
    if (ret > 0) {
        if (strstr(value, "OFFLINE")) {
            event.u.status = SND_CARD_STATUS_OFFLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else if (strstr(value, "ONLINE")) {
            event.u.status = SND_CARD_STATUS_ONLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else
            ALOGE("%s: unknown snd_card_status", __func__);
    }

    ret = str_parms_get_str(parms, "CPE_STATUS", value, sizeof(value));
    if (ret > 0) {
        if (strstr(value, "OFFLINE")) {
            event.u.status = CPE_STATUS_OFFLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else if (strstr(value, "ONLINE")) {
            event.u.status = CPE_STATUS_ONLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else
            ALOGE("%s: unknown CPE status", __func__);
    }

    return;
}

@@ -630,34 +662,7 @@ void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
        return;
    }

    ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
                            sizeof(value));
    if (ret > 0) {
        if (strstr(value, "OFFLINE")) {
            event.u.status = SND_CARD_STATUS_OFFLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else if (strstr(value, "ONLINE")) {
            event.u.status = SND_CARD_STATUS_ONLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else
            ALOGE("%s: unknown snd_card_status", __func__);
    }

    ret = str_parms_get_str(params, "CPE_STATUS", value, sizeof(value));
    if (ret > 0) {
        if (strstr(value, "OFFLINE")) {
            event.u.status = CPE_STATUS_OFFLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else if (strstr(value, "ONLINE")) {
            event.u.status = CPE_STATUS_ONLINE;
            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
        }
        else
            ALOGE("%s: unknown CPE status", __func__);
    }
    stdev_snd_mon_cb(NULL, params);

    ret = str_parms_get_int(params, "SVA_NUM_SESSIONS", &val);
    if (ret >= 0) {
+21 −0
Original line number Diff line number Diff line
@@ -505,6 +505,10 @@ static int out_set_mmap_volume(struct audio_stream_out *stream, float left, floa
static int out_set_voip_volume(struct audio_stream_out *stream, float left, float right);
static int out_set_pcm_volume(struct audio_stream_out *stream, float left, float right);

static void adev_snd_mon_cb(void *cookie, struct str_parms *parms);
static void in_snd_mon_cb(void * stream, struct str_parms * parms);
static void out_snd_mon_cb(void * stream, struct str_parms * parms);

#ifdef AUDIO_FEATURE_ENABLED_GCOV
extern void  __gcov_flush();
static void enable_gcov()
@@ -8049,6 +8053,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    if (!parms)
        goto error;

    /* notify adev and input/output streams on the snd card status */
    adev_snd_mon_cb((void *)adev, parms);

    list_for_each(node, &adev->active_outputs_list) {
        streams_output_ctxt_t *out_ctxt = node_to_item(node,
                                            streams_output_ctxt_t,
                                            list);
        out_snd_mon_cb((void *)out_ctxt->output, parms);
    }

    list_for_each(node, &adev->active_inputs_list) {
        streams_input_ctxt_t *in_ctxt = node_to_item(node,
                                            streams_input_ctxt_t,
                                            list);
        in_snd_mon_cb((void *)in_ctxt->input, parms);
    }

    pthread_mutex_lock(&adev->lock);
    ret = str_parms_get_str(parms, "BT_SCO", value, sizeof(value));
    if (ret >= 0) {