| .. | .. |
|---|
| 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 | }; |
|---|