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

当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平台设备与之匹配

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值