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 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | /* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> * Driver p16v chips * Version: 0.21 * * FEATURES currently supported: * Output fixed at S32_LE, 2 channel to hw:0,0 * Rates: 44.1, 48, 96, 192. * * Changelog: * 0.8 * Use separate card based buffer for periods table. * 0.9 * Use 2 channel output streams instead of 8 channel. * (8 channel output streams might be good for ASIO type output) * Corrected speaker output, so Front -> Front etc. * 0.10 * Fixed missed interrupts. * 0.11 * Add Sound card model number and names. * Add Analog volume controls. * 0.12 * Corrected playback interrupts. Now interrupt per period, instead of half period. * 0.13 * Use single trigger for multichannel. * 0.14 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo. * 0.15 * Force buffer_size / period_size == INTEGER. * 0.16 * Update p16v.c to work with changed alsa api. * 0.17 * Update p16v.c to work with changed alsa api. Removed boot_devs. * 0.18 * Merging with snd-emu10k1 driver. * 0.19 * One stereo channel at 24bit now works. * 0.20 * Added better register defines. * 0.21 * Split from p16v.c * * BUGS: * Some stability problems when unloading the snd-p16v kernel module. * -- * * TODO: * SPDIF out. * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz. * Currently capture fixed at 48000Hz. * * -- * GENERAL INFO: * Model: SB0240 * P16V Chip: CA0151-DBS * Audigy 2 Chip: CA0102-IAT * AC97 Codec: STAC 9721 * ADC: Philips 1361T (Stereo 24bit) * DAC: CS4382-K (8-channel, 24bit, 192Khz) * * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> */ /********************************************************************************************************/ /* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers */ /********************************************************************************************************/ /* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE. * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters. */ /* Initially all registers from 0x00 to 0x3f have zero contents. */ #define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */ /* One list entry: 4 bytes for DMA address, * 4 bytes for period_size << 16. * One list entry is 8 bytes long. * One list entry for each period in the buffer. */ #define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ #define PLAYBACK_UNKNOWN3 0x03 /* Not used */ #define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ #define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */ #define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */ #define PLAYBACK_FIFO_POINTER 0x08 /* Playback FIFO pointer and number of valid sound samples in cache */ #define PLAYBACK_UNKNOWN9 0x09 /* Not used */ #define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */ #define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */ #define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */ #define CAPTURE_FIFO_POINTER 0x13 /* Capture FIFO pointer and number of valid sound samples in cache */ #define CAPTURE_P16V_VOLUME1 0x14 /* Low: Capture volume 0xXXXX3030 */ #define CAPTURE_P16V_VOLUME2 0x15 /* High:Has no effect on capture volume */ #define CAPTURE_P16V_SOURCE 0x16 /* P16V source select. Set to 0x0700E4E5 for AC97 CAPTURE */ /* [0:1] Capture input 0 channel select. 0 = Capture output 0. * 1 = Capture output 1. * 2 = Capture output 2. * 3 = Capture output 3. * [3:2] Capture input 1 channel select. 0 = Capture output 0. * 1 = Capture output 1. * 2 = Capture output 2. * 3 = Capture output 3. * [5:4] Capture input 2 channel select. 0 = Capture output 0. * 1 = Capture output 1. * 2 = Capture output 2. * 3 = Capture output 3. * [7:6] Capture input 3 channel select. 0 = Capture output 0. * 1 = Capture output 1. * 2 = Capture output 2. * 3 = Capture output 3. * [9:8] Playback input 0 channel select. 0 = Play output 0. * 1 = Play output 1. * 2 = Play output 2. * 3 = Play output 3. * [11:10] Playback input 1 channel select. 0 = Play output 0. * 1 = Play output 1. * 2 = Play output 2. * 3 = Play output 3. * [13:12] Playback input 2 channel select. 0 = Play output 0. * 1 = Play output 1. * 2 = Play output 2. * 3 = Play output 3. * [15:14] Playback input 3 channel select. 0 = Play output 0. * 1 = Play output 1. * 2 = Play output 2. * 3 = Play output 3. * [19:16] Playback mixer output enable. 1 bit per channel. * [23:20] Capture mixer output enable. 1 bit per channel. * [26:24] FX engine channel capture 0 = 0x60-0x67. * 1 = 0x68-0x6f. * 2 = 0x70-0x77. * 3 = 0x78-0x7f. * 4 = 0x80-0x87. * 5 = 0x88-0x8f. * 6 = 0x90-0x97. * 7 = 0x98-0x9f. * [31:27] Not used. */ /* 0x1 = capture on. * 0x100 = capture off. * 0x200 = capture off. * 0x1000 = capture off. */ #define CAPTURE_RATE_STATUS 0x17 /* Capture sample rate. Read only */ /* [15:0] Not used. * [18:16] Channel 0 Detected sample rate. 0 - 44.1khz * 1 - 48 khz * 2 - 96 khz * 3 - 192 khz * 7 - undefined rate. * [19] Channel 0. 1 - Valid, 0 - Not Valid. * [22:20] Channel 1 Detected sample rate. * [23] Channel 1. 1 - Valid, 0 - Not Valid. * [26:24] Channel 2 Detected sample rate. * [27] Channel 2. 1 - Valid, 0 - Not Valid. * [30:28] Channel 3 Detected sample rate. * [31] Channel 3. 1 - Valid, 0 - Not Valid. */ /* 0x18 - 0x1f unused */ #define PLAYBACK_LAST_SAMPLE 0x20 /* The sample currently being played. Read only */ /* 0x21 - 0x3f unused */ #define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */ /* Playback (0x1<<channel_id) Don't touch high 16bits. */ /* Capture (0x100<<channel_id). not tested */ /* Start Playback [3:0] (one bit per channel) * Start Capture [11:8] (one bit per channel) * Record source select for channel 0 [18:16] * Record source select for channel 1 [22:20] * Record source select for channel 2 [26:24] * Record source select for channel 3 [30:28] * 0 - SPDIF channel. * 1 - I2S channel. * 2 - SRC48 channel. * 3 - SRCMulti_SPDIF channel. * 4 - SRCMulti_I2S channel. * 5 - SPDIF channel. * 6 - fxengine capture. * 7 - AC97 capture. */ /* Default 41110000. * Writing 0xffffffff hangs the PC. * Writing 0xffff0000 -> 77770000 so it must be some sort of route. * bit 0x1 starts DMA playback on channel_id 0 */ /* 0x41,42 take values from 0 - 0xffffffff, but have no effect on playback */ /* 0x43,0x48 do not remember settings */ /* 0x41-45 unused */ #define WATERMARK 0x46 /* Test bit to indicate cache level usage */ /* Values it can have while playing on channel 0. * 0000f000, 0000f004, 0000f008, 0000f00c. * Readonly. */ /* 0x47-0x4f unused */ /* 0x50-0x5f Capture cache data */ #define SRCSel 0x60 /* SRCSel. Default 0x4. Bypass P16V 0x14 */ /* [0] 0 = 10K2 audio, 1 = SRC48 mixer output. * [2] 0 = 10K2 audio, 1 = SRCMulti SPDIF mixer output. * [4] 0 = 10K2 audio, 1 = SRCMulti I2S mixer output. */ /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */ /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */ /* SRC48 and SRCMULTI sample rate select and output select. */ /* 0xffffffff -> 0xC0000015 * 0xXXXXXXX4 = Enable Front Left/Right * Enable PCMs */ /* 0x61 -> 0x6c are Volume controls */ #define PLAYBACK_VOLUME_MIXER1 0x61 /* SRC48 Low to mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER2 0x62 /* SRC48 High to mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER3 0x63 /* SRCMULTI SPDIF Low to mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER4 0x64 /* SRCMULTI SPDIF High to mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER5 0x65 /* SRCMULTI I2S Low to mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER6 0x66 /* SRCMULTI I2S High to mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER7 0x67 /* P16V Low to SRCMULTI SPDIF mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER8 0x68 /* P16V High to SRCMULTI SPDIF mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER9 0x69 /* P16V Low to SRCMULTI I2S mixer input volume control. */ /* 0xXXXX3030 = PCM0 Volume (Front). * 0x3030XXXX = PCM1 Volume (Center) */ #define PLAYBACK_VOLUME_MIXER10 0x6a /* P16V High to SRCMULTI I2S mixer input volume control. */ /* 0x3030XXXX = PCM3 Volume (Rear). */ #define PLAYBACK_VOLUME_MIXER11 0x6b /* E10K2 Low to SRC48 mixer input volume control. */ #define PLAYBACK_VOLUME_MIXER12 0x6c /* E10K2 High to SRC48 mixer input volume control. */ #define SRC48_ENABLE 0x6d /* SRC48 input audio enable */ /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */ /* [23:16] The corresponding P16V channel to SRC48 enabled if == 1. * [31:24] The corresponding E10K2 channel to SRC48 enabled. */ #define SRCMULTI_ENABLE 0x6e /* SRCMulti input audio enable. Default 0xffffffff */ /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */ /* [7:0] The corresponding P16V channel to SRCMulti_I2S enabled if == 1. * [15:8] The corresponding E10K2 channel to SRCMulti I2S enabled. * [23:16] The corresponding P16V channel to SRCMulti SPDIF enabled. * [31:24] The corresponding E10K2 channel to SRCMulti SPDIF enabled. */ /* Bypass P16V 0xff00ff00 * Bitmap. 0 = Off, 1 = On. * P16V playback outputs: * 0xXXXXXXX1 = PCM0 Left. (Front) * 0xXXXXXXX2 = PCM0 Right. * 0xXXXXXXX4 = PCM1 Left. (Center/LFE) * 0xXXXXXXX8 = PCM1 Right. * 0xXXXXXX1X = PCM2 Left. (Unknown) * 0xXXXXXX2X = PCM2 Right. * 0xXXXXXX4X = PCM3 Left. (Rear) * 0xXXXXXX8X = PCM3 Right. */ #define AUDIO_OUT_ENABLE 0x6f /* Default: 000100FF */ /* [3:0] Does something, but not documented. Probably capture enable. * [7:4] Playback channels enable. not documented. * [16] AC97 output enable if == 1 * [30] 0 = SRCMulti_I2S input from fxengine 0x68-0x6f. * 1 = SRCMulti_I2S input from SRC48 output. * [31] 0 = SRCMulti_SPDIF input from fxengine 0x60-0x67. * 1 = SRCMulti_SPDIF input from SRC48 output. */ /* 0xffffffff -> C00100FF */ /* 0 -> Not playback sound, irq still running */ /* 0xXXXXXX10 = PCM0 Left/Right On. (Front) * 0xXXXXXX20 = PCM1 Left/Right On. (Center/LFE) * 0xXXXXXX40 = PCM2 Left/Right On. (Unknown) * 0xXXXXXX80 = PCM3 Left/Right On. (Rear) */ #define PLAYBACK_SPDIF_SELECT 0x70 /* Default: 12030F00 */ /* 0xffffffff -> 3FF30FFF */ /* 0x00000001 pauses stream/irq fail. */ /* All other bits do not effect playback */ #define PLAYBACK_SPDIF_SRC_SELECT 0x71 /* Default: 0000E4E4 */ /* 0xffffffff -> F33FFFFF */ /* All bits do not effect playback */ #define PLAYBACK_SPDIF_USER_DATA0 0x72 /* SPDIF out user data 0 */ #define PLAYBACK_SPDIF_USER_DATA1 0x73 /* SPDIF out user data 1 */ /* 0x74-0x75 unknown */ #define CAPTURE_SPDIF_CONTROL 0x76 /* SPDIF in control setting */ #define CAPTURE_SPDIF_STATUS 0x77 /* SPDIF in status */ #define CAPURE_SPDIF_USER_DATA0 0x78 /* SPDIF in user data 0 */ #define CAPURE_SPDIF_USER_DATA1 0x79 /* SPDIF in user data 1 */ #define CAPURE_SPDIF_USER_DATA2 0x7a /* SPDIF in user data 2 */ |