7279键盘驱动程序

来源:互联网 发布:码字精灵 mac 编辑:程序博客网 时间:2024/05/16 05:15

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/delay.h>

#include <linux/ioport.h>

#include <linux/sched.h>

#include <linux/slab.h>

#include <linux/smp_lock.h>

#include <linux/errno.h>

#include <linux/init.h>

#include <linux/timer.h>

#include <linux/list.h>

#include <linux/interrupt.h>  

#include <linux/poll.h>

#include <linux/platform_device.h>

#include <linux/vmalloc.h>

#include <asm/io.h>

#include <asm/irq.h>

#include <linux/irq.h>

#include <asm/system.h>

#include <asm/unaligned.h>

#include <asm/dma.h>

#include <linux/cdev.h>

#include <linux/device.h>

#include <linux/miscdevice.h>

#include <linux/poll.h>

#include <asm/arch/io.h>

#include <asm/arch/irqs.h>

#include <asm/arch/regs-gpio.h>

#include <asm/arch/regs-mem.h>

MODULE_LICENSE("Dual BSD/GPL");

 

/*************************************************************************/

 

#define  cmd_reset 0xa4                                   

#define  cmd_test  0xbf                                   

#define  cmd_read  0x15                                   

#define  decode1   0xc8                                    

 

#define  key7279_base 0x20000004

static void __iomem *base_addr;

#define base_key7279 base_addr

/*************************************************************************/

 

void                short_delay (void);

void                long_delay(void);

unsigned char        read7279(void);

void                write7279(unsigned char,unsigned char);

void                send_byte(unsigned char);

unsigned char        receive_byte(void);

static struct class     *Key7279_class;

 

 

/*************************************************************************/

 

/*

--HD7279A鐨勬暟鎹槸閫氳繃CPLD浣滀负涓嶴3C241O閫氳鐨勬帴鍙o紝CPU閫氳繃鍦ㄧ浉搴斿湴鍧€涓婄殑璇诲啓CPLD锛屽嵆鍙笌HD7279

  杩涜鏈夋晥鐨勯€氳銆傜敱浜嶤PLD鏄€氳繃CPU鐨凬GCS4閫夋嫨鐨勶紝鎵€浠ュ悜CPLD璇诲啓鍧囬渶瑕佷娇鐢∟GCS4銆備笅闈负鍏蜂綋鐨?

  浣跨敤鏂规硶銆?

 

--鍚戝湴鍧€ 0x20000004 閲屽啓0x01锛岃〃绀洪€変腑HD7279锛屽嵆CS7279='0

--浠庡湴鍧€ 0x20000004 涓啓0x02锛岃〃绀烘湭閫変腑HD7279锛屽嵆CS7279='1

 

--鍚戝湴鍧€ 0x20000004 閲屽啓0x05锛岃〃绀烘暟鎹祦浠嶤PLD鍒癏D7279

--浠庡湴鍧€ 0x20000004 涓啓0x06锛岃〃绀烘暟鎹祦浠嶩D7279鍒癈PLD

 

*/

 

#define   clrcs1   __raw_writel(0x01,base_key7279)         /* CS 鏈夋晥 */

#define   setcs1   __raw_writel(0x02,base_key7279)         /* CS 鏃犳晥 */        

 

#define s_clr      __raw_writel(0x05,base_key7279)         /* DATA PIN 鏂瑰悜涓鸿緭鍏?*/

#define s_set      __raw_writel(0x06,base_key7279)         /* DATA PIN 鏂瑰悜涓鸿緭鍑?*/

 

#define IRQ_HD7279_ini  s3c2410_gpio_cfgpin(S3C2410_GPF5,S3C2410_GPF5_EINT5);

 

#define   clrclk   s3c2410_gpio_setpin(S3C2410_GPE13,0)

#define   setclk   s3c2410_gpio_setpin(S3C2410_GPE13,1)

 

#define   clrdat   s3c2410_gpio_setpin(S3C2410_GPE12,0)

#define   setdat   s3c2410_gpio_setpin(S3C2410_GPE12,1)

 

#define HD7279_DAT s3c2410_gpio_getpin(S3C2410_GPE12)

 

/*************************************************************************/

 

#define KEYBOARD_MAJOR 50

#define Key7279_GETKEY 0

 

int KeyValue;

int key_isopen;

unsigned char key_buf = 0xff;

 

/************************************************************************

- 鍑芥暟鍚嶇О : void long_delay(void)

- 鍑芥暟璇存槑 : 闀垮欢鏃剁▼搴?

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 鏃?

*************************************************************************/

 

void long_delay(void)

unsigned char i;

   for (i=0;i<250;i++)    

   {

   }

}

 

/************************************************************************

- 鍑芥暟鍚嶇О : void short_delay(void)

- 鍑芥暟璇存槑 : 鐭欢鏃剁▼搴?

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 鏃?

*************************************************************************/

 

void short_delay(void)

