~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/isa/sb/sb16_main.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  4  *  Routines for control of 16-bit SoundBlaster cards and clones
  5  *  Note: This is very ugly hardware which uses one 8-bit DMA channel and
  6  *        second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't
  7  *        transfer 16-bit samples and 16-bit DMA channels can't transfer
  8  *        8-bit samples. This make full duplex more complicated than
  9  *        can be... People, don't buy these soundcards for full 16-bit
 10  *        duplex!!!
 11  *  Note: 16-bit wide is assigned to first direction which made request.
 12  *        With full duplex - playback is preferred with abstract layer.
 13  *
 14  *  Note: Some chip revisions have hardware bug. Changing capture
 15  *        channel from full-duplex 8bit DMA to 16bit DMA will block
 16  *        16bit DMA transfers from DSP chip (capture) until 8bit transfer
 17  *        to DSP chip (playback) starts. This bug can be avoided with
 18  *        "16bit DMA Allocation" setting set to Playback or Capture.
 19  */
 20 
 21 #include <linux/io.h>
 22 #include <asm/dma.h>
 23 #include <linux/init.h>
 24 #include <linux/time.h>
 25 #include <linux/module.h>
 26 #include <sound/core.h>
 27 #include <sound/sb.h>
 28 #include <sound/sb16_csp.h>
 29 #include <sound/mpu401.h>
 30 #include <sound/control.h>
 31 #include <sound/info.h>
 32 
 33 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 34 MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones");
 35 MODULE_LICENSE("GPL");
 36 
 37 #define runtime_format_bits(runtime) \
 38         ((unsigned int)pcm_format_to_bits((runtime)->format))
 39 
 40 #ifdef CONFIG_SND_SB16_CSP
 41 static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 42 {
 43         if (chip->hardware == SB_HW_16CSP) {
 44                 struct snd_sb_csp *csp = chip->csp;
 45 
 46                 if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 47                         /* manually loaded codec */
 48                         if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) &&
 49                             (runtime_format_bits(runtime) == csp->acc_format)) {
 50                                 /* Supported runtime PCM format for playback */
 51                                 if (csp->ops.csp_use(csp) == 0) {
 52                                         /* If CSP was successfully acquired */
 53                                         goto __start_CSP;
 54                                 }
 55                         } else if ((csp->mode & SNDRV_SB_CSP_MODE_QSOUND) && (csp->q_enabled)) {
 56                                 /* QSound decoder is loaded and enabled */
 57                                 if (runtime_format_bits(runtime) & (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
 58                                                               SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE)) {
 59                                         /* Only for simple PCM formats */
 60                                         if (csp->ops.csp_use(csp) == 0) {
 61                                                 /* If CSP was successfully acquired */
 62                                                 goto __start_CSP;
 63                                         }
 64                                 }
 65                         }
 66                 } else if (csp->ops.csp_use(csp) == 0) {
 67                         /* Acquire CSP and try to autoload hardware codec */
 68                         if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_WRITE)) {
 69                                 /* Unsupported format, release CSP */
 70                                 csp->ops.csp_unuse(csp);
 71                         } else {
 72                       __start_CSP:
 73                                 /* Try to start CSP */
 74                                 if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_PLAYBACK_16) ?
 75                                                        SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT,
 76                                                        (runtime->channels > 1) ?
 77                                                        SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) {
 78                                         /* Failed, release CSP */
 79                                         csp->ops.csp_unuse(csp);
 80                                 } else {
 81                                         /* Success, CSP acquired and running */
 82                                         chip->open = SNDRV_SB_CSP_MODE_DSP_WRITE;
 83                                 }
 84                         }
 85                 }
 86         }
 87 }
 88 
 89 static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 90 {
 91         if (chip->hardware == SB_HW_16CSP) {
 92                 struct snd_sb_csp *csp = chip->csp;
 93 
 94                 if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 95                         /* manually loaded codec */
 96                         if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) &&
 97                             (runtime_format_bits(runtime) == csp->acc_format)) {
 98                                 /* Supported runtime PCM format for capture */
 99                                 if (csp->ops.csp_use(csp) == 0) {
100                                         /* If CSP was successfully acquired */
101                                         goto __start_CSP;
102                                 }
103                         }
104                 } else if (csp->ops.csp_use(csp) == 0) {
105                         /* Acquire CSP and try to autoload hardware codec */
106                         if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_READ)) {
107                                 /* Unsupported format, release CSP */
108                                 csp->ops.csp_unuse(csp);
109                         } else {
110                       __start_CSP:
111                                 /* Try to start CSP */
112                                 if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_CAPTURE_16) ?
113                                                        SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT,
114                                                        (runtime->channels > 1) ?
115                                                        SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) {
116                                         /* Failed, release CSP */
117                                         csp->ops.csp_unuse(csp);
118                                 } else {
119                                         /* Success, CSP acquired and running */
120                                         chip->open = SNDRV_SB_CSP_MODE_DSP_READ;
121                                 }
122                         }
123                 }
124         }
125 }
126 
127 static void snd_sb16_csp_update(struct snd_sb *chip)
128 {
129         if (chip->hardware == SB_HW_16CSP) {
130                 struct snd_sb_csp *csp = chip->csp;
131 
132                 if (csp->qpos_changed) {
133                         spin_lock(&chip->reg_lock);
134                         csp->ops.csp_qsound_transfer (csp);
135                         spin_unlock(&chip->reg_lock);
136                 }
137         }
138 }
139 
140 static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
141 {
142         /* CSP decoders (QSound excluded) support only 16bit transfers */
143         if (chip->hardware == SB_HW_16CSP) {
144                 struct snd_sb_csp *csp = chip->csp;
145 
146                 if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
147                         /* manually loaded codec */
148                         if (csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) {
149                                 runtime->hw.formats |= csp->acc_format;
150                         }
151                 } else {
152                         /* autoloaded codecs */
153                         runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
154                                                SNDRV_PCM_FMTBIT_IMA_ADPCM;
155                 }
156         }
157 }
158 
159 static void snd_sb16_csp_playback_close(struct snd_sb *chip)
160 {
161         if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) {
162                 struct snd_sb_csp *csp = chip->csp;
163 
164                 if (csp->ops.csp_stop(csp) == 0) {
165                         csp->ops.csp_unuse(csp);
166                         chip->open = 0;
167                 }
168         }
169 }
170 
171 static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
172 {
173         /* CSP coders support only 16bit transfers */
174         if (chip->hardware == SB_HW_16CSP) {
175                 struct snd_sb_csp *csp = chip->csp;
176 
177                 if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
178                         /* manually loaded codec */
179                         if (csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) {
180                                 runtime->hw.formats |= csp->acc_format;
181                         }
182                 } else {
183                         /* autoloaded codecs */
184                         runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
185                                                SNDRV_PCM_FMTBIT_IMA_ADPCM;
186                 }
187         }
188 }
189 
190 static void snd_sb16_csp_capture_close(struct snd_sb *chip)
191 {
192         if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) {
193                 struct snd_sb_csp *csp = chip->csp;
194 
195                 if (csp->ops.csp_stop(csp) == 0) {
196                         csp->ops.csp_unuse(csp);
197                         chip->open = 0;
198                 }
199         }
200 }
201 #else
202 #define snd_sb16_csp_playback_prepare(chip, runtime)    /*nop*/
203 #define snd_sb16_csp_capture_prepare(chip, runtime)     /*nop*/
204 #define snd_sb16_csp_update(chip)                       /*nop*/
205 #define snd_sb16_csp_playback_open(chip, runtime)       /*nop*/
206 #define snd_sb16_csp_playback_close(chip)               /*nop*/
207 #define snd_sb16_csp_capture_open(chip, runtime)        /*nop*/
208 #define snd_sb16_csp_capture_close(chip)                /*nop*/
209 #endif
210 
211 
212 static void snd_sb16_setup_rate(struct snd_sb *chip,
213                                 unsigned short rate,
214                                 int channel)
215 {
216         unsigned long flags;
217 
218         spin_lock_irqsave(&chip->reg_lock, flags);
219         if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16))
220                 snd_sb_ack_16bit(chip);
221         else
222                 snd_sb_ack_8bit(chip);
223         if (!(chip->mode & SB_RATE_LOCK)) {
224                 chip->locked_rate = rate;
225                 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_IN);
226                 snd_sbdsp_command(chip, rate >> 8);
227                 snd_sbdsp_command(chip, rate & 0xff);
228                 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
229                 snd_sbdsp_command(chip, rate >> 8);
230                 snd_sbdsp_command(chip, rate & 0xff);
231         }
232         spin_unlock_irqrestore(&chip->reg_lock, flags);
233 }
234 
235 static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
236 {
237         unsigned long flags;
238         struct snd_sb *chip = snd_pcm_substream_chip(substream);
239         struct snd_pcm_runtime *runtime = substream->runtime;
240         unsigned char format;
241         unsigned int size, count, dma;
242 
243         snd_sb16_csp_playback_prepare(chip, runtime);
244         if (snd_pcm_format_unsigned(runtime->format) > 0) {
245                 format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO;
246         } else {
247                 format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO;
248         }
249 
250         snd_sb16_setup_rate(chip, runtime->rate, SNDRV_PCM_STREAM_PLAYBACK);
251         size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
252         dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
253         snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
254 
255         count = snd_pcm_lib_period_bytes(substream);
256         spin_lock_irqsave(&chip->reg_lock, flags);
257         if (chip->mode & SB_MODE_PLAYBACK_16) {
258                 count >>= 1;
259                 count--;
260                 snd_sbdsp_command(chip, SB_DSP4_OUT16_AI);
261                 snd_sbdsp_command(chip, format);
262                 snd_sbdsp_command(chip, count & 0xff);
263                 snd_sbdsp_command(chip, count >> 8);
264                 snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
265         } else {
266                 count--;
267                 snd_sbdsp_command(chip, SB_DSP4_OUT8_AI);
268                 snd_sbdsp_command(chip, format);
269                 snd_sbdsp_command(chip, count & 0xff);
270                 snd_sbdsp_command(chip, count >> 8);
271                 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
272         }
273         spin_unlock_irqrestore(&chip->reg_lock, flags);
274         return 0;
275 }
276 
277 static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
278                                      int cmd)
279 {
280         struct snd_sb *chip = snd_pcm_substream_chip(substream);
281         int result = 0;
282 
283         spin_lock(&chip->reg_lock);
284         switch (cmd) {
285         case SNDRV_PCM_TRIGGER_START:
286         case SNDRV_PCM_TRIGGER_RESUME:
287                 chip->mode |= SB_RATE_LOCK_PLAYBACK;
288                 snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
289                 break;
290         case SNDRV_PCM_TRIGGER_STOP:
291         case SNDRV_PCM_TRIGGER_SUSPEND:
292                 snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
293                 /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
294                 if (chip->mode & SB_RATE_LOCK_CAPTURE)
295                         snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
296                 chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
297                 break;
298         default:
299                 result = -EINVAL;
300         }
301         spin_unlock(&chip->reg_lock);
302         return result;
303 }
304 
305 static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
306 {
307         unsigned long flags;
308         struct snd_sb *chip = snd_pcm_substream_chip(substream);
309         struct snd_pcm_runtime *runtime = substream->runtime;
310         unsigned char format;
311         unsigned int size, count, dma;
312 
313         snd_sb16_csp_capture_prepare(chip, runtime);
314         if (snd_pcm_format_unsigned(runtime->format) > 0) {
315                 format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO;
316         } else {
317                 format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO;
318         }
319         snd_sb16_setup_rate(chip, runtime->rate, SNDRV_PCM_STREAM_CAPTURE);
320         size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
321         dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
322         snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
323 
324         count = snd_pcm_lib_period_bytes(substream);
325         spin_lock_irqsave(&chip->reg_lock, flags);
326         if (chip->mode & SB_MODE_CAPTURE_16) {
327                 count >>= 1;
328                 count--;
329                 snd_sbdsp_command(chip, SB_DSP4_IN16_AI);
330                 snd_sbdsp_command(chip, format);
331                 snd_sbdsp_command(chip, count & 0xff);
332                 snd_sbdsp_command(chip, count >> 8);
333                 snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
334         } else {
335                 count--;
336                 snd_sbdsp_command(chip, SB_DSP4_IN8_AI);
337                 snd_sbdsp_command(chip, format);
338                 snd_sbdsp_command(chip, count & 0xff);
339                 snd_sbdsp_command(chip, count >> 8);
340                 snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
341         }
342         spin_unlock_irqrestore(&chip->reg_lock, flags);
343         return 0;
344 }
345 
346 static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
347                                     int cmd)
348 {
349         struct snd_sb *chip = snd_pcm_substream_chip(substream);
350         int result = 0;
351 
352         spin_lock(&chip->reg_lock);
353         switch (cmd) {
354         case SNDRV_PCM_TRIGGER_START:
355         case SNDRV_PCM_TRIGGER_RESUME:
356                 chip->mode |= SB_RATE_LOCK_CAPTURE;
357                 snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
358                 break;
359         case SNDRV_PCM_TRIGGER_STOP:
360         case SNDRV_PCM_TRIGGER_SUSPEND:
361                 snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
362                 /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
363                 if (chip->mode & SB_RATE_LOCK_PLAYBACK)
364                         snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
365                 chip->mode &= ~SB_RATE_LOCK_CAPTURE;
366                 break;
367         default:
368                 result = -EINVAL;
369         }
370         spin_unlock(&chip->reg_lock);
371         return result;
372 }
373 
374 irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
375 {
376         struct snd_sb *chip = dev_id;
377         unsigned char status;
378         int ok;
379 
380         spin_lock(&chip->mixer_lock);
381         status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
382         spin_unlock(&chip->mixer_lock);
383         if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
384                 chip->rmidi_callback(irq, chip->rmidi->private_data);
385         if (status & SB_IRQTYPE_8BIT) {
386                 ok = 0;
387                 if (chip->mode & SB_MODE_PLAYBACK_8) {
388                         snd_pcm_period_elapsed(chip->playback_substream);
389                         snd_sb16_csp_update(chip);
390                         ok++;
391                 }
392                 if (chip->mode & SB_MODE_CAPTURE_8) {
393                         snd_pcm_period_elapsed(chip->capture_substream);
394                         ok++;
395                 }
396                 spin_lock(&chip->reg_lock);
397                 if (!ok)
398                         snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
399                 snd_sb_ack_8bit(chip);
400                 spin_unlock(&chip->reg_lock);
401         }
402         if (status & SB_IRQTYPE_16BIT) {
403                 ok = 0;
404                 if (chip->mode & SB_MODE_PLAYBACK_16) {
405                         snd_pcm_period_elapsed(chip->playback_substream);
406                         snd_sb16_csp_update(chip);
407                         ok++;
408                 }
409                 if (chip->mode & SB_MODE_CAPTURE_16) {
410                         snd_pcm_period_elapsed(chip->capture_substream);
411                         ok++;
412                 }
413                 spin_lock(&chip->reg_lock);
414                 if (!ok)
415                         snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
416                 snd_sb_ack_16bit(chip);
417                 spin_unlock(&chip->reg_lock);
418         }
419         return IRQ_HANDLED;
420 }
421 
422 /*
423 
424  */
425 
426 static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream)
427 {
428         struct snd_sb *chip = snd_pcm_substream_chip(substream);
429         unsigned int dma;
430         size_t ptr;
431 
432         dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
433         ptr = snd_dma_pointer(dma, chip->p_dma_size);
434         return bytes_to_frames(substream->runtime, ptr);
435 }
436 
437 static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream)
438 {
439         struct snd_sb *chip = snd_pcm_substream_chip(substream);
440         unsigned int dma;
441         size_t ptr;
442 
443         dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
444         ptr = snd_dma_pointer(dma, chip->c_dma_size);
445         return bytes_to_frames(substream->runtime, ptr);
446 }
447 
448 /*
449 
450  */
451 
452 static const struct snd_pcm_hardware snd_sb16_playback =
453 {
454         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
455                                  SNDRV_PCM_INFO_MMAP_VALID),
456         .formats =              0,
457         .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
458         .rate_min =             4000,
459         .rate_max =             44100,
460         .channels_min =         1,
461         .channels_max =         2,
462         .buffer_bytes_max =     (128*1024),
463         .period_bytes_min =     64,
464         .period_bytes_max =     (128*1024),
465         .periods_min =          1,
466         .periods_max =          1024,
467         .fifo_size =            0,
468 };
469 
470 static const struct snd_pcm_hardware snd_sb16_capture =
471 {
472         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
473                                  SNDRV_PCM_INFO_MMAP_VALID),
474         .formats =              0,
475         .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
476         .rate_min =             4000,
477         .rate_max =             44100,
478         .channels_min =         1,
479         .channels_max =         2,
480         .buffer_bytes_max =     (128*1024),
481         .period_bytes_min =     64,
482         .period_bytes_max =     (128*1024),
483         .periods_min =          1,
484         .periods_max =          1024,
485         .fifo_size =            0,
486 };
487 
488 /*
489  *  open/close
490  */
491 
492 static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
493 {
494         unsigned long flags;
495         struct snd_sb *chip = snd_pcm_substream_chip(substream);
496         struct snd_pcm_runtime *runtime = substream->runtime;
497 
498         spin_lock_irqsave(&chip->open_lock, flags);
499         if (chip->mode & SB_MODE_PLAYBACK) {
500                 spin_unlock_irqrestore(&chip->open_lock, flags);
501                 return -EAGAIN;
502         }
503         runtime->hw = snd_sb16_playback;
504 
505         /* skip if 16 bit DMA was reserved for capture */
506         if (chip->force_mode16 & SB_MODE_CAPTURE_16)
507                 goto __skip_16bit;
508 
509         if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_CAPTURE_16)) {
510                 chip->mode |= SB_MODE_PLAYBACK_16;
511                 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
512                 /* Vibra16X hack */
513                 if (chip->dma16 <= 3) {
514                         runtime->hw.buffer_bytes_max =
515                         runtime->hw.period_bytes_max = 64 * 1024;
516                 } else {
517                         snd_sb16_csp_playback_open(chip, runtime);
518                 }
519                 goto __open_ok;
520         }
521 
522       __skip_16bit:
523         if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_CAPTURE_8)) {
524                 chip->mode |= SB_MODE_PLAYBACK_8;
525                 /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */
526                 if (chip->dma16 < 0) {
527                         runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
528                         chip->mode |= SB_MODE_PLAYBACK_16;
529                 } else {
530                         runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8;
531                 }
532                 runtime->hw.buffer_bytes_max =
533                 runtime->hw.period_bytes_max = 64 * 1024;
534                 goto __open_ok;
535         }
536         spin_unlock_irqrestore(&chip->open_lock, flags);
537         return -EAGAIN;
538 
539       __open_ok:
540         if (chip->hardware == SB_HW_ALS100)
541                 runtime->hw.rate_max = 48000;
542         if (chip->hardware == SB_HW_CS5530) {
543                 runtime->hw.buffer_bytes_max = 32 * 1024;
544                 runtime->hw.periods_min = 2;
545                 runtime->hw.rate_min = 44100;
546         }
547         if (chip->mode & SB_RATE_LOCK)
548                 runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
549         chip->playback_substream = substream;
550         spin_unlock_irqrestore(&chip->open_lock, flags);
551         return 0;
552 }
553 
554 static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
555 {
556         unsigned long flags;
557         struct snd_sb *chip = snd_pcm_substream_chip(substream);
558 
559         snd_sb16_csp_playback_close(chip);
560         spin_lock_irqsave(&chip->open_lock, flags);
561         chip->playback_substream = NULL;
562         chip->mode &= ~SB_MODE_PLAYBACK;
563         spin_unlock_irqrestore(&chip->open_lock, flags);
564         return 0;
565 }
566 
567 static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
568 {
569         unsigned long flags;
570         struct snd_sb *chip = snd_pcm_substream_chip(substream);
571         struct snd_pcm_runtime *runtime = substream->runtime;
572 
573         spin_lock_irqsave(&chip->open_lock, flags);
574         if (chip->mode & SB_MODE_CAPTURE) {
575                 spin_unlock_irqrestore(&chip->open_lock, flags);
576                 return -EAGAIN;
577         }
578         runtime->hw = snd_sb16_capture;
579 
580         /* skip if 16 bit DMA was reserved for playback */
581         if (chip->force_mode16 & SB_MODE_PLAYBACK_16)
582                 goto __skip_16bit;
583 
584         if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_16)) {
585                 chip->mode |= SB_MODE_CAPTURE_16;
586                 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
587                 /* Vibra16X hack */
588                 if (chip->dma16 <= 3) {
589                         runtime->hw.buffer_bytes_max =
590                         runtime->hw.period_bytes_max = 64 * 1024;
591                 } else {
592                         snd_sb16_csp_capture_open(chip, runtime);
593                 }
594                 goto __open_ok;
595         }
596 
597       __skip_16bit:
598         if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_8)) {
599                 chip->mode |= SB_MODE_CAPTURE_8;
600                 /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */
601                 if (chip->dma16 < 0) {
602                         runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
603                         chip->mode |= SB_MODE_CAPTURE_16;
604                 } else {
605                         runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8;
606                 }
607                 runtime->hw.buffer_bytes_max =
608                 runtime->hw.period_bytes_max = 64 * 1024;
609                 goto __open_ok;
610         }
611         spin_unlock_irqrestore(&chip->open_lock, flags);
612         return -EAGAIN;
613 
614       __open_ok:
615         if (chip->hardware == SB_HW_ALS100)
616                 runtime->hw.rate_max = 48000;
617         if (chip->hardware == SB_HW_CS5530) {
618                 runtime->hw.buffer_bytes_max = 32 * 1024;
619                 runtime->hw.periods_min = 2;
620                 runtime->hw.rate_min = 44100;
621         }
622         if (chip->mode & SB_RATE_LOCK)
623                 runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
624         chip->capture_substream = substream;
625         spin_unlock_irqrestore(&chip->open_lock, flags);
626         return 0;
627 }
628 
629 static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
630 {
631         unsigned long flags;
632         struct snd_sb *chip = snd_pcm_substream_chip(substream);
633 
634         snd_sb16_csp_capture_close(chip);
635         spin_lock_irqsave(&chip->open_lock, flags);
636         chip->capture_substream = NULL;
637         chip->mode &= ~SB_MODE_CAPTURE;
638         spin_unlock_irqrestore(&chip->open_lock, flags);
639         return 0;
640 }
641 
642 /*
643  *  DMA control interface
644  */
645 
646 static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what)
647 {
648         if (chip->dma8 < 0 || chip->dma16 < 0) {
649                 if (snd_BUG_ON(what))
650                         return -EINVAL;
651                 return 0;
652         }
653         if (what == 0) {
654                 chip->force_mode16 = 0;
655         } else if (what == 1) {
656                 chip->force_mode16 = SB_MODE_PLAYBACK_16;
657         } else if (what == 2) {
658                 chip->force_mode16 = SB_MODE_CAPTURE_16;
659         } else {
660                 return -EINVAL;
661         }
662         return 0;
663 }
664 
665 static int snd_sb16_get_dma_mode(struct snd_sb *chip)
666 {
667         if (chip->dma8 < 0 || chip->dma16 < 0)
668                 return 0;
669         switch (chip->force_mode16) {
670         case SB_MODE_PLAYBACK_16:
671                 return 1;
672         case SB_MODE_CAPTURE_16:
673                 return 2;
674         default:
675                 return 0;
676         }
677 }
678 
679 static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
680 {
681         static const char * const texts[3] = {
682                 "Auto", "Playback", "Capture"
683         };
684 
685         return snd_ctl_enum_info(uinfo, 1, 3, texts);
686 }
687 
688 static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
689 {
690         struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
691         unsigned long flags;
692         
693         spin_lock_irqsave(&chip->reg_lock, flags);
694         ucontrol->value.enumerated.item[0] = snd_sb16_get_dma_mode(chip);
695         spin_unlock_irqrestore(&chip->reg_lock, flags);
696         return 0;
697 }
698 
699 static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
700 {
701         struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
702         unsigned long flags;
703         unsigned char nval, oval;
704         int change;
705         
706         nval = ucontrol->value.enumerated.item[0];
707         if (nval > 2)
708                 return -EINVAL;
709         spin_lock_irqsave(&chip->reg_lock, flags);
710         oval = snd_sb16_get_dma_mode(chip);
711         change = nval != oval;
712         snd_sb16_set_dma_mode(chip, nval);
713         spin_unlock_irqrestore(&chip->reg_lock, flags);
714         return change;
715 }
716 
717 static const struct snd_kcontrol_new snd_sb16_dma_control = {
718         .iface = SNDRV_CTL_ELEM_IFACE_CARD,
719         .name = "16-bit DMA Allocation",
720         .info = snd_sb16_dma_control_info,
721         .get = snd_sb16_dma_control_get,
722         .put = snd_sb16_dma_control_put
723 };
724 
725 /*
726  *  Initialization part
727  */
728  
729 int snd_sb16dsp_configure(struct snd_sb * chip)
730 {
731         unsigned long flags;
732         unsigned char irqreg = 0, dmareg = 0, mpureg;
733         unsigned char realirq, realdma, realmpureg;
734         /* note: mpu register should be present only on SB16 Vibra soundcards */
735 
736         // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
737         spin_lock_irqsave(&chip->mixer_lock, flags);
738         mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
739         spin_unlock_irqrestore(&chip->mixer_lock, flags);
740         switch (chip->irq) {
741         case 2:
742         case 9:
743                 irqreg |= SB_IRQSETUP_IRQ9;
744                 break;
745         case 5:
746                 irqreg |= SB_IRQSETUP_IRQ5;
747                 break;
748         case 7:
749                 irqreg |= SB_IRQSETUP_IRQ7;
750                 break;
751         case 10:
752                 irqreg |= SB_IRQSETUP_IRQ10;
753                 break;
754         default:
755                 return -EINVAL;
756         }
757         if (chip->dma8 >= 0) {
758                 switch (chip->dma8) {
759                 case 0:
760                         dmareg |= SB_DMASETUP_DMA0;
761                         break;
762                 case 1:
763                         dmareg |= SB_DMASETUP_DMA1;
764                         break;
765                 case 3:
766                         dmareg |= SB_DMASETUP_DMA3;
767                         break;
768                 default:
769                         return -EINVAL;
770                 }
771         }
772         if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) {
773                 switch (chip->dma16) {
774                 case 5:
775                         dmareg |= SB_DMASETUP_DMA5;
776                         break;
777                 case 6:
778                         dmareg |= SB_DMASETUP_DMA6;
779                         break;
780                 case 7:
781                         dmareg |= SB_DMASETUP_DMA7;
782                         break;
783                 default:
784                         return -EINVAL;
785                 }
786         }
787         switch (chip->mpu_port) {
788         case 0x300:
789                 mpureg |= 0x04;
790                 break;
791         case 0x330:
792                 mpureg |= 0x00;
793                 break;
794         default:
795                 mpureg |= 0x02; /* disable MPU */
796         }
797         spin_lock_irqsave(&chip->mixer_lock, flags);
798 
799         snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
800         realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
801 
802         snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
803         realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
804 
805         snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
806         realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
807 
808         spin_unlock_irqrestore(&chip->mixer_lock, flags);
809         if ((~realirq) & irqreg || (~realdma) & dmareg) {
810                 snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
811                 snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
812                 snd_printk(KERN_ERR "SB16 [0x%lx]:    got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
813                 return -ENODEV;
814         }
815         return 0;
816 }
817 
818 static const struct snd_pcm_ops snd_sb16_playback_ops = {
819         .open =         snd_sb16_playback_open,
820         .close =        snd_sb16_playback_close,
821         .prepare =      snd_sb16_playback_prepare,
822         .trigger =      snd_sb16_playback_trigger,
823         .pointer =      snd_sb16_playback_pointer,
824 };
825 
826 static const struct snd_pcm_ops snd_sb16_capture_ops = {
827         .open =         snd_sb16_capture_open,
828         .close =        snd_sb16_capture_close,
829         .prepare =      snd_sb16_capture_prepare,
830         .trigger =      snd_sb16_capture_trigger,
831         .pointer =      snd_sb16_capture_pointer,
832 };
833 
834 int snd_sb16dsp_pcm(struct snd_sb *chip, int device)
835 {
836         struct snd_card *card = chip->card;
837         struct snd_pcm *pcm;
838         int err;
839 
840         err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm);
841         if (err < 0)
842                 return err;
843         sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
844         pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
845         pcm->private_data = chip;
846         chip->pcm = pcm;
847 
848         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops);
849         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops);
850 
851         if (chip->dma16 >= 0 && chip->dma8 != chip->dma16)
852                 snd_ctl_add(card, snd_ctl_new1(&snd_sb16_dma_control, chip));
853         else
854                 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
855 
856         snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
857                                        card->dev, 64*1024, 128*1024);
858         return 0;
859 }
860 
861 const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction)
862 {
863         return direction == SNDRV_PCM_STREAM_PLAYBACK ?
864                 &snd_sb16_playback_ops : &snd_sb16_capture_ops;
865 }
866 
867 EXPORT_SYMBOL(snd_sb16dsp_pcm);
868 EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops);
869 EXPORT_SYMBOL(snd_sb16dsp_configure);
870 EXPORT_SYMBOL(snd_sb16dsp_interrupt);
871 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php