0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/io.h>
0020 #include <asm/dma.h>
0021 #include <linux/init.h>
0022 #include <linux/time.h>
0023 #include <linux/module.h>
0024 #include <sound/core.h>
0025 #include <sound/sb.h>
0026
0027 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Uros Bizjak <uros@kss-loka.si>");
0028 MODULE_DESCRIPTION("Routines for control of 8-bit SoundBlaster cards and clones");
0029 MODULE_LICENSE("GPL");
0030
0031 #define SB8_CLOCK 1000000
0032 #define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v))
0033 #define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v))
0034
0035 static const struct snd_ratnum clock = {
0036 .num = SB8_CLOCK,
0037 .den_min = 1,
0038 .den_max = 256,
0039 .den_step = 1,
0040 };
0041
0042 static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = {
0043 .nrats = 1,
0044 .rats = &clock,
0045 };
0046
0047 static const struct snd_ratnum stereo_clocks[] = {
0048 {
0049 .num = SB8_CLOCK,
0050 .den_min = SB8_DEN(22050),
0051 .den_max = SB8_DEN(22050),
0052 .den_step = 1,
0053 },
0054 {
0055 .num = SB8_CLOCK,
0056 .den_min = SB8_DEN(11025),
0057 .den_max = SB8_DEN(11025),
0058 .den_step = 1,
0059 }
0060 };
0061
0062 static int snd_sb8_hw_constraint_rate_channels(struct snd_pcm_hw_params *params,
0063 struct snd_pcm_hw_rule *rule)
0064 {
0065 struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
0066 if (c->min > 1) {
0067 unsigned int num = 0, den = 0;
0068 int err = snd_interval_ratnum(hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE),
0069 2, stereo_clocks, &num, &den);
0070 if (err >= 0 && den) {
0071 params->rate_num = num;
0072 params->rate_den = den;
0073 }
0074 return err;
0075 }
0076 return 0;
0077 }
0078
0079 static int snd_sb8_hw_constraint_channels_rate(struct snd_pcm_hw_params *params,
0080 struct snd_pcm_hw_rule *rule)
0081 {
0082 struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
0083 if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) {
0084 struct snd_interval t = { .min = 1, .max = 1 };
0085 return snd_interval_refine(hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS), &t);
0086 }
0087 return 0;
0088 }
0089
0090 static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
0091 {
0092 unsigned long flags;
0093 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0094 struct snd_pcm_runtime *runtime = substream->runtime;
0095 unsigned int mixreg, rate, size, count;
0096 unsigned char format;
0097 unsigned char stereo = runtime->channels > 1;
0098 int dma;
0099
0100 rate = runtime->rate;
0101 switch (chip->hardware) {
0102 case SB_HW_JAZZ16:
0103 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
0104 if (chip->mode & SB_MODE_CAPTURE_16)
0105 return -EBUSY;
0106 else
0107 chip->mode |= SB_MODE_PLAYBACK_16;
0108 }
0109 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
0110 break;
0111 case SB_HW_PRO:
0112 if (runtime->channels > 1) {
0113 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
0114 rate != SB8_RATE(22050)))
0115 return -EINVAL;
0116 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
0117 break;
0118 }
0119 fallthrough;
0120 case SB_HW_201:
0121 if (rate > 23000) {
0122 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
0123 break;
0124 }
0125 fallthrough;
0126 case SB_HW_20:
0127 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
0128 break;
0129 case SB_HW_10:
0130 chip->playback_format = SB_DSP_OUTPUT;
0131 break;
0132 default:
0133 return -EINVAL;
0134 }
0135 if (chip->mode & SB_MODE_PLAYBACK_16) {
0136 format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
0137 dma = chip->dma16;
0138 } else {
0139 format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
0140 chip->mode |= SB_MODE_PLAYBACK_8;
0141 dma = chip->dma8;
0142 }
0143 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
0144 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
0145 spin_lock_irqsave(&chip->reg_lock, flags);
0146 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
0147 if (chip->hardware == SB_HW_JAZZ16)
0148 snd_sbdsp_command(chip, format);
0149 else if (stereo) {
0150
0151 spin_lock(&chip->mixer_lock);
0152 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
0153 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02);
0154 spin_unlock(&chip->mixer_lock);
0155
0156
0157 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
0158 runtime->dma_area[0] = 0x80;
0159 snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
0160
0161 snd_sbdsp_command(chip, SB_DSP_OUTPUT);
0162 snd_sbdsp_command(chip, 0);
0163 snd_sbdsp_command(chip, 0);
0164 }
0165 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
0166 if (stereo) {
0167 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
0168 spin_lock(&chip->mixer_lock);
0169
0170 mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT);
0171 snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20);
0172 spin_unlock(&chip->mixer_lock);
0173
0174 chip->force_mode16 = mixreg;
0175 } else {
0176 snd_sbdsp_command(chip, 256 - runtime->rate_den);
0177 }
0178 if (chip->playback_format != SB_DSP_OUTPUT) {
0179 if (chip->mode & SB_MODE_PLAYBACK_16)
0180 count /= 2;
0181 count--;
0182 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
0183 snd_sbdsp_command(chip, count & 0xff);
0184 snd_sbdsp_command(chip, count >> 8);
0185 }
0186 spin_unlock_irqrestore(&chip->reg_lock, flags);
0187 snd_dma_program(dma, runtime->dma_addr,
0188 size, DMA_MODE_WRITE | DMA_AUTOINIT);
0189 return 0;
0190 }
0191
0192 static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
0193 int cmd)
0194 {
0195 unsigned long flags;
0196 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0197 unsigned int count;
0198
0199 spin_lock_irqsave(&chip->reg_lock, flags);
0200 switch (cmd) {
0201 case SNDRV_PCM_TRIGGER_START:
0202 snd_sbdsp_command(chip, chip->playback_format);
0203 if (chip->playback_format == SB_DSP_OUTPUT) {
0204 count = chip->p_period_size - 1;
0205 snd_sbdsp_command(chip, count & 0xff);
0206 snd_sbdsp_command(chip, count >> 8);
0207 }
0208 break;
0209 case SNDRV_PCM_TRIGGER_STOP:
0210 if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) {
0211 struct snd_pcm_runtime *runtime = substream->runtime;
0212 snd_sbdsp_reset(chip);
0213 if (runtime->channels > 1) {
0214 spin_lock(&chip->mixer_lock);
0215
0216 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02);
0217 spin_unlock(&chip->mixer_lock);
0218 }
0219 } else {
0220 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
0221 }
0222 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
0223 }
0224 spin_unlock_irqrestore(&chip->reg_lock, flags);
0225 return 0;
0226 }
0227
0228 static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
0229 {
0230 unsigned long flags;
0231 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0232 struct snd_pcm_runtime *runtime = substream->runtime;
0233 unsigned int mixreg, rate, size, count;
0234 unsigned char format;
0235 unsigned char stereo = runtime->channels > 1;
0236 int dma;
0237
0238 rate = runtime->rate;
0239 switch (chip->hardware) {
0240 case SB_HW_JAZZ16:
0241 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
0242 if (chip->mode & SB_MODE_PLAYBACK_16)
0243 return -EBUSY;
0244 else
0245 chip->mode |= SB_MODE_CAPTURE_16;
0246 }
0247 chip->capture_format = SB_DSP_LO_INPUT_AUTO;
0248 break;
0249 case SB_HW_PRO:
0250 if (runtime->channels > 1) {
0251 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
0252 rate != SB8_RATE(22050)))
0253 return -EINVAL;
0254 chip->capture_format = SB_DSP_HI_INPUT_AUTO;
0255 break;
0256 }
0257 chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO;
0258 break;
0259 case SB_HW_201:
0260 if (rate > 13000) {
0261 chip->capture_format = SB_DSP_HI_INPUT_AUTO;
0262 break;
0263 }
0264 fallthrough;
0265 case SB_HW_20:
0266 chip->capture_format = SB_DSP_LO_INPUT_AUTO;
0267 break;
0268 case SB_HW_10:
0269 chip->capture_format = SB_DSP_INPUT;
0270 break;
0271 default:
0272 return -EINVAL;
0273 }
0274 if (chip->mode & SB_MODE_CAPTURE_16) {
0275 format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
0276 dma = chip->dma16;
0277 } else {
0278 format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
0279 chip->mode |= SB_MODE_CAPTURE_8;
0280 dma = chip->dma8;
0281 }
0282 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
0283 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
0284 spin_lock_irqsave(&chip->reg_lock, flags);
0285 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
0286 if (chip->hardware == SB_HW_JAZZ16)
0287 snd_sbdsp_command(chip, format);
0288 else if (stereo)
0289 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
0290 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
0291 if (stereo) {
0292 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
0293 spin_lock(&chip->mixer_lock);
0294
0295 mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT);
0296 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20);
0297 spin_unlock(&chip->mixer_lock);
0298
0299 chip->force_mode16 = mixreg;
0300 } else {
0301 snd_sbdsp_command(chip, 256 - runtime->rate_den);
0302 }
0303 if (chip->capture_format != SB_DSP_INPUT) {
0304 if (chip->mode & SB_MODE_PLAYBACK_16)
0305 count /= 2;
0306 count--;
0307 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
0308 snd_sbdsp_command(chip, count & 0xff);
0309 snd_sbdsp_command(chip, count >> 8);
0310 }
0311 spin_unlock_irqrestore(&chip->reg_lock, flags);
0312 snd_dma_program(dma, runtime->dma_addr,
0313 size, DMA_MODE_READ | DMA_AUTOINIT);
0314 return 0;
0315 }
0316
0317 static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
0318 int cmd)
0319 {
0320 unsigned long flags;
0321 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0322 unsigned int count;
0323
0324 spin_lock_irqsave(&chip->reg_lock, flags);
0325 switch (cmd) {
0326 case SNDRV_PCM_TRIGGER_START:
0327 snd_sbdsp_command(chip, chip->capture_format);
0328 if (chip->capture_format == SB_DSP_INPUT) {
0329 count = chip->c_period_size - 1;
0330 snd_sbdsp_command(chip, count & 0xff);
0331 snd_sbdsp_command(chip, count >> 8);
0332 }
0333 break;
0334 case SNDRV_PCM_TRIGGER_STOP:
0335 if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) {
0336 struct snd_pcm_runtime *runtime = substream->runtime;
0337 snd_sbdsp_reset(chip);
0338 if (runtime->channels > 1) {
0339
0340 spin_lock(&chip->mixer_lock);
0341 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16);
0342 spin_unlock(&chip->mixer_lock);
0343
0344 snd_sbdsp_command(chip, SB_DSP_MONO_8BIT);
0345 }
0346 } else {
0347 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
0348 }
0349 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
0350 }
0351 spin_unlock_irqrestore(&chip->reg_lock, flags);
0352 return 0;
0353 }
0354
0355 irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
0356 {
0357 struct snd_pcm_substream *substream;
0358
0359 snd_sb_ack_8bit(chip);
0360 switch (chip->mode) {
0361 case SB_MODE_PLAYBACK_16:
0362 if (chip->hardware != SB_HW_JAZZ16)
0363 break;
0364 fallthrough;
0365 case SB_MODE_PLAYBACK_8:
0366 substream = chip->playback_substream;
0367 if (chip->playback_format == SB_DSP_OUTPUT)
0368 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START);
0369 snd_pcm_period_elapsed(substream);
0370 break;
0371 case SB_MODE_CAPTURE_16:
0372 if (chip->hardware != SB_HW_JAZZ16)
0373 break;
0374 fallthrough;
0375 case SB_MODE_CAPTURE_8:
0376 substream = chip->capture_substream;
0377 if (chip->capture_format == SB_DSP_INPUT)
0378 snd_sb8_capture_trigger(substream, SNDRV_PCM_TRIGGER_START);
0379 snd_pcm_period_elapsed(substream);
0380 break;
0381 }
0382 return IRQ_HANDLED;
0383 }
0384
0385 static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *substream)
0386 {
0387 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0388 size_t ptr;
0389 int dma;
0390
0391 if (chip->mode & SB_MODE_PLAYBACK_8)
0392 dma = chip->dma8;
0393 else if (chip->mode & SB_MODE_PLAYBACK_16)
0394 dma = chip->dma16;
0395 else
0396 return 0;
0397 ptr = snd_dma_pointer(dma, chip->p_dma_size);
0398 return bytes_to_frames(substream->runtime, ptr);
0399 }
0400
0401 static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *substream)
0402 {
0403 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0404 size_t ptr;
0405 int dma;
0406
0407 if (chip->mode & SB_MODE_CAPTURE_8)
0408 dma = chip->dma8;
0409 else if (chip->mode & SB_MODE_CAPTURE_16)
0410 dma = chip->dma16;
0411 else
0412 return 0;
0413 ptr = snd_dma_pointer(dma, chip->c_dma_size);
0414 return bytes_to_frames(substream->runtime, ptr);
0415 }
0416
0417
0418
0419
0420
0421 static const struct snd_pcm_hardware snd_sb8_playback =
0422 {
0423 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
0424 SNDRV_PCM_INFO_MMAP_VALID),
0425 .formats = SNDRV_PCM_FMTBIT_U8,
0426 .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 |
0427 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050),
0428 .rate_min = 4000,
0429 .rate_max = 23000,
0430 .channels_min = 1,
0431 .channels_max = 1,
0432 .buffer_bytes_max = 65536,
0433 .period_bytes_min = 64,
0434 .period_bytes_max = 65536,
0435 .periods_min = 1,
0436 .periods_max = 1024,
0437 .fifo_size = 0,
0438 };
0439
0440 static const struct snd_pcm_hardware snd_sb8_capture =
0441 {
0442 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
0443 SNDRV_PCM_INFO_MMAP_VALID),
0444 .formats = SNDRV_PCM_FMTBIT_U8,
0445 .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 |
0446 SNDRV_PCM_RATE_11025),
0447 .rate_min = 4000,
0448 .rate_max = 13000,
0449 .channels_min = 1,
0450 .channels_max = 1,
0451 .buffer_bytes_max = 65536,
0452 .period_bytes_min = 64,
0453 .period_bytes_max = 65536,
0454 .periods_min = 1,
0455 .periods_max = 1024,
0456 .fifo_size = 0,
0457 };
0458
0459
0460
0461
0462
0463 static int snd_sb8_open(struct snd_pcm_substream *substream)
0464 {
0465 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0466 struct snd_pcm_runtime *runtime = substream->runtime;
0467 unsigned long flags;
0468
0469 spin_lock_irqsave(&chip->open_lock, flags);
0470 if (chip->open) {
0471 spin_unlock_irqrestore(&chip->open_lock, flags);
0472 return -EAGAIN;
0473 }
0474 chip->open |= SB_OPEN_PCM;
0475 spin_unlock_irqrestore(&chip->open_lock, flags);
0476 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0477 chip->playback_substream = substream;
0478 runtime->hw = snd_sb8_playback;
0479 } else {
0480 chip->capture_substream = substream;
0481 runtime->hw = snd_sb8_capture;
0482 }
0483 switch (chip->hardware) {
0484 case SB_HW_JAZZ16:
0485 if (chip->dma16 == 5 || chip->dma16 == 7)
0486 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
0487 runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000;
0488 runtime->hw.rate_min = 4000;
0489 runtime->hw.rate_max = 50000;
0490 runtime->hw.channels_max = 2;
0491 break;
0492 case SB_HW_PRO:
0493 runtime->hw.rate_max = 44100;
0494 runtime->hw.channels_max = 2;
0495 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0496 snd_sb8_hw_constraint_rate_channels, NULL,
0497 SNDRV_PCM_HW_PARAM_CHANNELS,
0498 SNDRV_PCM_HW_PARAM_RATE, -1);
0499 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0500 snd_sb8_hw_constraint_channels_rate, NULL,
0501 SNDRV_PCM_HW_PARAM_RATE, -1);
0502 break;
0503 case SB_HW_201:
0504 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0505 runtime->hw.rate_max = 44100;
0506 } else {
0507 runtime->hw.rate_max = 15000;
0508 }
0509 break;
0510 default:
0511 break;
0512 }
0513 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0514 &hw_constraints_clock);
0515 if (chip->dma8 > 3 || chip->dma16 >= 0) {
0516 snd_pcm_hw_constraint_step(runtime, 0,
0517 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2);
0518 snd_pcm_hw_constraint_step(runtime, 0,
0519 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2);
0520 runtime->hw.buffer_bytes_max = 128 * 1024 * 1024;
0521 runtime->hw.period_bytes_max = 128 * 1024 * 1024;
0522 }
0523 return 0;
0524 }
0525
0526 static int snd_sb8_close(struct snd_pcm_substream *substream)
0527 {
0528 unsigned long flags;
0529 struct snd_sb *chip = snd_pcm_substream_chip(substream);
0530
0531 chip->playback_substream = NULL;
0532 chip->capture_substream = NULL;
0533 spin_lock_irqsave(&chip->open_lock, flags);
0534 chip->open &= ~SB_OPEN_PCM;
0535 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0536 chip->mode &= ~SB_MODE_PLAYBACK;
0537 else
0538 chip->mode &= ~SB_MODE_CAPTURE;
0539 spin_unlock_irqrestore(&chip->open_lock, flags);
0540 return 0;
0541 }
0542
0543
0544
0545
0546
0547 static const struct snd_pcm_ops snd_sb8_playback_ops = {
0548 .open = snd_sb8_open,
0549 .close = snd_sb8_close,
0550 .prepare = snd_sb8_playback_prepare,
0551 .trigger = snd_sb8_playback_trigger,
0552 .pointer = snd_sb8_playback_pointer,
0553 };
0554
0555 static const struct snd_pcm_ops snd_sb8_capture_ops = {
0556 .open = snd_sb8_open,
0557 .close = snd_sb8_close,
0558 .prepare = snd_sb8_capture_prepare,
0559 .trigger = snd_sb8_capture_trigger,
0560 .pointer = snd_sb8_capture_pointer,
0561 };
0562
0563 int snd_sb8dsp_pcm(struct snd_sb *chip, int device)
0564 {
0565 struct snd_card *card = chip->card;
0566 struct snd_pcm *pcm;
0567 int err;
0568 size_t max_prealloc = 64 * 1024;
0569
0570 err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm);
0571 if (err < 0)
0572 return err;
0573 sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
0574 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
0575 pcm->private_data = chip;
0576
0577 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops);
0578 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops);
0579
0580 if (chip->dma8 > 3 || chip->dma16 >= 0)
0581 max_prealloc = 128 * 1024;
0582 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
0583 card->dev, 64*1024, max_prealloc);
0584
0585 return 0;
0586 }
0587
0588 EXPORT_SYMBOL(snd_sb8dsp_pcm);
0589 EXPORT_SYMBOL(snd_sb8dsp_interrupt);
0590
0591 EXPORT_SYMBOL(snd_sb8dsp_midi_interrupt);
0592 EXPORT_SYMBOL(snd_sb8dsp_midi);