Skip to content

Commit fc800b8

Browse files
committed
Add support for non-interleaved mode in qmc_audio
Merge series from Herve Codina <[email protected]>: The qmc_audio driver supports only audio in interleaved mode. Non-interleaved mode can be easily supported using several QMC channel per DAI. In that case, data related to ch0 are sent to (received from) the first QMC channel, data related to ch1 use the next QMC channel and so on up to the last channel. In terms of constraints and settings, the interleaved and non-interleaved modes are slightly different. In interleaved mode: - The sample size should fit in the number of time-slots available for the QMC channel. - The number of audio channels should fit in the number of time-slots (taking into account the sample size) available for the QMC channel. In non-interleaved mode: - The number of audio channels is the number of available QMC channels. - Each QMC channel should have the same number of time-slots. - The sample size equals the number of time-slots of one QMC channel. This series add support for the non-interleaved mode in the qmc_audio driver and is composed of the following parts: - Patches 1 and 2: Fix some issues in the qmc_audio - Patches 3 to 6: Prepare qmc_audio for the non-interleaved mode - Patches 7 and 8: Extend the QMC driver API - Patches 9 and 10: The support for non-interleaved mode itself Compared to the previous iteration, this v2 series mainly improves qmc_audio_access_is_interleaved().
2 parents ecaec47 + 188d9ca commit fc800b8

File tree

4 files changed

+506
-185
lines changed

4 files changed

+506
-185
lines changed

Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ maintainers:
1212
description: |
1313
The QMC audio is an ASoC component which uses QMC (QUICC Multichannel
1414
Controller) channels to transfer the audio data.
15-
It provides as many DAI as the number of QMC channel used.
15+
It provides several DAIs. For each DAI, the DAI is working in interleaved mode
16+
if only one QMC channel is used by the DAI or it is working in non-interleaved
17+
mode if several QMC channels are used by the DAI.
1618
1719
allOf:
1820
- $ref: dai-common.yaml#
@@ -45,12 +47,19 @@ patternProperties:
4547
fsl,qmc-chan:
4648
$ref: /schemas/types.yaml#/definitions/phandle-array
4749
items:
48-
- items:
49-
- description: phandle to QMC node
50-
- description: Channel number
50+
items:
51+
- description: phandle to QMC node
52+
- description: Channel number
53+
minItems: 1
5154
description:
52-
Should be a phandle/number pair. The phandle to QMC node and the QMC
53-
channel to use for this DAI.
55+
Should be a phandle/number pair list. The list of phandle to QMC node
56+
and the QMC channel pair to use for this DAI.
57+
If only one phandle/number pair is provided, this DAI works in
58+
interleaved mode, i.e. audio channels for this DAI are interleaved in
59+
the QMC channel. If more than one pair is provided, this DAI works
60+
in non-interleave mode. In that case the first audio channel uses the
61+
the first QMC channel, the second audio channel uses the second QMC
62+
channel, etc...
5463

5564
required:
5665
- reg
@@ -79,6 +88,11 @@ examples:
7988
reg = <17>;
8089
fsl,qmc-chan = <&qmc 17>;
8190
};
91+
dai@18 {
92+
reg = <18>;
93+
/* Non-interleaved mode */
94+
fsl,qmc-chan = <&qmc 18>, <&qmc 19>;
95+
};
8296
};
8397
8498
sound {
@@ -115,4 +129,19 @@ examples:
115129
dai-tdm-slot-rx-mask = <0 0 1 0 1 0 1 0 1>;
116130
};
117131
};
132+
simple-audio-card,dai-link@2 {
133+
reg = <2>;
134+
format = "dsp_b";
135+
cpu {
136+
sound-dai = <&audio_controller 18>;
137+
};
138+
codec {
139+
sound-dai = <&codec3>;
140+
dai-tdm-slot-num = <2>;
141+
dai-tdm-slot-width = <8>;
142+
/* TS 9, 10 */
143+
dai-tdm-slot-tx-mask = <0 0 0 0 0 0 0 0 0 1 1>;
144+
dai-tdm-slot-rx-mask = <0 0 0 0 0 0 0 0 0 1 1>;
145+
};
146+
};
118147
};

drivers/soc/fsl/qe/qmc.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,13 +1777,28 @@ static struct qmc_chan *qmc_chan_get_from_qmc(struct device_node *qmc_np, unsign
17771777
return qmc_chan;
17781778
}
17791779

