2.[Gpio]-(Pinctrl实现对一个Gpio控制)

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 },
};
```

猜你喜欢

转载自blog.csdn.net/qq_16919359/article/details/105434376