|
Packit |
4a16fb |
/*
|
|
Packit |
4a16fb |
Copyright(c) 2014-2015 Intel Corporation
|
|
Packit |
4a16fb |
All rights reserved.
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
This library is free software; you can redistribute it and/or modify
|
|
Packit |
4a16fb |
it under the terms of the GNU Lesser General Public License as
|
|
Packit |
4a16fb |
published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
4a16fb |
the License, or (at your option) any later version.
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
This program is distributed in the hope that it will be useful,
|
|
Packit |
4a16fb |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
4a16fb |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
4a16fb |
GNU Lesser General Public License for more details.
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
|
Packit |
4a16fb |
Yao Jin <yao.jin@intel.com>
|
|
Packit |
4a16fb |
Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include "list.h"
|
|
Packit |
4a16fb |
#include "tplg_local.h"
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* mapping of channel text names to types */
|
|
Packit |
4a16fb |
static const struct map_elem channel_map[] = {
|
|
Packit |
4a16fb |
{"mono", SNDRV_CHMAP_MONO}, /* mono stream */
|
|
Packit |
4a16fb |
{"fl", SNDRV_CHMAP_FL}, /* front left */
|
|
Packit |
4a16fb |
{"fr", SNDRV_CHMAP_FR}, /* front right */
|
|
Packit |
4a16fb |
{"rl", SNDRV_CHMAP_RL}, /* rear left */
|
|
Packit |
4a16fb |
{"rr", SNDRV_CHMAP_RR}, /* rear right */
|
|
Packit |
4a16fb |
{"fc", SNDRV_CHMAP_FC}, /* front center */
|
|
Packit |
4a16fb |
{"lfe", SNDRV_CHMAP_LFE}, /* LFE */
|
|
Packit |
4a16fb |
{"sl", SNDRV_CHMAP_SL}, /* side left */
|
|
Packit |
4a16fb |
{"sr", SNDRV_CHMAP_SR}, /* side right */
|
|
Packit |
4a16fb |
{"rc", SNDRV_CHMAP_RC}, /* rear center */
|
|
Packit |
4a16fb |
{"flc", SNDRV_CHMAP_FLC}, /* front left center */
|
|
Packit |
4a16fb |
{"frc", SNDRV_CHMAP_FRC}, /* front right center */
|
|
Packit |
4a16fb |
{"rlc", SNDRV_CHMAP_RLC}, /* rear left center */
|
|
Packit |
4a16fb |
{"rrc", SNDRV_CHMAP_RRC}, /* rear right center */
|
|
Packit |
4a16fb |
{"flw", SNDRV_CHMAP_FLW}, /* front left wide */
|
|
Packit |
4a16fb |
{"frw", SNDRV_CHMAP_FRW}, /* front right wide */
|
|
Packit |
4a16fb |
{"flh", SNDRV_CHMAP_FLH}, /* front left high */
|
|
Packit |
4a16fb |
{"fch", SNDRV_CHMAP_FCH}, /* front center high */
|
|
Packit |
4a16fb |
{"frh", SNDRV_CHMAP_FRH}, /* front right high */
|
|
Packit |
4a16fb |
{"tc", SNDRV_CHMAP_TC}, /* top center */
|
|
Packit |
4a16fb |
{"tfl", SNDRV_CHMAP_TFL}, /* top front left */
|
|
Packit |
4a16fb |
{"tfr", SNDRV_CHMAP_TFR}, /* top front right */
|
|
Packit |
4a16fb |
{"tfc", SNDRV_CHMAP_TFC}, /* top front center */
|
|
Packit |
4a16fb |
{"trl", SNDRV_CHMAP_TRL}, /* top rear left */
|
|
Packit |
4a16fb |
{"trr", SNDRV_CHMAP_TRR}, /* top rear right */
|
|
Packit |
4a16fb |
{"trc", SNDRV_CHMAP_TRC}, /* top rear center */
|
|
Packit |
4a16fb |
{"tflc", SNDRV_CHMAP_TFLC}, /* top front left center */
|
|
Packit |
4a16fb |
{"tfrc", SNDRV_CHMAP_TFRC}, /* top front right center */
|
|
Packit |
4a16fb |
{"tsl", SNDRV_CHMAP_TSL}, /* top side left */
|
|
Packit |
4a16fb |
{"tsr", SNDRV_CHMAP_TSR}, /* top side right */
|
|
Packit |
4a16fb |
{"llfe", SNDRV_CHMAP_LLFE}, /* left LFE */
|
|
Packit |
4a16fb |
{"rlfe", SNDRV_CHMAP_RLFE}, /* right LFE */
|
|
Packit |
4a16fb |
{"bc", SNDRV_CHMAP_BC}, /* bottom center */
|
|
Packit |
4a16fb |
{"blc", SNDRV_CHMAP_BLC}, /* bottom left center */
|
|
Packit |
4a16fb |
{"brc", SNDRV_CHMAP_BRC}, /* bottom right center */
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static int lookup_channel(const char *c)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
unsigned int i;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (i = 0; i < ARRAY_SIZE(channel_map); i++) {
|
|
Packit |
4a16fb |
if (strcasecmp(channel_map[i].name, c) == 0) {
|
|
Packit |
4a16fb |
return channel_map[i].id;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
return -EINVAL;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* Parse a channel mapping. */
|
|
Packit |
4a16fb |
int tplg_parse_channel(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
snd_config_iterator_t i, next;
|
|
Packit |
4a16fb |
snd_config_t *n;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_channel *channel = private;
|
|
Packit |
4a16fb |
const char *id, *value;
|
|
Packit |
4a16fb |
int channel_id;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
if (tplg->channel_idx >= SND_SOC_TPLG_MAX_CHAN)
|
|
Packit |
4a16fb |
return -EINVAL;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
channel += tplg->channel_idx;
|
|
Packit |
4a16fb |
snd_config_get_id(cfg, &id;;
|
|
Packit |
4a16fb |
tplg_dbg("\tChannel %s at index %d\n", id, tplg->channel_idx);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
channel_id = lookup_channel(id);
|
|
Packit |
4a16fb |
if (channel_id < 0) {
|
|
Packit |
4a16fb |
SNDERR("error: invalid channel %s\n", id);
|
|
Packit |
4a16fb |
return -EINVAL;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
channel->id = channel_id;
|
|
Packit |
4a16fb |
channel->size = sizeof(*channel);
|
|
Packit |
4a16fb |
tplg_dbg("\tChan %s = %d\n", id, channel->id);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
snd_config_for_each(i, next, cfg) {
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
n = snd_config_iterator_entry(i);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* get id */
|
|
Packit |
4a16fb |
if (snd_config_get_id(n, &id) < 0)
|
|
Packit |
4a16fb |
continue;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* get value */
|
|
Packit |
4a16fb |
if (snd_config_get_string(n, &value) < 0)
|
|
Packit |
4a16fb |
continue;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
if (strcmp(id, "reg") == 0)
|
|
Packit |
4a16fb |
channel->reg = atoi(value);
|
|
Packit |
4a16fb |
else if (strcmp(id, "shift") == 0)
|
|
Packit |
4a16fb |
channel->shift = atoi(value);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
tplg_dbg("\t\t%s = %s\n", id, value);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
tplg->channel_idx++;
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
}
|