sound/isa/msnd/msnd.c

Source file repositories/reference/linux-study-clean/sound/isa/msnd/msnd.c

File Facts

System
Linux kernel
Corpus path
sound/isa/msnd/msnd.c
Extension
.c
Size
19097 bytes
Lines
698
Domain
Driver Families
Bucket
sound/isa
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (file) {
			dev_dbg(chip->card->dev, 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) {
			dev_dbg(chip->card->dev,
				LOGNAME ": Stopping write for %p\n", file);
			chip->mode &= ~FMODE_WRITE;
		}
		clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags);
	}
}
EXPORT_SYMBOL(snd_msnd_dsp_halt);


int snd_msnd_DARQ(struct snd_msnd *chip, int bank)
{
	int /*size, n,*/ timeout = 3;
	u16 wTmp;
	/* void *DAQD; */

	/* Increment the tail and check for queue wrap */
	wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
	if (wTmp > readw(chip->DARQ + JQS_wSize))
		wTmp = 0;
	while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--)
		udelay(1);

	if (chip->capturePeriods == 2) {
		void __iomem *pDAQ = chip->mappedbase + DARQ_DATA_BUFF +
			     bank * DAQDS__size + DAQDS_wStart;
		unsigned short offset = 0x3000 + chip->capturePeriodBytes;

		if (readw(pDAQ) != PCTODSP_BASED(0x3000))
			offset = 0x3000;
		writew(PCTODSP_BASED(offset), pDAQ);
	}

	writew(wTmp, chip->DARQ + JQS_wTail);

#if 0
	/* Get our digital audio queue struct */
	DAQD = bank * DAQDS__size + chip->mappedbase + DARQ_DATA_BUFF;

	/* Get length of data */
	size = readw(DAQD + DAQDS_wSize);

	/* Read data from the head (unprotected bank 1 access okay
	   since this is only called inside an interrupt) */
	outb(HPBLKSEL_1, chip->io + HP_BLKS);
	n = msnd_fifo_write(&chip->DARF,
			    (char *)(chip->base + bank * DAR_BUFF_SIZE),
			    size, 0);
	if (n <= 0) {
		outb(HPBLKSEL_0, chip->io + HP_BLKS);
		return n;
	}
	outb(HPBLKSEL_0, chip->io + HP_BLKS);
#endif

	return 1;
}
EXPORT_SYMBOL(snd_msnd_DARQ);

int snd_msnd_DAPQ(struct snd_msnd *chip, int start)
{
	u16	DAPQ_tail;
	int	protect = start, nbanks = 0;
	void	__iomem *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;
		}

Annotation

Implementation Notes