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

猜你喜欢

转载自blog.csdn.net/TSZ0000/article/details/90035776