Esempio n. 1
0
void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file)
{
	if ((file ? file->f_mode : chip->mode) & FMODE_READ) {
		clear_bit(F_READING, &chip->flags);
		snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP);
		snd_msnd_disable_irq(chip);
		if (file) {
			snd_printd(KERN_INFO LOGNAME
				   ": Stopping read for %p\n", file);
			chip->mode &= ~FMODE_READ;
		}
		clear_bit(F_AUDIO_READ_INUSE, &chip->flags);
	}
	if ((file ? file->f_mode : chip->mode) & FMODE_WRITE) {
		if (test_bit(F_WRITING, &chip->flags)) {
			snd_msnd_dsp_write_flush(chip);
			snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP);
		}
		snd_msnd_disable_irq(chip);
		if (file) {
			snd_printd(KERN_INFO
				   LOGNAME ": Stopping write for %p\n", file);
			chip->mode &= ~FMODE_WRITE;
		}
		clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags);
	}
}
Esempio n. 2
0
static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd)
{
	if (snd_msnd_send_dsp_cmd(chip, cmd) == 0)
		return 0;
	snd_msnd_dsp_full_reset(chip->card);
	return snd_msnd_send_dsp_cmd(chip, cmd);
}
Esempio n. 3
0
static int snd_msndmix_set_mux(struct snd_msnd *chip, int val)
{
	unsigned newrecsrc;
	int change;
	unsigned char msndbyte;

	switch (val) {
	case 0:
		newrecsrc = MSND_MASK_IMIX;
		msndbyte = HDEXAR_SET_ANA_IN;
		break;
	case 1:
		newrecsrc = MSND_MASK_SYNTH;
		msndbyte = HDEXAR_SET_SYNTH_IN;
		break;
	case 2:
		newrecsrc = MSND_MASK_DIGITAL;
		msndbyte = HDEXAR_SET_DAT_IN;
		break;
	default:
		return -EINVAL;
	}
	change  = newrecsrc != chip->recsrc;
	if (change) {
		change = 0;
		if (!snd_msnd_send_word(chip, 0, 0, msndbyte))
			if (!snd_msnd_send_dsp_cmd(chip, HDEX_AUX_REQ)) {
				chip->recsrc = newrecsrc;
				change = 1;
			}
	}
	return change;
}
Esempio n. 4
0
int snd_msnd_DAPQ(struct snd_msnd *chip, int start)
{
	u16	DAPQ_tail;
	int	protect = start, nbanks = 0;
	void	*DAQD;
	static int play_banks_submitted;
	/* unsigned long flags;
	spin_lock_irqsave(&chip->lock, flags); not necessary */

	DAPQ_tail = readw(chip->DAPQ + JQS_wTail);
	while (DAPQ_tail != readw(chip->DAPQ + JQS_wHead) || start) {
		int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);

		if (start) {
			start = 0;
			play_banks_submitted = 0;
		}

		/* Get our digital audio queue struct */
		DAQD = bank_num * DAQDS__size + chip->mappedbase +
			DAPQ_DATA_BUFF;

		/* Write size of this bank */
		writew(chip->play_period_bytes, DAQD + DAQDS_wSize);
		if (play_banks_submitted < 3)
			++play_banks_submitted;
		else if (chip->playPeriods == 2) {
			unsigned short offset = chip->play_period_bytes;

			if (readw(DAQD + DAQDS_wStart) != PCTODSP_BASED(0x0))
				offset = 0;

			writew(PCTODSP_BASED(offset), DAQD + DAQDS_wStart);
		}
		++nbanks;

		/* Then advance the tail */
		/*
		if (protect)
			snd_printd(KERN_INFO "B %X %lX\n",
				   bank_num, xtime.tv_usec);
		*/

		DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);
		writew(DAPQ_tail, chip->DAPQ + JQS_wTail);
		/* Tell the DSP to play the bank */
		snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_START);
		if (protect)
			if (2 == bank_num)
				break;
	}
	/*
	if (protect)
		snd_printd(KERN_INFO "%lX\n", xtime.tv_usec);
	*/
	/* spin_unlock_irqrestore(&chip->lock, flags); not necessary */
	return nbanks;
}
Esempio n. 5
0
static int snd_msnd_capture_trigger(struct snd_pcm_substream *substream,
				    int cmd)
{
	struct snd_msnd *chip = snd_pcm_substream_chip(substream);

	if (cmd == SNDRV_PCM_TRIGGER_START) {
		chip->last_recbank = -1;
		set_bit(F_READING, &chip->flags);
		if (snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_START) == 0)
			return 0;

		clear_bit(F_READING, &chip->flags);
	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
		clear_bit(F_READING, &chip->flags);
		snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP);
		return 0;
	}
	return -EINVAL;
}
Esempio n. 6
0
static int snd_msndmidi_input_close(struct snd_rawmidi_substream *substream)
{
	struct snd_msndmidi *mpu;

	mpu = substream->rmidi->private_data;
	snd_msnd_send_dsp_cmd(mpu->dev, HDEX_MIDI_IN_STOP);
	clear_bit(MSNDMIDI_MODE_BIT_INPUT, &mpu->mode);
	mpu->substream_input = NULL;
	snd_msnd_disable_irq(mpu->dev);
	return 0;
}
Esempio n. 7
0
/*
 * input/output open/close - protected by open_mutex in rawmidi.c
 */
