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

Commit 57411a5d authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: support zone control for ecns-hfp calls"

parents e0f9b827 1d46f347
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -121,6 +121,13 @@ struct audio_effect_config {
    uint32_t param_value;
};

struct audio_fluence_mmsecns_config {
    uint32_t topology_id;
    uint32_t module_id;
    uint32_t instance_id;
    uint32_t param_id;
};

#define MAX_MIXER_PATH_LEN 64

typedef enum card_status_t {
+190 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@
#define AUDIO_PARAMETER_KEY_DP_FOR_VOICE_USECASE "dp_for_voice"
#define AUDIO_PARAMETER_KEY_DP_CHANNEL_MASK "dp_channel_mask"
#define AUDIO_PARAMETER_KEY_SPKR_DEVICE_CHMAP "spkr_device_chmap"
#define AUDIO_PARAMETER_KEY_HFP_ZONE "hfp_zone"

#define EVENT_EXTERNAL_SPK_1 "qc_ext_spk_1"
#define EVENT_EXTERNAL_SPK_2 "qc_ext_spk_2"
@@ -774,6 +775,9 @@ static struct audio_effect_config effect_config_table[GET_IN_DEVICE_INDEX(SND_DE
    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)][EFFECT_NS] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x02},
};

static struct audio_fluence_mmsecns_config fluence_mmsecns_table = {TOPOLOGY_ID_MM_HFP_ECNS, MODULE_ID_MM_HFP_ECNS,
                                                                    INSTANCE_ID_MM_HFP_ECNS, PARAM_ID_MM_HFP_ZONE};

/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_NONE] = -1,
@@ -4628,6 +4632,26 @@ void platform_add_external_specific_device(snd_device_t snd_device,
            platform_get_snd_device_name(snd_device), usbid, acdb_id);
}

static int platform_get_fluence_mmsecns_config_data(struct audio_fluence_mmsecns_config *fluence_mmsecns_config)
{
    int ret = 0;

    if (fluence_mmsecns_config == NULL) {
        ALOGE("%s: Invalid fluence_mmsecns_config", __func__);
        ret = -EINVAL;
        goto done;
    }

    ALOGV("%s: topology_id = 0x%x, module_id = 0x%x, instance_id = 0x%x, param_id = 0x%x",
           __func__, fluence_mmsecns_table.topology_id, fluence_mmsecns_table.module_id,
           fluence_mmsecns_table.instance_id, fluence_mmsecns_table.param_id);
    memcpy(fluence_mmsecns_config, &fluence_mmsecns_table,
           sizeof(struct audio_fluence_mmsecns_config));

done:
    return ret;
}

int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
    int ret = 0;
@@ -4669,6 +4693,18 @@ done:
    return ret;
}

int platform_set_fluence_mmsecns_config(struct audio_fluence_mmsecns_config fluence_mmsecns_config)
{
    int ret = 0;

    ALOGV("%s: topology_id = 0x%x, module_id = 0x%x, instance_id = 0x%x, param_id = 0x%x",
           __func__, fluence_mmsecns_config.topology_id, fluence_mmsecns_config.module_id,
           fluence_mmsecns_config.instance_id, fluence_mmsecns_config.param_id);
    fluence_mmsecns_table = fluence_mmsecns_config;

    return ret;
}

