1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 3 * Creative Labs, Inc. 4 * Routines for control of EMU10K1 chips / proc interface routines 5 * 6 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> 7 * Added EMU 1010 support. 8 * 9 * BUGS: 10 * -- 11 * 12 * TODO: 13 * -- 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 * 29 */ 30 31 #include <sound/driver.h> 32 #include <linux/slab.h> 33 #include <linux/init.h> 34 #include <sound/core.h> 35 #include <sound/emu10k1.h> 36 #include "p16v.h" 37 38 #ifdef CONFIG_PROC_FS 39 static void snd_emu10k1_proc_spdif_status(struct snd_emu10k1 * emu, 40 struct snd_info_buffer *buffer, 41 char *title, 42 int status_reg, 43 int rate_reg) 44 { 45 static char *clkaccy[4] = { "1000ppm", "50ppm", "variable", "unknown" }; 46 static int samplerate[16] = { 44100, 1, 48000, 32000, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 47 static char *channel[16] = { "unspec", "left", "right", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" }; 48 static char *emphasis[8] = { "none", "50/15 usec 2 channel", "2", "3", "4", "5", "6", "7" }; 49 unsigned int status, rate = 0; 50 51 status = snd_emu10k1_ptr_read(emu, status_reg, 0); 52 53 snd_iprintf(buffer, "\n%s\n", title); 54 55 if (status != 0xffffffff) { 56 snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no"); 57 snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no"); 58 snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no"); 59 snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]); 60 snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6); 61 snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8); 62 snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy"); 63 snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16); 64 snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]); 65 snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]); 66 snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]); 67 68 if (rate_reg > 0) { 69 rate = snd_emu10k1_ptr_read(emu, rate_reg, 0); 70 snd_iprintf(buffer, "S/PDIF Valid : %s\n", rate & SRCS_SPDIFVALID ? "on" : "off"); 71 snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off"); 72 snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off"); 73 /* From ((Rate * 48000 ) / 262144); */ 74 snd_iprintf(buffer, "Estimated Sample Rate : %d\n", ((rate & 0xFFFFF ) * 375) >> 11); 75 } 76 } else { 77 snd_iprintf(buffer, "No signal detected.\n"); 78 } 79 80 } 81 82 static void snd_emu10k1_proc_read(struct snd_info_entry *entry, 83 struct snd_info_buffer *buffer) 84 { 85 /* FIXME - output names are in emufx.c too */ 86 static char *creative_outs[32] = { 87 /* 00 */ "AC97 Left", 88 /* 01 */ "AC97 Right", 89 /* 02 */ "Optical IEC958 Left", 90 /* 03 */ "Optical IEC958 Right", 91 /* 04 */ "Center", 92 /* 05 */ "LFE", 93 /* 06 */ "Headphone Left", 94 /* 07 */ "Headphone Right", 95 /* 08 */ "Surround Left", 96 /* 09 */ "Surround Right", 97 /* 10 */ "PCM Capture Left", 98 /* 11 */ "PCM Capture Right", 99 /* 12 */ "MIC Capture", 100 /* 13 */ "AC97 Surround Left", 101 /* 14 */ "AC97 Surround Right", 102 /* 15 */ "???", 103 /* 16 */ "???", 104 /* 17 */ "Analog Center", 105 /* 18 */ "Analog LFE", 106 /* 19 */ "???", 107 /* 20 */ "???", 108 /* 21 */ "???", 109 /* 22 */ "???", 110 /* 23 */ "???", 111 /* 24 */ "???", 112 /* 25 */ "???", 113 /* 26 */ "???", 114 /* 27 */ "???", 115 /* 28 */ "???", 116 /* 29 */ "???", 117 /* 30 */ "???", 118 /* 31 */ "???" 119 }; 120 121 static char *audigy_outs[64] = { 122 /* 00 */ "Digital Front Left", 123 /* 01 */ "Digital Front Right", 124 /* 02 */ "Digital Center", 125 /* 03 */ "Digital LEF", 126 /* 04 */ "Headphone Left", 127 /* 05 */ "Headphone Right", 128 /* 06 */ "Digital Rear Left", 129 /* 07 */ "Digital Rear Right", 130 /* 08 */ "Front Left", 131 /* 09 */ "Front Right", 132 /* 10 */ "Center", 133 /* 11 */ "LFE", 134 /* 12 */ "???", 135 /* 13 */ "???", 136 /* 14 */ "Rear Left", 137 /* 15 */ "Rear Right", 138 /* 16 */ "AC97 Front Left", 139 /* 17 */ "AC97 Front Right", 140 /* 18 */ "ADC Caputre Left", 141 /* 19 */ "ADC Capture Right", 142 /* 20 */ "???", 143 /* 21 */ "???", 144 /* 22 */ "???", 145 /* 23 */ "???", 146 /* 24 */ "???", 147 /* 25 */ "???", 148 /* 26 */ "???", 149 /* 27 */ "???", 150 /* 28 */ "???", 151 /* 29 */ "???", 152 /* 30 */ "???", 153 /* 31 */ "???", 154 /* 32 */ "FXBUS2_0", 155 /* 33 */ "FXBUS2_1", 156 /* 34 */ "FXBUS2_2", 157 /* 35 */ "FXBUS2_3", 158 /* 36 */ "FXBUS2_4", 159 /* 37 */ "FXBUS2_5", 160 /* 38 */ "FXBUS2_6", 161 /* 39 */ "FXBUS2_7", 162 /* 40 */ "FXBUS2_8", 163 /* 41 */ "FXBUS2_9", 164 /* 42 */ "FXBUS2_10", 165 /* 43 */ "FXBUS2_11", 166 /* 44 */ "FXBUS2_12", 167 /* 45 */ "FXBUS2_13", 168 /* 46 */ "FXBUS2_14", 169 /* 47 */ "FXBUS2_15", 170 /* 48 */ "FXBUS2_16", 171 /* 49 */ "FXBUS2_17", 172 /* 50 */ "FXBUS2_18", 173 /* 51 */ "FXBUS2_19", 174 /* 52 */ "FXBUS2_20", 175 /* 53 */ "FXBUS2_21", 176 /* 54 */ "FXBUS2_22", 177 /* 55 */ "FXBUS2_23", 178 /* 56 */ "FXBUS2_24", 179 /* 57 */ "FXBUS2_25", 180 /* 58 */ "FXBUS2_26", 181 /* 59 */ "FXBUS2_27", 182 /* 60 */ "FXBUS2_28", 183 /* 61 */ "FXBUS2_29", 184 /* 62 */ "FXBUS2_30", 185 /* 63 */ "FXBUS2_31" 186 }; 187 188 struct snd_emu10k1 *emu = entry->private_data; 189 unsigned int val, val1; 190 int nefx = emu->audigy ? 64 : 32; 191 char **outputs = emu->audigy ? audigy_outs : creative_outs; 192 int idx; 193 194 snd_iprintf(buffer, "EMU10K1\n\n"); 195 snd_iprintf(buffer, "Card : %s\n", 196 emu->audigy ? "Audigy" : (emu->card_capabilities->ecard ? "EMU APS" : "Creative")); 197 snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size); 198 snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2); 199 snd_iprintf(buffer, "\n"); 200 snd_iprintf(buffer, "Effect Send Routing :\n"); 201 for (idx = 0; idx < NUM_G; idx++) { 202 val = emu->audigy ? 203 snd_emu10k1_ptr_read(emu, A_FXRT1, idx) : 204 snd_emu10k1_ptr_read(emu, FXRT, idx); 205 val1 = emu->audigy ? 206 snd_emu10k1_ptr_read(emu, A_FXRT2, idx) : 207 0; 208 if (emu->audigy) { 209 snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i, ", 210 idx, 211 val & 0x3f, 212 (val >> 8) & 0x3f, 213 (val >> 16) & 0x3f, 214 (val >> 24) & 0x3f); 215 snd_iprintf(buffer, "E=%i, F=%i, G=%i, H=%i\n", 216 val1 & 0x3f, 217 (val1 >> 8) & 0x3f, 218 (val1 >> 16) & 0x3f, 219 (val1 >> 24) & 0x3f); 220 } else { 221 snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i\n", 222 idx, 223 (val >> 16) & 0x0f, 224 (val >> 20) & 0x0f, 225 (val >> 24) & 0x0f, 226 (val >> 28) & 0x0f); 227 } 228 } 229 snd_iprintf(buffer, "\nCaptured FX Outputs :\n"); 230 for (idx = 0; idx < nefx; idx++) { 231 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) 232 snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); 233 } 234 snd_iprintf(buffer, "\nAll FX Outputs :\n"); 235 for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++) 236 snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); 237 } 238 239 static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry, 240 struct snd_info_buffer *buffer) 241 { 242 struct snd_emu10k1 *emu = entry->private_data; 243 snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS); 244 snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS); 245 #if 0 246 val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0); 247 snd_iprintf(buffer, "\nZoomed Video\n"); 248 snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off"); 249 snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE); 250 #endif 251 } 252 253 static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry, 254 struct snd_info_buffer *buffer) 255 { 256 static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 }; 257 struct snd_emu10k1 *emu = entry->private_data; 258 unsigned int val, tmp, n; 259 val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); 260 tmp = (val >> 16) & 0x8; 261 for (n = 0; n < 4; n++) { 262 tmp = val >> (16 + (n*4)); 263 if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); 264 else snd_iprintf(buffer, "Channel %d: No input\n", n); 265 } 266 } 267 268 static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry, 269 struct snd_info_buffer *buffer) 270 { 271 u32 pc; 272 struct snd_emu10k1 *emu = entry->private_data; 273 274 snd_iprintf(buffer, "FX8010 Instruction List '%s'\n", emu->fx8010.name); 275 snd_iprintf(buffer, " Code dump :\n"); 276 for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) { 277 u32 low, high; 278 279 low = snd_emu10k1_efx_read(emu, pc * 2); 280 high = snd_emu10k1_efx_read(emu, pc * 2 + 1); 281 if (emu->audigy) 282 snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n", 283 (high >> 24) & 0x0f, 284 (high >> 12) & 0x7ff, 285 (high >> 0) & 0x7ff, 286 (low >> 12) & 0x7ff, 287 (low >> 0) & 0x7ff, 288 pc, 289 high, low); 290 else 291 snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n", 292 (high >> 20) & 0x0f, 293 (high >> 10) & 0x3ff, 294 (high >> 0) & 0x3ff, 295 (low >> 10) & 0x3ff, 296 (low >> 0) & 0x3ff, 297 pc, 298 high, low); 299 } 300 } 301 302 #define TOTAL_SIZE_GPR (0x100*4) 303 #define A_TOTAL_SIZE_GPR (0x200*4) 304 #define TOTAL_SIZE_TANKMEM_DATA (0xa0*4) 305 #define TOTAL_SIZE_TANKMEM_ADDR (0xa0*4) 306 #define A_TOTAL_SIZE_TANKMEM_DATA (0x100*4) 307 #define A_TOTAL_SIZE_TANKMEM_ADDR (0x100*4) 308 #define TOTAL_SIZE_CODE (0x200*8) 309 #define A_TOTAL_SIZE_CODE (0x400*8) 310 311 static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, 312 void *file_private_data, 313 struct file *file, char __user *buf, 314 unsigned long count, unsigned long pos) 315 { 316 long size; 317 struct snd_emu10k1 *emu = entry->private_data; 318 unsigned int offset; 319 int tram_addr = 0; 320 321 if (!strcmp(entry->name, "fx8010_tram_addr")) { 322 offset = TANKMEMADDRREGBASE; 323 tram_addr = 1; 324 } else if (!strcmp(entry->name, "fx8010_tram_data")) { 325 offset = TANKMEMDATAREGBASE; 326 } else if (!strcmp(entry->name, "fx8010_code")) { 327 offset = emu->audigy ? A_MICROCODEBASE : MICROCODEBASE; 328 } else { 329 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; 330 } 331 size = count; 332 if (pos + size > entry->size) 333 size = (long)entry->size - pos; 334 if (size > 0) { 335 unsigned int *tmp; 336 long res; 337 unsigned int idx; 338 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) 339 return -ENOMEM; 340 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) 341 if (tram_addr && emu->audigy) { 342 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11; 343 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20; 344 } else 345 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0); 346 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size)) 347 res = -EFAULT; 348 else { 349 res = size; 350 } 351 kfree(tmp); 352 return res; 353 } 354 return 0; 355 } 356 357 static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, 358 struct snd_info_buffer *buffer) 359 { 360 struct snd_emu10k1 *emu = entry->private_data; 361 struct snd_emu10k1_voice *voice; 362 int idx; 363 364 snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n"); 365 for (idx = 0; idx < NUM_G; idx++) { 366 voice = &emu->voices[idx]; 367 snd_iprintf(buffer, "%i\t%i\t%i\t%i\t%i\t%i\n", 368 idx, 369 voice->use, 370 voice->pcm, 371 voice->efx, 372 voice->synth, 373 voice->midi); 374 } 375 } 376 377 #ifdef CONFIG_SND_DEBUG 378 static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry, 379 struct snd_info_buffer *buffer) 380 { 381 struct snd_emu10k1 *emu = entry->private_data; 382 unsigned long value; 383 unsigned long flags; 384 unsigned long regs; 385 int i; 386 snd_iprintf(buffer, "EMU1010 Registers:\n\n"); 387 388 for(i = 0; i < 0x30; i+=1) { 389 spin_lock_irqsave(&emu->emu_lock, flags); 390 regs=i+0x40; /* 0x40 upwards are registers. */ 391 outl(regs, emu->port + A_IOCFG); 392 outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ 393 value = inl(emu->port + A_IOCFG); 394 spin_unlock_irqrestore(&emu->emu_lock, flags); 395 snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f); 396 } 397 } 398 399 static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry, 400 struct snd_info_buffer *buffer) 401 { 402 struct snd_emu10k1 *emu = entry->private_data; 403 unsigned long value; 404 unsigned long flags; 405 int i; 406 snd_iprintf(buffer, "IO Registers:\n\n"); 407 for(i = 0; i < 0x40; i+=4) { 408 spin_lock_irqsave(&emu->emu_lock, flags); 409 value = inl(emu->port + i); 410 spin_unlock_irqrestore(&emu->emu_lock, flags); 411 snd_iprintf(buffer, "%02X: %08lX\n", i, value); 412 } 413 } 414 415 static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry, 416 struct snd_info_buffer *buffer) 417 { 418 struct snd_emu10k1 *emu = entry->private_data; 419 unsigned long flags; 420 char line[64]; 421 u32 reg, val; 422 while (!snd_info_get_line(buffer, line, sizeof(line))) { 423 if (sscanf(line, "%x %x", ®, &val) != 2) 424 continue; 425 if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) { 426 spin_lock_irqsave(&emu->emu_lock, flags); 427 outl(val, emu->port + (reg & 0xfffffffc)); 428 spin_unlock_irqrestore(&emu->emu_lock, flags); 429 } 430 } 431 } 432 433 static unsigned int snd_ptr_read(struct snd_emu10k1 * emu, 434 unsigned int iobase, 435 unsigned int reg, 436 unsigned int chn) 437 { 438 unsigned long flags; 439 unsigned int regptr, val; 440 441 regptr = (reg << 16) | chn; 442 443 spin_lock_irqsave(&emu->emu_lock, flags); 444 outl(regptr, emu->port + iobase + PTR); 445 val = inl(emu->port + iobase + DATA); 446 spin_unlock_irqrestore(&emu->emu_lock, flags); 447 return val; 448 } 449 450 static void snd_ptr_write(struct snd_emu10k1 *emu, 451 unsigned int iobase, 452 unsigned int reg, 453 unsigned int chn, 454 unsigned int data) 455 { 456 unsigned int regptr; 457 unsigned long flags; 458 459 regptr = (reg << 16) | chn; 460 461 spin_lock_irqsave(&emu->emu_lock, flags); 462 outl(regptr, emu->port + iobase + PTR); 463 outl(data, emu->port + iobase + DATA); 464 spin_unlock_irqrestore(&emu->emu_lock, flags); 465 } 466 467 468 static void snd_emu_proc_ptr_reg_read(struct snd_info_entry *entry, 469 struct snd_info_buffer *buffer, int iobase, int offset, int length, int voices) 470 { 471 struct snd_emu10k1 *emu = entry->private_data; 472 unsigned long value; 473 int i,j; 474 if (offset+length > 0xa0) { 475 snd_iprintf(buffer, "Input values out of range\n"); 476 return; 477 } 478 snd_iprintf(buffer, "Registers 0x%x\n", iobase); 479 for(i = offset; i < offset+length; i++) { 480 snd_iprintf(buffer, "%02X: ",i); 481 for (j = 0; j < voices; j++) { 482 if(iobase == 0) 483 value = snd_ptr_read(emu, 0, i, j); 484 else 485 value = snd_ptr_read(emu, 0x20, i, j); 486 snd_iprintf(buffer, "%08lX ", value); 487 } 488 snd_iprintf(buffer, "\n"); 489 } 490 } 491 492 static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry, 493 struct snd_info_buffer *buffer, int iobase) 494 { 495 struct snd_emu10k1 *emu = entry->private_data; 496 char line[64]; 497 unsigned int reg, channel_id , val; 498 while (!snd_info_get_line(buffer, line, sizeof(line))) { 499 if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) 500 continue; 501 if ((reg < 0xa0) && (reg >= 0) && (val <= 0xffffffff) && (channel_id >= 0) && (channel_id <= 3) ) 502 snd_ptr_write(emu, iobase, reg, channel_id, val); 503 } 504 } 505 506 static void snd_emu_proc_ptr_reg_write00(struct snd_info_entry *entry, 507 struct snd_info_buffer *buffer) 508 { 509 snd_emu_proc_ptr_reg_write(entry, buffer, 0); 510 } 511 512 static void snd_emu_proc_ptr_reg_write20(struct snd_info_entry *entry, 513 struct snd_info_buffer *buffer) 514 { 515 snd_emu_proc_ptr_reg_write(entry, buffer, 0x20); 516 } 517 518 519 static void snd_emu_proc_ptr_reg_read00a(struct snd_info_entry *entry, 520 struct snd_info_buffer *buffer) 521 { 522 snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40, 64); 523 } 524 525 static void snd_emu_proc_ptr_reg_read00b(struct snd_info_entry *entry, 526 struct snd_info_buffer *buffer) 527 { 528 snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40, 64); 529 } 530 531 static void snd_emu_proc_ptr_reg_read20a(struct snd_info_entry *entry, 532 struct snd_info_buffer *buffer) 533 { 534 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40, 4); 535 } 536 537 static void snd_emu_proc_ptr_reg_read20b(struct snd_info_entry *entry, 538 struct snd_info_buffer *buffer) 539 { 540 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40, 4); 541 } 542 543 static void snd_emu_proc_ptr_reg_read20c(struct snd_info_entry *entry, 544 struct snd_info_buffer * buffer) 545 { 546 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x80, 0x20, 4); 547 } 548 #endif 549 550 static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = { 551 .read = snd_emu10k1_fx8010_read, 552 }; 553 554 int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu) 555 { 556 struct snd_info_entry *entry; 557 #ifdef CONFIG_SND_DEBUG 558 if ((emu->card_capabilities->emu1010) && 559 snd_card_proc_new(emu->card, "emu1010_regs", &entry)) { 560 snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read); 561 } 562 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { 563 snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); 564 entry->c.text.write = snd_emu_proc_io_reg_write; 565 entry->mode |= S_IWUSR; 566 } 567 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { 568 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00a); 569 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 570 entry->mode |= S_IWUSR; 571 } 572 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { 573 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00b); 574 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 575 entry->mode |= S_IWUSR; 576 } 577 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { 578 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20a); 579 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 580 entry->mode |= S_IWUSR; 581 } 582 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { 583 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20b); 584 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 585 entry->mode |= S_IWUSR; 586 } 587 if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) { 588 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20c); 589 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 590 entry->mode |= S_IWUSR; 591 } 592 #endif 593 594 if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) 595 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_read); 596 597 if (emu->card_capabilities->emu10k2_chip) { 598 if (! snd_card_proc_new(emu->card, "spdif-in", &entry)) 599 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_spdif_read); 600 } 601 if (emu->card_capabilities->ca0151_chip) { 602 if (! snd_card_proc_new(emu->card, "capture-rates", &entry)) 603 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_rates_read); 604 } 605 606 if (! snd_card_proc_new(emu->card, "voices", &entry)) 607 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_voices_read); 608 609 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) { 610 entry->content = SNDRV_INFO_CONTENT_DATA; 611 entry->private_data = emu; 612 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 613 entry->size = emu->audigy ? A_TOTAL_SIZE_GPR : TOTAL_SIZE_GPR; 614 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 615 } 616 if (! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) { 617 entry->content = SNDRV_INFO_CONTENT_DATA; 618 entry->private_data = emu; 619 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 620 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_DATA : TOTAL_SIZE_TANKMEM_DATA ; 621 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 622 } 623 if (! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) { 624 entry->content = SNDRV_INFO_CONTENT_DATA; 625 entry->private_data = emu; 626 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 627 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_ADDR : TOTAL_SIZE_TANKMEM_ADDR ; 628 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 629 } 630 if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) { 631 entry->content = SNDRV_INFO_CONTENT_DATA; 632 entry->private_data = emu; 633 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 634 entry->size = emu->audigy ? A_TOTAL_SIZE_CODE : TOTAL_SIZE_CODE; 635 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 636 } 637 if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) { 638 entry->content = SNDRV_INFO_CONTENT_TEXT; 639 entry->private_data = emu; 640 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 641 entry->c.text.read = snd_emu10k1_proc_acode_read; 642 } 643 return 0; 644 } 645 #endif /* CONFIG_PROC_FS */ 646