1 /* 2 * Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si> 3 * Takashi Iwai <tiwai@suse.de> 4 * 5 * SB16ASP/AWE32 CSP control 6 * 7 * CSP microcode loader: 8 * alsa-tools/sb16_csp/ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * 24 */ 25 26 #include <linux/delay.h> 27 #include <linux/init.h> 28 #include <linux/slab.h> 29 #include <sound/core.h> 30 #include <sound/control.h> 31 #include <sound/info.h> 32 #include <sound/sb16_csp.h> 33 #include <sound/initval.h> 34 35 MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); 36 MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); 37 MODULE_LICENSE("GPL"); 38 #ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL 39 MODULE_FIRMWARE("sb16/mulaw_main.csp"); 40 MODULE_FIRMWARE("sb16/alaw_main.csp"); 41 MODULE_FIRMWARE("sb16/ima_adpcm_init.csp"); 42 MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp"); 43 MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp"); 44 #endif 45 46 #ifdef SNDRV_LITTLE_ENDIAN 47 #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) 48 #else 49 #define CSP_HDR_VALUE(a,b,c,d) ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24)) 50 #endif 51 52 #define RIFF_HEADER CSP_HDR_VALUE('R', 'I', 'F', 'F') 53 #define CSP__HEADER CSP_HDR_VALUE('C', 'S', 'P', ' ') 54 #define LIST_HEADER CSP_HDR_VALUE('L', 'I', 'S', 'T') 55 #define FUNC_HEADER CSP_HDR_VALUE('f', 'u', 'n', 'c') 56 #define CODE_HEADER CSP_HDR_VALUE('c', 'o', 'd', 'e') 57 #define INIT_HEADER CSP_HDR_VALUE('i', 'n', 'i', 't') 58 #define MAIN_HEADER CSP_HDR_VALUE('m', 'a', 'i', 'n') 59 60 /* 61 * RIFF data format 62 */ 63 struct riff_header { 64 __u32 name; 65 __u32 len; 66 }; 67 68 struct desc_header { 69 struct riff_header info; 70 __u16 func_nr; 71 __u16 VOC_type; 72 __u16 flags_play_rec; 73 __u16 flags_16bit_8bit; 74 __u16 flags_stereo_mono; 75 __u16 flags_rates; 76 }; 77 78 /* 79 * prototypes 80 */ 81 static void snd_sb_csp_free(struct snd_hwdep *hw); 82 static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file); 83 static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg); 84 static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file); 85 86 static int csp_detect(struct snd_sb *chip, int *version); 87 static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val); 88 static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val); 89 static int read_register(struct snd_sb *chip, unsigned char reg); 90 static int set_mode_register(struct snd_sb *chip, unsigned char mode); 91 static int get_version(struct snd_sb *chip); 92 93 static int snd_sb_csp_riff_load(struct snd_sb_csp * p, 94 struct snd_sb_csp_microcode __user * code); 95 static int snd_sb_csp_unload(struct snd_sb_csp * p); 96 static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags); 97 static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode); 98 static int snd_sb_csp_check_version(struct snd_sb_csp * p); 99 100 static int snd_sb_csp_use(struct snd_sb_csp * p); 101 static int snd_sb_csp_unuse(struct snd_sb_csp * p); 102 static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels); 103 static int snd_sb_csp_stop(struct snd_sb_csp * p); 104 static int snd_sb_csp_pause(struct snd_sb_csp * p); 105 static int snd_sb_csp_restart(struct snd_sb_csp * p); 106 107 static int snd_sb_qsound_build(struct snd_sb_csp * p); 108 static void snd_sb_qsound_destroy(struct snd_sb_csp * p); 109 static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p); 110 111 static int init_proc_entry(struct snd_sb_csp * p, int device); 112 static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer); 113 114 /* 115 * Detect CSP chip and create a new instance 116 */ 117 int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) 118 { 119 struct snd_sb_csp *p; 120 int uninitialized_var(version); 121 int err; 122 struct snd_hwdep *hw; 123 124 if (rhwdep) 125 *rhwdep = NULL; 126 127 if (csp_detect(chip, &version)) 128 return -ENODEV; 129 130 if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0) 131 return err; 132 133 if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) { 134 snd_device_free(chip->card, hw); 135 return -ENOMEM; 136 } 137 p->chip = chip; 138 p->version = version; 139 140 /* CSP operators */ 141 p->ops.csp_use = snd_sb_csp_use; 142 p->ops.csp_unuse = snd_sb_csp_unuse; 143 p->ops.csp_autoload = snd_sb_csp_autoload; 144 p->ops.csp_start = snd_sb_csp_start; 145 p->ops.csp_stop = snd_sb_csp_stop; 146 p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer; 147 148 mutex_init(&p->access_mutex); 149 sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f)); 150 hw->iface = SNDRV_HWDEP_IFACE_SB16CSP; 151 hw->private_data = p; 152 hw->private_free = snd_sb_csp_free; 153 154 /* operators - only write/ioctl */ 155 hw->ops.open = snd_sb_csp_open; 156 hw->ops.ioctl = snd_sb_csp_ioctl; 157 hw->ops.release = snd_sb_csp_release; 158 159 /* create a proc entry */ 160 init_proc_entry(p, device); 161 if (rhwdep) 162 *rhwdep = hw; 163 return 0; 164 } 165 166 /* 167 * free_private for hwdep instance 168 */ 169 static void snd_sb_csp_free(struct snd_hwdep *hwdep) 170 { 171 #ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL 172 int i; 173 #endif 174 struct snd_sb_csp *p = hwdep->private_data; 175 if (p) { 176 if (p->running & SNDRV_SB_CSP_ST_RUNNING) 177 snd_sb_csp_stop(p); 178 #ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL 179 for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) 180 release_firmware(p->csp_programs[i]); 181 #endif 182 kfree(p); 183 } 184 } 185 186 /* ------------------------------ */ 187 188 /* 189 * open the device exclusively 190 */ 191 static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file) 192 { 193 struct snd_sb_csp *p = hw->private_data; 194 return (snd_sb_csp_use(p)); 195 } 196 197 /* 198 * ioctl for hwdep device: 199 */ 200 static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg) 201 { 202 struct snd_sb_csp *p = hw->private_data; 203 struct snd_sb_csp_info info; 204 struct snd_sb_csp_start start_info; 205 int err; 206 207 snd_assert(p != NULL, return -EINVAL); 208 209 if (snd_sb_csp_check_version(p)) 210 return -ENODEV; 211 212 switch (cmd) { 213 /* get information */ 214 case SNDRV_SB_CSP_IOCTL_INFO: 215 *info.codec_name = *p->codec_name; 216 info.func_nr = p->func_nr; 217 info.acc_format = p->acc_format; 218 info.acc_channels = p->acc_channels; 219 info.acc_width = p->acc_width; 220 info.acc_rates = p->acc_rates; 221 info.csp_mode = p->mode; 222 info.run_channels = p->run_channels; 223 info.run_width = p->run_width; 224 info.version = p->version; 225 info.state = p->running; 226 if (copy_to_user((void __user *)arg, &info, sizeof(info))) 227 err = -EFAULT; 228 else 229 err = 0; 230 break; 231 232 /* load CSP microcode */ 233 case SNDRV_SB_CSP_IOCTL_LOAD_CODE: 234 err = (p->running & SNDRV_SB_CSP_ST_RUNNING ? 235 -EBUSY : snd_sb_csp_riff_load(p, (struct snd_sb_csp_microcode __user *) arg)); 236 break; 237 case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE: 238 err = (p->running & SNDRV_SB_CSP_ST_RUNNING ? 239 -EBUSY : snd_sb_csp_unload(p)); 240 break; 241 242 /* change CSP running state */ 243 case SNDRV_SB_CSP_IOCTL_START: 244 if (copy_from_user(&start_info, (void __user *) arg, sizeof(start_info))) 245 err = -EFAULT; 246 else 247 err = snd_sb_csp_start(p, start_info.sample_width, start_info.channels); 248 break; 249 case SNDRV_SB_CSP_IOCTL_STOP: 250 err = snd_sb_csp_stop(p); 251 break; 252 case SNDRV_SB_CSP_IOCTL_PAUSE: 253 err = snd_sb_csp_pause(p); 254 break; 255 case SNDRV_SB_CSP_IOCTL_RESTART: 256 err = snd_sb_csp_restart(p); 257 break; 258 default: 259 err = -ENOTTY; 260 break; 261 } 262 263 return err; 264 } 265 266 /* 267 * close the device 268 */ 269 static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file) 270 { 271 struct snd_sb_csp *p = hw->private_data; 272 return (snd_sb_csp_unuse(p)); 273 } 274 275 /* ------------------------------ */ 276 277 /* 278 * acquire device 279 */ 280 static int snd_sb_csp_use(struct snd_sb_csp * p) 281 { 282 mutex_lock(&p->access_mutex); 283 if (p->used) { 284 mutex_unlock(&p->access_mutex); 285 return -EAGAIN; 286 } 287 p->used++; 288 mutex_unlock(&p->access_mutex); 289 290 return 0; 291 292 } 293 294 /* 295 * release device 296 */ 297 static int snd_sb_csp_unuse(struct snd_sb_csp * p) 298 { 299 mutex_lock(&p->access_mutex); 300 p->used--; 301 mutex_unlock(&p->access_mutex); 302 303 return 0; 304 } 305 306 /* 307 * load microcode via ioctl: 308 * code is user-space pointer 309 */ 310 static int snd_sb_csp_riff_load(struct snd_sb_csp * p, 311 struct snd_sb_csp_microcode __user * mcode) 312 { 313 struct snd_sb_csp_mc_header info; 314 315 unsigned char __user *data_ptr; 316 unsigned char __user *data_end; 317 unsigned short func_nr = 0; 318 319 struct riff_header file_h, item_h, code_h; 320 __u32 item_type; 321 struct desc_header funcdesc_h; 322 323 unsigned long flags; 324 int err; 325 326 if (copy_from_user(&info, mcode, sizeof(info))) 327 return -EFAULT; 328 data_ptr = mcode->data; 329 330 if (copy_from_user(&file_h, data_ptr, sizeof(file_h))) 331 return -EFAULT; 332 if ((file_h.name != RIFF_HEADER) || 333 (le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) { 334 snd_printd("%s: Invalid RIFF header\n", __func__); 335 return -EINVAL; 336 } 337 data_ptr += sizeof(file_h); 338 data_end = data_ptr + le32_to_cpu(file_h.len); 339 340 if (copy_from_user(&item_type, data_ptr, sizeof(item_type))) 341 return -EFAULT; 342 if (item_type != CSP__HEADER) { 343 snd_printd("%s: Invalid RIFF file type\n", __func__); 344 return -EINVAL; 345 } 346 data_ptr += sizeof (item_type); 347 348 for (; data_ptr < data_end; data_ptr += le32_to_cpu(item_h.len)) { 349 if (copy_from_user(&item_h, data_ptr, sizeof(item_h))) 350 return -EFAULT; 351 data_ptr += sizeof(item_h); 352 if (item_h.name != LIST_HEADER) 353 continue; 354 355 if (copy_from_user(&item_type, data_ptr, sizeof(item_type))) 356 return -EFAULT; 357 switch (item_type) { 358 case FUNC_HEADER: 359 if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h))) 360 return -EFAULT; 361 func_nr = le16_to_cpu(funcdesc_h.func_nr); 362 break; 363 case CODE_HEADER: 364 if (func_nr != info.func_req) 365 break; /* not required function, try next */ 366 data_ptr += sizeof(item_type); 367 368 /* destroy QSound mixer element */ 369 if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) { 370 snd_sb_qsound_destroy(p); 371 } 372 /* Clear all flags */ 373 p->running = 0; 374 p->mode = 0; 375 376 /* load microcode blocks */ 377 for (;;) { 378 if (data_ptr >= data_end) 379 return -EINVAL; 380 if (copy_from_user(&code_h, data_ptr, sizeof(code_h))) 381 return -EFAULT; 382 383 /* init microcode blocks */ 384 if (code_h.name != INIT_HEADER) 385 break; 386 data_ptr += sizeof(code_h); 387 err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len), 388 SNDRV_SB_CSP_LOAD_INITBLOCK); 389 if (err) 390 return err; 391 data_ptr += le32_to_cpu(code_h.len); 392 } 393 /* main microcode block */ 394 if (copy_from_user(&code_h, data_ptr, sizeof(code_h))) 395 return -EFAULT; 396 397 if (code_h.name != MAIN_HEADER) { 398 snd_printd("%s: Missing 'main' microcode\n", __func__); 399 return -EINVAL; 400 } 401 data_ptr += sizeof(code_h); 402 err = snd_sb_csp_load_user(p, data_ptr, 403 le32_to_cpu(code_h.len), 0); 404 if (err) 405 return err; 406 407 /* fill in codec header */ 408 strlcpy(p->codec_name, info.codec_name, sizeof(p->codec_name)); 409 p->func_nr = func_nr; 410 p->mode = le16_to_cpu(funcdesc_h.flags_play_rec); 411 switch (le16_to_cpu(funcdesc_h.VOC_type)) { 412 case 0x0001: /* QSound decoder */ 413 if (le16_to_cpu(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) { 414 if (snd_sb_qsound_build(p) == 0) 415 /* set QSound flag and clear all other mode flags */ 416 p->mode = SNDRV_SB_CSP_MODE_QSOUND; 417 } 418 p->acc_format = 0; 419 break; 420 case 0x0006: /* A Law codec */ 421 p->acc_format = SNDRV_PCM_FMTBIT_A_LAW; 422 break; 423 case 0x0007: /* Mu Law codec */ 424 p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW; 425 break; 426 case 0x0011: /* what Creative thinks is IMA ADPCM codec */ 427 case 0x0200: /* Creative ADPCM codec */ 428 p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM; 429 break; 430 case 201: /* Text 2 Speech decoder */ 431 /* TODO: Text2Speech handling routines */ 432 p->acc_format = 0; 433 break; 434 case 0x0202: /* Fast Speech 8 codec */ 435 case 0x0203: /* Fast Speech 10 codec */ 436 p->acc_format = SNDRV_PCM_FMTBIT_SPECIAL; 437 break; 438 default: /* other codecs are unsupported */ 439 p->acc_format = p->acc_width = p->acc_rates = 0; 440 p->mode = 0; 441 snd_printd("%s: Unsupported CSP codec type: 0x%04x\n", 442 __func__, 443 le16_to_cpu(funcdesc_h.VOC_type)); 444 return -EINVAL; 445 } 446 p->acc_channels = le16_to_cpu(funcdesc_h.flags_stereo_mono); 447 p->acc_width = le16_to_cpu(funcdesc_h.flags_16bit_8bit); 448 p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates); 449 450 /* Decouple CSP from IRQ and DMAREQ lines */ 451 spin_lock_irqsave(&p->chip->reg_lock, flags); 452 set_mode_register(p->chip, 0xfc); 453 set_mode_register(p->chip, 0x00); 454 spin_unlock_irqrestore(&p->chip->reg_lock, flags); 455 456 /* finished loading successfully */ 457 p->running = SNDRV_SB_CSP_ST_LOADED; /* set LOADED flag */ 458 return 0; 459 } 460 } 461 snd_printd("%s: Function #%d not found\n", __func__, info.func_req); 462 return -EINVAL; 463 } 464 465 /* 466 * unload CSP microcode 467 */ 468 static int snd_sb_csp_unload(struct snd_sb_csp * p) 469 { 470 if (p->running & SNDRV_SB_CSP_ST_RUNNING) 471 return -EBUSY; 472 if (!(p->running & SNDRV_SB_CSP_ST_LOADED)) 473 return -ENXIO; 474 475 /* clear supported formats */ 476 p->acc_format = 0; 477 p->acc_channels = p->acc_width = p->acc_rates = 0; 478 /* destroy QSound mixer element */ 479 if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) { 480 snd_sb_qsound_destroy(p); 481 } 482 /* clear all flags */ 483 p->running = 0; 484 p->mode = 0; 485 return 0; 486 } 487 488 /* 489 * send command sequence to DSP 490 */ 491 static inline int command_seq(struct snd_sb *chip, const unsigned char *seq, int size) 492 { 493 int i; 494 for (i = 0; i < size; i++) { 495 if (!snd_sbdsp_command(chip, seq[i])) 496 return -EIO; 497 } 498 return 0; 499 } 500 501 /* 502 * set CSP codec parameter 503 */ 504 static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val) 505 { 506 unsigned char dsp_cmd[3]; 507 508 dsp_cmd[0] = 0x05; /* CSP set codec parameter */ 509 dsp_cmd[1] = val; /* Parameter value */ 510 dsp_cmd[2] = par; /* Parameter */ 511 command_seq(chip, dsp_cmd, 3); 512 snd_sbdsp_command(chip, 0x03); /* DSP read? */ 513 if (snd_sbdsp_get_byte(chip) != par) 514 return -EIO; 515 return 0; 516 } 517 518 /* 519 * set CSP register 520 */ 521 static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val) 522 { 523 unsigned char dsp_cmd[3]; 524 525 dsp_cmd[0] = 0x0e; /* CSP set register */ 526 dsp_cmd[1] = reg; /* CSP Register */ 527 dsp_cmd[2] = val; /* value */ 528 return command_seq(chip, dsp_cmd, 3); 529 } 530 531 /* 532 * read CSP register 533 * return < 0 -> error 534 */ 535 static int read_register(struct snd_sb *chip, unsigned char reg) 536 { 537 unsigned char dsp_cmd[2]; 538 539 dsp_cmd[0] = 0x0f; /* CSP read register */ 540 dsp_cmd[1] = reg; /* CSP Register */ 541 command_seq(chip, dsp_cmd, 2); 542 return snd_sbdsp_get_byte(chip); /* Read DSP value */ 543 } 544 545 /* 546 * set CSP mode register 547 */ 548 static int set_mode_register(struct snd_sb *chip, unsigned char mode) 549 { 550 unsigned char dsp_cmd[2]; 551 552 dsp_cmd[0] = 0x04; /* CSP set mode register */ 553 dsp_cmd[1] = mode; /* mode */ 554 return command_seq(chip, dsp_cmd, 2); 555 } 556 557 /* 558 * Detect CSP 559 * return 0 if CSP exists. 560 */ 561 static int csp_detect(struct snd_sb *chip, int *version) 562 { 563 unsigned char csp_test1, csp_test2; 564 unsigned long flags; 565 int result = -ENODEV; 566 567 spin_lock_irqsave(&chip->reg_lock, flags); 568 569 set_codec_parameter(chip, 0x00, 0x00); 570 set_mode_register(chip, 0xfc); /* 0xfc = ?? */ 571 572 csp_test1 = read_register(chip, 0x83); 573 set_register(chip, 0x83, ~csp_test1); 574 csp_test2 = read_register(chip, 0x83); 575 if (csp_test2 != (csp_test1 ^ 0xff)) 576 goto __fail; 577 578 set_register(chip, 0x83, csp_test1); 579 csp_test2 = read_register(chip, 0x83); 580 if (csp_test2 != csp_test1) 581 goto __fail; 582 583 set_mode_register(chip, 0x00); /* 0x00 = ? */ 584 585 *version = get_version(chip); 586 snd_sbdsp_reset(chip); /* reset DSP after getversion! */ 587 if (*version >= 0x10 && *version <= 0x1f) 588 result = 0; /* valid version id */ 589 590 __fail: 591 spin_unlock_irqrestore(&chip->reg_lock, flags); 592 return result; 593 } 594 595 /* 596 * get CSP version number 597 */ 598 static int get_version(struct snd_sb *chip) 599 { 600 unsigned char dsp_cmd[2]; 601 602 dsp_cmd[0] = 0x08; /* SB_DSP_!something! */ 603 dsp_cmd[1] = 0x03; /* get chip version id? */ 604 command_seq(chip, dsp_cmd, 2); 605 606 return (snd_sbdsp_get_byte(chip)); 607 } 608 609 /* 610 * check if the CSP version is valid 611 */ 612 static int snd_sb_csp_check_version(struct snd_sb_csp * p) 613 { 614 if (p->version < 0x10 || p->version > 0x1f) { 615 snd_printd("%s: Invalid CSP version: 0x%x\n", __func__, p->version); 616 return 1; 617 } 618 return 0; 619 } 620 621 /* 622 * download microcode to CSP (microcode should have one "main" block). 623 */ 624 static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int size, int load_flags) 625 { 626 int status, i; 627 int err; 628 int result = -EIO; 629 unsigned long flags; 630 631 spin_lock_irqsave(&p->chip->reg_lock, flags); 632 snd_sbdsp_command(p->chip, 0x01); /* CSP download command */ 633 if (snd_sbdsp_get_byte(p->chip)) { 634 snd_printd("%s: Download command failed\n", __func__); 635 goto __fail; 636 } 637 /* Send CSP low byte (size - 1) */ 638 snd_sbdsp_command(p->chip, (unsigned char)(size - 1)); 639 /* Send high byte */ 640 snd_sbdsp_command(p->chip, (unsigned char)((size - 1) >> 8)); 641 /* send microcode sequence */ 642 /* load from kernel space */ 643 while (size--) { 644 if (!snd_sbdsp_command(p->chip, *buf++)) 645 goto __fail; 646 } 647 if (snd_sbdsp_get_byte(p->chip)) 648 goto __fail; 649 650 if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) { 651 i = 0; 652 /* some codecs (FastSpeech) take some time to initialize */ 653 while (1) { 654 snd_sbdsp_command(p->chip, 0x03); 655 status = snd_sbdsp_get_byte(p->chip); 656 if (status == 0x55 || ++i >= 10) 657 break; 658 udelay (10); 659 } 660 if (status != 0x55) { 661 snd_printd("%s: Microcode initialization failed\n", __func__); 662 goto __fail; 663 } 664 } else { 665 /* 666 * Read mixer register SB_DSP4_DMASETUP after loading 'main' code. 667 * Start CSP chip if no 16bit DMA channel is set - some kind 668 * of autorun or perhaps a bugfix? 669 */ 670 spin_lock(&p->chip->mixer_lock); 671 status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP); 672 spin_unlock(&p->chip->mixer_lock); 673 if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) { 674 err = (set_codec_parameter(p->chip, 0xaa, 0x00) || 675 set_codec_parameter(p->chip, 0xff, 0x00)); 676 snd_sbdsp_reset(p->chip); /* really! */ 677 if (err) 678 goto __fail; 679 set_mode_register(p->chip, 0xc0); /* c0 = STOP */ 680 set_mode_register(p->chip, 0x70); /* 70 = RUN */ 681 } 682 } 683 result = 0; 684 685 __fail: 686 spin_unlock_irqrestore(&p->chip->reg_lock, flags); 687 return result; 688 } 689 690 static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags) 691 { 692 int err = -ENOMEM; 693 unsigned char *kbuf = kmalloc(size, GFP_KERNEL); 694 if (kbuf) { 695 if (copy_from_user(kbuf, buf, size)) 696 err = -EFAULT; 697 else 698 err = snd_sb_csp_load(p, kbuf, size, load_flags); 699 kfree(kbuf); 700 } 701 return err; 702 } 703 704 #ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL 705 #include "sb16_csp_codecs.h" 706 707 static const struct firmware snd_sb_csp_static_programs[] = { 708 { .data = mulaw_main, .size = sizeof mulaw_main }, 709 { .data = alaw_main, .size = sizeof alaw_main }, 710 { .data = ima_adpcm_init, .size = sizeof ima_adpcm_init }, 711 { .data = ima_adpcm_playback, .size = sizeof ima_adpcm_playback }, 712 { .data = ima_adpcm_capture, .size = sizeof ima_adpcm_capture }, 713 }; 714 #endif 715 716 static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) 717 { 718 static const char *const names[] = { 719 "sb16/mulaw_main.csp", 720 "sb16/alaw_main.csp", 721 "sb16/ima_adpcm_init.csp", 722 "sb16/ima_adpcm_playback.csp", 723 "sb16/ima_adpcm_capture.csp", 724 }; 725 const struct firmware *program; 726 727 BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); 728 program = p->csp_programs[index]; 729 if (!program) { 730 #ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL 731 program = &snd_sb_csp_static_programs[index]; 732 #else 733 int err = request_firmware(&program, names[index], 734 p->chip->card->dev); 735 if (err < 0) 736 return err; 737 #endif 738 p->csp_programs[index] = program; 739 } 740 return snd_sb_csp_load(p, program->data, program->size, flags); 741 } 742 743 /* 744 * autoload hardware codec if necessary 745 * return 0 if CSP is loaded and ready to run (p->running != 0) 746 */ 747 static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode) 748 { 749 unsigned long flags; 750 int err = 0; 751 752 /* if CSP is running or manually loaded then exit */ 753 if (p->running & (SNDRV_SB_CSP_ST_RUNNING | SNDRV_SB_CSP_ST_LOADED)) 754 return -EBUSY; 755 756 /* autoload microcode only if requested hardware codec is not already loaded */ 757 if (((1 << pcm_sfmt) & p->acc_format) && (play_rec_mode & p->mode)) { 758 p->running = SNDRV_SB_CSP_ST_AUTO; 759 } else { 760 switch (pcm_sfmt) { 761 case SNDRV_PCM_FORMAT_MU_LAW: 762 err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0); 763 p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW; 764 p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; 765 break; 766 case SNDRV_PCM_FORMAT_A_LAW: 767 err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0); 768 p->acc_format = SNDRV_PCM_FMTBIT_A_LAW; 769 p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; 770 break; 771 case SNDRV_PCM_FORMAT_IMA_ADPCM: 772 err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT, 773 SNDRV_SB_CSP_LOAD_INITBLOCK); 774 if (err) 775 break; 776 if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) { 777 err = snd_sb_csp_firmware_load 778 (p, CSP_PROGRAM_ADPCM_PLAYBACK, 0); 779 p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE; 780 } else { 781 err = snd_sb_csp_firmware_load 782 (p, CSP_PROGRAM_ADPCM_CAPTURE, 0); 783 p->mode = SNDRV_SB_CSP_MODE_DSP_READ; 784 } 785 p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM; 786 break; 787 default: 788 /* Decouple CSP from IRQ and DMAREQ lines */ 789 if (p->running & SNDRV_SB_CSP_ST_AUTO) { 790 spin_lock_irqsave(&p->chip->reg_lock, flags); 791 set_mode_register(p->chip, 0xfc); 792 set_mode_register(p->chip, 0x00); 793 spin_unlock_irqrestore(&p->chip->reg_lock, flags); 794 p->running = 0; /* clear autoloaded flag */ 795 } 796 return -EINVAL; 797 } 798 if (err) { 799 p->acc_format = 0; 800 p->acc_channels = p->acc_width = p->acc_rates = 0; 801 802 p->running = 0; /* clear autoloaded flag */ 803 p->mode = 0; 804 return (err); 805 } else { 806 p->running = SNDRV_SB_CSP_ST_AUTO; /* set autoloaded flag */ 807 p->acc_width = SNDRV_SB_CSP_SAMPLE_16BIT; /* only 16 bit data */ 808 p->acc_channels = SNDRV_SB_CSP_MONO | SNDRV_SB_CSP_STEREO; 809 p->acc_rates = SNDRV_SB_CSP_RATE_ALL; /* HW codecs accept all rates */ 810 } 811 812 } 813 return (p->running & SNDRV_SB_CSP_ST_AUTO) ? 0 : -ENXIO; 814 } 815 816 /* 817 * start CSP 818 */ 819 static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels) 820 { 821 unsigned char s_type; /* sample type */ 822 unsigned char mixL, mixR; 823 int result = -EIO; 824 unsigned long flags; 825 826 if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) { 827 snd_printd("%s: Microcode not loaded\n", __func__); 828 return -ENXIO; 829 } 830 if (p->running & SNDRV_SB_CSP_ST_RUNNING) { 831 snd_printd("%s: CSP already running\n", __func__); 832 return -EBUSY; 833 } 834 if (!(sample_width & p->acc_width)) { 835 snd_printd("%s: Unsupported PCM sample width\n", __func__); 836 return -EINVAL; 837 } 838 if (!(channels & p->acc_channels)) { 839 snd_printd("%s: Invalid number of channels\n", __func__); 840 return -EINVAL; 841 } 842 843 /* Mute PCM volume */ 844 spin_lock_irqsave(&p->chip->mixer_lock, flags); 845 mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV); 846 mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1); 847 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7); 848 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7); 849 850 spin_lock(&p->chip->reg_lock); 851 set_mode_register(p->chip, 0xc0); /* c0 = STOP */ 852 set_mode_register(p->chip, 0x70); /* 70 = RUN */ 853 854 s_type = 0x00; 855 if (channels == SNDRV_SB_CSP_MONO) 856 s_type = 0x11; /* 000n 000n (n = 1 if mono) */ 857 if (sample_width == SNDRV_SB_CSP_SAMPLE_8BIT) 858 s_type |= 0x22; /* 00dX 00dX (d = 1 if 8 bit samples) */ 859 860 if (set_codec_parameter(p->chip, 0x81, s_type)) { 861 snd_printd("%s: Set sample type command failed\n", __func__); 862 goto __fail; 863 } 864 if (set_codec_parameter(p->chip, 0x80, 0x00)) { 865 snd_printd("%s: Codec start command failed\n", __func__); 866 goto __fail; 867 } 868 p->run_width = sample_width; 869 p->run_channels = channels; 870 871 p->running |= SNDRV_SB_CSP_ST_RUNNING; 872 873 if (p->mode & SNDRV_SB_CSP_MODE_QSOUND) { 874 set_codec_parameter(p->chip, 0xe0, 0x01); 875 /* enable QSound decoder */ 876 set_codec_parameter(p->chip, 0x00, 0xff); 877 set_codec_parameter(p->chip, 0x01, 0xff); 878 p->running |= SNDRV_SB_CSP_ST_QSOUND; 879 /* set QSound startup value */ 880 snd_sb_csp_qsound_transfer(p); 881 } 882 result = 0; 883 884 __fail: 885 spin_unlock(&p->chip->reg_lock); 886 887 /* restore PCM volume */ 888 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL); 889 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR); 890 spin_unlock_irqrestore(&p->chip->mixer_lock, flags); 891 892 return result; 893 } 894 895 /* 896 * stop CSP 897 */ 898 static int snd_sb_csp_stop(struct snd_sb_csp * p) 899 { 900 int result; 901 unsigned char mixL, mixR; 902 unsigned long flags; 903 904 if (!(p->running & SNDRV_SB_CSP_ST_RUNNING)) 905 return 0; 906 907 /* Mute PCM volume */ 908 spin_lock_irqsave(&p->chip->mixer_lock, flags); 909 mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV); 910 mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1); 911 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7); 912 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7); 913 914 spin_lock(&p->chip->reg_lock); 915 if (p->running & SNDRV_SB_CSP_ST_QSOUND) { 916 set_codec_parameter(p->chip, 0xe0, 0x01); 917 /* disable QSound decoder */ 918 set_codec_parameter(p->chip, 0x00, 0x00); 919 set_codec_parameter(p->chip, 0x01, 0x00); 920 921 p->running &= ~SNDRV_SB_CSP_ST_QSOUND; 922 } 923 result = set_mode_register(p->chip, 0xc0); /* c0 = STOP */ 924 spin_unlock(&p->chip->reg_lock); 925 926 /* restore PCM volume */ 927 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL); 928 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR); 929 spin_unlock_irqrestore(&p->chip->mixer_lock, flags); 930 931 if (!(result)) 932 p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING); 933 return result; 934 } 935 936 /* 937 * pause CSP codec and hold DMA transfer 938 */ 939 static int snd_sb_csp_pause(struct snd_sb_csp * p) 940 { 941 int result; 942 unsigned long flags; 943 944 if (!(p->running & SNDRV_SB_CSP_ST_RUNNING)) 945 return -EBUSY; 946 947 spin_lock_irqsave(&p->chip->reg_lock, flags); 948 result = set_codec_parameter(p->chip, 0x80, 0xff); 949 spin_unlock_irqrestore(&p->chip->reg_lock, flags); 950 if (!(result)) 951 p->running |= SNDRV_SB_CSP_ST_PAUSED; 952 953 return result; 954 } 955 956 /* 957 * restart CSP codec and resume DMA transfer 958 */ 959 static int snd_sb_csp_restart(struct snd_sb_csp * p) 960 { 961 int result; 962 unsigned long flags; 963 964 if (!(p->running & SNDRV_SB_CSP_ST_PAUSED)) 965 return -EBUSY; 966 967 spin_lock_irqsave(&p->chip->reg_lock, flags); 968 result = set_codec_parameter(p->chip, 0x80, 0x00); 969 spin_unlock_irqrestore(&p->chip->reg_lock, flags); 970 if (!(result)) 971 p->running &= ~SNDRV_SB_CSP_ST_PAUSED; 972 973 return result; 974 } 975 976 /* ------------------------------ */ 977 978 /* 979 * QSound mixer control for PCM 980 */ 981 982 #define snd_sb_qsound_switch_info snd_ctl_boolean_mono_info 983 984 static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 985 { 986 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); 987 988 ucontrol->value.integer.value[0] = p->q_enabled ? 1 : 0; 989 return 0; 990 } 991 992 static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 993 { 994 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); 995 unsigned long flags; 996 int change; 997 unsigned char nval; 998 999 nval = ucontrol->value.integer.value[0] & 0x01; 1000 spin_lock_irqsave(&p->q_lock, flags); 1001 change = p->q_enabled != nval; 1002 p->q_enabled = nval; 1003 spin_unlock_irqrestore(&p->q_lock, flags); 1004 return change; 1005 } 1006 1007 static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1008 { 1009 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1010 uinfo->count = 2; 1011 uinfo->value.integer.min = 0; 1012 uinfo->value.integer.max = SNDRV_SB_CSP_QSOUND_MAX_RIGHT; 1013 return 0; 1014 } 1015 1016 static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1017 { 1018 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); 1019 unsigned long flags; 1020 1021 spin_lock_irqsave(&p->q_lock, flags); 1022 ucontrol->value.integer.value[0] = p->qpos_left; 1023 ucontrol->value.integer.value[1] = p->qpos_right; 1024 spin_unlock_irqrestore(&p->q_lock, flags); 1025 return 0; 1026 } 1027 1028 static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1029 { 1030 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); 1031 unsigned long flags; 1032 int change; 1033 unsigned char nval1, nval2; 1034 1035 nval1 = ucontrol->value.integer.value[0]; 1036 if (nval1 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT) 1037 nval1 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT; 1038 nval2 = ucontrol->value.integer.value[1]; 1039 if (nval2 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT) 1040 nval2 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT; 1041 spin_lock_irqsave(&p->q_lock, flags); 1042 change = p->qpos_left != nval1 || p->qpos_right != nval2; 1043 p->qpos_left = nval1; 1044 p->qpos_right = nval2; 1045 p->qpos_changed = change; 1046 spin_unlock_irqrestore(&p->q_lock, flags); 1047 return change; 1048 } 1049 1050 static struct snd_kcontrol_new snd_sb_qsound_switch = { 1051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1052 .name = "3D Control - Switch", 1053 .info = snd_sb_qsound_switch_info, 1054 .get = snd_sb_qsound_switch_get, 1055 .put = snd_sb_qsound_switch_put 1056 }; 1057 1058 static struct snd_kcontrol_new snd_sb_qsound_space = { 1059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1060 .name = "3D Control - Space", 1061 .info = snd_sb_qsound_space_info, 1062 .get = snd_sb_qsound_space_get, 1063 .put = snd_sb_qsound_space_put 1064 }; 1065 1066 static int snd_sb_qsound_build(struct snd_sb_csp * p) 1067 { 1068 struct snd_card *card; 1069 int err; 1070 1071 snd_assert(p != NULL, return -EINVAL); 1072 1073 card = p->chip->card; 1074 p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2; 1075 p->qpos_changed = 0; 1076 1077 spin_lock_init(&p->q_lock); 1078 1079 if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0) 1080 goto __error; 1081 if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0) 1082 goto __error; 1083 1084 return 0; 1085 1086 __error: 1087 snd_sb_qsound_destroy(p); 1088 return err; 1089 } 1090 1091 static void snd_sb_qsound_destroy(struct snd_sb_csp * p) 1092 { 1093 struct snd_card *card; 1094 unsigned long flags; 1095 1096 snd_assert(p != NULL, return); 1097 1098 card = p->chip->card; 1099 1100 down_write(&card->controls_rwsem); 1101 if (p->qsound_switch) 1102 snd_ctl_remove(card, p->qsound_switch); 1103 if (p->qsound_space) 1104 snd_ctl_remove(card, p->qsound_space); 1105 up_write(&card->controls_rwsem); 1106 1107 /* cancel pending transfer of QSound parameters */ 1108 spin_lock_irqsave (&p->q_lock, flags); 1109 p->qpos_changed = 0; 1110 spin_unlock_irqrestore (&p->q_lock, flags); 1111 } 1112 1113 /* 1114 * Transfer qsound parameters to CSP, 1115 * function should be called from interrupt routine 1116 */ 1117 static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p) 1118 { 1119 int err = -ENXIO; 1120 1121 spin_lock(&p->q_lock); 1122 if (p->running & SNDRV_SB_CSP_ST_QSOUND) { 1123 set_codec_parameter(p->chip, 0xe0, 0x01); 1124 /* left channel */ 1125 set_codec_parameter(p->chip, 0x00, p->qpos_left); 1126 set_codec_parameter(p->chip, 0x02, 0x00); 1127 /* right channel */ 1128 set_codec_parameter(p->chip, 0x00, p->qpos_right); 1129 set_codec_parameter(p->chip, 0x03, 0x00); 1130 err = 0; 1131 } 1132 p->qpos_changed = 0; 1133 spin_unlock(&p->q_lock); 1134 return err; 1135 } 1136 1137 /* ------------------------------ */ 1138 1139 /* 1140 * proc interface 1141 */ 1142 static int init_proc_entry(struct snd_sb_csp * p, int device) 1143 { 1144 char name[16]; 1145 struct snd_info_entry *entry; 1146 sprintf(name, "cspD%d", device); 1147 if (! snd_card_proc_new(p->chip->card, name, &entry)) 1148 snd_info_set_text_ops(entry, p, info_read); 1149 return 0; 1150 } 1151 1152 static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1153 { 1154 struct snd_sb_csp *p = entry->private_data; 1155 1156 snd_iprintf(buffer, "Creative Signal Processor [v%d.%d]\n", (p->version >> 4), (p->version & 0x0f)); 1157 snd_iprintf(buffer, "State: %cx%c%c%c\n", ((p->running & SNDRV_SB_CSP_ST_QSOUND) ? 'Q' : '-'), 1158 ((p->running & SNDRV_SB_CSP_ST_PAUSED) ? 'P' : '-'), 1159 ((p->running & SNDRV_SB_CSP_ST_RUNNING) ? 'R' : '-'), 1160 ((p->running & SNDRV_SB_CSP_ST_LOADED) ? 'L' : '-')); 1161 if (p->running & SNDRV_SB_CSP_ST_LOADED) { 1162 snd_iprintf(buffer, "Codec: %s [func #%d]\n", p->codec_name, p->func_nr); 1163 snd_iprintf(buffer, "Sample rates: "); 1164 if (p->acc_rates == SNDRV_SB_CSP_RATE_ALL) { 1165 snd_iprintf(buffer, "All\n"); 1166 } else { 1167 snd_iprintf(buffer, "%s%s%s%s\n", 1168 ((p->acc_rates & SNDRV_SB_CSP_RATE_8000) ? "8000Hz " : ""), 1169 ((p->acc_rates & SNDRV_SB_CSP_RATE_11025) ? "11025Hz " : ""), 1170 ((p->acc_rates & SNDRV_SB_CSP_RATE_22050) ? "22050Hz " : ""), 1171 ((p->acc_rates & SNDRV_SB_CSP_RATE_44100) ? "44100Hz" : "")); 1172 } 1173 if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) { 1174 snd_iprintf(buffer, "QSound decoder %sabled\n", 1175 p->q_enabled ? "en" : "dis"); 1176 } else { 1177 snd_iprintf(buffer, "PCM format ID: 0x%x (%s/%s) [%s/%s] [%s/%s]\n", 1178 p->acc_format, 1179 ((p->acc_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? "16bit" : "-"), 1180 ((p->acc_width & SNDRV_SB_CSP_SAMPLE_8BIT) ? "8bit" : "-"), 1181 ((p->acc_channels & SNDRV_SB_CSP_MONO) ? "mono" : "-"), 1182 ((p->acc_channels & SNDRV_SB_CSP_STEREO) ? "stereo" : "-"), 1183 ((p->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) ? "playback" : "-"), 1184 ((p->mode & SNDRV_SB_CSP_MODE_DSP_READ) ? "capture" : "-")); 1185 } 1186 } 1187 if (p->running & SNDRV_SB_CSP_ST_AUTO) { 1188 snd_iprintf(buffer, "Autoloaded Mu-Law, A-Law or Ima-ADPCM hardware codec\n"); 1189 } 1190 if (p->running & SNDRV_SB_CSP_ST_RUNNING) { 1191 snd_iprintf(buffer, "Processing %dbit %s PCM samples\n", 1192 ((p->run_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? 16 : 8), 1193 ((p->run_channels & SNDRV_SB_CSP_MONO) ? "mono" : "stereo")); 1194 } 1195 if (p->running & SNDRV_SB_CSP_ST_QSOUND) { 1196 snd_iprintf(buffer, "Qsound position: left = 0x%x, right = 0x%x\n", 1197 p->qpos_left, p->qpos_right); 1198 } 1199 } 1200 1201 /* */ 1202 1203 EXPORT_SYMBOL(snd_sb_csp_new); 1204 1205 /* 1206 * INIT part 1207 */ 1208 1209 static int __init alsa_sb_csp_init(void) 1210 { 1211 return 0; 1212 } 1213 1214 static void __exit alsa_sb_csp_exit(void) 1215 { 1216 } 1217 1218 module_init(alsa_sb_csp_init) 1219 module_exit(alsa_sb_csp_exit) 1220