sound/soc/ux500/ux500_msp_i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/ux500/ux500_msp_i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/ux500/ux500_msp_i2s.c- Extension
.c- Size
- 18181 bytes
- Lines
- 668
- 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/module.hlinux/platform_device.hlinux/delay.hlinux/slab.hlinux/io.hlinux/of.hsound/soc.hux500_msp_i2s.h
Detected Declarations
function set_prot_desc_txfunction set_prot_desc_rxfunction configure_protocolfunction setup_bitclkfunction configure_multichannelfunction enable_mspfunction flush_fifo_rxfunction flush_fifo_txfunction ux500_msp_i2s_openfunction disable_msp_rxfunction disable_msp_txfunction disable_mspfunction ux500_msp_i2s_triggerfunction ux500_msp_i2s_closefunction ux500_msp_i2s_init_mspfunction ux500_msp_i2s_cleanup_msp
Annotated Snippet
if (config->protocol >= MSP_INVALID_PROTOCOL) {
dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n",
__func__);
return -EINVAL;
}
protdesc =
(struct msp_protdesc *)&prot_descs[config->protocol];
} else {
protdesc = (struct msp_protdesc *)&config->protdesc;
}
if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) {
dev_err(msp->dev,
"%s: ERROR: Invalid data-size requested (data_size = %d)!\n",
__func__, data_size);
return -EINVAL;
}
if (config->direction & MSP_DIR_TX)
set_prot_desc_tx(msp, protdesc, data_size);
if (config->direction & MSP_DIR_RX)
set_prot_desc_rx(msp, protdesc, data_size);
/* The code below should not be separated. */
temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
temp_reg |= MSP_TX_CLKPOL_BIT(~protdesc->tx_clk_pol);
writel(temp_reg, msp->registers + MSP_GCR);
temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol);
writel(temp_reg, msp->registers + MSP_GCR);
return 0;
}
static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
{
u32 reg_val_GCR;
u32 frame_per = 0;
u32 sck_div = 0;
u32 frame_width = 0;
u32 temp_reg = 0;
struct msp_protdesc *protdesc = NULL;
reg_val_GCR = readl(msp->registers + MSP_GCR);
writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
if (config->default_protdesc)
protdesc =
(struct msp_protdesc *)&prot_descs[config->protocol];
else
protdesc = (struct msp_protdesc *)&config->protdesc;
switch (config->protocol) {
case MSP_PCM_PROTOCOL:
case MSP_PCM_COMPAND_PROTOCOL:
frame_width = protdesc->frame_width;
sck_div = config->f_inputclk / (config->frame_freq *
(protdesc->clocks_per_frame));
frame_per = protdesc->frame_period;
break;
case MSP_I2S_PROTOCOL:
frame_width = protdesc->frame_width;
sck_div = config->f_inputclk / (config->frame_freq *
(protdesc->clocks_per_frame));
frame_per = protdesc->frame_period;
break;
default:
dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
__func__,
config->protocol);
return -EINVAL;
}
temp_reg = (sck_div - 1) & SCK_DIV_MASK;
temp_reg |= FRAME_WIDTH_BITS(frame_width);
temp_reg |= FRAME_PERIOD_BITS(frame_per);
writel(temp_reg, msp->registers + MSP_SRG);
msp->f_bitclk = (config->f_inputclk)/(sck_div + 1);
/* Enable bit-clock */
udelay(100);
reg_val_GCR = readl(msp->registers + MSP_GCR);
writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR);
udelay(100);
return 0;
}
static int configure_multichannel(struct ux500_msp *msp,
Annotation
- Immediate include surface: `linux/module.h`, `linux/platform_device.h`, `linux/delay.h`, `linux/slab.h`, `linux/io.h`, `linux/of.h`, `sound/soc.h`, `ux500_msp_i2s.h`.
- Detected declarations: `function set_prot_desc_tx`, `function set_prot_desc_rx`, `function configure_protocol`, `function setup_bitclk`, `function configure_multichannel`, `function enable_msp`, `function flush_fifo_rx`, `function flush_fifo_tx`, `function ux500_msp_i2s_open`, `function disable_msp_rx`.
- 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.