sound/soc/intel/keembay/kmb_platform.c
Source file repositories/reference/linux-study-clean/sound/soc/intel/keembay/kmb_platform.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/intel/keembay/kmb_platform.c- Extension
.c- Size
- 23885 bytes
- Lines
- 929
- 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.
- 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/bitrev.hlinux/clk.hlinux/dma-mapping.hlinux/io.hlinux/module.hlinux/of.hsound/dmaengine_pcm.hsound/pcm.hsound/pcm_params.hsound/soc.hkmb_platform.h
Detected Declarations
function hdmi_reformat_iec958function kmb_pcm_tx_fnfunction kmb_pcm_rx_fnfunction kmb_i2s_disable_channelsfunction kmb_i2s_clear_irqsfunction kmb_i2s_irq_triggerfunction kmb_pcm_operationfunction kmb_pcm_openfunction kmb_pcm_triggerfunction kmb_i2s_irq_handlerfunction kmb_platform_pcm_newfunction kmb_pcm_pointerfunction kmb_probefunction kmb_i2s_enable_dmafunction kmb_i2s_disable_dmafunction kmb_i2s_startfunction kmb_i2s_stopfunction kmb_disable_clkfunction kmb_set_dai_fmtfunction kmb_dai_triggerfunction kmb_i2s_configfunction kmb_dai_hw_paramsfunction kmb_dai_preparefunction kmb_dai_startupfunction kmb_dai_hw_freefunction kmb_plat_dai_probe
Annotated Snippet
if (kmb_i2s->config.data_width == 16) {
writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0));
writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0));
} else {
writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0));
writel(((u32(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0));
}
period_pos++;
if (++tx_ptr >= runtime->buffer_size)
tx_ptr = 0;
}
*period_elapsed = period_pos >= runtime->period_size;
return tx_ptr;
}
static unsigned int kmb_pcm_rx_fn(struct kmb_i2s_info *kmb_i2s,
struct snd_pcm_runtime *runtime,
unsigned int rx_ptr, bool *period_elapsed)
{
unsigned int period_pos = rx_ptr % runtime->period_size;
void __iomem *i2s_base = kmb_i2s->i2s_base;
int chan = kmb_i2s->config.chan_nr;
void *buf = runtime->dma_area;
int i, j;
/* KMB i2s uses two separate L/R FIFO */
for (i = 0; i < kmb_i2s->fifo_th; i++) {
for (j = 0; j < chan / 2; j++) {
if (kmb_i2s->config.data_width == 16) {
((u16 *)buf)[rx_ptr * chan + (j * 2)] =
readl(i2s_base + LRBR_LTHR(j));
((u16 *)buf)[rx_ptr * chan + ((j * 2) + 1)] =
readl(i2s_base + RRBR_RTHR(j));
} else {
((u32 *)buf)[rx_ptr * chan + (j * 2)] =
readl(i2s_base + LRBR_LTHR(j));
((u32 *)buf)[rx_ptr * chan + ((j * 2) + 1)] =
readl(i2s_base + RRBR_RTHR(j));
}
}
period_pos++;
if (++rx_ptr >= runtime->buffer_size)
rx_ptr = 0;
}
*period_elapsed = period_pos >= runtime->period_size;
return rx_ptr;
}
static inline void kmb_i2s_disable_channels(struct kmb_i2s_info *kmb_i2s,
u32 stream)
{
u32 i;
/* Disable all channels regardless of configuration*/
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
for (i = 0; i < MAX_ISR; i++)
writel(0, kmb_i2s->i2s_base + TER(i));
} else {
for (i = 0; i < MAX_ISR; i++)
writel(0, kmb_i2s->i2s_base + RER(i));
}
}
static inline void kmb_i2s_clear_irqs(struct kmb_i2s_info *kmb_i2s, u32 stream)
{
struct i2s_clk_config_data *config = &kmb_i2s->config;
u32 i;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
for (i = 0; i < config->chan_nr / 2; i++)
readl(kmb_i2s->i2s_base + TOR(i));
} else {
for (i = 0; i < config->chan_nr / 2; i++)
readl(kmb_i2s->i2s_base + ROR(i));
}
}
static inline void kmb_i2s_irq_trigger(struct kmb_i2s_info *kmb_i2s,
u32 stream, int chan_nr, bool trigger)
{
u32 i, irq;
u32 flag;
Annotation
- Immediate include surface: `linux/bitrev.h`, `linux/clk.h`, `linux/dma-mapping.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`, `sound/dmaengine_pcm.h`, `sound/pcm.h`.
- Detected declarations: `function hdmi_reformat_iec958`, `function kmb_pcm_tx_fn`, `function kmb_pcm_rx_fn`, `function kmb_i2s_disable_channels`, `function kmb_i2s_clear_irqs`, `function kmb_i2s_irq_trigger`, `function kmb_pcm_operation`, `function kmb_pcm_open`, `function kmb_pcm_trigger`, `function kmb_i2s_irq_handler`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- 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.