The use of gpio by Qualcomm msm8909@ TOC
- Many nodes are defined in the file msm8909-pinctrl.dtsi to set the function of pin combination, for example:
pmx_i2c_5 { //The name can be used casually without practical effect i2c_5_active: i2c_5_active { //I2C ﹣ 5 ﹣ active is the alias of this child node, which will be used when it is referenced elsewhere mux { pins = "gpio19", "gpio18"; function = "blsp_i2c5"; //Define the reuse function of the above two pins }; config { //Set the basic characteristics of pin pin pin, such as output current, pull-up / pull-down / no pull-up pins = "gpio19", "gpio18"; drive-strength = <2>; /* 2 MA */ bias-disable; /* No PULL */ }; }; i2c_5_sleep: i2c_5_sleep { mux { pins = "gpio19", "gpio18"; function = "blsp_i2c5"; }; config { pins = "gpio19", "gpio18"; drive-strength = <2>; /* 2 MA */ bias-disable; /* No PULL */ }; }; };
- If we want to use gpio20, gpio21, gpio22 as general GPIO output.
2.1 first of all, we need to set its multiplexing function in our project dtsi (msm8909-pinctrl.dtsi as a public file, try not to modify it), such as the following definition in msm8909-mtp.dtsi:
Node framework of msm8909-pinctrl.dtsi:
&soc { **msm_gpio**: pinctrl@1000000 { compatible = "qcom,msm8909-pinctrl"; reg = <0x1000000 0x300000>; interrupts = <0 208 0>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; ........ tlmm_gpio_key { gpio_key_active: gpio_key_active { mux { pins = "gpio90", "gpio91", "gpio92", "gpio22"; function = "gpio"; }; config { pins = "gpio90", "gpio91", "gpio92", "gpio22"; drive-strength = <2>; bias-pull-up; }; }; }; ...... }; };
&**msm_gpio** { //This is a reference to the msm8909-pinctrl.dtsi node cup_gpios { //Join the node you want to use cup_led_gpios: cup_led_gpios { //The alias will be referenced by other nodes to mux { pins = "gpio20", "gpio21", "gpio22"; function = "gpio"; }; config { pins = "gpio20", "gpio21", "gpio22"; drive-strength = <2>; /* 2 MA */ bias-pull-down; /* PULL DOWN */ }; }; }; };
2.2 reference to user-defined nodes in 2.1
We also define the nodes in msm8909-mtp.dtsi to match the platform driver driver, as follows:
cup-leds { compatible = "cup-leds"; pinctrl-names = "jeejio_cup_led_gpios"; //This name is used by the pinctrl? Lookup? State function in the driver pinctrl-0 = <&cup_led_gpios>; //By referring to the nodes defined in 2.1, pinctrl-0 corresponds to the first pinctrl names above. Pinctrl names can be composed of multiple strings, separated by commas. gpios = <&msm_gpio 22 0x1>, /* R */ //Define a gpio sequence <&msm_gpio 21 0x1>, /* G */ <&msm_gpio 20 0x1>; /* B */ };
2.3 use of gpio in drivers
/* Get pinctrl if target uses pinctrl */ cup_pinctrl = devm_pinctrl_get(&pdev->dev); //Get the pinctrl handle if (IS_ERR(cup_pinctrl)) { if (PTR_ERR(cup_pinctrl) == -EPROBE_DEFER) return -EPROBE_DEFER; pr_debug("Jeejio cup does not use pinctrl\n"); cup_pinctrl = NULL; } set_state = pinctrl_lookup_state(cup_pinctrl, "jeejio_cup_led_gpios"); //Get cup led gpios if (IS_ERR(set_state)) { pr_err( "cannot get jeejio cup pinctrl active state\n"); return PTR_ERR(set_state); } ret = pinctrl_select_state(cup_pinctrl, set_state); //Set each gpio in cup led gpios if (ret) { pr_err( "cannot set jeejio cup pinctrl active state\n"); return ret; } for(i = 0; i < GPIO_NUM; i++) { cup_gpio[i] = of_get_gpio(pdev->dev.of_node, i); //3 gpios defined by gpio sequence in 2.2, with index: 0, 1, 2 ret = gpio_request(cup_gpio[i], "rgb_gpio"); if(ret) { pr_err("request gpio err!\n"); } else { pr_err("request gpio success!\n"); } ret = gpio_direction_output(cup_gpio[i], 1); if(ret) { pr_err("set gpio direction err!\n"); } else { pr_err("set gpio direction success!\n"); } }