?? arm7279_driver.c
字號:
?
#include <linux/config.h>
#include <linux/utsname.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/timer.h>#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm-arm/arch-s3c2410/irqs.h>
#include <asm-arm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <linux/poll.h>
#include <asm/arch/io.h>
/********************************** 送給HD7279指令 *************************************/
#define cmd_reset 0xa4
#define cmd_test 0xbf
#define cmd_read 0x15
#define decode1 0xc8
/********************************** 函數定義 ********************************************/
void long_delay (void);
void short_delay (void);
void write7279 (unsigned char,unsigned char);
unsigned char read7279 (unsigned char);
void send_byte (unsigned char);
unsigned char receive_byte (void);
int kbd_isopen;unsigned char kbd_buf = 0xFF;
/******************************** HD7279A的使用原理說明 ***************************************/
/*
--HD7279A的數據是通過CPLD作為與S3C241O通訊的接口,CPU通過在相應地址上的讀寫CPLD,即可與HD7279
進行有效的通訊。由于CPLD是通過CPU的NGCS4選擇的,所以向CPLD讀寫均需要使用NGCS4。下面為具體的
使用方法。
--向地址 0x20000004 里寫0X01,表示選中HD7279,即CS7279='0
--從地址 0x20000004 中寫0x02,表示未選中HD7279,即CS7279='1
--向地址 0x20000004 里寫0x05,表示數據流從CPLD到HD7279
--從地址 0x20000004 中寫0x06,表示數據流從HD7279到CPLD
*/
/******************************** 7279時鐘模擬信號 ***************************************/
#define clrcs1 *((volatile unsigned char *)(CPLD_BASE + 0x4)) = 0x01
#define setcs1 *((volatile unsigned char *)(CPLD_BASE + 0x4)) = 0x02
#define s_clr *((volatile unsigned char *)(CPLD_BASE + 0x4)) = 0x05
#define s_set *((volatile unsigned char *)(CPLD_BASE + 0x4)) = 0x06
#define clk (GPIO_MODE_OUT | GPIO_PULLUP_EN | GPIO_E13)
#define dat (GPIO_MODE_OUT | GPIO_PULLUP_EN | GPIO_E12)
#define setclk write_gpio_bit(clk, 1) #define clrclk write_gpio_bit(clk, 0) #define setdat write_gpio_bit(dat, 1) #define clrdat write_gpio_bit(dat, 0)
//CPLD_BASE的定義在/includ/asm-arm/arch-s3c2410/smdk.h內.#define KEYBOARD_MAJOR 50
#define Kbd7279_GETKEY 0
int KeyValue;
/*
*************************************************************************************************************
- 函數名稱 : Kbd7279_Close
- 函數說明 : 關閉鍵盤設備
- 輸入參數 : 無
- 輸出參數 : 0
*************************************************************************************************************
*/
static int Kbd7279_Close(struct inode * inode, struct file * file){
printk("Close successful\n");
kbd_isopen = 0;
return 0;}
/*
*************************************************************************************************************
- 函數名稱 : Kbd7279_Open
- 函數說明 : 打開鍵盤設備
- 輸入參數 : 無
- 輸出參數 : 0
*************************************************************************************************************
*/static int Kbd7279_Open(struct inode * inode, struct file * file){ printk("Open successful\n"); kbd_isopen++;
return 0;}/**************************************************************************************************************- 函數名稱 : Kbd7279_Read- 函數說明 : 打開鍵盤設備- 輸入參數 : 無- 輸出參數 : 0**************************************************************************************************************/
static int Kbd7279_Read(struct file *fp, char *buf, size_t count)
{ put_user(kbd_buf, buf); kbd_buf = 0xFF; return 1;
}
/*
*************************************************************************************************************
- 函數名稱 : kbd7279_getkey
- 函數說明 : 獲取一個鍵值
- 輸入參數 : 無
- 輸出參數 : -1
*************************************************************************************************************
*/static int kbd7279_getkey(void){ int i,j;
enable_irq(33);
KeyValue = 0xff; for (i=0;i<3000;i++) for (j=0;j<900;j++); return KeyValue; //如果有按鍵按下,返回鍵值}
/*
*************************************************************************************************************
- 函數名稱 : Kbd7279_ISR
- 函數說明 : 鍵盤服務子程序
- 輸入參數 : irq,dev_id,regs
- 輸出參數 : -1
*************************************************************************************************************
*/static void Kbd7279_ISR(int irq,void* dev_id,struct pt_regs * regs){ int i;
disable_irq(33); for(i=0;i<100;i++);
KeyValue = read7279(cmd_read);
switch (KeyValue) { case 8: KeyValue = 0x4; break; case 9: KeyValue = 0x5; break; case 10: KeyValue = 0x6; break; case 11: KeyValue = 0x7; break; case 4: KeyValue = 0x8; break; case 5: KeyValue = 0x9; break; case 6: KeyValue = 0xa; break; case 7: KeyValue = 0xb; break; default: break; } write7279(decode1+5,KeyValue/16*8);
write7279(decode1+4,KeyValue & 0x0f);
kbd_buf = (unsigned char)KeyValue;
printk("KeyValue = %d\n",KeyValue); }
/*
*************************************************************************************************************
- 函數名稱 : Setup_kbd7279
- 函數說明 : 鍵盤設備的硬件初始化函數
- 輸入參數 : 無
- 輸出參數 : 無
*************************************************************************************************************
*/void Setup_Kbd7279(void){ int i;
BWSCON &=(~(3<<16)); // set the bank4 databus is 8 bitwidth /* GPE13: CLK, OUTPUT */ set_gpio_ctrl(clk); /* GPE12: DATA, OUTPUT */ set_gpio_ctrl(dat); set_gpio_ctrl(GPIO_F5|GPIO_MODE_EINT);
//set EINT MODE set_external_irq(33,2,0); //set falling edge triger for(i=0;i<100;i++);}
//其他選項省略/*
*************************************************************************************************************
- 函數名稱 : Kbd7279_Ioctl
- 函數說明 : 鍵盤控制
- 輸入參數 : 無
- 輸出參數 : 0
*************************************************************************************************************
*/static int Kbd7279_Ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg){// int i; switch(cmd) { case Kbd7279_GETKEY:
return kbd7279_getkey();
default: printk("Unkown Keyboard Command ID.\n"); } return 0;}
/*
*************************************************************************************************************
- 函數名稱 : struct file_operations Uart2_fops
- 函數說明 : 文件結構
- 輸入參數 : 無
- 輸出參數 : 無
*************************************************************************************************************
*/
struct file_operations Kbd7279_fops =
{ open: Kbd7279_Open, //打開設備文件 ioctl: Kbd7279_Ioctl, //設備文件其他操作 release: Kbd7279_Close, //關閉設備文件 read: Kbd7279_Read, //讀取設備文件};
/*
*************************************************************************************************************
- 函數名稱 : int Kbd7279Init(void)
- 函數說明 : 注冊鍵盤設備,調用初始化函數
- 輸入參數 : 無
- 輸出參數 : -1
*************************************************************************************************************
*/int __init Kbd7279_Init(void){ int result; printk("\n Registering Kbdboard Device\t--- >\t"); result = register_chrdev(KEYBOARD_MAJOR, "Kbd7279", &Kbd7279_fops);//注冊設備
if (result<0) { printk(KERN_INFO"[FALLED: Cannot register Kbd7279_driver!]\n"); return result; } else printk("[OK]\n");
printk("Initializing HD7279 Device\t--- >\t"); Setup_Kbd7279();
if (request_irq(33,Kbd7279_ISR,0,"Kbd7279","88")) { printk(KERN_INFO"[FALLED: Cannot register Kbd7279_Interrupt!]\n"); return -EBUSY; } else printk("[OK]\n"); printk("Kbd7279 Driver Installed.\n"); return 0;}
//其他選項省略
/*
*************************************************************************************************************
- 函數名稱 : 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++)
{
}
}
/*
*************************************************************************************************************
- 函數名稱 : void send_byte(unsigned char out_byte )
- 函數說明 : 向7279發送一個字節的程序
- 輸入參數 : out_byte
- 輸出參數 : 無
*************************************************************************************************************
*/
void send_byte(unsigned char out_byte )
{
unsigned short i;
clrcs1;
s_clr; long_delay();
for (i=0;i<8;i++)
{
if (0x80 == (out_byte & 0x80))
{
setdat;
}
else
{
clrdat;
}
setclk;
short_delay();
clrclk;
short_delay();
out_byte <<= 1;
}
short_delay();
clrdat;
}
/*
*************************************************************************************************************
- 函數名稱 : unsigned char receive_byte (void)
- 函數說明 : 向7279接收一個字節的程序
- 輸入參數 : 無
- 輸出參數 : in_byte
*************************************************************************************************************
*/
unsigned char receive_byte (void)
{
unsigned char i,in_byte=0; s_set; set_gpio_ctrl(GPIO_MODE_IN | GPIO_PULLUP_EN | GPIO_E12); long_delay(); for(i=0;i<8;i++) { setclk; short_delay(); in_byte <<= 1; if (read_gpio_bit(GPIO_E12)&0x01) { in_byte |= 1; } clrclk; short_delay(); } s_clr; set_gpio_ctrl(GPIO_MODE_OUT | GPIO_PULLUP_EN | GPIO_E12); clrdat; short_delay(); return(in_byte);}
/*
*************************************************************************************************************
- 函數名稱 : unsigned char read7279(unsigned char comand)
- 函數說明 : 讀鍵盤指令程序
- 輸入參數 : 無
- 輸出參數 : in_byte
*************************************************************************************************************
*/
unsigned char read7279(unsigned char comand)
{
send_byte(comand);
return (receive_byte());
}
/*
*************************************************************************************************************
- 函數名稱 : void write7279 (unsigned char cmd, unsigned char dat)
- 函數說明 : 寫鍵盤指令程序
- 輸入參數 : 無
- 輸出參數 : in_byte
*************************************************************************************************************
*/
void write7279 (unsigned char cmd, unsigned char date)
{
send_byte(cmd);
send_byte(date);
}
/*
*************************************************************************************************************
- 函數名稱 : Kbd7279_Close
- 函數說明 : 關閉鍵盤設備
- 輸入參數 : 無
- 輸出參數 : 0
*************************************************************************************************************
*/
void __exit Kbd7279_Exit(void){ unregister_chrdev(KEYBOARD_MAJOR, "Kbd7279"); free_irq(33,"88"); send_byte(cmd_reset); printk("You have uninstall The Kbd7279 Driver succesfully,\n if you want to install again,please use the insmod command \n");
}
module_init(Kbd7279_Init);
module_exit(Kbd7279_Exit);
/*
*************************************************************************************************************
*- 結束文件 -*
*************************************************************************************************************
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -