Commit b2fc1c08 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: rt1308-sdw: configure amplifier with set_tdm_slot()" from...

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
parents cfc50995 27a18e9e
...@@ -507,6 +507,28 @@ static void rt1308_sdw_shutdown(struct snd_pcm_substream *substream, ...@@ -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, ...@@ -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, ...@@ -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 = { ...@@ -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 { ...@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment