sound/soc/soc-link.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/soc-link.c
Extension
.c
Size
5511 bytes
Lines
214
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

// SPDX-License-Identifier: GPL-2.0
//
// soc-link.c
//
// Copyright (C) 2019 Renesas Electronics Corp.
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
//
#include <sound/soc.h>
#include <sound/soc-link.h>

#define soc_link_ret(rtd, ret) _soc_link_ret(rtd, __func__, ret)
static inline int _soc_link_ret(struct snd_soc_pcm_runtime *rtd,
				const char *func, int ret)
{
	return snd_soc_ret(rtd->dev, ret,
			   "at %s() on %s\n", func, rtd->dai_link->name);
}

/*
 * We might want to check substream by using list.
 * In such case, we can update these macros.
 */
#define soc_link_mark_push(rtd, substream, tgt)		((rtd)->mark_##tgt = substream)
#define soc_link_mark_pop(rtd, tgt)		((rtd)->mark_##tgt = NULL)
#define soc_link_mark_match(rtd, substream, tgt)	((rtd)->mark_##tgt == substream)

int snd_soc_link_init(struct snd_soc_pcm_runtime *rtd)
{
	int ret = 0;

	if (rtd->dai_link->init)
		ret = rtd->dai_link->init(rtd);

	return soc_link_ret(rtd, ret);
}

void snd_soc_link_exit(struct snd_soc_pcm_runtime *rtd)
{
	if (rtd->dai_link->exit)
		rtd->dai_link->exit(rtd);
}

int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				    struct snd_pcm_hw_params *params)
{
	int ret = 0;

	if (rtd->dai_link->be_hw_params_fixup)
		ret = rtd->dai_link->be_hw_params_fixup(rtd, params);

	return soc_link_ret(rtd, ret);
}

int snd_soc_link_startup(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	int ret = 0;

	if (rtd->dai_link->ops &&
	    rtd->dai_link->ops->startup)
		ret = rtd->dai_link->ops->startup(substream);

	/* mark substream if succeeded */
	if (ret == 0)
		soc_link_mark_push(rtd, substream, startup);

	return soc_link_ret(rtd, ret);
}

void snd_soc_link_shutdown(struct snd_pcm_substream *substream,
			   int rollback)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);

	if (rollback && !soc_link_mark_match(rtd, substream, startup))
		return;

	if (rtd->dai_link->ops &&
	    rtd->dai_link->ops->shutdown)
		rtd->dai_link->ops->shutdown(substream);

	/* remove marked substream */
	soc_link_mark_pop(rtd, startup);
}

int snd_soc_link_prepare(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	int ret = 0;

Annotation

Implementation Notes