forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
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 };
....@@ -68,7 +70,7 @@
6870 static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
6971 {
7072 struct axg_tdm_stream *ts = formatter->stream;
71
- bool invert = formatter->drv->invert_sclk;
73
+ bool invert;
7274 int ret;
7375
7476 /* Do nothing if the formatter is already enabled */
....@@ -76,16 +78,37 @@
7678 return 0;
7779
7880 /*
79
- * If sclk is inverted, invert it back and provide the inversion
80
- * required by the formatter
81
+ * On the g12a (and possibly other SoCs), when a stream using
82
+ * multiple lanes is restarted, it will sometimes not start
83
+ * from the first lane, but randomly from another used one.
84
+ * The result is an unexpected and random channel shift.
85
+ *
86
+ * The hypothesis is that an HW counter is not properly reset
87
+ * and the formatter simply starts on the lane it stopped
88
+ * before. Unfortunately, there does not seems to be a way to
89
+ * reset this through the registers of the block.
90
+ *
91
+ * However, the g12a has indenpendent reset lines for each audio
92
+ * devices. Using this reset before each start solves the issue.
8193 */
82
- invert ^= axg_tdm_sclk_invert(ts->iface->fmt);
83
- ret = clk_set_phase(formatter->sclk, invert ? 180 : 0);
94
+ ret = reset_control_reset(formatter->reset);
95
+ if (ret)
96
+ return ret;
97
+
98
+ /*
99
+ * If sclk is inverted, it means the bit should latched on the
100
+ * rising edge which is what our HW expects. If not, we need to
101
+ * invert it before the formatter.
102
+ */
103
+ invert = axg_tdm_sclk_invert(ts->iface->fmt);
104
+ ret = clk_set_phase(formatter->sclk, invert ? 0 : 180);
84105 if (ret)
85106 return ret;
86107
87108 /* Setup the stream parameter in the formatter */
88
- ret = formatter->drv->ops->prepare(formatter->map, formatter->stream);
109
+ ret = formatter->drv->ops->prepare(formatter->map,
110
+ formatter->drv->quirks,
111
+ formatter->stream);
89112 if (ret)
90113 return ret;
91114
....@@ -231,7 +254,6 @@
231254 struct device *dev = &pdev->dev;
232255 const struct axg_tdm_formatter_driver *drv;
233256 struct axg_tdm_formatter *formatter;
234
- struct resource *res;
235257 void __iomem *regs;
236258 int ret;
237259
....@@ -247,8 +269,7 @@
247269 platform_set_drvdata(pdev, formatter);
248270 formatter->drv = drv;
249271
250
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
251
- regs = devm_ioremap_resource(dev, res);
272
+ regs = devm_platform_ioremap_resource(pdev, 0);
252273 if (IS_ERR(regs))
253274 return PTR_ERR(regs);
254275
....@@ -301,6 +322,15 @@
301322 ret = PTR_ERR(formatter->lrclk_sel);
302323 if (ret != -EPROBE_DEFER)
303324 dev_err(dev, "failed to get lrclk_sel: %d\n", ret);
325
+ return ret;
326
+ }
327
+
328
+ /* Formatter dedicated reset line */
329
+ formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
330
+ if (IS_ERR(formatter->reset)) {
331
+ ret = PTR_ERR(formatter->reset);
332
+ if (ret != -EPROBE_DEFER)
333
+ dev_err(dev, "failed to get reset: %d\n", ret);
304334 return ret;
305335 }
306336
....@@ -368,7 +398,7 @@
368398 /*
369399 * If the list is not empty, it would mean that one of the formatter
370400 * widget is still powered and attached to the interface while we
371
- * we are removing the TDM DAI. It should not be possible
401
+ * are removing the TDM DAI. It should not be possible
372402 */
373403 WARN_ON(!list_empty(&ts->formatter_list));
374404 mutex_destroy(&ts->lock);