drivers/video/fbdev/mmp/hw/mmp_spi.c
Source file repositories/reference/linux-study-clean/drivers/video/fbdev/mmp/hw/mmp_spi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/video/fbdev/mmp/hw/mmp_spi.c- Extension
.c- Size
- 4156 bytes
- Lines
- 168
- Domain
- Driver Families
- Bucket
- drivers/video
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/errno.hlinux/delay.hlinux/err.hlinux/io.hlinux/spi/spi.hmmp_ctrl.h
Detected Declarations
function Copyrightfunction lcd_spi_setupfunction lcd_spi_one_transferfunction list_for_each_entryfunction lcd_spi_register
Annotated Snippet
if (!--timeout) {
ret = -ETIMEDOUT;
dev_err(&spi->dev, "spi cmd send time out\n");
break;
}
}
tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
tmp &= ~CFG_SPI_START_MASK;
tmp |= CFG_SPI_START(0);
writel_relaxed(tmp, reg_base + LCD_SPU_SPI_CTRL);
writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
return ret;
}
static int lcd_spi_setup(struct spi_device *spi)
{
void __iomem *reg_base = (void __iomem *)
*(void **) spi_controller_get_devdata(spi->controller);
u32 tmp;
tmp = CFG_SCLKCNT(16) |
CFG_TXBITS(spi->bits_per_word) |
CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
CFG_SPI_3W4WB(1);
writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
/*
* After set mode it needs some time to pull up the spi signals,
* or it would cause the wrong waveform when send spi command,
* especially on pxa910h
*/
tmp = readl_relaxed(reg_base + SPU_IOPAD_CONTROL);
if ((tmp & CFG_IOPADMODE_MASK) != IOPAD_DUMB18SPI)
writel_relaxed(IOPAD_DUMB18SPI |
(tmp & ~CFG_IOPADMODE_MASK),
reg_base + SPU_IOPAD_CONTROL);
udelay(20);
return 0;
}
static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m)
{
struct spi_transfer *t;
int i;
list_for_each_entry(t, &m->transfers, transfer_list) {
switch (spi->bits_per_word) {
case 8:
for (i = 0; i < t->len; i++)
lcd_spi_write(spi, ((u8 *)t->tx_buf)[i]);
break;
case 16:
for (i = 0; i < t->len/2; i++)
lcd_spi_write(spi, ((u16 *)t->tx_buf)[i]);
break;
case 32:
for (i = 0; i < t->len/4; i++)
lcd_spi_write(spi, ((u32 *)t->tx_buf)[i]);
break;
default:
dev_err(&spi->dev, "Wrong spi bit length\n");
}
}
m->status = 0;
if (m->complete)
m->complete(m->context);
return 0;
}
int lcd_spi_register(struct mmphw_ctrl *ctrl)
{
struct spi_controller *ctlr;
void **p_regbase;
int err;
ctlr = spi_alloc_host(ctrl->dev, sizeof(void *));
if (!ctlr) {
dev_err(ctrl->dev, "unable to allocate SPI host\n");
return -ENOMEM;
}
p_regbase = spi_controller_get_devdata(ctlr);
*p_regbase = (void __force *)ctrl->reg_base;
/* set bus num to 5 to avoid conflict with other spi hosts */
ctlr->bus_num = 5;
ctlr->num_chipselect = 1;
Annotation
- Immediate include surface: `linux/errno.h`, `linux/delay.h`, `linux/err.h`, `linux/io.h`, `linux/spi/spi.h`, `mmp_ctrl.h`.
- Detected declarations: `function Copyright`, `function lcd_spi_setup`, `function lcd_spi_one_transfer`, `function list_for_each_entry`, `function lcd_spi_register`.
- Atlas domain: Driver Families / drivers/video.
- 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.