Lines Matching +full:stm32h7 +full:- +full:sai

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
22 static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai);
35 * - STM32H7: rely on default settings
36 * - STM32MP1: retrieve settings from registers
47 * - do not use SAI parent clock source selection
48 * - do not use DMA burst mode
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 },
63 struct stm32_sai_data *sai = dev_get_drvdata(dev); in stm32_sai_pclk_disable() local
65 clk_disable_unprepare(sai->pclk); in stm32_sai_pclk_disable()
72 struct stm32_sai_data *sai = dev_get_drvdata(dev); in stm32_sai_pclk_enable() local
75 ret = clk_prepare_enable(sai->pclk); in stm32_sai_pclk_enable()
77 dev_err(&sai->pdev->dev, "failed to enable clock: %d\n", ret); in stm32_sai_pclk_enable()
84 static int stm32_sai_sync_conf_client(struct stm32_sai_data *sai, int synci) in stm32_sai_sync_conf_client() argument
89 ret = stm32_sai_pclk_enable(&sai->pdev->dev); in stm32_sai_sync_conf_client()
93 writel_relaxed(FIELD_PREP(SAI_GCR_SYNCIN_MASK, (synci - 1)), sai->base); in stm32_sai_sync_conf_client()
95 stm32_sai_pclk_disable(&sai->pdev->dev); in stm32_sai_sync_conf_client()
100 static int stm32_sai_sync_conf_provider(struct stm32_sai_data *sai, int synco) in stm32_sai_sync_conf_provider() argument
106 ret = stm32_sai_pclk_enable(&sai->pdev->dev); in stm32_sai_sync_conf_provider()
110 dev_dbg(&sai->pdev->dev, "Set %pOFn%s as synchro provider\n", in stm32_sai_sync_conf_provider()
111 sai->pdev->dev.of_node, in stm32_sai_sync_conf_provider()
114 prev_synco = FIELD_GET(SAI_GCR_SYNCOUT_MASK, readl_relaxed(sai->base)); in stm32_sai_sync_conf_provider()
116 dev_err(&sai->pdev->dev, "%pOFn%s already set as sync provider\n", in stm32_sai_sync_conf_provider()
117 sai->pdev->dev.of_node, in stm32_sai_sync_conf_provider()
119 stm32_sai_pclk_disable(&sai->pdev->dev); in stm32_sai_sync_conf_provider()
120 return -EINVAL; in stm32_sai_sync_conf_provider()
123 writel_relaxed(FIELD_PREP(SAI_GCR_SYNCOUT_MASK, synco), sai->base); in stm32_sai_sync_conf_provider()
125 stm32_sai_pclk_disable(&sai->pdev->dev); in stm32_sai_sync_conf_provider()
139 dev_err(&sai_client->pdev->dev, in stm32_sai_set_sync()
142 return -ENODEV; in stm32_sai_set_sync()
147 dev_err(&sai_client->pdev->dev, in stm32_sai_set_sync()
148 "SAI sync provider data not found\n"); in stm32_sai_set_sync()
149 ret = -EINVAL; in stm32_sai_set_sync()
162 put_device(&pdev->dev); in stm32_sai_set_sync()
167 static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai) in stm32_sai_get_parent_clk() argument
169 struct device *dev = &sai->pdev->dev; in stm32_sai_get_parent_clk()
171 sai->clk_x8k = devm_clk_get(dev, "x8k"); in stm32_sai_get_parent_clk()
172 if (IS_ERR(sai->clk_x8k)) { in stm32_sai_get_parent_clk()
173 if (PTR_ERR(sai->clk_x8k) != -EPROBE_DEFER) in stm32_sai_get_parent_clk()
175 PTR_ERR(sai->clk_x8k)); in stm32_sai_get_parent_clk()
176 return PTR_ERR(sai->clk_x8k); in stm32_sai_get_parent_clk()
179 sai->clk_x11k = devm_clk_get(dev, "x11k"); in stm32_sai_get_parent_clk()
180 if (IS_ERR(sai->clk_x11k)) { in stm32_sai_get_parent_clk()
181 if (PTR_ERR(sai->clk_x11k) != -EPROBE_DEFER) in stm32_sai_get_parent_clk()
183 PTR_ERR(sai->clk_x11k)); in stm32_sai_get_parent_clk()
184 return PTR_ERR(sai->clk_x11k); in stm32_sai_get_parent_clk()
192 struct stm32_sai_data *sai; in stm32_sai_probe() local
198 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); in stm32_sai_probe()
199 if (!sai) in stm32_sai_probe()
200 return -ENOMEM; in stm32_sai_probe()
202 sai->pdev = pdev; in stm32_sai_probe()
204 sai->base = devm_platform_ioremap_resource(pdev, 0); in stm32_sai_probe()
205 if (IS_ERR(sai->base)) in stm32_sai_probe()
206 return PTR_ERR(sai->base); in stm32_sai_probe()
208 conf = device_get_match_data(&pdev->dev); in stm32_sai_probe()
210 memcpy(&sai->conf, (const struct stm32_sai_conf *)conf, in stm32_sai_probe()
213 return -EINVAL; in stm32_sai_probe()
215 if (!STM_SAI_IS_F4(sai)) { in stm32_sai_probe()
216 sai->pclk = devm_clk_get(&pdev->dev, "pclk"); in stm32_sai_probe()
217 if (IS_ERR(sai->pclk)) in stm32_sai_probe()
218 return dev_err_probe(&pdev->dev, PTR_ERR(sai->pclk), in stm32_sai_probe()
222 if (sai->conf.get_sai_ck_parent) { in stm32_sai_probe()
223 ret = sai->conf.get_sai_ck_parent(sai); in stm32_sai_probe()
229 sai->irq = platform_get_irq(pdev, 0); in stm32_sai_probe()
230 if (sai->irq < 0) in stm32_sai_probe()
231 return sai->irq; in stm32_sai_probe()
234 rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); in stm32_sai_probe()
236 return dev_err_probe(&pdev->dev, PTR_ERR(rst), in stm32_sai_probe()
244 ret = clk_prepare_enable(sai->pclk); in stm32_sai_probe()
246 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); in stm32_sai_probe()
251 readl_relaxed(sai->base + STM_SAI_IDR)); in stm32_sai_probe()
253 val = readl_relaxed(sai->base + STM_SAI_HWCFGR); in stm32_sai_probe()
254 sai->conf.fifo_size = FIELD_GET(SAI_HWCFGR_FIFO_SIZE, val); in stm32_sai_probe()
255 sai->conf.has_spdif_pdm = !!FIELD_GET(SAI_HWCFGR_SPDIF_PDM, in stm32_sai_probe()
258 val = readl_relaxed(sai->base + STM_SAI_VERR); in stm32_sai_probe()
259 sai->conf.version = val; in stm32_sai_probe()
261 dev_dbg(&pdev->dev, "SAI version: %lu.%lu registered\n", in stm32_sai_probe()
265 clk_disable_unprepare(sai->pclk); in stm32_sai_probe()
267 sai->set_sync = &stm32_sai_set_sync; in stm32_sai_probe()
268 platform_set_drvdata(pdev, sai); in stm32_sai_probe()
270 return devm_of_platform_populate(&pdev->dev); in stm32_sai_probe()
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.
281 struct stm32_sai_data *sai = dev_get_drvdata(dev); in stm32_sai_suspend() local
288 sai->gcr = readl_relaxed(sai->base); in stm32_sai_suspend()
296 struct stm32_sai_data *sai = dev_get_drvdata(dev); in stm32_sai_resume() local
303 writel_relaxed(sai->gcr, sai->base); in stm32_sai_resume()
318 .name = "st,stm32-sai",
327 MODULE_DESCRIPTION("STM32 Soc SAI Interface");
329 MODULE_ALIAS("platform:st,stm32-sai");