1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 3 * Uros Bizjak <uros@kss-loka.si> 4 * 5 * Routines for control of 8-bit SoundBlaster cards and clones 6 * Please note: I don't have access to old SB8 soundcards. 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 * -- 24 * 25 * Thu Apr 29 20:36:17 BST 1999 George David Morrison <gdm@gedamo.demon.co.uk> 26 * DSP can't respond to commands whilst in "high speed" mode. Caused 27 * glitching during playback. Fixed. 28 * 29 * Wed Jul 12 22:02:55 CEST 2000 Uros Bizjak <uros@kss-loka.si> 30 * Cleaned up and rewrote lowlevel routines. 31 */ 32 33 #include <asm/io.h> 34 #include <asm/dma.h> 35 #include <linux/init.h> 36 #include <linux/time.h> 37 #include <sound/core.h> 38 #include <sound/sb.h> 39 40 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Uros Bizjak <uros@kss-loka.si>"); 41 MODULE_DESCRIPTION("Routines for control of 8-bit SoundBlaster cards and clones"); 42 MODULE_LICENSE("GPL"); 43 44 #define SB8_CLOCK 1000000 45 #define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v)) 46 #define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v)) 47 48 static struct snd_ratnum clock = { 49 .num = SB8_CLOCK, 50 .den_min = 1, 51 .den_max = 256, 52 .den_step = 1, 53 }; 54 55 static struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = { 56 .nrats = 1, 57 .rats = &clock, 58 }; 59 60 static struct snd_ratnum stereo_clocks[] = { 61 { 62 .num = SB8_CLOCK, 63 .den_min = SB8_DEN(22050), 64 .den_max = SB8_DEN(22050), 65 .den_step = 1, 66 }, 67 { 68 .num = SB8_CLOCK, 69 .den_min = SB8_DEN(11025), 70 .den_max = SB8_DEN(11025), 71 .den_step = 1, 72 } 73 }; 74 75 static int snd_sb8_hw_constraint_rate_channels(struct snd_pcm_hw_params *params, 76 struct snd_pcm_hw_rule *rule) 77 { 78 struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 79 if (c->min > 1) { 80 unsigned int num = 0, den = 0; 81 int err = snd_interval_ratnum(hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE), 82 2, stereo_clocks, &num, &den); 83 if (err >= 0 && den) { 84 params->rate_num = num; 85 params->rate_den = den; 86 } 87 return err; 88 } 89 return 0; 90 } 91 92 static int snd_sb8_hw_constraint_channels_rate(struct snd_pcm_hw_params *params, 93 struct snd_pcm_hw_rule *rule) 94 { 95 struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 96 if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) { 97 struct snd_interval t = { .min = 1, .max = 1 }; 98 return snd_interval_refine(hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS), &t); 99 } 100 return 0; 101 } 102 103 static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) 104 { 105 unsigned long flags; 106 struct snd_sb *chip = snd_pcm_substream_chip(substream); 107 struct snd_pcm_runtime *runtime = substream->runtime; 108 unsigned int mixreg, rate, size, count; 109 110 rate = runtime->rate; 111 switch (chip->hardware) { 112 case SB_HW_PRO: 113 if (runtime->channels > 1) { 114 if (snd_BUG_ON(rate != SB8_RATE(11025) && 115 rate != SB8_RATE(22050))) 116 return -EINVAL; 117 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; 118 break; 119 } 120 /* fallthru */ 121 case SB_HW_201: 122 if (rate > 23000) { 123 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; 124 break; 125 } 126 /* fallthru */ 127 case SB_HW_20: 128 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; 129 break; 130 case SB_HW_10: 131 chip->playback_format = SB_DSP_OUTPUT; 132 break; 133 default: 134 return -EINVAL; 135 } 136 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); 137 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); 138 spin_lock_irqsave(&chip->reg_lock, flags); 139 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); 140 if (runtime->channels > 1) { 141 /* set playback stereo mode */ 142 spin_lock(&chip->mixer_lock); 143 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); 144 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02); 145 spin_unlock(&chip->mixer_lock); 146 147 /* Soundblaster hardware programming reference guide, 3-23 */ 148 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); 149 runtime->dma_area[0] = 0x80; 150 snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); 151 /* force interrupt */ 152 chip->mode = SB_MODE_HALT; 153 snd_sbdsp_command(chip, SB_DSP_OUTPUT); 154 snd_sbdsp_command(chip, 0); 155 snd_sbdsp_command(chip, 0); 156 } 157 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 158 if (runtime->channels > 1) { 159 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 160 spin_lock(&chip->mixer_lock); 161 /* save output filter status and turn it off */ 162 mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT); 163 snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20); 164 spin_unlock(&chip->mixer_lock); 165 /* just use force_mode16 for temporary storate... */ 166 chip->force_mode16 = mixreg; 167 } else { 168 snd_sbdsp_command(chip, 256 - runtime->rate_den); 169 } 170 if (chip->playback_format != SB_DSP_OUTPUT) { 171 count--; 172 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 173 snd_sbdsp_command(chip, count & 0xff); 174 snd_sbdsp_command(chip, count >> 8); 175 } 176 spin_unlock_irqrestore(&chip->reg_lock, flags); 177 snd_dma_program(chip->dma8, runtime->dma_addr, 178 size, DMA_MODE_WRITE | DMA_AUTOINIT); 179 return 0; 180 } 181 182 static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, 183 int cmd) 184 { 185 unsigned long flags; 186 struct snd_sb *chip = snd_pcm_substream_chip(substream); 187 unsigned int count; 188 189 spin_lock_irqsave(&chip->reg_lock, flags); 190 switch (cmd) { 191 case SNDRV_PCM_TRIGGER_START: 192 snd_sbdsp_command(chip, chip->playback_format); 193 if (chip->playback_format == SB_DSP_OUTPUT) { 194 count = chip->p_period_size - 1; 195 snd_sbdsp_command(chip, count & 0xff); 196 snd_sbdsp_command(chip, count >> 8); 197 } 198 break; 199 case SNDRV_PCM_TRIGGER_STOP: 200 if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) { 201 struct snd_pcm_runtime *runtime = substream->runtime; 202 snd_sbdsp_reset(chip); 203 if (runtime->channels > 1) { 204 spin_lock(&chip->mixer_lock); 205 /* restore output filter and set hardware to mono mode */ 206 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02); 207 spin_unlock(&chip->mixer_lock); 208 } 209 } else { 210 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); 211 } 212 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 213 } 214 spin_unlock_irqrestore(&chip->reg_lock, flags); 215 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT; 216 return 0; 217 } 218 219 static int snd_sb8_hw_params(struct snd_pcm_substream *substream, 220 struct snd_pcm_hw_params *hw_params) 221 { 222 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 223 } 224 225 static int snd_sb8_hw_free(struct snd_pcm_substream *substream) 226 { 227 snd_pcm_lib_free_pages(substream); 228 return 0; 229 } 230 231 static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) 232 { 233 unsigned long flags; 234 struct snd_sb *chip = snd_pcm_substream_chip(substream); 235 struct snd_pcm_runtime *runtime = substream->runtime; 236 unsigned int mixreg, rate, size, count; 237 238 rate = runtime->rate; 239 switch (chip->hardware) { 240 case SB_HW_PRO: 241 if (runtime->channels > 1) { 242 if (snd_BUG_ON(rate != SB8_RATE(11025) && 243 rate != SB8_RATE(22050))) 244 return -EINVAL; 245 chip->capture_format = SB_DSP_HI_INPUT_AUTO; 246 break; 247 } 248 chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO; 249 break; 250 case SB_HW_201: 251 if (rate > 13000) { 252 chip->capture_format = SB_DSP_HI_INPUT_AUTO; 253 break; 254 } 255 /* fallthru */ 256 case SB_HW_20: 257 chip->capture_format = SB_DSP_LO_INPUT_AUTO; 258 break; 259 case SB_HW_10: 260 chip->capture_format = SB_DSP_INPUT; 261 break; 262 default: 263 return -EINVAL; 264 } 265 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); 266 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); 267 spin_lock_irqsave(&chip->reg_lock, flags); 268 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 269 if (runtime->channels > 1) 270 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); 271 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 272 if (runtime->channels > 1) { 273 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 274 spin_lock(&chip->mixer_lock); 275 /* save input filter status and turn it off */ 276 mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT); 277 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20); 278 spin_unlock(&chip->mixer_lock); 279 /* just use force_mode16 for temporary storate... */ 280 chip->force_mode16 = mixreg; 281 } else { 282 snd_sbdsp_command(chip, 256 - runtime->rate_den); 283 } 284 if (chip->capture_format != SB_DSP_INPUT) { 285 count--; 286 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 287 snd_sbdsp_command(chip, count & 0xff); 288 snd_sbdsp_command(chip, count >> 8); 289 } 290 spin_unlock_irqrestore(&chip->reg_lock, flags); 291 snd_dma_program(chip->dma8, runtime->dma_addr, 292 size, DMA_MODE_READ | DMA_AUTOINIT); 293 return 0; 294 } 295 296 static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, 297 int cmd) 298 { 299 unsigned long flags; 300 struct snd_sb *chip = snd_pcm_substream_chip(substream); 301 unsigned int count; 302 303 spin_lock_irqsave(&chip->reg_lock, flags); 304 switch (cmd) { 305 case SNDRV_PCM_TRIGGER_START: 306 snd_sbdsp_command(chip, chip->capture_format); 307 if (chip->capture_format == SB_DSP_INPUT) { 308 count = chip->c_period_size - 1; 309 snd_sbdsp_command(chip, count & 0xff); 310 snd_sbdsp_command(chip, count >> 8); 311 } 312 break; 313 case SNDRV_PCM_TRIGGER_STOP: 314 if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) { 315 struct snd_pcm_runtime *runtime = substream->runtime; 316 snd_sbdsp_reset(chip); 317 if (runtime->channels > 1) { 318 /* restore input filter status */ 319 spin_lock(&chip->mixer_lock); 320 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16); 321 spin_unlock(&chip->mixer_lock); 322 /* set hardware to mono mode */ 323 snd_sbdsp_command(chip, SB_DSP_MONO_8BIT); 324 } 325 } else { 326 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); 327 } 328 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 329 } 330 spin_unlock_irqrestore(&chip->reg_lock, flags); 331 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT; 332 return 0; 333 } 334 335 irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) 336 { 337 struct snd_pcm_substream *substream; 338 struct snd_pcm_runtime *runtime; 339 340 snd_sb_ack_8bit(chip); 341 switch (chip->mode) { 342 case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ 343 substream = chip->playback_substream; 344 runtime = substream->runtime; 345 if (chip->playback_format == SB_DSP_OUTPUT) 346 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); 347 snd_pcm_period_elapsed(substream); 348 break; 349 case SB_MODE_CAPTURE_8: 350 substream = chip->capture_substream; 351 runtime = substream->runtime; 352 if (chip->capture_format == SB_DSP_INPUT) 353 snd_sb8_capture_trigger(substream, SNDRV_PCM_TRIGGER_START); 354 snd_pcm_period_elapsed(substream); 355 break; 356 } 357 return IRQ_HANDLED; 358 } 359 360 static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *substream) 361 { 362 struct snd_sb *chip = snd_pcm_substream_chip(substream); 363 size_t ptr; 364 365 if (chip->mode != SB_MODE_PLAYBACK_8) 366 return 0; 367 ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); 368 return bytes_to_frames(substream->runtime, ptr); 369 } 370 371 static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *substream) 372 { 373 struct snd_sb *chip = snd_pcm_substream_chip(substream); 374 size_t ptr; 375 376 if (chip->mode != SB_MODE_CAPTURE_8) 377 return 0; 378 ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); 379 return bytes_to_frames(substream->runtime, ptr); 380 } 381 382 /* 383 384 */ 385 386 static struct snd_pcm_hardware snd_sb8_playback = 387 { 388 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 389 SNDRV_PCM_INFO_MMAP_VALID), 390 .formats = SNDRV_PCM_FMTBIT_U8, 391 .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 | 392 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050), 393 .rate_min = 4000, 394 .rate_max = 23000, 395 .channels_min = 1, 396 .channels_max = 1, 397 .buffer_bytes_max = 65536, 398 .period_bytes_min = 64, 399 .period_bytes_max = 65536, 400 .periods_min = 1, 401 .periods_max = 1024, 402 .fifo_size = 0, 403 }; 404 405 static struct snd_pcm_hardware snd_sb8_capture = 406 { 407 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 408 SNDRV_PCM_INFO_MMAP_VALID), 409 .formats = SNDRV_PCM_FMTBIT_U8, 410 .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 | 411 SNDRV_PCM_RATE_11025), 412 .rate_min = 4000, 413 .rate_max = 13000, 414 .channels_min = 1, 415 .channels_max = 1, 416 .buffer_bytes_max = 65536, 417 .period_bytes_min = 64, 418 .period_bytes_max = 65536, 419 .periods_min = 1, 420 .periods_max = 1024, 421 .fifo_size = 0, 422 }; 423 424 /* 425 * 426 */ 427 428 static int snd_sb8_open(struct snd_pcm_substream *substream) 429 { 430 struct snd_sb *chip = snd_pcm_substream_chip(substream); 431 struct snd_pcm_runtime *runtime = substream->runtime; 432 unsigned long flags; 433 434 spin_lock_irqsave(&chip->open_lock, flags); 435 if (chip->open) { 436 spin_unlock_irqrestore(&chip->open_lock, flags); 437 return -EAGAIN; 438 } 439 chip->open |= SB_OPEN_PCM; 440 spin_unlock_irqrestore(&chip->open_lock, flags); 441 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 442 chip->playback_substream = substream; 443 runtime->hw = snd_sb8_playback; 444 } else { 445 chip->capture_substream = substream; 446 runtime->hw = snd_sb8_capture; 447 } 448 switch (chip->hardware) { 449 case SB_HW_PRO: 450 runtime->hw.rate_max = 44100; 451 runtime->hw.channels_max = 2; 452 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 453 snd_sb8_hw_constraint_rate_channels, NULL, 454 SNDRV_PCM_HW_PARAM_CHANNELS, 455 SNDRV_PCM_HW_PARAM_RATE, -1); 456 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 457 snd_sb8_hw_constraint_channels_rate, NULL, 458 SNDRV_PCM_HW_PARAM_RATE, -1); 459 break; 460 case SB_HW_201: 461 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 462 runtime->hw.rate_max = 44100; 463 } else { 464 runtime->hw.rate_max = 15000; 465 } 466 default: 467 break; 468 } 469 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 470 &hw_constraints_clock); 471 return 0; 472 } 473 474 static int snd_sb8_close(struct snd_pcm_substream *substream) 475 { 476 unsigned long flags; 477 struct snd_sb *chip = snd_pcm_substream_chip(substream); 478 479 chip->playback_substream = NULL; 480 chip->capture_substream = NULL; 481 spin_lock_irqsave(&chip->open_lock, flags); 482 chip->open &= ~SB_OPEN_PCM; 483 spin_unlock_irqrestore(&chip->open_lock, flags); 484 return 0; 485 } 486 487 /* 488 * Initialization part 489 */ 490 491 static struct snd_pcm_ops snd_sb8_playback_ops = { 492 .open = snd_sb8_open, 493 .close = snd_sb8_close, 494 .ioctl = snd_pcm_lib_ioctl, 495 .hw_params = snd_sb8_hw_params, 496 .hw_free = snd_sb8_hw_free, 497 .prepare = snd_sb8_playback_prepare, 498 .trigger = snd_sb8_playback_trigger, 499 .pointer = snd_sb8_playback_pointer, 500 }; 501 502 static struct snd_pcm_ops snd_sb8_capture_ops = { 503 .open = snd_sb8_open, 504 .close = snd_sb8_close, 505 .ioctl = snd_pcm_lib_ioctl, 506 .hw_params = snd_sb8_hw_params, 507 .hw_free = snd_sb8_hw_free, 508 .prepare = snd_sb8_capture_prepare, 509 .trigger = snd_sb8_capture_trigger, 510 .pointer = snd_sb8_capture_pointer, 511 }; 512 513 int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) 514 { 515 struct snd_card *card = chip->card; 516 struct snd_pcm *pcm; 517 int err; 518 519 if (rpcm) 520 *rpcm = NULL; 521 if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0) 522 return err; 523 sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); 524 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 525 pcm->private_data = chip; 526 527 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); 528 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); 529 530 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 531 snd_dma_isa_data(), 532 64*1024, 64*1024); 533 534 if (rpcm) 535 *rpcm = pcm; 536 return 0; 537 } 538 539 EXPORT_SYMBOL(snd_sb8dsp_pcm); 540 EXPORT_SYMBOL(snd_sb8dsp_interrupt); 541 /* sb8_midi.c */ 542 EXPORT_SYMBOL(snd_sb8dsp_midi_interrupt); 543 EXPORT_SYMBOL(snd_sb8dsp_midi); 544 545 /* 546 * INIT part 547 */ 548 549 static int __init alsa_sb8_init(void) 550 { 551 return 0; 552 } 553 554 static void __exit alsa_sb8_exit(void) 555 { 556 } 557 558 module_init(alsa_sb8_init) 559 module_exit(alsa_sb8_exit) 560