📄 power.c
字号:
///@author WangHong///@bug///@verstion $Version$ #ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm/uaccess.h>#include <linux/miscdevice.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/in.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/init.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/errno.h>#include <linux/wait.h> #include <asm/arch/mx2.h>#include <asm/irq.h>#include <asm/arch/hardware.h>#include <asm/arch/irqs.h>#include "type.h"#include "power.h"#define MODULE_NAME "power_detect"#define DEVICE_NAME "power_detect"#undef DEBUG#define DEBUG#ifdef DEBUG#define DPRINTK(fmt, args...) printk(fmt, ##args)#else#define DPRINTK(fmt, args...)#endif#define POWER_IRQ 8static SINT32 powerMajor = 0;static UINT32 power_state = 0; #ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_power;#endifstatic struct timer_list power_timer;struct fasync_struct *ts_fasync;static int power_open (struct inode* inode, struct file* filp);static int power_release (struct inode* inode, struct file* filp);static ssize_t power_read (struct file* filp, char* buf, size_t count, loff_t* ppos);static ssize_t power_write (struct file* filp, const char* buf, size_t count, loff_t* ppos);static int power_ioctl (struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg);static int power_fasync (int fd, struct file* filp, int mode);static int check_device(struct inode *pInode);static struct file_operations power_fops = { .owner = THIS_MODULE, .open = power_open, .release = power_release, .read = power_read, .write = power_write, .ioctl = power_ioctl, .fasync = power_fasync, };static int power_open (struct inode* inode, struct file* filp){ MOD_INC_USE_COUNT; return 0;}static int check_device (struct inode* pInode){ kdev_t dev = pInode->i_rdev; if (MAJOR (dev) != powerMajor) return -1; return 0;}static int power_fasync (int fd, struct file* filp, int mode){ int major = check_device (filp->f_dentry->d_inode); if (major == -1) return -ENODEV; return fasync_helper (fd, filp, mode, &ts_fasync);}static int power_release (struct inode* inode, struct file* filp){ power_fasync (-1, filp, 0); MOD_DEC_USE_COUNT; DPRINTK ("release\n"); return 0;}static int power_read (struct file* filp, char* buf, size_t count, loff_t* ppos){ if (copy_to_user (buf, &power_state, sizeof(UINT32))) return -EFAULT; return sizeof(UINT32);}static int power_write (struct file* filp, const char* buf, size_t count, loff_t* ppos){ return 0;}static int power_ioctl (struct inode* inode, struct file* filp, unsigned int cmd,unsigned long arg){ return 0;}static void power_set_inter (void){ /*pc15 is used*/ _reg_GPIO_GIUS(GPIOC) |= 0x00008000; /* TODO:Set input configure register GPIO(15) interrupt status register*/ //_reg_GPIO_OCR1(GPIOC) |= 0xC0000000; //mask interrupt _reg_GPIO_IMR(GPIOC) &= ~(0x00008000); //input configure _reg_GPIO_ICONFA1(GPIOC) &= 0x3fffffff; _reg_GPIO_ICONFA1(GPIOC) |= 0x80000000; /* Set direction configure register,input */ _reg_GPIO_DDIR(GPIOC) &= ~(1 << 15); //open portc interrupt _reg_GPIO_PMASK |= 0x4; }static void power_disable_inter (void){ _reg_GPIO_IMR(GPIOC) &= ~(0x00008000);}static void power_enable_inter (void){ _reg_GPIO_IMR(GPIOC) |= 0x00008000;}static void power_clear_inter (void){ _reg_GPIO_ISR(GPIOC) |= 0x000080000;}static void power_set_rise_inter (void){ _reg_GPIO_ICR1(GPIOC) &= 0x3fffffff;}static void power_set_fall_inter (void){ _reg_GPIO_ICR1(GPIOC) &= 0x3fffffff; _reg_GPIO_ICR1(GPIOC) |= 0x40000000;}static void power_set_pos_inter (void){ //low power if (_reg_GPIO_SSR(GPIOC)&0x00008000) { power_state = 0; power_set_fall_inter (); } //high power else { power_state = 1; power_set_rise_inter (); }}static void power_irq (int irq, void* dev_id, struct pt_regs* regs){ if (((_reg_GPIO_ISR(GPIOC) & _reg_GPIO_IMR(GPIOC))&0x8000) != 0) { //clear interrupt power_clear_inter (); //close interrupt power_disable_inter (); power_timer.expires = jiffies + HZ/50; add_timer (&power_timer); } return;}static void power_callback (unsigned long arg){ power_set_pos_inter (); power_enable_inter (); if (ts_fasync) kill_fasync (&ts_fasync, SIGIO, POLL_IN); DPRINTK ("power_status = %d\n", power_state);}static int __init power_module_init (void){ init_timer (&power_timer); power_timer.function = power_callback; int ret = register_chrdev (0, DEVICE_NAME, &power_fops); if (ret < 0) { printk (DEVICE_NAME"cannot get major number\n"); return -1; } powerMajor = ret; #ifdef CONFIG_DEVFS_FS devfs_power = devfs_register (NULL, MODULE_NAME, DEVFS_FL_DEFAULT, powerMajor, 0, S_IFCHR | S_IRUSR | S_IWUSR, &power_fops, NULL);#endif ret = request_irq (POWER_IRQ, (void*)power_irq, SA_INTERRUPT|SA_SHIRQ, MODULE_NAME, MODULE_NAME); if (ret) { printk ("request_irq for power_detect failed\n");#ifdef CONFIG_DEVFS_FS devfs_unregister (devfs_power);#endif unregister_chrdev (powerMajor, DEVICE_NAME); return -1; } power_set_inter (); power_disable_inter (); power_set_pos_inter (); power_enable_inter (); DPRINTK ("power_detect driver init succeeded\n"); return 0;}static void __exit power_module_exit (void){ if (powerMajor > 0) {#ifdef CONFIG_DEVFS_FS devfs_unregister (devfs_power);#endif unregister_chrdev (powerMajor, DEVICE_NAME); } free_irq (POWER_IRQ, MODULE_NAME); del_timer (&power_timer); return;}module_init (power_module_init);module_exit (power_module_exit);MODULE_LICENSE ("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -