感谢支持
我们一直在努力

Linux设备模型之spi子系统

相比于前面介绍的i2c子系统(见 http://www.linuxidc.com/Linux/2012-01/52782.htm ),spi子系统相对简单,和i2c的结构也很相似,这里主要介绍一下平台无关部分的代码。先概括的说一下,spi总线或者说是spi控制器用结构体struct spi_master来表述,而一般不会明显的主动实现这个结构而是借助板级的一些信息结构,利用spi的模型填充,存在板级信息的一条链表board_list,上面挂接着板级spi设备的描述信息,其挂接的结构是struct boardinfo,这个结构内部嵌入了具体的板级spi设备所需信息结构struct spi_board_info,对于要操控的spi设备,用struct spidev_data来描述,内嵌了具体设备信息结构struct spi_device,并通过struct spi_device->device_entry成员挂接到全局spi设备链表device_list,结构struct spi_device就是根据前面board_list上所挂的信息填充的,而driver端比较简单,用struct spi_driver来描述,一会儿会看到该结构和标准的platform非常相似,总括的说下一般编写流程:对于soc,spi控制器一般注册成platform,当driver匹配后,会根据platform_device等信息构造出spi_master,一般发生在driver的probe函数,并且注册该master,在master的注册过程中会去遍历board_list找到bus号相同的spi设备信息,并实例化它,好了先就说这么多,下面先看一下具体的数据结构。

一、spi相关的数据结构


      先看一下spi设备的板级信息填充的结构:


     

[cpp]


  1. struct boardinfo {  

  2.     struct list_head    list;              //用于挂接到链表头board_list上                 

  3.     unsigned        n_board_info;      //设备信息号,spi_board_info成员的编号   

  4.     struct spi_board_info   board_info[0];     //内嵌的spi_board_info结构   

  5. };  

  6. //其中内嵌的描述spi设备的具体信息的结构struct spi_board_info为:   

  7. struct spi_board_info {  

  8.     /* the device name and module name are coupled, like platform_bus; 

  9.      * “modalias” is normally the driver name. 

  10.      * 

  11.      * platform_data goes to spi_device.dev.platform_data, 

  12.      * controller_data goes to spi_device.controller_data, 

  13.      * irq is copied too 

  14.      */  

  15.     char        modalias[SPI_NAME_SIZE];     //名字   

  16.     const void  *platform_data;              //如同注释写的指向spi_device.dev.platform_data   

  17.     void        *controller_data;            //指向spi_device.controller_data   

  18.     int     irq;                         //中断号   

  19.     /* slower signaling on noisy or low voltage boards */  

  20.     u32     max_speed_hz;                //时钟速率   

  21.     /* bus_num is board specific and matches the bus_num of some 

  22.      * spi_master that will probably be registered later. 

  23.      * 

  24.      * chip_select reflects how this chip is wired to that master; 

  25.      * it’s less than num_chipselect. 

  26.      */  

  27.     u16     bus_num;                     //所在的spi总线编号   

  28.     u16     chip_select;                     

  29.     /* mode becomes spi_device.mode, and is essential for chips 

  30.      * where the default of SPI_CS_HIGH = 0 is wrong. 

  31.      */  

  32.     u8      mode;                        //模式   

  33.     /* … may need additional spi_device chip config data here. 

  34.      * avoid stuff protocol drivers can set; but include stuff 

  35.      * needed to behave without being bound to a driver: 

  36.      *  – quirks like clock rate mattering when not selected 

  37.      */  

  38. };   


     利用boardinfo->list成员会将自身挂接到全局的board_list链表上。


     再来看一下spi控制器的表述结构:


 

[cpp]


  1. struct spi_master {  

  2.     struct device   dev;                //内嵌的标准dev结构   

  3.     /* other than negative (== assign one dynamically), bus_num is fully 

  4.      * board-specific.  usually that simplifies to being SOC-specific. 

  5.      * example:  one SOC has three SPI controllers, numbered 0..2, 

  6.      * and one board’s schematics might show it using SPI-2.  software 

  7.      * would normally use bus_num=2 for that controller. 

  8.      */  

  9.     s16         bus_num;                  //标识的总线号   

  10.     /* chipselects will be integral to many controllers; some others 

  11.      * might use board-specific GPIOs. 

  12.      */  

  13.     u16         num_chipselect;  

  14.     /* some SPI controllers pose alignment requirements on DMAable 

  15.      * buffers; let protocol drivers know about these requirements. 

  16.      */  

  17.     u16         dma_alignment;           //dma对其要求   

  18.     /* spi_device.mode flags understood by this controller driver */  

  19.     u16         mode_bits;               //代表操作的spi_device.mode   

  20.     /* other constraints relevant to this driver */  

  21.     u16         flags;                   //另外的一些标志   

  22. #define SPI_MASTER_HALF_DUPLEX  BIT(0)      /* can’t do full duplex */   

  23. #define SPI_MASTER_NO_RX    BIT(1)      /* can’t do buffer read */   

  24. #define SPI_MASTER_NO_TX    BIT(2)      /* can’t do buffer write */   

  25.     /* lock and mutex for SPI bus locking */  

  26.     spinlock_t      bus_lock_spinlock;  

  27.     struct mutex        bus_lock_mutex;  

  28.     /* flag indicating that the SPI bus is locked for exclusive use */  

  29.     bool            bus_lock_flag;  

  30.     /* Setup mode and clock, etc (spi driver may call many times). 

  31.      * 

  32.      * IMPORTANT:  this may be called when transfers to another 

  33.      * device are active.  DO NOT UPDATE SHARED REGISTERS in ways 

  34.      * which could break those transfers. 

  35.      */  

  36.     int         (*setup)(struct spi_device *spi);   //设置模式   

  37.     /* bidirectional bulk transfers 

  38.      * 

  39.      * + The transfer() method may not sleep; its main role is 

  40.      *   just to add the message to the queue. 

  41.      * + For now there’s no remove-from-queue operation, or 

  42.      *   any other request management 

  43.      * + To a given spi_device, message queueing is pure fifo 

  44.      * 

  45.      * + The master’s main job is to process its message queue, 

  46.      *   selecting a chip then transferring data 

  47.      * + If there are multiple spi_device children, the i/o queue 

  48.      *   arbitration algorithm is unspecified (round robin, fifo, 

  49.      *   priority, reservations, preemption, etc) 

  50.      * 

  51.      * + Chipselect stays active during the entire message 

  52.      *   (unless modified by spi_transfer.cs_change != 0). 

  53.      * + The message transfers use clock and SPI mode parameters 

  54.      *   previously established by setup() for this device 

  55.      */  

  56.     int         (*transfer)(struct spi_device *spi,    //传输函数   

  57.                         struct spi_message *mesg);  

  58.     /* called on release() to free memory provided by spi_master */  

  59.     void            (*cleanup)(struct spi_device *spi);  

  60. };  


   而对于要操控的spi总线上的设备,其表述结构为:


[cpp]


  1. struct spi_device {  

  2.     struct device       dev;               //内嵌标准device结构体   

  3.     struct spi_master   *master;         //spi主控制器   

  4.     u32         max_speed_hz;              //时钟速率   

  5.     u8          chip_select;               //设备编号   

  6.     u8          mode;                      //模式   

  7. #define SPI_CPHA    0x01            /* clock phase */   

  8. #define SPI_CPOL    0x02            /* clock polarity */   

  9. #define SPI_MODE_0  (0|0)           /* (original MicroWire) */   

  10. #define SPI_MODE_1  (0|SPI_CPHA)   

  11. #define SPI_MODE_2  (SPI_CPOL|0)   

  12. #define SPI_MODE_3  (SPI_CPOL|SPI_CPHA)   

  13. #define SPI_CS_HIGH 0x04            /* chipselect active high? */   

  14. #define SPI_LSB_FIRST   0x08            /* per-word bits-on-wire */   

  15. #define SPI_3WIRE   0x10            /* SI/SO signals shared */   

  16. #define SPI_LOOP    0x20            /* loopback mode */   

  17. #define SPI_NO_CS   0x40            /* 1 dev/bus, no chipselect */   

  18. #define SPI_READY   0x80            /* slave pulls low to pause */   

  19.     u8          bits_per_word;  

  20.     int         irq;                        //中断号   

  21.     void            *controller_state;        //控制状态   

  22.     void            *controller_data;         //私有数据   

  23.     char            modalias[SPI_NAME_SIZE];  //名字   

  24.     /* 

  25.      * likely need more hooks for more protocol options affecting how 

  26.      * the controller talks to each chip, like: 

  27.      *  – memory packing (12 bit samples into low bits, others zeroed) 

  28.      *  – priority 

  29.      *  – drop chipselect after each word 

  30.      *  – chipselect delays 

  31.      *  – … 

  32.      */  

  33. };  

再看一下对于spi设备结构更高层次的表述结构:


[cpp]


  1. struct spidev_data {  

  2.     dev_t           devt;  

  3.     spinlock_t      spi_lock;  

  4.     struct spi_device   *spi;            //指向spi设备结构   

  5.     struct list_head    device_entry;    //spi设备链表device_list挂接点      

  6.     /* buffer is NULL unless this device is open (users > 0) */  

  7.     struct mutex        buf_lock;  

  8.     unsigned        users;  

  9.     u8          *buffer;  

  10. };  


而driver端的表述结构struct spi_driver,具体如下:


[cpp]


  1. struct spi_driver {  

  2.     const struct spi_device_id *id_table; //匹配的设备表   

  3.     int         (*probe)(struct spi_device *spi);  

  4.     int         (*remove)(struct spi_device *spi);  

  5.     void            (*shutdown)(struct spi_device *spi);  

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

  7.     int         (*resume)(struct spi_device *spi);  

  8.     struct device_driver    driver;  

  9. };  


是不是很标准?哈,好了,关于相关的数据结构就先介绍这么多。


二、spi核心代码的初始化分析


      首先看一下spi总线的注册代码很简单,位于driver/spi/spi.c下:

[cpp]


  1. static int __init spi_init(void)  

  2. {  

  3.     int status;  

  4.    

  5.   //其中buf为static u8 *buf,    

  6.   //SPI_BUFSIZ为#define  SPI_BUFSIZ  max(32,SMP_CACHE_BYTES)   

  7.     buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);  

  8.     if (!buf) {  

  9.         status = -ENOMEM;  

  10.         goto err0;  

  11.     }  

  12.     

  13.   //注册spi_bus   

  14.     status = bus_register(&spi_bus_type);  

  15.     if (status < 0)  

  16.         goto err1;  

  17.     

  18.   //在sys/class下产生spi_master这个节点,用于自动产生设备节点   

  19.   //下面挂接的是控制器的节点   

  20.     status = class_register(&spi_master_class);  

  21.     if (status < 0)  

  22.         goto err2;  

  23.     return 0;  

  24. err2:  

  25.     bus_unregister(&spi_bus_type);  

  26. err1:  

  27.     kfree(buf);  

  28.     buf = NULL;  

  29. err0:  

  30.     return status;  

  31. }  

  32. //其中注册bus结构为   

  33. struct bus_type spi_bus_type = {  

  34.     .name       = “spi”,  

  35.     .dev_attrs  = spi_dev_attrs,  

  36.     .match      = spi_match_device,    //匹配函数   

  37.     .uevent     = spi_uevent,  

  38.     .suspend    = spi_suspend,  

  39.     .resume     = spi_resume,  

  40. };  

  41. //类函数为   

  42. static struct class spi_master_class = {  

  43.     .name       = “spi_master”,  

  44.     .owner      = THIS_MODULE,  

  45.     .dev_release    = spi_master_release,  

  46. };  

  47. //顺便把driver与device的匹配函数也一起分析了吧,很简单   

  48. static int spi_match_device(struct device *dev, struct device_driver *drv)  

  49. {  

  50.     const struct spi_device *spi = to_spi_device(dev);  

  51.     const struct spi_driver *sdrv = to_spi_driver(drv);  

  52.     /* Attempt an OF style match */  

  53.       

  54.     //利用of表进行匹配   

  55.     if (of_driver_match_device(dev, drv))  

  56.         return 1;  

  57.     

  58.         //利用id表进行匹配   

  59.     if (sdrv->id_table)  

  60.         return !!spi_match_id(sdrv->id_table, spi);  

  61.     

  62.         //利用名字进行匹配   

  63.     return strcmp(spi->modalias, drv->name) == 0;  

  64. }   


    再看一下driver的注册,spi_register_driver函数:


[cpp]


  1. int spi_register_driver(struct spi_driver *sdrv)  

  2. {  

  3.       

  4.     //很类似于platfor的注册,很简单,   

  5.     //就不具体介绍了   

  6.     sdrv->driver.bus = &spi_bus_type;  

  7.     if (sdrv->probe)  

  8.         sdrv->driver.probe = spi_drv_probe;  

  9.     if (sdrv->remove)  

  10.         sdrv->driver.remove = spi_drv_remove;  

  11.     if (sdrv->shutdown)  

  12.         sdrv->driver.shutdown = spi_drv_shutdown;  

  13.           

  14.     //注册标准的driver,此时会去匹配bus设备链表上   

  15.     //支持的device,找到会调用相应函数   

  16.     return driver_register(&sdrv->driver);  

  17. }  


还有个板级信息的添加函数:


[cpp]


  1. int __init  

  2. spi_register_board_info(struct spi_board_info const *info, unsigned n)  

  3. {  

  4.     struct boardinfo    *bi;  

  5.     bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL);  

  6.     if (!bi)  

  7.         return -ENOMEM;  

  8.     bi->n_board_info = n;  

  9.     memcpy(bi->board_info, info, n * sizeof *info);  

  10.     mutex_lock(&board_lock);  

  11.     list_add_tail(&bi->list, &board_list);  

  12.     mutex_unlock(&board_lock);  

  13.     return 0;  

  14. }  