1780-
struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name)
1780+
int qmc_chan_count_phandles(struct device_node *np, const char *phandles_name)
1781+
{
1782+
int count;
1783+
1784+
/* phandles are fixed args phandles with one arg */
1785+
count = of_count_phandle_with_args(np, phandles_name, NULL);
1786+
if (count < 0)
1787+
return count;
1788+
1789+
return count / 2;
1790+
}
1791+
EXPORT_SYMBOL(qmc_chan_count_phandles);
1792+
1793+
struct qmc_chan *qmc_chan_get_byphandles_index(struct device_node *np,
1794+
const char *phandles_name,
1795+
int index)
17811796
{
17821797
struct of_phandle_args out_args;
17831798
struct qmc_chan *qmc_chan;
17841799
int ret;
17851800

1786-
ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0,
1801+
ret = of_parse_phandle_with_fixed_args(np, phandles_name, 1, index,
17871802
&out_args);
17881803
if (ret < 0)
17891804
return ERR_PTR(ret);
@@ -1797,7 +1812,7 @@ struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phan
17971812
of_node_put(out_args.np);
17981813
return qmc_chan;
17991814
}
1800-
EXPORT_SYMBOL(qmc_chan_get_byphandle);
1815+
EXPORT_SYMBOL(qmc_chan_get_byphandles_index);
18011816

18021817
struct qmc_chan *qmc_chan_get_bychild(struct device_node *np)
18031818
{
@@ -1827,9 +1842,10 @@ static void devm_qmc_chan_release(struct device *dev, void *res)
18271842
qmc_chan_put(*qmc_chan);
18281843
}
18291844

1830-
struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
1831-
struct device_node *np,
1832-
const char *phandle_name)
1845+
struct qmc_chan *devm_qmc_chan_get_byphandles_index(struct device *dev,
1846+
struct device_node *np,
1847+
const char *phandles_name,
1848+
int index)
18331849
{
18341850
struct qmc_chan *qmc_chan;
18351851
struct qmc_chan **dr;
@@ -1838,7 +1854,7 @@ struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
18381854
if (!dr)
18391855
return ERR_PTR(-ENOMEM);
18401856

1841-
qmc_chan = qmc_chan_get_byphandle(np, phandle_name);
1857+
qmc_chan = qmc_chan_get_byphandles_index(np, phandles_name, index);
18421858
if (!IS_ERR(qmc_chan)) {
18431859
*dr = qmc_chan;
18441860
devres_add(dev, dr);
@@ -1848,7 +1864,7 @@ struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
18481864

18491865
return qmc_chan;
18501866
}
1851-
EXPORT_SYMBOL(devm_qmc_chan_get_byphandle);
1867+
EXPORT_SYMBOL(devm_qmc_chan_get_byphandles_index);
18521868

18531869
struct qmc_chan *devm_qmc_chan_get_bychild(struct device *dev,
18541870
struct device_node *np)

include/soc/fsl/qe/qmc.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,32 @@ struct device_node;
1616
struct device;
1717
struct qmc_chan;
1818

19-
struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name);
19+
int qmc_chan_count_phandles(struct device_node *np, const char *phandles_name);
20+
21+
struct qmc_chan *qmc_chan_get_byphandles_index(struct device_node *np,
22+
const char *phandles_name,
23+
int index);
24+
struct qmc_chan *devm_qmc_chan_get_byphandles_index(struct device *dev,
25+
struct device_node *np,
26+
const char *phandles_name,
27+
int index);
28+
29+
static inline struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np,
30+
const char *phandle_name)
31+
{
32+
return qmc_chan_get_byphandles_index(np, phandle_name, 0);
33+
}
34+
35+
static inline struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
36+
struct device_node *np,
37+
const char *phandle_name)
38+
{
39+
return devm_qmc_chan_get_byphandles_index(dev, np, phandle_name, 0);
40+
}
41+
2042
struct qmc_chan *qmc_chan_get_bychild(struct device_node *np);
2143
void qmc_chan_put(struct qmc_chan *chan);
22-
struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, struct device_node *np,
23-
const char *phandle_name);
44+
2445
struct qmc_chan *devm_qmc_chan_get_bychild(struct device *dev, struct device_node *np);
2546

2647
enum qmc_mode {

0 commit comments

Comments
 (0)