sound/soc/intel/boards/sof_maxim_common.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/boards/sof_maxim_common.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/boards/sof_maxim_common.c
Extension
.c
Size
15601 bytes
Lines
613
Domain
Driver Families
Bucket
sound/soc
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 (i >= ARRAY_SIZE(max_98373_tdm_mask)) {
			dev_err(codec_dai->dev, "only 2 amps are supported\n");
			return -EINVAL;
		}

		switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
		case SND_SOC_DAIFMT_DSP_A:
		case SND_SOC_DAIFMT_DSP_B:
			/* get the tplg configured tdm slot number */
			tdm_slots = sof_dai_get_tdm_slots(rtd);
			if (tdm_slots <= 0) {
				dev_err(rtd->dev, "invalid tdm slots %d\n",
					tdm_slots);
				return -EINVAL;
			}

			/* get the tx mask from ACPI device properties */
			tx_mask = max_98373_get_tx_mask(codec_dai->dev);
			if (!tx_mask)
				return -EINVAL;

			if (tx_mask & tx_mask_used) {
				dev_err(codec_dai->dev, "invalid tx mask 0x%x, used 0x%x\n",
					tx_mask, tx_mask_used);
				return -EINVAL;
			}

			tx_mask_used |= tx_mask;

			/*
			 * check if tdm slot number is too small for channel
			 * allocation
			 */
			if (fls(tx_mask) > tdm_slots) {
				dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",
					fls(tx_mask), tdm_slots);
				return -EINVAL;
			}

			if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) {
				dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n",
					fls(max_98373_tdm_mask[i].rx), tdm_slots);
				return -EINVAL;
			}

			dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n",
				tx_mask, max_98373_tdm_mask[i].rx,
				tdm_slots, params_width(params));

			ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask,
						       max_98373_tdm_mask[i].rx,
						       tdm_slots,
						       params_width(params));
			if (ret < 0) {
				dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
					ret);
				return ret;
			}
			break;
		default:
			dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
			break;
		}
	}
	return 0;
}

static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct snd_soc_dai *codec_dai;
	struct snd_soc_dai *cpu_dai;
	int j;
	int ret = 0;

	/* set spk pin by playback only */
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		return 0;

	cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
	for_each_rtd_codec_dais(rtd, j, codec_dai) {
		struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cpu_dai->component);
		char pin_name[MAX_98373_PIN_NAME];

		snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
			 codec_dai->component->name_prefix);

		switch (cmd) {
		case SNDRV_PCM_TRIGGER_START:
		case SNDRV_PCM_TRIGGER_RESUME:

Annotation

Implementation Notes