sound/soc/stm/stm32_i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/stm/stm32_i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/stm/stm32_i2s.c- Extension
.c- Size
- 36295 bytes
- Lines
- 1388
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/clk-provider.hlinux/delay.hlinux/module.hlinux/of_irq.hlinux/of_platform.hlinux/pm_runtime.hlinux/regmap.hlinux/reset.hlinux/spinlock.hsound/dmaengine_pcm.hsound/pcm_params.h
Detected Declarations
struct stm32_i2s_datastruct stm32_i2s_confstruct stm32_i2smclk_dataenum i2s_master_modeenum i2s_modeenum i2s_fifo_thenum i2s_stdenum i2s_datlenfunction stm32_i2s_calc_clk_divfunction stm32_i2s_set_clk_divfunction stm32_i2s_rate_accuratefunction stm32_i2s_set_parent_clockfunction stm32_i2s_put_parent_ratefunction stm32_i2s_set_parent_ratefunction stm32_i2smclk_determine_ratefunction stm32_i2smclk_recalc_ratefunction stm32_i2smclk_set_ratefunction stm32_i2smclk_enablefunction stm32_i2smclk_disablefunction stm32_i2s_add_mclk_providerfunction stm32_i2s_isrfunction scoped_guardfunction stm32_i2s_readable_regfunction stm32_i2s_volatile_regfunction stm32_i2s_writeable_regfunction stm32_i2s_set_dai_fmtfunction stm32_i2s_set_sysclkfunction stm32_i2s_configure_clockfunction stm32_i2s_configurefunction stm32_i2s_startupfunction stm32_i2s_hw_paramsfunction stm32_i2s_triggerfunction scoped_guardfunction scoped_guardfunction stm32_i2s_shutdownfunction stm32_i2s_dai_probefunction stm32_i2s_dai_initfunction stm32_i2s_dais_initfunction stm32_i2s_get_parent_clkfunction stm32_i2s_parse_dtfunction stm32_i2s_removefunction stm32_i2s_probefunction stm32_i2s_suspendfunction stm32_i2s_resume
Annotated Snippet
struct stm32_i2s_data {
const struct stm32_i2s_conf *conf;
struct regmap *regmap;
struct platform_device *pdev;
struct snd_soc_dai_driver *dai_drv;
struct snd_dmaengine_dai_dma_data dma_data_tx;
struct snd_dmaengine_dai_dma_data dma_data_rx;
struct snd_pcm_substream *substream;
struct clk *i2sclk;
struct clk *i2smclk;
struct clk *pclk;
struct clk *x8kclk;
struct clk *x11kclk;
void __iomem *base;
dma_addr_t phys_addr;
spinlock_t lock_fd; /* Manage race conditions for full duplex */
spinlock_t irq_lock; /* used to prevent race condition with IRQ */
unsigned int mclk_rate;
unsigned int fmt;
unsigned int divider;
unsigned int div;
bool odd;
bool i2s_clk_flg;
int refcount;
int ms_flg;
int (*set_i2s_clk_rate)(struct stm32_i2s_data *i2s, unsigned int rate);
void (*put_i2s_clk_rate)(struct stm32_i2s_data *i2s);
};
/**
* struct stm32_i2s_conf - I2S configuration
* @regmap_conf: regmap configuration pointer
* @get_i2s_clk_parent: get parent clock of I2S kernel clock
*/
struct stm32_i2s_conf {
const struct regmap_config *regmap_conf;
int (*get_i2s_clk_parent)(struct stm32_i2s_data *i2s);
};
struct stm32_i2smclk_data {
struct clk_hw hw;
unsigned long freq;
struct stm32_i2s_data *i2s_data;
};
#define to_mclk_data(_hw) container_of(_hw, struct stm32_i2smclk_data, hw)
static int stm32_i2s_get_parent_clk(struct stm32_i2s_data *i2s);
static int stm32_i2s_calc_clk_div(struct stm32_i2s_data *i2s,
unsigned long input_rate,
unsigned long output_rate)
{
unsigned int ratio, div, divider = 1;
bool odd;
ratio = DIV_ROUND_CLOSEST(input_rate, output_rate);
/* Check the parity of the divider */
odd = ratio & 0x1;
/* Compute the div prescaler */
div = ratio >> 1;
/* If div is 0 actual divider is 1 */
if (div) {
divider = ((2 * div) + odd);
dev_dbg(&i2s->pdev->dev, "Divider: 2*%d(div)+%d(odd) = %d\n",
div, odd, divider);
}
/* Division by three is not allowed by I2S prescaler */
if ((div == 1 && odd) || div > I2S_CGFR_I2SDIV_MAX) {
dev_err(&i2s->pdev->dev, "Wrong divider setting\n");
return -EINVAL;
}
if (input_rate % divider)
dev_dbg(&i2s->pdev->dev,
"Rate not accurate. requested (%ld), actual (%ld)\n",
output_rate, input_rate / divider);
i2s->div = div;
i2s->odd = odd;
i2s->divider = divider;
return 0;
}
static int stm32_i2s_set_clk_div(struct stm32_i2s_data *i2s)
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/clk-provider.h`, `linux/delay.h`, `linux/module.h`, `linux/of_irq.h`, `linux/of_platform.h`, `linux/pm_runtime.h`.
- Detected declarations: `struct stm32_i2s_data`, `struct stm32_i2s_conf`, `struct stm32_i2smclk_data`, `enum i2s_master_mode`, `enum i2s_mode`, `enum i2s_fifo_th`, `enum i2s_std`, `enum i2s_datlen`, `function stm32_i2s_calc_clk_div`, `function stm32_i2s_set_clk_div`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.