int platform_set_acdb_metainfo_key(void *platform, char *name, int key)
{
    struct meta_key_list *key_info;
@@ -7334,6 +7370,141 @@ static int update_external_device_status(struct platform_data *my_data,
    return ret;
}

static int platform_set_hfp_zone(struct platform_data *my_data, uint32_t zone)
{
    int ret = 0;
    int acdb_dev_id = -1;
    struct audio_usecase *usecase = NULL;
    struct audio_device *adev = (struct audio_device *)(my_data->adev);
    struct audio_fluence_mmsecns_config fluence_mmsecns_config;
    acdb_audio_cal_cfg_t cal = {0};
    ALOGV("Setting HFP Zone: %d", zone);

    /* Zone control is available only when EC car state is set. */
    if (!platform_get_eccarstate((void *) my_data)) {
        ALOGE("%s: EC State should be enabled first.", __func__);
        return -EINVAL;
    }

    usecase = get_usecase_from_list(adev, audio_extn_hfp_get_usecase());
    if (usecase == NULL) {
        ALOGE("%s: Could not find the usecase.", __func__);
        return -EINVAL;
    }

    acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(usecase->in_snd_device)];
    if (acdb_dev_id < 0) {
        ALOGE("%s: Could not find acdb id for device(%d)",
              __func__, usecase->in_snd_device);
        return -EINVAL;
    }

    if (platform_get_fluence_mmsecns_config_data(&fluence_mmsecns_config) < 0) {
        ALOGE("%s: Failed to get fluence mmsecns config data.", __func__);
        return -EINVAL;
    }

    cal.acdb_dev_id = acdb_dev_id;
    cal.app_type = DEFAULT_APP_TYPE_TX_PATH;
    cal.topo_id = fluence_mmsecns_config.topology_id;
    cal.module_id = fluence_mmsecns_config.module_id;
    cal.instance_id = fluence_mmsecns_config.instance_id;
    cal.param_id = fluence_mmsecns_config.param_id;

    if (my_data->acdb_set_audio_cal) {
        ret = my_data->acdb_set_audio_cal((void *)&cal, (void *)&zone, sizeof(uint32_t));
    }

    if (ret < 0)
        ALOGE("%s: Could not set hfp zone calibration to zone %d",
              __func__, zone);
    else
        ALOGV("%s: Successfully set hfp zone calibration to zone %d",
              __func__, zone);

    return ret;
}

static int platform_get_hfp_zone(struct platform_data *my_data)
{
    int ret = 0;
    int acdb_dev_id = -1;
    struct audio_usecase *usecase = NULL;
    struct audio_device *adev = (struct audio_device *)(my_data->adev);
    struct audio_fluence_mmsecns_config fluence_mmsecns_config;
    acdb_audio_cal_cfg_t cal = {0};
    uint8_t *dptr = NULL;
    uint32_t zone = 0;
    uint32_t param_len = MAX_SET_CAL_BYTE_SIZE;
    ALOGV("Getting HFP Zone");

    /* Zone control is available only when EC car state is set. */
    if (!platform_get_eccarstate((void *) my_data)) {
        ALOGE("%s: EC State should be enabled first.", __func__);
        return -EINVAL;
    }

    usecase = get_usecase_from_list(adev, audio_extn_hfp_get_usecase());
    if (usecase == NULL) {
        ALOGE("%s: Could not find the usecase.", __func__);
        return -EINVAL;
    }

    acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(usecase->in_snd_device)];
    if (acdb_dev_id < 0) {
        ALOGE("%s: Could not find acdb id for device(%d)",
              __func__, usecase->in_snd_device);
        return -EINVAL;
    }

    if (platform_get_fluence_mmsecns_config_data(&fluence_mmsecns_config) < 0) {
        ALOGE("%s: Failed to get fluence mmsecns config data.", __func__);
        return -EINVAL;
    }

    cal.acdb_dev_id = acdb_dev_id;
    cal.app_type = DEFAULT_APP_TYPE_TX_PATH;
    cal.topo_id = fluence_mmsecns_config.topology_id;
    cal.module_id = fluence_mmsecns_config.module_id;
    cal.instance_id = fluence_mmsecns_config.instance_id;
    cal.param_id = fluence_mmsecns_config.param_id;

    dptr = (uint8_t*)calloc(param_len, sizeof(uint8_t));
    if (!dptr) {
        ALOGE("%s: Failed to allocate memory.", __func__);
        return -ENOMEM;
    }

    if (my_data->acdb_get_audio_cal) {
        ret = my_data->acdb_get_audio_cal((void *)&cal, (void *)dptr, &param_len);
        if (ret == 0) {
            if ((param_len == 0) || (param_len == MAX_SET_CAL_BYTE_SIZE)) {
                ret = -EINVAL;
            } else if (param_len > 16) {
                /* returned data structure:
                 *  u32 module_id
                 *  u32 instance_id
                 *  u32 parameter_id
                 *  u32 payload_size
                 *  u8  payload[payload_size]
                 */
                zone = *(uint32_t *)(dptr + 16);
            }
        }
    }

    if (ret < 0)
        ALOGE("%s: Could not get hfp zone calibration to zone %d",
              __func__, zone);
    else
        ALOGV("%s: Successfully get hfp zone calibration to zone %d",
              __func__, zone);

    if (dptr)
        free(dptr);
    return zone;
}

