* [PATCH V3 0/2] ASoC: audio_graph_card2: Support variable slot widths
@ 2022-02-28 17:27 Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 1/2] ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map Richard Fitzgerald
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Richard Fitzgerald @ 2022-02-28 17:27 UTC (permalink / raw)
To: broonie, robh+dt, kuninori.morimoto.gx
Cc: alsa-devel, devicetree, linux-kernel, patches, Richard Fitzgerald
This adds support for I2S/TDM links where the slot width varies
depending on the sample width, in a way that cannot be guessed by
component hw_params().
A typical example is:
- 16-bit samples use 16-bit slots
- 24-bit samples use 32-bit slots
There is no way for a component hw_params() to deduce from the information
it is passed that 24-bit samples will be in 32-bit slots.
Some audio hardware cannot support a fixed slot width or a slot width
equal to the sample width in all cases. This is usually due either to
limitations of the audio serial port or system clocking restrictions.
These two patches add support for defining a mapping between sample widths
and sample slots. This allows audio_graph_card2 to be used in these
situations instead of having to write a custom machine driver.
Changes since V2:
- Change property type to uint32-matrix.
- Put min/max ranges on cells.
- Use per-item description to document the tuple entries.
- Add a slot count to the tuple - it's unlikely that this would change
for different sample rates but it's trivial to implement support for it.
- Minor tidying of the code in asoc_simple_parse_tdm_width_map() and
asoc_simple_set_tdm().
Richard Fitzgerald (2):
ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map
ASoC: audio_graph_card2: Add support for variable slot widths
.../bindings/sound/audio-graph-port.yaml | 20 ++++
include/sound/simple_card_utils.h | 11 +++
sound/soc/generic/audio-graph-card2.c | 4 +
sound/soc/generic/simple-card-utils.c | 97 +++++++++++++++++++
4 files changed, 132 insertions(+)
--
2.30.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH V3 1/2] ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map
2022-02-28 17:27 [PATCH V3 0/2] ASoC: audio_graph_card2: Support variable slot widths Richard Fitzgerald
@ 2022-02-28 17:27 ` Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 2/2] ASoC: audio_graph_card2: Add support for variable slot widths Richard Fitzgerald
2022-03-07 20:39 ` [PATCH V3 0/2] ASoC: audio_graph_card2: Support " Mark Brown
2 siblings, 0 replies; 4+ messages in thread
From: Richard Fitzgerald @ 2022-02-28 17:27 UTC (permalink / raw)
To: broonie, robh+dt, kuninori.morimoto.gx
Cc: alsa-devel, devicetree, linux-kernel, patches, Richard Fitzgerald
Some audio hardware cannot support a fixed slot width for all sample
widths, or a slot width equal to the sample width for all sample widths.
This is usually due either to limitations of the audio serial port or
system clocking restrictions.
This property allows setting a mapping of sample widths and the
corresponding tdm slot widths. The slot count is also provided for
each slot width - although this would almost always be the same for
all slot widths this allows for possibly adding extra padding slots
to maintain a fixed bitclock frequency.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
.../bindings/sound/audio-graph-port.yaml | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml
index 476dcb49ece6..5c368674d11a 100644
--- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml
+++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml
@@ -71,4 +71,24 @@ patternProperties:
description: CPU to Codec rate channels.
$ref: /schemas/types.yaml#/definitions/uint32
+ dai-tdm-slot-width-map:
+ description: Mapping of sample widths to slot widths. For hardware
+ that cannot support a fixed slot width or a slot width always
+ equal to sample width. A matrix of one or more 3-tuples.
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ items:
+ items:
+ -
+ description: Sample width in bits
+ minimum: 8
+ maximum: 64
+ -
+ description: Slot width in bits
+ minimum: 8
+ maximum: 256
+ -
+ description: Slot count
+ minimum: 1
+ maximum: 64
+
additionalProperties: true
--
2.30.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH V3 2/2] ASoC: audio_graph_card2: Add support for variable slot widths
2022-02-28 17:27 [PATCH V3 0/2] ASoC: audio_graph_card2: Support variable slot widths Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 1/2] ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map Richard Fitzgerald
@ 2022-02-28 17:27 ` Richard Fitzgerald
2022-03-07 20:39 ` [PATCH V3 0/2] ASoC: audio_graph_card2: Support " Mark Brown
2 siblings, 0 replies; 4+ messages in thread
From: Richard Fitzgerald @ 2022-02-28 17:27 UTC (permalink / raw)
To: broonie, robh+dt, kuninori.morimoto.gx
Cc: alsa-devel, devicetree, linux-kernel, patches, Richard Fitzgerald
Some audio hardware cannot support the same slot width for all sample
widths, or a slot width equal to the sample width for all sample widths.
This is usually due either to limitations of the audio serial port or
system clocking restrictions.
A typical example would be:
- 16-bit samples in 16-bit slots
- 24-bit samples in 32-bit slots
The new dai-tdm-slot-width-map property allows setting a mapping of
sample widths and the corresponding tdm slot widths and slot counts.
Although the slot count is usually the same for all cases this does
allow for adding padding slots to maintain the same bitclk frequency.
The property is added to each endpoint node that needs the component
DAI to be told the TDM slot width and count.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
include/sound/simple_card_utils.h | 11 +++
sound/soc/generic/audio-graph-card2.c | 4 ++
sound/soc/generic/simple-card-utils.c | 97 +++++++++++++++++++++++++++
3 files changed, 112 insertions(+)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 5ee269c59aac..8faa649f712b 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -16,6 +16,12 @@
#define asoc_simple_init_mic(card, sjack, prefix) \
asoc_simple_init_jack(card, sjack, 0, prefix, NULL)
+struct asoc_simple_tdm_width_map {
+ u8 sample_bits;
+ u8 slot_count;
+ u16 slot_width;
+};
+
struct asoc_simple_dai {
const char *name;
unsigned int sysclk;
@@ -26,6 +32,8 @@ struct asoc_simple_dai {
unsigned int rx_slot_mask;
struct clk *clk;
bool clk_fixed;
+ struct asoc_simple_tdm_width_map *tdm_width_map;
+ int n_tdm_widths;
};
struct asoc_simple_data {
@@ -132,6 +140,9 @@ int asoc_simple_parse_daifmt(struct device *dev,
struct device_node *codec,
char *prefix,
unsigned int *retfmt);
+int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np,
+ struct asoc_simple_dai *dai);
+
__printf(3, 4)
int asoc_simple_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link,
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
index c3947347dda3..c0f3907a01fd 100644
--- a/sound/soc/generic/audio-graph-card2.c
+++ b/sound/soc/generic/audio-graph-card2.c
@@ -503,6 +503,10 @@ static int __graph_parse_node(struct asoc_simple_priv *priv,
if (ret < 0)
return ret;
+ ret = asoc_simple_parse_tdm_width_map(dev, ep, dai);
+ if (ret < 0)
+ return ret;
+
ret = asoc_simple_parse_clk(dev, ep, dai, dlc);
if (ret < 0)
return ret;
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index a4babfb63175..14c8b3a74c2d 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -12,6 +12,7 @@
#include <linux/of_gpio.h>
#include <linux/of_graph.h>
#include <sound/jack.h>
+#include <sound/pcm_params.h>
#include <sound/simple_card_utils.h>
void asoc_simple_convert_fixup(struct asoc_simple_data *data,
@@ -87,6 +88,51 @@ int asoc_simple_parse_daifmt(struct device *dev,
}
EXPORT_SYMBOL_GPL(asoc_simple_parse_daifmt);
+int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np,
+ struct asoc_simple_dai *dai)
+{
+ u32 *array_values, *p;
+ int n, i, ret;
+
+ if (!of_property_read_bool(np, "dai-tdm-slot-width-map"))
+ return 0;
+
+ n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32));
+ if (n % 3) {
+ dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n");
+ return -EINVAL;
+ }
+
+ dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL);
+ if (!dai->tdm_width_map)
+ return -ENOMEM;
+
+ array_values = kcalloc(n, sizeof(*array_values), GFP_KERNEL);
+ if (!array_values)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n);
+ if (ret < 0) {
+ dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret);
+ goto out;
+ }
+
+ p = array_values;
+ for (i = 0; i < n / 3; ++i) {
+ dai->tdm_width_map[i].sample_bits = *p++;
+ dai->tdm_width_map[i].slot_width = *p++;
+ dai->tdm_width_map[i].slot_count = *p++;
+ }
+
+ dai->n_tdm_widths = i;
+ ret = 0;
+out:
+ kfree(array_values);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_parse_tdm_width_map);
+
int asoc_simple_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link,
const char *fmt, ...)
@@ -309,6 +355,42 @@ static int asoc_simple_set_clk_rate(struct device *dev,
return clk_set_rate(simple_dai->clk, rate);
}
+static int asoc_simple_set_tdm(struct snd_soc_dai *dai,
+ struct asoc_simple_dai *simple_dai,
+ struct snd_pcm_hw_params *params)
+{
+ int sample_bits = params_width(params);
+ int slot_width = simple_dai->slot_width;
+ int slot_count = simple_dai->slots;
+ int i, ret;
+
+ if (!simple_dai || !simple_dai->tdm_width_map)
+ return 0;
+
+ if (slot_width == 0)
+ slot_width = sample_bits;
+
+ for (i = 0; i < simple_dai->n_tdm_widths; ++i) {
+ if (simple_dai->tdm_width_map[i].sample_bits == sample_bits) {
+ slot_width = simple_dai->tdm_width_map[i].slot_width;
+ slot_count = simple_dai->tdm_width_map[i].slot_count;
+ break;
+ }
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(dai,
+ simple_dai->tx_slot_mask,
+ simple_dai->rx_slot_mask,
+ slot_count,
+ slot_width);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(dai->dev, "simple-card: set_tdm_slot error: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
int asoc_simple_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -362,6 +444,21 @@ int asoc_simple_hw_params(struct snd_pcm_substream *substream,
return ret;
}
}
+
+ for_each_prop_dai_codec(props, i, pdai) {
+ sdai = asoc_rtd_to_codec(rtd, i);
+ ret = asoc_simple_set_tdm(sdai, pdai, params);
+ if (ret < 0)
+ return ret;
+ }
+
+ for_each_prop_dai_cpu(props, i, pdai) {
+ sdai = asoc_rtd_to_cpu(rtd, i);
+ ret = asoc_simple_set_tdm(sdai, pdai, params);
+ if (ret < 0)
+ return ret;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(asoc_simple_hw_params);
--
2.30.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH V3 0/2] ASoC: audio_graph_card2: Support variable slot widths
2022-02-28 17:27 [PATCH V3 0/2] ASoC: audio_graph_card2: Support variable slot widths Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 1/2] ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 2/2] ASoC: audio_graph_card2: Add support for variable slot widths Richard Fitzgerald
@ 2022-03-07 20:39 ` Mark Brown
2 siblings, 0 replies; 4+ messages in thread
From: Mark Brown @ 2022-03-07 20:39 UTC (permalink / raw)
To: Richard Fitzgerald, kuninori.morimoto.gx, robh+dt
Cc: linux-kernel, patches, devicetree, alsa-devel
On Mon, 28 Feb 2022 17:27:52 +0000, Richard Fitzgerald wrote:
> This adds support for I2S/TDM links where the slot width varies
> depending on the sample width, in a way that cannot be guessed by
> component hw_params().
>
> A typical example is:
>
> - 16-bit samples use 16-bit slots
> - 24-bit samples use 32-bit slots
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/2] ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map
commit: 26e5366dd30569a469e1a87998b866b814deccf8
[2/2] ASoC: audio_graph_card2: Add support for variable slot widths
commit: 1e974e5b82b3d75069b50445cd248cee0199654e
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-03-07 20:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-28 17:27 [PATCH V3 0/2] ASoC: audio_graph_card2: Support variable slot widths Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 1/2] ASoC: dt-bindings: audio-graph-port: Add dai-tdm-slot-width-map Richard Fitzgerald
2022-02-28 17:27 ` [PATCH V3 2/2] ASoC: audio_graph_card2: Add support for variable slot widths Richard Fitzgerald
2022-03-07 20:39 ` [PATCH V3 0/2] ASoC: audio_graph_card2: Support " Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®