The use of gpio by Qualcomm msm8909 (including the function setting of pinctrl, the reference of gpio in the node, and the method of obtaining gpio by the driver)

The use of gpio by Qualcomm msm8909@ TOC

  1. 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 */
				};
			};
		};
  1. 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");
		}
	}


Added by fitzsic on Sun, 17 Nov 2019 21:49:21 +0200