SPI驅動程序設計(2)—Linux SPI子系統

1.SPI子系統架構

  • SPI 子系統架構主要有三部分組成
    • SPI core核心:用於連接SPI客戶驅動和SPI主控制器驅動,並且提供了對應的註冊和註銷的接口。
    • SPI controller driver主控制器驅動:用來驅動SPI控制器。
    • SPI protocol drvier客戶驅動:用來驅動SPI設備。

2.SPI控制器驅動分析

  • 1.SPI控制器驅動對應的內核文件在/drivers/spi/spi_s3c24xx.c中。找到模塊初始化函數s3c24xx_spi_init,從中可以看出控制器驅動是平臺驅動。
static int __init s3c24xx_spi_init(void)
{
        return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);
}
  • 2.找到初始化函數s3c24xx_spi_probe。硬件初始化在s3c24xx_spi_initialsetup中。註冊函數在spi_regiseter_master中,該函數由SPI核心提供給控制器驅動。
static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
{
	/* for the moment, permanently enable the clock */

	clk_enable(hw->clk);

	/* program defaults into the registers */

	writeb(0xff, hw->regs + S3C2410_SPPRE);
	writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
	writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);

	if (hw->pdata) {
		if (hw->set_cs == s3c24xx_spi_gpiocs)
			gpio_direction_output(hw->pdata->pin_cs, 1);

		if (hw->pdata->gpio_setup)
			hw->pdata->gpio_setup(hw->pdata, 1);
	}
}
...
  • 3.數據的收發在中斷處理函數s3c24xx_spi_irq中。
static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
{
	struct s3c24xx_spi *hw = dev;
	unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
	unsigned int count = hw->count;

	if (spsta & S3C2410_SPSTA_DCOL) {
		dev_dbg(hw->dev, "data-collision\n");
		complete(&hw->done);
		goto irq_done;
	}

	if (!(spsta & S3C2410_SPSTA_READY)) {
		dev_dbg(hw->dev, "spi not ready for tx?\n");
		complete(&hw->done);
		goto irq_done;
	}

	hw->count++;

	if (hw->rx)
		hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);

	count++;

	if (count < hw->len)
		writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
	else
		complete(&hw->done);

 irq_done:
	return IRQ_HANDLED;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章