sound/pci/oxygen/xonar_wm87x6.c

Source file repositories/reference/linux-study-clean/sound/pci/oxygen/xonar_wm87x6.c

File Facts

System
Linux kernel
Corpus path
sound/pci/oxygen/xonar_wm87x6.c
Extension
.c
Size
38448 bytes
Lines
1323
Domain
Driver Families
Bucket
sound/pci
Inferred role
Driver Families: implementation source
Status
source 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

struct xonar_wm87x6 {
	struct xonar_generic generic;
	u16 wm8776_regs[0x17];
	u16 wm8766_regs[0x10];
	struct snd_kcontrol *line_adcmux_control;
	struct snd_kcontrol *mic_adcmux_control;
	struct snd_kcontrol *lc_controls[13];
	struct snd_jack *hp_jack;
	struct xonar_hdmi hdmi;
};

static void wm8776_write_spi(struct oxygen *chip,
			     unsigned int reg, unsigned int value)
{
	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
			 OXYGEN_SPI_DATA_LENGTH_2 |
			 OXYGEN_SPI_CLOCK_160 |
			 (1 << OXYGEN_SPI_CODEC_SHIFT) |
			 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
			 (reg << 9) | value);
}

static void wm8776_write_i2c(struct oxygen *chip,
			     unsigned int reg, unsigned int value)
{
	oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
			 (reg << 1) | (value >> 8), value);
}

static void wm8776_write(struct oxygen *chip,
			 unsigned int reg, unsigned int value)
{
	struct xonar_wm87x6 *data = chip->model_data;

	if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
	    OXYGEN_FUNCTION_SPI)
		wm8776_write_spi(chip, reg, value);
	else
		wm8776_write_i2c(chip, reg, value);
	if (reg < ARRAY_SIZE(data->wm8776_regs)) {
		/* reg >= WM8776_HPLVOL is always true */
		if (reg <= WM8776_DACMASTER)
			value &= ~WM8776_UPDATE;
		data->wm8776_regs[reg] = value;
	}
}

static void wm8776_write_cached(struct oxygen *chip,
				unsigned int reg, unsigned int value)
{
	struct xonar_wm87x6 *data = chip->model_data;

	if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
	    value != data->wm8776_regs[reg])
		wm8776_write(chip, reg, value);
}

static void wm8766_write(struct oxygen *chip,
			 unsigned int reg, unsigned int value)
{
	struct xonar_wm87x6 *data = chip->model_data;

	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
			 OXYGEN_SPI_DATA_LENGTH_2 |
			 OXYGEN_SPI_CLOCK_160 |
			 (0 << OXYGEN_SPI_CODEC_SHIFT) |
			 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
			 (reg << 9) | value);
	if (reg < ARRAY_SIZE(data->wm8766_regs)) {
		/* reg >= WM8766_LDA1 is always true */
		if (reg <= WM8766_RDA1 ||
		    (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
			value &= ~WM8766_UPDATE;
		data->wm8766_regs[reg] = value;
	}
}

static void wm8766_write_cached(struct oxygen *chip,
				unsigned int reg, unsigned int value)
{
	struct xonar_wm87x6 *data = chip->model_data;

	if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
	    value != data->wm8766_regs[reg])
		wm8766_write(chip, reg, value);
}

static void wm8776_registers_init(struct oxygen *chip)
{
	struct xonar_wm87x6 *data = chip->model_data;

Annotation

Implementation Notes