static int parse_audiocal_cfg(struct str_parms *parms, acdb_audio_cal_cfg_t *cal)
{
    int err;
@@ -7832,6 +8003,18 @@ int platform_set_parameters(void *platform, struct str_parms *parms)
        ALOGV("%s: max_mic_count %d", __func__, my_data->max_mic_count);
    }

    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HFP_ZONE,
                            value, len);
    if (err >= 0) {
        uint32_t zone = atoi(value);

        str_parms_del(parms, AUDIO_PARAMETER_KEY_HFP_ZONE);
        if (zone > 6)
            ALOGE("%s: Only Zones 0 through 6 are supported", __func__);
        else
            platform_set_hfp_zone(my_data, zone);
    }

    platform_set_fluence_params(platform, parms, value, len);

    /* handle audio calibration parameters */
@@ -8160,6 +8343,13 @@ void platform_get_parameters(void *platform,
        }
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HFP_ZONE,
                            value, sizeof(value));
    if (ret >= 0) {
        snprintf(value, sizeof(value), "%d", platform_get_hfp_zone(my_data));
        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HFP_ZONE, value);
    }

    /* Handle audio calibration keys */
    get_audiocal(platform, query, reply);
    native_audio_get_params(query, reply, value, sizeof(value));
+6 −0
Original line number Diff line number Diff line
@@ -696,6 +696,12 @@ enum {
#define TX_VOICE_FLUENCE_SM_SB 0x10F38
#define TX_VOICE_FLUENCE_MM_SB 0x10F39

/* multi-mic surround ECNS zone control */
#define TOPOLOGY_ID_MM_HFP_ECNS 0x1FFF0002
#define MODULE_ID_MM_HFP_ECNS   0x10F3B
#define PARAM_ID_MM_HFP_ZONE    0x109F0
#define INSTANCE_ID_MM_HFP_ECNS 0x8000

#define LIB_CSD_CLIENT "libcsd-client.so"

#define AUDIO_MAKE_STRING_FROM_ENUM(X)   { #X, X }
+1 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ int platform_set_effect_config_data(snd_device_t snd_device,
int platform_get_effect_config_data(snd_device_t snd_device,
                                      struct audio_effect_config *effect_config,
                                      effect_type_t effect_type);
int platform_set_fluence_mmsecns_config(struct audio_fluence_mmsecns_config fluence_mmsecns_config);
int platform_get_snd_device_bit_width(snd_device_t snd_device);
int platform_set_acdb_metainfo_key(void *platform, char *name, int key);
void platform_release_acdb_metainfo_key(void *platform);
+69 −2
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ typedef enum {
    EXTERNAL_DEVICE_SPECIFIC,
    CUSTOM_MTMX_IN_PARAMS,
    CUSTOM_MTMX_PARAM_IN_CH_INFO,
    MMSECNS,
} section_t;

typedef void (* section_process_fn)(const XML_Char **attr);
@@ -102,6 +103,7 @@ static void process_custom_mtmx_param_coeffs(const XML_Char **attr);
static void process_external_dev(const XML_Char **attr);
static void process_custom_mtmx_in_params(const XML_Char **attr);
static void process_custom_mtmx_param_in_ch_info(const XML_Char **attr);
static void process_fluence_mmsecns(const XML_Char **attr);

static section_process_fn section_table[] = {
    [ROOT] = process_root,
@@ -125,6 +127,7 @@ static section_process_fn section_table[] = {
    [EXTERNAL_DEVICE_SPECIFIC] = process_external_dev,
    [CUSTOM_MTMX_IN_PARAMS] = process_custom_mtmx_in_params,
    [CUSTOM_MTMX_PARAM_IN_CH_INFO] = process_custom_mtmx_param_in_ch_info,
    [MMSECNS] = process_fluence_mmsecns,
};

static section_t section;
@@ -550,7 +553,6 @@ static void process_audio_effect(const XML_Char **attr, effect_type_t effect_typ
                                                 strtol((char *)attr[7], NULL, 0),
                                                 strtol((char *)attr[9], NULL, 0)};


    if (platform_set_effect_config_data(index, effect_config, effect_type) < 0) {
        ALOGE("%s: Effect = %d Device %s, MODULE/INSTANCE/PARAM ID %lu %lu %lu %lu was not set!",
              __func__, effect_type, attr[1], strtol((char *)attr[3], NULL, 0),
@@ -575,6 +577,63 @@ static void process_effect_ns(const XML_Char **attr)
    return;
}

static void process_fluence_mmsecns(const XML_Char **attr)
{
    int index;
    struct audio_fluence_mmsecns_config fluence_mmsecns_config;

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

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

    if (strcmp(attr[2], "topology_id") != 0) {
        ALOGE("%s: Device %s in platform info xml has no topology_id, no MODULE ID set!",
              __func__, attr[2]);
        goto done;
    }

    if (strcmp(attr[4], "module_id") != 0) {
        ALOGE("%s: Device %s in platform info xml has no module_id, no MODULE ID set!",
              __func__, attr[4]);
        goto done;
    }

    if (strcmp(attr[6], "instance_id") != 0) {
        ALOGE("%s: Device %s in platform info xml has no instance_id, no INSTANCE ID set!",
              __func__, attr[6]);
        goto done;
    }

    if (strcmp(attr[8], "param_id") != 0) {
        ALOGE("%s: Device %s in platform info xml has no param_id, no PARAM ID set!",
              __func__, attr[8]);
        goto done;
    }

    fluence_mmsecns_config = (struct audio_fluence_mmsecns_config){strtol((char *)attr[3], NULL, 0),
                                                                   strtol((char *)attr[5], NULL, 0),
                                                                   strtol((char *)attr[7], NULL, 0),
                                                                   strtol((char *)attr[9], NULL, 0)};


    if (platform_set_fluence_mmsecns_config(fluence_mmsecns_config) < 0) {
        ALOGE("%s: Device %s, TOPOLOGY/MODULE/INSTANCE/PARAM ID %lu %lu %lu %lu was not set!",
              __func__, attr[1], strtol((char *)attr[3], NULL, 0), strtol((char *)attr[5], NULL, 0),
              strtol((char *)attr[7], NULL, 0), strtol((char *)attr[9], NULL, 0));
        goto done;
    }

done:
    return;
}
static void process_bit_width(const XML_Char **attr)
{
    int index;
@@ -1238,7 +1297,7 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
        } else if (strcmp(tag_name, "snd_devices") == 0) {
            section = SND_DEVICES;
        } else if (strcmp(tag_name, "device") == 0) {
            if ((section != ACDB) && (section != AEC) && (section != NS) &&
            if ((section != ACDB) && (section != AEC) && (section != NS) && (section != MMSECNS) &&
                (section != BACKEND_NAME) && (section != BITWIDTH) &&
                (section != INTERFACE_NAME) && (section != OPERATOR_SPECIFIC)) {
                ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
@@ -1284,6 +1343,12 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
                return;
            }
            section = NS;
        } else if (strcmp(tag_name, "mmsecns") == 0) {
            if (section != MODULE) {
                ALOGE("mmsecns tag only supported with MODULE section");
                return;
            }
            section = MMSECNS;
        } else if (strcmp(tag_name, "gain_level_map") == 0) {
            if (section != GAIN_LEVEL_MAPPING) {
                ALOGE("gain_level_map tag only supported with GAIN_LEVEL_MAPPING section");
@@ -1403,6 +1468,8 @@ static void end_tag(void *userdata __unused, const XML_Char *tag_name)
        section = MODULE;
    } else if (strcmp(tag_name, "ns") == 0) {
        section = MODULE;
    } else if (strcmp(tag_name, "mmsecns") == 0) {
        section = MODULE;
    } else if (strcmp(tag_name, "pcm_ids") == 0) {
        section = ROOT;
    } else if (strcmp(tag_name, "backend_names") == 0) {