1.首先了解平台下可用的pinctrl节点
pio: pinctrl@1000b000 { //别名 pio
compatible = "mediatek,mt6761-pinctrl";
reg = <0 0x1000b000 0 0x1000>;
mediatek,pctl-regmap = <&syscfg_pctl_0>,
<&syscfg_pctl_1>,
<&syscfg_pctl_2>,
<&syscfg_pctl_3>,
<&syscfg_pctl_4>,
<&syscfg_pctl_5>,
<&syscfg_pctl_6>,
<&syscfg_pctl_7>;
pins-are-numbered;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <4>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
};
2.在dts中添加自己的pinctrl节点
2.1建一个设备节点
key_cust0: key_cust0{
compatible = "sprd,key_cust0";
status = "disabled";
};
2.2对设备节点进行补充,并使其可以用
&key_cust0 {
status = "okay";
pinctrl-names =
"key_cust0", "key_cust1";
pinctrl-0 = <&key_cust0_0>;
pinctrl-1 = <&key_cust0_1>;
};
2.3对其中的pinctrl 进行补充
&pio { /*在对应的pinctrl节点下增加gpio内容*/
key_cust0_0: reg2-keycust-0 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO174__FUNC_GPIO174>; /
slew-rate = <1>;
output-low; //输出低
};
};
key_cust0_pull_up_1: reg2-keycust-1 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO174__FUNC_GPIO174>;
slew-rate = <1>;
output-high; //输出高
};
};
};
3.在kernel中获取到对应的pinctrl节点
static struct pinctrl *pctrl_kcust0;
static struct pinctrl_state *pstate_kcust0;
static struct pinctrl_state *pstate_kcust1;
static int key_cust0_pinctrl_init(void)
{
struct platform_device *pdev = NULL;
struct device_node *np = NULL;
3.1获取dts中的device_node
np = of_find_compatible_node(NULL, NULL, "sprd,key_cust0");
if (!np) {
pr_err("*** Error: func:%s can`t find device node!\n",__func__);
return -ENODEV;
}
3.2通过device_node 获取platform_device
pdev = of_find_device_by_node(np);
if (!pdev) {
pr_err("*** Error: func:%s can`t find platform device!\n",__func__);
return -ENODEV;
} else {
3.3通过 device 获取 pinctrl句柄
pctrl_kcust0 = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(pctrl_kcust0)) {
pr_err("*** Error: func:%s devm_pinctrl_get failed!\n",__func__);
return PTR_ERR(pctrl_kcust0);
} else {
pstate_kcust0 = pinctrl_lookup_state(pctrl_kcust0, "key_cust0"); //查找pinctrl句柄下的pinctrl节点获取控制句柄
if (IS_ERR(pstate_kcust0)) {
pr_err("*** Error: func:%s pinctrl_lookup_state \
pstate_kcust0 failed!\n",__func__);
return PTR_ERR(pstate_kcust0);
}
pstate_kcust1 = pinctrl_lookup_state(pctrl_kcust0, "key_cust1");
if (IS_ERR(pstate_kcust1)) {
pr_err("*** Error: func:%s pinctrl_lookup_state \
pstate_kcust1 failed!\n",__func__);
return PTR_ERR(pstate_kcust1);
}
}
}
return 0;
}
4.对GPIO口进行操作
pinctrl_select_state(pctrl_kcust0, pctrl_kcust0);
pinctrl_select_state(pctrl_kcust0, pctrl_kcust1);
5.对于pinctrl节点下的都有配置,可以参考:
kernel-4.9/drivers/pinctrl/pinconf-generic.c
static const struct pinconf_generic_params dt_params[] = {
{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
{ "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
};
```