13. drivers/pinctrl/core.c : pinctrl_register_map(...)
判断一下PIN_MAP_TYPE_MUX_GROUP
pinctrl_register_map(...) --> list_add_tail(&maps_node->node, &pinctrl_maps) // pinctrl_maps 是全局变量: LIST_HEAD(pinctrl_maps);
######### 到这里, create_pinctrl(...) 的 pinctrl_dt_to_map(...) 函数已运行完成. #########
14. 回调pinctrl_dt_to_map完成, 回到第4步继续运行. 还是在create_pinctrl(...)函数里.
create_pinctrl(...) --> add_setting(...)
15. drivers/pinctrl/core.c : add_setting(...)
switch (map->type) {
case PIN_MAP_TYPE_MUX_GROUP:
ret = pinmux_map_to_setting(map, setting);
break;
}
add_setting(...) --> pinmux_map_to_setting(...)
16. drivers/pinctrl/pinmux.c : pinmux_map_to_setting(...)
pinmux_map_to_setting(...) --> pmxops->get_function_groups(...)
17. pmxops->get_function_groups(...) 就是 drivers/pinctrl/pinctrl-xxxxxx.c 中 struct pinmux_ops 的 get_function_groups成员函数指针,
也就是struct pinmux_ops xxxxxx_pinmux_ops->get_function_groups = xxxxxx_get_groups;
在xxxxxx_get_groups(...)函数里:可以取到 xxxxx_groups[] = {...};的字符串数值.
ret = pinmux_func_name_to_selector(pctldev, map->data.mux.function);
// pinmux_func_name_to_selector(...) { // 函数实现
// ...
// while (selector < nfuncs) {
// const char *fname = ops->get_function_name(pctldev,
// selector); // ops->get_function_name 就是struct pinmux_ops的get_function_name 取到 i2c
// if (!strcmp(function, fname)) // function: map->data.mux.function这个就是dts的 xxx,function = "i2c";
// return selector; // fname:得到const struct xxxxxx_function xxxxxx_functions[] 第几个是i2c,
// 所以, 代码里的 function 与 group 必须是一一对应的.
// selector++;
// }
// }
// ...
setting->data.mux.func = ret;
ret = pmxops->get_function_groups(pctldev, setting->data.mux.func,
&groups, &num_groups);
// groups 等于 fname##_groups 如:const char * const i2c_groups[] = { "i2c0_pos_0", "i2c0_pos_1", "i2c1", "i2c2"}
group = map->data.mux.group; // xxx,group = "i2c0_pos_0"; //注意: 凡是map相关的, 很可能是dts的内容
for (i = 0; i < num_groups; i++) {
if (!strcmp(group, groups[i])) {
found = true;
break;
}
}
// dts的 类似于xxx,group = "i2c0_pos_0" 与通过get_function_groups获取到代码的 const struct xxxxxx_function xxxxxx_functions[]全局变量.
// 两个作对比, 得到setting->data.mux.group;
ret = pinctrl_get_group_selector(pctldev, group);
// pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group) { // 函数实现
// ...
// while (group_selector < ngroups) {
// const char *gname = pctlops->get_group_name(pctldev,
// group_selector); // pctlops->get_group_name 就是 struct pinctrl_ops的get_group_name
// if (!strcmp(gname, pin_group)) { // pin_group: 是 xxx,group = "i2c0_pos_0";
// gname: 是 代码里的全局变量 const struct xxxxxx_group xxxxxx_groups[];
// dev_dbg(pctldev->dev,
// "found group selector %u for %s\n",
// group_selector,
// pin_group);
// return group_selector;
// }
// group_selector++;
// }
// ...