函数很简单,利用定义的spi_board_info信息,填充了boardinfo结构,并挂到board_list链表。


最后来看一下一个重量级函数,master的注册函数:


[cpp]


  1. int spi_register_master(struct spi_master *master)  

  2. {  

  3.     static atomic_t     dyn_bus_id = ATOMIC_INIT((1<<15) – 1);  

  4.     struct device       *dev = master->dev.parent;  

  5.     int         status = -ENODEV;  

  6.     int         dynamic = 0;  

  7.   //内嵌的标准设备结构必须初始化好   

  8.     if (!dev)  

  9.         return -ENODEV;  

  10.     /* even if it’s just one always-selected device, there must 

  11.      * be at least one chipselect 

  12.      */  

  13.        

  14.     //支持的设备数量为0,出错返回   

  15.     if (master->num_chipselect == 0)  

  16.         return -EINVAL;  

  17.     /* convention:  dynamically assigned bus IDs count down from the max */  

  18.       

  19.     if (master->bus_num < 0) {  

  20.         /* FIXME switch to an IDR based scheme, something like 

  21.          * I2C now uses, so we can’t run out of “dynamic” IDs 

  22.          */  

  23.       //控制器编号(总线编号)不能小于0   

  24.         master->bus_num = atomic_dec_return(&dyn_bus_id);  

  25.         dynamic = 1;  

  26.     }  

  27.     spin_lock_init(&master->bus_lock_spinlock);  

  28.     mutex_init(&master->bus_lock_mutex);  

  29.     master->bus_lock_flag = 0;  

  30.     /* register the device, then userspace will see it. 

  31.      * registration fails if the bus ID is in use. 

  32.      */  

  33.        

  34.     //设置master->dev的名字,形式为spi+bus_num,如:spi0   

  35.     dev_set_name(&master->dev, “spi%u”, master->bus_num);  

  36.       

  37.     //注册master内嵌的标准device结构   

  38.     status = device_add(&master->dev);  

  39.     if (status < 0)  

  40.         goto done;  

  41.     dev_dbg(dev, “registered master %s%s/n”, dev_name(&master->dev),  

  42.             dynamic ? ” (dynamic)” : “”);  

  43.     /* populate children from any spi device tables */  

  44.       

  45.     //重点哦,扫描并实例化spi设备   

  46.     scan_boardinfo(master);  

  47.     status = 0;  

  48.     /* Register devices from the device tree */  

  49.     of_register_spi_devices(master);  

  50. done:  

  51.     return status;  

  52. }  

  53. //先来看scan_boardinfo这个分支   

  54. static void scan_boardinfo(struct spi_master *master)  

  55. {  

  56.     struct boardinfo    *bi;  

  57.     mutex_lock(&board_lock);  

  58.       

  59.     //找到我们注册的spi相关的板级信息结构体   

  60.     //还记得board_list吧   

  61.     list_for_each_entry(bi, &board_list, list) {  

  62.         struct spi_board_info   *chip = bi->board_info;  

  63.         unsigned        n;  

  64.       

  65.     //因为可能存在多个spi总线,因此spi信息结构也会有   

  66.     //多个,找到bus号匹配的就对了   

  67.         for (n = bi->n_board_info; n > 0; n–, chip++) {  

  68.             if (chip->bus_num != master->bus_num)  

  69.                 continue;  

  70.             /* NOTE: this relies on spi_new_device to 

  71.              * issue diagnostics when given bogus inputs 

  72.              */  

  73.               

  74.             //找到了就要实例化它上面的设备了   

  75.             (void) spi_new_device(master, chip);  

  76.         }  

  77.     }  

  78.     mutex_unlock(&board_lock);  

  79. }  

  80. //跟进spi_new_device函数   

  81. struct spi_device *spi_new_device(struct spi_master *master,  

  82.                   struct spi_board_info *chip)  

  83. {  

  84.     struct spi_device   *proxy;  

  85.     int         status;  

  86.     /* NOTE:  caller did any chip->bus_num checks necessary. 

  87.      * 

  88.      * Also, unless we change the return value convention to use 

  89.      * error-or-pointer (not NULL-or-pointer), troubleshootability 

  90.      * suggests syslogged diagnostics are best here (ugh). 

  91.      */  

  92.     

  93.   //为需要实例化的设备分配内存   

  94.   //同时会将bus成员制定为spi_bus_type,parent   

  95.   //指定为该master,层次关系   

  96.     proxy = spi_alloc_device(master);  

  97.     if (!proxy)  

  98.         return NULL;  

  99.     WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));  

  100.   //各个成员赋值,都是用我们注册的板级信息   

  101.     proxy->chip_select = chip->chip_select;  

  102.     proxy->max_speed_hz = chip->max_speed_hz;  

  103.     proxy->mode = chip->mode;  

  104.     proxy->irq = chip->irq;  

  105.     strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));  

  106.     proxy->dev.platform_data = (void *) chip->platform_data;  

  107.     proxy->controller_data = chip->controller_data;  

  108.     proxy->controller_state = NULL;  

  109.     

  110.   //把该设备添加到spi总线   

  111.     status = spi_add_device(proxy);  

  112.     if (status < 0) {  

  113.         spi_dev_put(proxy);  

  114.         return NULL;  

  115.     }  

  116.     return proxy;  

  117. }  

  118. //继续spi_add_device函数   

  119. int spi_add_device(struct spi_device *spi)  

  120. {  

  121.     static DEFINE_MUTEX(spi_add_lock);  

  122.     struct device *dev = spi->master->dev.parent;  

  123.     struct device *d;  

  124.     int status;  

  125.     /* Chipselects are numbered 0..max; validate. */  

  126.       

  127.     //spi设备的编号不能大于master定义的最大数目   

  128.     if (spi->chip_select >= spi->master->num_chipselect) {  

  129.         dev_err(dev, “cs%d >= max %d/n”,  

  130.             spi->chip_select,  

  131.             spi->master->num_chipselect);  

  132.         return -EINVAL;  

  133.     }  

  134.     /* Set the bus ID string */  

  135.     //设备节点名字,形式:spi0.0   

  136.     dev_set_name(&spi->dev, “%s.%u”, dev_name(&spi->master->dev),  

  137.             spi->chip_select);  

  138.   

  139.     /* We need to make sure there’s no other device with this 

  140.      * chipselect **BEFORE** we call setup(), else we’ll trash 

  141.      * its configuration.  Lock against concurrent add() calls. 

  142.      */  

  143.     mutex_lock(&spi_add_lock);  

  144.     

  145.   //确保设备不会重复注册   

  146.     d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));  

  147.     if (d != NULL) {  

  148.         dev_err(dev, “chipselect %d already in use/n”,  

  149.                 spi->chip_select);  

  150.         put_device(d);  

  151.         status = -EBUSY;  

  152.         goto done;  

  153.     }  

  154.     /* Drivers may modify this initial i/o setup, but will 

  155.      * normally rely on the device being setup.  Devices 

  156.      * using SPI_CS_HIGH can’t coexist well otherwise… 

  157.      */  

  158.        

  159.     //设置spi模式和时钟速率   

  160.     //会调用spi->master->setup函数设置   

  161.     status = spi_setup(spi);  

  162.     if (status < 0) {  

  163.         dev_err(dev, “can’t %s %s, status %d/n”,  

  164.                 “setup”, dev_name(&spi->dev), status);  

  165.         goto done;  

  166.     }  

  167.     /* Device may be bound to an active driver when this returns */  

  168.       

  169.     //将该实例化的设备添加到总线   

  170.     status = device_add(&spi->dev);  

  171.     if (status < 0)  

  172.         dev_err(dev, “can’t %s %s, status %d/n”,  

  173.                 “add”, dev_name(&spi->dev), status);  

  174.     else  

  175.         dev_dbg(dev, “registered child %s/n”, dev_name(&spi->dev));  

  176. done:  

  177.     mutex_unlock(&spi_add_lock);  

  178.     return status;  

  179. }  

  180. //最后看下spi_setup函数   

  181. int spi_setup(struct spi_device *spi)  

  182. {  

  183.     unsigned    bad_bits;  

  184.     int     status;  

  185.     /* help drivers fail *cleanly* when they need options 

  186.      * that aren’t supported with their current master 

  187.      */  

  188.       

  189.     //必须和当前的master设置的模式匹配   

  190.     bad_bits = spi->mode & ~spi->master->mode_bits;  

  191.     if (bad_bits) {  

  192.         dev_dbg(&spi->dev, “setup: unsupported mode bits %x/n”,  

  193.             bad_bits);  

  194.         return -EINVAL;  

  195.     }  

  196.     if (!spi->bits_per_word)  

  197.         spi->bits_per_word = 8;  

  198.           

  199.         //最后调用控制器平台相关的setup成员设置该spi设备   

  200.     status = spi->master->setup(spi);  

  201.     dev_dbg(&spi->dev, “setup mode %d, %s%s%s%s”  

  202.                 “%u bits/w, %u Hz max –> %d/n”,  

  203.             (int) (spi->mode & (SPI_CPOL | SPI_CPHA)),  

  204.             (spi->mode & SPI_CS_HIGH) ? “cs_high, “ : “”,  

  205.             (spi->mode & SPI_LSB_FIRST) ? “lsb, “ : “”,  

  206.             (spi->mode & SPI_3WIRE) ? “3wire, “ : “”,  

  207.             (spi->mode & SPI_LOOP) ? “loopback, “ : “”,  

  208.             spi->bits_per_word, spi->max_speed_hz,  

  209.             status);  

  210.     return status;  

  211. }  

  212. //回头看下一开始下面的那个分支of_register_spi_devices   

  213. void of_register_spi_devices(struct spi_master *master)  

  214. {  

  215.     struct spi_device *spi;  

  216.     struct device_node *nc;  

  217.     const __be32 *prop;  

  218.     int rc;  

  219.     int len;  

  220.   //如果定义了of_node成员才会走该分支   

  221.     if (!master->dev.of_node)  

  222.         return;  

  223.           

  224.   //从控制器master->dev.of_node中去获取注册SPI设备spi_device的信息,然   

  225.   //后分配结构体spi_device并注册   

  226.     for_each_child_of_node(master->dev.of_node, nc) {  

  227.         /* Alloc an spi_device */  

  228.         spi = spi_alloc_device(master);  

  229.         if (!spi) {  

  230.             dev_err(&master->dev, “spi_device alloc error for %s/n”,  

  231.                 nc->full_name);  

  232.             spi_dev_put(spi);  

  233.             continue;  

  234.         }  

  235.         /* Select device driver */  

  236.         if (of_modalias_node(nc, spi->modalias,  

  237.                      sizeof(spi->modalias)) < 0) {  

  238.             dev_err(&master->dev, “cannot find modalias for %s/n”,  

  239.                 nc->full_name);  

  240.             spi_dev_put(spi);  

  241.             continue;  

  242.         }  

  243.         /* Device address */  

  244.         prop = of_get_property(nc, “reg”, &len);  

  245.         if (!prop || len < sizeof(*prop)) {  

  246.             dev_err(&master->dev, “%s has no ‘reg’ property/n”,  

  247.                 nc->full_name);  

  248.             spi_dev_put(spi);  

  249.             continue;  

  250.         }  

  251.         spi->chip_select = be32_to_cpup(prop);  

  252.         /* Mode (clock phase/polarity/etc.) */  

  253.         if (of_find_property(nc, “spi-cpha”, NULL))  

  254.             spi->mode |= SPI_CPHA;  

  255.         if (of_find_property(nc, “spi-cpol”, NULL))  

  256.             spi->mode |= SPI_CPOL;  

  257.         if (of_find_property(nc, “spi-cs-high”, NULL))  

  258.             spi->mode |= SPI_CS_HIGH;  

  259.         /* Device speed */  

  260.         prop = of_get_property(nc, “spi-max-frequency”, &len);  

  261.         if (!prop || len < sizeof(*prop)) {  

  262.             dev_err(&master->dev, “%s has no ‘spi-max-frequency’ property/n”,  

  263.                 nc->full_name);  

  264.             spi_dev_put(spi);  

  265.             continue;  

  266.         }  

  267.         spi->max_speed_hz = be32_to_cpup(prop);  

  268.         /* IRQ */  

  269.         spi->irq = irq_of_parse_and_map(nc, 0);  

  270.         /* Store a pointer to the node in the device structure */  

  271.         of_node_get(nc);  

  272.         spi->dev.of_node = nc;  

  273.         /* Register the new device */  

  274.         request_module(spi->modalias);  

  275.         rc = spi_add_device(spi);  

  276.         if (rc) {  

  277.             dev_err(&master->dev, “spi_device register error %s/n”,  

  278.                 nc->full_name);  

  279.             spi_dev_put(spi);  

  280.         }  

  281.     }  

  282. }  

