MODE | DIR | DOUT | DIN | DRIVE(2bit) | SMT | IES | PULL_EN | PULL_SEL | R1 R0 |
当前io功能 | 0输入1输出 | 输出值 | 输入值 | 驱动能力 | 使能施密特触发器 | 输入使能(默认1) | 有上拉或下拉 | 0下拉1上拉 | 控制上下拉阻值(特定gpio) |
echo mode 88 3 > mt_gpio | echo dir 88 1 > mt_gpio | echo out 88 1 > mt_gpio | echo driving 88 7 > mt_gpio | echo pullen 88 1 > mt_gpio | echo pullsel 88 1 > mt_gpio |
如
090: 2000000100
091: 1000000100 (0 0)
092: 1000000100 (0 0)
093: 1101001111 (1 0)
DRIVE占了两位
%1d%1d%1d%1d%02d%1d%1d%1d%1d",
tatic ssize_t mtk_gpio_store_pin(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int i, gpio, val, val2, pullup = 0, pullen = 0;
int vals[12];
char attrs[12];
struct mtk_pinctrl *hw = dev_get_drvdata(dev);
const struct mtk_pin_desc *desc;
struct gpio_chip *chip;
int r1r0_en[4] = {MTK_PUPD_SET_R1R0_00, MTK_PUPD_SET_R1R0_01,
MTK_PUPD_SET_R1R0_10, MTK_PUPD_SET_R1R0_11};
if (!hw) {
pr_debug("[pinctrl] Err: NULL pointer!\n");
return count;
}
chip = &hw->chip;
if (!strncmp(buf, "mode", 4)
&& (sscanf(buf+4, "%d %d", &gpio, &val) == 2)) {
mtk_pctrl_set_pinmux(hw, gpio, val);
} else if (!strncmp(buf, "dir", 3)
&& (sscanf(buf+3, "%d %d", &gpio, &val) == 2)) {
mtk_pctrl_set_direction(hw, gpio, val);
} else if (!strncmp(buf, "out", 3)
&& (sscanf(buf+3, "%d %d", &gpio, &val) == 2)) {
mtk_pctrl_set_direction(hw, gpio, val);
/* mtk_gpio_set(chip, gpio, val); */
mtk_pctrl_set_out(hw, gpio, val);
} else if (!strncmp(buf, "pullen", 6)
&& (sscanf(buf+6, "%d %d", &gpio, &val) == 2)) {
if (gpio < 0 || gpio > hw->soc->npins) {
pr_notice("invalid pin number\n");
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
if (pullen < MTK_PUPD_SET_R1R0_00) {
pullen = !!val;
} else {
if (val < 0)
val = 0;
else if (val > 3)
val = 3;
pullen = r1r0_en[val];
}
mtk_pinconf_bias_set_combo(hw, desc, pullup, pullen);
} else if ((!strncmp(buf, "pullsel", 7))
&& (sscanf(buf+7, "%d %d", &gpio, &val) == 2)) {
if (gpio < 0 || gpio > hw->soc->npins) {
pr_notice("invalid pin number\n");
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
mtk_pinconf_bias_set_combo(hw, desc, !!val, pullen);
} else if ((!strncmp(buf, "ies", 3))
&& (sscanf(buf+3, "%d %d", &gpio, &val) == 2)) {
mtk_pctrl_set_ies(hw, gpio, val);
} else if ((!strncmp(buf, "smt", 3))
&& (sscanf(buf+3, "%d %d", &gpio, &val) == 2)) {
mtk_pctrl_set_smt(hw, gpio, val);
} else if ((!strncmp(buf, "driving", 7))
&& (sscanf(buf+7, "%d %d", &gpio, &val) == 2)) {
if (gpio < 0 || gpio > hw->soc->npins) {
pr_notice("invalid pin number\n");
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_pinconf_drive_set_direct_val(hw, desc, val);
} else if ((!strncmp(buf, "r1r0", 4))
&& (sscanf(buf+4, "%d %d %d", &gpio, &val, &val2) == 3)) {
if (gpio < 0 || gpio > hw->soc->npins) {
pr_notice("invalid pin number\n");
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
pullen = r1r0_en[(((!!val) << 1) + !!val2)];
mtk_pinconf_bias_set_combo(hw, desc, pullup, pullen);
} else if (!strncmp(buf, "set", 3)) {
val = sscanf(buf+3, "%d %c%c%c%c%c%c%c%c%c%c %c%c", &gpio,
&attrs[0], &attrs[1], &attrs[2], &attrs[3],
&attrs[4], &attrs[5], &attrs[6], &attrs[7],
&attrs[8], &attrs[9], &attrs[10], &attrs[11]);
for (i = 0; i < ARRAY_SIZE(attrs); i++) {
if ((attrs[i] >= '0') && (attrs[i] <= '9'))
vals[i] = attrs[i] - '0';
else
vals[i] = 0;
}
if (gpio < 0) {
pr_notice("invalid pin number\n");
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
/* MODE */
mtk_pctrl_set_pinmux(hw, gpio, vals[0]);
/* DIR */
mtk_pctrl_set_direction(hw, gpio, !!vals[1]);
/* DOUT */
if (vals[1])
/*mtk_gpio_set(chip, gpio, !!vals[2]); */
mtk_pctrl_set_out(hw, gpio, !!vals[2]);
/* DRIVING */
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_pinconf_drive_set_direct_val(hw, desc,
vals[4]*10 + vals[5]);
/* SMT */
mtk_pctrl_set_smt(hw, gpio, vals[6]);
/* IES */
mtk_pctrl_set_ies(hw, gpio, vals[7]);
/* PULL */
mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
if (pullen < MTK_PUPD_SET_R1R0_00) {
mtk_pinconf_bias_set_combo(hw, desc, !!vals[9],
!!vals[8]);
} else {
pullen = r1r0_en[(((!!vals[10]) << 1) + !!vals[11])];
mtk_pinconf_bias_set_combo(hw, desc, !!vals[9],
pullen);
}
}
out:
return count;
}
在某些老的平台,没有mt_gpio,有pin节点,具体用法可参考代码
ssize_t mt_gpio_store_pin(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
...
if (!strncmp(buf, "-h", 2)) {
GPIOMSG("cat pin #show all pin setting\n");
GPIOMSG("echo -wmode num x > pin #num:pin,x:the mode 0~7\n");
GPIOMSG("echo -wpsel num x > pin #x: 1,pull-up; 0,pull-down\n");
GPIOMSG("echo -wdout num x > pin #x: 1,high; 0, low\n");
GPIOMSG("echo -wpen num x > pin #x: 1,pull enable; 0 pull disable\n");
GPIOMSG("echo -wies num x > pin #x: 1,ies enable; 0 ies disable\n");
GPIOMSG("echo -wdir num x > pin #x: 1, output; 0, input\n");
/*GPIOMSG("echo -wdinv num x > pin #x: 1, inversion enable; 0, disable\n"); */
GPIOMSG("echo -w=num x x x x x x > pin #set all property one time\n");
GPIOMSG("PIN: [MODE] [PSEL] [DIN] [DOUT] [PEN] [DIR] [IES]\n");
}
...
}
如
echo -wmode 67 6 > pin
echo -wdir 67 0 > pin
echo -wpsel 67 1 > pin