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