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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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