Blame src/topology/channel.c

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
}