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