Linux下简单4*4键盘驱动

#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/init.h> /* __init __exit */

#include <linux/types.h> /* size_t */
#include <linux/fs.h> /* file_operation */
#include <asm/uaccess.h> /* copy_to_user, copy_from_user */
#include <asm/arch/S3C2410.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/delay.h>
#include <linux/kfifo.h>

#define DRIVER_NAME "keyDriver"

#ifdef DEBUG
#define PRINTK(fmt, arg...)  printk(KERN_NOTICE fmt, ##arg)
#else
#define PRINTK(fmt, arg...)
#endif

 

spinlock_t buff_lock;
struct kfifo *buffer;
extern void init_IO();
extern int re_IO();
static int keyDriver_Major = 0;  /* Driver Major Number */

static void int_func(int irq, void *dev_id, struct pt_regs *regs)
{
 char pestion=0;
 int key=0;
 key = re_IO();
 key = key&0xf0;
 key = key>>4;
 switch (irq)
 {
  case 3:
   pestion = 0xA0;
   break;
  case 2:
   pestion = 0xB0;
   break;
  case 1:
   pestion = 0xC0;
   break;
  case 0:
   pestion = 0xD0;
  default :
   break;
 }
 switch (key)
 {
  case 0x08:
   pestion |= 0x01;
   break;
  case 0x04:
   pestion |= 0x02;
   break;
  case 0x02:
   pestion |= 0x03;
   break;
  case 0x01:
   pestion |= 0x04;
   break;
  default :
          break;
 }
 PRINTK("pes=%x/n", pestion);
 kfifo_put(buffer, &pestion, sizeof(pestion));
 init_IO();
}

int re_IO()
{
 int gpiodata=0;
 GPFDAT = 0;
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F0);
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F1);
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F2);
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F3);

 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_DIS|GPIO_F4);
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_DIS|GPIO_F5);
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_DIS|GPIO_F6);
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_DIS|GPIO_F7);
 udelay(300);
 write_gpio_reg(GPIO_F0,0x0f);
 udelay(200);
 gpiodata = read_gpio_reg(GPIO_F0);
 return gpiodata;
}

void init_IO()
{
 GPFDAT = 0;
 GPFUP = 0;
 PRINTK("io init ok_mxd/n");
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_EN|GPIO_F0);
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_EN|GPIO_F1);
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_EN|GPIO_F2);
 set_gpio_ctrl(GPIO_MODE_IN|GPIO_PULLUP_EN|GPIO_F3);

 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F4);
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F5);
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F6);
 set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|GPIO_F7);
 udelay(200);
 GPFDAT = 0x0f;

 set_external_irq(IRQ_EINT0, EXT_FALLING_EDGE, 0);
 set_external_irq(IRQ_EINT1, EXT_FALLING_EDGE, 0);
 set_external_irq(IRQ_EINT2, EXT_FALLING_EDGE, 0);
 set_external_irq(IRQ_EINT3, EXT_FALLING_EDGE, 0); 

 request_irq(IRQ_EINT0, int_func,SA_INTERRUPT, "GPF", int_func); 
 request_irq(IRQ_EINT1, int_func,SA_INTERRUPT, "GPF", int_func);
 request_irq(IRQ_EINT2, int_func,SA_INTERRUPT, "GPF", int_func);
 request_irq(IRQ_EINT3, int_func,SA_INTERRUPT, "GPF", int_func);
// PRINTK("out%x-%x-%x/n", GPFCON, GPFDAT, GFPUP);
}

static int keyDriver_open(struct inode *inode, struct file *filp)
{
 MOD_INC_USE_COUNT;
 enable_irq(IRQ_EINT0);
 enable_irq(IRQ_EINT1);
 enable_irq(IRQ_EINT2);
 enable_irq(IRQ_EINT3);
 PRINTK("myDriver open calkey!/n");
 return 0;
}

static int keyDriver_release(struct inode *inode, struct file *filp)
{
 MOD_DEC_USE_COUNT;
 PRINTK("myDriver release calkey!/n");
 return 0;
}

static ssize_t keyDriver_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
 char key=0;
 kfifo_get(buffer, &key, sizeof(key));
 copy_to_user(buf, &key, sizeof(key));
 return sizeof(key);
}

static struct file_operations keyDriver_fops = {
 owner:  THIS_MODULE,
 read:  keyDriver_read,
 open:  keyDriver_open,
 release: keyDriver_release,
};

/* Module Init & Exit function */

#ifdef CONFIG_DEVFS_FS
devfs_handle_t devfs_keyDriver_dir;
devfs_handle_t devfs_keyDriver_raw;
#endif

static int __init keyModule_init(void)
{
 buffer = kfifo_alloc(128, GFP_KERNEL, &buff_lock);
 PRINTK("myModule_init/n");
 init_IO();
 keyDriver_Major = register_chrdev(0, DRIVER_NAME, &keyDriver_fops);
 if(keyDriver_Major < 0)
 {
  PRINTK("register char device fail!/n");
  return keyDriver_Major;
 }
 PRINTK("register myDriver OK! Major = %d/n", keyDriver_Major);
#ifdef CONFIG_DEVFS_FS
 devfs_keyDriver_dir = devfs_mk_dir(NULL, "key", NULL);
 devfs_keyDriver_raw = devfs_register(devfs_keyDriver_dir, "key0", DEVFS_FL_DEFAULT, keyDriver_Major, 0, S_IFCHR | S_IRUSR | S_IWUSR, &keyDriver_fops, NULL);
 PRINTK("add dev file to devfs OK!/n");
#endif
 return 0;
}

static void __exit keyModule_exit(void)
{
 PRINTK("myModule_exit/n");

 disable_irq(IRQ_EINT0);
 disable_irq(IRQ_EINT1);
 disable_irq(IRQ_EINT2);
 disable_irq(IRQ_EINT3);

 

 free_irq(IRQ_EINT0, NULL);
 free_irq(IRQ_EINT1, NULL);
 free_irq(IRQ_EINT2, NULL);
 free_irq(IRQ_EINT3, NULL);
 
 kfifo_free(buffer);
 if(keyDriver_Major > 0)
 {
#ifdef CONFIG_DEVFS_FS
  devfs_unregister(devfs_keyDriver_raw);
  devfs_unregister(devfs_keyDriver_dir);
#endif
  unregister_chrdev(keyDriver_Major, DRIVER_NAME);
 }
 return;
}

module_init(keyModule_init);
module_exit(keyModule_exit);

 

这个是在试验箱上跑的,不过键盘去抖功能没加的,仅供测试的。

S3C2410, linux 2.4,GPIO_F0~F3和F4~F7端口.

呵呵~首次发一篇啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值