18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef AACI_H 88c2ecf20Sopenharmony_ci#define AACI_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci * Control and status register offsets 128c2ecf20Sopenharmony_ci * P39. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci#define AACI_CSCH1 0x000 158c2ecf20Sopenharmony_ci#define AACI_CSCH2 0x014 168c2ecf20Sopenharmony_ci#define AACI_CSCH3 0x028 178c2ecf20Sopenharmony_ci#define AACI_CSCH4 0x03c 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define AACI_RXCR 0x000 /* 29 bits Control Rx FIFO */ 208c2ecf20Sopenharmony_ci#define AACI_TXCR 0x004 /* 17 bits Control Tx FIFO */ 218c2ecf20Sopenharmony_ci#define AACI_SR 0x008 /* 12 bits Status */ 228c2ecf20Sopenharmony_ci#define AACI_ISR 0x00c /* 7 bits Int Status */ 238c2ecf20Sopenharmony_ci#define AACI_IE 0x010 /* 7 bits Int Enable */ 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* 268c2ecf20Sopenharmony_ci * Other registers 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci#define AACI_SL1RX 0x050 298c2ecf20Sopenharmony_ci#define AACI_SL1TX 0x054 308c2ecf20Sopenharmony_ci#define AACI_SL2RX 0x058 318c2ecf20Sopenharmony_ci#define AACI_SL2TX 0x05c 328c2ecf20Sopenharmony_ci#define AACI_SL12RX 0x060 338c2ecf20Sopenharmony_ci#define AACI_SL12TX 0x064 348c2ecf20Sopenharmony_ci#define AACI_SLFR 0x068 /* slot flags */ 358c2ecf20Sopenharmony_ci#define AACI_SLISTAT 0x06c /* slot interrupt status */ 368c2ecf20Sopenharmony_ci#define AACI_SLIEN 0x070 /* slot interrupt enable */ 378c2ecf20Sopenharmony_ci#define AACI_INTCLR 0x074 /* interrupt clear */ 388c2ecf20Sopenharmony_ci#define AACI_MAINCR 0x078 /* main control */ 398c2ecf20Sopenharmony_ci#define AACI_RESET 0x07c /* reset control */ 408c2ecf20Sopenharmony_ci#define AACI_SYNC 0x080 /* sync control */ 418c2ecf20Sopenharmony_ci#define AACI_ALLINTS 0x084 /* all fifo interrupt status */ 428c2ecf20Sopenharmony_ci#define AACI_MAINFR 0x088 /* main flag register */ 438c2ecf20Sopenharmony_ci#define AACI_DR1 0x090 /* data read/written fifo 1 */ 448c2ecf20Sopenharmony_ci#define AACI_DR2 0x0b0 /* data read/written fifo 2 */ 458c2ecf20Sopenharmony_ci#define AACI_DR3 0x0d0 /* data read/written fifo 3 */ 468c2ecf20Sopenharmony_ci#define AACI_DR4 0x0f0 /* data read/written fifo 4 */ 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * TX/RX fifo control register (CR). P48 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci#define CR_FEN (1 << 16) /* fifo enable */ 528c2ecf20Sopenharmony_ci#define CR_COMPACT (1 << 15) /* compact mode */ 538c2ecf20Sopenharmony_ci#define CR_SZ16 (0 << 13) /* 16 bits */ 548c2ecf20Sopenharmony_ci#define CR_SZ18 (1 << 13) /* 18 bits */ 558c2ecf20Sopenharmony_ci#define CR_SZ20 (2 << 13) /* 20 bits */ 568c2ecf20Sopenharmony_ci#define CR_SZ12 (3 << 13) /* 12 bits */ 578c2ecf20Sopenharmony_ci#define CR_SL12 (1 << 12) 588c2ecf20Sopenharmony_ci#define CR_SL11 (1 << 11) 598c2ecf20Sopenharmony_ci#define CR_SL10 (1 << 10) 608c2ecf20Sopenharmony_ci#define CR_SL9 (1 << 9) 618c2ecf20Sopenharmony_ci#define CR_SL8 (1 << 8) 628c2ecf20Sopenharmony_ci#define CR_SL7 (1 << 7) 638c2ecf20Sopenharmony_ci#define CR_SL6 (1 << 6) 648c2ecf20Sopenharmony_ci#define CR_SL5 (1 << 5) 658c2ecf20Sopenharmony_ci#define CR_SL4 (1 << 4) 668c2ecf20Sopenharmony_ci#define CR_SL3 (1 << 3) 678c2ecf20Sopenharmony_ci#define CR_SL2 (1 << 2) 688c2ecf20Sopenharmony_ci#define CR_SL1 (1 << 1) 698c2ecf20Sopenharmony_ci#define CR_EN (1 << 0) /* transmit enable */ 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* 728c2ecf20Sopenharmony_ci * status register bits. P49 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci#define SR_RXTOFE (1 << 11) /* rx timeout fifo empty */ 758c2ecf20Sopenharmony_ci#define SR_TXTO (1 << 10) /* rx timeout fifo nonempty */ 768c2ecf20Sopenharmony_ci#define SR_TXU (1 << 9) /* tx underrun */ 778c2ecf20Sopenharmony_ci#define SR_RXO (1 << 8) /* rx overrun */ 788c2ecf20Sopenharmony_ci#define SR_TXB (1 << 7) /* tx busy */ 798c2ecf20Sopenharmony_ci#define SR_RXB (1 << 6) /* rx busy */ 808c2ecf20Sopenharmony_ci#define SR_TXFF (1 << 5) /* tx fifo full */ 818c2ecf20Sopenharmony_ci#define SR_RXFF (1 << 4) /* rx fifo full */ 828c2ecf20Sopenharmony_ci#define SR_TXHE (1 << 3) /* tx fifo half empty */ 838c2ecf20Sopenharmony_ci#define SR_RXHF (1 << 2) /* rx fifo half full */ 848c2ecf20Sopenharmony_ci#define SR_TXFE (1 << 1) /* tx fifo empty */ 858c2ecf20Sopenharmony_ci#define SR_RXFE (1 << 0) /* rx fifo empty */ 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* 888c2ecf20Sopenharmony_ci * interrupt status register bits. 898c2ecf20Sopenharmony_ci */ 908c2ecf20Sopenharmony_ci#define ISR_RXTOFEINTR (1 << 6) /* rx fifo empty */ 918c2ecf20Sopenharmony_ci#define ISR_URINTR (1 << 5) /* tx underflow */ 928c2ecf20Sopenharmony_ci#define ISR_ORINTR (1 << 4) /* rx overflow */ 938c2ecf20Sopenharmony_ci#define ISR_RXINTR (1 << 3) /* rx fifo */ 948c2ecf20Sopenharmony_ci#define ISR_TXINTR (1 << 2) /* tx fifo intr */ 958c2ecf20Sopenharmony_ci#define ISR_RXTOINTR (1 << 1) /* tx timeout */ 968c2ecf20Sopenharmony_ci#define ISR_TXCINTR (1 << 0) /* tx complete */ 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci/* 998c2ecf20Sopenharmony_ci * interrupt enable register bits. 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ci#define IE_RXTOIE (1 << 6) 1028c2ecf20Sopenharmony_ci#define IE_URIE (1 << 5) 1038c2ecf20Sopenharmony_ci#define IE_ORIE (1 << 4) 1048c2ecf20Sopenharmony_ci#define IE_RXIE (1 << 3) 1058c2ecf20Sopenharmony_ci#define IE_TXIE (1 << 2) 1068c2ecf20Sopenharmony_ci#define IE_RXTIE (1 << 1) 1078c2ecf20Sopenharmony_ci#define IE_TXCIE (1 << 0) 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 1108c2ecf20Sopenharmony_ci * interrupt status. P51 1118c2ecf20Sopenharmony_ci */ 1128c2ecf20Sopenharmony_ci#define ISR_RXTOFE (1 << 6) /* rx timeout fifo empty */ 1138c2ecf20Sopenharmony_ci#define ISR_UR (1 << 5) /* tx fifo underrun */ 1148c2ecf20Sopenharmony_ci#define ISR_OR (1 << 4) /* rx fifo overrun */ 1158c2ecf20Sopenharmony_ci#define ISR_RX (1 << 3) /* rx interrupt status */ 1168c2ecf20Sopenharmony_ci#define ISR_TX (1 << 2) /* tx interrupt status */ 1178c2ecf20Sopenharmony_ci#define ISR_RXTO (1 << 1) /* rx timeout */ 1188c2ecf20Sopenharmony_ci#define ISR_TXC (1 << 0) /* tx complete */ 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* 1218c2ecf20Sopenharmony_ci * interrupt enable. P52 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_ci#define IE_RXTOFE (1 << 6) /* rx timeout fifo empty */ 1248c2ecf20Sopenharmony_ci#define IE_UR (1 << 5) /* tx fifo underrun */ 1258c2ecf20Sopenharmony_ci#define IE_OR (1 << 4) /* rx fifo overrun */ 1268c2ecf20Sopenharmony_ci#define IE_RX (1 << 3) /* rx interrupt status */ 1278c2ecf20Sopenharmony_ci#define IE_TX (1 << 2) /* tx interrupt status */ 1288c2ecf20Sopenharmony_ci#define IE_RXTO (1 << 1) /* rx timeout */ 1298c2ecf20Sopenharmony_ci#define IE_TXC (1 << 0) /* tx complete */ 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci/* 1328c2ecf20Sopenharmony_ci * slot flag register bits. P56 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci#define SLFR_RWIS (1 << 13) /* raw wake-up interrupt status */ 1358c2ecf20Sopenharmony_ci#define SLFR_RGPIOINTR (1 << 12) /* raw gpio interrupt */ 1368c2ecf20Sopenharmony_ci#define SLFR_12TXE (1 << 11) /* slot 12 tx empty */ 1378c2ecf20Sopenharmony_ci#define SLFR_12RXV (1 << 10) /* slot 12 rx valid */ 1388c2ecf20Sopenharmony_ci#define SLFR_2TXE (1 << 9) /* slot 2 tx empty */ 1398c2ecf20Sopenharmony_ci#define SLFR_2RXV (1 << 8) /* slot 2 rx valid */ 1408c2ecf20Sopenharmony_ci#define SLFR_1TXE (1 << 7) /* slot 1 tx empty */ 1418c2ecf20Sopenharmony_ci#define SLFR_1RXV (1 << 6) /* slot 1 rx valid */ 1428c2ecf20Sopenharmony_ci#define SLFR_12TXB (1 << 5) /* slot 12 tx busy */ 1438c2ecf20Sopenharmony_ci#define SLFR_12RXB (1 << 4) /* slot 12 rx busy */ 1448c2ecf20Sopenharmony_ci#define SLFR_2TXB (1 << 3) /* slot 2 tx busy */ 1458c2ecf20Sopenharmony_ci#define SLFR_2RXB (1 << 2) /* slot 2 rx busy */ 1468c2ecf20Sopenharmony_ci#define SLFR_1TXB (1 << 1) /* slot 1 tx busy */ 1478c2ecf20Sopenharmony_ci#define SLFR_1RXB (1 << 0) /* slot 1 rx busy */ 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/* 1508c2ecf20Sopenharmony_ci * Interrupt clear register. 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_ci#define ICLR_RXTOFEC4 (1 << 12) 1538c2ecf20Sopenharmony_ci#define ICLR_RXTOFEC3 (1 << 11) 1548c2ecf20Sopenharmony_ci#define ICLR_RXTOFEC2 (1 << 10) 1558c2ecf20Sopenharmony_ci#define ICLR_RXTOFEC1 (1 << 9) 1568c2ecf20Sopenharmony_ci#define ICLR_TXUEC4 (1 << 8) 1578c2ecf20Sopenharmony_ci#define ICLR_TXUEC3 (1 << 7) 1588c2ecf20Sopenharmony_ci#define ICLR_TXUEC2 (1 << 6) 1598c2ecf20Sopenharmony_ci#define ICLR_TXUEC1 (1 << 5) 1608c2ecf20Sopenharmony_ci#define ICLR_RXOEC4 (1 << 4) 1618c2ecf20Sopenharmony_ci#define ICLR_RXOEC3 (1 << 3) 1628c2ecf20Sopenharmony_ci#define ICLR_RXOEC2 (1 << 2) 1638c2ecf20Sopenharmony_ci#define ICLR_RXOEC1 (1 << 1) 1648c2ecf20Sopenharmony_ci#define ICLR_WISC (1 << 0) 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci/* 1678c2ecf20Sopenharmony_ci * Main control register bits. P62 1688c2ecf20Sopenharmony_ci */ 1698c2ecf20Sopenharmony_ci#define MAINCR_SCRA(x) ((x) << 10) /* secondary codec reg access */ 1708c2ecf20Sopenharmony_ci#define MAINCR_DMAEN (1 << 9) /* dma enable */ 1718c2ecf20Sopenharmony_ci#define MAINCR_SL12TXEN (1 << 8) /* slot 12 transmit enable */ 1728c2ecf20Sopenharmony_ci#define MAINCR_SL12RXEN (1 << 7) /* slot 12 receive enable */ 1738c2ecf20Sopenharmony_ci#define MAINCR_SL2TXEN (1 << 6) /* slot 2 transmit enable */ 1748c2ecf20Sopenharmony_ci#define MAINCR_SL2RXEN (1 << 5) /* slot 2 receive enable */ 1758c2ecf20Sopenharmony_ci#define MAINCR_SL1TXEN (1 << 4) /* slot 1 transmit enable */ 1768c2ecf20Sopenharmony_ci#define MAINCR_SL1RXEN (1 << 3) /* slot 1 receive enable */ 1778c2ecf20Sopenharmony_ci#define MAINCR_LPM (1 << 2) /* low power mode */ 1788c2ecf20Sopenharmony_ci#define MAINCR_LOOPBK (1 << 1) /* loopback */ 1798c2ecf20Sopenharmony_ci#define MAINCR_IE (1 << 0) /* aaci interface enable */ 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci/* 1828c2ecf20Sopenharmony_ci * Reset register bits. P65 1838c2ecf20Sopenharmony_ci */ 1848c2ecf20Sopenharmony_ci#define RESET_NRST (1 << 0) 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci/* 1878c2ecf20Sopenharmony_ci * Sync register bits. P65 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ci#define SYNC_FORCE (1 << 0) 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci/* 1928c2ecf20Sopenharmony_ci * Main flag register bits. P66 1938c2ecf20Sopenharmony_ci */ 1948c2ecf20Sopenharmony_ci#define MAINFR_TXB (1 << 1) /* transmit busy */ 1958c2ecf20Sopenharmony_ci#define MAINFR_RXB (1 << 0) /* receive busy */ 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistruct aaci_runtime { 2008c2ecf20Sopenharmony_ci void __iomem *base; 2018c2ecf20Sopenharmony_ci void __iomem *fifo; 2028c2ecf20Sopenharmony_ci spinlock_t lock; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci struct ac97_pcm *pcm; 2058c2ecf20Sopenharmony_ci int pcm_open; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci u32 cr; 2088c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci unsigned int period; /* byte size of a "period" */ 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci /* 2138c2ecf20Sopenharmony_ci * PIO support 2148c2ecf20Sopenharmony_ci */ 2158c2ecf20Sopenharmony_ci void *start; 2168c2ecf20Sopenharmony_ci void *end; 2178c2ecf20Sopenharmony_ci void *ptr; 2188c2ecf20Sopenharmony_ci int bytes; 2198c2ecf20Sopenharmony_ci unsigned int fifo_bytes; 2208c2ecf20Sopenharmony_ci}; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistruct aaci { 2238c2ecf20Sopenharmony_ci struct amba_device *dev; 2248c2ecf20Sopenharmony_ci struct snd_card *card; 2258c2ecf20Sopenharmony_ci void __iomem *base; 2268c2ecf20Sopenharmony_ci unsigned int fifo_depth; 2278c2ecf20Sopenharmony_ci unsigned int users; 2288c2ecf20Sopenharmony_ci struct mutex irq_lock; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci /* AC'97 */ 2318c2ecf20Sopenharmony_ci struct mutex ac97_sem; 2328c2ecf20Sopenharmony_ci struct snd_ac97_bus *ac97_bus; 2338c2ecf20Sopenharmony_ci struct snd_ac97 *ac97; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci u32 maincr; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci struct aaci_runtime playback; 2388c2ecf20Sopenharmony_ci struct aaci_runtime capture; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci struct snd_pcm *pcm; 2418c2ecf20Sopenharmony_ci}; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#define ACSTREAM_FRONT 0 2448c2ecf20Sopenharmony_ci#define ACSTREAM_SURROUND 1 2458c2ecf20Sopenharmony_ci#define ACSTREAM_LFE 2 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci#endif 248