/sys/kernel/debug/pinctrl
其他驱动调用pinctrl子系统:
#include <linux/pinctrl/consumer.h>
static struct pinctrl *xxx_pinctrl;
struct pinctrl_state *default_state = NULL;
// dts
pinctrl-0 = <&state1>
pinctrl-1 = <&state2>
1. /* 获取pin control state holder 的句柄 */
pinctrl = devm_pinctrl_get(dev);
2. /* 得到名字为state1和state2对应的pin state */
**struct** pinctrl_state * turnon_tes = pinctrl_lookup_state(pinctrl, "state1");
**struct** pinctrl_state * turnoff_tes = pinctrl_lookup_state(pinctrl, "state2");
3. pinctrl_select_state(pinctrl, turnon_tes)。
devm_pinctrl_get(struct device *dev) //返回一个pinctrl句柄
pinctrl_get(struct device *dev)
find_pinctrl(struct device *dev) // 查看是否device core已经创建了该pinctrl句柄
create_pinctrl(struct device *dev, struct pinctrl_dev *pctldev)
pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev) //从设备树中获取信息保存到pinctrl_map结构体中
for (state = 0; ; state++) {
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); //查找pinctrl-0,1,2属性
//size保存了pinctrl-0中phandle的个数,比如有的节点pinctrl-0 = <&x1, &x2>
prop = of_find_property(np, propname, &size);
list = prop->value; //list保存了phandle列表
//保存pinctrl-names index为state的name,比如pinctrl-names = "default"
ret = of_property_read_string_index(np, "pinctrl-names", state, &statename);
if (ret < 0)
// 如果没有定义pinctrl-names属性,那么我们将pinctrl-0 pinctrl-1 pinctrl-2……中的那个ID取出来作为state name
statename = prop->name + strlen("pinctrl-");
for (config = 0; config < size; config++) {
phandle = be32_to_cpup(list++);
np_config = of_find_node_by_phandle(phandle); // 找到pinctrl-x=<&x1, &x2>中的config节点
dt_to_map_one_config(p, pctldev, statename, np_config);
np_pctldev = of_node_get(np_config);
np_pctldev = of_get_next_parent(np_pctldev); // 找到pinctrl controller节点
pctldev = get_pinctrl_dev_from_of_node(np_pctldev); //找到pinctrl_dev
//调用底层的callback函数处理pin configuration node。
ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);
.dt_node_to_map = pinconf_generic_dt_node_to_map_all //rts pinctrl 用的框架通用函数
pinconf_generic_dt_node_to_map()
ret = pinconf_generic_dt_subnode_to_map();
for_each_available_child_of_node(np_config, np)
//rts pinctrl每一个config节点下都有子节点 逐个分析子节点
ret = pinconf_generic_dt_subnode_to_map();
pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
//将该pin configuration node的mapping entry信息注册到系统中
dt_remember_or_free_map(p, statename, pctldev, map, num_maps);
}
}
add_setting(p, pctldev, map); // 将pinctrl_map信息传递给pinctrl_mapping, 把这个setting的代码加入到holder中
setting->type = map->type;
setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
setting->dev_name = map->dev_name;
pinmux_map_to_setting(map, setting);
pinconf_map_to_setting(map, setting);
pinctrl_lookup_state(struct pinctrl *p, const char *name)
find_state(p, name);
pinctrl_select_state()
pinctrl_commit_state(p, state);
case PIN_MAP_TYPE_MUX_GROUP:
pinmux_enable_setting(setting);
ops->set_mux(pctldev, setting->data.mux.func, setting->data.mux.group);
case PIN_MAP_TYPE_CONFIGS_PIN:
case PIN_MAP_TYPE_CONFIGS_GROUP:
pinconf_apply_setting(setting);
switch (setting->type)
ops->pin_config_set()
ops->pin_config_group_set()
统一驱动设备模型会处理pin control:
platform_driver_register()
driver_register();
bus_add_driver();
driver_attach();
__driver_attach();
device_driver_attach(drv, dev);
driver_probe_device(drv, dev);
really_probe(dev, drv);
really_probe(struct device *dev, struct device_driver *drv)
pinctrl_bind_pins(dev);
devm_pinctrl_get(dev);
pinctrl_lookup_state(dev->pins->p, PINCTRL_STATE_DEFAULT);
pinctrl_lookup_state(dev->pins->p, PINCTRL_STATE_INIT);
pinctrl_select_state(dev->pins->p, dev->pins->default_state);