高通msm8909对gpio的使用@TOC
pmx_i2c_5 { //该名称可以随便起,无实际作用
i2c_5_active: i2c_5_active { //i2c_5_active是该子节点的别名,被别处引用是会用到
mux {
pins = "gpio19", "gpio18";
function = "blsp_i2c5"; //定义上面两个引脚的复用功能
};
config { //对pin脚的基本特性设置,如:输出电流,上拉/下拉/无上下拉
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 */
};
};
};
&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** { //这是对msm8909-pinctrl.dtsi节点的引用
cup_gpios { //加入自己要用的节点
cup_led_gpios: cup_led_gpios { //cup_led_gpios该别名会被其他节点引用到
mux {
pins = "gpio20", "gpio21", "gpio22";
function = "gpio";
};
config {
pins = "gpio20", "gpio21", "gpio22";
drive-strength = <2>; /* 2 MA */
bias-pull-down; /* PULL DOWN */
};
};
};
};
2.2 对2.1中自定义节点的引用
我们还是在msm8909-mtp.dtsi中定义要和platform_driver驱动匹配的节点,如下:
cup-leds {
compatible = "cup-leds";
pinctrl-names = "jeejio_cup_led_gpios"; //该名称在驱动程序中pinctrl_lookup_state函数会使用
pinctrl-0 = <&cup_led_gpios>; //引用2.1中定义的节点,pinctrl-0对应上面的第一个pinctrl-names,pinctrl-names可以由多个字符串组成,用逗号分割开。
gpios = <&msm_gpio 22 0x1>, /* R */ //定义一个gpio序列
<&msm_gpio 21 0x1>, /* G */
<&msm_gpio 20 0x1>; /* B */
};
2.3 驱动程序中对gpio的使用
/* Get pinctrl if target uses pinctrl */
cup_pinctrl = devm_pinctrl_get(&pdev->dev); //获取pinctrl句柄
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"); //获得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); //对cup_led_gpios里的每个gpio进行设置
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); //2.2中的gpio序列定义的3个gpio,其索引为: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");
}
}
pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_release";
pinctrl-0 = <&ts_int_active &ts_reset_active>;
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
pinctrl-2 = <&ts_release>;
atmel,reset-gpio = <&msm_gpio 12 0x00>;
atmel,irq-gpio = <&msm_gpio 13 0x00>;
上面设备树中对gpio的使用,在驱动程序中的获取方法是:
/* reset, irq gpio info */
pdata->gpio_reset = of_get_named_gpio_flags(np, "atmel,reset-gpio",
0, &temp_val);
pdata->gpio_irq = of_get_named_gpio_flags(np, "atmel,irq-gpio",
0, &temp_val);