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 initally 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/slab.h> 67 #include <linux/moduleparam.h> 68 #include <sound/core.h> 69 #include <sound/initval.h> 70 #include <sound/pcm.h> 71 #include <sound/ac97_codec.h> 72 #include <sound/info.h> 73 #include <sound/asoundef.h> 74 #include <asm/io.h> 75 76 #include "ca0106.h" 77 78 79 #ifdef CONFIG_PROC_FS 80 81 struct snd_ca0106_category_str { 82 int val; 83 const char *name; 84 }; 85 86 static struct snd_ca0106_category_str snd_ca0106_con_category[] = { 87 { IEC958_AES1_CON_DAT, "DAT" }, 88 { IEC958_AES1_CON_VCR, "VCR" }, 89 { IEC958_AES1_CON_MICROPHONE, "microphone" }, 90 { IEC958_AES1_CON_SYNTHESIZER, "synthesizer" }, 91 { IEC958_AES1_CON_RATE_CONVERTER, "rate converter" }, 92 { IEC958_AES1_CON_MIXER, "mixer" }, 93 { IEC958_AES1_CON_SAMPLER, "sampler" }, 94 { IEC958_AES1_CON_PCM_CODER, "PCM coder" }, 95 { IEC958_AES1_CON_IEC908_CD, "CD" }, 96 { IEC958_AES1_CON_NON_IEC908_CD, "non-IEC908 CD" }, 97 { IEC958_AES1_CON_GENERAL, "general" }, 98 }; 99 100 101 static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 value) 102 { 103 int i; 104 u32 status[4]; 105 status[0] = value & 0xff; 106 status[1] = (value >> 8) & 0xff; 107 status[2] = (value >> 16) & 0xff; 108 status[3] = (value >> 24) & 0xff; 109 110 if (! (status[0] & IEC958_AES0_PROFESSIONAL)) { 111 /* consumer */ 112 snd_iprintf(buffer, "Mode: consumer\n"); 113 snd_iprintf(buffer, "Data: "); 114 if (!(status[0] & IEC958_AES0_NONAUDIO)) { 115 snd_iprintf(buffer, "audio\n"); 116 } else { 117 snd_iprintf(buffer, "non-audio\n"); 118 } 119 snd_iprintf(buffer, "Rate: "); 120 switch (status[3] & IEC958_AES3_CON_FS) { 121 case IEC958_AES3_CON_FS_44100: 122 snd_iprintf(buffer, "44100 Hz\n"); 123 break; 124 case IEC958_AES3_CON_FS_48000: 125 snd_iprintf(buffer, "48000 Hz\n"); 126 break; 127 case IEC958_AES3_CON_FS_32000: 128 snd_iprintf(buffer, "32000 Hz\n"); 129 break; 130 default: 131 snd_iprintf(buffer, "unknown\n"); 132 break; 133 } 134 snd_iprintf(buffer, "Copyright: "); 135 if (status[0] & IEC958_AES0_CON_NOT_COPYRIGHT) { 136 snd_iprintf(buffer, "permitted\n"); 137 } else { 138 snd_iprintf(buffer, "protected\n"); 139 } 140 snd_iprintf(buffer, "Emphasis: "); 141 if ((status[0] & IEC958_AES0_CON_EMPHASIS) != IEC958_AES0_CON_EMPHASIS_5015) { 142 snd_iprintf(buffer, "none\n"); 143 } else { 144 snd_iprintf(buffer, "50/15us\n"); 145 } 146 snd_iprintf(buffer, "Category: "); 147 for (i = 0; i < ARRAY_SIZE(snd_ca0106_con_category); i++) { 148 if ((status[1] & IEC958_AES1_CON_CATEGORY) == snd_ca0106_con_category[i].val) { 149 snd_iprintf(buffer, "%s\n", snd_ca0106_con_category[i].name); 150 break; 151 } 152 } 153 if (i >= ARRAY_SIZE(snd_ca0106_con_category)) { 154 snd_iprintf(buffer, "unknown 0x%x\n", status[1] & IEC958_AES1_CON_CATEGORY); 155 } 156 snd_iprintf(buffer, "Original: "); 157 if (status[1] & IEC958_AES1_CON_ORIGINAL) { 158 snd_iprintf(buffer, "original\n"); 159 } else { 160 snd_iprintf(buffer, "1st generation\n"); 161 } 162 snd_iprintf(buffer, "Clock: "); 163 switch (status[3] & IEC958_AES3_CON_CLOCK) { 164 case IEC958_AES3_CON_CLOCK_1000PPM: 165 snd_iprintf(buffer, "1000 ppm\n"); 166 break; 167 case IEC958_AES3_CON_CLOCK_50PPM: 168 snd_iprintf(buffer, "50 ppm\n"); 169 break; 170 case IEC958_AES3_CON_CLOCK_VARIABLE: 171 snd_iprintf(buffer, "variable pitch\n"); 172 break; 173 default: 174 snd_iprintf(buffer, "unknown\n"); 175 break; 176 } 177 } else { 178 snd_iprintf(buffer, "Mode: professional\n"); 179 snd_iprintf(buffer, "Data: "); 180 if (!(status[0] & IEC958_AES0_NONAUDIO)) { 181 snd_iprintf(buffer, "audio\n"); 182 } else { 183 snd_iprintf(buffer, "non-audio\n"); 184 } 185 snd_iprintf(buffer, "Rate: "); 186 switch (status[0] & IEC958_AES0_PRO_FS) { 187 case IEC958_AES0_PRO_FS_44100: 188 snd_iprintf(buffer, "44100 Hz\n"); 189 break; 190 case IEC958_AES0_PRO_FS_48000: 191 snd_iprintf(buffer, "48000 Hz\n"); 192 break; 193 case IEC958_AES0_PRO_FS_32000: 194 snd_iprintf(buffer, "32000 Hz\n"); 195 break; 196 default: 197 snd_iprintf(buffer, "unknown\n"); 198 break; 199 } 200 snd_iprintf(buffer, "Rate Locked: "); 201 if (status[0] & IEC958_AES0_PRO_FREQ_UNLOCKED) 202 snd_iprintf(buffer, "no\n"); 203 else 204 snd_iprintf(buffer, "yes\n"); 205 snd_iprintf(buffer, "Emphasis: "); 206 switch (status[0] & IEC958_AES0_PRO_EMPHASIS) { 207 case IEC958_AES0_PRO_EMPHASIS_CCITT: 208 snd_iprintf(buffer, "CCITT J.17\n"); 209 break; 210 case IEC958_AES0_PRO_EMPHASIS_NONE: 211 snd_iprintf(buffer, "none\n"); 212 break; 213 case IEC958_AES0_PRO_EMPHASIS_5015: 214 snd_iprintf(buffer, "50/15us\n"); 215 break; 216 case IEC958_AES0_PRO_EMPHASIS_NOTID: 217 default: 218 snd_iprintf(buffer, "unknown\n"); 219 break; 220 } 221 snd_iprintf(buffer, "Stereophonic: "); 222 if ((status[1] & IEC958_AES1_PRO_MODE) == IEC958_AES1_PRO_MODE_STEREOPHONIC) { 223 snd_iprintf(buffer, "stereo\n"); 224 } else { 225 snd_iprintf(buffer, "not indicated\n"); 226 } 227 snd_iprintf(buffer, "Userbits: "); 228 switch (status[1] & IEC958_AES1_PRO_USERBITS) { 229 case IEC958_AES1_PRO_USERBITS_192: 230 snd_iprintf(buffer, "192bit\n"); 231 break; 232 case IEC958_AES1_PRO_USERBITS_UDEF: 233 snd_iprintf(buffer, "user-defined\n"); 234 break; 235 default: 236 snd_iprintf(buffer, "unknown\n"); 237 break; 238 } 239 snd_iprintf(buffer, "Sample Bits: "); 240 switch (status[2] & IEC958_AES2_PRO_SBITS) { 241 case IEC958_AES2_PRO_SBITS_20: 242 snd_iprintf(buffer, "20 bit\n"); 243 break; 244 case IEC958_AES2_PRO_SBITS_24: 245 snd_iprintf(buffer, "24 bit\n"); 246 break; 247 case IEC958_AES2_PRO_SBITS_UDEF: 248 snd_iprintf(buffer, "user defined\n"); 249 break; 250 default: 251 snd_iprintf(buffer, "unknown\n"); 252 break; 253 } 254 snd_iprintf(buffer, "Word Length: "); 255 switch (status[2] & IEC958_AES2_PRO_WORDLEN) { 256 case IEC958_AES2_PRO_WORDLEN_22_18: 257 snd_iprintf(buffer, "22 bit or 18 bit\n"); 258 break; 259 case IEC958_AES2_PRO_WORDLEN_23_19: 260 snd_iprintf(buffer, "23 bit or 19 bit\n"); 261 break; 262 case IEC958_AES2_PRO_WORDLEN_24_20: 263 snd_iprintf(buffer, "24 bit or 20 bit\n"); 264 break; 265 case IEC958_AES2_PRO_WORDLEN_20_16: 266 snd_iprintf(buffer, "20 bit or 16 bit\n"); 267 break; 268 default: 269 snd_iprintf(buffer, "unknown\n"); 270 break; 271 } 272 } 273 } 274 275 static void snd_ca0106_proc_iec958(struct snd_info_entry *entry, 276 struct snd_info_buffer *buffer) 277 { 278 struct snd_ca0106 *emu = entry->private_data; 279 u32 value; 280 281 value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0); 282 snd_iprintf(buffer, "Status: %s, %s, %s\n", 283 (value & 0x100000) ? "Rate Locked" : "Not Rate Locked", 284 (value & 0x200000) ? "SPDIF Locked" : "No SPDIF Lock", 285 (value & 0x400000) ? "Audio Valid" : "No valid audio" ); 286 snd_iprintf(buffer, "Estimated sample rate: %u\n", 287 ((value & 0xfffff) * 48000) / 0x8000 ); 288 if (value & 0x200000) { 289 snd_iprintf(buffer, "IEC958/SPDIF input status:\n"); 290 value = snd_ca0106_ptr_read(emu, SPDIF_INPUT_STATUS, 0); 291 snd_ca0106_proc_dump_iec958(buffer, value); 292 } 293 294 snd_iprintf(buffer, "\n"); 295 } 296 297 static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry, 298 struct snd_info_buffer *buffer) 299 { 300 struct snd_ca0106 *emu = entry->private_data; 301 unsigned long flags; 302 char line[64]; 303 u32 reg, val; 304 while (!snd_info_get_line(buffer, line, sizeof(line))) { 305 if (sscanf(line, "%x %x", ®, &val) != 2) 306 continue; 307 if (reg < 0x40 && val <= 0xffffffff) { 308 spin_lock_irqsave(&emu->emu_lock, flags); 309 outl(val, emu->port + (reg & 0xfffffffc)); 310 spin_unlock_irqrestore(&emu->emu_lock, flags); 311 } 312 } 313 } 314 315 static void snd_ca0106_proc_reg_read32(struct snd_info_entry *entry, 316 struct snd_info_buffer *buffer) 317 { 318 struct snd_ca0106 *emu = entry->private_data; 319 unsigned long value; 320 unsigned long flags; 321 int i; 322 snd_iprintf(buffer, "Registers:\n\n"); 323 for(i = 0; i < 0x20; i+=4) { 324 spin_lock_irqsave(&emu->emu_lock, flags); 325 value = inl(emu->port + i); 326 spin_unlock_irqrestore(&emu->emu_lock, flags); 327 snd_iprintf(buffer, "Register %02X: %08lX\n", i, value); 328 } 329 } 330 331 static void snd_ca0106_proc_reg_read16(struct snd_info_entry *entry, 332 struct snd_info_buffer *buffer) 333 { 334 struct snd_ca0106 *emu = entry->private_data; 335 unsigned int value; 336 unsigned long flags; 337 int i; 338 snd_iprintf(buffer, "Registers:\n\n"); 339 for(i = 0; i < 0x20; i+=2) { 340 spin_lock_irqsave(&emu->emu_lock, flags); 341 value = inw(emu->port + i); 342 spin_unlock_irqrestore(&emu->emu_lock, flags); 343 snd_iprintf(buffer, "Register %02X: %04X\n", i, value); 344 } 345 } 346 347 static void snd_ca0106_proc_reg_read8(struct snd_info_entry *entry, 348 struct snd_info_buffer *buffer) 349 { 350 struct snd_ca0106 *emu = entry->private_data; 351 unsigned int value; 352 unsigned long flags; 353 int i; 354 snd_iprintf(buffer, "Registers:\n\n"); 355 for(i = 0; i < 0x20; i+=1) { 356 spin_lock_irqsave(&emu->emu_lock, flags); 357 value = inb(emu->port + i); 358 spin_unlock_irqrestore(&emu->emu_lock, flags); 359 snd_iprintf(buffer, "Register %02X: %02X\n", i, value); 360 } 361 } 362 363 static void snd_ca0106_proc_reg_read1(struct snd_info_entry *entry, 364 struct snd_info_buffer *buffer) 365 { 366 struct snd_ca0106 *emu = entry->private_data; 367 unsigned long value; 368 int i,j; 369 370 snd_iprintf(buffer, "Registers\n"); 371 for(i = 0; i < 0x40; i++) { 372 snd_iprintf(buffer, "%02X: ",i); 373 for (j = 0; j < 4; j++) { 374 value = snd_ca0106_ptr_read(emu, i, j); 375 snd_iprintf(buffer, "%08lX ", value); 376 } 377 snd_iprintf(buffer, "\n"); 378 } 379 } 380 381 static void snd_ca0106_proc_reg_read2(struct snd_info_entry *entry, 382 struct snd_info_buffer *buffer) 383 { 384 struct snd_ca0106 *emu = entry->private_data; 385 unsigned long value; 386 int i,j; 387 388 snd_iprintf(buffer, "Registers\n"); 389 for(i = 0x40; i < 0x80; i++) { 390 snd_iprintf(buffer, "%02X: ",i); 391 for (j = 0; j < 4; j++) { 392 value = snd_ca0106_ptr_read(emu, i, j); 393 snd_iprintf(buffer, "%08lX ", value); 394 } 395 snd_iprintf(buffer, "\n"); 396 } 397 } 398 399 static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry, 400 struct snd_info_buffer *buffer) 401 { 402 struct snd_ca0106 *emu = entry->private_data; 403 char line[64]; 404 unsigned int reg, channel_id , val; 405 while (!snd_info_get_line(buffer, line, sizeof(line))) { 406 if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) 407 continue; 408 if (reg < 0x80 && val <= 0xffffffff && channel_id <= 3) 409 snd_ca0106_ptr_write(emu, reg, channel_id, val); 410 } 411 } 412 413 static void snd_ca0106_proc_i2c_write(struct snd_info_entry *entry, 414 struct snd_info_buffer *buffer) 415 { 416 struct snd_ca0106 *emu = entry->private_data; 417 char line[64]; 418 unsigned int reg, val; 419 while (!snd_info_get_line(buffer, line, sizeof(line))) { 420 if (sscanf(line, "%x %x", ®, &val) != 2) 421 continue; 422 if ((reg <= 0x7f) || (val <= 0x1ff)) { 423 snd_ca0106_i2c_write(emu, reg, val); 424 } 425 } 426 } 427 428 int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu) 429 { 430 struct snd_info_entry *entry; 431 432 if(! snd_card_proc_new(emu->card, "iec958", &entry)) 433 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_iec958); 434 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) { 435 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read32); 436 entry->c.text.write = snd_ca0106_proc_reg_write32; 437 entry->mode |= S_IWUSR; 438 } 439 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry)) 440 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read16); 441 if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry)) 442 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read8); 443 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) { 444 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read1); 445 entry->c.text.write = snd_ca0106_proc_reg_write; 446 entry->mode |= S_IWUSR; 447 } 448 if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) { 449 entry->c.text.write = snd_ca0106_proc_i2c_write; 450 entry->private_data = emu; 451 entry->mode |= S_IWUSR; 452 } 453 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) 454 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read2); 455 return 0; 456 } 457 458 #endif /* CONFIG_PROC_FS */ 459