sound/soc/stm/stm32_sai.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/stm/stm32_sai.c
Extension
.c
Size
7983 bytes
Lines
317
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
 *
 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/reset.h>

#include <sound/dmaengine_pcm.h>
#include <sound/core.h>

#include "stm32_sai.h"

static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai);

static const struct stm32_sai_conf stm32_sai_conf_f4 = {
	.version = STM_SAI_STM32F4,
	.fifo_size = 8,
	.has_spdif_pdm = false,
	.get_sai_ck_parent = stm32_sai_get_parent_clk,
};

/*
 * Default settings for STM32H7x socs and STM32MP1x.
 * These default settings will be overridden if the soc provides
 * support of hardware configuration registers.
 * - STM32H7: rely on default settings
 * - STM32MP1: retrieve settings from registers
 */
static const struct stm32_sai_conf stm32_sai_conf_h7 = {
	.version = STM_SAI_STM32H7,
	.fifo_size = 8,
	.has_spdif_pdm = true,
	.get_sai_ck_parent = stm32_sai_get_parent_clk,
};

/*
 * STM32MP2x:
 * - do not use SAI parent clock source selection
 * - do not use DMA burst mode
 */
static const struct stm32_sai_conf stm32_sai_conf_mp25 = {
	.no_dma_burst = true,
};

static const struct of_device_id stm32_sai_ids[] = {
	{ .compatible = "st,stm32f4-sai", .data = (void *)&stm32_sai_conf_f4 },
	{ .compatible = "st,stm32h7-sai", .data = (void *)&stm32_sai_conf_h7 },
	{ .compatible = "st,stm32mp25-sai", .data = (void *)&stm32_sai_conf_mp25 },
	{}
};

static int stm32_sai_pclk_disable(struct device *dev)
{
	struct stm32_sai_data *sai = dev_get_drvdata(dev);

	clk_disable_unprepare(sai->pclk);

	return 0;
}

static int stm32_sai_pclk_enable(struct device *dev)
{
	struct stm32_sai_data *sai = dev_get_drvdata(dev);
	int ret;

	ret = clk_prepare_enable(sai->pclk);
	if (ret) {
		dev_err(&sai->pdev->dev, "failed to enable clock: %d\n", ret);
		return ret;
	}

	return 0;
}

static int stm32_sai_sync_conf_client(struct stm32_sai_data *sai, int synci)
{
	int ret;

	/* Enable peripheral clock to allow GCR register access */
	ret = stm32_sai_pclk_enable(&sai->pdev->dev);
	if (ret)

Annotation

Implementation Notes