hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/soc/meson/axg-tdm-formatter.c
....@@ -7,6 +7,7 @@
77 #include <linux/module.h>
88 #include <linux/of_platform.h>
99 #include <linux/regmap.h>
10
+#include <linux/reset.h>
1011 #include <sound/soc.h>
1112
1213 #include "axg-tdm-formatter.h"
....@@ -20,6 +21,7 @@
2021 struct clk *lrclk;
2122 struct clk *sclk_sel;
2223 struct clk *lrclk_sel;
24
+ struct reset_control *reset;
2325 bool enabled;
2426 struct regmap *map;
2527 };
....@@ -28,27 +30,32 @@
2830 struct axg_tdm_stream *ts,
2931 unsigned int offset)
3032 {
31
- unsigned int val, ch = ts->channels;
32
- unsigned long mask;
33
- int i, j;
33
+ unsigned int ch = ts->channels;
34
+ u32 val[AXG_TDM_NUM_LANES];
35
+ int i, j, k;
36
+
37
+ /*
38
+ * We need to mimick the slot distribution used by the HW to keep the
39
+ * channel placement consistent regardless of the number of channel
40
+ * in the stream. This is why the odd algorithm below is used.
41
+ */
42
+ memset(val, 0, sizeof(*val) * AXG_TDM_NUM_LANES);
3443
3544 /*
3645 * Distribute the channels of the stream over the available slots
37
- * of each TDM lane
46
+ * of each TDM lane. We need to go over the 32 slots ...
3847 */
39
- for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
40
- val = 0;
41
- mask = ts->mask[i];
42
-
43
- for (j = find_first_bit(&mask, 32);
44
- (j < 32) && ch;
45
- j = find_next_bit(&mask, 32, j + 1)) {
46
- val |= 1 << j;
47
- ch -= 1;
48
+ for (i = 0; (i < 32) && ch; i += 2) {
49
+ /* ... of all the lanes ... */
50
+ for (j = 0; j < AXG_TDM_NUM_LANES; j++) {
51
+ /* ... then distribute the channels in pairs */
52
+ for (k = 0; k < 2; k++) {
53
+ if ((BIT(i + k) & ts->mask[j]) && ch) {
54
+ val[j] |= BIT(i + k);
55
+ ch -= 1;
56
+ }
57
+ }
4858 }
49
-
50
- regmap_write(map, offset, val);
51
- offset += regmap_get_reg_stride(map);
5259 }
5360
5461 /*
....@@ -61,6 +68,11 @@
6168 return -EINVAL;
6269 }
6370
71
+ for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
72
+ regmap_write(map, offset, val[i]);
73
+ offset += regmap_get_reg_stride(map);
74
+ }
75
+
6476 return 0;
6577 }
6678 EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
....@@ -68,7 +80,7 @@
6880 static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
6981 {
7082 struct axg_tdm_stream *ts = formatter->stream;
71
- bool invert = formatter->drv->invert_sclk;
83
+ bool invert;
7284 int ret;
7385
7486 /* Do nothing if the formatter is already enabled */
....@@ -76,16 +88,37 @@
7688 return 0;
7789
7890 /*
79
- * If sclk is inverted, invert it back and provide the inversion
80
- * required by the formatter
91
+ * On the g12a (and possibly other SoCs), when a stream using
92
+ * multiple lanes is restarted, it will sometimes not start
93
+ * from the first lane, but randomly from another used one.
94
+ * The result is an unexpected and random channel shift.
95
+ *
96
+ * The hypothesis is that an HW counter is not properly reset
97
+ * and the formatter simply starts on the lane it stopped
98
+ * before. Unfortunately, there does not seems to be a way to
99
+ * reset this through the registers of the block.
100
+ *
101
+ * However, the g12a has indenpendent reset lines for each audio
102
+ * devices. Using this reset before each start solves the issue.
81103 */
82
- invert ^= axg_tdm_sclk_invert(ts->iface->fmt);
83
- ret = clk_set_phase(formatter->sclk, invert ? 180 : 0);
104
+ ret = reset_control_reset(formatter->reset);
105
+ if (ret)
106
+ return ret;
107
+
108
+ /*
109
+ * If sclk is inverted, it means the bit should latched on the
110
+ * rising edge which is what our HW expects. If not, we need to
111
+ * invert it before the formatter.
112
+ */
113
+ invert = axg_tdm_sclk_invert(ts->iface->fmt);
114
+ ret = clk_set_phase(formatter->sclk, invert ? 0 : 180);
84115 if (ret)
85116 return ret;
86117
87118 /* Setup the stream parameter in the formatter */
88
- ret = formatter->drv->ops->prepare(formatter->map, formatter->stream);
119
+ ret = formatter->drv->ops->prepare(formatter->map,
120
+ formatter->drv->quirks,
121
+ formatter->stream);
89122 if (ret)
90123 return ret;
91124
....@@ -231,7 +264,6 @@
231264 struct device *dev = &pdev->dev;
232265 const struct axg_tdm_formatter_driver *drv;
233266 struct axg_tdm_formatter *formatter;
234
- struct resource *res;
235267 void __iomem *regs;
236268 int ret;
237269
....@@ -247,8 +279,7 @@
247279 platform_set_drvdata(pdev, formatter);
248280 formatter->drv = drv;
249281
250
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
251
- regs = devm_ioremap_resource(dev, res);
282
+ regs = devm_platform_ioremap_resource(pdev, 0);
252283 if (IS_ERR(regs))
253284 return PTR_ERR(regs);
254285
....@@ -301,6 +332,15 @@
301332 ret = PTR_ERR(formatter->lrclk_sel);
302333 if (ret != -EPROBE_DEFER)
303334 dev_err(dev, "failed to get lrclk_sel: %d\n", ret);
335
+ return ret;
336
+ }
337
+
338
+ /* Formatter dedicated reset line */
339
+ formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
340
+ if (IS_ERR(formatter->reset)) {
341
+ ret = PTR_ERR(formatter->reset);
342
+ if (ret != -EPROBE_DEFER)
343
+ dev_err(dev, "failed to get reset: %d\n", ret);
304344 return ret;
305345 }
306346
....@@ -368,7 +408,7 @@
368408 /*
369409 * If the list is not empty, it would mean that one of the formatter
370410 * widget is still powered and attached to the interface while we
371
- * we are removing the TDM DAI. It should not be possible
411
+ * are removing the TDM DAI. It should not be possible
372412 */
373413 WARN_ON(!list_empty(&ts->formatter_list));
374414 mutex_destroy(&ts->lock);