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!