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

Commit 5bc18845 authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Eric Laurent
Browse files

hal: Add XML parser for platform info

change 1
Add XML parser which parses the platform_info.xml
on the device. That xml contains ACDB ID information
and is populated from the device project folder to
the /etc folder on the device. It is used to overwrite
hardcoded ACDB ID's in platform.c.

change 2
Move platform_parser to root hal directory. Rename
platform_parser to platform_info. Change name of
XML file read from platform_info.xml to
audio_platform_info.xml. The xml now only needs
information for ACDB ID's that you want overwritten.
Names in the XML now match sound device enums in
platform.c.

(cherry-picked from CAF commits
61764e3b, 5588688c)

Change-Id: Ie5978f609bbe9d60a64e20a0906d6bd7a8c48e1b
parent fdf296a3
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ endif
LOCAL_SRC_FILES := \
	audio_hw.c \
	voice.c \
	platform_info.c \
	$(AUDIO_PLATFORM)/platform.c

LOCAL_SHARED_LIBRARIES := \
@@ -29,7 +30,8 @@ LOCAL_SHARED_LIBRARIES := \
	libtinyalsa \
	libtinycompress \
	libaudioroute \
	libdl
	libdl \
	libexpat

LOCAL_C_INCLUDES += \
	external/tinyalsa/include \
@@ -38,7 +40,8 @@ LOCAL_C_INCLUDES += \
	$(call include-path-for, audio-effects) \
	$(LOCAL_PATH)/$(AUDIO_PLATFORM) \
	$(LOCAL_PATH)/audio_extn \
	$(LOCAL_PATH)/voice_extn
	$(LOCAL_PATH)/voice_extn \
	external/expat/lib

ifneq ($(filter msm8084,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_SHARED_LIBRARIES += libmdmdetect
+10 −0
Original line number Diff line number Diff line
@@ -405,6 +405,16 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
    return device_id;
}

int platform_get_snd_device_index(char *snd_device_index_name)
{
    return -ENODEV;
}

int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
    return -ENODEV;
}

int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
{
    struct platform_data *my_data = (struct platform_data *)platform;
+86 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
};

/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
static const int acdb_device_table[SND_DEVICE_MAX] = {
static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_NONE] = -1,
    [SND_DEVICE_OUT_HANDSET] = 7,
    [SND_DEVICE_OUT_SPEAKER] = 15,
@@ -221,6 +221,47 @@ static const int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5,
};

struct snd_device_index {
    char name[100];
    unsigned int index;
};

#define TO_NAME_INDEX(X)   #X, X

/* Used to get index from parsed sting */
struct snd_device_index snd_device_name_index[SND_DEVICE_MAX] = {
    {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
};

#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)

@@ -576,6 +617,10 @@ void *platform_init(struct audio_device *adev)
        else
            my_data->acdb_init();
#endif

        /* Initialize ACDB ID's */
        /* Comment - does it make sense to init if acdb handle is NULL */
        platform_info_init();
    }

    /* load csd client */
@@ -642,6 +687,46 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
    return device_id;
}

int platform_get_snd_device_index(char *snd_device_index_name)
{
    int ret = 0;
    int i;

    if (snd_device_index_name == NULL) {
        ALOGE("%s: snd_device_index_name is NULL", __func__);
        ret = -ENODEV;
        goto done;
    }

    for (i=0; i < SND_DEVICE_MAX; i++) {
        if(strcmp(snd_device_name_index[i].name, snd_device_index_name) == 0) {
            ret = snd_device_name_index[i].index;
            goto done;
        }
    }
    ALOGE("%s: Could not find index for snd_device_index_name = %s",
            __func__, snd_device_index_name);
    ret = -ENODEV;
done:
    return ret;
}

int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
    int ret = 0;

    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
        ALOGE("%s: Invalid snd_device = %d",
            __func__, snd_device);
        ret = -EINVAL;
        goto done;
    }

    acdb_device_table[snd_device] = acdb_id;
done:
    return ret;
}

