一、概述
控制gpio一般有二种方式,第一种是gpio的控制方式,第二种通过pinctrl配置。
二、GPIO方式
1、 DTS设备节点中添加gpio
device_node {
...
gpio_name = <&tlmm XX 0>;
...
}
2、驱动代码
文件路径:android\kernel\msm-3.18\drivers\gpio\ gpiolib.c
int gpio_XXX = of_get_named_gpio(dev->of_node,"gpio_name", 0);
gpio_request(gpio_99, "gpio_name"); //通过gpio号申请gpio
gpio_direction_output(gpio_XX, 1); //设置gpio_XX输出,初始值为1
gpio_set_value(gpio_XX, 0); //设置gpio_XX值为0
gpio_free(gpio_XX); //gpio_XX不再使用后应当释放
三、Pinctrl控制方式
1、DTS代码
平台pinctrl节点下添加如下子节点
gpio_group {
gpio_active: gpio_active {
mux {
pins = "gpio99", "gpio98"; //复用引脚99和98
functions = "gpio"; //引脚功能配置为普通gpio
};
config {
pins = "gpio99", "gpio98";
drive-strength = <8>; //最大电流限制为8mA
bias-pull-up; //配置上拉
output-high; //输出高电平
};
};
gpio_sleep: gpio_sleep {
mux {
pins = "gpio99", "gpio98"; //复用引脚99和98
functions = "gpio"; //引脚功能配置为普通gpio
};
config {
pins = "gpio99", "gpio98";
drive-strength = <2>; //最大电流限制为2mA
bias-no-pull; //不上拉也不下拉
output-low; //输出低电平
};
};
2、设备节点中引用pinctrl
device_node {
...
pinctrl-names = "gpio_active", "gpio_sleep"; //分别对用pinctrl-0和pinctrl-1
pinctrl-0 = <&gpio_active>; //引用
pinctrl-1 = <&gpio_sleep>; //引用
...
};
3、内核驱动代码
struct pinctrl *pinctrl = devm_pinctrl_get(device); //获取device对应节点下的pinctrl
struct pinctrl_state = pinctrl_lookup_state(pinctrl, "gpio_active"); //通过pinctrl名获取pinctrl对应状态
pinctrl_select_state(pinctrl, pinctrl_state); //设置pinctrl的状态为'gpio_active
devm_pinctrl_put(pinctrl); //使用完了释放资源
四、 gpio debug
方法1:
msm8953_64:/sys/kernel/debug # cat gpio | grep gpio16
gpio16 : in 2 2mA pull down
方法2:
获取gpio状态
cd /sys/kernel/debug/
cat gpio
操作gpio(以gpio99为例)
cd /sys/class/gpio/
echo 99 > export
cd gpio99
echo in/out > direction //设置gpio输入或输出
cat direction //获取gpio输入输出状态
echo 'value' > value //设置gpio寄存器值
cat value //获取gpio寄存器的值
方法3:
TLMM_GPIO_CFGn 0x1000000 + 0x1000 * (n)
TLMM_GPIO_IN_OUTn 0x1000004 + 0x1000 * (n)
TLMM_GPIO_INTR_CFGn 0x1000008 + 0x1000 * (n)
TLMM_GPIO_INTR_STATUSn 0x100000C + 0x1000 * (n)
Example:To read GPIO 19 config registers
#/system/bin/r 0x1013000
#/system/bin/r 0x1013004
#/system/bin/r 0x1013008
#/system/bin/r 0x101300C
五、Regulator 配置
msm8953-regulator.dtsi
rpm-regulator-ldoa10 {
status = "okay";
pm8953_l10: regulator-l10 {
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
qcom,init-voltage = <2850000>;
status = "okay";
};
};
msm8953-sc826-evk.dtsi
&i2c_3 { /* BLSP1 QUP3 */
status = "okay";
goodix@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
vdd-supply = <&pm8953_l10>;
vdd_ld-supply = <&pm8953_l17>;
static int goodix_power_init(struct goodix_ts_data *ts)
{
ts->vdd = regulator_get(&ts->client->dev, "vdd");
if (IS_ERR(ts->vdd)) {
ret = PTR_ERR(ts->vdd);
}
regulator_set_voltage(ts->vdd, GOODIX_VTG_MIN_UV,
GOODIX_VTG_MAX_UV);//设置电压
regulator_enable(ts->vdd);//使能电压
regulator_disable(ts->vdd); //关闭电压
5.1 Regulator debug
msm8953_64:/sys/kernel/debug/regulator/pm8953_l8 # ls
7824900.sdhci-vdd consumers force_disable open_count pm8953_l8 voltage
bypass_count enable mode optimum_mode use_count
msm8953_64:/sys/class/regulator # ls
regulator.0 regulator.16 regulator.23 regulator.30 regulator.38 regulator.45
regulator.1 regulator.17 regulator.24 regulator.31 regulator.39 regulator.46
regulator.10 regulator.18 regulator.25 regulator.32 regulator.4 regulator.47
regulator.11 regulator.19 regulator.26 regulator.33 regulator.40 regulator.5
regulator.12 regulator.2 regulator.27 regulator.34 regulator.41 regulator.6
regulator.13 regulator.20 regulator.28 regulator.35 regulator.42 regulator.7
regulator.14 regulator.21 regulator.29 regulator.36 regulator.43 regulator.8
regulator.15 regulator.22 regulator.3 regulator.37 regulator.44 regulator.9
msm8953_64:/sys/class/regulator # cd regulator.20
msm8953_64:/sys/class/regulator/regulator.20 # ls
4080000.qcom,mss-vdd_pll max_microvolts num_users subsystem type
78000.ssphy-vdda18 microvolts opmode suspend_disk_state uevent
79000.qusb-vdda18 min_microvolts power suspend_mem_state
device name state suspend_standby_state
msm8953_64:/sys/class/regulator/regulator.20 # cat name
pm8953_l7
msm8953_64:/sys/class/regulator/regulator.20 # cat state
enabled