一、 前期思考:
问题
位于arch\arm\dts\imx6ull-pinfunc-snvs.h
文件
/*The pin function ID:
* <mux_reg conf_reg input_reg mux_mode input_val>
*/
#define MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x0008 0x004C 0x0000 0x5 0x0
这种宏定义用法在C语言如何使用?
想法
有没有可能是在初始化数组的时候使用,比如 :
uint32_t *Pin = {MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00}
后来想到数组初始化需要,
逗号隔开才行。
解惑
该文件位于dts
目录下,所以属于设备树使用的文件,同时设备树语法支持包含头文件用法:#include <xxx.h>
二、设备树调用头文件分析
设备树调用头文件位置:arch\arm\dts\imx6ull-colibri.dtsi
pinctrl_snvs_usdhc1_cd: snvs-usdhc1-cd-grp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0 /* CD */
>;
};
fsl,pin
结点解释
参考链接:
Required properties for pin configuration node:
- fsl,pins: each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
input_val> are specified using a PIN_FUNC_ID macro, which can be found in
imx*-pinfunc.h under device tree source folder. The last integer CONFIG is
the pad setting value like pull-up on this pin. And that's why fsl,pins entry
looks like <PIN_FUNC_ID CONFIG> in the example below.
Bits used for CONFIG:
NO_PAD_CTL(1 << 31): indicate this pin does not need config.
三、Drivers解析设备树 具体分析
Drivers解析设备树实现:drivers\pinctrl\freescale\pinctrl-imx6ul.c
static int imx6ul_pinctrl_probe(struct platform_device *pdev)
//drivers\pinctrl\freescale\pinctrl-imx.c
//1. platform_driver和device_driver根据of_match_table进行匹配,匹配成功调用probe函数
->imx_pinctrl_probe()
//2. 解析dt设备树
-> imx_pinctrl_probe_dt()
//3. 解析pinctrl 引脚功能
-> imx_pinctrl_parse_functions()
//4. 解析'fsl,pins'属性
-> imx_pinctrl_parse_groups()
//5. 读取'fsl,pins'属性
->imx_pinctrl_parse_pin_mem()
1. 解析fsl,pins
属性:
/*
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
* 1 u32 CONFIG, so 24 types in total for each pin.
*/
#define FSL_IMX8_PIN_SIZE 12
#define FSL_PIN_SIZE 24
#define SHARE_FSL_PIN_SIZE 20
static int imx_pinctrl_parse_groups(struct device_node *np,
struct imx_pin_group *grp,
struct imx_pinctrl_soc_info *info,
u32 index)
{
int size, pin_size;
const __be32 *list, **list_p;
int i;
dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
if (info->flags & IMX8_USE_SCU)
pin_size = FSL_IMX8_PIN_SIZE;
else if (info->flags & SHARE_MUX_CONF_REG)
pin_size = SHARE_FSL_PIN_SIZE;
else
pin_size = FSL_PIN_SIZE;
/* Initialise group */
grp->name = np->name;
/*
* the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>,
* do sanity check and calculate pins number
*/
list = of_get_property(np, "fsl,pins", &size);
if (!list) {
dev_err(info->dev, "no fsl,pins property in node %s\n", np->full_name);
return -EINVAL;
}
list_p = &list;
...
...
return 0;
}
为给定节点查找具有fsl,pins
的属性,并返回list
指针:list = of_get_property(np, "fsl,pins", &size);
2. 读取fsl,pins
属性:
int imx_pinctrl_parse_pin_mem(struct imx_pinctrl_soc_info *info,
unsigned int *grp_pin_id, struct imx_pin *pin,
const __be32 **list_p)
{
struct imx_pin_memmap *pin_memmap = &pin->pin_conf.pin_memmap;
u32 mux_reg = be32_to_cpu(*((*list_p)++));
u32 conf_reg;
u32 config;
unsigned int pin_id;
struct imx_pin_reg *pin_reg;
if (info->flags & SHARE_MUX_CONF_REG) {
conf_reg = mux_reg;
} else {
conf_reg = be32_to_cpu(*((*list_p)++));
if (!conf_reg)
conf_reg = -1;
}
pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4;
pin_reg = &info->pin_regs[pin_id];
pin->pin = pin_id;
*grp_pin_id = pin_id;
pin_reg->mux_reg = mux_reg;
pin_reg->conf_reg = conf_reg;
pin_memmap->input_reg = be32_to_cpu(*((*list_p)++));
pin_memmap->mux_mode = be32_to_cpu(*((*list_p)++));
pin_memmap->input_val = be32_to_cpu((*(*list_p)++));
/* SION bit is in mux register */
config = be32_to_cpu(*((*list_p)++));
if (config & IMX_PAD_SION)
pin_memmap->mux_mode |= IOMUXC_CONFIG_SION;
pin_memmap->config = config & ~IMX_PAD_SION;
dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name,
pin_memmap->mux_mode, pin_memmap->config);
return 0;
}
最后读取到 宏定义展开MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0
的结果,然后传递给下面数据中保存:
- pin_reg->mux_reg -> 0x0008
- pin_reg->conf_reg -> 0x004C
- pin_memmap->input_reg -> 0x0000
- pin_memmap->mux_mode -> 0x05
- pin_memmap->input_val -> 0x0
- pin_memmap->config -> 0x1b0b0
三、fsl,pin属性含义
上述参数根据 IMX6ULL参考手册 定义有完整定义。
MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00
引脚为复用引脚,相关定义位于 参考手册第32章节:IOMUX Controller(IOMUXC)
属性说明
- mux_reg:MUX Control Regisrter offset address(复用控制寄存器 偏移地址)
- mux_mode:MUX Control Regisrter Data (复用控制寄存器 设置值)
- conf_reg:PAD Control Regisrter offset address (引脚控制寄存器 偏移地址)
- config:PAD Control Regisrter Data (引脚控制寄存器 设置值)
- input_reg:XXX_SELECT_INPUT DAISY Register offset address (菊花链配置寄存器 偏移地址)
- input_val:XXX_SELECT_INPUT DAISY Register Data(菊花链配置寄存器 设置值)
1. mux_reg、mux_mode属性
mux_reg:复用控制寄存器 偏移地址:0x08h => 0x0008
mux_mode:前4个bit:MUX_MODE(复用模式) 默认为GPIO模式:101(Bin) => 0x5(Hex)
2. conf_reg属性
conf_reg:引脚控制寄存器 偏移地址:0x4Ch -> 0x004C
3. config属性
config:引脚控制寄存器 参数设置:0x1b0b0
0x1b0b0 (Hex)
0001 1011 0000 1011 0000 (Bin)
32b ---------- 0b
由此可知,设置引脚参数为:
-
Bit 31-17:Reserved
-
Bit 16(HYS):HYS_1_Hysteresis_Enabled
-
Bit 15-14(PUS):PUS_2_100K_Ohm_Pull_Up
-
Bit 13(PUE):PUE_1_Pull
-
Bit 12(PKE):PKE_1_Pull_Keeper_Enabled
-
Bit 11(ODE):ODE_0_Open_Drain_Disable
-
Bit 10 - 8:Reserved
-
Bit 7-6(SPEED): medium(100MHz)
-
Bit 5-3(DSE):DSE_6_R0_6
-
Bit 2-1:Reserved
-
Bit 0(SRE):SRE_0_Slow_Slew_Rate
4. input_reg,input_val属性
input_reg:菊花链配置寄存器 偏移地址,MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00
无该设置,所以设置为0x0000
。
input_val:菊花链配置寄存器 偏移地址,MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00
无该设置,所以设置为0x0
。
四、菊花链
参考
-
《IMX6ULLRM.pdf》