硬件平台: am335x
内核版本:linux-3.8.13
编译器版本: arm-linux-gnueabihf-gcc


1.注册驱动程序

// 设备匹配列表
static const struct of_device_id spidev_dt_ids[] = {
    { .compatible = "oroct,uart" },
    {},
};
 
// spi驱动结构
static struct spi_driver spidev_spi_driver = {
    .driver = {
        .name = "oroct_spi",    //  这个名子不重要了
        .of_match_table = of_match_ptr(spidev_dt_ids),
    },
    .probe  =   spidev_probe,    // 探测函数
    .remove =   spidev_remove,   // 移除函数
};

static int __init hnsw_spidev_init(void)
{
    int ret; 
        
    // 注册SPI驱动程序
    ret = spi_register_driver(&spidev_spi_driver);   
         
    pr_info("spi_register_driver.ret = %d\r\n",ret);
            
    return ret;
}

static void __exit hnsw_spidev_exit(void)
{   
    // 注销SPI驱动
    spi_unregister_driver(&spidev_spi_driver);
}

module_init(hnsw_spidev_init);
module_exit(hnsw_spidev_exit);

2.添加代码树

&spi1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&mcspi1_pins>;
    
    // 之前添加的spidev设备
    spidev@0 {
        status = "okay";
        compatible = "rohm,dh2228fv";
        spi-max-frequency=<24000000>;
        reg = <0>;    
    };
    
    // 在这里添加新的spi接口的设备
    spiuart@1 {
        status = "okay";
        compatible = "oroct,uart";
        spi-max-frequency=<24000000>;
        reg = <1>;    // 片选线SPI_nCS1
    };
    

3.设备探测函数

static int spidev_probe(struct spi_device *spi)
{
       
      
}

SPI收发处理

static void spidev_complete(void *arg)
{
    complete(arg);
}

/* spi收发 */
static ssize_t
spidev_sync(struct spidev_data *spidev, struct spi_message *message)
{
    DECLARE_COMPLETION_ONSTACK(done);
    int status;

    message->complete = spidev_complete;    // 消息结束回调函数
    message->context = &done;

    spin_lock_irq(&spidev->spi_lock);
    if (spidev->spi == NULL) {
        status = -ESHUTDOWN;
    }
    else {
        status = spi_async(spidev->spi, message);   // 这一句才是干货
    }
    spin_unlock_irq(&spidev->spi_lock);

    if (status == 0) {
        wait_for_completion(&done);
        status = message->status;
        if (status == 0)
            status = message->actual_length;
    }
    return status;
}

//----------------------------------------------------------
/* spi发送操作 */
static inline ssize_t
spidev_sync_write(struct spidev_data* spidev, void* buff, int len)
{   
    struct spi_transfer t = {
        .tx_buf = buff,    // 发送缓存
        .len    = len,
    };
        
    // 标准的SPI收发流程
    struct spi_message  m;    
    spi_message_init(&m);
    spi_message_add_tail(&t,   &m);
    return spidev_sync(spidev, &m);
}

/* spi接收操作 */
static inline ssize_t
spidev_sync_read(struct spidev_data* spidev, void* buff, int len)
{
    struct spi_transfer t = {
        .rx_buf   = buff,    // 接收缓存
        .len      = len,
    };
    
    // 标准的SPI收发流程
    struct spi_message  m;
    spi_message_init(&m);           
    spi_message_add_tail(&t,  &m);
    return spidev_sync(spidev,&m);
}