linux使用gpio示例

常见的方式

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);
}

平常自以为对这些很熟了,但看某快代码时,找不到对应的逻辑,发现对这块点知识有缺失,特总结下。 写博客只是为了不影响看代码的速度,把每块知识点都弄清了,那代码就为你服务了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值