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: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Jyri Sarha 2015-09-09 21:27:43 +03:00 committed by Mark Brown
parent 6ff33f3902
commit 6131084a0b
5 changed files with 45 additions and 3 deletions

View File

@ -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.

View File

@ -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;
};

View File

@ -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,

View File

@ -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;

View File

@ -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)