62 linux内核里基于GPIO口的SPI控制器驱动

来源:互联网 发布:搜索引擎优化流程 编辑:程序博客网 时间:2024/05/19 02:21

当SOC里的spi控制器不稳定,或者spi控制器不够用时,可以基于GPIO口扩展出SPI控制器.
在Linux内核里已提供了相应的代码,是一个平台驱动,只需写平台设备描述相关资源即可.

make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-Device Drivers  --->    [*] SPI support  --->         <*>   GPIO-based bitbanging SPI Master 

驱动源码在”drivers/spi/spi-gpio.c”

static struct platform_driver spi_gpio_driver = {     .driver.name    = DRIVER_NAME, //spi_gpio, 按名字匹配平台设备    .driver.owner   = THIS_MODULE,    .probe      = spi_gpio_probe,    .remove     = __devexit_p(spi_gpio_remove),};module_platform_driver(spi_gpio_driver);//通过阅读平台驱动里的probe函数可以得知平台设备需要提供的参数static int __devinit spi_gpio_probe(struct platform_device *pdev){    int             status;    struct spi_master       *master;    struct spi_gpio         *spi_gpio;    struct spi_gpio_platform_data   *pdata;    u16 master_flags = 0;    pdata = pdev->dev.platform_data;    ...    status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);    ...    master = spi_alloc_master(&pdev->dev, sizeof *spi_gpio);    ...    spi_gpio = spi_master_get_devdata(master);    platform_set_drvdata(pdev, spi_gpio);    spi_gpio->pdev = pdev;    master->flags = master_flags;    master->bus_num = pdev->id;    master->num_chipselect = SPI_N_CHIPSEL;    master->setup = spi_gpio_setup;    master->cleanup = spi_gpio_cleanup;    spi_gpio->bitbang.master = spi_master_get(master);    spi_gpio->bitbang.chipselect = spi_gpio_chipselect;    ...    spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer;    status = spi_bitbang_start(&spi_gpio->bitbang);    ...    return status;}平台数据所用的类型"include/linux/spi/spi_gpio.h"struct spi_gpio_platform_data {    unsigned    sck; // SCL所用的IO口     unsigned    mosi; // MOSI用的IO口    unsigned    miso; // MISO用的IO口    u16     num_chipselect; //支持多少个spi设备};

///////////////////////////////////
例如把 PA7, PA8, PA9分别作为SPI控制器的SCL, MOSI, MISO

myspi_pdev.c

#include <linux/init.h>#include <linux/module.h>#include <linux/platform_device.h>#include <linux/spi/spi_gpio.h>#include <mach/gpio.h>struct spi_gpio_platform_data pdata = {    GPIOA(7), GPIOA(8), GPIOA(9), 2};struct platform_device myspi_pdev = {    .name = "spi_gpio", //与平台驱动名一致    .id = 3, //控制器的编号3    .dev = {            .platform_data = &pdata,    },};  module_driver(myspi_pdev, platform_device_register, platform_device_unregister);MODULE_LICENSE("GPL");

///////////////////////////
加载模块后,在/sys/bus/platform/drivers/spi_gpio目录下是否有spi_gpio.3平台设备与之匹配

原创粉丝点击