Linux注册GPIO中断函数

注册gpio 25上升沿和下降沿中断函数,用于检测休眠唤醒信号。

DTS

	quec,quectel-low-consume{
		compatible = "quec,quectel-low-consume";
		notify_gpio = <&tlmm_pinmux 11 0>;      /* which gpio can be controlled by ioctl to notify mcu */

		wakeup_gpio = <&tlmm_pinmux 25 0>;      /* wakeup pin */
		pinctrl-names = "default", "sleep", "wakeup_default";     /* status pin: module sleep indication gpio42 */
		pinctrl-0 = <&sleep_ind_active>;
		pinctrl-1 = <&sleep_ind_sleep>;
		pinctrl-2 = <&wakeup_in_default>;   /* wakeup pin default state */
		status = "okay";            /* disable by default */
	};
		wakeup_in_default: wakeup_in_default {
			config {
				pins = "gpio25";
				drive-strength = <2>;
				bias-pull-up;
			};
		};

		sleep_ind_active: sleep_ind_active {
			mux {
				pins = "gpio11";
				function = "gpio";
			};
			config {
				pins = "gpio11";
				drive-strength = <2>;
				bias-disable;
				output-low;
			};
		};
		sleep_ind_sleep: sleep_ind_sleep {
			mux {
				pins = "gpio11";
				function = "gpio";
			};
			config {
				pins = "gpio11";
				drive-strength = <2>;
				bias-disable;
				output-high;
			};
		};

代码

static int notify_gpio = 0;
static int sleep_gpio = 0;
static int wakeup_gpio = 0;
static int wakeup_irq = 0;

static int quectel_low_consume_probe(struct platform_device *pdev)
{
	gpio_data = devm_kzalloc(&pdev->dev,
				 sizeof(struct gpio_pinctrl_info),
				 GFP_KERNEL);

	wakeup_gpio = of_get_named_gpio(pdev->dev.of_node, "wakeup_gpio", 0);
	if(quectel_wakeup_init() < 0)
        {
                printk("[gale] %s: init wakeup gpio fail\n", __func__);
                goto err_wakeup_init;
        }	

	notify_gpio = of_get_named_gpio(pdev->dev.of_node, "notify_gpio", 0);
	if((ret = gpio_init()) < 0)
	{
    		printk("[gale] %s: notify pin init failed\n", __func__);
                goto err_gpio_init;
	}
static int quectel_wakeup_init(void)
{
	int err;
	
	err = gpio_request(wakeup_gpio, "wakeup_in");
	if (err < 0)
	{
		printk("[gale] %s: request gpio: %d error: %d\n", __func__, wakeup_gpio, err);
		goto err_gpio_request;
	}
	
	err = gpio_direction_input(wakeup_gpio);
	if (err < 0)
	{
		printk("[gale] %s: set gpio direction input (%d) fail\n", __func__, wakeup_gpio);
		goto err_gpio_to_irq;
	}

	err = gpio_to_irq(wakeup_gpio);
	printk("[gale] %s: gpio to irq: %d : %d\n", __func__, wakeup_gpio, err);
	if (err < 0)
	{
		printk("[gale] %s: gpio to irq: %d error: %d\n", __func__, wakeup_gpio, err);
		goto err_gpio_to_irq;
	}
	
	wakeup_irq = err; //中断号
    
	err = request_any_context_irq(wakeup_irq, quectel_wakeup_irq_func, \
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "quectel_wakeup_in", NULL);
	if (err < 0)
	{
		printk("[gale] %s: Can't get %d IRQ for wakeup_in: %d\n", __func__, wakeup_irq, err);
		goto err_gpio_free_irq;
	}

中断回调函数,判断对应的高低电平执行对应动作。

#define LOW_VALUE 0
#define HIGH_VALUE 1

static irqreturn_t quectel_wakeup_irq_func(void)
{
	int value = gpio_get_value(wakeup_gpio);
	if(value == LOW_VALUE)
	{
		strcpy(edge, "falling");
		kill_fasync(&gpio_async, SIGIO, POLL_IN);
		printk(KERN_ERR "eason LOW_VALUE\n");
	}
	else if(value == HIGH_VALUE)
	{
		strcpy(edge, "rising");
		kill_fasync(&gpio_async, SIGIO, POLL_IN );
		printk(KERN_ERR "eason HIGH_VALUE\n");
	}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPIO按键中断注册函数可以使用Linux内核提供的gpio_keys_button驱动来实现。这个驱动可以将一个GPIO引脚配置为按键输入,并且在按键按下和松开时触发中断,以便应用程序能够检测到按键事件。 下面是一个示例代码,演示如何使用gpio_keys_button驱动注册GPIO按键中断: ```c #include <linux/input.h> #include <linux/gpio_keys.h> #define KEY_GPIO 17 static struct gpio_keys_button gpio_button = { .type = EV_KEY, .code = KEY_ENTER, .gpio = KEY_GPIO, .active_low = 1, .desc = "gpio_button", }; static int __init gpio_button_init(void) { int ret; ret = gpio_request(KEY_GPIO, "gpio_button"); if (ret) { printk(KERN_ERR "Failed to request gpio %d: %d\n", KEY_GPIO, ret); return ret; } ret = gpio_direction_input(KEY_GPIO); if (ret) { printk(KERN_ERR "Failed to set direction of gpio %d: %d\n", KEY_GPIO, ret); gpio_free(KEY_GPIO); return ret; } ret = gpio_keys_button_register(&gpio_button); if (ret) { printk(KERN_ERR "Failed to register gpio button: %d\n", ret); gpio_free(KEY_GPIO); return ret; } return 0; } static void __exit gpio_button_exit(void) { gpio_keys_button_unregister(&gpio_button); gpio_free(KEY_GPIO); } module_init(gpio_button_init); module_exit(gpio_button_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("GPIO Button Interrupt Driver"); ``` 在这个示例代码中,我们定义了一个名为gpio_button的struct gpio_keys_button结构体,其中type和code字段指定了按键事件的类型和代码,gpio字段指定了GPIO引脚的编号,active_low字段指定了按键是否使用低电平触发,desc字段是一个描述字符串,用于标识这个按键。 接下来,在gpio_button_init函数中,我们首先请求GPIO引脚,然后设置它为输入模式。最后,我们调用gpio_keys_button_register函数注册这个GPIO按键中断。 最后,在gpio_button_exit函数中,我们注销这个GPIO按键中断,并释放GPIO引脚。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值