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 snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); 115 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; 116 break; 117 } 118 /* fallthru */ 119 case SB_HW_201: 120 if (rate > 23000) { 121 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; 122 break; 123 } 124 /* fallthru */ 125 case SB_HW_20: 126 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; 127 break; 128 case SB_HW_10: 129 chip->playback_format = SB_DSP_OUTPUT; 130 break; 131 default: 132 return -EINVAL; 133 } 134 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); 135 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); 136 spin_lock_irqsave(&chip->reg_lock, flags); 137 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); 138 if (runtime->channels > 1) { 139 /* set playback stereo mode */ 140 spin_lock(&chip->mixer_lock); 141 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); 142 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02); 143 spin_unlock(&chip->mixer_lock); 144 145 /* Soundblaster hardware programming reference guide, 3-23 */ 146 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); 147 runtime->dma_area[0] = 0x80; 148 snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); 149 /* force interrupt */ 150 chip->mode = SB_MODE_HALT; 151 snd_sbdsp_command(chip, SB_DSP_OUTPUT); 152 snd_sbdsp_command(chip, 0); 153 snd_sbdsp_command(chip, 0); 154 } 155 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 156 if (runtime->channels > 1) { 157 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 158 spin_lock(&chip->mixer_lock); 159 /* save output filter status and turn it off */ 160 mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT); 161 snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20); 162 spin_unlock(&chip->mixer_lock); 163 /* just use force_mode16 for temporary storate... */ 164 chip->force_mode16 = mixreg; 165 } else { 166 snd_sbdsp_command(chip, 256 - runtime->rate_den); 167 } 168 if (chip->playback_format != SB_DSP_OUTPUT) { 169 count--; 170 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 171 snd_sbdsp_command(chip, count & 0xff); 172 snd_sbdsp_command(chip, count >> 8); 173 } 174 spin_unlock_irqrestore(&chip->reg_lock, flags); 175 snd_dma_program(chip->dma8, runtime->dma_addr, 176 size, DMA_MODE_WRITE | DMA_AUTOINIT); 177 return 0; 178 } 179 180 static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, 181 int cmd) 182 { 183 unsigned long flags; 184 struct snd_sb *chip = snd_pcm_substream_chip(substream); 185 unsigned int count; 186 187 spin_lock_irqsave(&chip->reg_lock, flags); 188 switch (cmd) { 189 case SNDRV_PCM_TRIGGER_START: 190 snd_sbdsp_command(chip, chip->playback_format); 191 if (chip->playback_format == SB_DSP_OUTPUT) { 192 count = chip->p_period_size - 1; 193 snd_sbdsp_command(chip, count & 0xff); 194 snd_sbdsp_command(chip, count >> 8); 195 } 196 break; 197 case SNDRV_PCM_TRIGGER_STOP: 198 if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) { 199 struct snd_pcm_runtime *runtime = substream->runtime; 200 snd_sbdsp_reset(chip); 201 if (runtime->channels > 1) { 202 spin_lock(&chip->mixer_lock); 203 /* restore output filter and set hardware to mono mode */ 204 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02); 205 spin_unlock(&chip->mixer_lock); 206 } 207 } else { 208 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); 209 } 210 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 211 } 212 spin_unlock_irqrestore(&chip->reg_lock, flags); 213 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT; 214 return 0; 215 } 216 217 static int snd_sb8_hw_params(struct snd_pcm_substream *substream, 218 struct snd_pcm_hw_params *hw_params) 219 { 220 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 221 } 222 223 static int snd_sb8_hw_free(struct snd_pcm_substream *substream) 224 { 225 snd_pcm_lib_free_pages(substream); 226 return 0; 227 } 228 229 static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) 230 { 231 unsigned long flags; 232 struct snd_sb *chip = snd_pcm_substream_chip(substream); 233 struct snd_pcm_runtime *runtime = substream->runtime; 234 unsigned int mixreg, rate, size, count; 235 236 rate = runtime->rate; 237 switch (chip->hardware) { 238 case SB_HW_PRO: 239 if (runtime->channels > 1) { 240 snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); 241 chip->capture_format = SB_DSP_HI_INPUT_AUTO; 242 break; 243 } 244 chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO; 245 break; 246 case SB_HW_201: 247 if (rate > 13000) { 248 chip->capture_format = SB_DSP_HI_INPUT_AUTO; 249 break; 250 } 251 /* fallthru */ 252 case SB_HW_20: 253 chip->capture_format = SB_DSP_LO_INPUT_AUTO; 254 break; 255 case SB_HW_10: 256 chip->capture_format = SB_DSP_INPUT; 257 break; 258 default: 259 return -EINVAL; 260 } 261 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); 262 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); 263 spin_lock_irqsave(&chip->reg_lock, flags); 264 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 265 if (runtime->channels > 1) 266 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); 267 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 268 if (runtime->channels > 1) { 269 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 270 spin_lock(&chip->mixer_lock); 271 /* save input filter status and turn it off */ 272 mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT); 273 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20); 274 spin_unlock(&chip->mixer_lock); 275 /* just use force_mode16 for temporary storate... */ 276 chip->force_mode16 = mixreg; 277 } else { 278 snd_sbdsp_command(chip, 256 - runtime->rate_den); 279 } 280 if (chip->capture_format != SB_DSP_INPUT) { 281 count--; 282 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 283 snd_sbdsp_command(chip, count & 0xff); 284 snd_sbdsp_command(chip, count >> 8); 285 } 286 spin_unlock_irqrestore(&chip->reg_lock, flags); 287 snd_dma_program(chip->dma8, runtime->dma_addr, 288 size, DMA_MODE_READ | DMA_AUTOINIT); 289 return 0; 290 } 291 292 static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, 293 int cmd) 294 { 295 unsigned long flags; 296 struct snd_sb *chip = snd_pcm_substream_chip(substream); 297 unsigned int count; 298 299 spin_lock_irqsave(&chip->reg_lock, flags); 300 switch (cmd) { 301 case SNDRV_PCM_TRIGGER_START: 302 snd_sbdsp_command(chip, chip->capture_format); 303 if (chip->capture_format == SB_DSP_INPUT) { 304 count = chip->c_period_size - 1; 305 snd_sbdsp_command(chip, count & 0xff); 306 snd_sbdsp_command(chip, count >> 8); 307 } 308 break; 309 case SNDRV_PCM_TRIGGER_STOP: 310 if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) { 311 struct snd_pcm_runtime *runtime = substream->runtime; 312 snd_sbdsp_reset(chip); 313 if (runtime->channels > 1) { 314 /* restore input filter status */ 315 spin_lock(&chip->mixer_lock); 316 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16); 317 spin_unlock(&chip->mixer_lock); 318 /* set hardware to mono mode */ 319 snd_sbdsp_command(chip, SB_DSP_MONO_8BIT); 320 } 321 } else { 322 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); 323 } 324 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 325 } 326 spin_unlock_irqrestore(&chip->reg_lock, flags); 327 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT; 328 return 0; 329 } 330 331 irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) 332 { 333 struct snd_pcm_substream *substream; 334 struct snd_pcm_runtime *runtime; 335 336 snd_sb_ack_8bit(chip); 337 switch (chip->mode) { 338 case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ 339 substream = chip->playback_substream; 340 runtime = substream->runtime; 341 if (chip->playback_format == SB_DSP_OUTPUT) 342 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); 343 snd_pcm_period_elapsed(substream); 344 break; 345 case SB_MODE_CAPTURE_8: 346 substream = chip->capture_substream; 347 runtime = substream->runtime; 348 if (chip->capture_format == SB_DSP_INPUT) 349 snd_sb8_capture_trigger(substream, SNDRV_PCM_TRIGGER_START); 350 snd_pcm_period_elapsed(substream); 351 break; 352 } 353 return IRQ_HANDLED; 354 } 355 356 static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *substream) 357 { 358 struct snd_sb *chip = snd_pcm_substream_chip(substream); 359 size_t ptr; 360 361 if (chip->mode != SB_MODE_PLAYBACK_8) 362 return 0; 363 ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); 364 return bytes_to_frames(substream->runtime, ptr); 365 } 366 367 static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *substream) 368 { 369 struct snd_sb *chip = snd_pcm_substream_chip(substream); 370 size_t ptr; 371 372 if (chip->mode != SB_MODE_CAPTURE_8) 373 return 0; 374 ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); 375 return bytes_to_frames(substream->runtime, ptr); 376 } 377 378 /* 379 380 */ 381 382 static struct snd_pcm_hardware snd_sb8_playback = 383 { 384 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 385 SNDRV_PCM_INFO_MMAP_VALID), 386 .formats = SNDRV_PCM_FMTBIT_U8, 387 .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 | 388 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050), 389 .rate_min = 4000, 390 .rate_max = 23000, 391 .channels_min = 1, 392 .channels_max = 1, 393 .buffer_bytes_max = 65536, 394 .period_bytes_min = 64, 395 .period_bytes_max = 65536, 396 .periods_min = 1, 397 .periods_max = 1024, 398 .fifo_size = 0, 399 }; 400 401 static struct snd_pcm_hardware snd_sb8_capture = 402 { 403 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 404 SNDRV_PCM_INFO_MMAP_VALID), 405 .formats = SNDRV_PCM_FMTBIT_U8, 406 .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 | 407 SNDRV_PCM_RATE_11025), 408 .rate_min = 4000, 409 .rate_max = 13000, 410 .channels_min = 1, 411 .channels_max = 1, 412 .buffer_bytes_max = 65536, 413 .period_bytes_min = 64, 414 .period_bytes_max = 65536, 415 .periods_min = 1, 416 .periods_max = 1024, 417 .fifo_size = 0, 418 }; 419 420 /* 421 * 422 */ 423 424 static int snd_sb8_open(struct snd_pcm_substream *substream) 425 { 426 struct snd_sb *chip = snd_pcm_substream_chip(substream); 427 struct snd_pcm_runtime *runtime = substream->runtime; 428 unsigned long flags; 429 430 spin_lock_irqsave(&chip->open_lock, flags); 431 if (chip->open) { 432 spin_unlock_irqrestore(&chip->open_lock, flags); 433 return -EAGAIN; 434 } 435 chip->open |= SB_OPEN_PCM; 436 spin_unlock_irqrestore(&chip->open_lock, flags); 437 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 438 chip->playback_substream = substream; 439 runtime->hw = snd_sb8_playback; 440 } else { 441 chip->capture_substream = substream; 442 runtime->hw = snd_sb8_capture; 443 } 444 switch (chip->hardware) { 445 case SB_HW_PRO: 446 runtime->hw.rate_max = 44100; 447 runtime->hw.channels_max = 2; 448 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 449 snd_sb8_hw_constraint_rate_channels, NULL, 450 SNDRV_PCM_HW_PARAM_CHANNELS, 451 SNDRV_PCM_HW_PARAM_RATE, -1); 452 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 453 snd_sb8_hw_constraint_channels_rate, NULL, 454 SNDRV_PCM_HW_PARAM_RATE, -1); 455 break; 456 case SB_HW_201: 457 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 458 runtime->hw.rate_max = 44100; 459 } else { 460 runtime->hw.rate_max = 15000; 461 } 462 default: 463 break; 464 } 465 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 466 &hw_constraints_clock); 467 return 0; 468 } 469 470 static int snd_sb8_close(struct snd_pcm_substream *substream) 471 { 472 unsigned long flags; 473 struct snd_sb *chip = snd_pcm_substream_chip(substream); 474 475 chip->playback_substream = NULL; 476 chip->capture_substream = NULL; 477 spin_lock_irqsave(&chip->open_lock, flags); 478 chip->open &= ~SB_OPEN_PCM; 479 spin_unlock_irqrestore(&chip->open_lock, flags); 480 return 0; 481 } 482 483 /* 484 * Initialization part 485 */ 486 487 static struct snd_pcm_ops snd_sb8_playback_ops = { 488 .open = snd_sb8_open, 489 .close = snd_sb8_close, 490 .ioctl = snd_pcm_lib_ioctl, 491 .hw_params = snd_sb8_hw_params, 492 .hw_free = snd_sb8_hw_free, 493 .prepare = snd_sb8_playback_prepare, 494 .trigger = snd_sb8_playback_trigger, 495 .pointer = snd_sb8_playback_pointer, 496 }; 497 498 static struct snd_pcm_ops snd_sb8_capture_ops = { 499 .open = snd_sb8_open, 500 .close = snd_sb8_close, 501 .ioctl = snd_pcm_lib_ioctl, 502 .hw_params = snd_sb8_hw_params, 503 .hw_free = snd_sb8_hw_free, 504 .prepare = snd_sb8_capture_prepare, 505 .trigger = snd_sb8_capture_trigger, 506 .pointer = snd_sb8_capture_pointer, 507 }; 508 509 int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) 510 { 511 struct snd_card *card = chip->card; 512 struct snd_pcm *pcm; 513 int err; 514 515 if (rpcm) 516 *rpcm = NULL; 517 if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0) 518 return err; 519 sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); 520 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 521 pcm->private_data = chip; 522 523 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); 524 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); 525 526 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 527 snd_dma_isa_data(), 528 64*1024, 64*1024); 529 530 if (rpcm) 531 *rpcm = pcm; 532 return 0; 533 } 534 535 EXPORT_SYMBOL(snd_sb8dsp_pcm); 536 EXPORT_SYMBOL(snd_sb8dsp_interrupt); 537 /* sb8_midi.c */ 538 EXPORT_SYMBOL(snd_sb8dsp_midi_interrupt); 539 EXPORT_SYMBOL(snd_sb8dsp_midi); 540 541 /* 542 * INIT part 543 */ 544 545 static int __init alsa_sb8_init(void) 546 { 547 return 0; 548 } 549 550 static void __exit alsa_sb8_exit(void) 551 { 552 } 553 554 module_init(alsa_sb8_init) 555 module_exit(alsa_sb8_exit) 556