sound/soc/atmel/mchp-pdmc.c

Source file repositories/reference/linux-study-clean/sound/soc/atmel/mchp-pdmc.c

File Facts

System
Linux kernel
Corpus path
sound/soc/atmel/mchp-pdmc.c
Extension
.c
Size
30523 bytes
Lines
1157
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 mic_map {
	int ds_pos;
	int clk_edge;
};

struct mchp_pdmc_chmap {
	struct snd_pcm_chmap_elem *chmap;
	struct mchp_pdmc *dd;
	struct snd_pcm *pcm;
	struct snd_kcontrol *kctl;
};

struct mchp_pdmc {
	struct mic_map channel_mic_map[MCHP_PDMC_MAX_CHANNELS];
	struct device *dev;
	struct snd_dmaengine_dai_dma_data addr;
	struct regmap *regmap;
	struct clk *pclk;
	struct clk *gclk;
	u32 pdmcen;
	u32 suspend_irq;
	u32 startup_delay_us;
	int mic_no;
	int sinc_order;
	bool audio_filter_en;
	atomic_t busy_stream;
};

static const char *const mchp_pdmc_sinc_filter_order_text[] = {
	"1", "2", "3", "4", "5"
};

static const unsigned int mchp_pdmc_sinc_filter_order_values[] = {
	1, 2, 3, 4, 5,
};

static const struct soc_enum mchp_pdmc_sinc_filter_order_enum = {
	.items = ARRAY_SIZE(mchp_pdmc_sinc_filter_order_text),
	.texts = mchp_pdmc_sinc_filter_order_text,
	.values = mchp_pdmc_sinc_filter_order_values,
};

static int mchp_pdmc_sinc_order_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int item;

	item = snd_soc_enum_val_to_item(e, dd->sinc_order);
	uvalue->value.enumerated.item[0] = item;

	return 0;
}

static int mchp_pdmc_sinc_order_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int *item = uvalue->value.enumerated.item;
	unsigned int val;

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

	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;

	if (atomic_read(&dd->busy_stream))
		return -EBUSY;

	if (val == dd->sinc_order)
		return 0;

	dd->sinc_order = val;

	return 1;
}

static int mchp_pdmc_af_get(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);

	uvalue->value.integer.value[0] = !!dd->audio_filter_en;

	return 0;

Annotation

Implementation Notes