三、spi设备文件的自动产生代码分析


      这部分代码相当于注册了一个spi实际driver,既是核心平台无关代码,又是个具体实例,我们来看下一下具体做了什么,也好学习一spi_driver的各部分具体都需要做些什么,代码位于driver/spi/spidev.c下:


[cpp]


  1. static int __init spidev_init(void)  

  2. {  

  3.     int status;  

  4.     /* Claim our 256 reserved device numbers.  Then register a class 

  5.      * that will key udev/mdev to add/remove /dev nodes.  Last, register 

  6.      * the driver which manages those device numbers. 

  7.      */  

  8.     BUILD_BUG_ON(N_SPI_MINORS > 256);  

  9.       

  10.     //注册主设备号为153的spi字符设备,spidev_fops结构下面会介绍   

  11.         //暂且不表   

  12.     status = register_chrdev(SPIDEV_MAJOR, “spi”, &spidev_fops);  

  13.     if (status < 0)  

  14.         return status;  

  15.   //在sys/class下产生spidev这个节点,udev会利用其在dev下产生spidev   

  16.   //这个设备节点   

  17.     spidev_class = class_create(THIS_MODULE, “spidev”);  

  18.     if (IS_ERR(spidev_class)) {  

  19.         unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);  

  20.         return PTR_ERR(spidev_class);  

  21.     }  

  22.         //注册spi驱动,该函数上面已经分析过       

  23.     status = spi_register_driver(&spidev_spi_driver);  

  24.     if (status < 0) {  

  25.         class_destroy(spidev_class);  

  26.         unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);  

  27.     }  

  28.     return status;  

  29. }  

  30. //先看一下spidev_spi_driver具体的结构   

  31. static struct spi_driver spidev_spi_driver = {  

  32.     .driver = {  

  33.         .name =     “spidev”,  

  34.         .owner =    THIS_MODULE,  

  35.     },  

  36.     .probe =    spidev_probe,  

  37.     .remove =   __devexit_p(spidev_remove),  

  38.     /* NOTE:  suspend/resume methods are not necessary here. 

  39.      * We don’t do anything except pass the requests to/from 

  40.      * the underlying controller.  The refrigerator handles 

  41.      * most issues; the controller driver handles the rest. 

  42.      */  

  43. };  

  44. //利用bus的match函数匹配成功后将首先调用spidev_probe函数,我们具体看下该函数:   

  45. static int __devinit spidev_probe(struct spi_device *spi)  

  46. {  

  47.     struct spidev_data  *spidev;  

  48.     int         status;  

  49.     unsigned long       minor;  

  50.     /* Allocate driver data */  

  51.       

  52.     //申请spidev_data所需内存,前面已经讲过该结构   

  53.     spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);  

  54.     if (!spidev)  

  55.         return -ENOMEM;  

  56.     /* Initialize the driver data */  

  57.         //赋值   

  58.     spidev->spi = spi;  

  59.     spin_lock_init(&spidev->spi_lock);  

  60.     mutex_init(&spidev->buf_lock);  

  61.     INIT_LIST_HEAD(&spidev->device_entry);  

  62.     /* If we can allocate a minor number, hook up this device. 

  63.      * Reusing minors is fine so long as udev or mdev is working. 

  64.      */  

  65.     mutex_lock(&device_list_lock);  

  66.       

  67.     //找到一个最小的次设备号   

  68.     //addr为内存区的起始地址,size为要查找的最大长度   

  69.         //返回第一个位为0的位号   

  70.     minor = find_first_zero_bit(minors, N_SPI_MINORS);  

  71.     if (minor < N_SPI_MINORS) {  

  72.         struct device *dev;  

  73.       

  74.        //下面两句用于在sys/class/spidev下产生类似于   

  75.        //spidev%d.%d形式的节点,这样,udev等工具就可以   

  76.        //自动在dev下创建相应设备号的设备节点   

  77.         spidev->devt = MKDEV(SPIDEV_MAJOR, minor);  

  78.         dev = device_create(spidev_class, &spi->dev, spidev->devt,  

  79.                     spidev, “spidev%d.%d”,  

  80.                     spi->master->bus_num, spi->chip_select);  

  81.         status = IS_ERR(dev) ? PTR_ERR(dev) : 0;  

  82.     } else {  

  83.         dev_dbg(&spi->dev, “no minor number available!/n”);  

  84.         status = -ENODEV;  

  85.     }  

  86.       

  87.     //如果成功标明刚才的次设备号已被占用   

  88.     //并且将该设备挂接到device_list链表   

  89.     if (status == 0) {  

  90.         set_bit(minor, minors);  

  91.         list_add(&spidev->device_entry, &device_list);  

  92.     }  

  93.     mutex_unlock(&device_list_lock);  

  94.        //设置spi->dev->p = spidev   

  95.     if (status == 0)  

  96.         spi_set_drvdata(spi, spidev);  

  97.     else  

  98.         kfree(spidev);  

  99.     return status;  

  100. }  


      当我们利用板级信息添加一个设备的时候,该driver如果匹配到这个设备,那么就会自动为其创建设备节点,封装spidev_data


