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

Commit 88e6fb26 authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Eric Laurent
Browse files

hal: integrate ADM module



HAL dynamically loads the ADM module and registers all the input
and output streams and also notifies all read and write operarations.

authored-by: default avatarRavi Kumar Alamanda <ralama@codeaurora.org>

Bug: 10546170
Change-Id: Ie599f990c5d7224a6261e703c099fb98b5980c35
parent 2bc7b022
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -838,7 +838,10 @@ int start_input_stream(struct stream_in *in)
        break;
    }

    ALOGV("%s: pcm_prepare start", __func__);
    pcm_prepare(in->pcm);
    ALOGV("%s: exit", __func__);

    return ret;

error_open:
@@ -1174,6 +1177,10 @@ int start_output_stream(struct stream_out *out)
            }
            break;
        }
        ALOGV("%s: pcm_prepare start", __func__);
        if (pcm_is_ready(out->pcm))
            pcm_prepare(out->pcm);

    } else {
        out->pcm = NULL;
        out->compr = compress_open(adev->snd_card, out->pcm_device_id,
@@ -1315,6 +1322,9 @@ static int out_standby(struct audio_stream *stream)

    pthread_mutex_lock(&out->lock);
    if (!out->standby) {
        if (adev->adm_deregister_stream)
            adev->adm_deregister_stream(adev->adm_data, out->handle);

        pthread_mutex_lock(&adev->lock);
        out->standby = true;
        if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -1589,6 +1599,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
            out->standby = true;
            goto exit;
        }
        if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
            adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
    }

    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -1615,14 +1627,22 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
        if (out->pcm) {
            if (out->muted)
                memset((void *)buffer, 0, bytes);

            ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
            if (adev->adm_request_focus)
                adev->adm_request_focus(adev->adm_data, out->handle);

            if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
            }
            else
                ret = pcm_write(out->pcm, (void *)buffer, bytes);

            if (ret == 0)
                out->written += bytes / (out->config.channels * sizeof(short));

            if (adev->adm_abandon_focus)
                adev->adm_abandon_focus(adev->adm_data, out->handle);
        }
    }

@@ -1849,6 +1869,9 @@ static int in_standby(struct audio_stream *stream)
    }

    if (!in->standby) {
        if (adev->adm_deregister_stream)
            adev->adm_deregister_stream(adev->adm_data, in->capture_handle);

        pthread_mutex_lock(&adev->lock);
        in->standby = true;
        if (in->pcm) {
@@ -1950,8 +1973,13 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
            goto exit;
        }
        in->standby = 0;
        if (adev->adm_register_input_stream)
            adev->adm_register_input_stream(adev->adm_data, in->capture_handle, in->flags);
    }

    if (adev->adm_request_focus)
        adev->adm_request_focus(adev->adm_data, in->capture_handle);

    if (in->pcm) {
        if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
            ret = pcm_mmap_read(in->pcm, buffer, bytes);
@@ -1959,6 +1987,9 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
            ret = pcm_read(in->pcm, buffer, bytes);
    }

    if (adev->adm_abandon_focus)
        adev->adm_abandon_focus(adev->adm_data, in->capture_handle);

    /*
     * Instead of writing zeroes here, we could trust the hardware
     * to always provide zeroes when muted.
@@ -2518,6 +2549,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
    in->standby = 1;
    in->channel_mask = config->channel_mask;
    in->capture_handle = handle;
    in->flags = flags;

    /* Update config params with the requested sample rate and channels */
    if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
@@ -2743,10 +2775,13 @@ static int adev_close(hw_device_t *device)
        for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
            pcm_params_free(adev->use_case_table[i]);
        }
        if (adev->adm_deinit)
            adev->adm_deinit(adev->adm_data);
        free(device);
    }

    pthread_mutex_unlock(&adev_init_lock);

    return 0;
}

@@ -2873,6 +2908,29 @@ static int adev_open(const hw_module_t *module, const char *name,
        }
    }

    if (access(ADM_LIBRARY_PATH, R_OK) == 0) {
        adev->adm_lib = dlopen(ADM_LIBRARY_PATH, RTLD_NOW);
        if (adev->adm_lib == NULL) {
            ALOGE("%s: DLOPEN failed for %s", __func__, ADM_LIBRARY_PATH);
        } else {
            ALOGV("%s: DLOPEN successful for %s", __func__, ADM_LIBRARY_PATH);
            adev->adm_init = (adm_init_t)
                                    dlsym(adev->adm_lib, "adm_init");
            adev->adm_deinit = (adm_deinit_t)
                                    dlsym(adev->adm_lib, "adm_deinit");
            adev->adm_register_input_stream = (adm_register_input_stream_t)
                                    dlsym(adev->adm_lib, "adm_register_input_stream");
            adev->adm_register_output_stream = (adm_register_output_stream_t)
                                    dlsym(adev->adm_lib, "adm_register_output_stream");
            adev->adm_deregister_stream = (adm_deregister_stream_t)
                                    dlsym(adev->adm_lib, "adm_deregister_stream");
            adev->adm_request_focus = (adm_request_focus_t)
                                    dlsym(adev->adm_lib, "adm_request_focus");
            adev->adm_abandon_focus = (adm_abandon_focus_t)
                                    dlsym(adev->adm_lib, "adm_abandon_focus");
        }
    }

    adev->bt_wb_speech_enabled = false;
    adev->enable_voicerx = false;

@@ -2902,6 +2960,9 @@ static int adev_open(const hw_module_t *module, const char *name,
    audio_device_ref_count++;
    pthread_mutex_unlock(&adev_init_lock);

    if (adev->adm_init)
        adev->adm_data = adev->adm_init();

    ALOGV("%s: exit", __func__);
    return 0;
}
+20 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@

#define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so"
#define OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH "/system/lib/soundfx/libqcompostprocbundle.so"
#define ADM_LIBRARY_PATH "/system/vendor/lib/libadm.so"

/* Flags used to initialize acdb_settings variable that goes to ACDB library */
#define DMIC_FLAG       0x00000002
@@ -174,6 +175,7 @@ struct stream_in {
    bool enable_ns;

    audio_io_handle_t capture_handle;
    audio_input_flags_t flags;
    bool is_st_session;
    bool is_st_session_active;

@@ -202,6 +204,14 @@ struct audio_usecase {
    union stream_ptr stream;
};

typedef void* (*adm_init_t)();
typedef void (*adm_deinit_t)(void *);
typedef void (*adm_register_output_stream_t)(void *, audio_io_handle_t, audio_output_flags_t);
typedef void (*adm_register_input_stream_t)(void *, audio_io_handle_t, audio_input_flags_t);
typedef void (*adm_deregister_stream_t)(void *, audio_io_handle_t);
typedef void (*adm_request_focus_t)(void *, audio_io_handle_t);
typedef void (*adm_abandon_focus_t)(void *, audio_io_handle_t);

struct audio_device {
    struct audio_hw_device device;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
@@ -241,6 +251,16 @@ struct audio_device {
    void *offload_effects_lib;
    int (*offload_effects_start_output)(audio_io_handle_t, int);
    int (*offload_effects_stop_output)(audio_io_handle_t, int);

    void *adm_data;
    void *adm_lib;
    adm_init_t adm_init;
    adm_deinit_t adm_deinit;
    adm_register_input_stream_t adm_register_input_stream;
    adm_register_output_stream_t adm_register_output_stream;
    adm_deregister_stream_t adm_deregister_stream;
    adm_request_focus_t adm_request_focus;
    adm_abandon_focus_t adm_abandon_focus;
};

int select_devices(struct audio_device *adev,