1 // SPDX-License-Identifier: GPL-2.0-only
3 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
5 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
6 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
9 #include <linux/bitfield.h>
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/module.h>
13 #include <linux/of_platform.h>
14 #include <linux/pinctrl/consumer.h>
15 #include <linux/reset.h>
17 #include <sound/dmaengine_pcm.h>
18 #include <sound/core.h>
20 #include "stm32_sai.h"
22 static int stm32_sai_get_parent_clk(struct stm32_sai_data
*sai
);
24 static const struct stm32_sai_conf stm32_sai_conf_f4
= {
25 .version
= STM_SAI_STM32F4
,
27 .has_spdif_pdm
= false,
28 .get_sai_ck_parent
= stm32_sai_get_parent_clk
,
32 * Default settings for STM32H7x socs and STM32MP1x.
33 * These default settings will be overridden if the soc provides
34 * support of hardware configuration registers.
35 * - STM32H7: rely on default settings
36 * - STM32MP1: retrieve settings from registers
38 static const struct stm32_sai_conf stm32_sai_conf_h7
= {
39 .version
= STM_SAI_STM32H7
,
41 .has_spdif_pdm
= true,
42 .get_sai_ck_parent
= stm32_sai_get_parent_clk
,
47 * - do not use SAI parent clock source selection
48 * - do not use DMA burst mode
50 static const struct stm32_sai_conf stm32_sai_conf_mp25
= {
54 static const struct of_device_id stm32_sai_ids
[] = {
55 { .compatible
= "st,stm32f4-sai", .data
= (void *)&stm32_sai_conf_f4
},
56 { .compatible
= "st,stm32h7-sai", .data
= (void *)&stm32_sai_conf_h7
},
57 { .compatible
= "st,stm32mp25-sai", .data
= (void *)&stm32_sai_conf_mp25
},
61 static int stm32_sai_pclk_disable(struct device
*dev
)
63 struct stm32_sai_data
*sai
= dev_get_drvdata(dev
);
65 clk_disable_unprepare(sai
->pclk
);
70 static int stm32_sai_pclk_enable(struct device
*dev
)
72 struct stm32_sai_data
*sai
= dev_get_drvdata(dev
);
75 ret
= clk_prepare_enable(sai
->pclk
);
77 dev_err(&sai
->pdev
->dev
, "failed to enable clock: %d\n", ret
);
84 static int stm32_sai_sync_conf_client(struct stm32_sai_data
*sai
, int synci
)
88 /* Enable peripheral clock to allow GCR register access */
89 ret
= stm32_sai_pclk_enable(&sai
->pdev
->dev
);
93 writel_relaxed(FIELD_PREP(SAI_GCR_SYNCIN_MASK
, (synci
- 1)), sai
->base
);
95 stm32_sai_pclk_disable(&sai
->pdev
->dev
);
100 static int stm32_sai_sync_conf_provider(struct stm32_sai_data
*sai
, int synco
)
105 /* Enable peripheral clock to allow GCR register access */
106 ret
= stm32_sai_pclk_enable(&sai
->pdev
->dev
);
110 dev_dbg(&sai
->pdev
->dev
, "Set %pOFn%s as synchro provider\n",
111 sai
->pdev
->dev
.of_node
,
112 synco
== STM_SAI_SYNC_OUT_A
? "A" : "B");
114 prev_synco
= FIELD_GET(SAI_GCR_SYNCOUT_MASK
, readl_relaxed(sai
->base
));
115 if (prev_synco
!= STM_SAI_SYNC_OUT_NONE
&& synco
!= prev_synco
) {
116 dev_err(&sai
->pdev
->dev
, "%pOFn%s already set as sync provider\n",
117 sai
->pdev
->dev
.of_node
,
118 prev_synco
== STM_SAI_SYNC_OUT_A
? "A" : "B");
119 stm32_sai_pclk_disable(&sai
->pdev
->dev
);
123 writel_relaxed(FIELD_PREP(SAI_GCR_SYNCOUT_MASK
, synco
), sai
->base
);
125 stm32_sai_pclk_disable(&sai
->pdev
->dev
);
130 static int stm32_sai_set_sync(struct stm32_sai_data
*sai_client
,
131 struct device_node
*np_provider
,
132 int synco
, int synci
)
134 struct platform_device
*pdev
= of_find_device_by_node(np_provider
);
135 struct stm32_sai_data
*sai_provider
;
139 dev_err(&sai_client
->pdev
->dev
,
140 "Device not found for node %pOFn\n", np_provider
);
141 of_node_put(np_provider
);
145 sai_provider
= platform_get_drvdata(pdev
);
147 dev_err(&sai_client
->pdev
->dev
,
148 "SAI sync provider data not found\n");
153 /* Configure sync client */
154 ret
= stm32_sai_sync_conf_client(sai_client
, synci
);
158 /* Configure sync provider */
159 ret
= stm32_sai_sync_conf_provider(sai_provider
, synco
);
162 put_device(&pdev
->dev
);
163 of_node_put(np_provider
);
167 static int stm32_sai_get_parent_clk(struct stm32_sai_data
*sai
)
169 struct device
*dev
= &sai
->pdev
->dev
;
171 sai
->clk_x8k
= devm_clk_get(dev
, "x8k");
172 if (IS_ERR(sai
->clk_x8k
)) {
173 if (PTR_ERR(sai
->clk_x8k
) != -EPROBE_DEFER
)
174 dev_err(dev
, "missing x8k parent clock: %ld\n",
175 PTR_ERR(sai
->clk_x8k
));
176 return PTR_ERR(sai
->clk_x8k
);
179 sai
->clk_x11k
= devm_clk_get(dev
, "x11k");
180 if (IS_ERR(sai
->clk_x11k
)) {
181 if (PTR_ERR(sai
->clk_x11k
) != -EPROBE_DEFER
)
182 dev_err(dev
, "missing x11k parent clock: %ld\n",
183 PTR_ERR(sai
->clk_x11k
));
184 return PTR_ERR(sai
->clk_x11k
);
190 static int stm32_sai_probe(struct platform_device
*pdev
)
192 struct stm32_sai_data
*sai
;
193 const struct stm32_sai_conf
*conf
;
194 struct reset_control
*rst
;
198 sai
= devm_kzalloc(&pdev
->dev
, sizeof(*sai
), GFP_KERNEL
);
204 sai
->base
= devm_platform_ioremap_resource(pdev
, 0);
205 if (IS_ERR(sai
->base
))
206 return PTR_ERR(sai
->base
);
208 conf
= device_get_match_data(&pdev
->dev
);
210 memcpy(&sai
->conf
, (const struct stm32_sai_conf
*)conf
,
211 sizeof(struct stm32_sai_conf
));
215 if (!STM_SAI_IS_F4(sai
)) {
216 sai
->pclk
= devm_clk_get(&pdev
->dev
, "pclk");
217 if (IS_ERR(sai
->pclk
))
218 return dev_err_probe(&pdev
->dev
, PTR_ERR(sai
->pclk
),
219 "missing bus clock pclk\n");
222 if (sai
->conf
.get_sai_ck_parent
) {
223 ret
= sai
->conf
.get_sai_ck_parent(sai
);
229 sai
->irq
= platform_get_irq(pdev
, 0);
234 rst
= devm_reset_control_get_optional_exclusive(&pdev
->dev
, NULL
);
236 return dev_err_probe(&pdev
->dev
, PTR_ERR(rst
),
237 "Reset controller error\n");
239 reset_control_assert(rst
);
241 reset_control_deassert(rst
);
243 /* Enable peripheral clock to allow register access */
244 ret
= clk_prepare_enable(sai
->pclk
);
246 dev_err(&pdev
->dev
, "failed to enable clock: %d\n", ret
);
250 val
= FIELD_GET(SAI_IDR_ID_MASK
,
251 readl_relaxed(sai
->base
+ STM_SAI_IDR
));
252 if (val
== SAI_IPIDR_NUMBER
) {
253 val
= readl_relaxed(sai
->base
+ STM_SAI_HWCFGR
);
254 sai
->conf
.fifo_size
= FIELD_GET(SAI_HWCFGR_FIFO_SIZE
, val
);
255 sai
->conf
.has_spdif_pdm
= !!FIELD_GET(SAI_HWCFGR_SPDIF_PDM
,
258 val
= readl_relaxed(sai
->base
+ STM_SAI_VERR
);
259 sai
->conf
.version
= val
;
261 dev_dbg(&pdev
->dev
, "SAI version: %lu.%lu registered\n",
262 FIELD_GET(SAI_VERR_MAJ_MASK
, val
),
263 FIELD_GET(SAI_VERR_MIN_MASK
, val
));
265 clk_disable_unprepare(sai
->pclk
);
267 sai
->set_sync
= &stm32_sai_set_sync
;
268 platform_set_drvdata(pdev
, sai
);
270 return devm_of_platform_populate(&pdev
->dev
);
273 #ifdef CONFIG_PM_SLEEP
275 * When pins are shared by two sai sub instances, pins have to be defined
276 * in sai parent node. In this case, pins state is not managed by alsa fw.
277 * These pins are managed in suspend/resume callbacks.
279 static int stm32_sai_suspend(struct device
*dev
)
281 struct stm32_sai_data
*sai
= dev_get_drvdata(dev
);
284 ret
= stm32_sai_pclk_enable(dev
);
288 sai
->gcr
= readl_relaxed(sai
->base
);
289 stm32_sai_pclk_disable(dev
);
291 return pinctrl_pm_select_sleep_state(dev
);
294 static int stm32_sai_resume(struct device
*dev
)
296 struct stm32_sai_data
*sai
= dev_get_drvdata(dev
);
299 ret
= stm32_sai_pclk_enable(dev
);
303 writel_relaxed(sai
->gcr
, sai
->base
);
304 stm32_sai_pclk_disable(dev
);
306 return pinctrl_pm_select_default_state(dev
);
308 #endif /* CONFIG_PM_SLEEP */
310 static const struct dev_pm_ops stm32_sai_pm_ops
= {
311 SET_SYSTEM_SLEEP_PM_OPS(stm32_sai_suspend
, stm32_sai_resume
)
314 MODULE_DEVICE_TABLE(of
, stm32_sai_ids
);
316 static struct platform_driver stm32_sai_driver
= {
318 .name
= "st,stm32-sai",
319 .of_match_table
= stm32_sai_ids
,
320 .pm
= &stm32_sai_pm_ops
,
322 .probe
= stm32_sai_probe
,
325 module_platform_driver(stm32_sai_driver
);
327 MODULE_DESCRIPTION("STM32 Soc SAI Interface");
328 MODULE_AUTHOR("Olivier Moysan <olivier.moysan@st.com>");
329 MODULE_ALIAS("platform:st,stm32-sai");
330 MODULE_LICENSE("GPL v2");