1. 程式人生 > >MTK平臺通過adb獲取GPIO狀態

MTK平臺通過adb獲取GPIO狀態

一、節點位置

    在MTK平臺,我們可以通過cat節點(mt_gpio)來檢視對應的狀態。不同的平臺,該管腳對應的位置也是不同的,建議直接進入手機目錄檢視:

adb shell
find -name "mt_gpio"

我這檢視到對應的是:sys/devices/platform/1000b000.pinctrl/mt_gpio

然後直接cat這個節點會出現如下的資訊:

PIN: [MODE] [DIR] [DOUT] [DIN] [PULL_EN] [PULL_SEL] [IES] [SMT] [DRIVE] ( [R1] [R0] )
   0: 011110100 01
   1: 000010100 01
   2: 000111100 01
   3: 000010100 01
   4: 011100100 00
   5: 000010100 01
   6: 000100110
   ... ...

二、原始碼分析

    1、首先我們從建立該節點的位置開始分析,在kernel-4.4/drivers/pinctrl/mediatek/pinctrl-mtk-common.c

    static DEVICE_ATTR(mt_gpio, 0664, mt_gpio_show_pin, mt_gpio_store_pin);

    這裡可以看到通過DEVICE_ATTR建立了mt_gpio節點,開了664的許可權。

    2、再來看下當cat節點時的動作 mt_gpio_show_pin

static ssize_t mt_gpio_show_pin(struct device *dev, struct device_attribute *attr, char *buf)
{
	int len = 0;
	int bufLen = PAGE_SIZE;
	struct mtk_pinctrl *pctl = dev_get_drvdata(dev);
	struct gpio_chip *chip = pctl->chip;
	unsigned i;
	int mode, pull_val;

	len += snprintf(buf+len, bufLen-len,
		"PIN: [MODE] [DIR] [DOUT] [DIN] [PULL_EN] [PULL_SEL] [IES] [SMT] [DRIVE] ( [R1] [R0] )\n");

	for (i = 0; i < chip->ngpio; i++) {
		pull_val = mtk_pullsel_get(chip, i);

		mode = mtk_pinmux_get(chip, i);
		if (mode >= 0) {
			len += snprintf(buf+len, bufLen-len, "%4d: %x%d%d%d%d%d%d%d%x",
				i,
				mtk_pinmux_get(chip, i),
				!mtk_gpio_get_direction(chip, i),
				mtk_gpio_get_out(chip, i),
				mtk_gpio_get_in(chip, i),
				mtk_pullen_get(chip, i),
				(pull_val >= 0) ? (pull_val&1) : -1,
				mtk_ies_get(chip, i),
				mtk_smt_get(chip, i),
				mtk_driving_get(chip, i));
			if ((pull_val & 8) && (pull_val >= 0))
				len += snprintf(buf+len, bufLen-len, " %d%d", !!(pull_val&4), !!(pull_val&2));
			len += snprintf(buf+len, bufLen-len, "\n");
		} else {
			len += snprintf(buf+len, bufLen-len, "%4d: XXXXXXXXX\n", i);
		}
	}
	return len;
}

    3、分解對應的項

    通過如上方法可以看到我們cat出來的資訊分別對應的是:

    PIN: [MODE] [DIR] [DOUT] [DIN] [PULL_EN] [PULL_SEL] [IES] [SMT] [DRIVE] ( [R1] [R0] )

    PIN:即對應的GPIO管腳;

    MODE:該管腳對應的模式,即該管腳作為什麼來用的,如作為普通的GPIO,或者int等,通過mtk_pinmux_get(chip, i)方法獲取;

    DIR:輸入還是輸出,即該管腳對應的方向,通過mtk_gpio_get_direction方法獲取;

    DOUT:如果是輸出模式對應的值是多少,通過mtk_gpio_get_out方法獲取,預設為0;

    DIN:如果是輸入模式對應的值是多少,通過mtk_gpio_get_in方法獲取,預設為0;

    PULL_EN:是否支援輸入上下拉,通過mtk_pullen_get方法獲取,如果不支援預設為0;

    PULL_SEL:如果支援上下拉,對應的值。通過pull_val的值來決定上拉還是下拉。如果不支援,預設為0;

    IES+SMT:輸入翻轉