sound/pci/ice1712/prodigy192.c

Source file repositories/reference/linux-study-clean/sound/pci/ice1712/prodigy192.c

File Facts

System
Linux kernel
Corpus path
sound/pci/ice1712/prodigy192.c
Extension
.c
Size
21073 bytes
Lines
784
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 prodigy192_spec {
	struct ak4114 *ak4114;
	/* rate change needs atomic mute/unmute of all dacs*/
	struct mutex mute_mutex;
};

static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
{
	snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
}

static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
{
	return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
}

/*
 * DAC mute control
 */

/*
 * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
 */
static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx,
		unsigned char mute)
{
	unsigned char new, old;
	int change;
	old = stac9460_get(ice, idx);
	new = (~mute << 7 & 0x80) | (old & ~0x80);
	change = (new != old);
	if (change)
		/* dev_dbg(ice->card->dev, "Volume register 0x%02x: 0x%02x\n", idx, new);*/
		stac9460_put(ice, idx, new);
	return change;
}

#define stac9460_dac_mute_info		snd_ctl_boolean_mono_info

static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	unsigned char val;
	int idx;

	if (kcontrol->private_value)
		idx = STAC946X_MASTER_VOLUME;
	else
		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
	val = stac9460_get(ice, idx);
	ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
	return 0;
}

static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	struct prodigy192_spec *spec = ice->spec;
	int idx;

	if (kcontrol->private_value)
		idx = STAC946X_MASTER_VOLUME;
	else
		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
	/* due to possible conflicts with stac9460_set_rate_val, mutexing */
	guard(mutex)(&spec->mute_mutex);
	/*
	dev_dbg(ice->card->dev, "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
	       ucontrol->value.integer.value[0]);
	*/
	return stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
}

/*
 * DAC volume attenuation mixer control
 */
static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;			/* mute */
	uinfo->value.integer.max = 0x7f;		/* 0dB */
	return 0;
}

static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
	int idx;
	unsigned char vol;

Annotation

Implementation Notes