Merge series "ASoC: rt1308-sdw: configure amplifier with set_tdm_slot()" from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:
When two (or more) amplifiers are on the same link, the integrator may: a) assign dedicated slots for each of the amplifiers. b) provide the same configuration to all amplifiers, and rely on additional controls/processing in the amplifier to generate different outputs. case a) was the initial direction for SoundWire and is required for amplifiers with limited capabilities, but to deal with orientation or 'posture' changes it's easier to implement case b) when the amplifier can deal with multiple channels. This patchset suggest the use of the set_tdm_slot() API to define which of the channels will be consumed by what amplifiers. This maps well with SoundWire's 'ChannelEnable' registers. The notion of slot_width is however irrelevant here and ignored, and SoundWire ports are typically single direction, so only one of the two masks shall be used. Pierre-Louis Bossart (2): ASoC: rt1308-sdw: add set_tdm_slot() support ASoC: rt1308-sdw: use slot and rx_mask to configure stream sound/soc/codecs/rt1308-sdw.c | 38 +++++++++++++++++++++++++++++++---- sound/soc/codecs/rt1308-sdw.h | 2 ++ 2 files changed, 36 insertions(+), 4 deletions(-) -- 2.20.1
This commit is contained in:
commit
b2fc1c08f7
|
@ -507,6 +507,28 @@ static void rt1308_sdw_shutdown(struct snd_pcm_substream *substream,
|
||||||
kfree(stream);
|
kfree(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rt1308_sdw_set_tdm_slot(struct snd_soc_dai *dai,
|
||||||
|
unsigned int tx_mask,
|
||||||
|
unsigned int rx_mask,
|
||||||
|
int slots, int slot_width)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component = dai->component;
|
||||||
|
struct rt1308_sdw_priv *rt1308 =
|
||||||
|
snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (tx_mask)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (slots > 2)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rt1308->rx_mask = rx_mask;
|
||||||
|
rt1308->slots = slots;
|
||||||
|
/* slot_width is not used since it's irrelevant for SoundWire */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream,
|
static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
|
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
|
@ -517,7 +539,7 @@ static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct sdw_port_config port_config;
|
struct sdw_port_config port_config;
|
||||||
enum sdw_data_direction direction;
|
enum sdw_data_direction direction;
|
||||||
struct sdw_stream_data *stream;
|
struct sdw_stream_data *stream;
|
||||||
int retval, port, num_channels;
|
int retval, port, num_channels, ch_mask;
|
||||||
|
|
||||||
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
|
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
|
||||||
stream = snd_soc_dai_get_dma_data(dai, substream);
|
stream = snd_soc_dai_get_dma_data(dai, substream);
|
||||||
|
@ -537,13 +559,20 @@ static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rt1308->slots) {
|
||||||
|
num_channels = rt1308->slots;
|
||||||
|
ch_mask = rt1308->rx_mask;
|
||||||
|
} else {
|
||||||
|
num_channels = params_channels(params);
|
||||||
|
ch_mask = (1 << num_channels) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
stream_config.frame_rate = params_rate(params);
|
stream_config.frame_rate = params_rate(params);
|
||||||
stream_config.ch_count = params_channels(params);
|
stream_config.ch_count = num_channels;
|
||||||
stream_config.bps = snd_pcm_format_width(params_format(params));
|
stream_config.bps = snd_pcm_format_width(params_format(params));
|
||||||
stream_config.direction = direction;
|
stream_config.direction = direction;
|
||||||
|
|
||||||
num_channels = params_channels(params);
|
port_config.ch_mask = ch_mask;
|
||||||
port_config.ch_mask = (1 << (num_channels)) - 1;
|
|
||||||
port_config.num = port;
|
port_config.num = port;
|
||||||
|
|
||||||
retval = sdw_stream_add_slave(rt1308->sdw_slave, &stream_config,
|
retval = sdw_stream_add_slave(rt1308->sdw_slave, &stream_config,
|
||||||
|
@ -597,6 +626,7 @@ static const struct snd_soc_dai_ops rt1308_aif_dai_ops = {
|
||||||
.hw_free = rt1308_sdw_pcm_hw_free,
|
.hw_free = rt1308_sdw_pcm_hw_free,
|
||||||
.set_sdw_stream = rt1308_set_sdw_stream,
|
.set_sdw_stream = rt1308_set_sdw_stream,
|
||||||
.shutdown = rt1308_sdw_shutdown,
|
.shutdown = rt1308_sdw_shutdown,
|
||||||
|
.set_tdm_slot = rt1308_sdw_set_tdm_slot,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RT1308_STEREO_RATES SNDRV_PCM_RATE_48000
|
#define RT1308_STEREO_RATES SNDRV_PCM_RATE_48000
|
||||||
|
|
|
@ -160,6 +160,8 @@ struct rt1308_sdw_priv {
|
||||||
struct sdw_bus_params params;
|
struct sdw_bus_params params;
|
||||||
bool hw_init;
|
bool hw_init;
|
||||||
bool first_hw_init;
|
bool first_hw_init;
|
||||||
|
int rx_mask;
|
||||||
|
int slots;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sdw_stream_data {
|
struct sdw_stream_data {
|
||||||
|
|
Loading…
Reference in a new issue