An example of Linux pinctrl driver

Since it's an instance, we only care about the use of API, and the specific implementation in API will not be described in detail.

For example: GPIO5 is configured as the reset pin in the dts file, which will be called in the driver. Now it is described separately from the dts file to the driver file.

1, dts file

/ {
	model = "CPU";
	compatible = "Vendor,CPU";
	interrupt-parent = <&gic>;
	#address-cells = <2>;
	#size-cells = <2>;
	chosen {
		bootargs = "console=tty0 console=ttyMT0,921600n1 root=/dev/ram initrd=0x84000000,0x400000 loglevel=8";
	};
	/*cpu{};pmu{};Wait here*/
	bus {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges = <0 0 0 0xffffffff>;
		/*i2c,spi Wait for bus related information to be added here*/
		pio: pinctrl@0x10005000 {
			compatible = "mediatek,mt6580-pinctrl";
			reg = <0x10005000 0x1000>;
			mediatek,pctl-regmap = <&syscfg_pctl_a>;
			pins-are-numbered;
			gpio-controller;
			#gpio-cells = <2>;
		};
	};
	gpio_rst: gpio_rst {
		compatible = "mediatek,gpio_rst";/*It can also be placed outside under the & GPIO first node, with the same effect*/
	};
};
&pio {
	gpio_rst_enable: caotuo@0 {
	    pins_cmd_dat {
	 pins = <PINMUX_GPIO5__FUNC_GPIO5>;/*#define PINMUX_GPIO5__FUNC_GPIO5 ((5<<8) | 0),Related to specific CPU*/
	 slew-rate = <1>; /*Output direction 0:in, 1:out*/
	 output-high; /*Valid for output only, output is high level*/
	 };
	};
	gpio_rst_disable: caotuo@1 {
	    pins_cmd_dat {
			pins = <PINMUX_GPIO5__FUNC_GPIO5>;
			slew-rate = <1>;
			output-low;
		};
	};
};
&gpio_rst {
		pinctrl-names = "gpio_rst_on", "gpio_rst_off";
		pinctrl-1 = <&gpio_rst_enable>;
		pinctrl-2 = <&gpio_rst_disable>;
}

2, Driver file

/*
struct pinctrl_state { 
    struct list_head node;//Nodes linked to the chain header
    const char *name;//The name of the state
    struct list_head settings;//All settings in this state
};*/
static int xxx_probe(struct platform_device *dev)
{
	/*First apply for memory and register to create related nodes*/
	/*Go to gpio ctrl directly*/
	struct pinctrl_state *xxx_pin_ctrl,*xxx_rst_on,*xxx_rst_off;
	
	xxx_pin_ctrl = devm_pinctrl_get(&pdev->dev); /*Resource managed pinctrl_get()*/
	if (IS_ERR(xxx_pin_ctrl)) {
		printk("failed\n");
		ret = PTR_ERR(xxx_pin_ctrl);
		return ret;
	}
	
	xxx_rst_on = pinctrl_lookup_state(xxx_pin_ctrl, "gpio_rst_on");
	if (IS_ERR(xxx_rst_on)) {
		printk("failed\n");
		ret = PTR_ERR(xxx_rst_on);
		return ret;
	}
	
	xxx_rst_off = pinctrl_lookup_state(xxx_pin_ctrl, "gpio_rst_off");
	if (IS_ERR(xxx_rst_off)) {
		printk("failed\n");
		ret = PTR_ERR(xxx_rst_off);
		return ret;
	}
	
	/*The following is a direct call to gpio5, which can be individually encapsulated as a function*/
	pinctrl_select_state(xxx_pin_ctrl, xxx_rst_on);/*gpio5 Output high level*/
	delay(20);
	pinctrl_select_state(xxx_pin_ctrl, xxx_rst_off);/*gpio5 Output low level*/
	delay(20);
}
static int xxx_remove(struct platform_device *dev){
	/*************/
}
#ifdef CONFIG_OF
static const struct of_device_id xxx_gpio_of_id[] = {
	{.compatible = "mediatek,gpio_rst",},
	{}
};
#endif
static struct platform_driver caotuo_platform_driver = {
	.probe = xxx_probe,
	.remove = xxx_remove,
	.driver = {
		   .name = my_name,
		   .owner = THIS_MODULE,
	#ifdef CONFIG_OF / * add macro judgment, the lower version kernel does not have dts*/
		   .of_match_table = xxx_gpio_of_id, 	  
	#endif
	},
};
static int __init caotuo_init(void)
{
	int ret=0;
	ret = platform_driver_register(&caotuo_platform_driver);
	if (ret) {
		printk("failed\n");
		return ret;
	}
	return ret;
}
static void __exit caotuo_exit(void)
{
	platform_driver_unregister(&caotuo_platform_driver);
}
module_init(caotuo_init);
module_exit(caotuo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxxx");
MODULE_DESCRIPTION("xxxx");

3, Summary

There are three main API s to master in the driver, which are called in sequence, namely:

Devm? Pinctrl? Get(); / / when defined, devres? Alloc() will be called to dynamically request memory space

pinctrl_lookup_state();

pinctrl_select_state();

Reprint please indicate the source!

Posted by eightonesix on Sat, 02 May 2020 02:58:01 -0700