基于Linux 3.10.49内核的pinctrl流程分析(2)

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++;
    // }
    // ...

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7ba6319fb11879e189706f1d0eff5d9e.html