Linux下SPI总线驱动

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Linux下SPI总线驱动有通用接口,一般的SPI设备驱动使用这个驱动接口实现设备驱动。分析驱动最好是先了解核心代码,然后从具体设备分析入手,然后从下至上,了解整个框架,再从上到下分析,理解透彻。以下分析内核根目录均以src代替。内核代码,版本2.6.37.2。SPI的核心代码即src/drivers/spi/spi.c——SPI初始化和核心代码src/drivers/spi/spi_gpio.c——IO模拟SPI接口代码头文件:src/include/linux/spi/spi.hsrc/include/linux/spi/spi_gpio.hsrc/include/linux/spi/spi_bitbang.h首先,先看核心代码。一步步来,先分析代码,然后看了具体驱动再回过头来看这个核心代码。spi.c--------------------------------------------------------------------------------/*这个函数是驱动模块卸载时使用*/32staticvoidspidev_release(structdevice*dev)33{/*标准设备结构体转换成SPI设备结构体*调用container_of函数获取dev设备所在的SPI设备结构体指针*/34structspi_device*spi=to_spi_device(dev);3536/*spimastersmaycleanupforreleaseddevices*//*清空SPI主机申请的内存*/37if(spi-master-cleanup)38spi-master-cleanup(spi);39/*减调用次数*/40spi_master_put(spi-master);/*释放SPI设备节点内存*/41kfree(spi);42}43/*打印模块别名*/44staticssize_t45modalias_show(structdevice*dev,structdevice_attribute*a,char*buf)46{47conststructspi_device*spi=to_spi_device(dev);4849returnsprintf(buf,%s\n,spi-modalias);50}51/*设置SPI总线属性——名称/显示*/52staticstructdevice_attributespi_dev_attrs[]={53__ATTR_RO(modalias),54__ATTR_NULL,55};56/*获取设备ID*/57/*modaliassupportmakesmodprobe$MODALIASnew-stylehotplugwork,58*andthesysfsversionmakescoldplugworktoo.59*/6061staticconststructspi_device_id*spi_match_id(conststructspi_device_id*id,62conststructspi_device*sdev)63{/*判断设备中名称与模块别名相同,则返回该设备ID*/64while(id-name[0]){65if(!strcmp(sdev-modalias,id-name))66returnid;67id++;68}69returnNULL;70}71/*返回设备ID*/72conststructspi_device_id*spi_get_device_id(conststructspi_device*sdev)73{74conststructspi_driver*sdrv=to_spi_driver(sdev-dev.driver);7576returnspi_match_id(sdrv-id_table,sdev);77}78EXPORT_SYMBOL_GPL(spi_get_device_id);接上一个继续看spi.c。-------------------------------匹配设备/*名词解释of:OpenFirmware*调用层次spi_match_device--of_driver_match_device--of_match_device--*of_match_node*用于驱动程序检查platform_device是否在其支持列表里*/80staticintspi_match_device(structdevice*dev,structdevice_driver*drv)81{82conststructspi_device*spi=to_spi_device(dev);83conststructspi_driver*sdrv=to_spi_driver(drv);8485/*AttemptanOFstylematch*//*不匹配返回0;匹配返回非0,指向structof_device_id类型的指针*dev:需要查找的设备;drv:驱动程序结构体*/86if(of_driver_match_device(dev,drv))87return1;88/*在驱动查找设备ID,找到返回真,否则假*/89if(sdrv-id_table)90return!!spi_match_id(sdrv-id_table,spi);91/*比较设备别名和驱动名称,匹配返回真*/92returnstrcmp(spi-modalias,drv-name)==0;93}94-------------------------------uevent/*structkobj_uevent_env是内核用户空间的一个环境参数*uevent是sysfs向用户空间发出的消息,这里实际上添加的是一串字符串消息。*关于uevent参考:*/95staticintspi_uevent(structdevice*dev,structkobj_uevent_env*env)96{97conststructspi_device*spi=to_spi_device(dev);9899add_uevent_var(env,MODALIAS=%s%s,SPI_MODULE_PREFIX,spi-modalias);100return0;101}-------------------------------电源管理/*配置了电源管理*现在不清楚suspend和resume函数哪里实现,等找到了再说*/103#ifdefCONFIG_PM104/*挂起*/105staticintspi_suspend(structdevice*dev,pm_message_tmessage)106{107intvalue=0;108structspi_driver*drv=to_spi_driver(dev-driver);109110/*suspendwillstopirqsanddma;nomorei/o*//*挂起将定制终端和DMA,没有输入输出*/111if(drv){/*驱动实现了挂起操作函数*/112if(drv-suspend)113value=drv-suspend(to_spi_device(dev),message);114else115dev_dbg(dev,...can'tsuspend\n);116}117returnvalue;118}119/*恢复*/120staticintspi_resume(structdevice*dev)121{122intvalue=0;123structspi_driver*drv=to_spi_driver(dev-driver);124125/*resumemayrestartthei/oqueue*//*重新开始输入输出队列*/126if(drv){127if(drv-resume)128value=drv-resume(to_spi_device(dev));129else130dev_dbg(dev,...can'tresume\n);131}132returnvalue;133}134135#else/*没有电源管理*/136#definespi_suspendNULL137#definespi_resumeNULL138#endif-------------------------------总线/*总线参考:*/140structbus_typespi_bus_type={141.name=spi,142.dev_attrs=spi_dev_attrs,143.match=spi_match_device,144.uevent=spi_uevent,145.suspend=spi_suspend,146.resume=spi_resume,147};148EXPORT_SYMBOL_GPL(spi_bus_type);-------------------------------驱动注册、删除/*驱动注册*/151staticintspi_drv_probe(structdevice*dev)152{153conststructspi_driver*sdrv=to_spi_driver(dev-driver);154155returnsdrv-probe(to_spi_device(dev));156}157/*驱动删除*/158staticintspi_drv_remove(structdevice*dev)159{160conststructspi_driver*sdrv=to_spi_driver(dev-driver);161162returnsdrv-remove(to_spi_device(dev));163}164/*关闭*/165staticvoidspi_drv_shutdown(structdevice*dev)166{167conststructspi_driver*sdrv=to_spi_driver(dev-driver);168169sdrv-shutdown(to_spi_device(dev));170}-------------------------------注册SPI总线驱动/*注册SPI驱动*/172/**173*spi_register_driver-registeraSPIdriver174*@sdrv:thedrivertoregister175*Context:cansleep176*/177intspi_register_driver(structspi_driver*sdrv)178{/*初始化总线结构体*/179sdrv-driver.bus=&spi_bus_type;/*初始化驱动相关函数*/180if(sdrv-probe)181sdrv-driver.probe=spi_drv_probe;182if(sdrv-remove)183sdrv-driver.remove=spi_drv_remove;184if(sdrv-shutdown)185sdrv-driver.shutdown=spi_drv_shutdown;/*驱动注册*添加驱动到总线*sysfs、uevent等创建、初始化*/186returndriver_register(&sdrv-driver);187}188EXPORT_SYMBOL_GPL(spi_register_driver);接下去看spi.c特殊

1 / 28
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功