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