sound/soc/tegra/tegra210_ahub.c

Source file repositories/reference/linux-study-clean/sound/soc/tegra/tegra210_ahub.c

File Facts

System
Linux kernel
Corpus path
sound/soc/tegra/tegra210_ahub.c
Extension
.c
Size
66571 bytes
Lines
2334
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 (reg_val) {
			bit_pos = ffs(reg_val) +
				  (8 * val_bytes * i);
			break;
		}
	}

	/* Find index related to the item in array *_ahub_mux_texts[] */
	for (i = 0; i < e->items; i++) {
		if (bit_pos == e->values[i]) {
			uctl->value.enumerated.item[0] = i;
			break;
		}
	}

	return 0;
}

static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl,
				     struct snd_ctl_elem_value *uctl)
{
	struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_to_component(kctl);
	struct tegra_ahub *ahub = snd_soc_component_get_drvdata(cmpnt);
	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctl);
	struct soc_enum *e = (struct soc_enum *)kctl->private_value;
	struct snd_soc_dapm_update update[TEGRA_XBAR_UPDATE_MAX_REG] = { };
	int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
	unsigned int *item = uctl->value.enumerated.item;
	unsigned int value;
	unsigned int i, bit_pos, reg_idx = 0, reg_val = 0;
	int change = 0;

	if (item[0] >= e->items)
		return -EINVAL;

	value = e->values[item[0]];

	if (value) {
		/* Get the register index and value to set */
		reg_idx = (value - 1) / (8 * val_bytes);
		bit_pos = (value - 1) % (8 * val_bytes);
		reg_val = BIT(bit_pos);
	}

	/*
	 * Run through all parts of a MUX register to find the state changes.
	 * There will be an additional update if new MUX input value is from
	 * different part of the MUX register.
	 */
	for (i = 0; i < ahub->soc_data->reg_count; i++) {
		update[i].reg = e->reg + (ahub->soc_data->xbar_part_size * i);
		update[i].val = (i == reg_idx) ? reg_val : 0;
		update[i].mask = ahub->soc_data->mask[i];
		update[i].kcontrol = kctl;

		/* Update widget power if state has changed */
		if (snd_soc_component_test_bits(cmpnt, update[i].reg,
						update[i].mask,
						update[i].val))
			change |= snd_soc_dapm_mux_update_power(dapm, kctl,
								item[0], e,
								&update[i]);
	}

	return change;
}

static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
	DAI(ADMAIF1),
	DAI(ADMAIF2),
	DAI(ADMAIF3),
	DAI(ADMAIF4),
	DAI(ADMAIF5),
	DAI(ADMAIF6),
	DAI(ADMAIF7),
	DAI(ADMAIF8),
	DAI(ADMAIF9),
	DAI(ADMAIF10),
	/* XBAR <-> I2S <-> Codec */
	DAI(I2S1),
	DAI(I2S2),
	DAI(I2S3),
	DAI(I2S4),
	DAI(I2S5),
	/* XBAR <- DMIC <- Codec */
	DAI(DMIC1),
	DAI(DMIC2),
	DAI(DMIC3),
	/* XBAR -> SFC -> XBAR */
	DAI(SFC1 RX),

Annotation

Implementation Notes