高通 --gpio控制和input event调试(附全代码)

一、概述

整机调试中,我们经常需要操作某些io,下面就io驱动添加,和input输入事件,以及ioctl的控制io,三个部分来实现完整的控制和调试io的过程。可以porting到任何linux平台。

二、gpio demo驱动详解

1、dts的pinctrl配置

文件:trinket-idp.dtsi
//add gpio demo
	gpio_demo {
		compatible = "sylon,gpio-demo";
		sylon,test1-gpio = <&tlmm 57 GPIO_ACTIVE_HIGH>;
		sylon,test2-gpio = <&tlmm 58 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "active","suspend";
		pinctrl-0 = <&gpio_demo_active>;
		pinctrl-1 = <&gpio_demo_suspend>;
	};
文件:trinket-pinctrl.dtsi
/* gpio demo */
		gpio_demo: gpio_demo {
			gpio_demo_active: gpio_demo_active{
				mux {
					pins = "gpio57", "gpio58";
					function = "gpio";
				};
				
				config {
					pins = "gpio57", "gpio58";
					drive-strength = <8>;
					bias-disable;
				};
			};
			gpio_demo_suspend: gpio_demo_suspend{
				mux {
					pins = "gpio57", "gpio58";
					function = "gpio";
				};
				
				config {
					pins = "gpio57", "gpio58";
					drive-strength = <2>;
					bias-pull-down;
				};
			};
		};
		input_key_default: input_key_default {
			mux {
				pins = "gpio123", "gpio124", "gpio130", "gpio132";
				function = "gpio";
			};
			config {
				pins = "gpio123", "gpio124", "gpio130", "gpio132";
				bias-pull-down;
				input-enable;
			};
		};
		/* gpio demo */

2、注册平台驱动,创建字符设备并分配设备id号。

gpio_device设备创建

3、io初始化

