sound/soc/xilinx/xlnx_i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/xilinx/xlnx_i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/xilinx/xlnx_i2s.c- Extension
.c- Size
- 7107 bytes
- Lines
- 260
- 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.
- 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/io.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hsound/pcm_params.hsound/soc.h
Detected Declarations
struct xlnx_i2s_drv_datafunction xlnx_i2s_set_sclkout_divfunction xlnx_i2s_set_sysclkfunction xlnx_i2s_startupfunction xlnx_i2s_hw_paramsfunction xlnx_i2s_triggerfunction xlnx_i2s_probe
Annotated Snippet
struct xlnx_i2s_drv_data {
struct snd_soc_dai_driver dai_drv;
void __iomem *base;
unsigned int sysclk;
u32 data_width;
u32 channels;
bool is_32bit_lrclk;
struct snd_ratnum ratnum;
struct snd_pcm_hw_constraint_ratnums rate_constraints;
};
static int xlnx_i2s_set_sclkout_div(struct snd_soc_dai *cpu_dai,
int div_id, int div)
{
struct xlnx_i2s_drv_data *drv_data = snd_soc_dai_get_drvdata(cpu_dai);
if (!div || (div & ~I2S_I2STIM_VALID_MASK))
return -EINVAL;
drv_data->sysclk = 0;
writel(div, drv_data->base + I2S_I2STIM_OFFSET);
return 0;
}
static int xlnx_i2s_set_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct xlnx_i2s_drv_data *drv_data = snd_soc_dai_get_drvdata(dai);
drv_data->sysclk = freq;
if (freq) {
unsigned int bits_per_sample;
if (drv_data->is_32bit_lrclk)
bits_per_sample = 32;
else
bits_per_sample = drv_data->data_width;
drv_data->ratnum.num = freq / (bits_per_sample * drv_data->channels) / 2;
drv_data->ratnum.den_step = 1;
drv_data->ratnum.den_min = 1;
drv_data->ratnum.den_max = 255;
drv_data->rate_constraints.rats = &drv_data->ratnum;
drv_data->rate_constraints.nrats = 1;
}
return 0;
}
static int xlnx_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct xlnx_i2s_drv_data *drv_data = snd_soc_dai_get_drvdata(dai);
if (drv_data->sysclk)
return snd_pcm_hw_constraint_ratnums(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&drv_data->rate_constraints);
return 0;
}
static int xlnx_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *i2s_dai)
{
u32 reg_off, chan_id;
struct xlnx_i2s_drv_data *drv_data = snd_soc_dai_get_drvdata(i2s_dai);
if (drv_data->sysclk) {
unsigned int bits_per_sample, sclk, sclk_div;
if (drv_data->is_32bit_lrclk)
bits_per_sample = 32;
else
bits_per_sample = drv_data->data_width;
sclk = params_rate(params) * bits_per_sample * params_channels(params);
sclk_div = drv_data->sysclk / sclk / 2;
if ((drv_data->sysclk % sclk != 0) ||
!sclk_div || (sclk_div & ~I2S_I2STIM_VALID_MASK)) {
dev_warn(i2s_dai->dev, "invalid SCLK divisor for sysclk %u and sclk %u\n",
drv_data->sysclk, sclk);
return -EINVAL;
}
writel(sclk_div, drv_data->base + I2S_I2STIM_OFFSET);
}
Annotation
- Immediate include surface: `linux/io.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `sound/pcm_params.h`, `sound/soc.h`.
- Detected declarations: `struct xlnx_i2s_drv_data`, `function xlnx_i2s_set_sclkout_div`, `function xlnx_i2s_set_sysclk`, `function xlnx_i2s_startup`, `function xlnx_i2s_hw_params`, `function xlnx_i2s_trigger`, `function xlnx_i2s_probe`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
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.