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

Commit f44af122 authored by Dhanalakshmi Siddani's avatar Dhanalakshmi Siddani Committed by Gerrit - the friendly Code Review server
Browse files

audio: HAL to support for peripheral manager

- Peripheral manager takes care of modem/adsp image loading/unloading

- Add support to register with PM and call subsystem_put to unload
  modem/adsp image to transfer the control to PM

Change-Id: I6fccff8821f737790f040751aaa03584006a23a1
parent 7ac445ae
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -186,6 +186,13 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUXPCM_BT)),true)
    LOCAL_CFLAGS += -DAUXPCM_BT_ENABLED
endif

ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PM_SUPPORT)),true)
    LOCAL_CFLAGS += -DPM_SUPPORT_ENABLED
    LOCAL_SRC_FILES += audio_extn/pm.c
    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libperipheralclient/inc
    LOCAL_SHARED_LIBRARIES += libperipheral_client
endif

LOCAL_COPY_HEADERS_TO   := mm-audio
LOCAL_COPY_HEADERS      := audio_extn/audio_defs.h

+1 −0
Original line number Diff line number Diff line
@@ -462,6 +462,7 @@ void audio_extn_set_parameters(struct audio_device *adev,
   audio_extn_hfp_set_parameters(adev, parms);
   audio_extn_ddp_set_parameters(adev, parms);
   audio_extn_customstereo_set_parameters(adev, parms);
   audio_extn_pm_set_parameters(parms);
}

void audio_extn_get_parameters(const struct audio_device *adev,
+10 −0
Original line number Diff line number Diff line
@@ -300,6 +300,16 @@ int audio_extn_dev_arbi_acquire(snd_device_t snd_device);
int audio_extn_dev_arbi_release(snd_device_t snd_device);
#endif

#ifndef PM_SUPPORT_ENABLED
#define audio_extn_pm_set_parameters(params) (0)
#define audio_extn_pm_vote(void) (0)
#define audio_extn_pm_unvote(void) (0)
#else
void audio_extn_pm_set_parameters(struct str_parms *parms);
int audio_extn_pm_vote (void);
void audio_extn_pm_unvote(void);
#endif

void audio_extn_utils_update_streams_output_cfg_list(void *platform,
                                  struct mixer *mixer,
                                  struct listnode *streams_output_cfg_list);

hal/audio_extn/pm.c

0 → 100644
+149 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#define LOG_TAG "audio_hw_pm"
/*#define LOG_NDEBUG 0*/

#include "pm.h"
#include <cutils/log.h>

static s_audio_subsys audio_ss;

int audio_extn_pm_vote(void)
{
    int err, intfd, ret;
    FILE *fd;
    enum pm_event subsys_state;
    char halPropVal[PROPERTY_VALUE_MAX];
    bool prop_unload_image = false;
    bool pm_reg = false;
    bool pm_supp = false;

    platform_get_subsys_image_name((char *)&audio_ss.img_name);
    ALOGD("%s: register with peripheral manager for %s",__func__, audio_ss.img_name);
    ret = pm_client_register(audio_extn_pm_event_notifier,
                      &audio_ss,
                      audio_ss.img_name,
                      PM_CLIENT_NAME,
                      &subsys_state,
                      &audio_ss.pm_handle);
    if (ret == PM_RET_SUCCESS) {
        pm_reg = true;
        pm_supp = true;
        ALOGV("%s: registered with peripheral manager for %s",
                  __func__, audio_ss.img_name);
    } else if (ret == PM_RET_UNSUPPORTED) {
        pm_reg = true;
        pm_supp = false;
        ALOGV("%s: peripheral mgr unsupported for %s",
              __func__, audio_ss.img_name);
        return ret;
    } else {
       return ret;
    }
    if (pm_supp == true &&
       pm_reg == true) {
       ALOGD("%s: Voting for subsystem power up", __func__);
       pm_client_connect(audio_ss.pm_handle);

       if (property_get("sys.audio.init", halPropVal, NULL)) {
           prop_unload_image = !(strncmp("false", halPropVal, sizeof("false")));
       }
       /*
        * adsp-loader loads modem/adsp image at boot up to play boot tone,
        * before peripheral manager service is up. Once PM is up, vote to PM
        * and unload the image to give control to PM to load/unload image
        */
       if (prop_unload_image) {
           intfd = open(BOOT_IMG_SYSFS_PATH, O_WRONLY);
           if (intfd == -1) {
               ALOGE("failed to open fd in write mode, %d", errno);
           } else {
               ALOGD("%s: write to sysfs to unload image", __func__);
               err = write(intfd, UNLOAD_IMAGE, 1);
               close(intfd);
               property_set("sys.audio.init", "true");
          }
       }
    }
    return 0;
}

void audio_extn_pm_unvote(void)
{
    ALOGD("%s", __func__);
    if (audio_ss.pm_handle) {
        pm_client_disconnect(audio_ss.pm_handle);
        pm_client_unregister(audio_ss.pm_handle);
    }
}

void audio_extn_pm_set_parameters(struct str_parms *parms)
{
    int ret;
    char value[32];

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DEV_SHUTDOWN, value, sizeof(value));
    if (ret >= 0) {
        if (strstr(value, "true")) {
            ALOGD("Device shutdown notification received, unregister with PM");
            audio_extn_pm_unvote();
        }
    }
}

void audio_extn_pm_event_notifier(void *client_data, enum pm_event event)
{
    pm_client_event_acknowledge(audio_ss.pm_handle, event);

    /* Closing and re-opening of session is done based on snd card status given
     * by AudioDaemon during SS offline/online (legacy code). Just return for now.
     */
    switch (event) {
    case EVENT_PERIPH_GOING_OFFLINE:
        ALOGV("%s: %s is going offline", __func__, audio_ss.img_name);
    break;

    case EVENT_PERIPH_IS_OFFLINE:
        ALOGV("%s: %s is offline", __func__, audio_ss.img_name);
    break;

    case EVENT_PERIPH_GOING_ONLINE:
        ALOGV("%s: %s is going online", __func__, audio_ss.img_name);
    break;

    case EVENT_PERIPH_IS_ONLINE:
        ALOGV("%s: %s is online", __func__, audio_ss.img_name);
    break;

    default:
        ALOGV("%s: invalid event received from PM", __func__);
    break;
    }
}

hal/audio_extn/pm.h

0 → 100644
+68 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef AUDIO_EXTN_PM_H
#define AUDIO_EXTN_PM_H

#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pm-service.h>
#include "audio_hw.h"
#include <platform.h>
#include <cutils/properties.h>
#include <cutils/log.h>


/* Client name to be registered with PM */
#define PM_CLIENT_NAME "audio"
/* Command to sysfs to unload image */
#define UNLOAD_IMAGE "0"
#define MAX_NAME_LEN 32
#define BOOT_IMG_SYSFS_PATH "/sys/kernel/boot_adsp/boot"

typedef struct {
    //MAX_NAME_LEN defined in mdm_detect.h
    char img_name[MAX_NAME_LEN];
    //this handle is used by peripheral mgr
    void *pm_handle;
}s_audio_subsys;

/* Vote to peripheral manager for required subsystem */
int audio_extn_pm_vote (void);

/* Unvote to peripheral manager */
void audio_extn_pm_unvote (void);

/* Get subsytem status notification from PM */
void audio_extn_pm_event_notifier (void *client_data, enum pm_event event);

#endif // AUDIO_EXTN_PM_H
Loading