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