int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
{
    struct platform_data *my_data = (struct platform_data *)platform;
+8 −3
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@
 * limitations under the License.
 */

#ifndef QCOM_AUDIO_PLATFORM_API_H
#define QCOM_AUDIO_PLATFORM_API_H
#ifndef AUDIO_PLATFORM_API_H
#define AUDIO_PLATFORM_API_H

void *platform_init(struct audio_device *adev);
void platform_deinit(void *platform);
@@ -23,6 +23,8 @@ const char *platform_get_snd_device_name(snd_device_t snd_device);
void platform_add_backend_name(void *platform, char *mixer_path,
                                                    snd_device_t snd_device);
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type);
int platform_get_snd_device_index(char *snd_device_index_name);
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id);
int platform_send_audio_calibration(void *platform, snd_device_t snd_device);
int platform_switch_voice_call_device_pre(void *platform);
int platform_switch_voice_call_enable_device_config(void *platform,
@@ -54,4 +56,7 @@ int platform_stop_incall_recording_usecase(void *platform);
int platform_start_incall_music_usecase(void *platform);
int platform_stop_incall_music_usecase(void *platform);

#endif // QCOM_AUDIO_PLATFORM_API_H
/* From platform_info_parser.c */
int platform_info_init(void);

#endif // AUDIO_PLATFORM_API_H

hal/platform_info.c

0 → 100644
+139 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#define LOG_TAG "platform_info"
#define LOG_NDDEBUG 0

#include <errno.h>
#include <stdio.h>
#include <expat.h>
#include <cutils/log.h>
#include <audio_hw.h>
#include "platform_api.h"
#include <platform.h>

#define PLATFORM_INFO_XML_PATH      "/system/etc/audio_platform_info.xml"

static void process_device(const XML_Char **attr)
{
    int index;

    if (strcmp(attr[0], "name") != 0) {
        ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
        goto done;
    }

    index = platform_get_snd_device_index((char *)attr[1]);
    if (index < 0) {
        ALOGE("%s: Device %s in %s not found, no ACDB ID set!",
              __func__, attr[1], PLATFORM_INFO_XML_PATH);
        goto done;
    }

    if (strcmp(attr[2], "acdb_id") != 0) {
        ALOGE("%s: Device %s in %s has no acdb_id, no ACDB ID set!",
              __func__, attr[1], PLATFORM_INFO_XML_PATH);
        goto done;
    }

    if(platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) {
        ALOGE("%s: Device %s in %s, ACDB ID %d was not set!",
              __func__, attr[1], PLATFORM_INFO_XML_PATH, atoi((char *)attr[3]));
        goto done;
    }

done:
    return;
}

static void start_tag(void *userdata __unused, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char              *attr_name = NULL;
    const XML_Char              *attr_value = NULL;
    unsigned int                i;

    if (strcmp(tag_name, "device") == 0)
        process_device(attr);

    return;
}

static void end_tag(void *userdata __unused, const XML_Char *tag_name __unused)
{

}

int platform_info_init(void)
{
    XML_Parser      parser;
    FILE            *file;
    int             ret = 0;
    int             bytes_read;
    void            *buf;
    static const uint32_t kBufSize = 1024;

    file = fopen(PLATFORM_INFO_XML_PATH, "r");
    if (!file) {
        ALOGD("%s: Failed to open %s, using defaults.",
            __func__, PLATFORM_INFO_XML_PATH);
        ret = -ENODEV;
        goto done;
    }

    parser = XML_ParserCreate(NULL);
    if (!parser) {
        ALOGE("%s: Failed to create XML parser!", __func__);
        ret = -ENODEV;
        goto err_close_file;
    }

    XML_SetElementHandler(parser, start_tag, end_tag);

    while (1) {
        buf = XML_GetBuffer(parser, kBufSize);
        if (buf == NULL) {
            ALOGE("%s: XML_GetBuffer failed", __func__);
            ret = -ENOMEM;
            goto err_free_parser;
        }

        bytes_read = fread(buf, 1, kBufSize, file);
        if (bytes_read < 0) {
            ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
             ret = bytes_read;
            goto err_free_parser;
        }

        if (XML_ParseBuffer(parser, bytes_read,
                            bytes_read == 0) == XML_STATUS_ERROR) {
            ALOGE("%s: XML_ParseBuffer failed, for %s",
                __func__, PLATFORM_INFO_XML_PATH);
            ret = -EINVAL;
            goto err_free_parser;
        }

        if (bytes_read == 0)
            break;
    }

err_free_parser:
    XML_ParserFree(parser);
err_close_file:
    fclose(file);
done:
    return ret;
}