sound/soc/ux500/mop500_ab8500.c

Source file repositories/reference/linux-study-clean/sound/soc/ux500/mop500_ab8500.c

File Facts

System
Linux kernel
Corpus path
sound/soc/ux500/mop500_ab8500.c
Extension
.c
Size
11213 bytes
Lines
438
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 mop500_ab8500_drvdata {
	/* Clocks */
	enum mclk mclk_sel;
	struct clk *clk_ptr_intclk;
	struct clk *clk_ptr_sysclk;
	struct clk *clk_ptr_ulpclk;
};

static inline const char *get_mclk_str(enum mclk mclk_sel)
{
	switch (mclk_sel) {
	case MCLK_SYSCLK:
		return "SYSCLK";
	case MCLK_ULPCLK:
		return "ULPCLK";
	default:
		return "Unknown";
	}
}

static int mop500_ab8500_set_mclk(struct device *dev,
				struct mop500_ab8500_drvdata *drvdata)
{
	int status;
	struct clk *clk_ptr;

	if (IS_ERR(drvdata->clk_ptr_intclk)) {
		dev_err(dev,
			"%s: ERROR: intclk not initialized!\n", __func__);
		return -EIO;
	}

	switch (drvdata->mclk_sel) {
	case MCLK_SYSCLK:
		clk_ptr = drvdata->clk_ptr_sysclk;
		break;
	case MCLK_ULPCLK:
		clk_ptr = drvdata->clk_ptr_ulpclk;
		break;
	default:
		return -EINVAL;
	}

	if (IS_ERR(clk_ptr)) {
		dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__,
			get_mclk_str(drvdata->mclk_sel));
		return -EIO;
	}

	status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr);
	if (status)
		dev_err(dev,
			"%s: ERROR: Setting intclk parent to %s failed (ret = %d)!",
			__func__, get_mclk_str(drvdata->mclk_sel), status);
	else
		dev_dbg(dev,
			"%s: intclk parent changed to %s.\n",
			__func__, get_mclk_str(drvdata->mclk_sel));

	return status;
}

/*
 * Control-events
 */

static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
	struct mop500_ab8500_drvdata *drvdata =
				snd_soc_card_get_drvdata(card);

	ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;

	return 0;
}

static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
	struct mop500_ab8500_drvdata *drvdata =
				snd_soc_card_get_drvdata(card);
	unsigned int val = ucontrol->value.enumerated.item[0];

	if (val > (unsigned int)MCLK_ULPCLK)
		return -EINVAL;
	if (drvdata->mclk_sel == val)
		return 0;

Annotation

Implementation Notes