sound/isa/sb/sb_common.c

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

File Facts

System
Linux kernel
Corpus path
sound/isa/sb/sb_common.c
Extension
.c
Size
5733 bytes
Lines
258
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 ((inb(SBP(chip, STATUS)) & 0x80) == 0) {
			outb(val, SBP(chip, COMMAND));
			return 1;
		}
	dev_dbg(chip->card->dev, "%s [0x%lx]: timeout (0x%x)\n", __func__, chip->port, val);
	return 0;
}

int snd_sbdsp_get_byte(struct snd_sb *chip)
{
	int val;
	int i;
	for (i = BUSY_LOOPS; i; i--) {
		if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
			val = inb(SBP(chip, READ));
#ifdef IO_DEBUG
			dev_dbg(chip->card->dev, "get_byte 0x%x\n", val);
#endif
			return val;
		}
	}
	dev_dbg(chip->card->dev, "%s [0x%lx]: timeout\n", __func__, chip->port);
	return -ENODEV;
}

int snd_sbdsp_reset(struct snd_sb *chip)
{
	int i;

	outb(1, SBP(chip, RESET));
	udelay(10);
	outb(0, SBP(chip, RESET));
	udelay(30);
	for (i = BUSY_LOOPS; i; i--)
		if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
			if (inb(SBP(chip, READ)) == 0xaa)
				return 0;
			else
				break;
		}
	if (chip->card)
		dev_dbg(chip->card->dev, "%s [0x%lx] failed...\n", __func__, chip->port);
	return -ENODEV;
}

static int snd_sbdsp_version(struct snd_sb * chip)
{
	unsigned int result;

	snd_sbdsp_command(chip, SB_DSP_GET_VERSION);
	result = (short) snd_sbdsp_get_byte(chip) << 8;
	result |= (short) snd_sbdsp_get_byte(chip);
	return result;
}

static int snd_sbdsp_probe(struct snd_sb * chip)
{
	int version;
	int major, minor;
	char *str;

	/*
	 *  initialization sequence
	 */

	scoped_guard(spinlock_irqsave, &chip->reg_lock) {
		if (snd_sbdsp_reset(chip) < 0)
			return -ENODEV;
		version = snd_sbdsp_version(chip);
		if (version < 0)
			return -ENODEV;
	}
	major = version >> 8;
	minor = version & 0xff;
	dev_dbg(chip->card->dev, "SB [0x%lx]: DSP chip found, version = %i.%i\n",
		chip->port, major, minor);

	switch (chip->hardware) {
	case SB_HW_AUTO:
		switch (major) {
		case 1:
			chip->hardware = SB_HW_10;
			str = "1.0";
			break;
		case 2:
			if (minor) {
				chip->hardware = SB_HW_201;
				str = "2.01+";
			} else {
				chip->hardware = SB_HW_20;

Annotation

Implementation Notes