ASoC: core: add TDM slot parsing from DT supports
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@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
72899ad8a4
commit
89c6785715
3 changed files with 64 additions and 0 deletions
|
@ -142,6 +142,8 @@ struct snd_soc_dai_ops {
|
||||||
* Called by soc_card drivers, normally in their hw_params.
|
* Called by soc_card drivers, normally in their hw_params.
|
||||||
*/
|
*/
|
||||||
int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
|
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,
|
int (*set_tdm_slot)(struct snd_soc_dai *dai,
|
||||||
unsigned int tx_mask, unsigned int rx_mask,
|
unsigned int tx_mask, unsigned int rx_mask,
|
||||||
int slots, int slot_width);
|
int slots, int slot_width);
|
||||||
|
|
|
@ -1175,6 +1175,9 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
|
||||||
const char *propname);
|
const char *propname);
|
||||||
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,
|
||||||
|
unsigned int *slots,
|
||||||
|
unsigned int *slot_width);
|
||||||
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
||||||
const char *propname);
|
const char *propname);
|
||||||
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
|
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
|
||||||
|
|
|
@ -3608,6 +3608,30 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_dai_set_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.
|
* snd_soc_dai_set_tdm_slot - configure DAI TDM.
|
||||||
* @dai: DAI
|
* @dai: DAI
|
||||||
|
@ -3622,6 +3646,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
|
||||||
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
|
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)
|
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)
|
if (dai->driver && dai->driver->ops->set_tdm_slot)
|
||||||
return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
|
return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
|
||||||
slots, slot_width);
|
slots, slot_width);
|
||||||
|
@ -4504,6 +4534,35 @@ 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);
|
||||||
|
|
||||||
|
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,
|
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
||||||
const char *propname)
|
const char *propname)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue