sound/soc/codecs/jz4760.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/jz4760.c
Extension
.c
Size
24218 bytes
Lines
861
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 jz_codec {
	struct device *dev;
	struct regmap *regmap;
	void __iomem *base;
};

static int jz4760_codec_set_bias_level(struct snd_soc_component *codec,
				       enum snd_soc_bias_level level)
{
	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
	struct regmap *regmap = jz_codec->regmap;

	switch (level) {
	case SND_SOC_BIAS_PREPARE:
		/* Reset all interrupt flags. */
		regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK);

		regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
		msleep(250);
		regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
		msleep(400);
		break;
	case SND_SOC_BIAS_STANDBY:
		regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
		regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
		break;
	default:
		break;
	}

	return 0;
}

static int jz4760_codec_startup(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct snd_soc_component *codec = dai->component;
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec);
	int ret = 0;

	/*
	 * SYSCLK output from the codec to the AIC is required to keep the
	 * DMA transfer going during playback when all audible outputs have
	 * been disabled.
	 */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
	return ret;
}

static void jz4760_codec_shutdown(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct snd_soc_component *codec = dai->component;
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		snd_soc_dapm_disable_pin(dapm, "SYSCLK");
}


static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream,
				    int cmd, struct snd_soc_dai *dai)
{
	struct snd_soc_component *codec = dai->component;
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec);
	int ret = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
			snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_ON);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		/* do nothing */
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
{
	struct snd_soc_component *codec = dai->component;

Annotation

Implementation Notes