常见的方式
foo_device {
compatible = "acme,foo";
red-gpios =<&gpio 17 GPIO_ACTIVE_HIGH>;
}
enum of_gpio_flags flags;
int gpio=of_get_named_gpio_flags(dev->of_node,"red-gpios", 0, &flags);//获取dts的gpio
gpio_request_one(gpio, flags, "red-gpios");//申请gpio,并根据flags设置输入或者输出高/低
变种1
foo_device {
compatible = "acme,foo";
red-gpios =<&gpio 17 GPIO_ACTIVE_HIGH>;
}
struct gpio_desc *red;
red = gpiod_get(dev, "red", GPIOD_OUT_HIGH);
变种2
foo_device {
compatible = "acme,foo";
...
led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */
<&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
<&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
};
struct gpio_desc *red, *green, *blue;
red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);
green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);
blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);
看下gpiod_set_value函数,设值的时候会根据flag进行翻转
void gpiod_set_value(struct gpio_desc *desc, int value)
{
VALIDATE_DESC_VOID(desc);
/* Should be using gpiod_set_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
value = !value;
_gpiod_set_raw_value(desc, value);
}
EXPORT_SYMBOL_GPL(gpiod_set_value);
gpiod_get通过gpiod_get_index实现
struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return gpiod_get_index(dev, con_id, 0, flags);
}
EXPORT_SYMBOL_GPL(gpiod_get);
看下gpiod_get_index的实现
static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" };
struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,const char *propname, int index, enum of_gpio_flags *flags)
{
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,&gpiospec);
chip = of_find_gpiochip_by_xlate(&gpiospec);
desc = of_xlate_and_get_gpiod_flags(chip, &gpiospec, flags);
}
struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,unsigned int idx,enum gpio_lookup_flags *flags)
{
char prop_name[32]; /* 32 is max size of property name */
struct gpio_desc *desc;
for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
if (con_id)
snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id,
gpio_suffixes[i]);
else
snprintf(prop_name, sizeof(prop_name), "%s",gpio_suffixes[i]);
desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,&of_flags);
}
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,unsigned long lflags, enum gpiod_flags dflags)
{
if (dflags & GPIOD_FLAGS_BIT_DIR_OUT)
status = gpiod_direction_output(desc,!!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
else
status = gpiod_direction_input(desc);
}
struct gpio_desc *__must_check gpiod_get_index(struct device *dev,const char *con_id,unsigned int idx,enum gpiod_flags flags)
{
desc = of_find_gpio(dev, con_id, idx, &lookupflags);
status = gpiod_request(desc, con_id ? con_id : devname);
status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
}
平常自以为对这些很熟了,但看某快代码时,找不到对应的逻辑,发现对这块点知识有缺失,特总结下。 写博客只是为了不影响看代码的速度,把每块知识点都弄清了,那代码就为你服务了。