博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux设备模型之spi子系统
阅读量:4600 次
发布时间:2019-06-09

本文共 31044 字,大约阅读时间需要 103 分钟。

===============================

本文系本站原创,欢迎转载!
转载请注明出处:

===============================

      相比于前面介绍的i2c子系统,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设备的板级信息填充的结构:

     

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控制器的表述结构:

 

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总线上的设备,其表述结构为:

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设备结构更高层次的表述结构:

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,具体如下:

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核心代码的初始化分析

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 }

 

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

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

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 }

 

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

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的注册函数:

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下:

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。

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

     

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的实例,这次就到这里了 @^.^@

 

转载于:https://www.cnblogs.com/gdt-a20/archive/2011/05/22/2291983.html

你可能感兴趣的文章
_bzoj2005 [Noi2010]能量采集
查看>>
pat 团体天梯赛 L3-010. 是否完全二叉搜索树
查看>>
烟草MES系统介绍-序
查看>>
优先队列小结
查看>>
线程安全与可重入函数之间的区别与联系
查看>>
bat批处理中如何获取前一天日期
查看>>
{Nodejs} request URL 中文乱码
查看>>
异常及日志使用与项目打包
查看>>
努力,时间,坚持,自律
查看>>
真三 bug PT的凤凰
查看>>
???动态SQL
查看>>
js错误处理与调试理论和办法
查看>>
Binding.StringFormat不起作用的原理和解决
查看>>
css hack兼容写法
查看>>
CSS两列布局 一边固定 一边自适应
查看>>
Hadoop2.6.0 动态增加节点
查看>>
图论的一些概念、定理
查看>>
WebView用法
查看>>
Lecture 3: Planning by Dynamic Programming
查看>>
用flash代替图片IMG,设置动态效果链接
查看>>