Linux下如何使用X86 CPU的GPIO( 二 )
先阅读源码看看 , probe()执行过程中需要用到device的哪些resource , 只要我们能获取到这些resource , 自己手动构造一个device注册到platform bus不就行了 , O(∩_∩)O哈哈~ 。
int intel_pinctrl_probe(struct platform_device *pdev,const struct intel_pinctrl_soc_data *soc_data){......for (i = 0; i < pctrl->ncommunities; i++) {......res = platform_get_resource(pdev, IORESOURCE_MEM,community->barno);//0regs = devm_ioremap_resource(...... } ...... irq = platform_get_irq(pdev, 0);......}
可以看到pin controller driver需要pincontrler 的地址空间和使用的中断号两部分资源 , 其中地址空间是三个 , 因为所有GPIO由三个GPIO控制器组成 , 三个GPIO控制器共享相同的中断线 , 三个GPIO控制器作为一个PCI设备 。 如何获取这两个信息呢?
4.手动构造device上面通过阅读源代码得知 ,intel-pinctrl 需要 pincontrler 地址空间、和使用的中断号两部分资源 。
地址空间起始地址可通过PCI 设备 P2SB Bridge (D31:F1) 获得 。 中断 vector 由 BIOS 配置 , 反编译 BIOS 给linux传递的 ACPI 信息 , 看是否有中断vector相关信息:
在板子上进入 /sys/firmware/acpi/tables, 将目录下所有文件考出 , 使用acpi工具 iasl 对DSDT文件进行反编译:
iasl -d DSDT.dat
得到 AML 文件 DSDT.dsl ,里面包含 BIOS 开发的各设备节点信息 。
打开 DSDT.dsl 并找到pin controler设备节点描述 , 只需要搜索驱动里的"INT344B"或"INT345D"就能定位到 。 到这里我们也明白了 , 为什么驱动里的 spt_pinctrl_acpi_match[] 有两像 , 原来是一个代表标压处理器(H),一个代表低压处理器(U) 。
Device (GPI0){Method (_HID, 0, NotSerialized)// _HID: Hardware ID{If ((PCHV () == SPTH)){If ((PCHG == 0x02)){Return ("INT3451")}Return ("INT345D")//表示7代标压处理器}Return ("INT344B")//表示7代低压处理器Name (LINK, "\\_SB.PCI0.GPI0")Method (_CRS, 0, NotSerialized)// _CRS: Current Resource Settings{Name (RBUF, ResourceTemplate (){Memory32Fixed (ReadWrite,0x00000000,// Address Base0x00010000,// Address Length地址空间大小_Y2E)Memory32Fixed (ReadWrite,0x00000000,// Address Base0x00010000,// Address Length地址空间大小_Y2F)Memory32Fixed (ReadWrite,0x00000000,// Address Base0x00010000,// Address Length地址空间大小_Y31)Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, _Y30){0x0000000E,//中断号}})CreateDWordField (RBUF, \_SB.PCI0.GPI0._CRS._Y2E._BAS, COM0)// _BAS: Base AddressCreateDWordField (RBUF, \_SB.PCI0.GPI0._CRS._Y2F._BAS, COM1)// _BAS: Base AddressCreateDWordField (RBUF, \_SB.PCI0.GPI0._CRS._Y30._INT, IRQN)// _INT: InterruptsCOM0 = (SBRG + 0x00AF0000)COM1 = (SBRG + 0x00AE0000)CreateDWordField (RBUF, \_SB.PCI0.GPI0._CRS._Y31._BAS, COM3)// _BAS: Base AddressCOM3 = (SBRG + 0x00AC0000)IRQN = SGIR /* \SGIR */Return (RBUF) /* \_SB_.PCI0.GPI0._CRS.RBUF */}
你可能看不懂上面面的信息 , 到底哪个是标压哪个是低压?没关系 , 我们去pin controller driver中 , 里面有注释 , 反推一下就知道 INT345D 代表的是标压 ,INT344B 代表的是低压 。
/* Sunrisepoint-LP */static const struct pinctrl_pin_desc sptlp_pins[] = {....}static const struct intel_pinctrl_soc_data sptlp_soc_data = http://kandian.youth.cn/index/{ .pins = sptlp_pins,...}...../* Sunrisepoint-H */static const struct pinctrl_pin_desc spth_pins[] = {....}static const struct intel_pinctrl_soc_data spth_soc_data = { .pins = spth_pins,...}static const struct acpi_device_id spt_pinctrl_acpi_match[] = { {"INT344B", (kernel_ulong_t)
回到正题 , 我们从 DSDT.dsl 获取得到中断号: 0xE , 三个地址空间起始地址及大小 。 构建一个platform_device 如下:
#include
- 推新标准建新生态,下载超198亿次金山发力海内外
- 闲鱼|电诉宝:“闲鱼”网络欺诈成用户投诉热点 Q3获“不建议下单”评级
- 王兴称美团优选目前重点是建设核心能力;苏宁旗下云网万店融资60亿元;阿里小米拟增资居然之家|8点1氪 | 美团
- 页面|如何简单、快速制作流程图?上班族的画图技巧get
- 培育|跨境电商人才如何培育,长沙有“谱”了
- 先别|用了周冬雨的照片,我会成为下一个被告?自媒体创作者先别自乱阵脚
- 丹丹|福佑卡车创始人兼CEO单丹丹:数字领航 驶向下一个十年
- 抖音小店|抖音进军电商,短视频的商业模式与变现,创业者该如何抓住机遇?
- 看过明年的iPhone之后,现在下手的都哭了
- 计费|5G是如何计费的?