brintos

brintos / linux-shallow public Read only

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