static int snd_msndmidi_input_open(struct snd_rawmidi_substream *substream)
{
	struct snd_msndmidi *mpu;

	snd_printdd("snd_msndmidi_input_open()\n");

	mpu = substream->rmidi->private_data;

	mpu->substream_input = substream;

	snd_msnd_enable_irq(mpu->dev);

	snd_msnd_send_dsp_cmd(mpu->dev, HDEX_MIDI_IN_START);
	set_bit(MSNDMIDI_MODE_BIT_INPUT, &mpu->mode);
	return 0;
}
Esempio n. 8
0
static int snd_msnd_playback_trigger(struct snd_pcm_substream *substream,
				     int cmd)
{
	struct snd_msnd *chip = snd_pcm_substream_chip(substream);
	int	result = 0;

	if (cmd == SNDRV_PCM_TRIGGER_START) {
		snd_printdd("snd_msnd_playback_trigger(START)\n");
		chip->banksPlayed = 0;
		set_bit(F_WRITING, &chip->flags);
		snd_msnd_DAPQ(chip, 1);
	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
		snd_printdd("snd_msnd_playback_trigger(STop)\n");
		/* interrupt diagnostic, comment this out later */
		clear_bit(F_WRITING, &chip->flags);
		snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP);
	} else {
		snd_printd(KERN_ERR "snd_msnd_playback_trigger(?????)\n");
		result = -EINVAL;
	}

	snd_printdd("snd_msnd_playback_trigger() ENDE\n");
	return result;
}
Esempio n. 9
0
static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu)
{
	snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_STOP);
	snd_msnd_disable_irq(mpu->private_data);
}
Esempio n. 10
0
/*
 * ALSA callback function, called when attempting to open the MIDI device.
 */
static int snd_msnd_mpu401_open(struct snd_mpu401 *mpu)
{
	snd_msnd_enable_irq(mpu->private_data);
	snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_START);
	return 0;
}
Esempio n. 11
0
static int snd_msndmix_set(struct snd_msnd *dev, int d, int left, int right)
{
	int bLeft, bRight;
	int wLeft, wRight;
	int updatemaster = 0;

	if (d >= LEVEL_ENTRIES)
		return -EINVAL;

	bLeft = left * 0xff / 100;
	wLeft = left * 0xffff / 100;

	bRight = right * 0xff / 100;
	wRight = right * 0xffff / 100;

	dev->left_levels[d] = wLeft;
	dev->right_levels[d] = wRight;

	switch (d) {
		/* master volume unscaled controls */
	case MSND_MIXER_LINE:			/* line pot control */
		/* scaled by IMIX in digital mix */
		writeb(bLeft, dev->SMA + SMA_bInPotPosLeft);
		writeb(bRight, dev->SMA + SMA_bInPotPosRight);
		if (snd_msnd_send_word(dev, 0, 0, HDEXAR_IN_SET_POTS) == 0)
			snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ);
		break;
	case MSND_MIXER_MIC:			/* mic pot control */
		if (dev->type == msndClassic)
			return -EINVAL;
		/* scaled by IMIX in digital mix */
		writeb(bLeft, dev->SMA + SMA_bMicPotPosLeft);
		writeb(bRight, dev->SMA + SMA_bMicPotPosRight);
		if (snd_msnd_send_word(dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
			snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ);
		break;
	case MSND_MIXER_VOLUME:		/* master volume */
		writew(wLeft, dev->SMA + SMA_wCurrMastVolLeft);
		writew(wRight, dev->SMA + SMA_wCurrMastVolRight);
		/* fall through */

	case MSND_MIXER_AUX:			/* aux pot control */
		/* scaled by master volume */
		/* fall through */

		/* digital controls */
	case MSND_MIXER_SYNTH:			/* synth vol (dsp mix) */
	case MSND_MIXER_PCM:			/* pcm vol (dsp mix) */
	case MSND_MIXER_IMIX:			/* input monitor (dsp mix) */
		/* scaled by master volume */
		updatemaster = 1;
		break;

	default:
		return -EINVAL;
	}

	if (updatemaster) {
		/* update master volume scaled controls */
		update_volm(MSND_MIXER_PCM, wCurrPlayVol);
		update_volm(MSND_MIXER_IMIX, wCurrInVol);
		if (dev->type == msndPinnacle)
			update_volm(MSND_MIXER_SYNTH, wCurrMHdrVol);
		update_potm(MSND_MIXER_AUX, bAuxPotPos, HDEXAR_AUX_SET_POTS);
	}

	return 0;
}