14765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/*
24765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
34765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *
44765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Redistribution and use in source and binary forms, with or without
54765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * modification, are permitted provided that the following conditions are
64765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * met:
74765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *   * Redistributions of source code must retain the above copyright
84765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *     notice, this list of conditions and the following disclaimer.
94765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *   * Redistributions in binary form must reproduce the above
104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *     copyright notice, this list of conditions and the following
114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *     disclaimer in the documentation and/or other materials provided
124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *     with the distribution.
134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *     contributors may be used to endorse or promote products derived
154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *     from this software without specific prior written permission.
164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *
174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
299746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_TAG "alsa_ucm"
30295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani//#define LOG_NDDEBUG 0
314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#ifdef ANDROID
334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* definitions for Android logging */
344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <utils/Log.h>
354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <cutils/properties.h>
364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#else /* ANDROID */
374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <math.h>
384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define strlcat g_strlcat
394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define strlcpy g_strlcpy
404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ALOGI(...)      fprintf(stdout, __VA_ARGS__)
414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ALOGE(...)      fprintf(stderr, __VA_ARGS__)
424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ALOGV(...)      fprintf(stderr, __VA_ARGS__)
434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ALOGD(...)      fprintf(stderr, __VA_ARGS__)
444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif /* ANDROID */
454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdio.h>
474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdlib.h>
484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <fcntl.h>
494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdarg.h>
504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <string.h>
514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <errno.h>
524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <unistd.h>
534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <pthread.h>
544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <ctype.h>
554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/stat.h>
564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/ioctl.h>
574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/mman.h>
584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/time.h>
594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/poll.h>
604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdint.h>
615ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani#include <dlfcn.h>
624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <linux/ioctl.h>
644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "msm8960_use_cases.h"
654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#if defined(QC_PROP)
665ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani    static void (*acdb_send_audio_cal)(int,int);
675ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani    static void (*acdb_send_voice_cal)(int,int);
684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define PARSE_DEBUG 0
704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Create an identifier
734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * fmt - sprintf like format,
744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * ... - Optional arguments
754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns - string allocated or NULL on error
764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevchar *snd_use_case_identifier(const char *fmt, ...)
784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGE("API not implemented for now, to be updated if required");
804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NULL;
814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Free a list
854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * list - list to free
864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * items -  Count of strings
874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Return Zero on success, otherwise a negative error code
884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_free_list(const char *list[], int items)
904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* list points to UCM internal static tables,
924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     * hence there is no need to do a free call
934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev     * just set the list to NULL and return */
944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list = NULL;
954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Obtain a list of entries
1004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer or  NULL for card list
1014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * identifier - NULL for card list
1024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * list - Returns allocated list
1034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns Number of list entries on success, otherwise a negative error code
1044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
1054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
1064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          const char *identifier,
1074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          const char **list[])
1084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
1094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
1104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int verb_index, list_size, index = 0;
1114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (identifier == NULL) {
1134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *list = card_list;
1144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return ((int)MAX_NUM_CARDS);
1154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
1164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
1184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
1194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
1204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_get_list(): failed, invalid arguments");
1214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
1224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
1234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
1244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
1254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strncmp(identifier, "_verbs", 6)) {
1264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while(strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
1274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
1284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Verb:%s", index,
1294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 uc_mgr->card_ctxt_ptr->verb_list[index]);
1304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
1314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *list = (char ***)uc_mgr->card_ctxt_ptr->verb_list;
1334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
1344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return index;
1354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else  if (!strncmp(identifier, "_devices", 8)) {
1364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
1374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            SND_USE_CASE_VERB_INACTIVE, strlen(SND_USE_CASE_VERB_INACTIVE))) {
1384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Use case verb name not set, invalid current verb");
1394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
1404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -EINVAL;
1414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
1434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while(strncmp(uc_mgr->card_ctxt_ptr->current_verb,
1444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].use_case_name,
1454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (strlen(verb_list[index].use_case_name)+1))) {
1464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
1474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index = index;
1494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index = 0;
1504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while(strncmp(verb_list[verb_index].device_list[index],
1514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
1524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Device:%s", index,
1534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 verb_list[verb_index].device_list[index]);
1544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
1554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *list = verb_list[verb_index].device_list;
1574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
1584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return index;
1594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else  if (!strncmp(identifier, "_modifiers", 10)) {
1604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
1614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
1624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Use case verb name not set, invalid current verb");
1634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
1644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -EINVAL;
1654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
1674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while(strncmp(uc_mgr->card_ctxt_ptr->current_verb,
1684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].use_case_name,
1694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (strlen(verb_list[index].use_case_name)+1))) {
1704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
1714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index = index;
1734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index = 0;
1744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while(strncmp(verb_list[verb_index].modifier_list[index],
1754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
1764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Modifier:%s", index,
1774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 verb_list[verb_index].modifier_list[index]);
1784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
1794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *list = verb_list[verb_index].modifier_list;
1814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
1824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return index;
1834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else  if (!strncmp(identifier, "_enadevs", 8)) {
1844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr->device_list_count) {
1854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            for (index = 0; index < uc_mgr->device_list_count; index++) {
1864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(uc_mgr->current_device_list[index]);
1874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->current_device_list[index] = NULL;
1884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
1894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr->current_device_list);
1904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->current_device_list = NULL;
1914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->device_list_count = 0;
1924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
1934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list_size =
1944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
1954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->device_list_count = list_size;
1969efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani    if (list_size > 0) {
1974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->current_device_list =
1984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (char **)malloc(sizeof(char *)*list_size);
1994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (uc_mgr->current_device_list == NULL) {
2004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                *list = NULL;
2014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
2034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
2044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            for (index = 0; index < list_size; index++) {
2054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->current_device_list[index] =
2064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
2074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index);
2084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
2094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
2104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *list = (const char **)uc_mgr->current_device_list;
2114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return (list_size);
2134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else  if (!strncmp(identifier, "_enamods", 8)) {
2144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr->modifier_list_count) {
2154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            for (index = 0; index < uc_mgr->modifier_list_count; index++) {
2164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(uc_mgr->current_modifier_list[index]);
2174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->current_modifier_list[index] = NULL;
2184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
2194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr->current_modifier_list);
2204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->current_modifier_list = NULL;
2214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->modifier_list_count = 0;
2224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
2234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list_size =
2244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
2254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->modifier_list_count = list_size;
2269efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani    if (list_size > 0) {
2274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->current_modifier_list =
2284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (char **)malloc(sizeof(char *) * list_size);
2294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (uc_mgr->current_modifier_list == NULL) {
2304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                *list = NULL;
2314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
2334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
2344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            for (index = 0; index < list_size; index++) {
2354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->current_modifier_list[index] =
2364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
2374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index);
2384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
2394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
2404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *list = (const char **)uc_mgr->current_modifier_list;
2414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return (list_size);
2434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
2444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Invalid identifier: %s", identifier);
2454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
2474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
2494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
2524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Get current value of the identifier
2534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * identifier - NULL for current card
2544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        _verb
2554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        <Name>/<_device/_modifier>
2564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *    Name -    PlaybackPCM
2574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        CapturePCM
2584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        PlaybackCTL
2594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        CaptureCTL
2604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * value - Value pointer
2614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns Zero if success, otherwise a negative error code
2624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
2634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
2644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     const char *identifier,
2654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     const char **value)
2664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
2674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *ctrl_list;
2684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
2694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char ident[MAX_STR_LEN], *ident1, *ident2, *temp_ptr;
2704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index, verb_index = 0, ret = 0;
2714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
2734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
2744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
2754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_get(): failed, invalid arguments");
2764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
2784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (identifier == NULL) {
2814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr->card_ctxt_ptr->card_name != NULL) {
2824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *value = strdup(uc_mgr->card_ctxt_ptr->card_name);
2834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
2844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *value = NULL;
2854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
2864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return 0;
2884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
2904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strncmp(identifier, "_verb", 5)) {
2914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr->card_ctxt_ptr->current_verb != NULL) {
2924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *value = strdup(uc_mgr->card_ctxt_ptr->current_verb);
2934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
2944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *value = NULL;
2954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
2964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
2974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return 0;
2984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
2994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
3004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(ident, identifier, sizeof(ident));
3014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
3024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("No valid identifier found: %s", ident);
3034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = -EINVAL;
3044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
3054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((!strncmp(ident1, "PlaybackPCM", 11)) ||
3064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (!strncmp(ident1, "CapturePCM", 10))) {
3074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ident2 = strtok_r(NULL, "/", &temp_ptr);
3084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index = 0;
3094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ident2 != NULL) {
3104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
3114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
3124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((get_usecase_type(uc_mgr, ident2)) == CTRL_LIST_VERB) {
3134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ctrl_list = verb_list[verb_index].verb_ctrls;
3144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
3154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ctrl_list = verb_list[verb_index].mod_ctrls;
3164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
3174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((verb_index < 0) ||
3184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
3194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    SND_UCM_END_OF_LIST, 3)) || (ctrl_list == NULL)) {
3204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGE("Invalid current verb value: %s - %d",
3214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         uc_mgr->card_ctxt_ptr->current_verb, verb_index);
3224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
3234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return -EINVAL;
3244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
3254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                while(strncmp(ctrl_list[index].case_name, ident2,
3264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (strlen(ident2)+1))) {
3274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (!strncmp(ctrl_list[index].case_name,
3284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))){
3294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        *value = NULL;
3304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = -EINVAL;
3314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
3324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
3334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        index++;
3344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
3354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
3364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
3374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -EINVAL;
3384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
3394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
3404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("No valid device/modifier found with given identifier: %s",
3414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     ident2);
3424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
3434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if(!strncmp(ident1, "PlaybackPCM", 11)) {
3444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ctrl_list[index].playback_dev_name) {
3454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        *value = strdup(ctrl_list[index].playback_dev_name);
3464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
3474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        *value = NULL;
3484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = -ENODEV;
3494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
3504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else if(!strncmp(ident1, "CapturePCM", 10)) {
3514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ctrl_list[index].capture_dev_name) {
3524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        *value = strdup(ctrl_list[index].capture_dev_name);
3534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
3544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        *value = NULL;
3554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = -ENODEV;
3564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
3574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
3584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGE("No valid device name exists for given identifier: %s",
3594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         ident2);
3604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    *value = NULL;
3614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENODEV;
3624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
3634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
3644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if ((!strncmp(ident1, "PlaybackCTL", 11)) ||
3654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (!strncmp(ident1, "CaptureCTL", 10))) {
3664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(uc_mgr->card_ctxt_ptr->control_device != NULL) {
3674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                *value = strdup(uc_mgr->card_ctxt_ptr->control_device);
3684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
3694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("No valid control device found");
3704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                *value = NULL;
3714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -ENODEV;
3724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
3734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncmp(ident1, "ACDBID", 11)) {
3744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ident2 = strtok_r(NULL, "/", &temp_ptr);
3754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index = 0; verb_index = 0;
3764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
3774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if((verb_index < 0) ||
3784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
3794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_UCM_END_OF_LIST, 3)) ||
3804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (verb_list[verb_index].verb_ctrls == NULL)) {
3814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid current verb value: %s - %d",
3824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     uc_mgr->card_ctxt_ptr->current_verb, verb_index);
3834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
3844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -EINVAL;
3854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
3864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ctrl_list = verb_list[verb_index].device_ctrls;
3874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ident2 != NULL) {
3884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                while(strncmp(ctrl_list[index].case_name, ident2,
3894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    MAX_LEN(ctrl_list[index].case_name,ident2))) {
3904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
3914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlen(SND_UCM_END_OF_LIST))){
3924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = -EINVAL;
3934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
3944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
3954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        index++;
3964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
3974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
3984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
3994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
4004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("No valid device/modifier found with given identifier: %s",
4014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      ident2);
4024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
4034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_list[verb_index].device_ctrls[index].acdb_id) {
4044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = verb_list[verb_index].device_ctrls[index].acdb_id;
4054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
4064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENODEV;
4074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncmp(ident1, "EffectsMixerCTL", 11)) {
4104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ident2 = strtok_r(NULL, "/", &temp_ptr);
4114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index = 0; verb_index = 0;
4124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
4134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if((verb_index < 0) ||
4144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
4154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_UCM_END_OF_LIST, 3)) ||
4164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (verb_list[verb_index].verb_ctrls == NULL)) {
4174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid current verb value: %s - %d",
4184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     uc_mgr->card_ctxt_ptr->current_verb, verb_index);
4194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
4204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -EINVAL;
4214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ctrl_list = verb_list[verb_index].device_ctrls;
4234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ident2 != NULL) {
4244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                while(strncmp(ctrl_list[index].case_name, ident2, strlen(ident2)+1)) {
4254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
4264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlen(SND_UCM_END_OF_LIST))){
4274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = -EINVAL;
4284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
4294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
4304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        index++;
4314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
4324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
4354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("No valid device/modifier found with given identifier: %s",
4364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      ident2);
4374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
4384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_list[verb_index].device_ctrls[index].effects_mixer_ctl) {
4394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    *value = strdup(verb_list[verb_index].device_ctrls[index].effects_mixer_ctl);
4404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
4414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    *value = NULL;
4424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENODEV;
4434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
4444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
4454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
4464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Unsupported identifier value: %s", ident1);
4474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *value = NULL;
4484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -EINVAL;
4494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
4504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
4524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
4534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
4544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
4554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
4564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Get current status
4574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure
4584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * identifier - _devstatus/<device>,
4594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        _modstatus/<modifier>
4604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * value - result
4614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns 0 on success, otherwise a negative error code
4624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
4634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
4644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              const char *identifier,
4654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              long *value)
4664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
4674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char ident[MAX_STR_LEN], *ident1, *ident2, *ident_value, *temp_ptr;
4684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index, list_size, ret = -EINVAL;
4694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
4704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
4714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
4724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
4734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_geti(): failed, invalid arguments");
4744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
4754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
4764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
4774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
4784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    *value = 0;
4794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(ident, identifier, sizeof(ident));
4804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
4814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("No valid identifier found: %s", ident);
4824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = -EINVAL;
4834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
4844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(ident1, "_devstatus", 10)) {
4854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ident2 = strtok_r(NULL, "/", &temp_ptr);
4864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ident2 != NULL) {
4874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list_size =
4884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
4894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                for (index = 0; index < list_size; index++) {
4904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((ident_value =
4914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
4924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
4934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (!strncmp(ident2, ident_value,
4944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            (strlen(ident_value)+1))) {
4954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            *value = 1;
4964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            free(ident_value);
4974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ident_value = NULL;
4984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
4994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        } else {
5004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            free(ident_value);
5014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ident_value = NULL;
5024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
5034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
5044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
5054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = 0;
5064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
5074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncmp(ident1, "_modstatus", 10)) {
5084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ident2 = strtok_r(NULL, "/", &temp_ptr);
5094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ident2 != NULL) {
5104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list_size =
5114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
5124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                for (index = 0; index < list_size; index++) {
5134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((ident_value =
5144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
5154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
5164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (!strncmp(ident2, ident_value,
5174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            (strlen(ident_value)+1))) {
5184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            *value = 1;
5194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            free(ident_value);
5204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ident_value = NULL;
5214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
5224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        } else {
5234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            free(ident_value);
5244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ident_value = NULL;
5254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
5264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
5274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
5284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = 0;
5294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
5304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
5314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Unknown identifier: %s", ident1);
5324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
5334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
5354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
5364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
5374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5389858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Manistatic int check_devices_for_voice_call(snd_use_case_mgr_t *uc_mgr,
5399858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Maniconst char *use_case)
5409858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani{
5419858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    struct snd_ucm_ident_node *dev_node = NULL;
5429858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    int index = 0, list_size = 0, rx_dev_status = 0, tx_dev_status = 0;
5439858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani
5449858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    if ((!strncmp(use_case, SND_USE_CASE_VERB_VOICECALL,
5459858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        strlen(SND_USE_CASE_VERB_VOICECALL))) ||
5469858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        (!strncmp(use_case, SND_USE_CASE_VERB_IP_VOICECALL,
5479858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
5489858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        (!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOICE,
5499858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        strlen(SND_USE_CASE_MOD_PLAY_VOICE))) ||
5509858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        (!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOIP,
5519858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
5529858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        ALOGV("check_devices_for_voice_call(): voice cap detected\n");
5539858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        list_size =
5549858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
5559858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        for (index = 0; index < list_size; index++) {
5569858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            if ((dev_node =
5579858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                snd_ucm_get_device_node(uc_mgr->card_ctxt_ptr->dev_list_head,
5589858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                index))) {
5599858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                if (dev_node->capability == CAP_RX && dev_node->active == 1) {
5609858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    rx_dev_status = 1;
5619858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                } else if (dev_node->capability == CAP_TX && dev_node->active == 1) {
5629858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    tx_dev_status = 1;
5639858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                }
5649858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            }
5659858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        }
5669858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        if (rx_dev_status == 1 && tx_dev_status == 1) {
5679858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            ALOGV("check_devices_for_voice_call(): Rx and Tx devices enabled\n");
5689858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            return 0;
5699858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        } else {
5709858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            ALOGV("check_devices_for_voice_call(): Rx/Tx dev not enabled: \
5719858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                  %d,%d\n", rx_dev_status, tx_dev_status);
5729858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            return 1;
5739858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        }
5749858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    }
5759858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    return 0;
5769858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani}
5779858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani
5784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_use_case_apply_voice_acdb(snd_use_case_mgr_t *uc_mgr,
5794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint use_case_index)
5804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
5814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *ctrl_list;
5824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int list_size, index, verb_index, ret = 0, voice_acdb = 0, rx_id, tx_id;
5834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *ident_value = NULL;
5844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
5854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Check if voice call use case/modifier exists */
5864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
5874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        SND_USE_CASE_VERB_VOICECALL, strlen(SND_USE_CASE_VERB_VOICECALL))) ||
5884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
5894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        SND_USE_CASE_VERB_IP_VOICECALL,
5904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlen(SND_USE_CASE_VERB_IP_VOICECALL)))) {
5914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        voice_acdb = 1;
5924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
5934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (voice_acdb != 1) {
5944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list_size =
5954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
5964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for (index = 0; index < list_size; index++) {
5974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if ((ident_value =
5984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
5994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
6004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOICE,
6014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlen(SND_USE_CASE_MOD_PLAY_VOICE))) ||
6024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOIP,
6034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
6044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    voice_acdb = 1;
6054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free(ident_value);
6064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ident_value = NULL;
6074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
6084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
6094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(ident_value);
6104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ident_value = NULL;
6114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
6124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
6134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
6154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
6164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if((verb_index < 0) ||
6174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
6184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        SND_UCM_END_OF_LIST, 3))) {
6194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Invalid current verb value: %s - %d",
6204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->current_verb, verb_index);
6214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
6224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (voice_acdb == 1) {
6244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
6254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
6264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list_size =
6274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
6284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for (index = 0; index < list_size; index++) {
6294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if ((ident_value =
6304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
6314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
6324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (strncmp(ident_value, ctrl_list[use_case_index].case_name,
6334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (strlen(ctrl_list[use_case_index].case_name)+1))) {
6344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
6354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
6364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(ident_value);
6374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ident_value = NULL;
6384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
6394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
6404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index = 0;
6414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ident_value != NULL) {
6424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while(strncmp(ctrl_list[index].case_name, ident_value,
6434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (strlen(ident_value)+1))) {
6444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
6454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlen(SND_UCM_END_OF_LIST))) {
6464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -EINVAL;
6474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
6484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
6494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index++;
6504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
6514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
6524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("No valid device found: %s",ident_value);
6534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
6544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ctrl_list[use_case_index].capability == CAP_RX) {
6554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    rx_id = ctrl_list[use_case_index].acdb_id;
6564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    tx_id = ctrl_list[index].acdb_id;
6574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
6584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    rx_id = ctrl_list[index].acdb_id;
6594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    tx_id = ctrl_list[use_case_index].acdb_id;
6604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
66191e9fad9dff8746a5cd9d44ee4f1313d3ad7cfdcehgrace.kim                if(((rx_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID)||(rx_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID))
66291e9fad9dff8746a5cd9d44ee4f1313d3ad7cfdcehgrace.kim                    && tx_id == DEVICE_HANDSET_TX_ACDB_ID) {
6634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    tx_id = DEVICE_SPEAKER_TX_ACDB_ID;
66491e9fad9dff8746a5cd9d44ee4f1313d3ad7cfdcehgrace.kim                } else if (((rx_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID )||(rx_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID))
66591e9fad9dff8746a5cd9d44ee4f1313d3ad7cfdcehgrace.kim                    && tx_id == DEVICE_HANDSET_TX_FV5_ACDB_ID) {
6669746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                    tx_id = DEVICE_SPEAKER_TX_FV5_ACDB_ID;
6674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
6689746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani
6694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((rx_id != uc_mgr->current_rx_device) ||
6704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (tx_id != uc_mgr->current_tx_device)) {
6714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    uc_mgr->current_rx_device = rx_id;
6724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    uc_mgr->current_tx_device = tx_id;
6734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGD("Voice acdb: rx id %d tx id %d",
6744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          uc_mgr->current_rx_device,
6754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          uc_mgr->current_tx_device);
676295559398bf12612fb208ab3dd24ac08b6f04f2aSathishKumar Mani                    if (uc_mgr->acdb_handle && !uc_mgr->isFusion3Platform) {
6775ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                        acdb_send_voice_cal = dlsym(uc_mgr->acdb_handle,"acdb_loader_send_voice_cal");
6785ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                        if (acdb_send_voice_cal == NULL) {
6795ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                            ALOGE("ucm: dlsym: Error:%s Loading acdb_loader_send_voice_cal", dlerror());
6805ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                        }else {
6815ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                            acdb_send_voice_cal(uc_mgr->current_rx_device,
6825ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                                       uc_mgr->current_tx_device);
6835ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                        }
6845ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                   }
6854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
6864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Voice acdb: Required acdb already pushed \
6874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         rx id %d tx id %d", uc_mgr->current_rx_device,
6884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         uc_mgr->current_tx_device);
6894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
6904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
6914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(ident_value);
6924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ident_value = NULL;
6934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
6944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
6954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("No voice use case found");
6964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->current_rx_device = -1; uc_mgr->current_tx_device = -1;
6974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = -ENODEV;
6984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
6994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
7004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
7014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint get_use_case_index(snd_use_case_mgr_t *uc_mgr, const char *use_case,
7034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint ctrl_list_type)
7044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
7054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
7064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *ctrl_list;
7074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = 0, index = 0, verb_index;
7084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
7104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
7114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ctrl_list_type == CTRL_LIST_VERB) {
7124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
7134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
7144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
7154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
7164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
7174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
7184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
7194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
7204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
7214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list = NULL;
7224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if((verb_index < 0) ||
7244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev      (!strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_UCM_END_OF_LIST, 3)) ||
7254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev      (ctrl_list == NULL) || (ctrl_list[index].case_name == NULL)) {
7264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Invalid current verb value: %s - %d",
7274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->card_ctxt_ptr->current_verb, verb_index);
7284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
7294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(strncmp(ctrl_list[index].case_name, use_case, (strlen(use_case)+1))) {
7314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
7324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_UCM_END_OF_LIST))) {
7334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -EINVAL;
7344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
7354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
7364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index++;
7374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ctrl_list[index].case_name == NULL) {
7384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Invalid case_name at index %d", index);
7394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -EINVAL;
7404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
7414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
7424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ret < 0) {
7444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return ret;
7454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
7464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return index;
7474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
7494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Apply the required mixer controls for specific use case
7514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer
7524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * use_case - use case name
7534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * return 0 on sucess, otherwise a negative error code
7544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
7554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_apply_mixer_controls(snd_use_case_mgr_t *uc_mgr,
7564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *use_case, int enable, int ctrl_list_type, int uc_index)
7574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
7584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *ctrl_list;
7594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    mixer_control_t *mixer_list;
7604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct mixer_ctl *ctl;
7614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int i, ret = 0, index = 0, verb_index, mixer_count;
7624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
7634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
7644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ctrl_list_type == CTRL_LIST_VERB) {
7654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
7664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
7674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
7684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
7694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
7704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
7714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list =
7724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
7734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
7744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list = NULL;
7754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if((verb_index < 0) ||
7774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev      (!strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_UCM_END_OF_LIST, 3)) ||
7784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev      (ctrl_list == NULL)) {
7794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Invalid current verb value: %s - %d",
7804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->current_verb, verb_index);
7814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
7824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
7834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (uc_index < 0) {
7844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("No valid use case found with the use case: %s", use_case);
7854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = -ENODEV;
7864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
7874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!uc_mgr->card_ctxt_ptr->mixer_handle) {
7884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Control device not initialized");
7894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -ENODEV;
7904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
7919858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            if (enable &&
7929858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                (check_devices_for_voice_call(uc_mgr, use_case) != NULL))
7939858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                return ret;
7944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGD("Set mixer controls for %s enable %d", use_case, enable);
7954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ctrl_list[uc_index].acdb_id && ctrl_list[uc_index].capability) {
7964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (enable) {
7974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (snd_use_case_apply_voice_acdb(uc_mgr, uc_index)) {
7989efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani                        ALOGV("acdb_id %d cap %d enable %d",
7994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ctrl_list[uc_index].acdb_id,
8004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ctrl_list[uc_index].capability, enable);
8015ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                        if (uc_mgr->acdb_handle) {
8025ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                            acdb_send_audio_cal = dlsym(uc_mgr->acdb_handle,"acdb_loader_send_audio_cal");
8035ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                            if (acdb_send_audio_cal == NULL) {
8045ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                                ALOGE("ucm:dlsym:Error:%s Loading acdb_loader_send_audio_cal", dlerror());
8055ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                            } else {
8065ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                                acdb_send_audio_cal(ctrl_list[uc_index].acdb_id,
8075ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                                                     ctrl_list[uc_index].capability);
8085ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                            }
8095ff7a02ca497656b711919b81a783e6a10cdcc76SathishKumar Mani                        }
8104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
8114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
8124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
8134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (enable) {
8144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                mixer_list = ctrl_list[uc_index].ena_mixer_list;
8154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                mixer_count = ctrl_list[uc_index].ena_mixer_count;
8164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
8174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                mixer_list = ctrl_list[uc_index].dis_mixer_list;
8184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                mixer_count = ctrl_list[uc_index].dis_mixer_count;
8194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
8204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            for(index = 0; index < mixer_count; index++) {
8214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (mixer_list == NULL) {
8224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGE("No valid controls exist for this case: %s", use_case);
8234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
8244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
8254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ctl = mixer_get_control(uc_mgr->card_ctxt_ptr->mixer_handle,
8264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          mixer_list[index].control_name, 0);
8274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ctl) {
8284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (mixer_list[index].type == TYPE_INT) {
8299efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani                        ALOGV("Setting mixer control: %s, value: %d",
8304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                             mixer_list[index].control_name,
8314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                             mixer_list[index].value);
8324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = mixer_ctl_set(ctl, mixer_list[index].value);
8334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else if (mixer_list[index].type == TYPE_MULTI_VAL) {
8344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ALOGD("Setting multi value: %s",
8354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            mixer_list[index].control_name);
8364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = mixer_ctl_set_value(ctl, mixer_list[index].value,
8374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                mixer_list[index].mulval);
8384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (ret < 0)
8394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ALOGE("Failed to set multi value control %s\n",
8404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                mixer_list[index].control_name);
8414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
8429efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani                        ALOGV("Setting mixer control: %s, value: %s",
8434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            mixer_list[index].control_name,
8444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            mixer_list[index].string);
8454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = mixer_ctl_select(ctl, mixer_list[index].string);
8464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
8474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if ((ret != 0) && enable) {
8484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       /* Disable all the mixer controls which are
8494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        * already enabled before failure */
8504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       mixer_list = ctrl_list[uc_index].dis_mixer_list;
8514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       mixer_count = ctrl_list[uc_index].dis_mixer_count;
8524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       for(i = 0; i < mixer_count; i++) {
8534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           ctl = mixer_get_control(
8544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                     uc_mgr->card_ctxt_ptr->mixer_handle,
8554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                     mixer_list[i].control_name, 0);
8564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           if (ctl) {
8574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                               if (mixer_list[i].type == TYPE_INT) {
8584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                   ret = mixer_ctl_set(ctl,
8594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                             mixer_list[i].value);
8604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                               } else {
8614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                   ret = mixer_ctl_select(ctl,
8624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                             mixer_list[i].string);
8634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                               }
8644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           }
8654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       }
8664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       ALOGE("Failed to enable the mixer controls for %s",
8674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            use_case);
8684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       break;
8694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
8704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
8714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
8724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
8734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
8744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
8754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
8764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
8774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint getUseCaseType(const char *useCase)
8784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
8794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("getUseCaseType: use case is %s\n", useCase);
8804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
8814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev           MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI)) ||
882d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani        !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
883d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani           MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
8844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
8854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev           MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
8864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
8874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
8884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
8894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
8904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
8914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
8924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
8934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) ||
894d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
895d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
8964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
8974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
8984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
8994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
9004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
9014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
9024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
9034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
9044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return CAP_RX;
9054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
9064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
9074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
9084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
9094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
9104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
9114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
9124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
913d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani        !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
914d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani            MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
915d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
916d1c97008da7b8081eb39bfa8fddb10196b2945f8SathishKumar Mani            MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
9174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
9184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
9194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
9204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
9214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return CAP_TX;
9224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
9234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
9244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
9254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
9264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
9274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
9284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
9294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
9304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
9314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
9324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
9334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
9344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
9354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
9364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
9374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
9384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
9394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
9404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
9414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
9424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
9434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOLTE))) {
9444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return CAP_VOICE;
9454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
9464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("unknown use case %s, returning voice capablity", useCase);
9474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return CAP_VOICE;
9484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
9504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Set/Reset mixer controls of specific use case for all current devices
9524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer
9534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * ident  - use case name (verb or modifier)
9544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * enable - 1 for enable and 0 for disable
9554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * return 0 on sucess, otherwise a negative error code
9564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
9574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int set_controls_of_usecase_for_all_devices(snd_use_case_mgr_t *uc_mgr,
9584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *ident, int enable, int ctrl_list_type)
9594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
9604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *dev_list, *uc_list;
9614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_device, use_case[MAX_UC_LEN];
9624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int list_size, index, uc_index, ret = 0, intdev_flag = 0;
9639858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    int verb_index, capability = 0, ident_cap = 0, dev_cap =0;
9644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
9654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("set_use_case_ident_for_all_devices(): %s", ident);
9664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
9674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index = 0;
9684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev_list =
9694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
9704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ctrl_list_type == CTRL_LIST_VERB) {
9714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_list =
9724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
9734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
9744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_list =
9754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
9764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
9774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_list = NULL;
9784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
9794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ident_cap = getUseCaseType(ident);
9804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
9814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for (index = 0; index < list_size; index++) {
9824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        current_device =
9834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head, index);
9844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (current_device != NULL) {
9854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_index = get_use_case_index(uc_mgr, current_device,
9864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       CTRL_LIST_DEVICE);
9879858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            dev_cap = dev_list[uc_index].capability;
9884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!capability) {
9894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                capability = dev_list[uc_index].capability;
9904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else if (capability != dev_list[uc_index].capability) {
9914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                capability = CAP_VOICE;
9924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
9939858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            if (ident_cap == CAP_VOICE  || ident_cap == dev_cap) {
9949858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                if (enable) {
9959858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    if (!snd_ucm_get_status_at_index(
9964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        uc_mgr->card_ctxt_ptr->dev_list_head, current_device)) {
9979858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        if (uc_index >= 0) {
9989858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            ALOGV("Applying mixer controls for device: %s",
9999858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                  current_device);
10009858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            ret = snd_use_case_apply_mixer_controls(uc_mgr,
10019858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                  current_device, enable, CTRL_LIST_DEVICE, uc_index);
10029858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            if (!ret)
10039858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                snd_ucm_set_status_at_index(
10049858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                  uc_mgr->card_ctxt_ptr->dev_list_head,
10059858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                  current_device, enable, dev_cap);
10069858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        }
10079858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                     } else if (ident_cap == CAP_VOICE) {
10089858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        snd_use_case_apply_voice_acdb(uc_mgr, uc_index);
10099858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                     }
10109858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 }
10119858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 strlcpy(use_case, ident, sizeof(use_case));
10129858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 strlcat(use_case, current_device, sizeof(use_case));
10139858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 ALOGV("Applying mixer controls for use case: %s", use_case);
10149858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 if ((uc_index =
10159858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                      get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
10169858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                      ALOGV("No valid use case found: %s", use_case);
10179858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                      intdev_flag++;
10189858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 } else {
10199858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                      if (capability == CAP_VOICE || ident_cap == CAP_VOICE ||
10209858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                          capability == ident_cap) {
10219858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                          ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
10229858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                enable, ctrl_list_type, uc_index);
10239858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                      }
10249858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 }
10259858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 use_case[0] = 0;
10269858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                 free(current_device);
10279858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani             }
10284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (intdev_flag) {
10314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type)) < 0) {
10324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("use case %s not valid without device combination", ident);
10334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
10344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (capability == CAP_VOICE || capability == ident_cap ||
10354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ident_cap == CAP_VOICE) {
10364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
10374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ctrl_list_type, uc_index);
10384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
10394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
10414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
10424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
10434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Set/Reset mixer controls of specific use case for a specific device
10454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer
10464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * ident  - use case name (verb or modifier)
10474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * device - device for which use case needs to be set/reset
10484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * enable - 1 for enable and 0 for disable
10494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * return 0 on sucess, otherwise a negative error code
10504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
10514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int set_controls_of_usecase_for_device(snd_use_case_mgr_t *uc_mgr,
10524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *ident, const char *device, int enable, int ctrl_list_type)
10534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
10549858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    card_mctrl_t *dev_list;
10554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char use_case[MAX_UC_LEN];
10564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int list_size, index, dev_index, uc_index, ret = 0;
10579858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    int verb_index, capability = 0;
10584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
10594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("set_use_case_ident_for_device(): use case %s device %s", ident,
10604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        device);
10619858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
10629858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        verb_index = 0;
10639858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    dev_list =
10649858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
10654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (device != NULL) {
10664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (enable) {
10674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
10689858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            capability = dev_list[dev_index].capability;
10694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!snd_ucm_get_status_at_index(
10704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
10714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_apply_mixer_controls(uc_mgr, device,
10724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         enable, CTRL_LIST_DEVICE, dev_index);
10734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!ret)
10744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    snd_ucm_set_status_at_index(
10759858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
10769858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    capability);
10774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
10784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(use_case, ident, sizeof(use_case));
10804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcat(use_case, device, sizeof(use_case));
10819efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani    ALOGV("Applying mixer controls for use case: %s", use_case);
10824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((uc_index = get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
10834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("No valid use case found: %s", use_case );
10844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type);
10854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
10864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ctrl_list_type, uc_index) < 0) {
10874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 ALOGV("use case %s not valid without device combination also",
10884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     ident);
10894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
10904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
10914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case, enable,
10924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      ctrl_list_type, uc_index);
10934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
10944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
10954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type);
10964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
10974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ctrl_list_type, uc_index) < 0) {
10984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             ALOGV("use case %s not valid without device combination also",
10994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 ident);
11004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
11014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
11024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
11034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
11044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
11054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Set/Reset mixer controls of specific device for all use cases
11064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer
11074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * device - device name
11084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * enable - 1 for enable and 0 for disable
11094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * return 0 on sucess, otherwise a negative error code
11104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
11114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int set_controls_of_device_for_all_usecases(snd_use_case_mgr_t *uc_mgr,
11124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *device, int enable)
11134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
11144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *dev_list, *uc_list;
11154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *ident_value, use_case[MAX_UC_LEN];
11164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int verb_index, uc_index, dev_index, capability = 0;
11174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int list_size, index = 0, ret = -ENODEV, flag = 0, intdev_flag = 0;
11184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
11194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("set_controls_of_device_for_all_usecases: %s", device);
11204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
11214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index = 0;
11224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev_list =
11234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
11244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
112594de74c9450130f9dd01972414b18cb358062876ty.lee    if (dev_index >= 0)
112694de74c9450130f9dd01972414b18cb358062876ty.lee        capability = dev_list[dev_index].capability;
11274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
11284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlen(SND_USE_CASE_VERB_INACTIVE))) {
11294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_list =
11304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
11319858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        if (capability == CAP_VOICE ||
11329858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            capability == getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ||
11339858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) == CAP_VOICE) {
11349858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            strlcpy(use_case, uc_mgr->card_ctxt_ptr->current_verb,
11359858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                sizeof(use_case));
11369858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            strlcat(use_case, device, sizeof(use_case));
11379858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            if ((uc_index =
11389858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                get_use_case_index(uc_mgr, use_case, CTRL_LIST_VERB)) < 0) {
11399858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                ALOGV("No valid use case found: %s", use_case);
11409858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                intdev_flag = 1;
11419858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            } else {
11429858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                if (enable) {
11439858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    if (!snd_ucm_get_status_at_index(
11449858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
11459858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        ret = snd_use_case_apply_mixer_controls(uc_mgr, device,
11469858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                  enable, CTRL_LIST_DEVICE, dev_index);
11479858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        if (!ret)
11489858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            snd_ucm_set_status_at_index(
11499858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            uc_mgr->card_ctxt_ptr->dev_list_head, device,
11509858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            enable, capability);
11519858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            flag = 1;
11529858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    }
11534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
11544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("set %d for use case value: %s", enable, use_case);
11554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
11564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          enable, CTRL_LIST_VERB, uc_index);
11574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret != 0)
11584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     ALOGE("No valid controls exists for usecase %s and device \
11594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          %s, enable: %d", use_case, device, enable);
11604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
11614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
11624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (intdev_flag) {
11634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (enable && !flag) {
11644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!snd_ucm_get_status_at_index(
11654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
11664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = snd_use_case_apply_mixer_controls(uc_mgr,
11674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              device, enable, CTRL_LIST_DEVICE, dev_index);
11684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (!ret)
11694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        snd_ucm_set_status_at_index(
11709858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
11719858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        capability);
11724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    flag = 1;
11734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
11744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
11754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            use_case[0] = 0;
11764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(use_case, uc_mgr->card_ctxt_ptr->current_verb,
11774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                sizeof(use_case));
11784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_index = get_use_case_index(uc_mgr, use_case, CTRL_LIST_VERB);
11794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (capability == CAP_VOICE ||
11804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                capability ==
11814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ||
11824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ==
11834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                CAP_VOICE) {
11844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("set %d for use case value: %s", enable, use_case);
11854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
11864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          enable, CTRL_LIST_VERB, uc_index);
11874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret != 0)
11884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      ALOGE("No valid controls exists for usecase %s and \
11894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           device %s, enable: %d", use_case, device, enable);
11904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
11914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            intdev_flag = 0;
11924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
11934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        use_case[0] = 0;
11944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
11954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_ucm_print_list(uc_mgr->card_ctxt_ptr->mod_list_head);
11964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_list =
11974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
11984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
11994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for (index = 0; index < list_size; index++) {
12004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((ident_value =
12014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
12024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index))) {
12039858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani            if (capability == CAP_VOICE ||
12049858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                getUseCaseType(ident_value) == CAP_VOICE ||
12059858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                capability == getUseCaseType(ident_value)) {
12069858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                strlcpy(use_case, ident_value, sizeof(use_case));
12079858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                strlcat(use_case, device, sizeof(use_case));
12089858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                if ((uc_index = get_use_case_index(uc_mgr, use_case,
12099858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    CTRL_LIST_MODIFIER)) < 0) {
12109858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    ALOGV("No valid use case found: %s", use_case);
12119858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    intdev_flag = 1;
12129858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                } else {
12139858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    if (enable && !flag) {
12149858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        if (!snd_ucm_get_status_at_index(
12159858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
12169858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            ret = snd_use_case_apply_mixer_controls(uc_mgr,
12179858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                      device, enable, CTRL_LIST_DEVICE,
12189858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                      dev_index);
12199858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            if (!ret)
12209858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                snd_ucm_set_status_at_index(
12219858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                    uc_mgr->card_ctxt_ptr->dev_list_head,
12229858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                                    device, enable, capability);
12239858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            flag = 1;
12249858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        }
12254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
12264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("set %d for use case value: %s", enable, use_case);
12279858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    ret = snd_use_case_apply_mixer_controls(uc_mgr,
12289858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                          use_case, enable, CTRL_LIST_MODIFIER, uc_index);
12299858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                    if (ret != 0)
12309858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        ALOGE("No valid controls exists for usecase %s and \
12319858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            device %s, enable: %d", use_case, device, enable);
12324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
12334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
12344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (intdev_flag) {
12354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (enable && !flag) {
12364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (!snd_ucm_get_status_at_index(
12374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
12384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = snd_use_case_apply_mixer_controls(uc_mgr,
12394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                  device, enable, CTRL_LIST_DEVICE, dev_index);
12404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (!ret)
12414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            snd_ucm_set_status_at_index(
12424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            uc_mgr->card_ctxt_ptr->dev_list_head, device,
12439858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                            enable, capability);
12444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        flag = 1;
12454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
12464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
12474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                use_case[0] = 0;
12484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(use_case, ident_value, sizeof(use_case));
12494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_index =
12504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    get_use_case_index(uc_mgr, ident_value, CTRL_LIST_MODIFIER);
12514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (capability == CAP_VOICE ||
12524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    capability == getUseCaseType(ident_value) ||
12534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    getUseCaseType(ident_value) == CAP_VOICE) {
12544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("set %d for use case value: %s", enable, use_case);
12554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
12564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          enable, CTRL_LIST_MODIFIER, uc_index);
12574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ret != 0)
12584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         ALOGE("No valid controls exists for usecase %s and \
12594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              device %s, enable: %d", use_case, device, enable);
12604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
12614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                intdev_flag = 0;
12624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
12634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            use_case[0] = 0;
12644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(ident_value);
12654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
12664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
12674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!enable) {
12684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_use_case_apply_mixer_controls(uc_mgr, device, enable,
12694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  CTRL_LIST_DEVICE, dev_index);
12704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!ret)
12714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_set_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
12729858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                device, enable, capability);
12734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
12744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
12754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
12764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
12774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Returns usecase type i.e. either verb or modifier
12784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer
12794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * usecase - usecase name either verb or modifier
12804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * return CTRL_LIST_VERB or CTRL_LIST_MODIFIER for verb/modifier respectively
12814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
12824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_usecase_type(snd_use_case_mgr_t *uc_mgr, const char *usecase)
12834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
12844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = -EINVAL, index = 0;
12854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
12864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
12874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
12884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index], usecase,
12894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (strlen(usecase)+1))) {
12904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = 0;
12914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
12924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
12934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index++;
12944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
12954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ret == 0)
12964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return CTRL_LIST_VERB;
12974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    else
12984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return CTRL_LIST_MODIFIER;
12994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
13004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
13014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Set/Reset mixer controls of specific device and specific use cases
13024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure pointer
13034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * device - device name
13044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * usecase - use case for which device needs to be enabled
13054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * enable - 1 for enable and 0 for disable
13064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * return 0 on sucess, otherwise a negative error code
13074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
13084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int set_controls_of_device_for_usecase(snd_use_case_mgr_t *uc_mgr,
13094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    const char *device, const char *usecase, int enable)
13104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
13119858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    card_mctrl_t *dev_list;
13124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char use_case[MAX_UC_LEN];
13134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = -ENODEV, uc_index, dev_index;
13149858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    int verb_index, capability = 0;
13154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
13164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("set_device_for_ident(): %s %s", device, usecase);
13179858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
13189858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        verb_index = 0;
13199858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    dev_list =
13209858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani         uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
13214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
13229858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    capability = dev_list[dev_index].capability;
13234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (usecase != NULL) {
13244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(use_case, usecase, sizeof(use_case));
13254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcat(use_case, device, sizeof(use_case));
13264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((uc_index = get_use_case_index(uc_mgr, use_case,
13274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            get_usecase_type(uc_mgr, usecase))) < 0) {
13284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("No valid use case found: %s", use_case);
13294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
13304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (enable) {
13314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!snd_ucm_get_status_at_index(
13324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
13334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = snd_use_case_apply_mixer_controls(uc_mgr, device,
13344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          enable, CTRL_LIST_DEVICE, dev_index);
13354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (!ret)
13364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        snd_ucm_set_status_at_index
13379858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        (uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
13389858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        capability);
13394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
13404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
13414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("set %d for use case value: %s", enable, use_case);
13424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case, enable,
13434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      get_usecase_type(uc_mgr, usecase), uc_index);
13444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret != 0)
13454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("No valid controls exists for usecase %s and device %s, \
13464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     enable: %d", use_case, device, enable);
13474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
13484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        use_case[0] = 0;
13494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
13504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (enable) {
13514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!snd_ucm_get_status_at_index(
13524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
13534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_apply_mixer_controls(uc_mgr, device, enable,
13544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          CTRL_LIST_DEVICE, dev_index);
13554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!ret)
13564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    snd_ucm_set_status_at_index(
13579858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
13589858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                        capability);
13594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
13604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
13614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
13624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!enable) {
13634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_use_case_apply_mixer_controls(uc_mgr, device, enable,
13644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  CTRL_LIST_DEVICE, dev_index);
13654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!ret)
13664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_set_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
13679858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani                device, enable, capability);
13684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
13694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
13704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
13714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
13724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
13734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Set new value for an identifier
13744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure
13754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * identifier - _verb, _enadev, _disdev, _enamod, _dismod
13764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        _swdev, _swmod
13774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * value - Value to be set
13784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns 0 on success, otherwise a negative error code
13794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
13804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
13814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     const char *identifier,
13824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     const char *value)
13834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
13844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
13854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char ident[MAX_STR_LEN], *ident1, *ident2, *temp_ptr;
13864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int verb_index, list_size, index = 0, ret = -EINVAL;
13874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
13884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
13894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) || (value == NULL) ||
13904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL) ||
13914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (identifier == NULL)) {
13924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_set(): failed, invalid arguments");
13934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
13944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
13954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
13964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
13974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGD("snd_use_case_set(): uc_mgr %p identifier %s value %s", uc_mgr,
13984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         identifier, value);
13994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(ident, identifier, sizeof(ident));
14004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
14014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("No multiple identifiers found in identifier value");
14024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ident[0] = 0;
14034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
14044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(ident1, "_swdev", 6)) {
14054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
14064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGD("Invalid disable device value: %s, but enabling new \
14074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     device", ident2);
14084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
14094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_ucm_del_ident_from_list(
14104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          &uc_mgr->card_ctxt_ptr->dev_list_head, ident2);
14114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret < 0) {
14124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Ignore device %s disable, device not part of \
14134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         enabled list", ident2);
14144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
14154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("swdev: device value to be disabled: %s", ident2);
14164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    /* Disable mixer controls for
14174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     * corresponding use cases and device */
14184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = set_controls_of_device_for_all_usecases(uc_mgr,
14194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              ident2, 0);
14204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ret < 0) {
14214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ALOGV("Device %s not disabled, no valid use case \
14224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              found: %d", ident2, errno);
14234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
14244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
14254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
14274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_use_case_set(uc_mgr, "_enadev", value);
14284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
14294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("Device %s not enabled, no valid use case found: %d",
14304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    value, errno);
14314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return ret;
14334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncmp(ident1, "_swmod", 6)) {
14344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
14354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
14364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGD("Invalid modifier value: %s, but enabling new modifier",
14374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ident2);
14384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
14394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_set(uc_mgr, "_dismod", ident2);
14404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret < 0) {
14414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Modifier %s not disabled, no valid use case \
14424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         found: %d", ident2, errno);
14434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
14444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_use_case_set(uc_mgr, "_enamod", value);
14464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
14474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("Modifier %s not enabled, no valid use case found: %d",
14484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    value, errno);
14494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return ret;
14514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
14524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("No switch device/modifier option found: %s", ident1);
14534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
14544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ident[0] = 0;
14554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
14564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
14574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strncmp(identifier, "_verb", 5)) {
14584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Check if value is valid verb */
14594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while (strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
14604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
14614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index], value,
14624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (strlen(value)+1))) {
14634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = 0;
14644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
14654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
14674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
14684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((ret < 0) && (strncmp(value, SND_USE_CASE_VERB_INACTIVE,
14694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlen(SND_USE_CASE_VERB_INACTIVE)))) {
14704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Invalid verb identifier value");
14714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
14724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Verb:%s", index,
14734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->card_ctxt_ptr->verb_list[index]);
14744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Disable the mixer controls for current use case
14754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * for all the enabled devices */
14764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
14774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_USE_CASE_VERB_INACTIVE,
14784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlen(SND_USE_CASE_VERB_INACTIVE))) {
14794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = set_controls_of_usecase_for_all_devices(uc_mgr,
14804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      uc_mgr->card_ctxt_ptr->current_verb, 0, CTRL_LIST_VERB);
14814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret != 0)
14824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGE("Failed to disable controls for use case: %s",
14834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        uc_mgr->card_ctxt_ptr->current_verb);
14844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(uc_mgr->card_ctxt_ptr->current_verb, value, MAX_STR_LEN);
14864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Enable the mixer controls for the new use case
14874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * for all the enabled devices */
14884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
14894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               SND_USE_CASE_VERB_INACTIVE,
14904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               strlen(SND_USE_CASE_VERB_INACTIVE))) {
14914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               uc_mgr->card_ctxt_ptr->current_verb_index = index;
14924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               ret = set_controls_of_usecase_for_all_devices(uc_mgr,
14934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     uc_mgr->card_ctxt_ptr->current_verb, 1, CTRL_LIST_VERB);
14944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
14954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
14964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_enadev", 7)) {
14974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index = 0; ret = 0;
14984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list_size =
14994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
15004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for (index = 0; index < list_size; index++) {
15014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if ((ident1 =
15024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
15034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
15044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!strncmp(ident1, value, (strlen(value)+1))) {
15054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Ignore enable as %s device is already part of \
15064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         enabled list", value);
15074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free(ident1);
15084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
15094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
15104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(ident1);
15114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
15124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (index == list_size) {
15144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("enadev: device value to be enabled: %s", value);
15154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
15164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                value);
15174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_print_list(uc_mgr->card_ctxt_ptr->dev_list_head);
15194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Apply Mixer controls of all verb and modifiers for this device*/
15204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = set_controls_of_device_for_all_usecases(uc_mgr, value, 1);
15214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_disdev", 7)) {
15224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_ucm_get_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
15234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  value);
15244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ret < 0) {
15254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGD("disdev: device %s not enabled, no need to disable", value);
15264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (ret == 0) {
15274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("disdev: device %s not active, remove from the list", value);
15284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret =
15294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
15304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            value);
15314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
15324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid device: Device not part of enabled device list");
15334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
15344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
15354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret =
15364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
15374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            value);
15384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
15394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid device: Device not part of enabled device list");
15404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
15414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("disdev: device value to be disabled: %s", value);
15424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index = get_use_case_index(uc_mgr, value, CTRL_LIST_DEVICE);
15434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                /* Apply Mixer controls for corresponding device and modifier */
15444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_apply_mixer_controls(uc_mgr, value, 0,
15454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          CTRL_LIST_DEVICE, index);
15464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
15474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_enamod", 7)) {
15494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index = 0; ret = 0;
15504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
15514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (verb_index < 0) {
15524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Invalid verb identifier value");
15534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
15544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Verb:%s", verb_index,
15554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 uc_mgr->card_ctxt_ptr->verb_list[verb_index]);
15564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
15574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while(strncmp(verb_list[verb_index].modifier_list[index], value,
15584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  (strlen(value)+1))) {
15594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!strncmp(verb_list[verb_index].modifier_list[index],
15604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))){
15614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -EINVAL;
15624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
15634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
15644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index++;
15654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
15664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
15674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid modifier identifier value");
15684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
15694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
15704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    value);
15714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                /* Enable the mixer controls for the new use case
15724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 * for all the enabled devices */
15734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = set_controls_of_usecase_for_all_devices(uc_mgr, value, 1,
15744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          CTRL_LIST_MODIFIER);
15754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
15764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_dismod", 7)) {
15784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
15794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  value);
15804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ret < 0) {
15814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Modifier not enabled currently, invalid modifier");
15824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
15834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("dismod: modifier value to be disabled: %s", value);
15844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Enable the mixer controls for the new use case
15854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * for all the enabled devices */
15864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = set_controls_of_usecase_for_all_devices(uc_mgr, value, 0,
15874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      CTRL_LIST_MODIFIER);
15884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
15894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
15904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Unknown identifier value: %s", identifier);
15914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
15924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
15934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
15944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
15954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
15964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
15974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Set new value for an identifier based on use case
15984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - UCM structure
15994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * identifier - _verb, _enadev, _disdev, _enamod, _dismod
16004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *        _swdev, _swmod
16014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * value - Value to be set
16024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * usecase - usecase/device for which this command needs to be executed
16034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns 0 on success, otherwise a negative error code
16044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
16054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_set_case(snd_use_case_mgr_t *uc_mgr,
16064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     const char *identifier,
16074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     const char *value, const char *usecase)
16084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
16094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
16104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char ident[MAX_STR_LEN], *ident1, *ident2, *temp_ptr;
16114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int verb_index, list_size, index = 0, ret = -EINVAL;
16124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
16134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
16144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) || (value == NULL) ||
16154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL) ||
16164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (identifier == NULL)) {
16174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_set_case(): failed, invalid arguments");
16184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
16194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
16204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
16214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
16224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGD("snd_use_case_set_case(): uc_mgr %p identifier %s value %s",
16234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr, identifier, value);
16244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(ident, identifier, sizeof(ident));
16254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
16264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("No multiple identifiers found in identifier value");
16274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ident[0] = 0;
16284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
16294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(ident1, "_swdev", 6)) {
16304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
16314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGD("Invalid disable device value: %s, but enabling new \
16324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     device", ident2);
16334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
16344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_ucm_del_ident_from_list(
16354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          &uc_mgr->card_ctxt_ptr->dev_list_head, ident2);
16364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret < 0) {
16374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Ignore device %s disable, device not part of \
16384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         enabled list", ident2);
16394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
16404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("swdev: device value to be disabled: %s", ident2);
16414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    /* Disable mixer controls for
16424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     * corresponding use cases and device */
16434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = set_controls_of_device_for_usecase(uc_mgr, ident2,
16444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              usecase, 0);
16454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ret < 0) {
16464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ALOGV("Device %s not disabled, no valid use case \
16474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                             found: %d", ident2, errno);
16484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
16494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
16504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
16514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
16524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_use_case_set_case(uc_mgr, "_enadev", value, usecase);
16534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
16544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("Device %s not enabled, no valid use case found: %d",
16554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    value, errno);
16564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
16574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return ret;
16584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncmp(ident1, "_swmod", 6)) {
16594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
16604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
16614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGD("Invalid modifier value: %s, but enabling new modifier",
16624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ident2);
16634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
16644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_use_case_set_case(uc_mgr, "_dismod", ident2, usecase);
16654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret < 0) {
16664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Modifier %s not disabled, no valid use case \
16674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         found: %d", ident2, errno);
16684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
16694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
16704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_use_case_set_case(uc_mgr, "_enamod", value, usecase);
16714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
16724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("Modifier %s not enabled, no valid use case found: %d",
16734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    value, errno);
16744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
16754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return ret;
16764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
16774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("No switch device/modifier option found: %s", ident1);
16784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
16794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ident[0] = 0;
16804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
16814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
16824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!strncmp(identifier, "_verb", 5)) {
16834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Check if value is valid verb */
16844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while (strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
16854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               SND_UCM_END_OF_LIST, MAX_STR_LEN)) {
16864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
16874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                value, MAX_STR_LEN)) {
16884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = 0;
16894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
16904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
16914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
16924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
16934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((ret < 0) && (strncmp(value, SND_USE_CASE_VERB_INACTIVE,
16944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_STR_LEN))) {
16954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Invalid verb identifier value");
16964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
16974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Verb:%s", index,
16984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 uc_mgr->card_ctxt_ptr->verb_list[index]);
16994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Disable the mixer controls for current use case
17004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * for specified device */
17014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
17024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
17034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = set_controls_of_usecase_for_device(uc_mgr,
17044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          uc_mgr->card_ctxt_ptr->current_verb, usecase,
17054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          0, CTRL_LIST_VERB);
17064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret != 0)
17074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGE("Failed to disable controls for use case: %s",
17084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        uc_mgr->card_ctxt_ptr->current_verb);
17094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
17104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(uc_mgr->card_ctxt_ptr->current_verb, value, MAX_STR_LEN);
17114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Enable the mixer controls for the new use case
17124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * for specified device */
17134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
17144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
17154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               uc_mgr->card_ctxt_ptr->current_verb_index = index;
17164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               index = 0;
17174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               list_size =
17184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
17194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               for (index = 0; index < list_size; index++) {
17204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   if ((ident1 = snd_ucm_get_value_at_index(
17214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       uc_mgr->card_ctxt_ptr->dev_list_head, index))) {
17224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       if (!strncmp(ident1, usecase, MAX_STR_LEN)) {
17234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           ALOGV("Device already part of enabled list: %s",
17244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                               usecase);
17254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           free(ident1);
17264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           break;
17274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       }
17284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       free(ident1);
17294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   }
17304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               }
17314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               if (index == list_size) {
17324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   ALOGV("enadev: device value to be enabled: %s", usecase);
17334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
17344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        usecase);
17354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               }
17364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               ret = set_controls_of_usecase_for_device(uc_mgr,
17374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         uc_mgr->card_ctxt_ptr->current_verb, usecase,
17384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         1, CTRL_LIST_VERB);
17394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
17404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
17414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_enadev", 7)) {
17424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index = 0; ret = 0;
17434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list_size =
17444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
17454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for (index = 0; index < list_size; index++) {
17464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if ((ident1 =
17474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
17484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
17494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!strncmp(ident1, value, MAX_STR_LEN)) {
17504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("Device already part of enabled list: %s", value);
17514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free(ident1);
17524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
17534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
17544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(ident1);
17554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
17564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
17574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (index == list_size) {
17584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("enadev: device value to be enabled: %s", value);
17594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
17604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                value);
17614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
17624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_print_list(uc_mgr->card_ctxt_ptr->dev_list_head);
17634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Apply Mixer controls of usecase for this device*/
17644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = set_controls_of_device_for_usecase(uc_mgr, value, usecase, 1);
17654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_disdev", 7)) {
17664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_ucm_get_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
17674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  value);
17684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ret < 0) {
17694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGD("disdev: device %s not enabled, no need to disable", value);
17704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (ret == 0) {
17714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("disdev: device %s not active, remove from the list", value);
17724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret =
17734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
17744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            value);
17754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
17764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid device: Device not part of enabled device list");
17774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
17784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
17794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret =
17804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
17814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            value);
17824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
17834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid device: Device not part of enabled device list");
17844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
17854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGV("disdev: device value to be disabled: %s", value);
17864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                /* Apply Mixer controls of usecase for this device*/
17874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = set_controls_of_device_for_usecase(uc_mgr, value,
17884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                          usecase, 0);
17894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
17904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
17914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_enamod", 7)) {
17924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
17934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
17944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Invalid use case verb value");
17954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -EINVAL;
17964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
17974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = 0;
17984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while(strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
17994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  uc_mgr->card_ctxt_ptr->current_verb, MAX_STR_LEN)) {
18004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
18014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    SND_UCM_END_OF_LIST, MAX_STR_LEN)){
18024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -EINVAL;
18034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
18044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
18054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index++;
18064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
18074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
18084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ret < 0) {
18094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Invalid verb identifier value");
18104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
18114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_index = index; index = 0; ret = 0;
18124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
18134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Index:%d Verb:%s", verb_index,
18144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 uc_mgr->card_ctxt_ptr->verb_list[verb_index]);
18154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while(strncmp(verb_list[verb_index].modifier_list[index],
18164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                value, MAX_STR_LEN)) {
18174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (!strncmp(verb_list[verb_index].modifier_list[index],
18184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    SND_UCM_END_OF_LIST, MAX_STR_LEN)){
18194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -EINVAL;
18204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
18214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
18224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index++;
18234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
18244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
18254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Invalid modifier identifier value");
18264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
18274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index = 0;
18284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list_size =
18294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
18304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                for (index = 0; index < list_size; index++) {
18314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if ((ident1 = snd_ucm_get_value_at_index(
18324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        uc_mgr->card_ctxt_ptr->dev_list_head, index))) {
18334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (!strncmp(ident1, usecase, MAX_STR_LEN)) {
18344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ALOGV("Device already part of enabled list: %s",
18354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                usecase);
18364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            free(ident1);
18374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
18384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
18394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        free(ident1);
18404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
18414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
18424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (index == list_size) {
18434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGV("enadev: device value to be enabled: %s", usecase);
18444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
18454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         usecase);
18464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
18474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
18484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    value);
18494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                /* Enable the mixer controls for the new use case
18504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 * for all the enabled devices */
18514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = set_controls_of_usecase_for_device(uc_mgr, value,
18524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      usecase, 1, CTRL_LIST_MODIFIER);
18534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
18544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
18554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp(identifier, "_dismod", 7)) {
18564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
18574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev              value);
18584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ret < 0) {
18594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Modifier not enabled currently, invalid modifier");
18604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
18614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("dismod: modifier value to be disabled: %s", value);
18624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Enable the mixer controls for the new use case
18634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * for all the enabled devices */
18644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = set_controls_of_usecase_for_device(uc_mgr, value, usecase,
18654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      0, CTRL_LIST_MODIFIER);
18664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
18674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
18684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Unknown identifier value: %s", identifier);
18694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
18704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
18714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
18724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
18734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
18744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
18754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Open and initialise use case core for sound card
18764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - Returned use case manager pointer
18774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * card_name - Sound card name.
18784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * returns 0 on success, otherwise a negative error code
18794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
18804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, const char *card_name)
18814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
18824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_use_case_mgr_t *uc_mgr_ptr = NULL;
18834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index, ret = -EINVAL;
18844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char tmp[2];
18854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
18864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("snd_use_case_open(): card_name %s", card_name);
18874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
18884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (card_name == NULL) {
18894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_mgr_open: failed, invalid arguments");
18904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return ret;
18914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
18924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
18934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for (index = 0; index < (int)MAX_NUM_CARDS; index++) {
18944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(!strncmp(card_name, card_mapping_list[index].card_name,
18954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev           (strlen(card_mapping_list[index].card_name)+1))) {
18964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = 0;
18974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
18984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
18994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
19004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
19014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ret < 0) {
19024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Card %s not found", card_name);
19034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
19044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr = (snd_use_case_mgr_t *)calloc(1,
19054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                         sizeof(snd_use_case_mgr_t));
19064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr_ptr == NULL) {
19074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to allocate memory for instance");
19084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -ENOMEM;
19094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
19104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->snd_card_index = index;
19114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->card_ctxt_ptr = (card_ctxt_t *)calloc(1,
19124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                        sizeof(card_ctxt_t));
19134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr_ptr->card_ctxt_ptr == NULL) {
19144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to allocate memory for card context");
19154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr_ptr);
19164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr_ptr = NULL;
19174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -ENOMEM;
19184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
19194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->card_ctxt_ptr->card_number =
19204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            card_mapping_list[index].card_number;
19214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->card_ctxt_ptr->card_name =
19224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (char *)malloc((strlen(card_name)+1)*sizeof(char));
19234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr_ptr->card_ctxt_ptr->card_name == NULL) {
19244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to allocate memory for card name");
19254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr_ptr->card_ctxt_ptr);
19264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr_ptr);
19274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr_ptr = NULL;
19284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -ENOMEM;
19294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
19304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(uc_mgr_ptr->card_ctxt_ptr->card_name, card_name,
19314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ((strlen(card_name)+1)*sizeof(char)));
19324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->card_ctxt_ptr->control_device =
19334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (char *)malloc((strlen("/dev/snd/controlC")+2)*sizeof(char));
19344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (uc_mgr_ptr->card_ctxt_ptr->control_device == NULL) {
19354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to allocate memory for control device string");
19364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr_ptr->card_ctxt_ptr->card_name);
19374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr_ptr->card_ctxt_ptr);
19384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr_ptr);
19394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr_ptr = NULL;
19404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -ENOMEM;
19414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
19424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(uc_mgr_ptr->card_ctxt_ptr->control_device,
19434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            "/dev/snd/controlC", 18);
19444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snprintf(tmp, sizeof(tmp), "%d",
19454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr_ptr->card_ctxt_ptr->card_number);
19464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcat(uc_mgr_ptr->card_ctxt_ptr->control_device, tmp,
19474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (strlen("/dev/snd/controlC")+2)*sizeof(char));
19484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->device_list_count = 0;
19494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->modifier_list_count = 0;
19504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->current_device_list = NULL;
19514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->current_modifier_list = NULL;
19524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->current_tx_device = -1;
19534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->current_rx_device = -1;
19544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutexattr_init(&uc_mgr_ptr->card_ctxt_ptr->card_lock_attr);
19554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_init(&uc_mgr_ptr->card_ctxt_ptr->card_lock,
19564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            &uc_mgr_ptr->card_ctxt_ptr->card_lock_attr);
19574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(uc_mgr_ptr->card_ctxt_ptr->current_verb,
19584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN);
19594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Reset all mixer controls if any applied
19604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         * previously for the same card */
19619efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani    snd_use_case_mgr_reset(uc_mgr_ptr);
19624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->card_ctxt_ptr->current_verb_index = -1;
19634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Parse config files and update mixer controls */
19644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = snd_ucm_parse(&uc_mgr_ptr);
19654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(ret < 0) {
19664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to parse config files: %d", ret);
19674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_free_mixer_list(&uc_mgr_ptr);
19684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
19694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Open mixer device: %s",
19704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr_ptr->card_ctxt_ptr->control_device);
19714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr_ptr->card_ctxt_ptr->mixer_handle =
19724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            mixer_open(uc_mgr_ptr->card_ctxt_ptr->control_device);
19734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Mixer handle %p", uc_mgr_ptr->card_ctxt_ptr->mixer_handle);
19744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *uc_mgr = uc_mgr_ptr;
19754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
19764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("snd_use_case_open(): returning instance %p", uc_mgr_ptr);
19774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
19784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
19794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
19804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
19814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
19824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \brief Reload and re-parse use case configuration files for sound card.
19834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \param uc_mgr Use case manager
19844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \return zero if success, otherwise a negative error code
19854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
19864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr) {
19874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGE("Reload is not implemented for now as there is no use case currently");
19884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
19894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
19904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
19914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
19924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \brief Close use case manager
19934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \param uc_mgr Use case manager
19944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \return zero if success, otherwise a negative error code
19954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
19964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr)
19974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
19984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = 0;
19994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
20004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
20014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
20024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_mgr_close(): failed, invalid arguments");
20034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
20044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
20054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
20064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("snd_use_case_close(): instance %p", uc_mgr);
20074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ret = snd_use_case_mgr_reset(uc_mgr);
20084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ret < 0)
20094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to reset ucm session");
20104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_ucm_free_mixer_list(&uc_mgr);
20114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutexattr_destroy(&uc_mgr->card_ctxt_ptr->card_lock_attr);
20124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_destroy(&uc_mgr->card_ctxt_ptr->card_lock);
20134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (uc_mgr->card_ctxt_ptr->mixer_handle) {
20144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        mixer_close(uc_mgr->card_ctxt_ptr->mixer_handle);
20154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->card_ctxt_ptr->mixer_handle = NULL;
20164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
20174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr->snd_card_index = -1;
20184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr->current_tx_device = -1;
20194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr->current_rx_device = -1;
20204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(uc_mgr->card_ctxt_ptr->control_device);
20214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(uc_mgr->card_ctxt_ptr->card_name);
20224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(uc_mgr->card_ctxt_ptr);
20234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr->card_ctxt_ptr = NULL;
20244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(uc_mgr);
20254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr = NULL;
20264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("snd_use_case_mgr_close(): card instace closed successfully");
20274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
20284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
20294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
20304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/**
20314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \brief Reset use case manager verb, device, modifier to deafult settings.
20324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \param uc_mgr Use case manager
20334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * \return zero if success, otherwise a negative error code
20344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
20354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr)
20364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
20374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *ident_value;
20384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index, list_size, ret = 0;
20394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
20404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("snd_use_case_reset(): instance %p", uc_mgr);
20414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
20424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
20434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
20444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("snd_use_case_mgr_reset(): failed, invalid arguments");
20454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
20464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
20474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
20484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
20494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Disable mixer controls of all the enabled modifiers */
20504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
20514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for (index = (list_size-1); index >= 0; index--) {
20524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((ident_value =
20534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
20544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
20554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
20564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ident_value);
20574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = set_controls_of_usecase_for_all_devices(uc_mgr,
20584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      ident_value, 0, CTRL_LIST_MODIFIER);
20599efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani        if (ret != 0)
20604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Failed to disable mixer controls for %s", ident_value);
20614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(ident_value);
20624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
20634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
20644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Clear the enabled modifiers list */
20654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (uc_mgr->modifier_list_count) {
20664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for (index = 0; index < uc_mgr->modifier_list_count; index++) {
20674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr->current_modifier_list[index]);
20684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->current_modifier_list[index] = NULL;
20694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
20704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(uc_mgr->current_modifier_list);
20714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->current_modifier_list = NULL;
20724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->modifier_list_count = 0;
20734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
20744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Disable mixer controls of current use case verb */
20754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
20764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev       strlen(SND_USE_CASE_VERB_INACTIVE))) {
20774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = set_controls_of_usecase_for_all_devices(uc_mgr,
20784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  uc_mgr->card_ctxt_ptr->current_verb, 0, CTRL_LIST_VERB);
20794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ret != 0)
20804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to disable mixer controls for %s",
20814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                uc_mgr->card_ctxt_ptr->current_verb);
20824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
20834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            MAX_STR_LEN);
20844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
20854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Disable mixer controls of all the enabled devices */
20864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
20874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for (index = (list_size-1); index >= 0; index--) {
20884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((ident_value =
20894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
20904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index))) {
20914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
20924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ident_value);
20934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = set_controls_of_device_for_all_usecases(uc_mgr,
20944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      ident_value, 0);
20959efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani        if (ret != 0)
20964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Failed to disable or no mixer controls set for %s",
20974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ident_value);
20989efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani        free(ident_value);
20994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
21004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
21014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Clear the enabled devices list */
21024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (uc_mgr->device_list_count) {
21034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for (index = 0; index < uc_mgr->device_list_count; index++) {
21044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(uc_mgr->current_device_list[index]);
21054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->current_device_list[index] = NULL;
21064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
21074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(uc_mgr->current_device_list);
21084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->current_device_list = NULL;
21094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        uc_mgr->device_list_count = 0;
21104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
21114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr->current_tx_device = -1;
21124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    uc_mgr->current_rx_device = -1;
21134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
21144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
21154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
21164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
21174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* 2nd stage parsing done in seperate thread */
21184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid *second_stage_parsing_thread(void *uc_mgr_ptr)
21194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
21204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
21214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char path[200];
21224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct stat st;
21234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int fd, index = 0, ret = 0, rc = 0;
21244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *read_buf = NULL, *next_str = NULL, *current_str = NULL, *buf = NULL;
21254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p = NULL, *verb_name = NULL, *file_name = NULL, *temp_ptr = NULL;
21264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    snd_use_case_mgr_t **uc_mgr = (snd_use_case_mgr_t **)&uc_mgr_ptr;
21274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
21284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(path, CONFIG_DIR, (strlen(CONFIG_DIR)+1));
21294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcat(path, (*uc_mgr)->card_ctxt_ptr->card_name, sizeof(path));
21304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("master config file path:%s", path);
21314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    fd = open(path, O_RDONLY);
21324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (fd < 0) {
21334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to open config file %s error %d\n", path, errno);
21344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NULL;
21354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
21364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (fstat(fd, &st) < 0) {
21374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to stat %s error %d\n", path, errno);
21384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
21394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NULL;
21404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
21414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
21424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               MAP_PRIVATE, fd, 0);
21434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (read_buf == MAP_FAILED) {
21444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to mmap file error %d\n", errno);
21454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
21464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NULL;
21474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
21484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = read_buf;
21494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_name = NULL;
21504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (*current_str != (char)EOF)  {
21514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
21524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
21534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
21544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
21554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (verb_name == NULL) {
21564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            buf = strstr(current_str, "SectionUseCase");
21574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (buf == NULL) {
21584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((current_str = next_str) == NULL)
21594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
21604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else
21614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    continue;
21624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
21634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Ignore parsing first use case (HiFi) as it is already parsed
21644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * in 1st stage of parsing */
21654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (index == 0) {
21664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index++;
21674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((current_str = next_str) == NULL)
21684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
21694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else
21704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    continue;
21714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
21724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            p = strtok_r(buf, ".", &temp_ptr);
21734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while (p != NULL) {
21744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                p = strtok_r(NULL, "\"", &temp_ptr);
21754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (p == NULL)
21764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
21774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_name = (char *)malloc((strlen(p)+1)*sizeof(char));
21784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if(verb_name == NULL) {
21794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
21804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
21814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
21824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(verb_name, p, (strlen(p)+1)*sizeof(char));
21834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
21844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
21854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
21864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            buf = strstr(current_str, "File");
21874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (buf == NULL) {
21884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((current_str = next_str) == NULL)
21894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
21904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else
21914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    continue;
21924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
21934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            p = strtok_r(buf, "\"", &temp_ptr);
21944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while (p != NULL) {
21954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                p = strtok_r(NULL, "\"", &temp_ptr);
21964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (p == NULL)
21974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
21984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                file_name = (char *)malloc((strlen(p)+1)*sizeof(char));
21994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if(file_name == NULL) {
22004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
22014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
22024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
22034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(file_name, p, (strlen(p)+1)*sizeof(char));
22044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
22054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
22064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
22074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (file_name != NULL) {
22084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_ucm_parse_verb(uc_mgr, file_name, index);
22094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[index].use_case_name =
22104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char *)malloc((strlen(verb_name)+1)*sizeof(char));
22114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(verb_list[index].use_case_name, verb_name,
22124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ((strlen(verb_name)+1)*sizeof(char)));
22134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                /* Verb list might have been appended with END OF LIST in
22144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 * 1st stage parsing. Delete this entry so that new verbs
22154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 * are appended from here and END OF LIST will be added
22164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 * again at the end of 2nd stage parsing
22174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 */
22184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((*uc_mgr)->card_ctxt_ptr->verb_list[index]) {
22194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free((*uc_mgr)->card_ctxt_ptr->verb_list[index]);
22204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (*uc_mgr)->card_ctxt_ptr->verb_list[index] = NULL;
22214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
22224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (*uc_mgr)->card_ctxt_ptr->verb_list[index] =
22234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char *)malloc((strlen(verb_name)+1)*sizeof(char));
22244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index], verb_name,
22254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ((strlen(verb_name)+1)*sizeof(char)));
22264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(verb_name);
22274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_name = NULL;
22284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(file_name);
22294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                file_name = NULL;
22304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
22314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
22324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (*uc_mgr)->card_ctxt_ptr->verb_list[index] =
22334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
22344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
22354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 SND_UCM_END_OF_LIST,
22364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
22374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
22384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
22394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
22404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
22414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (verb_name != NULL) {
22424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(verb_name);
22434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_name = NULL;
22444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
22454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (file_name != NULL) {
22464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(file_name);
22474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        file_name = NULL;
22484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
22494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    munmap(read_buf, st.st_size);
22504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    close(fd);
22514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#if PARSE_DEBUG
22524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Prints use cases and mixer controls parsed from config files */
22534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_print((*uc_mgr));
22544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
22554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(ret < 0)
22564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to parse config files: %d", ret);
22574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGE("Exiting parsing thread uc_mgr %p\n", uc_mgr);
22584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return NULL;
22594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
22604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
22614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Function can be used by UCM clients to wait until parsing completes
22624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - use case manager structure
22634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on success, error number otherwise
22644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev*/
22654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint snd_use_case_mgr_wait_for_parsing(snd_use_case_mgr_t *uc_mgr)
22664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
22674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret;
22684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
22694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ret = pthread_join(uc_mgr->thr, NULL);
22704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
22714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
22724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
22734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Parse config files and update mixer controls for the use cases
22744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * 1st stage parsing done to parse HiFi config file
22754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - use case manager structure
22764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
22774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
22784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_parse(snd_use_case_mgr_t **uc_mgr)
22794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
22804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
22814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct stat st;
22824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int fd, verb_count, index = 0, ret = 0, rc;
22834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *read_buf, *next_str, *current_str, *buf, *p, *verb_name;
22844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *file_name = NULL, *temp_ptr;
22854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char path[200];
22864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
22874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(path, CONFIG_DIR, (strlen(CONFIG_DIR)+1));
22884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcat(path, (*uc_mgr)->card_ctxt_ptr->card_name, sizeof(path));
22894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("master config file path:%s", path);
22904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    fd = open(path, O_RDONLY);
22914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (fd < 0) {
22924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to open config file %s error %d\n", path, errno);
22934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
22944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
22954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (fstat(fd, &st) < 0) {
22964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to stat %s error %d\n", path, errno);
22974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
22984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
22994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
23004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
23014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               MAP_PRIVATE, fd, 0);
23024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (read_buf == MAP_FAILED) {
23034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to mmap file error %d\n", errno);
23044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
23054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
23064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
23074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = read_buf;
23084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_count = get_verb_count(current_str);
23094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    (*uc_mgr)->card_ctxt_ptr->use_case_verb_list =
23104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (use_case_verb_t *)malloc((verb_count+1)*(sizeof(use_case_verb_t)));
23114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((*uc_mgr)->card_ctxt_ptr->use_case_verb_list == NULL) {
23124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to allocate memory for use case verb list\n");
23134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        munmap(read_buf, st.st_size);
23144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
23154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
23164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
23174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (((*uc_mgr)->card_ctxt_ptr->verb_list =
23184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (char **)malloc((verb_count+2)*(sizeof(char *)))) == NULL) {
23194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("failed to allocate memory for verb list\n");
23204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        munmap(read_buf, st.st_size);
23214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
23224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
23234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
23244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_name = NULL;
23254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((ret = is_single_config_format(current_str))) {
23264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("Single config file format detected\n");
23274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = parse_single_config_format(uc_mgr, current_str, verb_count);
23284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        munmap(read_buf, st.st_size);
23294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
23304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return ret;
23314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
23324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (*current_str != (char)EOF)  {
23334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
23344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
23354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
23364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
23374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (verb_name == NULL) {
23384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            buf = strstr(current_str, "SectionUseCase");
23394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (buf == NULL) {
23404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((current_str = next_str) == NULL)
23414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else
23434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    continue;
23444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
23454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
23464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            p = strtok_r(buf, ".", &temp_ptr);
23474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while (p != NULL) {
23484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                p = strtok_r(NULL, "\"", &temp_ptr);
23494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (p == NULL)
23504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_name = (char *)malloc((strlen(p)+1)*sizeof(char));
23524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if(verb_name == NULL) {
23534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
23544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
23564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(verb_name, p, (strlen(p)+1)*sizeof(char));
23574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((verb_list[index].use_case_name =
23584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char *)malloc((strlen(verb_name)+1)*sizeof(char)))) {
23594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy(verb_list[index].use_case_name,
23604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        verb_name, ((strlen(verb_name)+1)*sizeof(char)));
23614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
23624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
23634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
23654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
23664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char *)malloc((strlen(verb_name)+1)*sizeof(char)))) {
23674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
23684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        verb_name, ((strlen(verb_name)+1)*sizeof(char)));
23694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
23704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
23714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
23734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
23744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
23754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
23764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            buf = strstr(current_str, "File");
23774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (buf == NULL) {
23784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if((current_str = next_str) == NULL)
23794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                else
23814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    continue;
23824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
23834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            p = strtok_r(buf, "\"", &temp_ptr);
23844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while (p != NULL) {
23854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                p = strtok_r(NULL, "\"", &temp_ptr);
23864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (p == NULL)
23874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                file_name = (char *)malloc((strlen(p)+1)*sizeof(char));
23894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if(file_name == NULL) {
23904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
23914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
23924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
23934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(file_name, p, (strlen(p)+1)*sizeof(char));
23944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
23954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
23964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (file_name != NULL) {
23974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = snd_ucm_parse_verb(uc_mgr, file_name, index);
23984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (ret < 0)
23994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ALOGE("Failed to parse config file %s\n", file_name);
24004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(verb_name);
24014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_name = NULL;
24024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(file_name);
24034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                file_name = NULL;
24044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
24054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
24064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            /* Break here so that only one first use case config file (HiFi)
24074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * from master config file is parsed initially and all other
24084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * config files are parsed in seperate thread created below so
24094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             * that audio HAL can initialize faster during boot-up
24104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             */
24114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
24124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
24134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
24144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
24154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
24164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    munmap(read_buf, st.st_size);
24174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    close(fd);
24184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
24194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)))) {
24204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index], SND_UCM_END_OF_LIST,
24214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
24224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
24234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory\n");
24244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = -ENOMEM;
24254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
24264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (!ret) {
24274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("Creating Parsing thread uc_mgr %p\n", uc_mgr);
24284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        rc = pthread_create(&(*uc_mgr)->thr, 0, second_stage_parsing_thread,
24294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 (void*)(*uc_mgr));
24304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(rc < 0) {
24314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to create parsing thread rc %d errno %d\n", rc, errno);
24324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
24334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Prasing thread created successfully\n");
24344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
24354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
24364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (verb_name)
24374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(verb_name);
24384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (file_name)
24394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(file_name);
24404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
24414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
24424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
24434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Parse a single config file format
24444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - use case manager structure
24454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * buf - config file buffer to be parsed
24464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
24474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
24484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int parse_single_config_format(snd_use_case_mgr_t **uc_mgr,
24494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevchar *current_str, int num_verbs)
24504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
24514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct stat st;
24524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *list;
24534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
24544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int verb_count = 0, device_count = 0, mod_count = 0, index = -1, ret = 0;
24554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *next_str, *buf, *p, *verb_ptr, *temp_ptr;
24564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
24574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
24584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (*current_str != (char)EOF)  {
24594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
24604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
24614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
24624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
24634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((buf = strcasestr(current_str, "SectionUseCase")) != NULL) {
24644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (index != -1) {
24654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list = (verb_list[index].verb_ctrls +
24664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            verb_list[index].verb_count);
24674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->case_name = (char *)
24684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
24694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if(list->case_name == NULL) {
24704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free(verb_list[index].verb_ctrls);
24714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return -ENOMEM;
24724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
24734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(list->case_name, SND_UCM_END_OF_LIST,
24744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
24754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->ena_mixer_list = NULL;
24764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->dis_mixer_list = NULL;
24774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->ena_mixer_count = 0;
24784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->dis_mixer_count = 0;
24794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->playback_dev_name = NULL;
24804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->capture_dev_name = NULL;
24814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->acdb_id = 0;
24824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->capability = 0;
24834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
24844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            index++;
24854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            p = strtok_r(buf, ".", &temp_ptr);
24864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while (p != NULL) {
24874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                p = strtok_r(NULL, "\"", &temp_ptr);
24884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (p == NULL)
24894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
24904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((verb_list[index].use_case_name =
24914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char *)malloc((strlen(p)+1)*sizeof(char)))) {
24924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy(verb_list[index].use_case_name,
24934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        p, ((strlen(p)+1)*sizeof(char)));
24944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
24954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
24964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
24974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
24984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
24994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char *)malloc((strlen(p)+1)*sizeof(char)))) {
25004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
25014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       p, ((strlen(p)+1)*sizeof(char)));
25024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
25034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
25044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
25054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
25064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
25074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
25084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_count = 0;
25094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_count = 0;
25104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].mod_count = 0;
25114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_list = NULL;
25124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].modifier_list = NULL;
25134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_ctrls = NULL;
25144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_ctrls = NULL;
25154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].mod_ctrls = NULL;
25164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_count = get_num_verbs_config_format(next_str);
25174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_ctrls = (card_mctrl_t *)
25184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                malloc((verb_count+1)*sizeof(card_mctrl_t));
25194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_list[index].verb_ctrls == NULL) {
25204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               ret = -ENOMEM;
25214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               break;
25224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
25234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_count = 0;
25244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncasecmp(current_str, "SectionVerb", 11)) {
25254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_parse_section(uc_mgr, &current_str,
25264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    &next_str, index, CTRL_LIST_VERB);
25274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
25284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
25294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncasecmp(current_str, "SectionDevice", 13)) {
25304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (device_count == 0) {
25314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                device_count = get_num_device_config_format(next_str);
25324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].device_ctrls = (card_mctrl_t *)
25334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    malloc((device_count+1)*sizeof(card_mctrl_t));
25344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_list[0].device_ctrls == NULL) {
25354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
25364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
25374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
25384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].device_list =
25394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char **)malloc((device_count+1)*sizeof(char *));
25404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_list[0].device_list == NULL)
25414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return -ENOMEM;
25424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].device_count = 0;
25434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
25444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_parse_section(uc_mgr, &current_str,
25454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      &next_str, 0, CTRL_LIST_DEVICE);
25464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
25474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
25484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
25494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list = (verb_list[0].device_ctrls +
25504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                           (verb_list[0].device_count - 1));
25514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_ptr = (char *)
25524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    malloc((strlen(list->case_name)+1)*sizeof(char));
25534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (verb_ptr == NULL) {
25544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ret = -ENOMEM;
25554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
25564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
25574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    strlcpy(verb_ptr, list->case_name,
25584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        ((strlen(list->case_name)+1)*sizeof(char)));
25594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    verb_list[0].device_list[(verb_list[0].device_count-1)]
25604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        = verb_ptr;
25614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
25624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (!strncasecmp(current_str, "SectionModifier", 15)) {
25634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (mod_count == 0) {
25644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                mod_count = get_num_mod_config_format(next_str);
25654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].mod_ctrls = (card_mctrl_t *)
25664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    malloc((mod_count+1)*sizeof(card_mctrl_t));
25674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_list[0].mod_ctrls == NULL) {
25684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
25694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
25704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
25714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].modifier_list =
25724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    (char **)malloc((mod_count+1)*sizeof(char *));
25734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_list[0].modifier_list == NULL)
25744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    return -ENOMEM;
25754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].mod_count = 0;
25764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
25774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_parse_section(uc_mgr, &current_str,
25784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                     &next_str, 0, CTRL_LIST_MODIFIER);
25794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0) {
25804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
25814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else {
25824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list = (verb_list[0].mod_ctrls +
25834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        (verb_list[0].mod_count - 1));
25844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_ptr = (char *)
25854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    malloc((strlen(list->case_name)+1)*sizeof(char));
25864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (verb_ptr == NULL) {
25874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
25884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
25894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
25904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                strlcpy(verb_ptr, list->case_name,
25914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   ((strlen(list->case_name)+1)*sizeof(char)));
25924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                verb_list[0].modifier_list[(verb_list[0].mod_count - 1)]
25934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    = verb_ptr;
25944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
25954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
25964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
25974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
25984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
25994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list = (verb_list[index].verb_ctrls +
26004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_count);
26014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->case_name =
26024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(list->case_name == NULL) {
26044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(verb_list[index].verb_ctrls);
26054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
26064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
26074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(list->case_name, SND_UCM_END_OF_LIST,
26084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_list = NULL;
26104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_list = NULL;
26114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_count = 0;
26124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_count = 0;
26134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->playback_dev_name = NULL;
26144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capture_dev_name = NULL;
26154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->acdb_id = 0;
26164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capability = 0;
26174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    index++;
26184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (index != -1) {
26194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
26204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)))) {
26214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
26224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                SND_UCM_END_OF_LIST,
26234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
26244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
26254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Failed to allocate memory\n");
26264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -ENOMEM;
26274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
26284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
26294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Add end of list to device list */
26304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_ptr =
26314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev       (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (verb_ptr == NULL)
26334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
26344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
26354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
26364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list[0].device_list[verb_list[0].device_count] = verb_ptr;
26374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Add end of list to modifier list */
26384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_ptr =
26394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (verb_ptr == NULL)
26414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -ENOMEM;
26424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
26434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
26444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list[0].modifier_list[verb_list[0].mod_count] = verb_ptr;
26454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Add end of list to device controls list */
26464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list = (verb_list[0].device_ctrls +
26474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               verb_list[0].device_count);
26484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->case_name =
26494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(list->case_name == NULL) {
26514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(verb_list[0].device_ctrls);
26524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
26534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
26544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(list->case_name, SND_UCM_END_OF_LIST,
26554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_list = NULL;
26574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_list = NULL;
26584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_count = 0;
26594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_count = 0;
26604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->playback_dev_name = NULL;
26614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capture_dev_name = NULL;
26624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->acdb_id = 0;
26634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capability = 0;
26644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    /* Add end of list to modifier controls list */
26654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list = (verb_list[0].mod_ctrls +
26664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[0].mod_count);
26674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->case_name =
26684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(list->case_name == NULL) {
26704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(verb_list[0].mod_ctrls);
26714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
26724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
26734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(list->case_name, SND_UCM_END_OF_LIST,
26744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
26754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_list = NULL;
26764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_list = NULL;
26774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_count = 0;
26784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_count = 0;
26794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->playback_dev_name = NULL;
26804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capture_dev_name = NULL;
26814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->acdb_id = 0;
26824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capability = 0;
26834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for (index = 1; index < num_verbs; index++) {
26844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[index].device_ctrls = verb_list[0].device_ctrls;
26854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[index].device_list = verb_list[0].device_list;
26864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[index].device_count = verb_list[0].device_count;
26874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[index].mod_ctrls = verb_list[0].mod_ctrls;
26884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[index].modifier_list = verb_list[0].modifier_list;
26894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_list[index].mod_count = verb_list[0].mod_count;
26904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
26914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ret < 0) {
26924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to parse config file ret %d errno %d\n", ret, errno);
26934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
26944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Prasing done successfully\n");
26954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#if PARSE_DEBUG
26964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        /* Prints use cases and mixer controls parsed from config files */
26974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        snd_ucm_print((*uc_mgr));
26984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif
26994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
27014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
27024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Returns number of verb sections for specific use case verb*/
27044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_num_verbs_config_format(const char *nxt_str)
27054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
27064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_str, *next_str, *str_addr, *buf;
27074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int count = 0;
27084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
27104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (next_str == NULL) {
27114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
27124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
27134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
27154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    str_addr = next_str;
27164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = next_str;
27174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
27184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
27194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
27204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
27224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strcasestr(current_str, "SectionUseCase");
27234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
27244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strcasestr(current_str, "SectionVerb");
27264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
27274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            count++;
27284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (*next_str == (char)EOF)
27294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
27314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(str_addr);
27344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return count;
27354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
27364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Returns number of common device sections for all use case verbs*/
27384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_num_device_config_format(const char *nxt_str)
27394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
27404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_str, *next_str, *str_addr, *buf;
27414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int count = 1;
27424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
27444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (next_str == NULL) {
27454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
27464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
27474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
27494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    str_addr = next_str;
27504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = next_str;
27514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
27524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
27534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
27544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
27564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strcasestr(current_str, "SectionDevice");
27574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
27584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            count++;
27594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (*next_str == (char)EOF)
27604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
27624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(str_addr);
27654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return count;
27664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
27674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Returns number of common modifier sections for all use case verbs*/
27694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_num_mod_config_format(const char *nxt_str)
27704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
27714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_str, *next_str, *str_addr, *buf;
27724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int count = 1;
27734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
27754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (next_str == NULL) {
27764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
27774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
27784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
27804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    str_addr = next_str;
27814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = next_str;
27824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
27834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
27844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
27854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
27874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strcasestr(current_str, "SectionModifier");
27884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
27894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            count++;
27904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (*next_str == (char)EOF)
27914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
27934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
27944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
27954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(str_addr);
27964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return count;
27974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
27984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
27994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Gets the number of use case verbs defined by master config file */
28004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_verb_count(const char *nxt_str)
28014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
28024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_str, *next_str, *str_addr, *buf, *p;
28034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int count = 0;
28044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
28054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
28064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (next_str == NULL) {
28074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
28084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
28094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
28104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
28114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    str_addr = next_str;
28124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = next_str;
28134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
28144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
28154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
28164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
28174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
28184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strstr(current_str, "SectionUseCase");
28194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
28204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            count++;
28214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (*next_str == (char)EOF)
28224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
28234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
28244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
28254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
28264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(str_addr);
28274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return count;
28284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
28294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
28304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Returns one if single config file per sound card format is being used */
28314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int is_single_config_format(const char *nxt_str)
28324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
28334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_str, *next_str, *str_addr, *buf;
28344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = 1, count = 0;
28354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
28364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
28374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (next_str == NULL) {
28384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
28394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
28404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
28414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
28424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    str_addr = next_str;
28434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = next_str;
28444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
28454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
28464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (!next_str)
28474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
28484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
28494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strstr(current_str, "SectionUseCase");
28504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
28514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            count++;
28524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        buf = strstr(current_str, "File");
28534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (buf != NULL)
28544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = 0;
28554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((*next_str == (char)EOF) || (count == 2))
28564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
28574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((current_str = next_str) == NULL)
28584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
28594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
28604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(str_addr);
28614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
28624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
28634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
28644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Parse a use case verb config files and update mixer controls for the verb
28654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - use case manager structure
28664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * file_name - use case verb config file name
28674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * index - index of the verb in the list
28684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
28694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
28704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_parse_verb(snd_use_case_mgr_t **uc_mgr,
28714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *file_name, int index)
28724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
28734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct stat st;
28744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *list;
28754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int device_count, modifier_count;
28764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int fd, ret = 0, parse_count = 0;
28774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *read_buf, *next_str, *current_str, *verb_ptr;
28784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char path[200];
28794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
28804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
28814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(path, CONFIG_DIR, (strlen(CONFIG_DIR)+1));
28824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcat(path, file_name, sizeof(path));
28834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("path:%s", path);
28844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
28854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
28864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        device_count = 0; modifier_count = 0;
28874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (parse_count == 0) {
28884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_count = 0;
28894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_count = 0;
28904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].mod_count = 0;
28914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_list = NULL;
28924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].modifier_list = NULL;
28934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_ctrls = NULL;
28944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_ctrls = NULL;
28954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].mod_ctrls = NULL;
28964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
28974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        fd = open(path, O_RDONLY);
28984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (fd < 0) {
28994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             ALOGE("failed to open config file %s error %d\n", path, errno);
29004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             return -EINVAL;
29014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
29024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (fstat(fd, &st) < 0) {
29034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("failed to stat %s error %d\n", path, errno);
29044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            close(fd);
29054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -EINVAL;
29064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
29074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
29084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                   MAP_PRIVATE, fd, 0);
29094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (read_buf == MAP_FAILED) {
29104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("failed to mmap file error %d\n", errno);
29114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            close(fd);
29124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return -EINVAL;
29134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
29144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        current_str = read_buf;
29154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while (*current_str != (char)EOF)  {
29164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            next_str = strchr(current_str, '\n');
29174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!next_str)
29184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
29194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *next_str++ = '\0';
29204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!strncasecmp(current_str, "SectionVerb", 11)) {
29214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (parse_count == 0) {
29224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    verb_list[index].verb_count++;
29234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
29244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = snd_ucm_parse_section(uc_mgr, &current_str,
29254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              &next_str, index, CTRL_LIST_VERB);
29264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ret < 0)
29274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
29284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
29294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else if (!strncasecmp(current_str, "SectionDevice", 13)) {
29304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (parse_count == 0) {
29314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    verb_list[index].device_count++;
29324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    device_count++;
29334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
29344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = snd_ucm_parse_section(uc_mgr, &current_str,
29354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              &next_str, index, CTRL_LIST_DEVICE);
29364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ret < 0) {
29374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
29384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
29394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        list = (verb_list[index].device_ctrls +
29404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                                   (verb_list[index].device_count - 1));
29414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        verb_ptr = (char *)
29424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            malloc((strlen(list->case_name)+1)*sizeof(char));
29434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (verb_ptr == NULL) {
29444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ret = -ENOMEM;
29454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
29464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
29474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlcpy(verb_ptr, list->case_name,
29484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ((strlen(list->case_name)+1)*sizeof(char)));
29494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        verb_list[index].device_list[device_count] = verb_ptr;
29504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        device_count++;
29514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
29524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
29534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            } else if (!strncasecmp(current_str, "SectionModifier", 15)) {
29544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (parse_count == 0) {
29554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    verb_list[index].mod_count++;
29564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    modifier_count++;
29574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
29584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = snd_ucm_parse_section(uc_mgr, &current_str,
29594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                              &next_str, index, CTRL_LIST_MODIFIER);
29604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    if (ret < 0) {
29614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        break;
29624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    } else {
29634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        list = (verb_list[index].mod_ctrls +
29644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                               (verb_list[index].mod_count - 1));
29654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        verb_ptr = (char *)
29664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            malloc((strlen(list->case_name)+1)*sizeof(char));
29674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (verb_ptr == NULL) {
29684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ret = -ENOMEM;
29694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
29704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        }
29714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlcpy(verb_ptr, list->case_name,
29724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            ((strlen(list->case_name)+1)*sizeof(char)));
29734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        verb_list[index].modifier_list[modifier_count]
29744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            = verb_ptr;
29754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        modifier_count++;
29764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
29774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
29784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
29794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if((current_str = next_str) == NULL)
29804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
29814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
29824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        munmap(read_buf, st.st_size);
29834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        close(fd);
29844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(ret < 0)
29854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            return ret;
29864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (parse_count == 0) {
29874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_list =
29884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (char **)malloc((device_count+1)*sizeof(char *));
29894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_list[index].device_list == NULL)
29904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
29914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].modifier_list =
29924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                (char **)malloc((modifier_count+1)*sizeof(char *));
29934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_list[index].modifier_list == NULL)
29944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
29954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            parse_count += verb_list[index].verb_count;
29964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_ctrls = (card_mctrl_t *)
29974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                malloc((verb_list[index].verb_count+1)*sizeof(card_mctrl_t));
29984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_list[index].verb_ctrls == NULL) {
29994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               ret = -ENOMEM;
30004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               break;
30014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
30024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].verb_count = 0;
30034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            parse_count += verb_list[index].device_count;
30044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_ctrls = (card_mctrl_t *)
30054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                malloc((verb_list[index].device_count+1)*sizeof(card_mctrl_t));
30064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_list[index].device_ctrls == NULL) {
30074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               ret = -ENOMEM;
30084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               break;
30094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
30104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_count = 0;
30114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            parse_count += verb_list[index].mod_count;
30124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].mod_ctrls = (card_mctrl_t *)
30134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                malloc((verb_list[index].mod_count+1)*sizeof(card_mctrl_t));
30144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_list[index].mod_ctrls == NULL) {
30154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               ret = -ENOMEM;
30164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               break;
30174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
30184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].mod_count = 0;
30194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            continue;
30204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
30214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_ptr =
30224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_ptr == NULL)
30244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
30254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
30264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
30274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].device_list[device_count] = verb_ptr;
30284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_ptr =
30294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (verb_ptr == NULL)
30314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
30324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
30334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
30344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[index].modifier_list[modifier_count] = verb_ptr;
30354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list = (verb_list[index].verb_ctrls +
30364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       verb_list[index].verb_count);
30374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->case_name =
30384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list->case_name == NULL) {
30404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(verb_list[index].verb_ctrls);
30414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
30424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
30434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(list->case_name, SND_UCM_END_OF_LIST,
30444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_list = NULL;
30464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_list = NULL;
30474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_count = 0;
30484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_count = 0;
30494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->playback_dev_name = NULL;
30504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->capture_dev_name = NULL;
30514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->acdb_id = 0;
30524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->capability = 0;
30534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list = (verb_list[index].device_ctrls +
30544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       verb_list[index].device_count);
30554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->case_name =
30564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list->case_name == NULL) {
30584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(verb_list[index].device_ctrls);
30594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
30604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
30614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(list->case_name, SND_UCM_END_OF_LIST,
30624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_list = NULL;
30644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_list = NULL;
30654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_count = 0;
30664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_count = 0;
30674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->playback_dev_name = NULL;
30684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->capture_dev_name = NULL;
30694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->acdb_id = 0;
30704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->capability = 0;
30714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list = (verb_list[index].mod_ctrls +
30724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                       verb_list[index].mod_count);
30734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->case_name =
30744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list->case_name == NULL) {
30764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(verb_list[index].mod_ctrls);
30774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                return -ENOMEM;
30784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
30794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(list->case_name, SND_UCM_END_OF_LIST,
30804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev               (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
30814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_list = NULL;
30824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_list = NULL;
30834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_count = 0;
30844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_count = 0;
30854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->playback_dev_name = NULL;
30864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->capture_dev_name = NULL;
30874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->acdb_id = 0;
30884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->capability = 0;
30894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            parse_count = 0;
30904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
30914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
30924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
30934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
30944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
30954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
30964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Print mixer controls in a specific list
30974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * list - list to be printed
30984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * verb_index - verb index
30994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * count - number of elements in the list
31004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
31014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
31024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int print_list(card_mctrl_t *list, int verb_index, int count)
31034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
31044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int i, j;
31054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
31064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for(i=0; i < count; i++) {
31074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("\tcase name: %s\n", list[i].case_name);
31084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("\tEnable sequence: %d\n", list[i].ena_mixer_count);
31094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for(j=0; j<list[i].ena_mixer_count; j++) {
31100a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani            ALOGD("\t\t%s : %d : %d: %s\n",
31114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].ena_mixer_list[j].control_name,
31124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].ena_mixer_list[j].type,
31134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].ena_mixer_list[j].value,
31144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].ena_mixer_list[j].string);
31154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
31164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("\tDisable sequence: %d\n", list[i].dis_mixer_count);
31174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for(j=0; j<list[i].dis_mixer_count; j++) {
31180a019914794cc27f5dacddf4e5dbc019dbe21788SathishKumar Mani            ALOGD("\t\t%s : %d : %d : %s\n",
31194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].dis_mixer_list[j].control_name,
31204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].dis_mixer_list[j].type,
31214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].dis_mixer_list[j].value,
31224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list[i].dis_mixer_list[j].string);
31234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
31244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
31254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
31264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
31274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
31284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Print mixer controls extracted from config files
31294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - use case manager structure
31304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
31314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
31324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_print(snd_use_case_mgr_t *uc_mgr)
31334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
31344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *list;
31354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int i, j, verb_index = 0;
31364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
31374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
31384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
31394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
31404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(strncmp(uc_mgr->card_ctxt_ptr->verb_list[verb_index],
31414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev         SND_UCM_END_OF_LIST, 3)) {
31424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("\nuse case verb: %s\n",
31434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            uc_mgr->card_ctxt_ptr->verb_list[verb_index]);
31444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(verb_list[verb_index].device_list) {
31454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGD("\tValid device list:");
31464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            i = 0;
31474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while(strncmp(verb_list[verb_index].device_list[i],
31484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  SND_UCM_END_OF_LIST, 3)) {
31494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGD("\t\t%s", verb_list[verb_index].device_list[i]);
31504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                i++;
31514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
31524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
31534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(verb_list[verb_index].modifier_list) {
31544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGD("\tValid modifier list:");
31554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            i = 0;
31564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            while(strncmp(verb_list[verb_index].modifier_list[i],
31574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  SND_UCM_END_OF_LIST, 3)) {
31584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGD("\t\t%s", verb_list[verb_index].modifier_list[i]);
31594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                i++;
31604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
31614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
31624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("Verbs:\n");
31634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = verb_list[verb_index].verb_ctrls;
31644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        print_list(list, verb_index, verb_list[verb_index].verb_count);
31654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("Devices:\n");
31664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = verb_list[verb_index].device_ctrls;
31674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        print_list(list, verb_index, verb_list[verb_index].device_count);
31684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGD("Modifier:\n");
31694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = verb_list[verb_index].mod_ctrls;
31704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        print_list(list, verb_index, verb_list[verb_index].mod_count);
31714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index++;
31724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
31734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
31744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
31754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
31764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
31774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Gets the number of controls for specific sequence of a use cae */
31784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_controls_count(const char *nxt_str)
31794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
31804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *current_str, *next_str, *str_addr;
31814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int count = 0;
31824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
31834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
31844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (next_str == NULL) {
31854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
31864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
31874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
31884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
31894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    str_addr = next_str;
31904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(1) {
31914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        current_str = next_str;
31924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
31934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((!next_str) || (!strncasecmp(current_str, "EndSection", 10)))
31944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
31954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
31964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (strcasestr(current_str, "EndSequence") != NULL) {
31974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
31984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
31994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            count++;
32004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
32014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (*next_str == (char)EOF)
32024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
32034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(!strncasecmp(current_str, "EndSection", 10))
32044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
32054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
32064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(str_addr);
32074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return count;
32084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
32094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
32104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Parse a section of config files
32114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * uc_mgr - use case manager structure
32124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
32134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
32144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_parse_section(snd_use_case_mgr_t **uc_mgr, char **cur_str,
32154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevchar **nxt_str, int verb_index, int ctrl_list_type)
32164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
32174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
32184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *list;
32194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int enable_seq = 0, disable_seq = 0, controls_count = 0, ret = 0;
32204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p, *current_str, *next_str, *name;
32214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
32224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
32234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ctrl_list_type == CTRL_LIST_VERB) {
32244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = (verb_list[verb_index].verb_ctrls +
32254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[verb_index].verb_count);
32264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
32274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = (verb_list[verb_index].device_ctrls +
32284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[verb_index].device_count);
32294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
32304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = (verb_list[verb_index].mod_ctrls +
32314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[verb_index].mod_count);
32324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
32334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Invalid list type: %d\n", ctrl_list_type);
32344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
32354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
32364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->case_name = NULL;
32374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_list = NULL;
32384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_list = NULL;
32394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->ena_mixer_count = 0;
32404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->dis_mixer_count = 0;
32414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->playback_dev_name = NULL;
32424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capture_dev_name = NULL;
32434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->acdb_id = 0;
32444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->capability = 0;
32454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    list->effects_mixer_ctl = NULL;
32464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    current_str = *cur_str; next_str = *nxt_str;
32474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(strncasecmp(current_str, "EndSection", 10)) {
32484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        current_str = next_str;
32494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        next_str = strchr(current_str, '\n');
32504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if ((!next_str) || (!strncasecmp(current_str, "EndSection", 10)))
32514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
32524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *next_str++ = '\0';
32534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (strcasestr(current_str, "EndSequence") != NULL) {
32544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (enable_seq == 1)
32554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                enable_seq = 0;
32564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            else if (disable_seq == 1)
32574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                disable_seq = 0;
32584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            else
32594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ALOGE("Error: improper config file\n");
32604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
32614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (enable_seq == 1) {
32624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_controls(current_str, &list->ena_mixer_list,
32634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  list->ena_mixer_count);
32644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
32654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
32664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_count++;
32674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (disable_seq == 1) {
32684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_controls(current_str, &list->dis_mixer_list,
32694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                  list->dis_mixer_count);
32704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
32714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
32724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_count++;
32734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (strcasestr(current_str, "Name") != NULL) {
32744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_name(current_str, &list->case_name);
32754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
32764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
32774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Name of section is %s\n", list->case_name);
32784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (strcasestr(current_str, "PlaybackPCM") != NULL) {
32794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_dev_name(current_str,
32804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      &list->playback_dev_name);
32814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
32824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
32834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Device name of playback is %s\n",
32844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->playback_dev_name);
32854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (strcasestr(current_str, "CapturePCM") != NULL) {
32864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_dev_name(current_str,
32874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      &list->capture_dev_name);
32884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
32894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
32904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Device name of capture is %s\n", list->capture_dev_name);
32914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (strcasestr(current_str, "ACDBID") != NULL) {
32924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_acdb(current_str, &list->acdb_id,
32934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      &list->capability);
32944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
32954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
32964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("ACDB ID: %d CAPABILITY: %d\n", list->acdb_id,
32974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->capability);
32984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (strcasestr(current_str, "EffectsMixerCTL") != NULL) {
32994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = snd_ucm_extract_effects_mixer_ctl(current_str,
33004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                      &list->effects_mixer_ctl);
33014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (ret < 0)
33024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
33034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGV("Effects mixer ctl: %s: %d\n", list->effects_mixer_ctl);
33044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
33054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (strcasestr(current_str, "EnableSequence") != NULL) {
33064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            controls_count = get_controls_count(next_str);
33074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (controls_count < 0) {
33084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -ENOMEM;
33094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
33104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
33114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->ena_mixer_list =
33124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (mixer_control_t *)malloc((controls_count*sizeof(mixer_control_t)));
33134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (list->ena_mixer_list == NULL) {
33144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -ENOMEM;
33154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
33164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
33174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            enable_seq = 1;
33184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (strcasestr(current_str, "DisableSequence") != NULL) {
33194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            controls_count = get_controls_count(next_str);
33204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (controls_count < 0) {
33214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -ENOMEM;
33224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
33234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
33244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->dis_mixer_list =
33254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            (mixer_control_t *)malloc((controls_count*sizeof(mixer_control_t)));
33264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (list->dis_mixer_list == NULL) {
33274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -ENOMEM;
33284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
33294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
33304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            disable_seq = 1;
33314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
33324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (*next_str == (char)EOF)
33334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev             break;
33344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
33354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if(ret == 0) {
33364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *cur_str = current_str; *nxt_str = next_str;
33374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (ctrl_list_type == CTRL_LIST_VERB) {
33384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[verb_index].verb_count++;
33394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
33404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[verb_index].device_count++;
33414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
33424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            verb_list[verb_index].mod_count++;
33434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
33444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
33454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
33464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
33474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
33484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Extract a mixer control name from config file
33494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
33504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
33514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_extract_name(char *buf, char **case_name)
33524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
33534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = 0;
33544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p, *name = *case_name, *temp_ptr;
33554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
33564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    p = strtok_r(buf, "\"", &temp_ptr);
33574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (p != NULL) {
33584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(NULL, "\"", &temp_ptr);
33594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL)
33604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
33614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        name = (char *)malloc((strlen(p)+1)*sizeof(char));
33624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(name == NULL) {
33634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -ENOMEM;
33644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
33654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
33664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(name, p, (strlen(p)+1)*sizeof(char));
33674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *case_name = name;
33684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        break;
33694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
33704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
33714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
33724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
33734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Extract a ACDB ID and capability of use case from config file
33744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
33754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
33764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_extract_acdb(char *buf, int *id, int *cap)
33774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
33784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p, key[] = "0123456789", *temp_ptr;
33794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
33804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    p = strpbrk(buf, key);
33814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (p == NULL) {
33824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *id = 0;
33834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *cap = 0;
33844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
33854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(p, ":", &temp_ptr);
33864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while (p != NULL) {
33874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *id = atoi(p);
33884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            p = strtok_r(NULL, "\0", &temp_ptr);
33894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (p == NULL)
33904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
33914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *cap = atoi(p);
33924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
33934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
33944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
33954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
33964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
33974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
33984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Extract Effects Mixer ID of device from config file
33994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
34004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
34014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_extract_effects_mixer_ctl(char *buf, char **mixer_name)
34024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
34034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = 0;
34044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p, *name = *mixer_name, *temp_ptr;
34054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    p = strtok_r(buf, "\"", &temp_ptr);
34074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (p != NULL) {
34084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(NULL, "\"", &temp_ptr);
34094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL)
34104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
34114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        name = (char *)malloc((strlen(p)+1)*sizeof(char));
34124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(name == NULL) {
34134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -ENOMEM;
34144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
34154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
34164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(name, p, (strlen(p)+1)*sizeof(char));
34174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *mixer_name = name;
34184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        break;
34194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
34204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
34214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
34224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Extract a playback and capture device name of use case from config file
34244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
34254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
34264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_extract_dev_name(char *buf, char **dev_name)
34274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
34284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char key[] = "0123456789";
34294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p, *name = *dev_name;
34304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char dev_pre[] = "hw:0,";
34314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *temp_ptr;
34324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    p = strpbrk(buf, key);
34344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (p == NULL) {
34354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *dev_name = NULL;
34364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
34374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(p, "\r\n", &temp_ptr);
34384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL) {
34394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *dev_name = NULL;
34404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
34414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            name = (char *)malloc((strlen(p)+strlen(dev_pre)+1)*sizeof(char));
34424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(name == NULL)
34434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                 return -ENOMEM;
34444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(name, dev_pre, (strlen(p)+strlen(dev_pre)+1)*sizeof(char));
34454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcat(name, p, (strlen(p)+strlen(dev_pre)+1)*sizeof(char));
34464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *dev_name = name;
34474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
34484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
34494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
34504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
34514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int get_num_values(const char *buf)
34534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
34544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *buf_addr, *p;
34554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int count = 0;
34564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *temp_ptr;
34574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    buf_addr = (char *)malloc((strlen(buf)+1)*sizeof(char));
34594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (buf_addr == NULL) {
34604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory");
34614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
34624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
34634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    strlcpy(buf_addr, buf, ((strlen(buf)+1)*sizeof(char)));
34644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    p = strtok_r(buf_addr, " ", &temp_ptr);
34654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (p != NULL) {
34664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        count++;
34674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(NULL, " ", &temp_ptr);
34684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL)
34694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
34704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
34714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    free(buf_addr);
34724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return count;
34734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
34744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Extract a mixer control from config file
34764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
34774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
34784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_extract_controls(char *buf, mixer_control_t **mixer_list,
34794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint size)
34804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
34814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    unsigned long temp;
34824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = -EINVAL, i, index = 0, count = 0;
34834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *p, *ps, *pmv, temp_coeff[20];
34844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    mixer_control_t *list;
34854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    static const char *const seps = "\r\n";
34864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    char *temp_ptr, *temp_vol_ptr;
34874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
34884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    p = strtok_r(buf, "'", &temp_ptr);
34894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (p != NULL) {
34904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(NULL, "'", &temp_ptr);
34914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL)
34924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
34934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list = ((*mixer_list)+size);
34944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        list->control_name = (char *)malloc((strlen(p)+1)*sizeof(char));
34954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list->control_name == NULL) {
34964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = -ENOMEM;
34974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free((*mixer_list));
34984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
34994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
35004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(list->control_name, p, (strlen(p)+1)*sizeof(char));
35014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(NULL, ":", &temp_ptr);
35024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL)
35034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
35044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(!strncmp(p, "0", 1)) {
35054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->type = TYPE_STR;
35064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if(!strncmp(p, "1", 1)) {
35074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->type = TYPE_INT;
35084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if(!strncmp(p, "2", 1)) {
35094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->type = TYPE_MULTI_VAL;
35104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
35114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Unknown type: p %s\n", p);
35124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
35134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        p = strtok_r(NULL, seps, &temp_ptr);
35144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if (p == NULL)
35154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
35164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list->type == TYPE_INT) {
35174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->value = atoi(p);
35184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->string = NULL;
35194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->mulval = NULL;
35204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if(list->type == TYPE_STR) {
35214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->value = -1;
35224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->string = (char *)malloc((strlen(p)+1)*sizeof(char));
35234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->mulval = NULL;
35244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list->string == NULL) {
35254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = -ENOMEM;
35264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free((*mixer_list));
35274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(list->control_name);
35284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
35294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
35304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            strlcpy(list->string, p, (strlen(p)+1)*sizeof(char));
35314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else if(list->type == TYPE_MULTI_VAL) {
35324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (p != NULL) {
35334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                count = get_num_values(p);
35344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->mulval = (char **)malloc(count*sizeof(char *));
35354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if (list->mulval == NULL) {
35364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    ret = -ENOMEM;
35374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free((*mixer_list));
35384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free(list->control_name);
35394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    break;
35404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
35414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                index = 0;
35424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                /* To support volume values in percentage */
35434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                if ((count == 1) && (strstr(p, "%") != NULL)) {
35444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    pmv = strtok_r(p, " ", &temp_vol_ptr);
35454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    while (pmv != NULL) {
35464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        list->mulval[index] =
35474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            (char *)malloc((strlen(pmv)+1)*sizeof(char));
35484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlcpy(list->mulval[index], pmv, (strlen(pmv)+1));
35494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        index++;
35504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        pmv = strtok_r(NULL, " ", &temp_vol_ptr);
35514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (pmv == NULL)
35524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
35534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
35544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                } else {
35554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    pmv = strtok_r(p, " ", &temp_vol_ptr);
35564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    while (pmv != NULL) {
35574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        temp = strtoul(pmv, &ps, 16);
35584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        snprintf(temp_coeff, sizeof(temp_coeff),"%lu", temp);
35594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        list->mulval[index] =
35604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            (char *)malloc((strlen(temp_coeff)+1)*sizeof(char));
35614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        strlcpy(list->mulval[index], temp_coeff,
35624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            (strlen(temp_coeff)+1));
35634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        index++;
35644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        pmv = strtok_r(NULL, " ", &temp_vol_ptr);
35654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                        if (pmv == NULL)
35664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                            break;
35674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    }
35684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
35694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->value = count;
35704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                list->string = NULL;
35714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
35724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        } else {
35734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ALOGE("Unknown type: p %s\n", p);
35744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->value = -1;
35754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            list->string = NULL;
35764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
35774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ret = 0;
35784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        break;
35794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
35804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
35814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
35824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
35834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid free_list(card_mctrl_t *list, int verb_index, int count)
35844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
35854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int case_index = 0, index = 0, mindex = 0;
35864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
35874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    for(case_index = 0; case_index < count; case_index++) {
35884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for(index = 0; index < list[case_index].ena_mixer_count; index++) {
35894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list[case_index].ena_mixer_list[index].control_name) {
35904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(list[case_index].ena_mixer_list[index].control_name);
35914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
35924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list[case_index].ena_mixer_list[index].string) {
35934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(list[case_index].ena_mixer_list[index].string);
35944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
35954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list[case_index].ena_mixer_list[index].mulval) {
35964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                for(mindex = 0;
35974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    mindex < list[case_index].ena_mixer_list[index].value;
35984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    mindex++) {
35994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                    free(list[case_index].ena_mixer_list[index].mulval[mindex]);
36004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                }
36019746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                if(list[case_index].ena_mixer_list[index].mulval) {
36029746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                    free(list[case_index].ena_mixer_list[index].mulval);
36039746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                }
36044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
36054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        for(index = 0; index < list[case_index].dis_mixer_count; index++) {
36074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list[case_index].dis_mixer_list[index].control_name) {
36084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(list[case_index].dis_mixer_list[index].control_name);
36094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
36104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if(list[case_index].dis_mixer_list[index].string) {
36114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                free(list[case_index].dis_mixer_list[index].string);
36124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
36139746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            if(list[case_index].dis_mixer_list[index].mulval) {
36149746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                for(mindex = 0;
36159746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                    mindex < list[case_index].dis_mixer_list[index].value;
36169746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                    mindex++) {
36179746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                    free(list[case_index].dis_mixer_list[index].mulval[mindex]);
36189746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                }
36199746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                if(list[case_index].dis_mixer_list[index].mulval) {
36209746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                    free(list[case_index].dis_mixer_list[index].mulval);
36219746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                }
36229746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            }
36234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list[case_index].case_name) {
36254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(list[case_index].case_name);
36264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list[case_index].ena_mixer_list) {
36284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(list[case_index].ena_mixer_list);
36294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list[case_index].dis_mixer_list) {
36314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(list[case_index].dis_mixer_list);
36324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list[case_index].playback_dev_name) {
36344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(list[case_index].playback_dev_name);
36354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(list[case_index].capture_dev_name) {
36374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(list[case_index].capture_dev_name);
36384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36399746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        if(list[case_index].effects_mixer_ctl) {
36409746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            list[case_index].effects_mixer_ctl = NULL;
36419746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        }
36424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
36434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
36444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
36454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid snd_ucm_free_mixer_list(snd_use_case_mgr_t **uc_mgr)
36464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
36474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    card_mctrl_t *ctrl_list;
36484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    use_case_verb_t *verb_list;
36494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index = 0, verb_index = 0;
36504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
36514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_lock(&(*uc_mgr)->card_ctxt_ptr->card_lock);
36529746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
36534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while(strncmp((*uc_mgr)->card_ctxt_ptr->verb_list[verb_index],
36544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev          SND_UCM_END_OF_LIST, 3)) {
36554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ctrl_list = verb_list[verb_index].verb_ctrls;
36564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free_list(ctrl_list, verb_index, verb_list[verb_index].verb_count);
36574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(verb_list[verb_index].use_case_name)
36584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free(verb_list[verb_index].use_case_name);
36594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if((*uc_mgr)->card_ctxt_ptr->verb_list[verb_index]) {
36604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            free((*uc_mgr)->card_ctxt_ptr->verb_list[verb_index]);
36614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
36624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        verb_index++;
36634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
36649746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    verb_index -= 1;
36659746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    ctrl_list = verb_list[verb_index].device_ctrls;
36669746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    free_list(ctrl_list, verb_index, verb_list[verb_index].device_count);
36679746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    ctrl_list = verb_list[verb_index].mod_ctrls;
36689746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    free_list(ctrl_list, verb_index, verb_list[verb_index].mod_count);
36699746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    index = 0;
36709746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    while(1) {
36719746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        if (verb_list[verb_index].device_list[index]) {
36729746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            if (!strncmp(verb_list[verb_index].device_list[index],
36739746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                SND_UCM_END_OF_LIST, 3)) {
36749746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                free(verb_list[verb_index].device_list[index]);
36759746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                break;
36769746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            } else {
36779746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                free(verb_list[verb_index].device_list[index]);
36789746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                index++;
36799746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            }
36809746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        }
36819746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    }
36829746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    if (verb_list[verb_index].device_list)
36839746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        free(verb_list[verb_index].device_list);
36849746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    index = 0;
36859746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    while(1) {
36869746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        if (verb_list[verb_index].modifier_list[index]) {
36879746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            if (!strncmp(verb_list[verb_index].modifier_list[index],
36889746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                SND_UCM_END_OF_LIST, 3)) {
36899746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                free(verb_list[verb_index].modifier_list[index]);
36909746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                break;
36919746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            } else {
36929746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                free(verb_list[verb_index].modifier_list[index]);
36939746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani                index++;
36949746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani            }
36959746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        }
36969746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    }
36979746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani    if (verb_list[verb_index].modifier_list)
36989746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani        free(verb_list[verb_index].modifier_list);
36994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if((*uc_mgr)->card_ctxt_ptr->use_case_verb_list)
37004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free((*uc_mgr)->card_ctxt_ptr->use_case_verb_list);
37014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if((*uc_mgr)->card_ctxt_ptr->verb_list)
37024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free((*uc_mgr)->card_ctxt_ptr->verb_list);
37034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    pthread_mutex_unlock(&(*uc_mgr)->card_ctxt_ptr->card_lock);
37044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
37054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
37064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Add an identifier to the respective list
37074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * head - list head
37084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * value - node value that needs to be added
37094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
37104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
37114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_add_ident_to_list(struct snd_ucm_ident_node **head,
37124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *value)
37134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
37144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct snd_ucm_ident_node *temp, *node;
37154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
37164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    node =
37174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        (struct snd_ucm_ident_node *)malloc(sizeof(struct snd_ucm_ident_node));
37184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (node == NULL) {
37194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Failed to allocate memory for new node");
37204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -ENOMEM;
37214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
37224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        node->next = NULL;
37234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        strlcpy(node->ident, value, MAX_STR_LEN);
37244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        node->active = 0;
37259858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        node->capability = 0;
37264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
37274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (*head == NULL) {
37284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        *head = node;
37294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
37304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp = *head;
37314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while (temp->next != NULL) {
37324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            temp = temp->next;
37334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
37344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp->next = node;
37354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
37364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("add_to_list: head %p, value %s", *head, node->ident);
37374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return 0;
37384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
37394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
37404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Get the status of identifier at particulare index of the list
37414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * head - list head
37424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * ident - identifier value for which status needs to be get
37434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * status - status to be set (1 - active, 0 - inactive)
37444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
37454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_get_status_at_index(struct snd_ucm_ident_node *head,
37464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *ident)
37474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
37484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (head != NULL) {
37494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(!strncmp(ident, head->ident, (strlen(head->ident)+1))) {
37504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
37514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
37524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        head = head->next;
37534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
37544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (head == NULL) {
37554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Element not found in the list");
37564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
37574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return(head->active);
37584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
37594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return -EINVAL;
37604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
37614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
37629858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani/* Get the node at particular index
37639858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani * head - list head
37649858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani * index - index value
37659858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani */
37669858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Manistruct snd_ucm_ident_node *snd_ucm_get_device_node(struct snd_ucm_ident_node *head,
37679858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Maniint index)
37689858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani{
37699858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    if (head == NULL) {
37709858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        ALOGV("Empty list");
37719858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        return NULL;
37729858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    }
37739858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani
37749858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    if ((index < 0) || (index >= (snd_ucm_get_size_of_list(head)))) {
37759858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        ALOGE("Element with given index %d doesn't exist in the list", index);
37769858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        return NULL;
37779858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    }
37789858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani
37799858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    while (index) {
37809858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        head = head->next;
37819858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        index--;
37829858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    }
37839858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani
37849858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani    return head;
37859858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani}
37869858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani
37874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Set the status of identifier at particulare index of the list
37884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * head - list head
37894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * ident - identifier value for which status needs to be set
37904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * status - status to be set (1 - active, 0 - inactive)
37914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
37924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void snd_ucm_set_status_at_index(struct snd_ucm_ident_node *head,
37939858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Maniconst char *ident, int status, int capability)
37944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
37954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (head != NULL) {
37964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        if(!strncmp(ident, head->ident, (strlen(head->ident)+1))) {
37974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            break;
37984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
37994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        head = head->next;
38004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (head == NULL) {
38024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Element not found to set the status");
38034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
38044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        head->active = status;
38059858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        head->capability = capability;
38064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
38084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Get the identifier value at particulare index of the list
38104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * head - list head
38114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * index - node index value
38124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns node idetifier value at index on sucess, NULL otherwise
38134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
38144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char *snd_ucm_get_value_at_index(struct snd_ucm_ident_node *head,
38154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint index)
38164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
38174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (head == NULL) {
38184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Empty list");
38194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NULL;
38204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if ((index < 0) || (index >= (snd_ucm_get_size_of_list(head)))) {
38234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Element with given index %d doesn't exist in the list", index);
38244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return NULL;
38254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (index) {
38284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        head = head->next;
38294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index--;
38304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return (strdup(head->ident));
38334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
38344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Get the size of the list
38364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * head - list head
38374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns size of list on sucess, negative error code otherwise
38384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
38394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_get_size_of_list(struct snd_ucm_ident_node *head)
38404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
38414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index = 0;
38424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (head == NULL) {
38444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Empty list");
38454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return 0;
38464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (head->next != NULL) {
38494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index++;
38504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        head = head->next;
38514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return (index+1);
38544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
38554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic void snd_ucm_print_list(struct snd_ucm_ident_node *head)
38574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
38584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int index = 0;
38594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("print_list: head %p", head);
38614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (head == NULL) {
38624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("Empty list");
38634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return;
38644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    while (head->next != NULL) {
38674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGV("index: %d, value: %s", index, head->ident);
38684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        index++;
38694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        head = head->next;
38704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
38714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    ALOGV("index: %d, value: %s", index, head->ident);
38724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
38734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* Delete an identifier from respective list
38754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * head - list head
38764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * value - node value that needs to be deleted
38774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Returns 0 on sucess, negative error code otherwise
38784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *
38794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */
38804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int snd_ucm_del_ident_from_list(struct snd_ucm_ident_node **head,
38814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevconst char *value)
38824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{
38834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    struct snd_ucm_ident_node *temp1, *temp2;
38844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    int ret = -EINVAL;
38854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev
38864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (*head == NULL) {
38874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("del_from_list: Empty list");
38884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        return -EINVAL;
38894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else if (!strncmp((*head)->ident, value, (strlen(value)+1))) {
38904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            temp2 = *head;
38914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            *head = temp2->next;
38924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            ret = 0;
38934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
38944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp1 = *head;
38954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp2 = temp1->next;
38964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        while (temp2 != NULL) {
38974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            if (!strncmp(temp2->ident, value, (strlen(value)+1))) {
38984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                temp1->next = temp2->next;
38994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                ret = 0;
39004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev                break;
39014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            }
39024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            temp1 = temp1->next;
39034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev            temp2 = temp1->next;
39044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        }
39054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
39064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    if (ret < 0) {
39074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        ALOGE("Element not found in enabled list");
39084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    } else {
39094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp2->next = NULL;
39104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp2->ident[0] = 0;
39114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp2->active = 0;
39129858010096e3469c3b1ccb5372ebba9cfbdeb384SathishKumar Mani        temp2->capability = 0;
39134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        free(temp2);
39144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev        temp2 = NULL;
39154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    }
39164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev    return ret;
39174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}
3918