18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards 48c2ecf20Sopenharmony_ci * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* 88c2ecf20Sopenharmony_ci * 2002-07 Benny Sjostrand benny@hostmobility.com 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_CS46XX_NEW_DSP /* hack ... */ 128c2ecf20Sopenharmony_ci#ifndef __DSP_SPOS_H__ 138c2ecf20Sopenharmony_ci#define __DSP_SPOS_H__ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define DSP_MAX_SYMBOLS 1024 168c2ecf20Sopenharmony_ci#define DSP_MAX_MODULES 64 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define DSP_CODE_BYTE_SIZE 0x00007000UL 198c2ecf20Sopenharmony_ci#define DSP_PARAMETER_BYTE_SIZE 0x00003000UL 208c2ecf20Sopenharmony_ci#define DSP_SAMPLE_BYTE_SIZE 0x00003800UL 218c2ecf20Sopenharmony_ci#define DSP_PARAMETER_BYTE_OFFSET 0x00000000UL 228c2ecf20Sopenharmony_ci#define DSP_SAMPLE_BYTE_OFFSET 0x00010000UL 238c2ecf20Sopenharmony_ci#define DSP_CODE_BYTE_OFFSET 0x00020000UL 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define WIDE_INSTR_MASK 0x0040 268c2ecf20Sopenharmony_ci#define WIDE_LADD_INSTR_MASK 0x0380 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* this instruction types 298c2ecf20Sopenharmony_ci needs to be reallocated when load 308c2ecf20Sopenharmony_ci code into DSP */ 318c2ecf20Sopenharmony_cienum wide_opcode { 328c2ecf20Sopenharmony_ci WIDE_FOR_BEGIN_LOOP = 0x20, 338c2ecf20Sopenharmony_ci WIDE_FOR_BEGIN_LOOP2, 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci WIDE_COND_GOTO_ADDR = 0x30, 368c2ecf20Sopenharmony_ci WIDE_COND_GOTO_CALL, 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci WIDE_TBEQ_COND_GOTO_ADDR = 0x70, 398c2ecf20Sopenharmony_ci WIDE_TBEQ_COND_CALL_ADDR, 408c2ecf20Sopenharmony_ci WIDE_TBEQ_NCOND_GOTO_ADDR, 418c2ecf20Sopenharmony_ci WIDE_TBEQ_NCOND_CALL_ADDR, 428c2ecf20Sopenharmony_ci WIDE_TBEQ_COND_GOTO1_ADDR, 438c2ecf20Sopenharmony_ci WIDE_TBEQ_COND_CALL1_ADDR, 448c2ecf20Sopenharmony_ci WIDE_TBEQ_NCOND_GOTOI_ADDR, 458c2ecf20Sopenharmony_ci WIDE_TBEQ_NCOND_CALL1_ADDR, 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* SAMPLE segment */ 498c2ecf20Sopenharmony_ci#define VARI_DECIMATE_BUF1 0x0000 508c2ecf20Sopenharmony_ci#define WRITE_BACK_BUF1 0x0400 518c2ecf20Sopenharmony_ci#define CODEC_INPUT_BUF1 0x0500 528c2ecf20Sopenharmony_ci#define PCM_READER_BUF1 0x0600 538c2ecf20Sopenharmony_ci#define SRC_DELAY_BUF1 0x0680 548c2ecf20Sopenharmony_ci#define VARI_DECIMATE_BUF0 0x0780 558c2ecf20Sopenharmony_ci#define SRC_OUTPUT_BUF1 0x07A0 568c2ecf20Sopenharmony_ci#define ASYNC_IP_OUTPUT_BUFFER1 0x0A00 578c2ecf20Sopenharmony_ci#define OUTPUT_SNOOP_BUFFER 0x0B00 588c2ecf20Sopenharmony_ci#define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00 598c2ecf20Sopenharmony_ci#define SPDIFO_IP_OUTPUT_BUFFER1 0x1000 608c2ecf20Sopenharmony_ci#define MIX_SAMPLE_BUF1 0x1400 618c2ecf20Sopenharmony_ci#define MIX_SAMPLE_BUF2 0x2E80 628c2ecf20Sopenharmony_ci#define MIX_SAMPLE_BUF3 0x2F00 638c2ecf20Sopenharmony_ci#define MIX_SAMPLE_BUF4 0x2F80 648c2ecf20Sopenharmony_ci#define MIX_SAMPLE_BUF5 0x3000 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* Task stack address */ 678c2ecf20Sopenharmony_ci#define HFG_STACK 0x066A 688c2ecf20Sopenharmony_ci#define FG_STACK 0x066E 698c2ecf20Sopenharmony_ci#define BG_STACK 0x068E 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* SCB's addresses */ 728c2ecf20Sopenharmony_ci#define SPOSCB_ADDR 0x070 738c2ecf20Sopenharmony_ci#define BG_TREE_SCB_ADDR 0x635 748c2ecf20Sopenharmony_ci#define NULL_SCB_ADDR 0x000 758c2ecf20Sopenharmony_ci#define TIMINGMASTER_SCB_ADDR 0x010 768c2ecf20Sopenharmony_ci#define CODECOUT_SCB_ADDR 0x020 778c2ecf20Sopenharmony_ci#define PCMREADER_SCB_ADDR 0x030 788c2ecf20Sopenharmony_ci#define WRITEBACK_SCB_ADDR 0x040 798c2ecf20Sopenharmony_ci#define CODECIN_SCB_ADDR 0x080 808c2ecf20Sopenharmony_ci#define MASTERMIX_SCB_ADDR 0x090 818c2ecf20Sopenharmony_ci#define SRCTASK_SCB_ADDR 0x0A0 828c2ecf20Sopenharmony_ci#define VARIDECIMATE_SCB_ADDR 0x0B0 838c2ecf20Sopenharmony_ci#define PCMSERIALIN_SCB_ADDR 0x0C0 848c2ecf20Sopenharmony_ci#define FG_TASK_HEADER_ADDR 0x600 858c2ecf20Sopenharmony_ci#define ASYNCTX_SCB_ADDR 0x0E0 868c2ecf20Sopenharmony_ci#define ASYNCRX_SCB_ADDR 0x0F0 878c2ecf20Sopenharmony_ci#define SRCTASKII_SCB_ADDR 0x100 888c2ecf20Sopenharmony_ci#define OUTPUTSNOOP_SCB_ADDR 0x110 898c2ecf20Sopenharmony_ci#define PCMSERIALINII_SCB_ADDR 0x120 908c2ecf20Sopenharmony_ci#define SPIOWRITE_SCB_ADDR 0x130 918c2ecf20Sopenharmony_ci#define REAR_CODECOUT_SCB_ADDR 0x140 928c2ecf20Sopenharmony_ci#define OUTPUTSNOOPII_SCB_ADDR 0x150 938c2ecf20Sopenharmony_ci#define PCMSERIALIN_PCM_SCB_ADDR 0x160 948c2ecf20Sopenharmony_ci#define RECORD_MIXER_SCB_ADDR 0x170 958c2ecf20Sopenharmony_ci#define REAR_MIXER_SCB_ADDR 0x180 968c2ecf20Sopenharmony_ci#define CLFE_MIXER_SCB_ADDR 0x190 978c2ecf20Sopenharmony_ci#define CLFE_CODEC_SCB_ADDR 0x1A0 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* hyperforground SCB's*/ 1008c2ecf20Sopenharmony_ci#define HFG_TREE_SCB 0xBA0 1018c2ecf20Sopenharmony_ci#define SPDIFI_SCB_INST 0xBB0 1028c2ecf20Sopenharmony_ci#define SPDIFO_SCB_INST 0xBC0 1038c2ecf20Sopenharmony_ci#define WRITE_BACK_SPB 0x0D0 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* offsets */ 1068c2ecf20Sopenharmony_ci#define AsyncCIOFIFOPointer 0xd 1078c2ecf20Sopenharmony_ci#define SPDIFOFIFOPointer 0xd 1088c2ecf20Sopenharmony_ci#define SPDIFIFIFOPointer 0xd 1098c2ecf20Sopenharmony_ci#define TCBData 0xb 1108c2ecf20Sopenharmony_ci#define HFGFlags 0xa 1118c2ecf20Sopenharmony_ci#define TCBContextBlk 0x10 1128c2ecf20Sopenharmony_ci#define AFGTxAccumPhi 0x4 1138c2ecf20Sopenharmony_ci#define SCBsubListPtr 0x9 1148c2ecf20Sopenharmony_ci#define SCBfuncEntryPtr 0xA 1158c2ecf20Sopenharmony_ci#define SRCCorPerGof 0x2 1168c2ecf20Sopenharmony_ci#define SRCPhiIncr6Int26Frac 0xd 1178c2ecf20Sopenharmony_ci#define SCBVolumeCtrl 0xe 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* conf */ 1208c2ecf20Sopenharmony_ci#define UseASER1Input 1 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci/* 1258c2ecf20Sopenharmony_ci * The following defines are for the flags in the rsConfig01/23 registers of 1268c2ecf20Sopenharmony_ci * the SP. 1278c2ecf20Sopenharmony_ci */ 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_SIZE_MASK 0x0000000FL 1308c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_16 0x00000001L 1318c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_32 0x00000002L 1328c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_64 0x00000003L 1338c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_128 0x00000004L 1348c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_256 0x00000005L 1358c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_512 0x00000006L 1368c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_1024 0x00000007L 1378c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_4 0x00000008L 1388c2ecf20Sopenharmony_ci#define RSCONFIG_MODULO_8 0x00000009L 1398c2ecf20Sopenharmony_ci#define RSCONFIG_SAMPLE_SIZE_MASK 0x000000C0L 1408c2ecf20Sopenharmony_ci#define RSCONFIG_SAMPLE_8MONO 0x00000000L 1418c2ecf20Sopenharmony_ci#define RSCONFIG_SAMPLE_8STEREO 0x00000040L 1428c2ecf20Sopenharmony_ci#define RSCONFIG_SAMPLE_16MONO 0x00000080L 1438c2ecf20Sopenharmony_ci#define RSCONFIG_SAMPLE_16STEREO 0x000000C0L 1448c2ecf20Sopenharmony_ci#define RSCONFIG_UNDERRUN_ZERO 0x00004000L 1458c2ecf20Sopenharmony_ci#define RSCONFIG_DMA_TO_HOST 0x00008000L 1468c2ecf20Sopenharmony_ci#define RSCONFIG_STREAM_NUM_MASK 0x00FF0000L 1478c2ecf20Sopenharmony_ci#define RSCONFIG_MAX_DMA_SIZE_MASK 0x1F000000L 1488c2ecf20Sopenharmony_ci#define RSCONFIG_DMA_ENABLE 0x20000000L 1498c2ecf20Sopenharmony_ci#define RSCONFIG_PRIORITY_MASK 0xC0000000L 1508c2ecf20Sopenharmony_ci#define RSCONFIG_PRIORITY_HIGH 0x00000000L 1518c2ecf20Sopenharmony_ci#define RSCONFIG_PRIORITY_MEDIUM_HIGH 0x40000000L 1528c2ecf20Sopenharmony_ci#define RSCONFIG_PRIORITY_MEDIUM_LOW 0x80000000L 1538c2ecf20Sopenharmony_ci#define RSCONFIG_PRIORITY_LOW 0xC0000000L 1548c2ecf20Sopenharmony_ci#define RSCONFIG_STREAM_NUM_SHIFT 16L 1558c2ecf20Sopenharmony_ci#define RSCONFIG_MAX_DMA_SIZE_SHIFT 24L 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci/* SP constants */ 1588c2ecf20Sopenharmony_ci#define FG_INTERVAL_TIMER_PERIOD 0x0051 1598c2ecf20Sopenharmony_ci#define BG_INTERVAL_TIMER_PERIOD 0x0100 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/* Only SP accessible registers */ 1638c2ecf20Sopenharmony_ci#define SP_ASER_COUNTDOWN 0x8040 1648c2ecf20Sopenharmony_ci#define SP_SPDOUT_FIFO 0x0108 1658c2ecf20Sopenharmony_ci#define SP_SPDIN_MI_FIFO 0x01E0 1668c2ecf20Sopenharmony_ci#define SP_SPDIN_D_FIFO 0x01F0 1678c2ecf20Sopenharmony_ci#define SP_SPDIN_STATUS 0x8048 1688c2ecf20Sopenharmony_ci#define SP_SPDIN_CONTROL 0x8049 1698c2ecf20Sopenharmony_ci#define SP_SPDIN_FIFOPTR 0x804A 1708c2ecf20Sopenharmony_ci#define SP_SPDOUT_STATUS 0x804C 1718c2ecf20Sopenharmony_ci#define SP_SPDOUT_CONTROL 0x804D 1728c2ecf20Sopenharmony_ci#define SP_SPDOUT_CSUV 0x808E 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic inline u8 _wrap_all_bits (u8 val) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci u8 wrapped; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci /* wrap all 8 bits */ 1798c2ecf20Sopenharmony_ci wrapped = 1808c2ecf20Sopenharmony_ci ((val & 0x1 ) << 7) | 1818c2ecf20Sopenharmony_ci ((val & 0x2 ) << 5) | 1828c2ecf20Sopenharmony_ci ((val & 0x4 ) << 3) | 1838c2ecf20Sopenharmony_ci ((val & 0x8 ) << 1) | 1848c2ecf20Sopenharmony_ci ((val & 0x10) >> 1) | 1858c2ecf20Sopenharmony_ci ((val & 0x20) >> 3) | 1868c2ecf20Sopenharmony_ci ((val & 0x40) >> 5) | 1878c2ecf20Sopenharmony_ci ((val & 0x80) >> 7); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci return wrapped; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip, 1938c2ecf20Sopenharmony_ci struct dsp_scb_descriptor * scb) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci /* update nextSCB and subListPtr in SCB */ 1968c2ecf20Sopenharmony_ci snd_cs46xx_poke(chip, 1978c2ecf20Sopenharmony_ci (scb->address + SCBsubListPtr) << 2, 1988c2ecf20Sopenharmony_ci (scb->sub_list_ptr->address << 0x10) | 1998c2ecf20Sopenharmony_ci (scb->next_scb_ptr->address)); 2008c2ecf20Sopenharmony_ci scb->updated = 1; 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, 2048c2ecf20Sopenharmony_ci struct dsp_scb_descriptor * scb, 2058c2ecf20Sopenharmony_ci u16 left, u16 right) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci unsigned int val = ((0xffff - left) << 16 | (0xffff - right)); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); 2108c2ecf20Sopenharmony_ci snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); 2118c2ecf20Sopenharmony_ci scb->volume_set = 1; 2128c2ecf20Sopenharmony_ci scb->volume[0] = left; 2138c2ecf20Sopenharmony_ci scb->volume[1] = right; 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci#endif /* __DSP_SPOS_H__ */ 2168c2ecf20Sopenharmony_ci#endif /* CONFIG_SND_CS46XX_NEW_DSP */ 217