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