diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/tdm-slot.txt | 20 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/sound/widgets.txt | 20 | ||||
-rw-r--r-- | include/sound/soc-dai.h | 2 | ||||
-rw-r--r-- | include/sound/soc.h | 3 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 59 |
5 files changed, 104 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/tdm-slot.txt b/Documentation/devicetree/bindings/sound/tdm-slot.txt new file mode 100644 index 000000000000..6a2c84247f91 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tdm-slot.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | TDM slot: | ||
2 | |||
3 | This specifies audio DAI's TDM slot. | ||
4 | |||
5 | TDM slot properties: | ||
6 | dai-tdm-slot-num : Number of slots in use. | ||
7 | dai-tdm-slot-width : Width in bits for each slot. | ||
8 | |||
9 | For instance: | ||
10 | dai-tdm-slot-num = <2>; | ||
11 | dai-tdm-slot-width = <8>; | ||
12 | |||
13 | And for each spcified driver, there could be one .of_xlate_tdm_slot_mask() | ||
14 | to specify a explicit mapping of the channels and the slots. If it's absent | ||
15 | the default snd_soc_of_xlate_tdm_slot_mask() will be used to generating the | ||
16 | tx and rx masks. | ||
17 | |||
18 | For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit | ||
19 | for an active slot as default, and the default active bits are at the LSB of | ||
20 | the masks. | ||
diff --git a/Documentation/devicetree/bindings/sound/widgets.txt b/Documentation/devicetree/bindings/sound/widgets.txt new file mode 100644 index 000000000000..b6de5ba3b2de --- /dev/null +++ b/Documentation/devicetree/bindings/sound/widgets.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | Widgets: | ||
2 | |||
3 | This mainly specifies audio off-codec DAPM widgets. | ||
4 | |||
5 | Each entry is a pair of strings in DT: | ||
6 | |||
7 | "template-wname", "user-supplied-wname" | ||
8 | |||
9 | The "template-wname" being the template widget name and currently includes: | ||
10 | "Microphone", "Line", "Headphone" and "Speaker". | ||
11 | |||
12 | The "user-supplied-wname" being the user specified widget name. | ||
13 | |||
14 | For instance: | ||
15 | simple-audio-widgets = | ||
16 | "Microphone", "Microphone Jack", | ||
17 | "Line", "Line In Jack", | ||
18 | "Line", "Line Out Jack", | ||
19 | "Headphone", "Headphone Jack", | ||
20 | "Speaker", "Speaker External"; | ||
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 71f27c403194..d86e0fc41e80 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
@@ -142,6 +142,8 @@ struct snd_soc_dai_ops { | |||
142 | * Called by soc_card drivers, normally in their hw_params. | 142 | * Called by soc_card drivers, normally in their hw_params. |
143 | */ | 143 | */ |
144 | int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); | 144 | int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); |
145 | int (*of_xlate_tdm_slot_mask)(unsigned int slots, | ||
146 | unsigned int *tx_mask, unsigned int *rx_mask); | ||
145 | int (*set_tdm_slot)(struct snd_soc_dai *dai, | 147 | int (*set_tdm_slot)(struct snd_soc_dai *dai, |
146 | unsigned int tx_mask, unsigned int rx_mask, | 148 | unsigned int tx_mask, unsigned int rx_mask, |
147 | int slots, int slot_width); | 149 | int slots, int slot_width); |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 465dc6e0674d..2a878d03c147 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -1175,6 +1175,9 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, | |||
1175 | const char *propname); | 1175 | const char *propname); |
1176 | int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, | 1176 | int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, |
1177 | const char *propname); | 1177 | const char *propname); |
1178 | int snd_soc_of_parse_tdm_slot(struct device_node *np, | ||
1179 | unsigned int *slots, | ||
1180 | unsigned int *slot_width); | ||
1178 | int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | 1181 | int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, |
1179 | const char *propname); | 1182 | const char *propname); |
1180 | unsigned int snd_soc_of_parse_daifmt(struct device_node *np, | 1183 | 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 0540cb08e0ea..5b7d3ba87c7a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -3609,6 +3609,30 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
3609 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); | 3609 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); |
3610 | 3610 | ||
3611 | /** | 3611 | /** |
3612 | * snd_soc_of_xlate_tdm_slot - generate tx/rx slot mask. | ||
3613 | * @slots: Number of slots in use. | ||
3614 | * @tx_mask: bitmask representing active TX slots. | ||
3615 | * @rx_mask: bitmask representing active RX slots. | ||
3616 | * | ||
3617 | * Generates the TDM tx and rx slot default masks for DAI. | ||
3618 | */ | ||
3619 | static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots, | ||
3620 | unsigned int *tx_mask, | ||
3621 | unsigned int *rx_mask) | ||
3622 | { | ||
3623 | if (*tx_mask || *rx_mask) | ||
3624 | return 0; | ||
3625 | |||
3626 | if (!slots) | ||
3627 | return -EINVAL; | ||
3628 | |||
3629 | *tx_mask = (1 << slots) - 1; | ||
3630 | *rx_mask = (1 << slots) - 1; | ||
3631 | |||
3632 | return 0; | ||
3633 | } | ||
3634 | |||
3635 | /** | ||
3612 | * snd_soc_dai_set_tdm_slot - configure DAI TDM. | 3636 | * snd_soc_dai_set_tdm_slot - configure DAI TDM. |
3613 | * @dai: DAI | 3637 | * @dai: DAI |
3614 | * @tx_mask: bitmask representing active TX slots. | 3638 | * @tx_mask: bitmask representing active TX slots. |
@@ -3622,6 +3646,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); | |||
3622 | int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, | 3646 | int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, |
3623 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) | 3647 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
3624 | { | 3648 | { |
3649 | if (dai->driver && dai->driver->ops->of_xlate_tdm_slot_mask) | ||
3650 | dai->driver->ops->of_xlate_tdm_slot_mask(slots, | ||
3651 | &tx_mask, &rx_mask); | ||
3652 | else | ||
3653 | snd_soc_of_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); | ||
3654 | |||
3625 | if (dai->driver && dai->driver->ops->set_tdm_slot) | 3655 | if (dai->driver && dai->driver->ops->set_tdm_slot) |
3626 | return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, | 3656 | return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, |
3627 | slots, slot_width); | 3657 | slots, slot_width); |
@@ -4504,6 +4534,35 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, | |||
4504 | } | 4534 | } |
4505 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); | 4535 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); |
4506 | 4536 | ||
4537 | int snd_soc_of_parse_tdm_slot(struct device_node *np, | ||
4538 | unsigned int *slots, | ||
4539 | unsigned int *slot_width) | ||
4540 | { | ||
4541 | u32 val; | ||
4542 | int ret; | ||
4543 | |||
4544 | if (of_property_read_bool(np, "dai-tdm-slot-num")) { | ||
4545 | ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); | ||
4546 | if (ret) | ||
4547 | return ret; | ||
4548 | |||
4549 | if (slots) | ||
4550 | *slots = val; | ||
4551 | } | ||
4552 | |||
4553 | if (of_property_read_bool(np, "dai-tdm-slot-width")) { | ||
4554 | ret = of_property_read_u32(np, "dai-tdm-slot-width", &val); | ||
4555 | if (ret) | ||
4556 | return ret; | ||
4557 | |||
4558 | if (slot_width) | ||
4559 | *slot_width = val; | ||
4560 | } | ||
4561 | |||
4562 | return 0; | ||
4563 | } | ||
4564 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot); | ||
4565 | |||
4507 | int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | 4566 | int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, |
4508 | const char *propname) | 4567 | const char *propname) |
4509 | { | 4568 | { |