1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 // Copyright (c) 2018 BayLibre, SAS.
4 // Author: Jerome Brunet <jbrunet@baylibre.com>
7 #include <linux/module.h>
8 #include <linux/of_platform.h>
9 #include <linux/regmap.h>
10 #include <linux/reset.h>
11 #include <sound/soc.h>
13 #include "axg-tdm-formatter.h"
15 struct axg_tdm_formatter
{
16 struct list_head list
;
17 struct axg_tdm_stream
*stream
;
18 const struct axg_tdm_formatter_driver
*drv
;
23 struct clk
*lrclk_sel
;
24 struct reset_control
*reset
;
29 int axg_tdm_formatter_set_channel_masks(struct regmap
*map
,
30 struct axg_tdm_stream
*ts
,
33 unsigned int ch
= ts
->channels
;
34 u32 val
[AXG_TDM_NUM_LANES
];
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.
42 memset(val
, 0, sizeof(*val
) * AXG_TDM_NUM_LANES
);
45 * Distribute the channels of the stream over the available slots
46 * of each TDM lane. We need to go over the 32 slots ...
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
) {
62 * If we still have channel left at the end of the process, it means
63 * the stream has more channels than we can accommodate and we should
64 * have caught this earlier.
66 if (WARN_ON(ch
!= 0)) {
67 pr_err("channel mask error\n");
71 for (i
= 0; i
< AXG_TDM_NUM_LANES
; i
++) {
72 regmap_write(map
, offset
, val
[i
]);
73 offset
+= regmap_get_reg_stride(map
);
78 EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks
);
80 static int axg_tdm_formatter_enable(struct axg_tdm_formatter
*formatter
)
82 struct axg_tdm_stream
*ts
= formatter
->stream
;
86 /* Do nothing if the formatter is already enabled */
87 if (formatter
->enabled
)
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.
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.
101 * However, the g12a has indenpendent reset lines for each audio
102 * devices. Using this reset before each start solves the issue.
104 ret
= reset_control_reset(formatter
->reset
);
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.
113 invert
= axg_tdm_sclk_invert(ts
->iface
->fmt
);
114 ret
= clk_set_phase(formatter
->sclk
, invert
? 0 : 180);
118 /* Setup the stream parameter in the formatter */
119 ret
= formatter
->drv
->ops
->prepare(formatter
->map
,
120 formatter
->drv
->quirks
,
125 /* Enable the signal clocks feeding the formatter */
126 ret
= clk_prepare_enable(formatter
->sclk
);
130 ret
= clk_prepare_enable(formatter
->lrclk
);
132 clk_disable_unprepare(formatter
->sclk
);
136 /* Finally, actually enable the formatter */
137 formatter
->drv
->ops
->enable(formatter
->map
);
138 formatter
->enabled
= true;
143 static void axg_tdm_formatter_disable(struct axg_tdm_formatter
*formatter
)
145 /* Do nothing if the formatter is already disabled */
146 if (!formatter
->enabled
)
149 formatter
->drv
->ops
->disable(formatter
->map
);
150 clk_disable_unprepare(formatter
->lrclk
);
151 clk_disable_unprepare(formatter
->sclk
);
152 formatter
->enabled
= false;
155 static int axg_tdm_formatter_attach(struct axg_tdm_formatter
*formatter
)
157 struct axg_tdm_stream
*ts
= formatter
->stream
;
160 mutex_lock(&ts
->lock
);
162 /* Catch up if the stream is already running when we attach */
164 ret
= axg_tdm_formatter_enable(formatter
);
166 pr_err("failed to enable formatter\n");
171 list_add_tail(&formatter
->list
, &ts
->formatter_list
);
173 mutex_unlock(&ts
->lock
);
177 static void axg_tdm_formatter_dettach(struct axg_tdm_formatter
*formatter
)
179 struct axg_tdm_stream
*ts
= formatter
->stream
;
181 mutex_lock(&ts
->lock
);
182 list_del(&formatter
->list
);
183 mutex_unlock(&ts
->lock
);
185 axg_tdm_formatter_disable(formatter
);
188 static int axg_tdm_formatter_power_up(struct axg_tdm_formatter
*formatter
,
189 struct snd_soc_dapm_widget
*w
)
191 struct axg_tdm_stream
*ts
= formatter
->drv
->ops
->get_stream(w
);
195 * If we don't get a stream at this stage, it would mean that the
196 * widget is powering up but is not attached to any backend DAI.
197 * It should not happen, ever !
202 /* Clock our device */
203 ret
= clk_prepare_enable(formatter
->pclk
);
207 /* Reparent the bit clock to the TDM interface */
208 ret
= clk_set_parent(formatter
->sclk_sel
, ts
->iface
->sclk
);
212 /* Reparent the sample clock to the TDM interface */
213 ret
= clk_set_parent(formatter
->lrclk_sel
, ts
->iface
->lrclk
);
217 formatter
->stream
= ts
;
218 ret
= axg_tdm_formatter_attach(formatter
);
225 clk_disable_unprepare(formatter
->pclk
);
229 static void axg_tdm_formatter_power_down(struct axg_tdm_formatter
*formatter
)
231 axg_tdm_formatter_dettach(formatter
);
232 clk_disable_unprepare(formatter
->pclk
);
233 formatter
->stream
= NULL
;
236 int axg_tdm_formatter_event(struct snd_soc_dapm_widget
*w
,
237 struct snd_kcontrol
*control
,
240 struct snd_soc_component
*c
= snd_soc_dapm_to_component(w
->dapm
);
241 struct axg_tdm_formatter
*formatter
= snd_soc_component_get_drvdata(c
);
245 case SND_SOC_DAPM_PRE_PMU
:
246 ret
= axg_tdm_formatter_power_up(formatter
, w
);
249 case SND_SOC_DAPM_PRE_PMD
:
250 axg_tdm_formatter_power_down(formatter
);
254 dev_err(c
->dev
, "Unexpected event %d\n", event
);
260 EXPORT_SYMBOL_GPL(axg_tdm_formatter_event
);
262 int axg_tdm_formatter_probe(struct platform_device
*pdev
)
264 struct device
*dev
= &pdev
->dev
;
265 const struct axg_tdm_formatter_driver
*drv
;
266 struct axg_tdm_formatter
*formatter
;
269 drv
= of_device_get_match_data(dev
);
271 dev_err(dev
, "failed to match device\n");
275 formatter
= devm_kzalloc(dev
, sizeof(*formatter
), GFP_KERNEL
);
278 platform_set_drvdata(pdev
, formatter
);
279 formatter
->drv
= drv
;
281 regs
= devm_platform_ioremap_resource(pdev
, 0);
283 return PTR_ERR(regs
);
285 formatter
->map
= devm_regmap_init_mmio(dev
, regs
, drv
->regmap_cfg
);
286 if (IS_ERR(formatter
->map
)) {
287 dev_err(dev
, "failed to init regmap: %ld\n",
288 PTR_ERR(formatter
->map
));
289 return PTR_ERR(formatter
->map
);
292 /* Peripharal clock */
293 formatter
->pclk
= devm_clk_get(dev
, "pclk");
294 if (IS_ERR(formatter
->pclk
))
295 return dev_err_probe(dev
, PTR_ERR(formatter
->pclk
), "failed to get pclk\n");
297 /* Formatter bit clock */
298 formatter
->sclk
= devm_clk_get(dev
, "sclk");
299 if (IS_ERR(formatter
->sclk
))
300 return dev_err_probe(dev
, PTR_ERR(formatter
->sclk
), "failed to get sclk\n");
302 /* Formatter sample clock */
303 formatter
->lrclk
= devm_clk_get(dev
, "lrclk");
304 if (IS_ERR(formatter
->lrclk
))
305 return dev_err_probe(dev
, PTR_ERR(formatter
->lrclk
), "failed to get lrclk\n");
307 /* Formatter bit clock input multiplexer */
308 formatter
->sclk_sel
= devm_clk_get(dev
, "sclk_sel");
309 if (IS_ERR(formatter
->sclk_sel
))
310 return dev_err_probe(dev
, PTR_ERR(formatter
->sclk_sel
), "failed to get sclk_sel\n");
312 /* Formatter sample clock input multiplexer */
313 formatter
->lrclk_sel
= devm_clk_get(dev
, "lrclk_sel");
314 if (IS_ERR(formatter
->lrclk_sel
))
315 return dev_err_probe(dev
, PTR_ERR(formatter
->lrclk_sel
),
316 "failed to get lrclk_sel\n");
318 /* Formatter dedicated reset line */
319 formatter
->reset
= devm_reset_control_get_optional_exclusive(dev
, NULL
);
320 if (IS_ERR(formatter
->reset
))
321 return dev_err_probe(dev
, PTR_ERR(formatter
->reset
), "failed to get reset\n");
323 return devm_snd_soc_register_component(dev
, drv
->component_drv
,
326 EXPORT_SYMBOL_GPL(axg_tdm_formatter_probe
);
328 int axg_tdm_stream_start(struct axg_tdm_stream
*ts
)
330 struct axg_tdm_formatter
*formatter
;
333 mutex_lock(&ts
->lock
);
336 /* Start all the formatters attached to the stream */
337 list_for_each_entry(formatter
, &ts
->formatter_list
, list
) {
338 ret
= axg_tdm_formatter_enable(formatter
);
340 pr_err("failed to start tdm stream\n");
346 mutex_unlock(&ts
->lock
);
349 EXPORT_SYMBOL_GPL(axg_tdm_stream_start
);
351 void axg_tdm_stream_stop(struct axg_tdm_stream
*ts
)
353 struct axg_tdm_formatter
*formatter
;
355 mutex_lock(&ts
->lock
);
358 /* Stop all the formatters attached to the stream */
359 list_for_each_entry(formatter
, &ts
->formatter_list
, list
) {
360 axg_tdm_formatter_disable(formatter
);
363 mutex_unlock(&ts
->lock
);
365 EXPORT_SYMBOL_GPL(axg_tdm_stream_stop
);
367 struct axg_tdm_stream
*axg_tdm_stream_alloc(struct axg_tdm_iface
*iface
)
369 struct axg_tdm_stream
*ts
;
371 ts
= kzalloc(sizeof(*ts
), GFP_KERNEL
);
373 INIT_LIST_HEAD(&ts
->formatter_list
);
374 mutex_init(&ts
->lock
);
380 EXPORT_SYMBOL_GPL(axg_tdm_stream_alloc
);
382 void axg_tdm_stream_free(struct axg_tdm_stream
*ts
)
385 * If the list is not empty, it would mean that one of the formatter
386 * widget is still powered and attached to the interface while we
387 * are removing the TDM DAI. It should not be possible
389 WARN_ON(!list_empty(&ts
->formatter_list
));
390 mutex_destroy(&ts
->lock
);
393 EXPORT_SYMBOL_GPL(axg_tdm_stream_free
);
395 int axg_tdm_stream_set_cont_clocks(struct axg_tdm_stream
*ts
,
400 if (fmt
& SND_SOC_DAIFMT_CONT
) {
401 /* Clock are already enabled - skipping */
405 ret
= clk_prepare_enable(ts
->iface
->mclk
);
409 ret
= clk_prepare_enable(ts
->iface
->sclk
);
413 ret
= clk_prepare_enable(ts
->iface
->lrclk
);
417 ts
->clk_enabled
= true;
421 /* Clocks are already disabled - skipping */
422 if (!ts
->clk_enabled
)
425 clk_disable_unprepare(ts
->iface
->lrclk
);
427 clk_disable_unprepare(ts
->iface
->sclk
);
429 clk_disable_unprepare(ts
->iface
->mclk
);
430 ts
->clk_enabled
= false;
433 EXPORT_SYMBOL_GPL(axg_tdm_stream_set_cont_clocks
);
435 MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver");
436 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
437 MODULE_LICENSE("GPL v2");