sound/pci/oxygen/xonar_cs43xx.c

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

File Facts

System
Linux kernel
Corpus path
sound/pci/oxygen/xonar_cs43xx.c
Extension
.c
Size
12104 bytes
Lines
440
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_cs43xx {
	struct xonar_generic generic;
	u8 cs4398_regs[8];
	u8 cs4362a_regs[15];
};

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

	oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
	if (reg < ARRAY_SIZE(data->cs4398_regs))
		data->cs4398_regs[reg] = value;
}

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

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

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

	oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
	if (reg < ARRAY_SIZE(data->cs4362a_regs))
		data->cs4362a_regs[reg] = value;
}

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

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

static void cs43xx_registers_init(struct oxygen *chip)
{
	struct xonar_cs43xx *data = chip->model_data;
	unsigned int i;

	/* set CPEN (control port mode) and power down */
	cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
	cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
	/* configure */
	cs4398_write(chip, 2, data->cs4398_regs[2]);
	cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
	cs4398_write(chip, 4, data->cs4398_regs[4]);
	cs4398_write(chip, 5, data->cs4398_regs[5]);
	cs4398_write(chip, 6, data->cs4398_regs[6]);
	cs4398_write(chip, 7, data->cs4398_regs[7]);
	cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
	cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
		      CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
	cs4362a_write(chip, 0x04, data->cs4362a_regs[0x04]);
	cs4362a_write(chip, 0x05, 0);
	for (i = 6; i <= 14; ++i)
		cs4362a_write(chip, i, data->cs4362a_regs[i]);
	/* clear power down */
	cs4398_write(chip, 8, CS4398_CPEN);
	cs4362a_write(chip, 0x01, CS4362A_CPEN);
}

static void xonar_d1_init(struct oxygen *chip)
{
	struct xonar_cs43xx *data = chip->model_data;

	data->generic.anti_pop_delay = 800;
	data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
	data->cs4398_regs[2] =
		CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
	data->cs4398_regs[4] = CS4398_MUTEP_LOW |
		CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE;
	data->cs4398_regs[5] = 60 * 2;
	data->cs4398_regs[6] = 60 * 2;
	data->cs4398_regs[7] = CS4398_RMP_DN | CS4398_RMP_UP |
		CS4398_ZERO_CROSS | CS4398_SOFT_RAMP;
	data->cs4362a_regs[4] = CS4362A_RMP_DN | CS4362A_DEM_NONE;
	data->cs4362a_regs[6] = CS4362A_FM_SINGLE |
		CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
	data->cs4362a_regs[7] = 60 | CS4362A_MUTE;
	data->cs4362a_regs[8] = 60 | CS4362A_MUTE;
	data->cs4362a_regs[9] = data->cs4362a_regs[6];
	data->cs4362a_regs[10] = 60 | CS4362A_MUTE;
	data->cs4362a_regs[11] = 60 | CS4362A_MUTE;
	data->cs4362a_regs[12] = data->cs4362a_regs[6];

Annotation

Implementation Notes