信息,并且挂到全局设备链表device_list。


      最后看一下刚才注册的字符设备的统一操作集:


     

[cpp]


  1. static const struct file_operations spidev_fops = {  

  2.     .owner =    THIS_MODULE,  

  3.     /* REVISIT switch to aio primitives, so that userspace 

  4.      * gets more complete API coverage.  It’ll simplify things 

  5.      * too, except for the locking. 

  6.      */  

  7.     .write =    spidev_write,  

  8.     .read =     spidev_read,  

  9.     .unlocked_ioctl = spidev_ioctl,  

  10.     .open =     spidev_open,  

  11.     .release =  spidev_release,  

  12. };  

  13. //按应用的操作顺序先看下open函数   

  14. static int spidev_open(struct inode *inode, struct file *filp)  

  15. {  

  16.     struct spidev_data  *spidev;  

  17.     int         status = -ENXIO;  

  18.     mutex_lock(&device_list_lock);  

  19.     

  20.   //遍历spi设备链表device_list,根据设备号找到spidev_data结构   

  21.     list_for_each_entry(spidev, &device_list, device_entry) {  

  22.         if (spidev->devt == inode->i_rdev) {  

  23.             status = 0;  

  24.             break;  

  25.         }  

  26.     }  

  27.     if (status == 0) {  

  28.         //buffer为空,为其申请内存   

  29.         if (!spidev->buffer) {  

  30.             spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);  

  31.             if (!spidev->buffer) {  

  32.                 dev_dbg(&spidev->spi->dev, “open/ENOMEM/n”);  

  33.                 status = -ENOMEM;  

  34.             }  

  35.         }  

  36.           

  37.         //设备用户使用量+1   

  38.         if (status == 0) {  

  39.             spidev->users++;  

  40.               

  41.             //传到filp的私有成员,在read,write的时候可以从其得到该结构   

  42.             filp->private_data = spidev;  

  43.             nonseekable_open(inode, filp);  

  44.         }  

  45.     } else  

  46.         pr_debug(“spidev: nothing for minor %d/n”, iminor(inode));  

  47.     mutex_unlock(&device_list_lock);  

  48.     return status;  

  49. }  

  50. //再看read函数   

  51. static ssize_t  

  52. spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)  

  53. {  

  54.     struct spidev_data  *spidev;  

  55.     ssize_t         status = 0;  

  56.     /* chipselect only toggles at start or end of operation */  

  57.     if (count > bufsiz)  

  58.         return -EMSGSIZE;  

  59.     

  60.   //得到传递的结构   

  61.     spidev = filp->private_data;  

  62.     mutex_lock(&spidev->buf_lock);  

  63.       

  64.     //调用��体的读函数   

  65.     status = spidev_sync_read(spidev, count);  

  66.     if (status > 0) {  

  67.         unsigned long   missing;  

  68.     //将得到的信息传递给用户   

  69.         missing = copy_to_user(buf, spidev->buffer, status);  

  70.         if (missing == status)  

  71.             status = -EFAULT;  

  72.         else  

  73.             status = status – missing;  

  74.     }  

  75.     mutex_unlock(&spidev->buf_lock);  

  76.     return status;  

  77. }  

  78. //跟进spidev_sync_read函数,下面的操作比较直白,简要分析下   

  79. //只关注主流程   

  80. static inline ssize_t  

  81. spidev_sync_read(struct spidev_data *spidev, size_t len)  

  82. {  

  83.     //临时传输操作结构   

  84.     struct spi_transfer t = {  

  85.             .rx_buf     = spidev->buffer,  

  86.             .len        = len,  

  87.         };  

  88.           

  89.     //传输所用的信息结构   

  90.     struct spi_message  m;  

  91.   //初始化该结构   

  92.     spi_message_init(&m);  

  93.     //加到请求队列尾   

  94.     spi_message_add_tail(&t, &m);  

  95.     //调用spidev_sync继续   

  96.     return spidev_sync(spidev, &m);  

  97. }  

  98. //继续spidev_sync函数   

  99. static ssize_t  

  100. spidev_sync(struct spidev_data *spidev, struct spi_message *message)  

  101. {  

  102.     DECLARE_COMPLETION_ONSTACK(done);  

  103.     int status;  

  104.     message->complete = spidev_complete;  

  105.     //设置个完成量   

  106.     message->context = &done;  

  107.     spin_lock_irq(&spidev->spi_lock);  

  108.     if (spidev->spi == NULL)  

  109.         status = -ESHUTDOWN;  

  110.     else  

  111.         //继续调用spi_async函数   

  112.         status = spi_async(spidev->spi, message);  

  113.     spin_unlock_irq(&spidev->spi_lock);  

  114.     if (status == 0) {  

  115.         //等待完成   

  116.         wait_for_completion(&done);  

  117.         status = message->status;  

  118.         if (status == 0)  

  119.             status = message->actual_length;  

  120.     }  

  121.     return status;  

  122. }  

  123. //spi_async函数   

  124. int spi_async(struct spi_device *spi, struct spi_message *message)  

  125. {  

  126.     struct spi_master *master = spi->master;  

  127.     int ret;  

  128.     unsigned long flags;  

  129.     spin_lock_irqsave(&master->bus_lock_spinlock, flags);  

  130.     if (master->bus_lock_flag)  

  131.         ret = -EBUSY;  

  132.     else  

  133.         //好长…继续跟进   

  134.         ret = __spi_async(spi, message);  

  135.     spin_unlock_irqrestore(&master->bus_lock_spinlock, flags);  

  136.     return ret;  

  137. }  

  138. //__spi_async函数   

  139. static int __spi_async(struct spi_device *spi, struct spi_message *message)  

  140. {  

  141.     struct spi_master *master = spi->master;  

  142.     /* Half-duplex links include original MicroWire, and ones with 

  143.      * only one data pin like SPI_3WIRE (switches direction) or where 

  144.      * either MOSI or MISO is missing.  They can also be caused by 

  145.      * software limitations. 

  146.      */  

  147.     if ((master->flags & SPI_MASTER_HALF_DUPLEX)  

  148.             || (spi->mode & SPI_3WIRE)) {  

  149.         struct spi_transfer *xfer;  

  150.         unsigned flags = master->flags;  

  151.         list_for_each_entry(xfer, &message->transfers, transfer_list) {  

  152.             if (xfer->rx_buf && xfer->tx_buf)  

  153.                 return -EINVAL;  

  154.             if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf)  

  155.                 return -EINVAL;  

  156.             if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf)  

  157.                 return -EINVAL;  

  158.         }  

  159.     }  

  160.     message->spi = spi;  

  161.     message->status = -EINPROGRESS;  

  162.       

  163.     //最后调用master->transfer具体的平台相关的结构   

  164.     return master->transfer(spi, message);  

  165. }  


      read函数就分析到此,至于write函数就不具体分析了,流程是相似的!


四、总结


     根据前面的积累,这次简要分析了下spi设备驱动的模型,由于和i2c很相似,就不给出具体框图了,后面有时间会结合具体平台分析一下spi的实例,这次就到这里了 @^.^@

赞(0) 打赏
转载请注明出处:服务器评测 » Linux设备模型之spi子系统
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