sound/hda/codecs/side-codecs/cs35l56_hda.c

Source file repositories/reference/linux-study-clean/sound/hda/codecs/side-codecs/cs35l56_hda.c

File Facts

System
Linux kernel
Corpus path
sound/hda/codecs/side-codecs/cs35l56_hda.c
Extension
.c
Size
35887 bytes
Lines
1287
Domain
Driver Families
Bucket
sound/hda
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (cs35l56->suspended) {
			cs35l56->playing = true;
			break;
		}

		cs35l56_hda_play(cs35l56);
		break;
	case HDA_GEN_PCM_ACT_CLEANUP:
		if (!cs35l56->playing)
			break;

		cs35l56_hda_pause(cs35l56);
		break;
	default:
		break;
	}
}

static int cs35l56_hda_runtime_suspend(struct device *dev)
{
	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);

	if (cs35l56->cs_dsp.booted)
		cs_dsp_stop(&cs35l56->cs_dsp);

	return cs35l56_runtime_suspend_common(&cs35l56->base);
}

static int cs35l56_hda_runtime_resume(struct device *dev)
{
	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
	int ret;

	ret = cs35l56_runtime_resume_common(&cs35l56->base, false);
	if (ret < 0)
		return ret;

	if (cs35l56->cs_dsp.booted) {
		ret = cs_dsp_run(&cs35l56->cs_dsp);
		if (ret) {
			dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);
			goto err;
		}
	}

	return 0;

err:
	cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE);
	regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
		     CS35L56_MBOX_CMD_HIBERNATE_NOW);

	regcache_cache_only(cs35l56->base.regmap, true);

	return ret;
}

static int cs35l56_hda_mixer_info(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
	uinfo->count = 1;
	uinfo->value.enumerated.items = CS35L56_NUM_INPUT_SRC;
	if (uinfo->value.enumerated.item >= CS35L56_NUM_INPUT_SRC)
		uinfo->value.enumerated.item = CS35L56_NUM_INPUT_SRC - 1;
	strscpy(uinfo->value.enumerated.name, cs35l56_tx_input_texts[uinfo->value.enumerated.item],
		sizeof(uinfo->value.enumerated.name));

	return 0;
}

static int cs35l56_hda_mixer_get(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
	unsigned int reg_val;
	int i, ret;

	cs35l56_hda_wait_dsp_ready(cs35l56);

	ret = regmap_read(cs35l56->base.regmap, kcontrol->private_value,
			  &reg_val);
	if (ret)
		return ret;

	reg_val &= CS35L56_ASP_TXn_SRC_MASK;

	for (i = 0; i < CS35L56_NUM_INPUT_SRC; ++i) {
		if (cs35l56_tx_input_values[i] == reg_val) {
			ucontrol->value.enumerated.item[0] = i;

Annotation

Implementation Notes