static int gpio_demo_probe(struct platform_device *pdev)
{
	int err,ret;
	struct device *dev = &pdev->dev;
	int gpio123_di0_irq,gpio124_di1_irq,gpio130_di2_irq,gpio132_di3_irq;
	//申请gpio并上拉
	test1_gpio = of_get_named_gpio(dev->of_node, "sylon,test1-gpio", 0);
	if (gpio_is_valid(test1_gpio)) {
		err = gpio_request(test1_gpio, "test1");
		if (err<0) {
			pr_err("test1 gpio request failed\n");
		}
		gpio_direction_output(test1_gpio, 0);
		gpio_set_value(test1_gpio, 1);	
	}
	test2_gpio = of_get_named_gpio(dev->of_node, "sylon,test2-gpio", 0);
	if (gpio_is_valid(test2_gpio)) {
		err = gpio_request(test2_gpio, "test2");
		if (err<0) {
			pr_err("test2 gpio request failed\n");
		}
		gpio_direction_output(test2_gpio, 0);
		gpio_set_value(test2_gpio, 1);	
	}
	
	test3_gpio = of_get_named_gpio(dev->of_node, "sylon,test3-gpio", 0);
	if (gpio_is_valid(test3_gpio)) {
		err = gpio_request(test3_gpio, "gpio130_in");
		if (err<0) {
			pr_err("test3 gpio request failed\n");
		}
		gpio_direction_input(test3_gpio);
		gpio130_di2_irq = gpio_to_irq(test3_gpio);
		request_irq(gpio130_di2_irq, di2_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio130_di2_irq", NULL);
		enable_irq_wake(gpio130_di2_irq);
	}

	test4_gpio = of_get_named_gpio(dev->of_node, "sylon,test4-gpio", 0);
	if (gpio_is_valid(test4_gpio)) {
		err = gpio_request(test4_gpio, "gpio132_in");
		if (err<0) {
			pr_err("test4 gpio request failed\n");
		}
		gpio_direction_input(test4_gpio);
		gpio132_di3_irq = gpio_to_irq(test4_gpio);
		request_irq(gpio132_di3_irq, di3_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio132_di3_irq", NULL);
		enable_irq_wake(gpio132_di3_irq);

	}
	
	test5_gpio = of_get_named_gpio(dev->of_node, "sylon,test5-gpio", 0);
	if (gpio_is_valid(test5_gpio)) {
		err = gpio_request(test5_gpio, "gpio123_in");
		if (err<0) {
			pr_err("test5 gpio request failed\n");
		}
		gpio_direction_input(test5_gpio);
		gpio123_di0_irq = gpio_to_irq(test5_gpio);
		request_irq(gpio123_di0_irq, di0_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio123_di0_irq", NULL);
		enable_irq_wake(gpio123_di0_irq);
	}

	test6_gpio = of_get_named_gpio(dev->of_node, "sylon,test6-gpio", 0);
	if (gpio_is_valid(test6_gpio)) {
		err = gpio_request(test6_gpio, "gpio124_in");
		if (err<0) {
			pr_err("test6 gpio request failed\n");
		}
		gpio_direction_input(test6_gpio);
		gpio124_di1_irq = gpio_to_irq(test6_gpio);
		request_irq(gpio124_di1_irq, di1_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio124_di1_irq", NULL);
		enable_irq_wake(gpio124_di1_irq);
	}
	inputdev = input_allocate_device();
    inputdev->name = "input_device_bem";
	__set_bit(EV_KEY, inputdev->evbit); 
	__set_bit(EV_SYN, inputdev->evbit);
	__set_bit(EV_REP, inputdev->evbit); 
	__set_bit(KEY1, inputdev->keybit); 
	__set_bit(KEY2, inputdev->keybit); 
	__set_bit(KEY3, inputdev->keybit); 
	__set_bit(KEY4, inputdev->keybit); 

	ret = input_register_device(inputdev);
	if (ret) {
		printk("debug : register input device failed!\r\n");
	return ret;
	}
	device_create_file(&pdev->dev, &dev_attr_gpio_demo);
	
	pr_err("[]gpio_demo_probe end...\n");
	
	return 0;
	
}

4、中断处理函数配置

static irqreturn_t di0_interrput_handler(int irq, void *dev_id)
{
	static int KEY1_state = 0;
    //int i;
    // for(i=0; i<10; i++){ //debouncing 10us
    //     KEY1_state = gpio_get_value(test5_gpio);
    // }
	printk(" >>>>>>>>>>>>>> KEY1_state =%d,di0_interrput_handler interrput set gpio 123  \n",KEY1_state);
    // if(KEY1_state){   
    //     input_report_key(inputdev,KEY1,0);
    //     input_sync(inputdev);
    // }
    // else{  
    //     input_report_key(inputdev,KEY1,1);
    //     input_sync(inputdev);
    // }
	return IRQ_HANDLED;
}

5、ioctl的函数配置

struct file_operations gpio_demo_ops={
.owner = THIS_MODULE,
.unlocked_ioctl = gpio_demo_ioctl,
};
在这里插入图片描述

三、ioctl操作io

在这里插入图片描述

四、input输入事件

1、dts配置

在这里插入图片描述

2、read配置的input io事件

在这里插入图片描述

3、输出input事件和类型

在这里插入图片描述

5、整体代码

1、input_event.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <linux/input.h>
#define INPUT_NAME  "gpio-keys"
static struct input_event inputevent;

static int find_key_devpath(char *dev_path, int len)
{
    int ret = -1;
    int id = 0, event_name_fd;
    char event_name_path[40];
    char event_name[40];
    if((NULL == dev_path) || (len < 32)){
        printf("para error dev_path:%d len:%d\n", (int)dev_path, len);
        return -1;
    }
    for(id = 0; id < 16; ++id) {
        memset(event_name_path, 0, sizeof(event_name_path));
        memset(event_name, 0, sizeof(event_name_path));
        sprintf(event_name_path, "/sys/class/input/event%d/device/name", id);
        event_name_fd = open(event_name_path, O_RDONLY);
        if(event_name_fd < 0){
            printf("can not open dev_path:%s ret = %d\n", dev_path, event_name_fd);
            continue;
        }
        if(read(event_name_fd, &event_name, sizeof(event_name)) != -1 && (strstr(event_name, INPUT_NAME))) {
                memset(dev_path, 0, len);
                sprintf(dev_path, "/dev/input/event%d", id);
                close(event_name_fd);
                ret = 0;
                break;
        }
        close(event_name_fd);
    }
    printf("find_input_devpath dev_path:%s \n", dev_path);
    return ret;
}
/*
 * @description		: main主程序
 * @param - argc 	: argv数组元素个数
 * @param - argv 	: 具体参数
 * @return 			: 0 成功;其他 失败
 */
//int main(int argc, char *argv[])
int main()
{
    int fd;
    int err = 0;
    char filename[32];

    if(find_key_devpath(filename, sizeof(filename))){
        printf("can't find_input dev\r");
        return 0;
    }
    printf("use input(%s)\r\n", filename);
    fd = open(filename, O_RDWR);
    if (fd < 0)
    {
        printf("Can't open file %s\r\n", filename);
        return -1;
    }
     while (1)
    {
        err = read(fd, &inputevent, sizeof(inputevent));
        if (err > 0)
        { /* 读取数据成功 */
            switch (inputevent.type)
            {
            case EV_KEY:
                printf("EV_KEY:code(%d) value:(%d) \r\n", inputevent.code, inputevent.value); 
                break;
            case EV_REL:
                break;
            case EV_ABS:
                break;
            case EV_MSC:
                break;
            case EV_SW:
                break;
            default:
                //printf("inputevent(%d):code(%d) value:(%d) \r\n", inputevent.type, inputevent.code, inputevent.value); 
                break;
            }
        }
        else
        {
            printf("failed to read inputevent data.\r\n");
        }
    }
    return 0;
}

2、gpio_ioctl.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <sys/ioctl.h>

#define GPIO57_HIGH _IO('L', 0)
#define GPIO57_LOW _IO('L', 1)
#define GPIO58_HIGH _IO('L', 2)
#define GPIO58_LOW _IO('L', 3)


int main()
{
    int fd,ch;
    //char buff[64] = {0};
    fd = open("/dev/gpio_device", O_RDWR);      
    if(fd < 0){
        perror("open error\n");                 
        return fd;
    }

    while(1)
    {        
        printf("(0:GPIO57_HIGH; 1:GPIO57_LOW; \n");
        printf("(2:GPIO58_HIGH; 3:GPIO58_LOW; \n");
    
        scanf("%d",&ch);
        while((getchar())!='\n');
        switch (ch)
        {
            case 0:
                ioctl(fd, GPIO57_HIGH);                  
                break;
            case 1:
                ioctl(fd, GPIO57_LOW);                  
                break;
            case 2:
                ioctl(fd, GPIO58_HIGH);                  
                break;
            case 3:
                ioctl(fd, GPIO58_LOW);                  
                break;
                             
            default:
                printf("Not ctl any gpio\n");                  
                break;
        }

    }
    return 0;
}

3、gpio_demo.c

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/irq.h>
#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/dmi.h>
#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include <asm/unaligned.h>


#define GPIO57_HIGH _IO('L', 0)
#define GPIO57_LOW _IO('L', 1)
#define GPIO58_HIGH _IO('L', 2)
#define GPIO58_LOW _IO('L', 3)
#define GPIO130_HIGH _IO('L', 4)
#define GPIO130_LOW _IO('L', 5)
#define GPIO132_HIGH _IO('L', 6)
#define GPIO132_LOW _IO('L', 7)
#define GPIO123_HIGH _IO('L', 8)
#define GPIO123_LOW _IO('L', 9)
#define GPIO124_HIGH _IO('L', 10)
#define GPIO124_LOW _IO('L', 11)
static int major;
static struct class *cls;
struct input_dev *inputdev;
int test1_gpio;
int test2_gpio;
int test3_gpio;
int test4_gpio;
int test5_gpio;
int test6_gpio;
static int show_gpio;
#define KEY1  '0'
#define KEY2  '1'
#define KEY3  '2'
#define KEY4  '3'


static ssize_t gpio_value_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", gpio_get_value(show_gpio));
}

static ssize_t gpio_value_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)
{
	if ('0' == buf[0]) {
		show_gpio = test1_gpio;
		gpio_direction_output(test1_gpio, 0);
		printk("echo  gpio57 = 0 \n");
	} else if ('1' == buf[0]) {
		show_gpio = test1_gpio;
		gpio_direction_output(test1_gpio, 1);
		printk("echo  gpio57 = 1 \n");
	} else if ('0' == buf[0]) {
		show_gpio = test2_gpio;
		gpio_direction_output(test2_gpio, 0);
		printk("echo  gpio58 = 0 \n");
	} else if ('1' == buf[0]) {
		show_gpio = test2_gpio;
		gpio_direction_output(test2_gpio, 1);
		printk("echo  gpio58 = 1 \n");
	} else if ('0' == buf[0]) {
		show_gpio = test3_gpio;
		gpio_direction_output(test3_gpio, 0);
		printk("echo  gpio130 = 0 \n");
	} else if ('1' == buf[0]) {
		show_gpio = test3_gpio;
		gpio_direction_output(test3_gpio, 1);
		printk("echo  gpio130 = 1 \n");
	} else if ('0' == buf[0]) {
		show_gpio = test4_gpio;
		gpio_direction_output(test4_gpio, 0);
		printk("echo  gpio132 = 0 \n");
	} else if ('1' == buf[0]) {
		show_gpio = test4_gpio;
		gpio_direction_output(test4_gpio, 1);
		printk("echo  gpio132 = 1 \n");
	}else if ('0' == buf[0]) {
		show_gpio = test5_gpio;
		gpio_direction_output(test5_gpio, 0);
		printk("echo  gpio123 = 0 \n");
	} else if ('1' == buf[0]) {
		show_gpio = test5_gpio;
		gpio_direction_output(test5_gpio, 1);
		printk("echo  gpio123 = 1 \n");
	} else if ('0' == buf[0]) {
		show_gpio = test6_gpio;
		gpio_direction_output(test6_gpio, 0);
		printk("echo  gpio124 = 0 \n");
	} else if ('1' == buf[0]) {
		show_gpio = test6_gpio;
		gpio_direction_output(test6_gpio, 1);
		printk("echo  gpio124 = 1 \n");
	} else
		pr_err("I only support 0 or 1 to ctrl gpio on or off\n");
	return len;
}

static DEVICE_ATTR(gpio_demo, 0664, gpio_value_show, gpio_value_store);

long gpio_demo_ioctl( struct file *file, unsigned int cmd, unsigned long arg )
{
    switch( cmd )
    {
        case GPIO57_HIGH:
            gpio_direction_output(test1_gpio, 1);
			printk("set gpio57 to 1 \n");
            break;
        case GPIO57_LOW:
            gpio_direction_output(test1_gpio, 0);
			printk("set gpio57 to 0 \n");
            break;

		case GPIO58_HIGH:
            gpio_direction_output(test2_gpio, 1);
			printk("set gpio58 to 1 \n");
            break;
        case GPIO58_LOW:
            gpio_direction_output(test2_gpio, 0);
			printk("set gpio58 to 0 \n");
            break;
		
		// case GPIO130_HIGH:
        //     gpio_direction_output(test3_gpio, 1);
		// 	printk("set gpio130 to 1 \n");
        //     break;
        // case GPIO130_LOW:
        //     gpio_direction_output(test3_gpio, 0);
		// 	printk("set gpio130 to 0 \n");
        //     break;
		
		// case GPIO132_HIGH:
        //     gpio_direction_output(test4_gpio, 1);
		// 	printk("set gpio132 to 1 \n");
        //     break;
        // case GPIO132_LOW:
        //     gpio_direction_output(test4_gpio, 0);
		// 	printk("set gpio132 to 0 \n");
        //     break;
		// case GPIO123_HIGH:
        //     gpio_direction_output(test5_gpio, 1);
		// 	printk("set GPIO123 to 1 \n");
        //     break;
        // case GPIO123_LOW:
        //     gpio_direction_output(test5_gpio, 0);
		// 	printk("set GPIO123 to 0 \n");
        //     break;
		// case GPIO124_HIGH:
        //     gpio_direction_output(test6_gpio, 1);
		// 	printk("set GPIO124 to 1 \n");
        //     break;
        // case GPIO124_LOW:
        //     gpio_direction_output(test6_gpio, 0);
		// 	printk("set GPIO124 to 0 \n");
        //     break;
        default: 
            return -EINVAL;        
            break;
    }
    return 0;
}


struct file_operations gpio_demo_ops={
         .owner  = THIS_MODULE,
		 .unlocked_ioctl = gpio_demo_ioctl,
};

static irqreturn_t di0_interrput_handler(int irq, void *dev_id)
{
	static int KEY1_state = 0;
    //int i;
    // for(i=0; i<10; i++){ //debouncing 10us
    //     KEY1_state = gpio_get_value(test5_gpio);
    // }
	printk(" >>>>>>>>>>>>>> KEY1_state =%d,di0_interrput_handler interrput set gpio 123  \n",KEY1_state);
    // if(KEY1_state){   
    //     input_report_key(inputdev,KEY1,0);
    //     input_sync(inputdev);
    // }
    // else{  
    //     input_report_key(inputdev,KEY1,1);
    //     input_sync(inputdev);
    // }
	return IRQ_HANDLED;
}
static irqreturn_t di1_interrput_handler(int irq, void *dev_id)
{
	static int KEY2_state = 0;
    //int i;
    // for(i=0; i<10; i++){ //debouncing 10us
    //     KEY2_state = gpio_get_value(test5_gpio);
    // }
	printk(">>>>>>>>>>>>>> KEY2_state =%d,di1_interrput_handler interrput set gpio 124 \n",KEY2_state);
    // if(KEY2_state){   
    //     input_report_key(inputdev,KEY2,0);
    //     input_sync(inputdev);
    // }
    // else{  
    //     input_report_key(inputdev,KEY2,1);
    //     input_sync(inputdev);
    // }
	return IRQ_HANDLED;
}
static irqreturn_t di2_interrput_handler(int irq, void *dev_id)
{
	static int KEY3_state = 0;
    //int i;
    // for(i=0; i<10; i++){ //debouncing 10us
    //     KEY3_state = gpio_get_value(test5_gpio);
    // }
	printk(" >>>>>>>>>>>>>> KEY3_state =%d,di2_interrput_handler interrput set gpio 130  \n",KEY3_state);
    // if(KEY3_state){   
    //     input_report_key(inputdev,KEY3,0);
    //     input_sync(inputdev);
    // }
    // else{  
    //     input_report_key(inputdev,KEY3,1);
    //     input_sync(inputdev);
    // }
	return IRQ_HANDLED;
}
static irqreturn_t di3_interrput_handler(int irq, void *dev_id)
{
	static int KEY4_state = 0;
    //int i;
    // for(i=0; i<10; i++){ //debouncing 10us
    //     KEY4_state = gpio_get_value(test5_gpio);
    // }
	printk(">>>>>>>>>>>>>> KEY4_state =%d,di3_interrput_handler interrput set gpio 132\n",KEY4_state);
    // if(KEY4_state){   
    //     input_report_key(inputdev,KEY4,0);
    //     input_sync(inputdev);
    // }
    // else{  
    //     input_report_key(inputdev,KEY4,1);
    //     input_sync(inputdev);
    // }
	return IRQ_HANDLED;
}


static int gpio_demo_probe(struct platform_device *pdev)
{
	int err,ret;
	struct device *dev = &pdev->dev;
	int gpio123_di0_irq,gpio124_di1_irq,gpio130_di2_irq,gpio132_di3_irq;
	//申请gpio并上拉
	test1_gpio = of_get_named_gpio(dev->of_node, "sylon,test1-gpio", 0);
	if (gpio_is_valid(test1_gpio)) {
		err = gpio_request(test1_gpio, "test1");
		if (err<0) {
			pr_err("test1 gpio request failed\n");
		}
		gpio_direction_output(test1_gpio, 0);
		gpio_set_value(test1_gpio, 1);	
	}
	test2_gpio = of_get_named_gpio(dev->of_node, "sylon,test2-gpio", 0);
	if (gpio_is_valid(test2_gpio)) {
		err = gpio_request(test2_gpio, "test2");
		if (err<0) {
			pr_err("test2 gpio request failed\n");
		}
		gpio_direction_output(test2_gpio, 0);
		gpio_set_value(test2_gpio, 1);	
	}
	
	test3_gpio = of_get_named_gpio(dev->of_node, "sylon,test3-gpio", 0);
	if (gpio_is_valid(test3_gpio)) {
		err = gpio_request(test3_gpio, "gpio130_in");
		if (err<0) {
			pr_err("test3 gpio request failed\n");
		}
		gpio_direction_input(test3_gpio);
		gpio130_di2_irq = gpio_to_irq(test3_gpio);
		request_irq(gpio130_di2_irq, di2_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio130_di2_irq", NULL);
		enable_irq_wake(gpio130_di2_irq);
	}

	test4_gpio = of_get_named_gpio(dev->of_node, "sylon,test4-gpio", 0);
	if (gpio_is_valid(test4_gpio)) {
		err = gpio_request(test4_gpio, "gpio132_in");
		if (err<0) {
			pr_err("test4 gpio request failed\n");
		}
		gpio_direction_input(test4_gpio);
		gpio132_di3_irq = gpio_to_irq(test4_gpio);
		request_irq(gpio132_di3_irq, di3_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio132_di3_irq", NULL);
		enable_irq_wake(gpio132_di3_irq);

	}
	
	test5_gpio = of_get_named_gpio(dev->of_node, "sylon,test5-gpio", 0);
	if (gpio_is_valid(test5_gpio)) {
		err = gpio_request(test5_gpio, "gpio123_in");
		if (err<0) {
			pr_err("test5 gpio request failed\n");
		}
		gpio_direction_input(test5_gpio);
		gpio123_di0_irq = gpio_to_irq(test5_gpio);
		request_irq(gpio123_di0_irq, di0_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio123_di0_irq", NULL);
		enable_irq_wake(gpio123_di0_irq);
	}

	test6_gpio = of_get_named_gpio(dev->of_node, "sylon,test6-gpio", 0);
	if (gpio_is_valid(test6_gpio)) {
		err = gpio_request(test6_gpio, "gpio124_in");
		if (err<0) {
			pr_err("test6 gpio request failed\n");
		}
		gpio_direction_input(test6_gpio);
		gpio124_di1_irq = gpio_to_irq(test6_gpio);
		request_irq(gpio124_di1_irq, di1_interrput_handler,
				IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING,
				"gpio124_di1_irq", NULL);
		enable_irq_wake(gpio124_di1_irq);
	}
	inputdev = input_allocate_device();
    inputdev->name = "input_device_bem";
	__set_bit(EV_KEY, inputdev->evbit); 
	__set_bit(EV_SYN, inputdev->evbit);
	__set_bit(EV_REP, inputdev->evbit); 
	__set_bit(KEY1, inputdev->keybit); 
	__set_bit(KEY2, inputdev->keybit); 
	__set_bit(KEY3, inputdev->keybit); 
	__set_bit(KEY4, inputdev->keybit); 

	ret = input_register_device(inputdev);
	if (ret) {
		printk("debug : register input device failed!\r\n");
	return ret;
	}
	device_create_file(&pdev->dev, &dev_attr_gpio_demo);
	
	pr_err("[]gpio_demo_probe end...\n");
	
	return 0;
	
}

static struct of_device_id gpio_demo_match_table[] = {
	{ .compatible = "sylon,gpio-demo"},
	{ }
};

static int gpio_demo_remove(struct platform_device *pdev)
{
	pr_err("[]gpio_demo_remove...\n");
	return 0;
}

static struct platform_driver gpio_demo_driver = {
	.driver = {
		.name = "gpio_demo",
		.owner = THIS_MODULE,
		.of_match_table = gpio_demo_match_table,
	},
	.probe = gpio_demo_probe,
	.remove = gpio_demo_remove,
};

static int gpio_demo_init(void)
{
	struct device *mydev;

	pr_err("[]gpio_demo_init start...\n");
	platform_driver_register(&gpio_demo_driver);
	
	major=register_chrdev(0,"gpiotest", &gpio_demo_ops);
	cls=class_create(THIS_MODULE, "gpio_demo_class");
	mydev = device_create(cls, 0, MKDEV(major,0),NULL,"gpio_device");
	if(sysfs_create_file(&(mydev->kobj), &dev_attr_gpio_demo.attr)){  
            return -1;
	}
	
	return 0;
}

static void gpio_demo_exit(void)
{
	pr_err("[]gpio_demo_exit...\n");
	platform_driver_unregister(&gpio_demo_driver);

	device_destroy(cls, MKDEV(major,0));
    class_destroy(cls);
    unregister_chrdev(major, "gpiotest");
}

module_init(gpio_demo_init);
module_exit(gpio_demo_exit);

MODULE_AUTHOR("123");
MODULE_DESCRIPTION("Device_create Driver");
MODULE_LICENSE("GPL");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值