[PATCH v3 2/3] ASoC: core: add TDM slot parsing from DT supports

From: Xiubo Li
Date: Thu Feb 13 2014 - 21:38:38 EST


For some CPU/CODEC DAI devices the TDM slot infomation maybe needed. This
patch adds the slot parsing from DT supports.

TDM slot properties:
dai-tdm-slot-num : Number of slots in use.
dai-tdm-slot-width : Width in bits for each slot.

For instance:
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <8>;

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
the default snd_soc_of_xlate_tdm_slot_mask() will be used to generating the
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.

Signed-off-by: Xiubo Li <Li.Xiubo@xxxxxxxxxxxxx>
Cc: Lars-Peter Clausen <lars@xxxxxxxxxx>
Cc: Mark Brown <broonie@xxxxxxxxxx>
---
include/sound/soc-dai.h | 2 ++
include/sound/soc.h | 3 +++
sound/soc/soc-core.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+)

diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 71f27c4..d86e0fc 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -142,6 +142,8 @@ struct snd_soc_dai_ops {
* Called by soc_card drivers, normally in their hw_params.
*/
int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
+ int (*of_xlate_tdm_slot_mask)(unsigned int slots,
+ unsigned int *tx_mask, unsigned int *rx_mask);
int (*set_tdm_slot)(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width);
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 21d025e..759db05 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1190,6 +1190,9 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
const char *propname);
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 *slots,
+ unsigned int *slot_width);
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
const char *propname);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index abee5f4..bc3d090 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3663,6 +3663,30 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);

/**
+ * snd_soc_of_xlate_tdm_slot - generate tx/rx slot mask.
+ * @slots: Number of slots in use.
+ * @tx_mask: bitmask representing active TX slots.
+ * @rx_mask: bitmask representing active RX slots.
+ *
+ * Generates the TDM tx and rx slot default masks for DAI.
+ */
+static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots,
+ unsigned int *tx_mask,
+ unsigned int *rx_mask)
+{
+ if (*tx_mask || *rx_mask)
+ return 0;
+
+ if (!slots)
+ return -EINVAL;
+
+ *tx_mask = (1 << slots) - 1;
+ *rx_mask = (1 << slots) - 1;
+
+ return 0;
+}
+
+/**
* snd_soc_dai_set_tdm_slot - configure DAI TDM.
* @dai: DAI
* @tx_mask: bitmask representing active TX slots.
@@ -3676,6 +3700,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{
+ if (dai->driver && dai->driver->ops->of_xlate_tdm_slot_mask)
+ dai->driver->ops->of_xlate_tdm_slot_mask(slots,
+ &tx_mask, &rx_mask);
+ else
+ snd_soc_of_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
+
if (dai->driver && dai->driver->ops->set_tdm_slot)
return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
slots, slot_width);
@@ -4558,6 +4588,35 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);

+int snd_soc_of_parse_tdm_slot(struct device_node *np,
+ unsigned int *slots,
+ unsigned int *slot_width)
+{
+ u32 val;
+ int ret;
+
+ if (of_property_read_bool(np, "dai-tdm-slot-num")) {
+ ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
+ if (ret)
+ return ret;
+
+ if (slots)
+ *slots = val;
+ }
+
+ if (of_property_read_bool(np, "dai-tdm-slot-width")) {
+ ret = of_property_read_u32(np, "dai-tdm-slot-width", &val);
+ if (ret)
+ return ret;
+
+ if (slot_width)
+ *slot_width = val;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
+
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
const char *propname)
{
--
1.8.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/