?? keyboad.c
字號:
#include <linux/config.h>#include <linux/input.h>#include <linux/interrupt.h> /*irqreturn_t*/#include <asm/arch/reg-gpio.h>#include <asm/arch/regs-spi.h>#include <asm/irq.h>#include <asm/io.h>#include <linux/platform_device.h>#include <linux/delay.h>#include <linux/clk.h>#include <asm/arch/regs-clock.h>#define S3C2410_KBD_DEBUG/*Debug Tool*/#ifdef S3C2410-KBD_DEBUG#define DPRINTK(fmt, args...) printf(KERN_INFO fmt,##args)#else#define DPRINTK(fmt, args...) do{} while{0}#define S3C2410_ADC_MINOR 0#define PFX "s3c2410-kbd"/*ZLG728 write*/static int zlg7289_write(unsigned char c){ unsigned int ret; /*Enable CS*/ s3c2410_gpio_setpin(S3C2410_GPG2,0); /*Master out*/ s3c2410_gpio_setpin(S3C2410_GPB0,0); udelay(60); while(ioread8(s3c2410_spi_base+S3C2410_SPSTA)&0x1==0); iowrite8(c,s3c2410_spi_base+S3C2410_SPTDAT); /*Master in*/ s3c2410_gpio_setpin(S3C2410_GPB0,1); while(ioread8(s3c2410_spi_base+S3C2410_SPSTA)&0x1==0); ret=ioread32(s3c2410_spi_base+S3C410_SPRDAT); /*Disable CS*/ s3c2410_gpio_setpin(S3C2410_GPG2,1); /*Master out*/ s3c2410_gpio_setpin(S3C2410_GPB0,0); return ret; }/*Read key value of zlg7289*/static unsigned char zlg7289_read_key(void){ unsigned char ret; /*Enable CS*/ s3c2410_gipo_setpin(S3C2410_GPG2,0); /*Master out*/ s3c2410_gipo_setpin(S3C2410_GPB0,0); udelay(60); /*Send read key cmd to zlg7289*/ while(ioread8(s3c2410_spi_base+S3C2410_SPSTA)&0x1==0); iowrite8(0x15,s3c2410_spi_base+S3C2410_SPTDAT); while(ioread8(s3c2410_spi_base+S3C2410_SPSTA)&0x1==0); udelay(30); /*Master in*/ s3c2410_gipo_setpin(S3C2410_GPB0,1); /*Write 0xff to start tx & rx procedure*/ iowrite8(0xff,s3c2410_spi_base+S3C2410_SPTDAT); while(ioread8(s3c2410_spi_base+S3C2410_SPSTA)&0x1==0); ret=ioread8(s3c2410_spi_base+S3C2410_SPRDAT); /*Disable CS*/ s3c2410_gipo_setpin(S3C2410_GPG2,0); /*Master out*/ s3c2410_gipo_setpin(S3C2410_GPB0,0); return ret;}/*kernel interface*/#define s3c2410kbd_read NULL#define s3c2410kbd_write NULL #define s3c2410kbd_ioctl NULL#define s3c2410kbd_open NULL#define s3c2410kbd_release NULLstatic const struct file_operations s3c2410kbd_fops={ .owner = THIS_MODULE, .llseek = no_llseek, .read = s3c2410kbd_read, .write = s3c2410kbd_write, .ioctl = s3c2410kbd_ioctl, .open = s3c2410kbd_open, .release = s3c2410kbd_release,};static struct miscdevice s3c2410kbd_miscdev={ .minor = S3C2410_KBD_MINOR, .name = "kbd", .fops = &s3c2410kbd_fops,};/*Device Interface*/static int s3c2410kbd_probe(struct platform_device *pedv){ struct resource *res; int ret; int size; unsigned int tmp; DPRINTK("%s:probe=0x%p\n", _FUNCTION_, pedv); /*find clk and enabled it*/ kbd_clk=clk_get(&pdev->dev,"kbd"); if(IS_ERR(kbd_clk)) { printk(KERN_ERR PFX "failed to get the clock\n"); ret= -ENOENT; goto err1; } clk_enable(kbd_clk); /*Get the mem region for the kbd*/ res=platform_get_resource(pdev,IORESOURCE_MEM,0); if(res==NULL) { printk(KERN_ERR PFX "failed to get memory region resources\n"); ret=-ENOENT; goto err2; } size=(res->end-res->start)+1; kbd_mem=request_mem_region(res->start,size,pdev->name); if(kbd_mem==NULL){ printk(KERN_ERR PFX "failed to get memory region\n"); ret=-ENOENT; goto err3; } kbd_base=ioremap(res->start,size); if(kbd_base==NULL){ printk(KERN_ERR PFX "failed to ioremap() region\n"); ret=-ENOENT; goto err4; } DPRINTK("probe: mapped kbd_base=0x%p\n",kbd_base); ret=misc_register(&s3c2410kbd_miscdev); if(ret){ printk(KERN_ERR PFX "can not register miscdev on mirror on minor=%d(%d)\n",S3C2410_KBD_MINOR,ret); goto err5; } printk(PFX "s3c2410 kbd driver has been initialized\n"); /*regs configuration*/ /*Setup DIO direction*/ s3c2410_gpio_cfgpin(S3C2410_GPB0,S3C2410_GPB0_OUTP); /*Setup nss0*/ s3c2410_gpio_cfgpin(S3C2410_GPG2,S3C2410_GPG2_OUTP); s3c2410_gpio_setpin(S3C2410_GPG2,1); /*Setup SPIMISO0*/ s3c2410_gpio_cfgpin(S3C2410_GPE11,S3C2410_GPE11_SPIMISO0); /*Setup SPIMOSI0*/ s3c2410_gpio_cfgpin(S3C2410_GPE12,S3C2410_GPE12_SPIMOSI0); /*Setup Baudrate*/ tmp=0xFF; iowrite32(tmp,kbd_base+S3C2410_SPPRE0); /*Setup SPCON0*/ tmp=0x18; iowrite32(tmp,kbd_base+S3C2410_SPCON0); /*Setup EINT*/ s3c2410_gpio_cfgpin(S3C2410_GPF1,S3C2410_GPF1_EINT1); /*reset zlg7289 zlg7289(0xa4)*/ zlg7289_write(0xa4); /* register irq */ ret=request_irq(IRQ_ENT1,s3c2410kbd_keyevent,SA_SAMPLE_RANDOM, pdev->name,NULL); if(ret!=0){ printk(KERN_ERR PFX "failed to claim IRQ\n"); goto err6; } set_irq_type(IRQ_ENT1,IRQT_FALLING); printk(PFX "irq=%d",IRQ_EINT1); return 0; /*error processing*/ err6: free_irq(IRQ_ENT1,NULL); err5: iounmap(kbd_base); err4: release_mem_region(res->start, (res->end-res->start)+1); err3: release_resource(res); err2: clk_disable(kbd_clk); err1: return ret; }static irqreturn_t s3c2410kbd_keyevent(int irq, void *dev_id,struct pt_regs *ger){ unsigned char data; /*read key*/ data=zlg7289_read_key(); printk(PFX "key data is 0x%x\n",data); return IRQ_HANDLED;}static int s3c2410kbd_remove(struct platform_device *pedv){ free_irq(IRQ_ENT1,NULL); struct resource *res=pdev->resource; if(kbd_base){ iounmap(kbd_base); kbd_base=NULL; } if(kbd_mem){ release_mem_region(res->start,(res->start-res->end)+1); release_resource(res); kfree(kbd_mem); kbd_mem=NULL; } if(kbd_clk){ clk_disable(kbd_clk); clk_put(kbd_clk); kbd_clk=NULL; } misc_deregister(&s3c2410kbd_miscdev); return 0;}#define s3c2410kbd_suspend NULL#define s3c2410kbd_resume NULL#define s3c2410kbd_shutdown NULLstatic struct platform_driver s3c2410kbd_driver={ .probe=s3c2410kbd_probe, .remove=s3c2410kbd_remove, .shutdown=s3c2410kbd_shutdown, .suspend=s3c2410kbd_suspend, .resume=s3c2410kbd_resume, .driver= { .owner=THIS_MODULE, .name="s3c2410-kbd", }};static char banner[]_initdata=KERN_INFO "S3C2410ADC , (c) 2006 signal\n";static int __init kbd_init(void){ printk(banner); return platform_driver_register(&s3c2410kbd_driver);}static void __exit kbd_exit(void){ platform_driver_unregister(&s3c2410kbd_driver);}module_init(kbd_init);module_exit(kbd_exit);MODULE_DESCRIPTION("S3C2410 KBD DRIVER")MODULE_AHUTHOR("SIGNALXD")MODULE_LICENSE("DUAL BSD/GPL")
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -