sound/isa/es1688/es1688_lib.c

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

File Facts

System
Linux kernel
Corpus path
sound/isa/es1688/es1688_lib.c
Extension
.c
Size
28327 bytes
Lines
976
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(ES1688P(chip, STATUS)) & 0x80) == 0) {
			outb(val, ES1688P(chip, COMMAND));
			return 1;
		}
	dev_dbg(chip->card->dev, "%s: timeout (0x%x)\n", __func__, val);
	return 0;
}

static int snd_es1688_dsp_get_byte(struct snd_es1688 *chip)
{
	int i;

	for (i = 1000; i; i--)
		if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80)
			return inb(ES1688P(chip, READ));
	dev_dbg(chip->card->dev, "es1688 get byte failed: 0x%lx = 0x%x!!!\n",
		ES1688P(chip, DATA_AVAIL), inb(ES1688P(chip, DATA_AVAIL)));
	return -ENODEV;
}

static int snd_es1688_write(struct snd_es1688 *chip,
			    unsigned char reg, unsigned char data)
{
	if (!snd_es1688_dsp_command(chip, reg))
		return 0;
	return snd_es1688_dsp_command(chip, data);
}

static int snd_es1688_read(struct snd_es1688 *chip, unsigned char reg)
{
	/* Read a byte from an extended mode register of ES1688 */
	if (!snd_es1688_dsp_command(chip, 0xc0))
		return -1;
	if (!snd_es1688_dsp_command(chip, reg))
		return -1;
	return snd_es1688_dsp_get_byte(chip);
}

void snd_es1688_mixer_write(struct snd_es1688 *chip,
			    unsigned char reg, unsigned char data)
{
	outb(reg, ES1688P(chip, MIXER_ADDR));
	udelay(10);
	outb(data, ES1688P(chip, MIXER_DATA));
	udelay(10);
}

static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned char reg)
{
	unsigned char result;

	outb(reg, ES1688P(chip, MIXER_ADDR));
	udelay(10);
	result = inb(ES1688P(chip, MIXER_DATA));
	udelay(10);
	return result;
}

int snd_es1688_reset(struct snd_es1688 *chip)
{
	int i;

	outb(3, ES1688P(chip, RESET));		/* valid only for ESS chips, SB -> 1 */
	udelay(10);
	outb(0, ES1688P(chip, RESET));
	udelay(30);
	for (i = 0; i < 1000 && !(inb(ES1688P(chip, DATA_AVAIL)) & 0x80); i++);
	if (inb(ES1688P(chip, READ)) != 0xaa) {
		dev_dbg(chip->card->dev, "ess_reset at 0x%lx: failed!!!\n",
			chip->port);
		return -ENODEV;
	}
	snd_es1688_dsp_command(chip, 0xc6);	/* enable extended mode */
	return 0;
}
EXPORT_SYMBOL(snd_es1688_reset);

static int snd_es1688_probe(struct snd_es1688 *chip)
{
	unsigned short major, minor;
	int i;

	/*
	 *  initialization sequence
	 */

	scoped_guard(spinlock_irqsave, &chip->reg_lock) {	/* Some ESS1688 cards need this */
		inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
		inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
		inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */

Annotation

Implementation Notes