int i;

  for(i=0;i<150;i++)

  {

  }

 

}

 

/************************************************************************

- 鍑芥暟鍚嶇О : Key7279_Close

- 鍑芥暟璇存槑 : 鍏抽棴閿洏璁惧

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 0

*************************************************************************/

 

static int Key7279_Close(struct inode * inode, struct file * file)

{

        printk("Close successful/n");

key_isopen = 0;

return 0;

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Key7279_Open

- 鍑芥暟璇存槑 : 鎵撳紑閿洏璁惧

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 0

************************************************************************/

 

static int Key7279_Open(struct inode * inode, struct file * file)

{

      printk("Open successful/n");

      key_isopen++;

      return 0;

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Key7279_Read

- 鍑芥暟璇存槑 : 鎵撳紑閿洏璁惧

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 0

************************************************************************/

 

static int Key7279_Read(struct file *fp, char *buf, size_t count)

{

    put_user(key_buf, buf);

    key_buf = 0xff;

    return 1;

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Key7279_getkey

- 鍑芥暟璇存槑 : 鑾峰彇涓€涓敭鍊?

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : -1

************************************************************************/

 

static int key7279_getkey(void)

{

   int  i,j;

   //enable_irq(49);

   KeyValue = 0xff;

   for (i=0;i<3000;i++)

   for (j=0;j<900;j++);

   return KeyValue;     /* 濡傛灉鏈夋寜閿寜涓嬶紝杩斿洖閿€?*/

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : void send_byte(unsigned char out_byte )

- 鍑芥暟璇存槑 : 鍚?279鍙戦€佷竴涓瓧鑺傜殑绋嬪簭

- 杈撳叆鍙傛暟 : out_byte

- 杈撳嚭鍙傛暟 : 鏃?

************************************************************************/

 

void send_byte(unsigned char out_byte )

{

unsigned short  i;

clrcs1;

         s_clr;

        s3c2410_gpio_cfgpin(S3C2410_GPE12,S3C2410_GPE12_OUTP);

        long_delay(); 

        short_delay();

         short_delay();

  for (i=0;i<8;i++)

    {   

     if (0x80 == (out_byte & 0x80))    setdat;

           elseclrdat;

         setclk;

         short_delay();

         clrclk;

         short_delay();

         out_byte <<= 1;

   }

  short_delay();

  clrdat;

 }

 

/***********************************************************************

- 鍑芥暟鍚嶇О : unsigned char receive_byte (void)

- 鍑芥暟璇存槑 : 鍚?279鎺ユ敹涓€涓瓧鑺傜殑绋嬪簭

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : in_byte

************************************************************************/

 

unsigned char receive_byte (void)    

{

   unsigned char i,in_byte=0;

        s_set;

        s3c2410_gpio_cfgpin(S3C2410_GPE12,S3C2410_GPE12_INP);

   long_delay();

        for(i=0;i<8;i++)

         {

      setclk;

      short_delay();

      in_byte <<= 1;

 

      if (HD7279_DAT) 

in_byte |= 1;

 clrclk;

      short_delay();

         }

       s_clr;

       clrdat;

       s3c2410_gpio_cfgpin(S3C2410_GPE12,S3C2410_GPE12_OUTP);

       short_delay();

       printk("Get a Key %x/r/n",in_byte);

       return(in_byte);

}

 

 

/***********************************************************************

- 鍑芥暟鍚嶇О : unsigned char read7279(unsigned char comand)

- 鍑芥暟璇存槑 : 璇婚敭鐩樻寚浠ょ▼搴?

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : in_byte

************************************************************************/

 

static unsigned char read7279(void)

{

  send_byte(cmd_read);

   return (receive_byte());

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : void write7279 (unsigned char cmd, unsigned char dat)

- 鍑芥暟璇存槑 : 鍐欓敭鐩樻寚浠ょ▼搴?

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : in_byte

************************************************************************/

 

void write7279 (unsigned char cmd, unsigned char dat)

{

send_byte(cmd);

 send_byte(dat);

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Key7279_ISR

- 鍑芥暟璇存槑 : 閿洏鏈嶅姟瀛愮▼搴?

- 杈撳叆鍙傛暟 : irq,dev_id,regs

- 杈撳嚭鍙傛暟 : -1

************************************************************************/

 

static irqreturn_t Key7279_ISR(int irq,void* dev_id)

{

   int i;

   disable_irq(49);

   for(i=0;i<100;i++);

   KeyValue = read7279();

   switch (KeyValue)

   {

   case 0:

     KeyValue = 0x00;

     break;

            case 1:

              KeyValue = 0x01;

     break;

            case 2:

              KeyValue = 0x02;

              break;

            case 3:

              KeyValue = 0x03;

              break;

            case 8:

     KeyValue = 0x04;

              break;

            case 9:

              KeyValue = 0x5;

              break;

            case 10:

              KeyValue = 0x06;

              break;

            case 11:

              KeyValue = 0x07;

              break;

            case 4:

              KeyValue = 0x08;

              break;

            case 5:

              KeyValue = 0x09;

              break;

            case 6:

              KeyValue = 0x0a;

              break;

            case 7:

              KeyValue = 0x0b;

              break;

            case 12:

              KeyValue = 0xc;

              break;

            case 13:

              KeyValue = 0x0d;

              break;

            case 14:

              KeyValue = 0x0e;

              break;

            case 15:

              KeyValue = 0x0f;

              break;

            default:

              break;

   }

 

   write7279(decode1+4,KeyValue % 16);

   write7279(decode1+5,KeyValue / 16); 

 

   key_buf = (unsigned char)KeyValue;

   printk("KeyValue = %d/n",KeyValue);

   enable_irq(49);

   return IRQ_HANDLED;   

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Setup_Key7279

- 鍑芥暟璇存槑 : 閿洏璁惧鐨勭‖浠跺垵濮嬪寲鍑芥暟

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 鏃?

************************************************************************/

 

void Setup_Key7279(void)

{

   int i,value;

 

   value=__raw_readl(S3C2410_BWSCON);              /* set the bank4 databus is 8 bitwidth */

   value=value&(~(3<<16));

   __raw_writel(value,S3C2410_BWSCON);

   printk("set_up/n");

   IRQ_HD7279_ini;

 

   set_irq_type(49 , IRQT_FALLING);                 /* set falling edge triger */

 

   s3c2410_gpio_pullup(S3C2410_GPE12,0);

   s3c2410_gpio_pullup(S3C2410_GPE13,0);

   s3c2410_gpio_pullup(S3C2410_GPF5,0);

   s3c2410_gpio_cfgpin(S3C2410_GPE13,S3C2410_GPE13_OUTP);

 

   send_byte(cmd_reset);

   setcs1;

   enable_irq(49);

   printk("setup /n");

   for(i=0;i<1000;i++);

   write7279(decode1+3,0xf);

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Key7279_Ioctl

- 鍑芥暟璇存槑 : 閿洏鎺у埗

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 0

************************************************************************/

 

static int Key7279_Ioctl(struct inode *inode,struct file *file,unsigned int cmd, unsigned long arg)

{

switch(cmd) 

 {

  case Key7279_GETKEY:

return key7279_getkey();

           default:

                 printk("Unkown Keyboard Command ID./n");

          }

    return 0;

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : struct file_operations Key7279_fops

- 鍑芥暟璇存槑 : 鏂囦欢缁撴瀯

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 鏃?

************************************************************************/

 

struct file_operations Key7279_fops = 

{

.open = Key7279_Open, 

.ioctl = Key7279_Ioctl, 

.release = Key7279_Close,

.read = Key7279_Read,

};

 

/***********************************************************************

- 鍑芥暟鍚嶇О : int Key7279Init(void)

- 鍑芥暟璇存槑 : 娉ㄥ唽閿洏璁惧锛岃皟鐢ㄥ垵濮嬪寲鍑芥暟

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : -1

************************************************************************/

 

int __init Key7279_Init(void)

{

   int result;

   base_addr = ioremap(key7279_base,4);

   printk("/n Registering Keyboard Device/t--- >/t");

 

   result = register_chrdev(KEYBOARD_MAJOR, "Key7279", &Key7279_fops);//脳垄虏谩脡猫卤啪

 

   if (result<0)

 

{

printk(KERN_INFO"[FALLED: Cannot register Key7279_driver!]/n");

return result;

}

else

printk("[OK]/n");

 

   printk("Initializing Key7279 Device/t--- >/t");

 

   Setup_Key7279();

 

   if (request_irq(49,Key7279_ISR,0,"Key7279","88"))

  {

   printk(KERN_INFO"[FALLED: Cannot register Key7279_Interrupt!]/n");

return -EBUSY;

  }

else

printk("[OK]/n");

   printk("Key7279 Driver Installed./n");

 

   Key7279_class=class_create(THIS_MODULE,"Key7279");

   class_device_create(Key7279_class,NULL,MKDEV(KEYBOARD_MAJOR,0),NULL,"key7279");

 

   return 0;

}

 

/***********************************************************************

- 鍑芥暟鍚嶇О : Kbd7279_Close

- 鍑芥暟璇存槑 : 鍏抽棴閿洏璁惧

- 杈撳叆鍙傛暟 : 鏃?

- 杈撳嚭鍙傛暟 : 0

************************************************************************/

 

void __exit Key7279_Exit(void)

{

   unregister_chrdev(KEYBOARD_MAJOR, "Key7279");

 

   free_irq(49,"88");

 

   class_device_destroy(Key7279_class,MKDEV(KEYBOARD_MAJOR,0));

   class_destroy(Key7279_class);

   printk("You have uninstall The Key7279 Driver succesfully,/n if you want to install again,please use the insmod command /n");

}

 

module_init(Key7279_Init);

module_exit(Key7279_Exit);

原创粉丝点击