mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	topology: Parse HW configurations of physical DAI links defined by C API
Add HW configurations to C API template of physical link configuration. Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									f5b275b24c
								
							
						
					
					
						commit
						6b4d775b97
					
				
					 4 changed files with 84 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -927,6 +927,33 @@ struct snd_tplg_pcm_template {
 | 
			
		|||
	struct snd_tplg_stream_template stream[0]; /*!< supported configs */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 /** \struct snd_tplg_hw_config_template
 | 
			
		||||
 * \brief Template type to describe a physical link runtime supported
 | 
			
		||||
 * hardware config, i.e. hardware audio formats.
 | 
			
		||||
 */
 | 
			
		||||
struct snd_tplg_hw_config_template {
 | 
			
		||||
	int id;                         /* unique ID - - used to match */
 | 
			
		||||
	unsigned int fmt;               /* SND_SOC_DAI_FORMAT_ format value */
 | 
			
		||||
	unsigned char clock_gated;      /* 1 if clock can be gated to save power */
 | 
			
		||||
	unsigned char  invert_bclk;     /* 1 for inverted BCLK, 0 for normal */
 | 
			
		||||
	unsigned char  invert_fsync;    /* 1 for inverted frame clock, 0 for normal */
 | 
			
		||||
	unsigned char  bclk_master;     /* 1 for master of BCLK, 0 for slave */
 | 
			
		||||
	unsigned char  fsync_master;    /* 1 for master of FSYNC, 0 for slave */
 | 
			
		||||
	unsigned char  mclk_direction;  /* 0 for input, 1 for output */
 | 
			
		||||
	unsigned short reserved;        /* for 32bit alignment */
 | 
			
		||||
	unsigned int mclk_rate;	        /* MCLK or SYSCLK freqency in Hz */
 | 
			
		||||
	unsigned int bclk_rate;	        /* BCLK freqency in Hz */
 | 
			
		||||
	unsigned int fsync_rate;        /* frame clock in Hz */
 | 
			
		||||
	unsigned int tdm_slots;         /* number of TDM slots in use */
 | 
			
		||||
	unsigned int tdm_slot_width;    /* width in bits for each slot */
 | 
			
		||||
	unsigned int tx_slots;          /* bit mask for active Tx slots */
 | 
			
		||||
	unsigned int rx_slots;          /* bit mask for active Rx slots */
 | 
			
		||||
	unsigned int tx_channels;       /* number of Tx channels */
 | 
			
		||||
	unsigned int *tx_chanmap;       /* array of slot number */
 | 
			
		||||
	unsigned int rx_channels;       /* number of Rx channels */
 | 
			
		||||
	unsigned int *rx_chanmap;       /* array of slot number */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** \struct snd_tplg_link_template
 | 
			
		||||
 * \brief Template type for BE and CC DAI Links.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -934,7 +961,11 @@ struct snd_tplg_link_template {
 | 
			
		|||
	const char *name;	/*!< link name */
 | 
			
		||||
	int id;	/*!< unique ID - used to match with existing BE and CC links */
 | 
			
		||||
	int num_streams;	/*!< number of configs */
 | 
			
		||||
	struct snd_tplg_stream_template stream[0]; /*!< supported configs */
 | 
			
		||||
	struct snd_tplg_stream_template *stream;       /*!< supported configs */
 | 
			
		||||
 | 
			
		||||
	struct snd_tplg_hw_config_template *hw_config; /*!< supported HW configs */
 | 
			
		||||
	int num_hw_configs;		/* number of hw configs */
 | 
			
		||||
	int default_hw_config_id;       /* default hw config ID for init */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** \struct snd_tplg_obj_template
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -193,6 +193,7 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
 | 
			
		|||
		obj_size = sizeof(struct snd_soc_tplg_pcm);
 | 
			
		||||
		break;
 | 
			
		||||
	case SND_TPLG_TYPE_BE:
 | 
			
		||||
	case SND_TPLG_TYPE_LINK:
 | 
			
		||||
		list_add_tail(&elem->list, &tplg->be_list);
 | 
			
		||||
		obj_size = sizeof(struct snd_soc_tplg_link_config);
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,6 +348,7 @@ int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
 | 
			
		|||
		return tplg_add_graph_object(tplg, t);
 | 
			
		||||
	case SND_TPLG_TYPE_PCM:
 | 
			
		||||
		return tplg_add_pcm_object(tplg, t);
 | 
			
		||||
	case SND_TPLG_TYPE_LINK:
 | 
			
		||||
	case SND_TPLG_TYPE_BE:
 | 
			
		||||
	case SND_TPLG_TYPE_CC:
 | 
			
		||||
		return tplg_add_link_object(tplg, t);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ static int build_link(snd_tplg_t *tplg, struct tplg_elem *elem)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* build BE/CC DAI link configurations */
 | 
			
		||||
/* build physical DAI link configurations */
 | 
			
		||||
int tplg_build_links(snd_tplg_t *tplg, unsigned int type)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *base, *pos;
 | 
			
		||||
| 
						 | 
				
			
			@ -176,6 +176,7 @@ int tplg_build_links(snd_tplg_t *tplg, unsigned int type)
 | 
			
		|||
	int err = 0;
 | 
			
		||||
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case SND_TPLG_TYPE_LINK:
 | 
			
		||||
	case SND_TPLG_TYPE_BE:
 | 
			
		||||
		base = &tplg->be_list;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -189,11 +190,6 @@ int tplg_build_links(snd_tplg_t *tplg, unsigned int type)
 | 
			
		|||
	list_for_each(pos, base) {
 | 
			
		||||
 | 
			
		||||
		elem = list_entry(pos, struct tplg_elem, list);
 | 
			
		||||
		if (elem->type != type) {
 | 
			
		||||
			SNDERR("error: invalid elem '%s'\n", elem->id);
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		err =  build_link(tplg, elem);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
| 
						 | 
				
			
			@ -741,6 +737,47 @@ int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set link HW config from C API template */
 | 
			
		||||
static int set_link_hw_config(struct snd_soc_tplg_hw_config *cfg,
 | 
			
		||||
			struct snd_tplg_hw_config_template *tpl)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	cfg->size = sizeof(*cfg);
 | 
			
		||||
	cfg->id = tpl->id;
 | 
			
		||||
 | 
			
		||||
	cfg->fmt = tpl->fmt;
 | 
			
		||||
	cfg->clock_gated = tpl->clock_gated;
 | 
			
		||||
	cfg->invert_bclk = tpl->invert_bclk;
 | 
			
		||||
	cfg->invert_fsync = tpl->invert_fsync;
 | 
			
		||||
	cfg->bclk_master = tpl->bclk_master;
 | 
			
		||||
	cfg->fsync_master = tpl->fsync_master;
 | 
			
		||||
	cfg->mclk_direction = tpl->mclk_direction;
 | 
			
		||||
	cfg->reserved = tpl->reserved;
 | 
			
		||||
	cfg->mclk_rate = tpl->mclk_rate;
 | 
			
		||||
	cfg->bclk_rate = tpl->bclk_rate;
 | 
			
		||||
	cfg->fsync_rate = tpl->fsync_rate;
 | 
			
		||||
 | 
			
		||||
	cfg->tdm_slots = tpl->tdm_slots;
 | 
			
		||||
	cfg->tdm_slot_width = tpl->tdm_slot_width;
 | 
			
		||||
	cfg->tx_slots = tpl->tx_slots;
 | 
			
		||||
	cfg->rx_slots = tpl->rx_slots;
 | 
			
		||||
 | 
			
		||||
	if (cfg->tx_channels > SND_SOC_TPLG_MAX_CHAN
 | 
			
		||||
		|| cfg->rx_channels > SND_SOC_TPLG_MAX_CHAN)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	cfg->tx_channels = tpl->tx_channels;
 | 
			
		||||
	for (i = 0; i < cfg->tx_channels; i++)
 | 
			
		||||
		cfg->tx_chanmap[i] = tpl->tx_chanmap[i];
 | 
			
		||||
 | 
			
		||||
	cfg->rx_channels = tpl->rx_channels;
 | 
			
		||||
	for (i = 0; i < cfg->rx_channels; i++)
 | 
			
		||||
		cfg->rx_chanmap[i] = tpl->rx_chanmap[i];
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Add a physical DAI link element from C API */
 | 
			
		||||
int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -771,5 +808,12 @@ int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
 | 
			
		|||
	for (i = 0; i < link->num_streams; i++)
 | 
			
		||||
		tplg_add_stream_object(&link->stream[i], &link_tpl->stream[i]);
 | 
			
		||||
 | 
			
		||||
	/* HW configs */
 | 
			
		||||
	if (link_tpl->num_hw_configs > SND_SOC_TPLG_HW_CONFIG_MAX)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	link->num_hw_configs = link_tpl->num_hw_configs;
 | 
			
		||||
	link->default_hw_config_id = link_tpl->default_hw_config_id;
 | 
			
		||||
	for (i = 0; i < link->num_hw_configs; i++)
 | 
			
		||||
		set_link_hw_config(&link->hw_config[i], &link_tpl->hw_config[i]);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue