summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/tdm-slot.txt11
-rw-r--r--include/sound/simple_card.h2
-rw-r--r--include/sound/soc.h2
-rw-r--r--sound/soc/generic/simple-card.c8
-rw-r--r--sound/soc/soc-core.c25
5 files changed, 45 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/sound/tdm-slot.txt b/Documentation/devicetree/bindings/sound/tdm-slot.txt
index 6a2c84247f91..34cf70e2cbc4 100644
--- a/Documentation/devicetree/bindings/sound/tdm-slot.txt
+++ b/Documentation/devicetree/bindings/sound/tdm-slot.txt
@@ -4,11 +4,15 @@ This specifies audio DAI's TDM slot.
TDM slot properties:
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:
dai-tdm-slot-num = <2>;
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()
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 an active slot as default, and the default active bits are at the LSB of
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.
diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h
index b9b4f289fe6b..0399352f3a62 100644
--- a/include/sound/simple_card.h
+++ b/include/sound/simple_card.h
@@ -19,6 +19,8 @@ struct asoc_simple_dai {
unsigned int sysclk;
int slots;
int slot_width;
+ unsigned int tx_slot_mask;
+ unsigned int rx_slot_mask;
struct clk *clk;
};
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 884e728b09d9..a76622d7bb2f 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -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,
const char *propname);
int snd_soc_of_parse_tdm_slot(struct device_node *np,
+ unsigned int *tx_mask,
+ unsigned int *rx_mask,
unsigned int *slots,
unsigned int *slot_width);
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 3ff76d419436..54c33204541f 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
}
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->slot_width);
if (ret && ret != -ENOTSUPP) {
@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
return ret;
/* 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)
return ret;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6173d15236c3..c5e21ca0c015 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -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);
+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,
+ unsigned int *tx_mask,
+ unsigned int *rx_mask,
unsigned int *slots,
unsigned int *slot_width)
{
u32 val;
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")) {
ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
if (ret)