Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);