Lines Matching +full:pcm +full:- +full:clock +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Uros Bizjak <uros@kss-loka.si>
6 * Routines for control of 8-bit SoundBlaster cards and clones
9 * --
12 * DSP can't respond to commands whilst in "high speed" mode. Caused
15 * Wed Jul 12 22:02:55 CEST 2000 Uros Bizjak <uros@kss-loka.si>
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");
35 static const struct snd_ratnum clock = { variable
44 .rats = &clock,
66 if (c->min > 1) { in snd_sb8_hw_constraint_rate_channels()
71 params->rate_num = num; in snd_sb8_hw_constraint_rate_channels()
72 params->rate_den = den; in snd_sb8_hw_constraint_rate_channels()
83 if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) { in snd_sb8_hw_constraint_channels_rate()
94 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sb8_playback_prepare()
97 unsigned char stereo = runtime->channels > 1; in snd_sb8_playback_prepare()
100 rate = runtime->rate; in snd_sb8_playback_prepare()
101 switch (chip->hardware) { in snd_sb8_playback_prepare()
103 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { in snd_sb8_playback_prepare()
104 if (chip->mode & SB_MODE_CAPTURE_16) in snd_sb8_playback_prepare()
105 return -EBUSY; in snd_sb8_playback_prepare()
107 chip->mode |= SB_MODE_PLAYBACK_16; in snd_sb8_playback_prepare()
109 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; in snd_sb8_playback_prepare()
112 if (runtime->channels > 1) { in snd_sb8_playback_prepare()
115 return -EINVAL; in snd_sb8_playback_prepare()
116 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; in snd_sb8_playback_prepare()
122 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; in snd_sb8_playback_prepare()
127 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; in snd_sb8_playback_prepare()
130 chip->playback_format = SB_DSP_OUTPUT; in snd_sb8_playback_prepare()
133 return -EINVAL; in snd_sb8_playback_prepare()
135 if (chip->mode & SB_MODE_PLAYBACK_16) { in snd_sb8_playback_prepare()
137 dma = chip->dma16; in snd_sb8_playback_prepare()
140 chip->mode |= SB_MODE_PLAYBACK_8; in snd_sb8_playback_prepare()
141 dma = chip->dma8; in snd_sb8_playback_prepare()
143 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); in snd_sb8_playback_prepare()
144 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); in snd_sb8_playback_prepare()
145 spin_lock_irqsave(&chip->reg_lock, flags); in snd_sb8_playback_prepare()
147 if (chip->hardware == SB_HW_JAZZ16) in snd_sb8_playback_prepare()
150 /* set playback stereo mode */ in snd_sb8_playback_prepare()
151 spin_lock(&chip->mixer_lock); in snd_sb8_playback_prepare()
154 spin_unlock(&chip->mixer_lock); in snd_sb8_playback_prepare()
156 /* Soundblaster hardware programming reference guide, 3-23 */ in snd_sb8_playback_prepare()
158 runtime->dma_area[0] = 0x80; in snd_sb8_playback_prepare()
159 snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); in snd_sb8_playback_prepare()
167 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); in snd_sb8_playback_prepare()
168 spin_lock(&chip->mixer_lock); in snd_sb8_playback_prepare()
172 spin_unlock(&chip->mixer_lock); in snd_sb8_playback_prepare()
174 chip->force_mode16 = mixreg; in snd_sb8_playback_prepare()
176 snd_sbdsp_command(chip, 256 - runtime->rate_den); in snd_sb8_playback_prepare()
178 if (chip->playback_format != SB_DSP_OUTPUT) { in snd_sb8_playback_prepare()
179 if (chip->mode & SB_MODE_PLAYBACK_16) in snd_sb8_playback_prepare()
181 count--; in snd_sb8_playback_prepare()
186 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_sb8_playback_prepare()
187 snd_dma_program(dma, runtime->dma_addr, in snd_sb8_playback_prepare()
199 spin_lock_irqsave(&chip->reg_lock, flags); in snd_sb8_playback_trigger()
202 snd_sbdsp_command(chip, chip->playback_format); in snd_sb8_playback_trigger()
203 if (chip->playback_format == SB_DSP_OUTPUT) { in snd_sb8_playback_trigger()
204 count = chip->p_period_size - 1; in snd_sb8_playback_trigger()
210 if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) { in snd_sb8_playback_trigger()
211 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sb8_playback_trigger()
213 if (runtime->channels > 1) { in snd_sb8_playback_trigger()
214 spin_lock(&chip->mixer_lock); in snd_sb8_playback_trigger()
215 /* restore output filter and set hardware to mono mode */ in snd_sb8_playback_trigger()
216 snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02); in snd_sb8_playback_trigger()
217 spin_unlock(&chip->mixer_lock); in snd_sb8_playback_trigger()
224 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_sb8_playback_trigger()
232 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sb8_capture_prepare()
235 unsigned char stereo = runtime->channels > 1; in snd_sb8_capture_prepare()
238 rate = runtime->rate; in snd_sb8_capture_prepare()
239 switch (chip->hardware) { in snd_sb8_capture_prepare()
241 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { in snd_sb8_capture_prepare()
242 if (chip->mode & SB_MODE_PLAYBACK_16) in snd_sb8_capture_prepare()
243 return -EBUSY; in snd_sb8_capture_prepare()
245 chip->mode |= SB_MODE_CAPTURE_16; in snd_sb8_capture_prepare()
247 chip->capture_format = SB_DSP_LO_INPUT_AUTO; in snd_sb8_capture_prepare()
250 if (runtime->channels > 1) { in snd_sb8_capture_prepare()
253 return -EINVAL; in snd_sb8_capture_prepare()
254 chip->capture_format = SB_DSP_HI_INPUT_AUTO; in snd_sb8_capture_prepare()
257 chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO; in snd_sb8_capture_prepare()
261 chip->capture_format = SB_DSP_HI_INPUT_AUTO; in snd_sb8_capture_prepare()
266 chip->capture_format = SB_DSP_LO_INPUT_AUTO; in snd_sb8_capture_prepare()
269 chip->capture_format = SB_DSP_INPUT; in snd_sb8_capture_prepare()
272 return -EINVAL; in snd_sb8_capture_prepare()
274 if (chip->mode & SB_MODE_CAPTURE_16) { in snd_sb8_capture_prepare()
276 dma = chip->dma16; in snd_sb8_capture_prepare()
279 chip->mode |= SB_MODE_CAPTURE_8; in snd_sb8_capture_prepare()
280 dma = chip->dma8; in snd_sb8_capture_prepare()
282 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); in snd_sb8_capture_prepare()
283 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); in snd_sb8_capture_prepare()
284 spin_lock_irqsave(&chip->reg_lock, flags); in snd_sb8_capture_prepare()
286 if (chip->hardware == SB_HW_JAZZ16) in snd_sb8_capture_prepare()
292 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); in snd_sb8_capture_prepare()
293 spin_lock(&chip->mixer_lock); in snd_sb8_capture_prepare()
297 spin_unlock(&chip->mixer_lock); in snd_sb8_capture_prepare()
299 chip->force_mode16 = mixreg; in snd_sb8_capture_prepare()
301 snd_sbdsp_command(chip, 256 - runtime->rate_den); in snd_sb8_capture_prepare()
303 if (chip->capture_format != SB_DSP_INPUT) { in snd_sb8_capture_prepare()
304 if (chip->mode & SB_MODE_PLAYBACK_16) in snd_sb8_capture_prepare()
306 count--; in snd_sb8_capture_prepare()
311 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_sb8_capture_prepare()
312 snd_dma_program(dma, runtime->dma_addr, in snd_sb8_capture_prepare()
324 spin_lock_irqsave(&chip->reg_lock, flags); in snd_sb8_capture_trigger()
327 snd_sbdsp_command(chip, chip->capture_format); in snd_sb8_capture_trigger()
328 if (chip->capture_format == SB_DSP_INPUT) { in snd_sb8_capture_trigger()
329 count = chip->c_period_size - 1; in snd_sb8_capture_trigger()
335 if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) { in snd_sb8_capture_trigger()
336 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sb8_capture_trigger()
338 if (runtime->channels > 1) { in snd_sb8_capture_trigger()
340 spin_lock(&chip->mixer_lock); in snd_sb8_capture_trigger()
341 snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16); in snd_sb8_capture_trigger()
342 spin_unlock(&chip->mixer_lock); in snd_sb8_capture_trigger()
343 /* set hardware to mono mode */ in snd_sb8_capture_trigger()
351 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_sb8_capture_trigger()
360 switch (chip->mode) { in snd_sb8dsp_interrupt()
362 if (chip->hardware != SB_HW_JAZZ16) in snd_sb8dsp_interrupt()
366 substream = chip->playback_substream; in snd_sb8dsp_interrupt()
367 if (chip->playback_format == SB_DSP_OUTPUT) in snd_sb8dsp_interrupt()
372 if (chip->hardware != SB_HW_JAZZ16) in snd_sb8dsp_interrupt()
376 substream = chip->capture_substream; in snd_sb8dsp_interrupt()
377 if (chip->capture_format == SB_DSP_INPUT) in snd_sb8dsp_interrupt()
391 if (chip->mode & SB_MODE_PLAYBACK_8) in snd_sb8_playback_pointer()
392 dma = chip->dma8; in snd_sb8_playback_pointer()
393 else if (chip->mode & SB_MODE_PLAYBACK_16) in snd_sb8_playback_pointer()
394 dma = chip->dma16; in snd_sb8_playback_pointer()
397 ptr = snd_dma_pointer(dma, chip->p_dma_size); in snd_sb8_playback_pointer()
398 return bytes_to_frames(substream->runtime, ptr); in snd_sb8_playback_pointer()
407 if (chip->mode & SB_MODE_CAPTURE_8) in snd_sb8_capture_pointer()
408 dma = chip->dma8; in snd_sb8_capture_pointer()
409 else if (chip->mode & SB_MODE_CAPTURE_16) in snd_sb8_capture_pointer()
410 dma = chip->dma16; in snd_sb8_capture_pointer()
413 ptr = snd_dma_pointer(dma, chip->c_dma_size); in snd_sb8_capture_pointer()
414 return bytes_to_frames(substream->runtime, ptr); in snd_sb8_capture_pointer()
466 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sb8_open()
469 spin_lock_irqsave(&chip->open_lock, flags); in snd_sb8_open()
470 if (chip->open) { in snd_sb8_open()
471 spin_unlock_irqrestore(&chip->open_lock, flags); in snd_sb8_open()
472 return -EAGAIN; in snd_sb8_open()
474 chip->open |= SB_OPEN_PCM; in snd_sb8_open()
475 spin_unlock_irqrestore(&chip->open_lock, flags); in snd_sb8_open()
476 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in snd_sb8_open()
477 chip->playback_substream = substream; in snd_sb8_open()
478 runtime->hw = snd_sb8_playback; in snd_sb8_open()
480 chip->capture_substream = substream; in snd_sb8_open()
481 runtime->hw = snd_sb8_capture; in snd_sb8_open()
483 switch (chip->hardware) { in snd_sb8_open()
485 if (chip->dma16 == 5 || chip->dma16 == 7) in snd_sb8_open()
486 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE; in snd_sb8_open()
487 runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000; in snd_sb8_open()
488 runtime->hw.rate_min = 4000; in snd_sb8_open()
489 runtime->hw.rate_max = 50000; in snd_sb8_open()
490 runtime->hw.channels_max = 2; in snd_sb8_open()
493 runtime->hw.rate_max = 44100; in snd_sb8_open()
494 runtime->hw.channels_max = 2; in snd_sb8_open()
498 SNDRV_PCM_HW_PARAM_RATE, -1); in snd_sb8_open()
501 SNDRV_PCM_HW_PARAM_RATE, -1); in snd_sb8_open()
504 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in snd_sb8_open()
505 runtime->hw.rate_max = 44100; in snd_sb8_open()
507 runtime->hw.rate_max = 15000; in snd_sb8_open()
515 if (chip->dma8 > 3 || chip->dma16 >= 0) { in snd_sb8_open()
520 runtime->hw.buffer_bytes_max = 128 * 1024 * 1024; in snd_sb8_open()
521 runtime->hw.period_bytes_max = 128 * 1024 * 1024; in snd_sb8_open()
531 chip->playback_substream = NULL; in snd_sb8_close()
532 chip->capture_substream = NULL; in snd_sb8_close()
533 spin_lock_irqsave(&chip->open_lock, flags); in snd_sb8_close()
534 chip->open &= ~SB_OPEN_PCM; in snd_sb8_close()
535 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in snd_sb8_close()
536 chip->mode &= ~SB_MODE_PLAYBACK; in snd_sb8_close()
538 chip->mode &= ~SB_MODE_CAPTURE; in snd_sb8_close()
539 spin_unlock_irqrestore(&chip->open_lock, flags); in snd_sb8_close()
565 struct snd_card *card = chip->card; in snd_sb8dsp_pcm()
566 struct snd_pcm *pcm; in snd_sb8dsp_pcm() local
570 err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm); in snd_sb8dsp_pcm()
573 sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); in snd_sb8dsp_pcm()
574 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; in snd_sb8dsp_pcm()
575 pcm->private_data = chip; in snd_sb8dsp_pcm()
577 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); in snd_sb8dsp_pcm()
578 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); in snd_sb8dsp_pcm()
580 if (chip->dma8 > 3 || chip->dma16 >= 0) in snd_sb8dsp_pcm()
582 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, in snd_sb8dsp_pcm()
583 card->dev, 64*1024, max_prealloc); in snd_sb8dsp_pcm()