本文主要是介绍linux 驱动开发 知识点,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在dev目录下看有没有对应的设别文件 有框架
cat /proc/devices 设备号
pinctrl子系统 imx6ull.dtsi
1.1 IOMUX SNVS控制器
iomuxc_snvs: iomuxc-snvs@02290000 {
compatible = "fsl,imx6ull-iomuxc-snvs";
reg = <0x02290000 0x10000>;
};
1.2 IOMUX 控制器
iomuxc: iomuxc@020e0000 {
compatible = "fsl,imx6ul-iomuxc";
reg = <0x020e0000 0x4000>;
};
1.3 gpr控制器
gpr: iomuxc-gpr@020e4000 {
compatible = "fsl,imx6ul-iomuxc-gpr",
"fsl,imx6q-iomuxc-gpr", "syscon";
reg = <0x020e4000 0x4000>;
};
imx6ull-alientek-emmc.dts
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
>;
};
pinctrl_csi1: csi1grp {
fsl,pins = <
MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
>;
};
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10b0
>;
};
};
根据设备的类型,创建对应的子节点,然后设备所用ping都用在此节点
1.4 如何添加一个PIN 的信息 以hoggrp -1 为例
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
>;
};
打开imx6ull-pinfunc.h 找到MX6UL_PAD_UART1_RTS_B
打开imx6ull参考手册 找到
SW_MUX_CTL_PAD_UART1_RTS_B SW MUX Control Register 找到寄存器复用
#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031C 0x0000 0x5 0x0
<mux_reg conf_reg input_reg mux_mode input_val>
0x0090 0x031C 0x0000 0x5 0x0
mux_reg 0x020e0000
IOMUXC 父节点首地址 0x020e0000 + 0x0090 因此UART1_RTS_B 这个PIN的mux寄存器地址 就是0x020e0000 + 0x0090 = 0x020e0090 就是MX6UL_PAD_UART1_RTS_B 的复用地址
mux_mode = 5 复用为__GPIO1_IO09
管脚配置寄存器为 SW_PAD_CTL_PAD_UART1_RTS_B SW PAD Control Register
conf_reg 0x020e0000 + 0x031c
0x17059 为管脚的电气属性值
input_reg 偏移为0 表示MX6UL_PAD_UART1_RTS_B没有这个属性
input_val 写给input 寄存器的值
1.5 pinctrl驱动 (各个厂家写的不一样)
如何找到IMX6U对应的pinctrl子系统驱动,设备树里面的设备结点是如何根据驱动匹配的呢 ? 通过compatible属性,此属性是一段字符串列表。驱动文件里面有一个描述驱动兼容性的东西,当设备树系结点的compatible属性和驱动里面的兼容性字符匹配,也就是一模一样的时候就表示设备和驱动匹配了。
所以我们只需要全局搜索,设备节点里面的compatible属性的值,看看在哪个.c文件里面有,那么此.c文件就是驱动文件。
找到pinctrl-imx6ull.c文件,那么此文件按就是6ul/6ull的pinctrl驱动文件
当驱动和设备匹配以后执行probe 函数。
imx6ul_pinctrl_probe
->imx_pinctrl_probe
->此函数会初始化 pinctrl_desc类型的结构体
最后通过 pinctrl_register函数向系统注册一个imx_pinctrl_desc
->imx_pinctrl_probe_dt
->imx_pinctrl_parse_functions
->imx_pinctrl_parse_groups
//配置config 寄存器
imx_pinctrl_probe
->imx_pinconf_ops
->imx_pinconf_set
->
for (i = 0; i < num_configs; i++) {
if (info->flags & SHARE_MUX_CONF_REG) {
u32 reg;
reg = readl(ipctl->base + pin_reg->conf_reg);
reg &= ~0xffff;
reg |= configs[i];
writel(reg, ipctl->base + pin_reg->conf_reg);
} else {
writel(configs[i], ipctl->base + pin_reg->conf_reg);
}
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
pin_reg->conf_reg, configs[i]);
} /* for each config */
imx_pinconf_ops 设置电器属性
imx_pmx_ops 设置复用属性
这篇关于linux 驱动开发 知识点的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!