sound/pci/oxygen/xonar_pcm179x.c

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

File Facts

System
Linux kernel
Corpus path
sound/pci/oxygen/xonar_pcm179x.c
Extension
.c
Size
34962 bytes
Lines
1349
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_pcm179x {
	struct xonar_generic generic;
	unsigned int dacs;
	u8 pcm1796_regs[4][5];
	unsigned int current_rate;
	bool h6;
	bool hp_active;
	s8 hp_gain_offset;
	bool has_cs2000;
	u8 cs2000_regs[0x1f];
	bool broken_i2c;
};

struct xonar_hdav {
	struct xonar_pcm179x pcm179x;
	struct xonar_hdmi hdmi;
};


static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
				     u8 reg, u8 value)
{
	/* maps ALSA channel pair number to SPI output */
	static const u8 codec_map[4] = {
		0, 1, 2, 4
	};
	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER  |
			 OXYGEN_SPI_DATA_LENGTH_2 |
			 OXYGEN_SPI_CLOCK_160 |
			 (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
			 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
			 (reg << 8) | value);
}

static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
				     u8 reg, u8 value)
{
	oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value);
}

static void pcm1796_write(struct oxygen *chip, unsigned int codec,
			  u8 reg, u8 value)
{
	struct xonar_pcm179x *data = chip->model_data;

	if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
	    OXYGEN_FUNCTION_SPI)
		pcm1796_write_spi(chip, codec, reg, value);
	else
		pcm1796_write_i2c(chip, codec, reg, value);
	if ((unsigned int)(reg - PCM1796_REG_BASE)
	    < ARRAY_SIZE(data->pcm1796_regs[codec]))
		data->pcm1796_regs[codec][reg - PCM1796_REG_BASE] = value;
}

static void pcm1796_write_cached(struct oxygen *chip, unsigned int codec,
				 u8 reg, u8 value)
{
	struct xonar_pcm179x *data = chip->model_data;

	if (value != data->pcm1796_regs[codec][reg - PCM1796_REG_BASE])
		pcm1796_write(chip, codec, reg, value);
}

static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
{
	struct xonar_pcm179x *data = chip->model_data;

	oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
	data->cs2000_regs[reg] = value;
}

static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
{
	struct xonar_pcm179x *data = chip->model_data;

	if (value != data->cs2000_regs[reg])
		cs2000_write(chip, reg, value);
}

static void pcm1796_registers_init(struct oxygen *chip)
{
	struct xonar_pcm179x *data = chip->model_data;
	unsigned int i;
	s8 gain_offset;

	msleep(1);
	gain_offset = data->hp_active ? data->hp_gain_offset : 0;
	for (i = 0; i < data->dacs; ++i) {
		/* set ATLD before ATL/ATR */

Annotation

Implementation Notes