sound/soc/codecs/pcm6240.c

Source file repositories/reference/linux-study-clean/sound/soc/codecs/pcm6240.c

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/pcm6240.c
Extension
.c
Size
51735 bytes
Lines
2161
Domain
Driver Families
Bucket
sound/soc
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 (ret) {
			dev_err(pcm_dev->dev, "%s: read mode err=%d\n",
				__func__, ret);
			goto out;
		}
		val &= PCM1690_REG_MODE_CTRL_DAMS_MSK;
		/* Set to wide-range mode, before using vol ctrl. */
		if (!val && vol_ctrl_type == PCMDEV_PCM1690_VOL_CTRL) {
			ucontrol->value.integer.value[0] = -25500;
			goto out;
		}
		/* Set to fine mode, before using fine vol ctrl. */
		if (val && vol_ctrl_type == PCMDEV_PCM1690_FINE_VOL_CTRL) {
			ucontrol->value.integer.value[0] = -12750;
			goto out;
		}
	}

	ret = pcmdev_dev_read(pcm_dev, dev_no, reg, &val);
	if (ret) {
		dev_err(pcm_dev->dev, "%s: read err=%d\n",
			__func__, ret);
		goto out;
	}

	val = (val >> shift) & mask;
	val = (val > max) ? max : val;
	val = mc->invert ? max - val : val;
	ucontrol->value.integer.value[0] = val;
out:
	mutex_unlock(&pcm_dev->codec_lock);
	return ret;
}

static int pcmdevice_get_volsw(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL);
}

static int pcm1690_get_volsw(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL);
}

static int pcm1690_get_finevolsw(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	return pcmdev_get_volsw(kcontrol, ucontrol,
		PCMDEV_PCM1690_FINE_VOL_CTRL);
}

static int pcmdev_put_volsw(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct pcmdevice_priv *pcm_dev =
		snd_soc_component_get_drvdata(component);
	struct pcmdevice_mixer_control *mc =
		(struct pcmdevice_mixer_control *)kcontrol->private_value;
	int max = mc->max, rc;
	unsigned int mask = BIT(fls(max)) - 1;
	unsigned int dev_no = mc->dev_no;
	unsigned int shift = mc->shift;
	unsigned int val, val_mask;
	unsigned int reg = mc->reg;

	mutex_lock(&pcm_dev->codec_lock);
	val = ucontrol->value.integer.value[0] & mask;
	val = (val > max) ? max : val;
	val = mc->invert ? max - val : val;
	val_mask = mask << shift;
	val = val << shift;

	switch (vol_ctrl_type) {
	case PCMDEV_PCM1690_VOL_CTRL:
		val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK;
		val |= PCM1690_REG_MODE_CTRL_DAMS_WIDE_RANGE;
		break;
	case PCMDEV_PCM1690_FINE_VOL_CTRL:
		val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK;
		val |= PCM1690_REG_MODE_CTRL_DAMS_FINE_STEP;
		break;
	}

	rc = pcmdev_dev_update_bits(pcm_dev, dev_no, reg, val_mask, val);
	if (rc < 0)
		dev_err(pcm_dev->dev, "%s: update_bits err = %d\n",
			__func__, rc);

Annotation

Implementation Notes