Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6131084a authored by Jyri Sarha's avatar Jyri Sarha Committed by Mark Brown
Browse files

ASoC: simple-card: Add tdm slot mask support to simple-card



Adds DT binding for explicitly choosing a tdm mask for DAI and uses it
in simple-card. The API for snd_soc_of_parse_tdm_slot() has also been
changed.

Signed-off-by: default avatarJyri Sarha <jsarha@ti.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6ff33f39
Loading
Loading
Loading
Loading
+10 −1
Original line number Original line Diff line number Diff line
@@ -5,10 +5,14 @@ This specifies audio DAI's TDM slot.
TDM slot properties:
TDM slot properties:
dai-tdm-slot-num : Number of slots in use.
dai-tdm-slot-num : Number of slots in use.
dai-tdm-slot-width : Width in bits for each slot.
dai-tdm-slot-width : Width in bits for each slot.
dai-tdm-slot-tx-mask : Transmit direction slot mask, optional
dai-tdm-slot-rx-mask : Receive direction slot mask, optional


For instance:
For instance:
	dai-tdm-slot-num = <2>;
	dai-tdm-slot-num = <2>;
	dai-tdm-slot-width = <8>;
	dai-tdm-slot-width = <8>;
	dai-tdm-slot-tx-mask = <0 1>;
	dai-tdm-slot-rx-mask = <1 0>;


And for each spcified driver, there could be one .of_xlate_tdm_slot_mask()
And for each spcified driver, there could be one .of_xlate_tdm_slot_mask()
to specify a explicit mapping of the channels and the slots. If it's absent
to specify a explicit mapping of the channels and the slots. If it's absent
@@ -18,3 +22,8 @@ tx and rx masks.
For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
for an active slot as default, and the default active bits are at the LSB of
for an active slot as default, and the default active bits are at the LSB of
the masks.
the masks.

The explicit masks are given as array of integers, where the first
number presents bit-0 (LSB), second presents bit-1, etc. Any non zero
number is considered 1 and 0 is 0. snd_soc_of_xlate_tdm_slot_mask()
does not do anything, if either mask is set non zero value.
+2 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,8 @@ struct asoc_simple_dai {
	unsigned int sysclk;
	unsigned int sysclk;
	int slots;
	int slots;
	int slot_width;
	int slot_width;
	unsigned int tx_slot_mask;
	unsigned int rx_slot_mask;
	struct clk *clk;
	struct clk *clk;
};
};


+2 −0
Original line number Original line Diff line number Diff line
@@ -1601,6 +1601,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
					  const char *propname);
					  const char *propname);
int snd_soc_of_parse_tdm_slot(struct device_node *np,
int snd_soc_of_parse_tdm_slot(struct device_node *np,
			      unsigned int *tx_mask,
			      unsigned int *rx_mask,
			      unsigned int *slots,
			      unsigned int *slots,
			      unsigned int *slot_width);
			      unsigned int *slot_width);
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
+6 −2
Original line number Original line Diff line number Diff line
@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
	}
	}


	if (set->slots) {
	if (set->slots) {
		ret = snd_soc_dai_set_tdm_slot(dai, 0, 0,
		ret = snd_soc_dai_set_tdm_slot(dai,
					       set->tx_slot_mask,
					       set->rx_slot_mask,
						set->slots,
						set->slots,
						set->slot_width);
						set->slot_width);
		if (ret && ret != -ENOTSUPP) {
		if (ret && ret != -ENOTSUPP) {
@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
		return ret;
		return ret;


	/* Parse TDM slot */
	/* Parse TDM slot */
	ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
	ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
					&dai->rx_slot_mask,
					&dai->slots, &dai->slot_width);
	if (ret)
	if (ret)
		return ret;
		return ret;


+25 −0
Original line number Original line Diff line number Diff line
@@ -3291,13 +3291,38 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
}
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);


static int snd_soc_of_get_slot_mask(struct device_node *np,
				    const char *prop_name,
				    unsigned int *mask)
{
	u32 val;
	const u32 *of_slot_mask = of_get_property(np, prop_name, &val);
	int i;

	if (!of_slot_mask)
		return 0;
	val /= sizeof(u32);
	for (i = 0; i < val; i++)
		if (be32_to_cpup(&of_slot_mask[i]))
			*mask |= (1 << i);

	return val;
}

int snd_soc_of_parse_tdm_slot(struct device_node *np,
int snd_soc_of_parse_tdm_slot(struct device_node *np,
			      unsigned int *tx_mask,
			      unsigned int *rx_mask,
			      unsigned int *slots,
			      unsigned int *slots,
			      unsigned int *slot_width)
			      unsigned int *slot_width)
{
{
	u32 val;
	u32 val;
	int ret;
	int ret;


	if (tx_mask)
		snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask);
	if (rx_mask)
		snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask);

	if (of_property_read_bool(np, "dai-tdm-slot-num")) {
	if (of_property_read_bool(np, "dai-tdm-slot-num")) {
		ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
		ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
		if (ret)
		if (ret)