sound/pci/oxygen/xonar_dg_mixer.c

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

File Facts

System
Linux kernel
Corpus path
sound/pci/oxygen/xonar_dg_mixer.c
Extension
.c
Size
12334 bytes
Lines
457
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

if (idx == data->input_sel) {
			ret = input_volume_apply(chip,
				data->input_vol[idx][0],
				data->input_vol[idx][1]);
		}
		changed = ret >= 0 ? 1 : ret;
	}
	return changed;
}

/* Capture Source */

static int input_source_apply(struct oxygen *chip)
{
	struct dg *data = chip->model_data;

	data->cs4245_shadow[CS4245_ANALOG_IN] &= ~CS4245_SEL_MASK;
	if (data->input_sel == CAPTURE_SRC_FP_MIC)
		data->cs4245_shadow[CS4245_ANALOG_IN] |= CS4245_SEL_INPUT_2;
	else if (data->input_sel == CAPTURE_SRC_LINE)
		data->cs4245_shadow[CS4245_ANALOG_IN] |= CS4245_SEL_INPUT_4;
	else if (data->input_sel != CAPTURE_SRC_MIC)
		data->cs4245_shadow[CS4245_ANALOG_IN] |= CS4245_SEL_INPUT_1;
	return cs4245_write_spi(chip, CS4245_ANALOG_IN);
}

static int input_sel_info(struct snd_kcontrol *ctl,
			  struct snd_ctl_elem_info *info)
{
	static const char *const names[4] = {
		"Mic", "Front Mic", "Line", "Aux"
	};

	return snd_ctl_enum_info(info, 1, 4, names);
}

static int input_sel_get(struct snd_kcontrol *ctl,
			 struct snd_ctl_elem_value *value)
{
	struct oxygen *chip = ctl->private_data;
	struct dg *data = chip->model_data;

	guard(mutex)(&chip->mutex);
	value->value.enumerated.item[0] = data->input_sel;
	return 0;
}

static int input_sel_put(struct snd_kcontrol *ctl,
			 struct snd_ctl_elem_value *value)
{
	struct oxygen *chip = ctl->private_data;
	struct dg *data = chip->model_data;
	int changed;
	int ret;

	if (value->value.enumerated.item[0] > 3)
		return -EINVAL;

	guard(mutex)(&chip->mutex);
	changed = value->value.enumerated.item[0] != data->input_sel;
	if (changed) {
		data->input_sel = value->value.enumerated.item[0];

		ret = input_source_apply(chip);
		if (ret >= 0)
			ret = input_volume_apply(chip,
				data->input_vol[data->input_sel][0],
				data->input_vol[data->input_sel][1]);
		changed = ret >= 0 ? 1 : ret;
	}
	return changed;
}

/* ADC high-pass filter */

static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
{
	static const char *const names[2] = { "Active", "Frozen" };

	return snd_ctl_enum_info(info, 1, 2, names);
}

static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
{
	struct oxygen *chip = ctl->private_data;
	struct dg *data = chip->model_data;

	value->value.enumerated.item[0] =
		!!(data->cs4245_shadow[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE);
	return 0;

Annotation

Implementation Notes