303 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.4 *5 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved6 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.7 */8 9#include <linux/bitfield.h>10 11/******************** SAI Register Map **************************************/12 13/* Global configuration register */14#define STM_SAI_GCR 0x0015 16/* Sub-block A&B registers offsets, relative to A&B sub-block addresses */17#define STM_SAI_CR1_REGX 0x00 /* A offset: 0x04. B offset: 0x24 */18#define STM_SAI_CR2_REGX 0x0419#define STM_SAI_FRCR_REGX 0x0820#define STM_SAI_SLOTR_REGX 0x0C21#define STM_SAI_IMR_REGX 0x1022#define STM_SAI_SR_REGX 0x1423#define STM_SAI_CLRFR_REGX 0x1824#define STM_SAI_DR_REGX 0x1C25 26/* Sub-block A registers, relative to sub-block A address */27#define STM_SAI_PDMCR_REGX 0x4028#define STM_SAI_PDMLY_REGX 0x4429 30/* Hardware configuration registers */31#define STM_SAI_HWCFGR 0x3F032#define STM_SAI_VERR 0x3F433#define STM_SAI_IDR 0x3F834#define STM_SAI_SIDR 0x3FC35 36/******************** Bit definition for SAI_GCR register *******************/37#define SAI_GCR_SYNCIN_SHIFT 038#define SAI_GCR_SYNCIN_WDTH 239#define SAI_GCR_SYNCIN_MASK GENMASK(1, SAI_GCR_SYNCIN_SHIFT)40#define SAI_GCR_SYNCIN_MAX FIELD_GET(SAI_GCR_SYNCIN_MASK,\41 SAI_GCR_SYNCIN_MASK)42 43#define SAI_GCR_SYNCOUT_SHIFT 444#define SAI_GCR_SYNCOUT_MASK GENMASK(5, SAI_GCR_SYNCOUT_SHIFT)45 46/******************* Bit definition for SAI_XCR1 register *******************/47#define SAI_XCR1_RX_TX_SHIFT 048#define SAI_XCR1_RX_TX BIT(SAI_XCR1_RX_TX_SHIFT)49#define SAI_XCR1_SLAVE_SHIFT 150#define SAI_XCR1_SLAVE BIT(SAI_XCR1_SLAVE_SHIFT)51 52#define SAI_XCR1_PRTCFG_SHIFT 253#define SAI_XCR1_PRTCFG_MASK GENMASK(3, SAI_XCR1_PRTCFG_SHIFT)54#define SAI_XCR1_PRTCFG_SET(x) ((x) << SAI_XCR1_PRTCFG_SHIFT)55 56#define SAI_XCR1_DS_SHIFT 557#define SAI_XCR1_DS_MASK GENMASK(7, SAI_XCR1_DS_SHIFT)58#define SAI_XCR1_DS_SET(x) ((x) << SAI_XCR1_DS_SHIFT)59 60#define SAI_XCR1_LSBFIRST_SHIFT 861#define SAI_XCR1_LSBFIRST BIT(SAI_XCR1_LSBFIRST_SHIFT)62#define SAI_XCR1_CKSTR_SHIFT 963#define SAI_XCR1_CKSTR BIT(SAI_XCR1_CKSTR_SHIFT)64 65#define SAI_XCR1_SYNCEN_SHIFT 1066#define SAI_XCR1_SYNCEN_MASK GENMASK(11, SAI_XCR1_SYNCEN_SHIFT)67#define SAI_XCR1_SYNCEN_SET(x) ((x) << SAI_XCR1_SYNCEN_SHIFT)68 69#define SAI_XCR1_MONO_SHIFT 1270#define SAI_XCR1_MONO BIT(SAI_XCR1_MONO_SHIFT)71#define SAI_XCR1_OUTDRIV_SHIFT 1372#define SAI_XCR1_OUTDRIV BIT(SAI_XCR1_OUTDRIV_SHIFT)73#define SAI_XCR1_SAIEN_SHIFT 1674#define SAI_XCR1_SAIEN BIT(SAI_XCR1_SAIEN_SHIFT)75#define SAI_XCR1_DMAEN_SHIFT 1776#define SAI_XCR1_DMAEN BIT(SAI_XCR1_DMAEN_SHIFT)77#define SAI_XCR1_NODIV_SHIFT 1978#define SAI_XCR1_NODIV BIT(SAI_XCR1_NODIV_SHIFT)79 80#define SAI_XCR1_MCKDIV_SHIFT 2081#define SAI_XCR1_MCKDIV_WIDTH(x) (((x) == STM_SAI_STM32F4) ? 4 : 6)82#define SAI_XCR1_MCKDIV_MASK(x) GENMASK((SAI_XCR1_MCKDIV_SHIFT + (x) - 1),\83 SAI_XCR1_MCKDIV_SHIFT)84#define SAI_XCR1_MCKDIV_SET(x) ((x) << SAI_XCR1_MCKDIV_SHIFT)85#define SAI_XCR1_MCKDIV_MAX(x) ((1 << SAI_XCR1_MCKDIV_WIDTH(x)) - 1)86 87#define SAI_XCR1_OSR_SHIFT 2688#define SAI_XCR1_OSR BIT(SAI_XCR1_OSR_SHIFT)89 90#define SAI_XCR1_MCKEN_SHIFT 2791#define SAI_XCR1_MCKEN BIT(SAI_XCR1_MCKEN_SHIFT)92 93/******************* Bit definition for SAI_XCR2 register *******************/94#define SAI_XCR2_FTH_SHIFT 095#define SAI_XCR2_FTH_MASK GENMASK(2, SAI_XCR2_FTH_SHIFT)96#define SAI_XCR2_FTH_SET(x) ((x) << SAI_XCR2_FTH_SHIFT)97 98#define SAI_XCR2_FFLUSH_SHIFT 399#define SAI_XCR2_FFLUSH BIT(SAI_XCR2_FFLUSH_SHIFT)100#define SAI_XCR2_TRIS_SHIFT 4101#define SAI_XCR2_TRIS BIT(SAI_XCR2_TRIS_SHIFT)102#define SAI_XCR2_MUTE_SHIFT 5103#define SAI_XCR2_MUTE BIT(SAI_XCR2_MUTE_SHIFT)104#define SAI_XCR2_MUTEVAL_SHIFT 6105#define SAI_XCR2_MUTEVAL BIT(SAI_XCR2_MUTEVAL_SHIFT)106 107#define SAI_XCR2_MUTECNT_SHIFT 7108#define SAI_XCR2_MUTECNT_MASK GENMASK(12, SAI_XCR2_MUTECNT_SHIFT)109#define SAI_XCR2_MUTECNT_SET(x) ((x) << SAI_XCR2_MUTECNT_SHIFT)110 111#define SAI_XCR2_CPL_SHIFT 13112#define SAI_XCR2_CPL BIT(SAI_XCR2_CPL_SHIFT)113 114#define SAI_XCR2_COMP_SHIFT 14115#define SAI_XCR2_COMP_MASK GENMASK(15, SAI_XCR2_COMP_SHIFT)116#define SAI_XCR2_COMP_SET(x) ((x) << SAI_XCR2_COMP_SHIFT)117 118/****************** Bit definition for SAI_XFRCR register *******************/119#define SAI_XFRCR_FRL_SHIFT 0120#define SAI_XFRCR_FRL_MASK GENMASK(7, SAI_XFRCR_FRL_SHIFT)121#define SAI_XFRCR_FRL_SET(x) ((x) << SAI_XFRCR_FRL_SHIFT)122 123#define SAI_XFRCR_FSALL_SHIFT 8124#define SAI_XFRCR_FSALL_MASK GENMASK(14, SAI_XFRCR_FSALL_SHIFT)125#define SAI_XFRCR_FSALL_SET(x) ((x) << SAI_XFRCR_FSALL_SHIFT)126 127#define SAI_XFRCR_FSDEF_SHIFT 16128#define SAI_XFRCR_FSDEF BIT(SAI_XFRCR_FSDEF_SHIFT)129#define SAI_XFRCR_FSPOL_SHIFT 17130#define SAI_XFRCR_FSPOL BIT(SAI_XFRCR_FSPOL_SHIFT)131#define SAI_XFRCR_FSOFF_SHIFT 18132#define SAI_XFRCR_FSOFF BIT(SAI_XFRCR_FSOFF_SHIFT)133 134/****************** Bit definition for SAI_XSLOTR register ******************/135#define SAI_XSLOTR_FBOFF_SHIFT 0136#define SAI_XSLOTR_FBOFF_MASK GENMASK(4, SAI_XSLOTR_FBOFF_SHIFT)137#define SAI_XSLOTR_FBOFF_SET(x) ((x) << SAI_XSLOTR_FBOFF_SHIFT)138 139#define SAI_XSLOTR_SLOTSZ_SHIFT 6140#define SAI_XSLOTR_SLOTSZ_MASK GENMASK(7, SAI_XSLOTR_SLOTSZ_SHIFT)141#define SAI_XSLOTR_SLOTSZ_SET(x) ((x) << SAI_XSLOTR_SLOTSZ_SHIFT)142 143#define SAI_XSLOTR_NBSLOT_SHIFT 8144#define SAI_XSLOTR_NBSLOT_MASK GENMASK(11, SAI_XSLOTR_NBSLOT_SHIFT)145#define SAI_XSLOTR_NBSLOT_SET(x) ((x) << SAI_XSLOTR_NBSLOT_SHIFT)146 147#define SAI_XSLOTR_SLOTEN_SHIFT 16148#define SAI_XSLOTR_SLOTEN_WIDTH 16149#define SAI_XSLOTR_SLOTEN_MASK GENMASK(31, SAI_XSLOTR_SLOTEN_SHIFT)150#define SAI_XSLOTR_SLOTEN_SET(x) ((x) << SAI_XSLOTR_SLOTEN_SHIFT)151 152/******************* Bit definition for SAI_XIMR register *******************/153#define SAI_XIMR_OVRUDRIE BIT(0)154#define SAI_XIMR_MUTEDETIE BIT(1)155#define SAI_XIMR_WCKCFGIE BIT(2)156#define SAI_XIMR_FREQIE BIT(3)157#define SAI_XIMR_CNRDYIE BIT(4)158#define SAI_XIMR_AFSDETIE BIT(5)159#define SAI_XIMR_LFSDETIE BIT(6)160 161#define SAI_XIMR_SHIFT 0162#define SAI_XIMR_MASK GENMASK(6, SAI_XIMR_SHIFT)163 164/******************** Bit definition for SAI_XSR register *******************/165#define SAI_XSR_OVRUDR BIT(0)166#define SAI_XSR_MUTEDET BIT(1)167#define SAI_XSR_WCKCFG BIT(2)168#define SAI_XSR_FREQ BIT(3)169#define SAI_XSR_CNRDY BIT(4)170#define SAI_XSR_AFSDET BIT(5)171#define SAI_XSR_LFSDET BIT(6)172 173#define SAI_XSR_SHIFT 0174#define SAI_XSR_MASK GENMASK(6, SAI_XSR_SHIFT)175 176/****************** Bit definition for SAI_XCLRFR register ******************/177#define SAI_XCLRFR_COVRUDR BIT(0)178#define SAI_XCLRFR_CMUTEDET BIT(1)179#define SAI_XCLRFR_CWCKCFG BIT(2)180#define SAI_XCLRFR_CFREQ BIT(3)181#define SAI_XCLRFR_CCNRDY BIT(4)182#define SAI_XCLRFR_CAFSDET BIT(5)183#define SAI_XCLRFR_CLFSDET BIT(6)184 185#define SAI_XCLRFR_SHIFT 0186#define SAI_XCLRFR_MASK GENMASK(6, SAI_XCLRFR_SHIFT)187 188/****************** Bit definition for SAI_PDMCR register ******************/189#define SAI_PDMCR_PDMEN BIT(0)190 191#define SAI_PDMCR_MICNBR_SHIFT 4192#define SAI_PDMCR_MICNBR_MASK GENMASK(5, SAI_PDMCR_MICNBR_SHIFT)193#define SAI_PDMCR_MICNBR_SET(x) ((x) << SAI_PDMCR_MICNBR_SHIFT)194 195#define SAI_PDMCR_CKEN1 BIT(8)196#define SAI_PDMCR_CKEN2 BIT(9)197#define SAI_PDMCR_CKEN3 BIT(10)198#define SAI_PDMCR_CKEN4 BIT(11)199 200/****************** Bit definition for (SAI_PDMDLY register ****************/201#define SAI_PDMDLY_1L_SHIFT 0202#define SAI_PDMDLY_1L_MASK GENMASK(2, SAI_PDMDLY_1L_SHIFT)203#define SAI_PDMDLY_1L_WIDTH 3204 205#define SAI_PDMDLY_1R_SHIFT 4206#define SAI_PDMDLY_1R_MASK GENMASK(6, SAI_PDMDLY_1R_SHIFT)207#define SAI_PDMDLY_1R_WIDTH 3208 209#define SAI_PDMDLY_2L_SHIFT 8210#define SAI_PDMDLY_2L_MASK GENMASK(10, SAI_PDMDLY_2L_SHIFT)211#define SAI_PDMDLY_2L_WIDTH 3212 213#define SAI_PDMDLY_2R_SHIFT 12214#define SAI_PDMDLY_2R_MASK GENMASK(14, SAI_PDMDLY_2R_SHIFT)215#define SAI_PDMDLY_2R_WIDTH 3216 217#define SAI_PDMDLY_3L_SHIFT 16218#define SAI_PDMDLY_3L_MASK GENMASK(18, SAI_PDMDLY_3L_SHIFT)219#define SAI_PDMDLY_3L_WIDTH 3220 221#define SAI_PDMDLY_3R_SHIFT 20222#define SAI_PDMDLY_3R_MASK GENMASK(22, SAI_PDMDLY_3R_SHIFT)223#define SAI_PDMDLY_3R_WIDTH 3224 225#define SAI_PDMDLY_4L_SHIFT 24226#define SAI_PDMDLY_4L_MASK GENMASK(26, SAI_PDMDLY_4L_SHIFT)227#define SAI_PDMDLY_4L_WIDTH 3228 229#define SAI_PDMDLY_4R_SHIFT 28230#define SAI_PDMDLY_4R_MASK GENMASK(30, SAI_PDMDLY_4R_SHIFT)231#define SAI_PDMDLY_4R_WIDTH 3232 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 0x00130031251 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 0x0256 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)260 261enum stm32_sai_syncout {262 STM_SAI_SYNC_OUT_NONE,263 STM_SAI_SYNC_OUT_A,264 STM_SAI_SYNC_OUT_B,265};266 267/**268 * struct stm32_sai_conf - SAI configuration269 * @version: SAI version270 * @fifo_size: SAI fifo size as words number271 * @has_spdif_pdm: SAI S/PDIF and PDM features support flag272 */273struct stm32_sai_conf {274 u32 version;275 u32 fifo_size;276 bool has_spdif_pdm;277};278 279/**280 * struct stm32_sai_data - private data of SAI instance driver281 * @pdev: device data pointer282 * @base: common register bank virtual base address283 * @pclk: SAI bus clock284 * @clk_x8k: SAI parent clock for sampling frequencies multiple of 8kHz285 * @clk_x11k: SAI parent clock for sampling frequencies multiple of 11kHz286 * @conf: SAI hardware capabitilites287 * @irq: SAI interrupt line288 * @set_sync: pointer to synchro mode configuration callback289 * @gcr: SAI Global Configuration Register290 */291struct stm32_sai_data {292 struct platform_device *pdev;293 void __iomem *base;294 struct clk *pclk;295 struct clk *clk_x8k;296 struct clk *clk_x11k;297 struct stm32_sai_conf conf;298 int irq;299 int (*set_sync)(struct stm32_sai_data *sai,300 struct device_node *np_provider, int synco, int synci);301 u32 gcr;302};303