Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | /* SPDX-License-Identifier: GPL-2.0-or-later */ /* * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards * Copyright (c) by Jaroslav Kysela <perex@perex.cz> */ /* * 2002-07 Benny Sjostrand benny@hostmobility.com */ #ifdef CONFIG_SND_CS46XX_NEW_DSP /* hack ... */ #ifndef __DSP_SPOS_H__ #define __DSP_SPOS_H__ #define DSP_MAX_SYMBOLS 1024 #define DSP_MAX_MODULES 64 #define DSP_CODE_BYTE_SIZE 0x00007000UL #define DSP_PARAMETER_BYTE_SIZE 0x00003000UL #define DSP_SAMPLE_BYTE_SIZE 0x00003800UL #define DSP_PARAMETER_BYTE_OFFSET 0x00000000UL #define DSP_SAMPLE_BYTE_OFFSET 0x00010000UL #define DSP_CODE_BYTE_OFFSET 0x00020000UL #define WIDE_INSTR_MASK 0x0040 #define WIDE_LADD_INSTR_MASK 0x0380 /* this instruction types needs to be reallocated when load code into DSP */ enum wide_opcode { WIDE_FOR_BEGIN_LOOP = 0x20, WIDE_FOR_BEGIN_LOOP2, WIDE_COND_GOTO_ADDR = 0x30, WIDE_COND_GOTO_CALL, WIDE_TBEQ_COND_GOTO_ADDR = 0x70, WIDE_TBEQ_COND_CALL_ADDR, WIDE_TBEQ_NCOND_GOTO_ADDR, WIDE_TBEQ_NCOND_CALL_ADDR, WIDE_TBEQ_COND_GOTO1_ADDR, WIDE_TBEQ_COND_CALL1_ADDR, WIDE_TBEQ_NCOND_GOTOI_ADDR, WIDE_TBEQ_NCOND_CALL1_ADDR, }; /* SAMPLE segment */ #define VARI_DECIMATE_BUF1 0x0000 #define WRITE_BACK_BUF1 0x0400 #define CODEC_INPUT_BUF1 0x0500 #define PCM_READER_BUF1 0x0600 #define SRC_DELAY_BUF1 0x0680 #define VARI_DECIMATE_BUF0 0x0780 #define SRC_OUTPUT_BUF1 0x07A0 #define ASYNC_IP_OUTPUT_BUFFER1 0x0A00 #define OUTPUT_SNOOP_BUFFER 0x0B00 #define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00 #define SPDIFO_IP_OUTPUT_BUFFER1 0x1000 #define MIX_SAMPLE_BUF1 0x1400 #define MIX_SAMPLE_BUF2 0x2E80 #define MIX_SAMPLE_BUF3 0x2F00 #define MIX_SAMPLE_BUF4 0x2F80 #define MIX_SAMPLE_BUF5 0x3000 /* Task stack address */ #define HFG_STACK 0x066A #define FG_STACK 0x066E #define BG_STACK 0x068E /* SCB's addresses */ #define SPOSCB_ADDR 0x070 #define BG_TREE_SCB_ADDR 0x635 #define NULL_SCB_ADDR 0x000 #define TIMINGMASTER_SCB_ADDR 0x010 #define CODECOUT_SCB_ADDR 0x020 #define PCMREADER_SCB_ADDR 0x030 #define WRITEBACK_SCB_ADDR 0x040 #define CODECIN_SCB_ADDR 0x080 #define MASTERMIX_SCB_ADDR 0x090 #define SRCTASK_SCB_ADDR 0x0A0 #define VARIDECIMATE_SCB_ADDR 0x0B0 #define PCMSERIALIN_SCB_ADDR 0x0C0 #define FG_TASK_HEADER_ADDR 0x600 #define ASYNCTX_SCB_ADDR 0x0E0 #define ASYNCRX_SCB_ADDR 0x0F0 #define SRCTASKII_SCB_ADDR 0x100 #define OUTPUTSNOOP_SCB_ADDR 0x110 #define PCMSERIALINII_SCB_ADDR 0x120 #define SPIOWRITE_SCB_ADDR 0x130 #define REAR_CODECOUT_SCB_ADDR 0x140 #define OUTPUTSNOOPII_SCB_ADDR 0x150 #define PCMSERIALIN_PCM_SCB_ADDR 0x160 #define RECORD_MIXER_SCB_ADDR 0x170 #define REAR_MIXER_SCB_ADDR 0x180 #define CLFE_MIXER_SCB_ADDR 0x190 #define CLFE_CODEC_SCB_ADDR 0x1A0 /* hyperforground SCB's*/ #define HFG_TREE_SCB 0xBA0 #define SPDIFI_SCB_INST 0xBB0 #define SPDIFO_SCB_INST 0xBC0 #define WRITE_BACK_SPB 0x0D0 /* offsets */ #define AsyncCIOFIFOPointer 0xd #define SPDIFOFIFOPointer 0xd #define SPDIFIFIFOPointer 0xd #define TCBData 0xb #define HFGFlags 0xa #define TCBContextBlk 0x10 #define AFGTxAccumPhi 0x4 #define SCBsubListPtr 0x9 #define SCBfuncEntryPtr 0xA #define SRCCorPerGof 0x2 #define SRCPhiIncr6Int26Frac 0xd #define SCBVolumeCtrl 0xe /* conf */ #define UseASER1Input 1 /* * The following defines are for the flags in the rsConfig01/23 registers of * the SP. */ #define RSCONFIG_MODULO_SIZE_MASK 0x0000000FL #define RSCONFIG_MODULO_16 0x00000001L #define RSCONFIG_MODULO_32 0x00000002L #define RSCONFIG_MODULO_64 0x00000003L #define RSCONFIG_MODULO_128 0x00000004L #define RSCONFIG_MODULO_256 0x00000005L #define RSCONFIG_MODULO_512 0x00000006L #define RSCONFIG_MODULO_1024 0x00000007L #define RSCONFIG_MODULO_4 0x00000008L #define RSCONFIG_MODULO_8 0x00000009L #define RSCONFIG_SAMPLE_SIZE_MASK 0x000000C0L #define RSCONFIG_SAMPLE_8MONO 0x00000000L #define RSCONFIG_SAMPLE_8STEREO 0x00000040L #define RSCONFIG_SAMPLE_16MONO 0x00000080L #define RSCONFIG_SAMPLE_16STEREO 0x000000C0L #define RSCONFIG_UNDERRUN_ZERO 0x00004000L #define RSCONFIG_DMA_TO_HOST 0x00008000L #define RSCONFIG_STREAM_NUM_MASK 0x00FF0000L #define RSCONFIG_MAX_DMA_SIZE_MASK 0x1F000000L #define RSCONFIG_DMA_ENABLE 0x20000000L #define RSCONFIG_PRIORITY_MASK 0xC0000000L #define RSCONFIG_PRIORITY_HIGH 0x00000000L #define RSCONFIG_PRIORITY_MEDIUM_HIGH 0x40000000L #define RSCONFIG_PRIORITY_MEDIUM_LOW 0x80000000L #define RSCONFIG_PRIORITY_LOW 0xC0000000L #define RSCONFIG_STREAM_NUM_SHIFT 16L #define RSCONFIG_MAX_DMA_SIZE_SHIFT 24L /* SP constants */ #define FG_INTERVAL_TIMER_PERIOD 0x0051 #define BG_INTERVAL_TIMER_PERIOD 0x0100 /* Only SP accessible registers */ #define SP_ASER_COUNTDOWN 0x8040 #define SP_SPDOUT_FIFO 0x0108 #define SP_SPDIN_MI_FIFO 0x01E0 #define SP_SPDIN_D_FIFO 0x01F0 #define SP_SPDIN_STATUS 0x8048 #define SP_SPDIN_CONTROL 0x8049 #define SP_SPDIN_FIFOPTR 0x804A #define SP_SPDOUT_STATUS 0x804C #define SP_SPDOUT_CONTROL 0x804D #define SP_SPDOUT_CSUV 0x808E static inline u8 _wrap_all_bits (u8 val) { u8 wrapped; /* wrap all 8 bits */ wrapped = ((val & 0x1 ) << 7) | ((val & 0x2 ) << 5) | ((val & 0x4 ) << 3) | ((val & 0x8 ) << 1) | ((val & 0x10) >> 1) | ((val & 0x20) >> 3) | ((val & 0x40) >> 5) | ((val & 0x80) >> 7); return wrapped; } static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip, struct dsp_scb_descriptor * scb) { /* update nextSCB and subListPtr in SCB */ snd_cs46xx_poke(chip, (scb->address + SCBsubListPtr) << 2, (scb->sub_list_ptr->address << 0x10) | (scb->next_scb_ptr->address)); scb->updated = 1; } static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, struct dsp_scb_descriptor * scb, u16 left, u16 right) { unsigned int val = ((0xffff - left) << 16 | (0xffff - right)); snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); scb->volume_set = 1; scb->volume[0] = left; scb->volume[1] = right; } #endif /* __DSP_SPOS_H__ */ #endif /* CONFIG_SND_CS46XX_NEW_DSP */ |