.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * STM32 ALSA SoC Digital Audio Interface (SAI) driver. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2016, STMicroelectronics - All Rights Reserved |
---|
5 | 6 | * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics. |
---|
6 | | - * |
---|
7 | | - * License terms: GPL V2.0. |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify it |
---|
10 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
11 | | - * the Free Software Foundation. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, but |
---|
14 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
15 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
---|
16 | | - * details. |
---|
17 | 7 | */ |
---|
18 | 8 | |
---|
19 | 9 | #include <linux/bitfield.h> |
---|
.. | .. |
---|
36 | 26 | /* Sub-block A registers, relative to sub-block A address */ |
---|
37 | 27 | #define STM_SAI_PDMCR_REGX 0x40 |
---|
38 | 28 | #define STM_SAI_PDMLY_REGX 0x44 |
---|
| 29 | + |
---|
| 30 | +/* Hardware configuration registers */ |
---|
| 31 | +#define STM_SAI_HWCFGR 0x3F0 |
---|
| 32 | +#define STM_SAI_VERR 0x3F4 |
---|
| 33 | +#define STM_SAI_IDR 0x3F8 |
---|
| 34 | +#define STM_SAI_SIDR 0x3FC |
---|
39 | 35 | |
---|
40 | 36 | /******************** Bit definition for SAI_GCR register *******************/ |
---|
41 | 37 | #define SAI_GCR_SYNCIN_SHIFT 0 |
---|
.. | .. |
---|
82 | 78 | #define SAI_XCR1_NODIV BIT(SAI_XCR1_NODIV_SHIFT) |
---|
83 | 79 | |
---|
84 | 80 | #define SAI_XCR1_MCKDIV_SHIFT 20 |
---|
85 | | -#define SAI_XCR1_MCKDIV_WIDTH(x) (((x) == SAI_STM32F4) ? 4 : 6) |
---|
| 81 | +#define SAI_XCR1_MCKDIV_WIDTH(x) (((x) == STM_SAI_STM32F4) ? 4 : 6) |
---|
86 | 82 | #define SAI_XCR1_MCKDIV_MASK(x) GENMASK((SAI_XCR1_MCKDIV_SHIFT + (x) - 1),\ |
---|
87 | 83 | SAI_XCR1_MCKDIV_SHIFT) |
---|
88 | 84 | #define SAI_XCR1_MCKDIV_SET(x) ((x) << SAI_XCR1_MCKDIV_SHIFT) |
---|
.. | .. |
---|
90 | 86 | |
---|
91 | 87 | #define SAI_XCR1_OSR_SHIFT 26 |
---|
92 | 88 | #define SAI_XCR1_OSR BIT(SAI_XCR1_OSR_SHIFT) |
---|
| 89 | + |
---|
| 90 | +#define SAI_XCR1_MCKEN_SHIFT 27 |
---|
| 91 | +#define SAI_XCR1_MCKEN BIT(SAI_XCR1_MCKEN_SHIFT) |
---|
93 | 92 | |
---|
94 | 93 | /******************* Bit definition for SAI_XCR2 register *******************/ |
---|
95 | 94 | #define SAI_XCR2_FTH_SHIFT 0 |
---|
.. | .. |
---|
231 | 230 | #define SAI_PDMDLY_4R_MASK GENMASK(30, SAI_PDMDLY_4R_SHIFT) |
---|
232 | 231 | #define SAI_PDMDLY_4R_WIDTH 3 |
---|
233 | 232 | |
---|
234 | | -#define STM_SAI_IS_F4(ip) ((ip)->conf->version == SAI_STM32F4) |
---|
235 | | -#define STM_SAI_IS_H7(ip) ((ip)->conf->version == SAI_STM32H7) |
---|
| 233 | +/* Registers below apply to SAI version 2.1 and more */ |
---|
| 234 | + |
---|
| 235 | +/* Bit definition for SAI_HWCFGR register */ |
---|
| 236 | +#define SAI_HWCFGR_FIFO_SIZE GENMASK(7, 0) |
---|
| 237 | +#define SAI_HWCFGR_SPDIF_PDM GENMASK(11, 8) |
---|
| 238 | +#define SAI_HWCFGR_REGOUT GENMASK(19, 12) |
---|
| 239 | + |
---|
| 240 | +/* Bit definition for SAI_VERR register */ |
---|
| 241 | +#define SAI_VERR_MIN_MASK GENMASK(3, 0) |
---|
| 242 | +#define SAI_VERR_MAJ_MASK GENMASK(7, 4) |
---|
| 243 | + |
---|
| 244 | +/* Bit definition for SAI_IDR register */ |
---|
| 245 | +#define SAI_IDR_ID_MASK GENMASK(31, 0) |
---|
| 246 | + |
---|
| 247 | +/* Bit definition for SAI_SIDR register */ |
---|
| 248 | +#define SAI_SIDR_ID_MASK GENMASK(31, 0) |
---|
| 249 | + |
---|
| 250 | +#define SAI_IPIDR_NUMBER 0x00130031 |
---|
| 251 | + |
---|
| 252 | +/* SAI version numbers are 1.x for F4. Major version number set to 1 for F4 */ |
---|
| 253 | +#define STM_SAI_STM32F4 BIT(4) |
---|
| 254 | +/* Dummy version number for H7 socs and next */ |
---|
| 255 | +#define STM_SAI_STM32H7 0x0 |
---|
| 256 | + |
---|
| 257 | +#define STM_SAI_IS_F4(ip) ((ip)->conf.version == STM_SAI_STM32F4) |
---|
| 258 | +#define STM_SAI_HAS_SPDIF_PDM(ip)\ |
---|
| 259 | + ((ip)->pdata->conf.has_spdif_pdm) |
---|
236 | 260 | |
---|
237 | 261 | enum stm32_sai_syncout { |
---|
238 | 262 | STM_SAI_SYNC_OUT_NONE, |
---|
.. | .. |
---|
240 | 264 | STM_SAI_SYNC_OUT_B, |
---|
241 | 265 | }; |
---|
242 | 266 | |
---|
243 | | -enum stm32_sai_version { |
---|
244 | | - SAI_STM32F4, |
---|
245 | | - SAI_STM32H7 |
---|
246 | | -}; |
---|
247 | | - |
---|
248 | 267 | /** |
---|
249 | 268 | * struct stm32_sai_conf - SAI configuration |
---|
250 | 269 | * @version: SAI version |
---|
251 | | - * @has_spdif: SAI S/PDIF support flag |
---|
| 270 | + * @fifo_size: SAI fifo size as words number |
---|
| 271 | + * @has_spdif_pdm: SAI S/PDIF and PDM features support flag |
---|
252 | 272 | */ |
---|
253 | 273 | struct stm32_sai_conf { |
---|
254 | | - int version; |
---|
255 | | - bool has_spdif; |
---|
| 274 | + u32 version; |
---|
| 275 | + u32 fifo_size; |
---|
| 276 | + bool has_spdif_pdm; |
---|
256 | 277 | }; |
---|
257 | 278 | |
---|
258 | 279 | /** |
---|
.. | .. |
---|
262 | 283 | * @pclk: SAI bus clock |
---|
263 | 284 | * @clk_x8k: SAI parent clock for sampling frequencies multiple of 8kHz |
---|
264 | 285 | * @clk_x11k: SAI parent clock for sampling frequencies multiple of 11kHz |
---|
265 | | - * @version: SOC version |
---|
| 286 | + * @conf: SAI hardware capabitilites |
---|
266 | 287 | * @irq: SAI interrupt line |
---|
267 | 288 | * @set_sync: pointer to synchro mode configuration callback |
---|
| 289 | + * @gcr: SAI Global Configuration Register |
---|
268 | 290 | */ |
---|
269 | 291 | struct stm32_sai_data { |
---|
270 | 292 | struct platform_device *pdev; |
---|
.. | .. |
---|
272 | 294 | struct clk *pclk; |
---|
273 | 295 | struct clk *clk_x8k; |
---|
274 | 296 | struct clk *clk_x11k; |
---|
275 | | - struct stm32_sai_conf *conf; |
---|
| 297 | + struct stm32_sai_conf conf; |
---|
276 | 298 | int irq; |
---|
277 | 299 | int (*set_sync)(struct stm32_sai_data *sai, |
---|
278 | 300 | struct device_node *np_provider, int synco, int synci); |
---|
| 301 | + u32 gcr; |
---|
279 | 302 | }; |
---|