mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
229 lines
5.7 KiB
C
229 lines
5.7 KiB
C
/*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* Support for the verb/device/modifier core logic and API,
|
|
* command line tool and file parser was kindly sponsored by
|
|
* Texas Instruments Inc.
|
|
* Support for multiple active modifiers and devices,
|
|
* transition sequences, multiple client access and user defined use
|
|
* cases was kindly sponsored by Wolfson Microelectronics PLC.
|
|
*
|
|
* Copyright (C) 2008-2010 SlimLogic Ltd
|
|
* Copyright (C) 2010 Wolfson Microelectronics PLC
|
|
* Copyright (C) 2010 Texas Instruments Inc.
|
|
* Copyright (C) 2010 Red Hat Inc.
|
|
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
|
* Stefan Schmidt <stefan@slimlogic.co.uk>
|
|
* Justin Xu <justinx@slimlogic.co.uk>
|
|
* Jaroslav Kysela <perex@perex.cz>
|
|
*/
|
|
|
|
#include "ucm_local.h"
|
|
|
|
void uc_mgr_error(const char *fmt,...)
|
|
{
|
|
va_list va;
|
|
va_start(va, fmt);
|
|
fprintf(stderr, "ucm: ");
|
|
vfprintf(stderr, fmt, va);
|
|
va_end(va);
|
|
}
|
|
|
|
void uc_mgr_stdout(const char *fmt,...)
|
|
{
|
|
va_list va;
|
|
va_start(va, fmt);
|
|
vfprintf(stdout, fmt, va);
|
|
va_end(va);
|
|
}
|
|
|
|
int uc_mgr_config_load(const char *file, snd_config_t **cfg)
|
|
{
|
|
FILE *fp;
|
|
snd_input_t *in;
|
|
snd_config_t *top;
|
|
int err;
|
|
|
|
fp = fopen(file, "r");
|
|
if (fp == NULL) {
|
|
err = -errno;
|
|
goto __err;
|
|
}
|
|
err = snd_input_stdio_attach(&in, fp, 1);
|
|
if (err < 0) {
|
|
__err:
|
|
uc_error("could not open configuration file %s", file);
|
|
return err;
|
|
}
|
|
err = snd_config_top(&top);
|
|
if (err < 0)
|
|
return err;
|
|
err = snd_config_load(top, in);
|
|
if (err < 0) {
|
|
uc_error("could not load configuration file %s", file);
|
|
snd_config_delete(top);
|
|
return err;
|
|
}
|
|
err = snd_input_close(in);
|
|
if (err < 0) {
|
|
snd_config_delete(top);
|
|
return err;
|
|
}
|
|
*cfg = top;
|
|
return 0;
|
|
}
|
|
|
|
void uc_mgr_free_value(struct list_head *base)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct ucm_value *val;
|
|
|
|
list_for_each_safe(pos, npos, base) {
|
|
val = list_entry(pos, struct ucm_value, list);
|
|
free(val->name);
|
|
free(val->data);
|
|
list_del(&val->list);
|
|
free(val);
|
|
}
|
|
}
|
|
|
|
void uc_mgr_free_dev_list(struct list_head *base)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct dev_list *dlist;
|
|
|
|
list_for_each_safe(pos, npos, base) {
|
|
dlist = list_entry(pos, struct dev_list, list);
|
|
free(dlist->name);
|
|
list_del(&dlist->list);
|
|
free(dlist);
|
|
}
|
|
}
|
|
|
|
void uc_mgr_free_sequence_element(struct sequence_element *seq)
|
|
{
|
|
if (seq == NULL)
|
|
return;
|
|
switch (seq->type) {
|
|
case SEQUENCE_ELEMENT_TYPE_CSET:
|
|
case SEQUENCE_ELEMENT_TYPE_EXEC:
|
|
free(seq->data.exec);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
free(seq);
|
|
}
|
|
|
|
void uc_mgr_free_sequence(struct list_head *base)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct sequence_element *seq;
|
|
|
|
list_for_each_safe(pos, npos, base) {
|
|
seq = list_entry(pos, struct sequence_element, list);
|
|
list_del(&seq->list);
|
|
uc_mgr_free_sequence_element(seq);
|
|
}
|
|
}
|
|
|
|
void uc_mgr_free_transition_element(struct transition_sequence *tseq)
|
|
{
|
|
free(tseq->name);
|
|
uc_mgr_free_sequence(&tseq->transition_list);
|
|
free(tseq);
|
|
}
|
|
|
|
void uc_mgr_free_transition(struct list_head *base)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct transition_sequence *tseq;
|
|
|
|
list_for_each_safe(pos, npos, base) {
|
|
tseq = list_entry(pos, struct transition_sequence, list);
|
|
list_del(&tseq->list);
|
|
uc_mgr_free_transition_element(tseq);
|
|
}
|
|
}
|
|
|
|
void uc_mgr_free_modifier(struct list_head *base)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct use_case_modifier *mod;
|
|
|
|
list_for_each_safe(pos, npos, base) {
|
|
mod = list_entry(pos, struct use_case_modifier, list);
|
|
free(mod->name);
|
|
free(mod->comment);
|
|
uc_mgr_free_sequence(&mod->enable_list);
|
|
uc_mgr_free_sequence(&mod->disable_list);
|
|
uc_mgr_free_transition(&mod->transition_list);
|
|
uc_mgr_free_dev_list(&mod->dev_list);
|
|
uc_mgr_free_value(&mod->value_list);
|
|
list_del(&mod->list);
|
|
free(mod);
|
|
}
|
|
}
|
|
|
|
void uc_mgr_free_device(struct list_head *base)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct use_case_device *dev;
|
|
|
|
list_for_each_safe(pos, npos, base) {
|
|
dev = list_entry(pos, struct use_case_device, list);
|
|
free(dev->name);
|
|
free(dev->comment);
|
|
uc_mgr_free_sequence(&dev->enable_list);
|
|
uc_mgr_free_sequence(&dev->disable_list);
|
|
uc_mgr_free_transition(&dev->transition_list);
|
|
uc_mgr_free_value(&dev->value_list);
|
|
list_del(&dev->list);
|
|
free(dev);
|
|
}
|
|
}
|
|
|
|
void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr)
|
|
{
|
|
struct list_head *pos, *npos;
|
|
struct use_case_verb *verb;
|
|
|
|
list_for_each_safe(pos, npos, &uc_mgr->verb_list) {
|
|
verb = list_entry(pos, struct use_case_verb, list);
|
|
free(verb->name);
|
|
free(verb->comment);
|
|
uc_mgr_free_sequence(&verb->enable_list);
|
|
uc_mgr_free_sequence(&verb->disable_list);
|
|
uc_mgr_free_transition(&verb->transition_list);
|
|
uc_mgr_free_value(&verb->value_list);
|
|
uc_mgr_free_device(&verb->device_list);
|
|
uc_mgr_free_modifier(&verb->modifier_list);
|
|
list_del(&verb->list);
|
|
free(verb);
|
|
}
|
|
uc_mgr_free_sequence(&uc_mgr->default_list);
|
|
free(uc_mgr->comment);
|
|
uc_mgr->comment = NULL;
|
|
uc_mgr->active_verb = NULL;
|
|
INIT_LIST_HEAD(&uc_mgr->active_devices);
|
|
INIT_LIST_HEAD(&uc_mgr->active_modifiers);
|
|
}
|
|
|
|
void uc_mgr_free(snd_use_case_mgr_t *uc_mgr)
|
|
{
|
|
uc_mgr_free_verb(uc_mgr);
|
|
free(uc_mgr->card_name);
|
|
free(uc_mgr);
|
|
}
|