一、使用struct pin_desc 管理按键的值
1.定义结构体
2.将前面我们申请中断时写的(void *)1修改为 &pins_desc[n]
在ioctl中,设置中断中修改
在key_release中释放中修改
3.在中断程序中利用我们定义的struc pins_desc判断并得到按键的值
4.得到按键键值后,唤醒程序,在read函数中返回键值
附上驱动源程序:
1 /******************************
2 linux key_query
3 *****************************/
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18
19 #include 'mx257_gpio.h'
20 #include 'mx25_pins.h'
21 #include 'iomux.h'
22
23 #define Driver_NAME 'key_interrupt'
24 #define DEVICE_NAME 'key_interrupt'
25
26 #define GPIO2_21 MX25_PIN_CLKO
27 #define GPIO3_15 MX25_PIN_EXT_ARMCLK
28 #define GPIO2_10 MX25_PIN_A24
29 #define GPIO2_11 MX25_PIN_A25
30 #define GPIO2_8 MX25_PIN_A22
31 #define GPIO2_9 MX25_PIN_A23
32 #define GPIO2_6 MX25_PIN_A20
33 #define GPIO2_7 MX25_PIN_A21
34 //command
35 #define key_input 0
36 #define version 1
37 //定义各个按键按下的键值
38 struct pin_desc{
39 unsigned int pin;
40 unsigned int key_val;
41 };
42 //当按键按下时,键值分别为 以下值
43 struct pin_desc pins_desc[8] = {
44 {GPIO2_6, 0x01},
45 {GPIO2_7, 0x02},
46 {GPIO2_8, 0x03},
47 {GPIO2_9, 0x04},
48 {GPIO2_10, 0x05},
49 {GPIO2_11, 0x06},
50 {GPIO2_21, 0x07},
51 {GPIO3_15, 0x08},
52 };
53 //定义一个全局变量,用于保存按下的键值
54 static unsigned int key_val;
55
56 //interrupt head
57 static DECLARE_WAIT_QUEUE_HEAD(key_interrupt_wait);
58 static volatile unsigned char ev_press;
59
60 static int major=0;
61
62 //auto to create device node
63 static struct class *drv_class = NULL;
64 static struct class_device *drv_class_dev = NULL;
65
66
67 /* 应用程序对设备文件/dev/key_query执行open(...)时,
68 * 就会调用key_open函数*/
69 static int key_open(struct inode *inode, struct file *file)
70 {
71 printk('<0>function open!nn');
72
73 return 0;
74 }
75
76 /* 中断程序key_irq */
77 static irqreturn_t key_irq(int irq, void *dev_id)
78 {
79 struct pin_desc * pindesc = (struct pin_desc *)dev_id;
80 //发生了中断
81 //printk('<0>function interrupt key_irq!nn');
82 //获取按键键值
83 if(gpio_get_value(IOMUX_TO_GPIO(pindesc->pin))){
84 /* 按下 */
85 key_val = pindesc->key_val;
86 }else{
87 key_val = 0x80 | pindesc->key_val;
88 }
89 printk('<0>get key 0x%x',key_val);
90 ev_press = 1;
91 wake_up_interruptible(&key_interrupt_wait);
92
93 return IRQ_RETVAL(IRQ_HANDLED);
94 }
95
96
97 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
98 {
99 int ret;
100 //如果按键没有按下,没有中断,休眠
101 wait_event_interruptible(key_interrupt_wait,ev_press);
102
103 ret = copy_to_user(buff,&key_val,sizeof(key_val));
104 if(ret){
105 ;
106 }
107 ev_press = 0;
108 return sizeof(key_val);
109
110 //int cnt=0;
111 //unsigned char key_vals[8];
112
113 /*
114 // reading the pins value
115 key_vals[0] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_6)) ? 1 : 0;
116 key_vals[1] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_7)) ? 1 : 0;
117 key_vals[2] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_8)) ? 1 : 0;
118 key_vals[3] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_9)) ? 1 : 0;
119 key_vals[4] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_10)) ? 1 : 0;
120 key_vals[5] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_11)) ? 1 : 0;
121 key_vals[6] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_21)) ? 1 : 0;
122 key_vals[7] = gpio_get_value(IOMUX_TO_GPIO(GPIO3_15)) ? 1 : 0;
123
124 //printk('<0>%04d key pressed: %d %d %d %d %d %d %d %dn',cnt++,key_vals[0],key_vals[1],key_vals[2],key_vals[3],key_vals[4],key_vals[5],key_vals[6],key_vals[7]);
125 */
126 }
127
128 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
129 {
130 printk('<0>function write!nn');
131
132 return 1;
133 }
134
135 static int key_release(struct inode *inode, struct file *filp)
136 {
137 printk('<0>function release!nn');
138 //释放中断
139 free_irq(IOMUX_TO_IRQ(GPIO2_21), &pins_desc[6]);
140 //free_irq(IOMUX_TO_IRQ(GPIO3_15),&pins_desc[7]);
141 free_irq(IOMUX_TO_IRQ(GPIO2_11), &pins_desc[5]);
142 free_irq(IOMUX_TO_IRQ(GPIO2_10), &pins_desc[4]);
143 free_irq(IOMUX_TO_IRQ(GPIO2_9), &pins_desc[3]);
144 //free_irq(IOMUX_TO_IRQ(GPIO2_8), &pins_desc[2]);
145 free_irq(IOMUX_TO_IRQ(GPIO2_7), &pins_desc[1]);
146 free_irq(IOMUX_TO_IRQ(GPIO2_6), &pins_desc[0]);
147 return 0;
148 }
149
150 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
151 {
152 int ret;
153 printk('<0>function ioctl!nn');
154 switch (command) {
155 case key_input:
156 //设置所有的引脚为输入
157 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21));
158 gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15));
159 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));
160 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));
161 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8));
162 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));
163 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6));
164 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7));
165 printk('<0>have setting all pins to gpio input mod !n');
166 //设置GPIO引脚为上拉模式
167 mxc_iomux_set_pad(GPIO2_6, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
168 mxc_iomux_set_pad(GPIO2_7, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
169 //mxc_iomux_set_pad(GPIO2_8, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
170 mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
171 mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
172 mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
173 mxc_iomux_set_pad(GPIO2_21, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
174 //mxc_iomux_set_pad(GPIO3_15, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
175
176 //设置GPIO引脚中断 ,下降沿触发
177 request_irq(IOMUX_TO_IRQ(GPIO2_6), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_6', &pins_desc[0]);
178 request_irq(IOMUX_TO_IRQ(GPIO2_7), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_7', &pins_desc[1]);
179 request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_9', &pins_desc[3]);
180 request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_10', &pins_desc[4]);