drivers/spi/spi-bcm63xx.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-bcm63xx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-bcm63xx.c- Extension
.c- Size
- 17628 bytes
- Lines
- 678
- Domain
- Driver Families
- Bucket
- drivers/spi
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/clk.hlinux/io.hlinux/module.hlinux/platform_device.hlinux/delay.hlinux/interrupt.hlinux/spi/spi.hlinux/completion.hlinux/err.hlinux/pm_runtime.hlinux/of.hlinux/reset.h
Detected Declarations
struct bcm63xx_spienum bcm63xx_regs_spifunction bcm_spi_readbfunction bcm_spi_writebfunction bcm_spi_writewfunction bcm63xx_spi_setup_transferfunction bcm63xx_txrx_bufsfunction bcm63xx_spi_transfer_onefunction bcm63xx_spi_interruptfunction bcm63xx_spi_max_lengthfunction bcm63xx_spi_probefunction bcm63xx_spi_removefunction bcm63xx_spi_suspendfunction bcm63xx_spi_resume
Annotated Snippet
struct bcm63xx_spi {
struct completion done;
void __iomem *regs;
int irq;
/* Platform data */
const unsigned long *reg_offsets;
unsigned int fifo_size;
unsigned int msg_type_shift;
unsigned int msg_ctl_width;
/* data iomem */
u8 __iomem *tx_io;
const u8 __iomem *rx_io;
struct clk *clk;
struct platform_device *pdev;
};
static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
unsigned int offset)
{
return readb(bs->regs + bs->reg_offsets[offset]);
}
static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
u8 value, unsigned int offset)
{
writeb(value, bs->regs + bs->reg_offsets[offset]);
}
static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
u16 value, unsigned int offset)
{
#ifdef CONFIG_CPU_BIG_ENDIAN
iowrite16be(value, bs->regs + bs->reg_offsets[offset]);
#else
writew(value, bs->regs + bs->reg_offsets[offset]);
#endif
}
static const unsigned int bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
{ 20000000, SPI_CLK_20MHZ },
{ 12500000, SPI_CLK_12_50MHZ },
{ 6250000, SPI_CLK_6_250MHZ },
{ 3125000, SPI_CLK_3_125MHZ },
{ 1563000, SPI_CLK_1_563MHZ },
{ 781000, SPI_CLK_0_781MHZ },
{ 391000, SPI_CLK_0_391MHZ }
};
static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
struct spi_transfer *t)
{
struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
u8 clk_cfg, reg;
int i;
/* Default to lowest clock configuration */
clk_cfg = SPI_CLK_0_391MHZ;
/* Find the closest clock configuration */
for (i = 0; i < SPI_CLK_MASK; i++) {
if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) {
clk_cfg = bcm63xx_spi_freq_table[i][1];
break;
}
}
/* clear existing clock configuration bits of the register */
reg = bcm_spi_readb(bs, SPI_CLK_CFG);
reg &= ~SPI_CLK_MASK;
reg |= clk_cfg;
bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
clk_cfg, t->speed_hz);
}
/* the spi->mode bits understood by this driver: */
#define MODEBITS (SPI_CPOL | SPI_CPHA)
static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
unsigned int num_transfers)
{
struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
u16 msg_ctl;
u16 cmd;
unsigned int i, timeout = 0, prepend_len = 0, len = 0;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/clk.h`, `linux/io.h`, `linux/module.h`, `linux/platform_device.h`, `linux/delay.h`, `linux/interrupt.h`, `linux/spi/spi.h`.
- Detected declarations: `struct bcm63xx_spi`, `enum bcm63xx_regs_spi`, `function bcm_spi_readb`, `function bcm_spi_writeb`, `function bcm_spi_writew`, `function bcm63xx_spi_setup_transfer`, `function bcm63xx_txrx_bufs`, `function bcm63xx_spi_transfer_one`, `function bcm63xx_spi_interrupt`, `function bcm63xx_spi_max_length`.
- Atlas domain: Driver Families / drivers/spi.
- 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.