参考转载的文章:http://blog.csdn.net/tq384998430/article/details/76269786
Hi3519跑的系统没有使用设备树传递配置信息,所以按照“古老”的方式进行板级的初始化,也就是“Machine Driver”方式,就是在linux系统启动的时候建立pinctrl_map表,pinctrl_map其实就是一个映射consumer driver到pinctrl driver的一个结构体。consumer driver就是系统中使用pinctrl driver提供服务的驱动,例如SDIO driver、IIC driver、LED driver等等都算是consumer driver。pinctrl_map结构体的定义如下:
struct pinctrl_map {const char *dev_name;---使用这个映射条目(mapping entry)的设备名const char *name;---本mapping entry的名称enum pinctrl_map_type type;---本mapping entry的映射类型const char *ctrl_dev_name;---对应的pin controller设备名union {struct pinctrl_map_mux mux;struct pinctrl_map_configs configs;} data;
};
如果结构体中的type为PIN_MAP_TYPE_MUX_GROUP则联合体data表示的是mux,如果是PIN_MAP_TYPE_CONFIGS*则data表示的是configs。先说一下struct pinctrl_map_mux类型:
struct pinctrl_map_mux {const char *group;---对应的group名称const char *function;---对应的function名称
};
这里假设建立一个pinctrl_map对象:
struct pinctrl_map map =
{.dev_name = "spi0",.name = PINCTRL_STATE_DEFAULT,.type = PIN_MAP_TYPE_MUX_GROUP,.ctrl_dev_name = "pinctrl-Hi3519",.data.mux ={.group = "spi0_group",.function = "spi0",}
}
创建的map映射条目将spi0设备和pinctrl-Hi3519对应上,同时map type为PIN_MAP_TYPE_MUX_GROUP表示是进行引脚复用映射,映射的引脚组名为spi0_group,功能名为spi0。整个结构体对象的意思就是:“spi0”驱动使用pin controller “pinctrl-Hi3519”提供的服务,并且对应“pinctrl-Hi3519”中的组名为“spi0_group”的组以及功能名为“spi0”的功能。
上面只是建立了一个map,一个系统一般有很多设备使用pin controller提供服务,所以需要建立一个大的map表,一般是建立一个pinctrl_map数组,参考linux源码中U300机器的map表:
static struct pinctrl_map __initdata u300_pinmux_map[] = {/* anonymous maps for chip power and EMIFs */PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),/* per-device maps for MMC/SD, SPI and UART */PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),/* This pin is used for clock return rather than GPIO */PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11", pin_pullup_conf),/* This pin is used for card detect */PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS", pin_highz_conf),
};
我们单看其中的一条mapping entry:
PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
其中的PIN_MAP_MUX_GROUP_DEFAULT是一个宏,在文件/include/linux/pinctrl/machine.h文件中定义:
#define PIN_MAP_MUX_GROUP_DEFAULT(dev, pinctrl, grp, func) \PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, func)
PIN_MAP_MUX_GROUP的定义如下:
#define PIN_MAP_MUX_GROUP(dev, state, pinctrl, grp, func) \
{ \
.dev_name = dev, \
.name = state, \
.type = PIN_MAP_TYPE_MUX_GROUP, \
.ctrl_dev_name = pinctrl, \
.data.mux = { \
.group = grp, \
.function = func, \
}, \
}
那么这条mapping entry的含义就是pinctrl-u300为设备mmci驱动提供服务,并且mmci驱动使用pinctrl-u300中的名称为“mmc0”功能,group为NULL表示选择pinctrl-u300中拥有名称为“mmc0”功能的groups中的第一个group(因为一个功能可能对应多个group,例如某SOC的SPI0功能可以映射到引脚PA0、1、2、3也可以映射到引脚PB5、6、7、8,所以一个function可以有多个group)。
建立完一个pinctrl_map数组之后需要将这个pinctrl_map数组注册到pinctrl sub system中去,由pinctrl子系统来管理:
pinctrl_register_mappings(u300_pinmux_map, ARRAY_SIZE(u300_pinmux_map));
其实mapping table是在pinctrl驱动写完之后根据pinctrl驱动中的group和function来创建的,这里首先说mapping table是为了说明其他驱动如何pinctrl驱动挂钩的,知道如何挂钩才能编写新的pinctrl驱动。但是目前为止只是知道了在pinctrl sub system中注册了consumer driver和pinctrl driver之间的联系,而consumer driver如果使用pinctrl sub system提供的接口也需要说明清楚。