sound/soc/codecs/wm8998.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/wm8998.c
Extension
.c
Size
50359 bytes
Lines
1438
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

struct wm8998_priv {
	struct arizona_priv core;
	struct arizona_fll fll[2];
};

static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
			  struct snd_kcontrol *kcontrol,
			  int event)
{
	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
	unsigned int val;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		val = snd_soc_component_read(component, ARIZONA_ASRC_RATE1);
		val &= ARIZONA_ASRC_RATE1_MASK;
		val >>= ARIZONA_ASRC_RATE1_SHIFT;

		switch (val) {
		case 0:
		case 1:
		case 2:
			val = snd_soc_component_read(component,
					   ARIZONA_SAMPLE_RATE_1 + val);
			if (val >= 0x11) {
				dev_warn(component->dev,
					 "Unsupported ASRC rate1 (%s)\n",
					 arizona_sample_rate_val_to_name(val));
				return -EINVAL;
			}
			break;
		default:
			dev_err(component->dev,
				"Illegal ASRC rate1 selector (0x%x)\n",
				val);
			return -EINVAL;
		}

		val = snd_soc_component_read(component, ARIZONA_ASRC_RATE2);
		val &= ARIZONA_ASRC_RATE2_MASK;
		val >>= ARIZONA_ASRC_RATE2_SHIFT;

		switch (val) {
		case 8:
		case 9:
			val -= 0x8;
			val = snd_soc_component_read(component,
					   ARIZONA_ASYNC_SAMPLE_RATE_1 + val);
			if (val >= 0x11) {
				dev_warn(component->dev,
					 "Unsupported ASRC rate2 (%s)\n",
					 arizona_sample_rate_val_to_name(val));
				return -EINVAL;
			}
			break;
		default:
			dev_err(component->dev,
				"Illegal ASRC rate2 selector (0x%x)\n",
				val);
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol);
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
	struct wm8998_priv *wm8998 = snd_soc_component_get_drvdata(component);
	struct arizona *arizona = wm8998->core.arizona;
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int mode_reg, mode_index;
	unsigned int mux, inmode, src_val, mode_val;
	int change, ret;

	mux = ucontrol->value.enumerated.item[0];
	if (mux > 1)
		return -EINVAL;

	switch (e->reg) {
	case ARIZONA_ADC_DIGITAL_VOLUME_2L:
		mode_reg = ARIZONA_IN2L_CONTROL;
		mode_index = 1 + (2 * mux);
		break;

Annotation

Implementation Notes