设备驱动之SPI

本文非专业讲SPI,只是讲网上看到的资料略微总结,并加上自己的想法,附资料links。

 

devs.c  :各个platform_device 的定义,比如I2C、USB、SPI等等。应该是内核加载时,读取该配置文件,然后注册进系统。目录在/arch/arm/plat-samsung/devs.c

  比如:

    

/* SPI */

#ifdef CONFIG_PLAT_S3C24XX
static struct resource s3c_spi0_resource[] = { //下面s3c_device_spi0对象的资源
    [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
    [1] = DEFINE_RES_IRQ(IRQ_SPI0),
};

struct platform_device s3c_device_spi0 = {  // 声明s3c_device_spi0 platform设备
    .name        = "s3c2410-spi",  //会与驱动匹配,比较两个名字是一样的
    .id        = 0,  //相当于次设备号
    .num_resources    = ARRAY_SIZE(s3c_spi0_resource),
    .resource    = s3c_spi0_resource,
    .dev        = {
        .dma_mask        = &samsung_device_dma_mask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
    }
};

 

 spi_master 本质上是个device,看做总线。spi总线以spi_master体现,可以当做一样

奇怪  SPI_MASTER: comment "SPI Master Controller Drivers"

struct spi_master {
    struct device    dev; //说明spi_master本质上是device的封装,总线本身就是一个设备

    struct list_head list;
    s16            bus_num;
    u16            num_chipselect;
    u16            dma_alignment;

    /* spi_device.mode flags understood by this controller driver */
    u16            mode_bits;

    /* other constraints relevant to this driver */
    u16            flags;
#define SPI_MASTER_HALF_DUPLEX    BIT(0)        /* can't do full duplex */
#define SPI_MASTER_NO_RX    BIT(1)        /* can't do buffer read */
#define SPI_MASTER_NO_TX    BIT(2)        /* can't do buffer write */

    /* lock and mutex for SPI bus locking */
    spinlock_t        bus_lock_spinlock;
    struct mutex        bus_lock_mutex;

    /* flag indicating that the SPI bus is locked for exclusive use */
    bool            bus_lock_flag;
    int            (*setup)(struct spi_device *spi);

    int            (*transfer)(struct spi_device *spi,
                        struct spi_message *mesg);

    /* called on release() to free memory provided by spi_master */
    void            (*cleanup)(struct spi_device *spi);

    bool                queued;
    struct kthread_worker        kworker;
    struct task_struct        *kworker_task;
    struct kthread_work        pump_messages;
    spinlock_t            queue_lock;
    struct list_head        queue;
    struct spi_message        *cur_msg;
    bool                busy;
    bool                running;
    bool                rt;

    int (*prepare_transfer_hardware)(struct spi_master *master);
    int (*transfer_one_message)(struct spi_master *master,
                    struct spi_message *mesg);
    int (*unprepare_transfer_hardware)(struct spi_master *master);
};

 

struct boardinfo {
    struct list_head    list;
    struct spi_board_info    board_info;
};

 

SPI分三层:

  SPI核心层:/drivers/spi/spi.c

    postcore_initcall(spi_init);--->内核调用spi_init()---->status = bus_register(&spi_bus_type);spi总线对象注册到platform_bus上。

  SPI控制器驱动层:/drivers/spi/spi-s3c24xx.c   

    module_platform_driver(s3c24xx_spi_driver);--->s3c24xx_spi_driver->probe()初始化控制器各项--->spi_alloc_master()分配一个spi_master(spc.c中fun)--->

    -->spi_bitbang_start()中---->调用spi_register_master()(spc.c中fun)注册spi_master主控制器到platform_bus上,--->device_add(&master->dev);(spc.c中fun)//register the device, then userspace will see it.

  SPI设备驱动层: /drivers/spi/spidev.c

     module_init(spidev_init);--->spidev_init(void)--->spi_register_driver(&spidev_spi_driver);(spi.c中fun) //注册设备驱动

 

 1、spi_device代表一个外围spi设备,由master controller driver注册完成后扫描BSP中注册设备产生的设备链表并向spi_bus注册产生。

2、  spi_driver代表一个SPI protocol drivers,即外设驱动。

3、spi_master代表一个主机控制器,此处即S3C2440中的SPI控制器,它是抽象出来的?

4、spi_transfer代表一个读写缓冲对,包含接收缓冲区及发送缓冲区,其实,spi_transfer的发送是通过构建spi_message实现,通过将spi_transfer中的链表transfer_list链接到spi_message中的transfers,再以spi_message形势向底层发送数据。

5、spi_message代表spi消息,由多个spi_ transfer段组成:

6、s3c24xx_spi代表具体的s3c2440中的spi控制器,包含了控制器的信息,如中断,寄存器等信息,定义于/drivers/spi/spi_s3c24xx.c(因为该结构与具体的硬件有关,属于linux里面的非通用代码)

7、struct spi_bitbang是具体的负责信息传输的数据结构,它维护一个workqueue_struct,每收到一个消息,都会向其中添加一个work_struct,由内核守护进程在将来的某个时间调用该work_struct中的function进行消息发送。 

 

 

related links:

 

posted @ 2015-02-10 14:22  zyliang  阅读(1293)  评论(0编辑  收藏  举报