📄 i2c-keypad.c
字号:
* mode : * Value Returned: int : Return status.If no error, return 0. * * Description: provide fasync functionality for select system call * *****************************************************************************/static int keypad_fasync(int fd, struct file *filp, int mode){ int ret; /* TODO put this data into file private data */ int minor = checkDevice( filp->f_dentry->d_inode); if ( minor == - 1) { printk("<1>keypad_fasyn:bad device minor\n"); return -ENODEV; } printk("keypad driver keypad_fasync\n"); ret = fasync_helper(fd, filp, mode, &keypadv_fasync); if(ret < 0) return ret; return 0; }/****************************************************************************** * Function Name: keypad_ioctl * * Input: inode : * filp : * cmd : command for ioctl * arg : parameter for command * Value Returned: int : Return status.If no error, return 0. * * Description: ioctl for this device driver * * *****************************************************************************/int keypad_ioctl(struct inode * inode, struct file *filp, unsigned int cmd , unsigned long arg){ int ret = -EIO; int minor; minor = checkDevice( inode ); if ( minor == - 1) { printk("keypad_ioctl:bad minor\n"); return -ENODEV; } printk("keypad_ioctl:minor=%08x cmd=%d\n",minor,cmd); return ret;}/****************************************************************************** * Function Name: keypad_poll * * Input: filp : * wait : * Value Returned: int : Return status.If no error, return 0. * * Description: support poll and select * *****************************************************************************/unsigned int keypad_poll(struct file * filp, struct poll_table_struct * wait){ int minor; minor = checkDevice( filp->f_dentry->d_inode); if ( minor == - 1) return -ENODEV; poll_wait(filp, &gkeypadWait, wait); return ( keypadmx1.gDataFlag==0) ? 0 : (POLLIN | POLLRDNORM);}/****************************************************************************** * Function Name: keypad_interrupt * * Input: irq : interrupt number * dev_id : device driver name * regs : registers * Value Returned: void : * * Description: interrupt handler for keypad device * *****************************************************************************/static void keypad_interrupt(int irq, void *dev_id, struct pt_regs *regs){ unsigned long val; char command; struct i2c_msg msg[2]; char keybuf[2]; #ifdef TEST printk("TOUT2 Raises\n"); MX1_REG_PTD_DR |= 0x80000000;#endif val = READREG(KEYPAD_ISR_B); if(val & 0x00008000) //check if PortB 15 interrupt generated { val |= 0x00008000; WRITEREG(KEYPAD_ISR_B,val); //clear the Interrupt status bit command = 0x00; keybuf[0] = 0; keybuf[1] = 0; msg[0].addr = i2c_keypad_client.addr; msg[0].flags = 0x00; msg[0].len = 1; msg[0].buf = &command; msg[1].addr = i2c_keypad_client.addr; msg[1].flags = I2C_M_RD; msg[1].len = 2; msg[1].buf = keybuf; i2c_control( &i2c_keypad_client, I2C_IO_CHANGE_FREQ, 0x10);//change to 400K freq i2c_transfer( i2c_keypad_client.adapter, msg, 2 ); i2c_control( &i2c_keypad_client, I2C_IO_CHANGE_FREQ, DEFAULT_FREQ);//change back to 100K freq key[0]=keybuf[0]; key[1]=keybuf[1]; keypadmx1.gDataFlag = 1; wake_up_interruptible(&gkeypadWait); if(keypadv_fasync) kill_fasync(&keypadv_fasync, SIGIO, POLL_IN); //val |= 0x00008000; //WRITEREG(KEYPAD_ISR_B,val); //clear the Interrupt status bit }}/****************************************************************************** * Function Name: checkDevice * * Input: inode : * Value Returned: int : Return status.If no error, return 0. * * Description: verify if the inode is a correct inode * *****************************************************************************/static int checkDevice(struct inode *pInode){ int minor; kdev_t dev = pInode->i_rdev; if( MAJOR(dev) != gMajor) { printk("checkDevice bad major = %d\n",MAJOR(dev) ); return -1; } minor = MINOR(dev); if ( minor < MAX_ID ) return minor; else { printk("checkDevice bad minor = %d\n",minor ); return -1; }}/****************************************************************************** * Function Name: initkeypad * * Input: : * Value Returned: int : init keypad hardware * * Description: verify if the inode is a correct inode * *****************************************************************************/static void __init initkeypad(){ unsigned long val; if (i2c_keypad_initialized == 0) { val = READREG(KEYPAD_GIUS_B); val |= 0x00008000; WRITEREG(KEYPAD_GIUS_B,val); //for GPIO use val = READREG(KEYPAD_DDIR_B); val &= 0xFFFF7FFF; WRITEREG(KEYPAD_DDIR_B,val); //pin B15 is GPIO input val = READREG(KEYPAD_ICR1_B); //this register need the SIM_PD input status---positive or negative, edge or level //val &= 0x3FFFFFFF; //set to positive edge sensitive //val |= 0x40000000; //set to negative edge sensitive val |= 0xC0000000; //set to negative level sensitive WRITEREG(KEYPAD_ICR1_B,val);/* val = READREG(KEYPAD_ICONFA1_B); val &= 0x3FFFFFFF; val |= 0x40000000; WRITEREG(KEYPAD_ICONFA1_B,val); //for GPIO use*/ val = READREG(KEYPAD_PUEN_B); //Port B15 is tri-state when no driven internally or externally val &= 0xFFFF7FFF; val |= 0x00008000;//Port B15 is high when no driven internally or externally WRITEREG(KEYPAD_PUEN_B,val); i2c_keypad_initialized = 1; }}/****************************************************************************** * Function Name: init_module * * Input: void : * Value Returned: int : Return status.If no error, return 0. * * Description: device driver initialization * *****************************************************************************/static devfs_handle_t devfs_handle;#ifdef MODULEint init_module(void)#elseint __init keypad_init(void)#endif{ unsigned long flags; int res; int result = 0; initkeypad(); /* register our character device */ result = devfs_register_chrdev(0, MOD_NAME, &keypad_fops); if ( result < 0 ) { printk("i2c-keypad driver: Unable to register driver\n"); return -ENODEV; } devfs_handle = devfs_register(NULL, MOD_NAME, DEVFS_FL_DEFAULT, result, 0, S_IFCHR | S_IRUSR | S_IWUSR, &keypad_fops, NULL); if( gMajor == 0 ) gMajor = result; result = request_irq(KEYPAD_GPIO_INT_B, keypad_interrupt, SA_INTERRUPT|SA_SHIRQ, MOD_NAME, MOD_NAME); printk("request_irq() result is %d\n",result); if (result) { printk("init_module error from irq %d\n", result); devfs_unregister_chrdev(gMajor, MOD_NAME); devfs_unregister(devfs_handle); return -1; } init_waitqueue_head(&gkeypadWait); i2c_keypad_client.addr = I2C_ADDR_KEYPAD; if (( res = i2c_add_driver( &i2c_keypad_driver ))) { return res; } if (( res = i2c_attach_client(&i2c_keypad_client )) != 0 ) { i2c_del_driver(&i2c_keypad_driver); return res; } save_flags_cli(flags); keypadmx1.gDataFlag = 0; keypadmx1.gKeypadFlag = 0; restore_flags(flags);#ifdef TEST MX1_REG_PTD_GIUS |= 0x80000000; MX1_REG_PTD_OCR2 |= 0xc0000000; MX1_REG_PTD_DR |= 0x80000000; MX1_REG_PTD_DDIR |= 0x80000000; printk("TOUT2 as the time trigger\n"); MX1_REG_PTD_DR |= 0x80000000; MX1_REG_PTD_DR &= ~0x80000000; #endif //printk("The major number is %d!\n",gMajor); printk("The keypad device can now be access from /dev/i2c-keypad\n"); printk("The device still can be access through mknod i2c-keypad c %d 0\n",gMajor); return 0;}/****************************************************************************** * Function Name: keypad_cleanup * * Input: void : * Value Returned: void : * * Description: clean up and free all of resource for this MODULE * * Modification History: * 10 DEC,2001, Chen Ning *****************************************************************************/#ifdef MODULEvoid cleanup_module(void)#elsevoid __exit keypad_cleanup(void)#endif{// int res; unsigned long val,flags; val = READREG(KEYPAD_IMR_B); val &= 0xFFFF7FFF; WRITEREG(KEYPAD_IMR_B,val); //unmask the interrupt i2c_detach_client(&i2c_keypad_client); i2c_del_driver(&i2c_keypad_driver); i2c_keypad_initialized = 0; free_irq(KEYPAD_GPIO_INT_B, MOD_NAME); devfs_unregister_chrdev(gMajor, MOD_NAME); devfs_unregister(devfs_handle); save_flags_cli(flags); keypadmx1.gDataFlag = 0; keypadmx1.gKeypadFlag = 0; restore_flags(flags);}#ifndef MODULEmodule_init(keypad_init);module_exit(keypad_cleanup);#endif/* end of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -