DM355Éϰ´¼ü³ÌÐò ÊÕ²Ø
ÀûÓÃÖжϲ¶×½°´¼üÐÅÏ¢£¬ÑÓʱȥ¶¶ºó¼´¿É¶Á³ö
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "buttons" /* ¼ÓÔØÄ£Ê½ºó£¬Ö´ÐС±cat /proc/devices¡±ÃüÁî¿´µ½µÄÉ豸Ãû³Æ */
#define BUTTON_NR_DEVS 1
struct button_irq_desc {
int irq;
int pin;
int number;
char *name;
};
#define GPIO8 8
#define GPIO9 9
#define GPIO5 5
#define GPIO6 6
#define GPIO7 7
/* For registeration of charatcer device */
#define BUTTONS_STATUS_GET 1
static struct cdev c_dev;
/* device structure to make entry in device */
static dev_t dev;
static struct class_simple *af_class = NULL;
/* ÓÃÀ´Ö¸¶¨°´¼üËùÓõÄÍⲿÖжÏÒý½Å¼°Öжϴ¥·¢·½Ê½, Ãû×Ö */
static struct button_irq_desc button_irqs [] = {
{IRQ_DM355_GPIO8, GPIO8, 0, "KEY1"}, /* K1 */
{IRQ_DM355_GPIO9, GPIO9, 1, "KEY2"}, /* K2 */
{IRQ_DM355_GPIO5, GPIO5, 2, "KEY3"}, /* K3 */
{IRQ_DM355_GPIO6, GPIO6, 3, "KEY4"}, /* K4 */
{IRQ_DM355_GPIO7, GPIO7, 4, "KEY5"}, /* K5 */
};
/* °´¼ü±»°´ÏµĴÎÊý(׼ȷµØËµ£¬ÊÇ·¢ÉúÖжϵĴÎÊý) */
static volatile int key_values [] = {0, 0, 0, 0, 0};
/* µÈ´ý¶ÓÁÐ:
* µ±Ã»Óа´¼ü±»°´ÏÂʱ£¬Èç¹ûÓнø³Ìµ÷ÓÃdavinci_buttons_readº¯Êý£¬
* Ëü½«ÐÝÃß
*/
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
/* ÖжÏʼþ±êÖ¾, ÖжϷþÎñ³ÌÐò½«ËüÖÃ1£¬davinci_buttons_read½«ËüÇå0 */
static volatile int ev_press = 0;
static struct timer_list button_timer;
/* ÖжϷþÎñ³ÌÐò void *dev_idÏìÓ¦¹Ü½ÅµÄbutton_irqs[i] ÒòΪÿ¸ö¹Ü½ÅµÄÖж϶¼×¢²áÁËÏìÓ¦µÄbutton_irqs[i]
err = request_irq(button_irqs[i].irq, buttons_interrupt, NULL, button_irqs[i].name, (void *)&button_irqs[i]);*/
static irqreturn_t buttons_interrupt(int irq, void *dev_id,struct pt_regs *regs)
{
int i;
struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
//ÆÁ±Î°´¼üÖжÏ
button_timer.data=(unsigned long)button_irqs;
for (i = 0; i gpio_interrupt_disable(button_irqs[i].pin,TRIGGER_FALLING_EDGE );
}
button_timer.expires=jiffies+HZ/100;
add_timer(&button_timer);
return IRQ_RETVAL(IRQ_HANDLED);
}
static void button_timer_handler(unsigned long data)
{
int i;
int KeyStatus=0;
struct button_irq_desc *button_irqs = (struct button_irq_desc *)data;
KeyStatus=gpio_get_value(button_irqs->pin);
if(KeyStatus==0)
{
key_values[button_irqs->number] += 1;
printk("the button %d was push down\n",button_irqs->number);
ev_press = 1; /* ±íʾÖжϷ¢ÉúÁË */
wake_up_interruptible(&button_waitq); /* »½ÐÑÐÝÃߵĽø³Ì */
}
//ÖØÐ¿ªÆô°´¼üÖжÏ
for (i = 0; i gpio_interrupt_enable(button_irqs[i].pin,TRIGGER_FALLING_EDGE );
}
}
/* Ó¦ÓóÌÐò¶ÔÉ豸Îļþ/dev/buttonsÖ´ÐÐopen(...)ʱ£¬
* ¾Í»áµ÷ÓÃdavinci_buttons_openº¯Êý
*/
static int davinci_buttons_open(struct inode *inode, struct file *file)
{
int i;
int err;
__REG(0x01c4000c)&=0xf1ffffff;
for (i = 0; i
/* Enable interrupt generation from GPIO Bank 0 (GPIO0-GPIO15) */
gpio_interrupt_bank_enable(button_irqs[i].pin);
/* Configure GPIO1 as an input */
gpio_set_direction(button_irqs[i].pin, GIO_DIR_INPUT);
/* Configure GPIO1 to generate an interrupt on falling edge only */
gpio_interrupt_enable(button_irqs[i].pin,TRIGGER_FALLING_EDGE );
gpio_interrupt_disable(button_irqs[i].pin, TRIGGER_RISING_EDGE);
// ×¢²áÖжϴ¦Àíº¯Êý
err = request_irq(button_irqs[i].irq, buttons_interrupt, NULL,
button_irqs[i].name, (void *)&button_irqs[i]);
if (err)
break;
}
if (err) {
// ÊÍ·ÅÒѾע²áµÄÖжÏ
i--;
for (; i >= 0; i--) {
disable_ir