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