1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk> 4 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit 5 * Version: 0.0.18 6 * 7 * FEATURES currently supported: 8 * See ca0106_main.c for features. 9 * 10 * Changelog: 11 * Support interrupts per period. 12 * Removed noise from Center/LFE channel when in Analog mode. 13 * Rename and remove mixer controls. 14 * 0.0.6 15 * Use separate card based DMA buffer for periods table list. 16 * 0.0.7 17 * Change remove and rename ctrls into lists. 18 * 0.0.8 19 * Try to fix capture sources. 20 * 0.0.9 21 * Fix AC3 output. 22 * Enable S32_LE format support. 23 * 0.0.10 24 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".) 25 * 0.0.11 26 * Add Model name recognition. 27 * 0.0.12 28 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period. 29 * Remove redundent "voice" handling. 30 * 0.0.13 31 * Single trigger call for multi channels. 32 * 0.0.14 33 * Set limits based on what the sound card hardware can do. 34 * playback periods_min=2, periods_max=8 35 * capture hw constraints require period_size = n * 64 bytes. 36 * playback hw constraints require period_size = n * 64 bytes. 37 * 0.0.15 38 * Separate ca0106.c into separate functional .c files. 39 * 0.0.16 40 * Modified Copyright message. 41 * 0.0.17 42 * Add iec958 file in proc file system to show status of SPDIF in. 43 * 0.0.18 44 * Implement support for Line-in capture on SB Live 24bit. 45 * 46 * This code was initially based on code from ALSA's emu10k1x.c which is: 47 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 48 */ 49 #include <linux/delay.h> 50 #include <linux/init.h> 51 #include <linux/interrupt.h> 52 #include <linux/moduleparam.h> 53 #include <linux/io.h> 54 #include <sound/core.h> 55 #include <sound/initval.h> 56 #include <sound/pcm.h> 57 #include <sound/ac97_codec.h> 58 #include <sound/info.h> 59 #include <sound/asoundef.h> 60 61 #include "ca0106.h" 62 63 64 struct snd_ca0106_category_str { 65 int val; 66 const char *name; 67 }; 68 69 static const struct snd_ca0106_category_str snd_ca0106_con_category[] = { 70 { IEC958_AES1_CON_DAT, "DAT" }, 71 { IEC958_AES1_CON_VCR, "VCR" }, 72 { IEC958_AES1_CON_MICROPHONE, "microphone" }, 73 { IEC958_AES1_CON_SYNTHESIZER, "synthesizer" }, 74 { IEC958_AES1_CON_RATE_CONVERTER, "rate converter" }, 75 { IEC958_AES1_CON_MIXER, "mixer" }, 76 { IEC958_AES1_CON_SAMPLER, "sampler" }, 77 { IEC958_AES1_CON_PCM_CODER, "PCM coder" }, 78 { IEC958_AES1_CON_IEC908_CD, "CD" }, 79 { IEC958_AES1_CON_NON_IEC908_CD, "non-IEC908 CD" }, 80 { IEC958_AES1_CON_GENERAL, "general" }, 81 }; 82 83 84 static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 value) 85 { 86 int i; 87 u32 status[4]; 88 status[0] = value & 0xff; 89 status[1] = (value >> 8) & 0xff; 90 status[2] = (value >> 16) & 0xff; 91 status[3] = (value >> 24) & 0xff; 92 93 if (! (status[0] & IEC958_AES0_PROFESSIONAL)) { 94 /* consumer */ 95 snd_iprintf(buffer, "Mode: consumer\n"); 96 snd_iprintf(buffer, "Data: "); 97 if (!(status[0] & IEC958_AES0_NONAUDIO)) { 98 snd_iprintf(buffer, "audio\n"); 99 } else { 100 snd_iprintf(buffer, "non-audio\n"); 101 } 102 snd_iprintf(buffer, "Rate: "); 103 switch (status[3] & IEC958_AES3_CON_FS) { 104 case IEC958_AES3_CON_FS_44100: 105 snd_iprintf(buffer, "44100 Hz\n"); 106 break; 107 case IEC958_AES3_CON_FS_48000: 108 snd_iprintf(buffer, "48000 Hz\n"); 109 break; 110 case IEC958_AES3_CON_FS_32000: 111 snd_iprintf(buffer, "32000 Hz\n"); 112 break; 113 default: 114 snd_iprintf(buffer, "unknown\n"); 115 break; 116 } 117 snd_iprintf(buffer, "Copyright: "); 118 if (status[0] & IEC958_AES0_CON_NOT_COPYRIGHT) { 119 snd_iprintf(buffer, "permitted\n"); 120 } else { 121 snd_iprintf(buffer, "protected\n"); 122 } 123 snd_iprintf(buffer, "Emphasis: "); 124 if ((status[0] & IEC958_AES0_CON_EMPHASIS) != IEC958_AES0_CON_EMPHASIS_5015) { 125 snd_iprintf(buffer, "none\n"); 126 } else { 127 snd_iprintf(buffer, "50/15us\n"); 128 } 129 snd_iprintf(buffer, "Category: "); 130 for (i = 0; i < ARRAY_SIZE(snd_ca0106_con_category); i++) { 131 if ((status[1] & IEC958_AES1_CON_CATEGORY) == snd_ca0106_con_category[i].val) { 132 snd_iprintf(buffer, "%s\n", snd_ca0106_con_category[i].name); 133 break; 134 } 135 } 136 if (i >= ARRAY_SIZE(snd_ca0106_con_category)) { 137 snd_iprintf(buffer, "unknown 0x%x\n", status[1] & IEC958_AES1_CON_CATEGORY); 138 } 139 snd_iprintf(buffer, "Original: "); 140 if (status[1] & IEC958_AES1_CON_ORIGINAL) { 141 snd_iprintf(buffer, "original\n"); 142 } else { 143 snd_iprintf(buffer, "1st generation\n"); 144 } 145 snd_iprintf(buffer, "Clock: "); 146 switch (status[3] & IEC958_AES3_CON_CLOCK) { 147 case IEC958_AES3_CON_CLOCK_1000PPM: 148 snd_iprintf(buffer, "1000 ppm\n"); 149 break; 150 case IEC958_AES3_CON_CLOCK_50PPM: 151 snd_iprintf(buffer, "50 ppm\n"); 152 break; 153 case IEC958_AES3_CON_CLOCK_VARIABLE: 154 snd_iprintf(buffer, "variable pitch\n"); 155 break; 156 default: 157 snd_iprintf(buffer, "unknown\n"); 158 break; 159 } 160 } else { 161 snd_iprintf(buffer, "Mode: professional\n"); 162 snd_iprintf(buffer, "Data: "); 163 if (!(status[0] & IEC958_AES0_NONAUDIO)) { 164 snd_iprintf(buffer, "audio\n"); 165 } else { 166 snd_iprintf(buffer, "non-audio\n"); 167 } 168 snd_iprintf(buffer, "Rate: "); 169 switch (status[0] & IEC958_AES0_PRO_FS) { 170 case IEC958_AES0_PRO_FS_44100: 171 snd_iprintf(buffer, "44100 Hz\n"); 172 break; 173 case IEC958_AES0_PRO_FS_48000: 174 snd_iprintf(buffer, "48000 Hz\n"); 175 break; 176 case IEC958_AES0_PRO_FS_32000: 177 snd_iprintf(buffer, "32000 Hz\n"); 178 break; 179 default: 180 snd_iprintf(buffer, "unknown\n"); 181 break; 182 } 183 snd_iprintf(buffer, "Rate Locked: "); 184 if (status[0] & IEC958_AES0_PRO_FREQ_UNLOCKED) 185 snd_iprintf(buffer, "no\n"); 186 else 187 snd_iprintf(buffer, "yes\n"); 188 snd_iprintf(buffer, "Emphasis: "); 189 switch (status[0] & IEC958_AES0_PRO_EMPHASIS) { 190 case IEC958_AES0_PRO_EMPHASIS_CCITT: 191 snd_iprintf(buffer, "CCITT J.17\n"); 192 break; 193 case IEC958_AES0_PRO_EMPHASIS_NONE: 194 snd_iprintf(buffer, "none\n"); 195 break; 196 case IEC958_AES0_PRO_EMPHASIS_5015: 197 snd_iprintf(buffer, "50/15us\n"); 198 break; 199 case IEC958_AES0_PRO_EMPHASIS_NOTID: 200 default: 201 snd_iprintf(buffer, "unknown\n"); 202 break; 203 } 204 snd_iprintf(buffer, "Stereophonic: "); 205 if ((status[1] & IEC958_AES1_PRO_MODE) == IEC958_AES1_PRO_MODE_STEREOPHONIC) { 206 snd_iprintf(buffer, "stereo\n"); 207 } else { 208 snd_iprintf(buffer, "not indicated\n"); 209 } 210 snd_iprintf(buffer, "Userbits: "); 211 switch (status[1] & IEC958_AES1_PRO_USERBITS) { 212 case IEC958_AES1_PRO_USERBITS_192: 213 snd_iprintf(buffer, "192bit\n"); 214 break; 215 case IEC958_AES1_PRO_USERBITS_UDEF: 216 snd_iprintf(buffer, "user-defined\n"); 217 break; 218 default: 219 snd_iprintf(buffer, "unknown\n"); 220 break; 221 } 222 snd_iprintf(buffer, "Sample Bits: "); 223 switch (status[2] & IEC958_AES2_PRO_SBITS) { 224 case IEC958_AES2_PRO_SBITS_20: 225 snd_iprintf(buffer, "20 bit\n"); 226 break; 227 case IEC958_AES2_PRO_SBITS_24: 228 snd_iprintf(buffer, "24 bit\n"); 229 break; 230 case IEC958_AES2_PRO_SBITS_UDEF: 231 snd_iprintf(buffer, "user defined\n"); 232 break; 233 default: 234 snd_iprintf(buffer, "unknown\n"); 235 break; 236 } 237 snd_iprintf(buffer, "Word Length: "); 238 switch (status[2] & IEC958_AES2_PRO_WORDLEN) { 239 case IEC958_AES2_PRO_WORDLEN_22_18: 240 snd_iprintf(buffer, "22 bit or 18 bit\n"); 241 break; 242 case IEC958_AES2_PRO_WORDLEN_23_19: 243 snd_iprintf(buffer, "23 bit or 19 bit\n"); 244 break; 245 case IEC958_AES2_PRO_WORDLEN_24_20: 246 snd_iprintf(buffer, "24 bit or 20 bit\n"); 247 break; 248 case IEC958_AES2_PRO_WORDLEN_20_16: 249 snd_iprintf(buffer, "20 bit or 16 bit\n"); 250 break; 251 default: 252 snd_iprintf(buffer, "unknown\n"); 253 break; 254 } 255 } 256 } 257 258 static void snd_ca0106_proc_iec958(struct snd_info_entry *entry, 259 struct snd_info_buffer *buffer) 260 { 261 struct snd_ca0106 *emu = entry->private_data; 262 u32 value; 263 264 value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0); 265 snd_iprintf(buffer, "Status: %s, %s, %s\n", 266 (value & 0x100000) ? "Rate Locked" : "Not Rate Locked", 267 (value & 0x200000) ? "SPDIF Locked" : "No SPDIF Lock", 268 (value & 0x400000) ? "Audio Valid" : "No valid audio" ); 269 snd_iprintf(buffer, "Estimated sample rate: %u\n", 270 ((value & 0xfffff) * 48000) / 0x8000 ); 271 if (value & 0x200000) { 272 snd_iprintf(buffer, "IEC958/SPDIF input status:\n"); 273 value = snd_ca0106_ptr_read(emu, SPDIF_INPUT_STATUS, 0); 274 snd_ca0106_proc_dump_iec958(buffer, value); 275 } 276 277 snd_iprintf(buffer, "\n"); 278 } 279 280 static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry, 281 struct snd_info_buffer *buffer) 282 { 283 struct snd_ca0106 *emu = entry->private_data; 284 char line[64]; 285 u32 reg, val; 286 while (!snd_info_get_line(buffer, line, sizeof(line))) { 287 if (sscanf(line, "%x %x", ®, &val) != 2) 288 continue; 289 if (reg < 0x40 && val <= 0xffffffff) { 290 guard(spinlock_irqsave)(&emu->emu_lock); 291 outl(val, emu->port + (reg & 0xfffffffc)); 292 } 293 } 294 } 295 296 static void snd_ca0106_proc_reg_read32(struct snd_info_entry *entry, 297 struct snd_info_buffer *buffer) 298 { 299 struct snd_ca0106 *emu = entry->private_data; 300 unsigned long value; 301 int i; 302 303 snd_iprintf(buffer, "Registers:\n\n"); 304 for(i = 0; i < 0x20; i+=4) { 305 scoped_guard(spinlock_irqsave, &emu->emu_lock) { 306 value = inl(emu->port + i); 307 } 308 snd_iprintf(buffer, "Register %02X: %08lX\n", i, value); 309 } 310 } 311 312 static void snd_ca0106_proc_reg_read16(struct snd_info_entry *entry, 313 struct snd_info_buffer *buffer) 314 { 315 struct snd_ca0106 *emu = entry->private_data; 316 unsigned int value; 317 int i; 318 319 snd_iprintf(buffer, "Registers:\n\n"); 320 for(i = 0; i < 0x20; i+=2) { 321 scoped_guard(spinlock_irqsave, &emu->emu_lock) { 322 value = inw(emu->port + i); 323 } 324 snd_iprintf(buffer, "Register %02X: %04X\n", i, value); 325 } 326 } 327 328 static void snd_ca0106_proc_reg_read8(struct snd_info_entry *entry, 329 struct snd_info_buffer *buffer) 330 { 331 struct snd_ca0106 *emu = entry->private_data; 332 unsigned int value; 333 int i; 334 335 snd_iprintf(buffer, "Registers:\n\n"); 336 for(i = 0; i < 0x20; i+=1) { 337 scoped_guard(spinlock_irqsave, &emu->emu_lock) { 338 value = inb(emu->port + i); 339 } 340 snd_iprintf(buffer, "Register %02X: %02X\n", i, value); 341 } 342 } 343 344 static void snd_ca0106_proc_reg_read1(struct snd_info_entry *entry, 345 struct snd_info_buffer *buffer) 346 { 347 struct snd_ca0106 *emu = entry->private_data; 348 unsigned long value; 349 int i,j; 350 351 snd_iprintf(buffer, "Registers\n"); 352 for(i = 0; i < 0x40; i++) { 353 snd_iprintf(buffer, "%02X: ",i); 354 for (j = 0; j < 4; j++) { 355 value = snd_ca0106_ptr_read(emu, i, j); 356 snd_iprintf(buffer, "%08lX ", value); 357 } 358 snd_iprintf(buffer, "\n"); 359 } 360 } 361 362 static void snd_ca0106_proc_reg_read2(struct snd_info_entry *entry, 363 struct snd_info_buffer *buffer) 364 { 365 struct snd_ca0106 *emu = entry->private_data; 366 unsigned long value; 367 int i,j; 368 369 snd_iprintf(buffer, "Registers\n"); 370 for(i = 0x40; i < 0x80; i++) { 371 snd_iprintf(buffer, "%02X: ",i); 372 for (j = 0; j < 4; j++) { 373 value = snd_ca0106_ptr_read(emu, i, j); 374 snd_iprintf(buffer, "%08lX ", value); 375 } 376 snd_iprintf(buffer, "\n"); 377 } 378 } 379 380 static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry, 381 struct snd_info_buffer *buffer) 382 { 383 struct snd_ca0106 *emu = entry->private_data; 384 char line[64]; 385 unsigned int reg, channel_id , val; 386 while (!snd_info_get_line(buffer, line, sizeof(line))) { 387 if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) 388 continue; 389 if (reg < 0x80 && val <= 0xffffffff && channel_id <= 3) 390 snd_ca0106_ptr_write(emu, reg, channel_id, val); 391 } 392 } 393 394 static void snd_ca0106_proc_i2c_write(struct snd_info_entry *entry, 395 struct snd_info_buffer *buffer) 396 { 397 struct snd_ca0106 *emu = entry->private_data; 398 char line[64]; 399 unsigned int reg, val; 400 while (!snd_info_get_line(buffer, line, sizeof(line))) { 401 if (sscanf(line, "%x %x", ®, &val) != 2) 402 continue; 403 if ((reg <= 0x7f) || (val <= 0x1ff)) { 404 snd_ca0106_i2c_write(emu, reg, val); 405 } 406 } 407 } 408 409 int snd_ca0106_proc_init(struct snd_ca0106 *emu) 410 { 411 snd_card_ro_proc_new(emu->card, "iec958", emu, snd_ca0106_proc_iec958); 412 snd_card_rw_proc_new(emu->card, "ca0106_reg32", emu, 413 snd_ca0106_proc_reg_read32, 414 snd_ca0106_proc_reg_write32); 415 snd_card_ro_proc_new(emu->card, "ca0106_reg16", emu, 416 snd_ca0106_proc_reg_read16); 417 snd_card_ro_proc_new(emu->card, "ca0106_reg8", emu, 418 snd_ca0106_proc_reg_read8); 419 snd_card_rw_proc_new(emu->card, "ca0106_regs1", emu, 420 snd_ca0106_proc_reg_read1, 421 snd_ca0106_proc_reg_write); 422 snd_card_rw_proc_new(emu->card, "ca0106_i2c", emu, NULL, 423 snd_ca0106_proc_i2c_write); 424 snd_card_ro_proc_new(emu->card, "ca0106_regs2", emu, 425 snd_ca0106_proc_reg_read2); 426 return 0; 427 } 428