快速业务通道

Linux主机驱动与外设驱动分离思想

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-19
truct spi_master *master);

void spi_unregister_master(struct spi_master *master);

在Linux中,用代码清单12.13的spi_driver结构体来描述一个SPI外设驱动,可以认为是spi_master的client驱动.

代码清单12.13 spi_driver结构体

1 struct spi_driver {

2 int (*probe)(struct spi_device *spi);

3 int (*remove)(struct spi_device *spi);

4 void (*shutdown)(struct spi_device *spi);

5 int (*suspend)(struct spi_device *spi, pm_message_t mesg);

6 int (*resume)(struct spi_device *spi);

7 struct device_driver driver;

8 };

可以看出,spi_driver结构体和platform_driver结构体有极大的相似性,都有probe()、remove()、suspend()、resume()这样的接口.是的,这几乎是一切client驱动的习惯模板.

在SPI外设驱动中,当透过SPI总线进行数据传输的时候,使用了一套与CPU无关的统一的接口.这套接口的第1个关键数据结构就是spi_transfer,它用于描述SPI传输,如代码清单12.14.

代码清单12.14 spi_transfer结构体

1 struct spi_transfer {

2 const void *tx_buf;

3 void *rx_buf;

4 unsigned len;

5

6 dma_addr_t tx_dma;

7 dma_addr_t rx_dma;

8

9 unsigned cs_change:1;

10 u8 bits_per_word;

11 u16 delay_usecs;

12 u32 speed_hz;

13

14 struct list_head transfer_list;

15 };

而一次完整的SPI传输流程可能不只包含1次spi_transfer,它可能包含1个或多个spi_transfer,这些spi_transfer最终通过spi_message组织在一起,其定义如代码清单12.15.

代码清单12.15 spi_message结构体

1 struct spi_message {

2 struct list_head transfers;

3

4 struct spi_device *spi;

5

6 unsigned is_dma_mapped:1;

7

8 /* 完成被一个callback报告 */

9 void (*complete)(void *context);

10 void *context;

11 unsigned actual_length;

12 int status;

13

14 struct list_head queue;

15 void *state;

16 };

通过spi_message_init()可以初始化spi_message,而将spi_transfer添加到spi_message队列的方法则是:

void spi_message_add_tail(struct spi_transfer *t, struct spi_message *m);

发起一次spi_message的传输有同步和异步两种方式,使用同步API时,会阻塞等待这个消息被处理完.同步操作时使用的API是:

int spi_sync(struct spi_device *spi, struct spi_message *message);

使用异步API时,不会阻塞等待这个消息被处理完,但是可以在spi_message的complete字段挂接一个回调函数,当消息被处理完成后,该函数会被调用.异步操作时使用的API是:

int spi_async(struct spi_device *spi, struct spi_message *message);

代码清单12.16是非常典型的初始化spi_transfer、spi_message并进行SPI数据传输的例子,同时它们也是SPI核心层的2个通用API,在SPI外设驱动中可以直接调用它们进行写和读操作.

代码清单12.16 SPI传输实例spi_write()、spi_read() API

1 static inline int

2 spi_write(struct spi_device *spi, const u8 *buf, size_t len)

3 {

4 struct spi_transfer t = {

5 .tx_buf = buf,

6 .len = len,

7 };

8 struct spi_message m;

9

10 spi_message_init(&m);

11 spi_message_add_tail(&t, &m);

12 return spi_sync(spi, &m);

13 }

14

15 static inline int

16 spi_read(struct spi_device *spi, u8 *buf, size_t len)

17 {

18 struct spi_transfer t = {

19 .rx_buf = buf,

20 .len = len,

21 };

22 struct spi_message m;

23

24 spi_message_init(&m);

25 spi_message_add_tail(&t, &m);

26 return spi_sync(spi, &am

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多
上一篇: Linux菜鸟之路下一篇: 更改linux主题

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号