1 /* 2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved. 3 * 4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in 5 * the the people's Republic of China and other countries. 6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission. 7 * 8 * DISCLAIMER 9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT. 10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.) 11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN 12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES. 13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS 14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE. 15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY. 16 * 17 * 18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT 19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, 20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING 21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE 22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 * OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 #ifndef __SUNXI_MAD_H_ 33 #define __SUNXI_MAD_H_ 34 35 #include <aw_common.h> 36 #include <hal_clk.h> 37 #include <hal_dma.h> 38 #include <snd_core.h> 39 #include <snd_pcm.h> 40 #include <snd_io.h> 41 42 #include "sunxi-pcm.h" 43 44 /* memory mapping */ 45 #define MAD_BASE SUNXI_MAD_PBASE 46 #define MAD_SRAM_DMA_SRC_ADDR SUNXI_MAD_SRAM_PBASE 47 48 #ifdef CONFIG_ARCH_SUN8IW18P1 49 /* SUN8IW18P1 should not be setup. */ 50 #undef MAD_CLK_ALWAYS_ON 51 //#undef SUNXI_LPSD_CLK_ALWAYS_ON 52 #define SUNXI_LPSD_CLK_ALWAYS_ON 53 #undef SUNXI_MAD_DATA_INT_USE 54 //#define SUNXI_MAD_DATA_INT_USE 55 #define SUNXI_MAD_SRAM_SUSPEND_RESET 56 57 /* 128k bytes */ 58 #define MAD_SRAM_SIZE_VALUE 0x80 59 #endif 60 61 /*memory mapping*/ 62 #ifndef MAD_BASE 63 #define MAD_BASE (0x05400000) 64 #endif 65 #ifndef MAD_SRAM_DMA_SRC_ADDR 66 #define MAD_SRAM_DMA_SRC_ADDR (0x05480000) 67 #endif 68 /* 128k bytes */ 69 #ifndef MAD_SRAM_SIZE_VALUE 70 #define MAD_SRAM_SIZE_VALUE 0x80 71 #endif 72 73 enum mad_sram_bmode { 74 MAD_SRAM_BMODE_NORMAL = 0, 75 MAD_SRAM_BMODE_BOOT = 1, 76 }; 77 78 enum mad_path_sel { 79 MAD_PATH_NONE = 0, 80 MAD_PATH_I2S0 = 1, 81 MAD_PATH_CODEC = 2, 82 MAD_PATH_DMIC = 3, 83 MAD_PATH_I2S1 = 4, 84 MAD_PATH_I2S2 = 5, 85 }; 86 87 #ifdef CONFIG_ARCH_SUN8IW18P1 88 #undef SUNXI_MAD_DATA_INT_USE 89 #endif 90 91 #define EVT_MAX_SIZE 256 92 #define SUNXI_NETLINK_MAD 30 93 94 /*------------------MAD register definition--------------------*/ 95 #define SUNXI_MAD_CTRL 0x00 96 #define SUNXI_MAD_SRAM_POINT 0x04 97 #define SUNXI_MAD_SRAM_SIZE 0x08 98 #define SUNXI_MAD_SRAM_RD_POINT 0x0C 99 #define SUNXI_MAD_RD_SIZE 0x10 100 #define SUNXI_MAD_SRAM_STORE_TH 0x14 101 #define SUNXI_MAD_SRAM_AHB1_TX_TH 0x18 102 #define SUNXI_MAD_SRAM_AHB1_RX_TH 0x1C 103 #define SUNXI_MAD_SRAM_WAKE_BACK_DATA 0x20 104 #define SUNXI_MAD_AD_PATH_SEL 0x24 105 #define SUNXI_MAD_LPSD_AD_SYNC_FC 0x28 106 #define SUNXI_MAD_LPSD_TH 0x2C 107 #define SUNXI_MAD_LPSD_RRUN 0x30 108 #define SUNXI_MAD_LPSD_RSTOP 0x34 109 #define SUNXI_MAD_LPSD_ECNT 0x38 110 #define SUNXI_MAD_SRAM_CH_MASK 0x3C 111 #define SUNXI_MAD_LPSD_CH_MASK 0x40 112 #define SUNXI_MAD_SRAM_SEC_REGION_REG 0x44 113 #define SUNXI_MAD_SRAM_PRE_DSIZE 0x48 114 #define SUNXI_MAD_DMA_TF_SIZE 0x4C 115 #define SUNXI_MAD_DMA_TF_LAST_SIZE 0x50 116 #define SUNXI_MAD_INT_ST_CLR 0x60 117 #define SUNXI_MAD_INT_MASK 0x64 118 #define SUNXI_MAD_STA 0x68 119 #define SUNXI_MAD_DEBUG 0x6C 120 121 /*SUNXI_MAD_CTRL: 0x00*/ 122 #define AUDIO_DATA_SYNC_FRC 7 123 #define SRAM_RST 6 124 #define DMA_TYPE 5 125 #define DMA_EN 4 126 #define CPUS_RD_DONE 3 127 #define GO_ON_SLEEP 2 128 #define KEY_WORD_OK 1 129 #define MAD_EN 0 130 /* DMA type*/ 131 #define DMA_TYPE_MASK 0x1 132 #define DMA_TYPE_IO 0x1 133 #define DMA_TYPE_MEM 0x0 134 135 /*SUNXI_MAD_SRAM_POINT: 0x04*/ 136 #define MAD_SRAM_PONT 0 137 138 /*SUNXI_MAD_SRAM_SIZE: 0x08*/ 139 #define MAD_SRAM_SIZE 0 140 141 /*SUNXI_MAD_SRAM_RD_POINT: 0x0C*/ 142 #define MAD_SRAM_RD_POINT 0 143 144 /*SUNXI_MAD_SRAM_RD_SIZE(unit: half word): 0x10*/ 145 #define MAD_SRAM_RD_SIZE 0 146 147 /*SUNXI_MAD_SRAM_STORE_TH(unit: half word): 0x14*/ 148 #define MAD_SRAM_STORE_TH 0 149 150 /*SUNXI_MAD_SRAM_AHB1_TX_TH(unit: byte): 0x18*/ 151 #define MAD_SRAM_AHB1_TX_TH 0 152 153 /*SUNXI_MAD_SRAM_AHB1_RX_TH(unit: byte): 0x1C*/ 154 #define MAD_SRAM_AHB1_RX_TH 0 155 156 /*SUNXI_MAD_SRAM_WAKE_BACK_DATA(unit: frame): 0x20*/ 157 #define MAD_SRAM_WAKE_BACK_DATA 0 158 159 /*SUNXI_MAD_AD_PATH_SEL: 0x24*/ 160 #define MAD_AD_PATH_SEL 0 161 #define MAD_AD_PATH_SEL_MASK 0xF 162 /*MAD audio src sel*/ 163 #define MAD_AD_PATH_NO_SRC 0x0 164 #define MAD_AD_PATH_I2S0_SRC 0x1 165 #define MAD_AD_PATH_CODEC_SRC 0x2 166 #define MAD_AD_PATH_DMIC_SRC 0x3 167 #define MAD_AD_PATH_I2S1_SRC 0x4 168 #define MAD_AD_PATH_I2S2_SRC 0x5 169 170 /*SUNXI_MAD_LPSD_AD_SYNC_FC: 0x28*/ 171 #define MAD_LPSD_AD_SYNC_FC 0 172 #define MAD_LPSD_AD_SYNC_FC_DEF 0X20 173 174 /*SUNXI_MAD_LPSD_TH: 0x2C*/ 175 #define MAD_LPSD_TH 0 176 177 /*SUNXI_MAD_LPSD_RRUN: 0x30*/ 178 #define MAD_LPSD_RRUN 0 179 180 /*SUNXI_MAD_LPSD_RSTOP: 0x34*/ 181 #define MAD_LPSD_RSTOP 0 182 183 /*SUNXI_MAD_LPSD_ECNT: 0x38*/ 184 #define MAD_LPSD_ECNT 0 185 186 /*SUNXI_MAD_SRAM_CH_MASK: 0x3C*/ 187 #define MAD_CH_CHANGE_EN 30 188 #define MAD_CH_COM_NUM 26 189 #define MAD_AD_SRC_CH_NUM 21 190 #define MAD_SRAM_CH_NUM 16 191 #define MAD_SRAM_CH_MASK 0 192 193 #define MAD_SRAM_CH_NUM_MASK 0x1F 194 195 /*MAD channel change sel*/ 196 #define MAD_CH_COM_NUM_MASK 0xF 197 #define MAD_CH_COM_NON 0x0 198 #define MAD_CH_COM_2CH_TO_4CH 0x1 199 #define MAD_CH_COM_2CH_TO_6CH 0x2 200 #define MAD_CH_COM_2CH_TO_8CH 0x3 201 #define MAD_CH_COM_4CH_TO_6CH 0x4 202 #define MAD_CH_COM_4CH_TO_8CH 0x5 203 204 /*SUNXI_MAD_LPSD_CH_MASK: 0x40*/ 205 #define MAD_LPSD_DCBLOCK_EN 20 206 #define MAD_LPSD_CH_NUM 16 207 #define MAD_LPSD_CH_MASK 0 208 /*LPSD receive 0/1 audio channel mask*/ 209 #define MAD_LPSD_CH_NUM_MASK 0xF 210 /*LPSD AUDIO channel num sel*/ 211 #define MAD_LPSD_CH_NUM_NON 0x0 212 #define MAD_LPSD_CH_NUM_1CH 0x1 213 214 /*SUNXI_MAD_SRAM_SEC_REGION: 0x44*/ 215 #define MAD_SRAM_SEC_REGION 0 216 217 /*SUNXI_MAD_SRAM_PRE_DATA_SIZE(unit: half word): 0x48*/ 218 #define MAD_SRAM_PRE_DATA_SIZE 0 219 220 /*SUNXI_MAD_DMA_TF_SIZE: 0x4C*/ 221 #define MAD_DMA_TF_SIZE 0 222 223 /*SUNXI_MAD_DMA_TF_LAST_SIZE: 0x50*/ 224 #define MAD_DMA_TF_LAST_SIZE 0 225 226 /*SUNXI_MAD_INT_ST_CLR: 0x60*/ 227 #define DATA_REQ_INT 1 228 #define WAKE_INT 0 229 230 /*SUNXI_MAD_INT_MASK: 0x64*/ 231 #define DATA_REQ_INT_MASK 1 232 #define MAD_REQ_INT_MASK 0 233 234 /*SUNXI_MAD_STATE_REG: 0x68*/ 235 #define MAD_LPSD_STAT 8 236 #define MAD_STATE 4 237 #define MAD_SRAM_FULL 2 238 #define MAD_SRAM_EMPTY 1 239 #define MAD_RUN 0 240 /*MAD STATE(read only)*/ 241 #define MAD_STATE_IDLE 0x0 242 #define MAD_STATE_WAIT 0x1 243 #define MAD_STATE_RUN 0x2 244 #define MAD_STATE_NORMAL 0x4 245 246 /*SUNXI_MAD_DEBUG: 0x6C*/ 247 #define MAD_CFG_ERR 4 248 #define MAD_SRAM_FULL_ERR 3 249 #define MAD_SRAM_EMPTY_ERR 2 250 #define DATA_SRAM_ADDR_ERR 1 251 #define MAD_SRAM_SEC_ERR 0 252 /*MAD_CFG_ERR mask*/ 253 #define MAD_CFG_ERR_MASK 0x3 254 255 /* for mad clk*/ 256 #define MAD_SRAM_BMODE_CTRL 24 257 #define SRAM_BMODE_CTRL_REG 0x3000004 258 259 enum sunxi_mad_standby_debug_flag { 260 SUNXI_MAD_DEBUG_STANDBY_NULL = 0, 261 SUNXI_MAD_DEBUG_STANDBY_SUSPEND = 1, 262 SUNXI_MAD_DEBUG_STANDBY_RESUME = 2, 263 }; 264 265 enum sunxi_mad_irq_work_flag { 266 SUNXI_MAD_NULL_IRQ_WORK = 0, 267 SUNXI_MAD_LPSD_IRQ_WORK = 1, 268 SUNXI_MAD_DATA_IRQ_WORK = 2, 269 }; 270 271 enum sunxi_mad_sram_reset_flag { 272 SUNXI_MAD_SRAM_RESET_IDLE = 0, 273 SUNXI_MAD_SRAM_RESET_START = 1, 274 SUNXI_MAD_SRAM_RESET_END = 2, 275 }; 276 277 enum sunxi_mad_status { 278 SUNXI_MAD_OPEN = 0, 279 SUNXI_MAD_PARAMS = 1, 280 SUNXI_MAD_SUSPEND = 2, 281 SUNXI_MAD_RESUME = 3, 282 SUNXI_MAD_CLOSE = 4, 283 }; 284 285 enum sunxi_mad_dma_type { 286 SUNXI_MAD_DMA_MEM = 0, 287 SUNXI_MAD_DMA_IO = 1, 288 }; 289 290 enum sunxi_mad_standby_flag { 291 /* bit0 for sram IO type when standby */ 292 SUNXI_MAD_STANDBY_SRAM_MEM = 0x1, 293 }; 294 295 enum sunxi_mad_wakeup_flag { 296 /* bit0 for wakeup source */ 297 SUNXI_MAD_WAKEUP_OFF = 0x0, 298 SUNXI_MAD_WAKEUP_ON = 0x1, 299 /* bit1 for wakeup use or no */ 300 SUNXI_MAD_WAKEUP_USE = 0x2, 301 302 /* bit2 for lpsd wakeup */ 303 SUNXI_MAD_WAKEUP_LPSD_IRQ = 0x4, 304 /* bit3 for mad irq wakeup */ 305 SUNXI_MAD_WAKEUP_MAD_IRQ = 0x8, 306 /* bit4 for other irq wakeup */ 307 SUNXI_MAD_WAKEUP_OTHER = 0x10, 308 }; 309 310 struct sunxi_mad_priv { 311 struct sunxi_mad_info *sunxi_mad; 312 unsigned int mad_bind; 313 unsigned int mad_suspend; 314 /* mad params */ 315 unsigned int sample_rate; 316 unsigned int lpsd_chan_sel; 317 unsigned int standby_chan_sel; 318 unsigned int audio_src_chan_num; 319 }; 320 321 struct sunxi_mad_info { 322 hal_clk_id_t mad_clk; 323 hal_clk_id_t mad_cfg_clk; 324 hal_clk_id_t mad_ad_clk; 325 hal_clk_id_t lpsd_clk; 326 hal_clk_id_t pll_clk; 327 hal_clk_id_t hosc_clk; 328 329 freert_spinlock_t resume_spin; 330 331 unsigned int pll_audio_src_used; 332 unsigned int hosc_src_used; 333 334 void *mem_base; 335 336 unsigned int mad_irq; 337 unsigned int lpsd_irq; 338 QueueHandle_t irq_queue; 339 TaskHandle_t pxMadIrqTask; 340 341 unsigned int sram_rd_point; 342 unsigned int audio_src_path; 343 344 unsigned int mad_bind; 345 346 int status; 347 unsigned int wakeup_flag; 348 unsigned int suspend_flag; 349 unsigned int sram_reset_flag; 350 int standby_sram_type; 351 int wakeup_irq_en; 352 unsigned int ref_count; 353 354 struct sunxi_mad_priv mad_priv; 355 356 void *private_data; 357 }; 358 359 int sunxi_mad_sram_set_reset_flag(enum sunxi_mad_sram_reset_flag reset_flag); 360 enum sunxi_mad_sram_reset_flag sunxi_mad_sram_get_reset_flag(void); 361 int sunxi_mad_sram_wait_reset_flag(enum sunxi_mad_sram_reset_flag reset_flag, 362 unsigned int time_out_msecond); 363 364 void sunxi_mad_sram_chan_params(unsigned int mad_channels); 365 struct sunxi_mad_info *sunxi_mad_get_mad_info(void); 366 367 void sunxi_mad_clk_enable(bool val); 368 void sunxi_mad_ad_clk_enable(bool val); 369 void sunxi_mad_cfg_clk_enable(bool val); 370 void sunxi_mad_module_clk_enable(bool val); 371 void sunxi_lpsd_clk_enable(bool val); 372 373 /* for mad interrupt */ 374 void sunxi_lpsd_int_stat_clr(void); 375 void sunxi_mad_set_lpsd_req(bool enable); 376 void sunxi_mad_set_data_req(bool enable); 377 378 /* for mad init */ 379 int sunxi_mad_open(void); 380 int sunxi_mad_close(void); 381 void sunxi_mad_sram_init(void); 382 void sunxi_mad_lpsd_init(void); 383 void sunxi_sram_ahb1_threshole_init(void); 384 void sunxi_mad_standby_chan_sel(unsigned int num); 385 void sunxi_lpsd_chan_sel(unsigned int num); 386 void sunxi_mad_audio_src_chan_num(unsigned int num); 387 void sunxi_sram_dma_config(struct sunxi_dma_params *capture_dma_param); 388 int sunxi_mad_hw_params(unsigned int mad_channels, unsigned int sample_rate); 389 int sunxi_mad_audio_source_sel(unsigned int path_sel, unsigned int enable); 390 int sunxi_mad_suspend_external(void); 391 int sunxi_mad_resume_external(void); 392 void sunxi_mad_dma_enable(bool enable); 393 void sunxi_mad_dma_type(enum sunxi_mad_dma_type dma_type); 394 int sunxi_mad_enable(bool enable); 395 void sunxi_mad_set_go_on_sleep(bool enable); 396 void sunxi_mad_sram_set_reset_bit(void); 397 398 #ifdef CONFIG_SUNXI_MAD_DEBUG 399 int sunxi_mad_schd_timeout(SemaphoreHandle_t semaphore, long ms); 400 void sunxi_mad_schd_wakeup(SemaphoreHandle_t semaphore); 401 #endif 402 403 /* for probe mad module */ 404 int sunxi_mad_platform_probe(struct snd_platform *platform); 405 int sunxi_mad_platform_remove(struct snd_platform *platform); 406 #endif /* SUNXI_MAD_H */ 407