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