📄 gpio_driv.c
字号:
#include <linux/config.h>#include <linux/init.h> //#include <kernel.h> #include <asm/hardware.h>#include <asm/leds.h>#include <asm/system.h>#include <asm/arch/smdk.h>#include <linux/module.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/miscdevice.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <linux/version.h>#include <asm/arch/smdk.h>#include <asm/arch/S3C2440.h>#define LED0 (1 << 0)#define LED1 (1 << 1)#define LED2 (1 << 2)#define LED3 (1 << 3)#define __NO_VERSION__ #ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))#endif#define DEVICE_NAME "gpio_driv"#define IOPORT_MAJOR 100 //定义主设备号,和前面的mknod/dev/gpiotestc 220 0匹配#define GPIO_A_CON 0x56000000#define GPIO_A_DAT 0x56000004#define GPIO_B_CON 0x56000010#define GPIO_B_DAT 0x56000014#define GPIO_B_PUP 0x56000018#define GPIO_C_CON 0x56000020#define GPIO_C_DAT 0x56000024#define GPIO_C_PUP 0x56000028#define GPIO_D_CON 0x56000030#define GPIO_D_DAT 0x56000034#define GPIO_D_PUP 0x56000038#define GPIO_E_CON 0x56000040#define GPIO_E_DAT 0x56000044#define GPIO_E_PUP 0x56000048#define GPIO_F_CON 0x56000050#define GPIO_F_DAT 0x56000054#define GPIO_F_PUP 0x56000058#define GPIO_G_CON 0x56000060#define GPIO_G_DAT 0x56000064#define GPIO_G_PUP 0x56000068#define GPIO_H_CON 0x56000070#define GPIO_H_DAT 0x56000074#define GPIO_H_PUP 0x56000078#define GPIO_J_CON 0x56000080#define GPIO_J_DAT 0x56000084#define GPIO_J_PUP 0x56000088static int gpio_open(struct inode*, struct file *);static int gpio_release(struct inode*, struct file *);static int gpio_ioctl(struct inode *, struct file *, unsigned int intcommand, unsigned long arg);static int gpio_read(struct file *file, char *buffer, /* The buffer to fill with data*/ size_t length, /* The length of the buffer */ loff_t * offset); /* Our offset in the file */static int gpio_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what); char kernel_version [] = UTS_RELEASE;static struct file_operations gpio_ctl_fops= { ioctl: gpio_ioctl, read: gpio_read, write:gpio_write, open: gpio_open, release: gpio_release,}; static int gpio_open(struct inode *inode, struct file *file){ MOD_INC_USE_COUNT; printk ("device_open(%p,%p)\n", inode, file); /* * Get major / minor numbers when needed */ printk ("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF); return 0;} static int gpio_release(struct inode *inode, struct file *file){ MOD_DEC_USE_COUNT; return 0;} static int gpio_ioctl(struct inode*inode,struct file *flip,unsigned intcommand,unsigned long arg){return 0;}static int gpio_read(struct file *file, char *buffer, /*buffer[0-3]=addr buffer[4-7]= bit */ size_t length, loff_t * offset) { unsigned long templong,tempcon,tmpold; unsigned char i; int bit,GPIOAddr,GPIOData,temp_gdata[8]; for(i=0;i<8;i++) temp_gdata[i]=(int)buffer[i]; GPIOAddr=temp_gdata[0]+temp_gdata[1]*256+temp_gdata[2]*256*256+temp_gdata[3]*256*256*256; GPIOData=temp_gdata[4]+temp_gdata[5]*256+temp_gdata[6]*256*256+temp_gdata[7]*256*256*256;// printk("\n GPIOAddr=%x GPIOData=%x", GPIOAddr,GPIOData); tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr )); tmpold=tempcon; if (length&0x8) { printk("CON is %x,DAT is %x, PULL is %x\n", *((volatile unsigned long *)io_p2v( GPIOAddr )), *((volatile unsigned long *)io_p2v( GPIOAddr+4)), *((volatile unsigned long *)io_p2v( GPIOAddr+8))); return 0; } if (length&0x2) //about set pullup, 1 set, 0 disable { switch(length&0x1) { case 1: templong= *((volatile unsigned long *)io_p2v( GPIOAddr+8)); *((volatile unsigned long *)io_p2v(GPIOAddr+8 ))=templong|(1<<GPIOData); //GP DAT =1 break; case 0: templong= *((volatile unsigned long *)io_p2v(GPIOAddr+8 )); *((volatile unsigned long *)io_p2v(GPIOAddr+8 ))=templong&(~(1<<GPIOData)); //GP DAT = 0 break; default: break; } return 0; } *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon&(~(3<<(GPIOData*2))); // GP CON = 00 as input templong= *((volatile unsigned long *)io_p2v( GPIOAddr+4)); if((templong&(1<<GPIOData))!=0) bit=1; else bit=0; // printk("\nGPIOData=%x GPIO con=%x", GPIOData,*((volatile unsigned long *)io_p2v(GPIOAddr))); if (length&0x4) *((volatile unsigned long *)io_p2v(GPIOAddr))=tmpold; // Keep CON IO as before return bit; }static int gpio_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what) { unsigned long templong,tempcon,tmpold; unsigned char i; int GPIOAddr,GPIOData,temp_gdata[8]; for(i=0;i<8;i++) temp_gdata[i]=(int)gdata[i]; GPIOAddr=temp_gdata[0]+temp_gdata[1]*256+temp_gdata[2]*256*256+temp_gdata[3]*256*256*256; GPIOData=temp_gdata[4]+temp_gdata[5]*256+temp_gdata[6]*256*256+temp_gdata[7]*256*256*256; // printk("\n GPIOAddr=%x GPIOData=%x", GPIOAddr,GPIOData); tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr )); tmpold=tempcon; if (length&0x4) //about set function11 { *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon|((3<<(GPIOData*2))); // GP CON = 11 as FUNCTION2 return 0; } if (length&0x2) //about set function10 { *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon&(~(1<<(GPIOData*2))); // GP CON = 10 as FUNCTION1 tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr )); *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon|((1<<(GPIOData*2+1))); // GP CON = 10 as FUNCTION1 return 0; } *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon&(~(1<<(GPIOData*2+1))); // GP CON = 01 as output tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr )); *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon|((1<<(GPIOData*2))); // GP CON = 01 as output switch(length&0x1) { case 1: templong= *((volatile unsigned long *)io_p2v( GPIOAddr+4)); *((volatile unsigned long *)io_p2v(GPIOAddr+4 ))=templong|(1<<GPIOData); //GP DAT =1// printk("Write gpio %d\n",length); break; case 0: templong= *((volatile unsigned long *)io_p2v(GPIOAddr+4 )); *((volatile unsigned long *)io_p2v(GPIOAddr+4 ))=templong&(~(1<<GPIOData)); //GP DAT = 0 // printk(" Write gpio %d\n",length); break; default: break; } // if (length&0x4)// *((volatile unsigned long *)io_p2v(GPIOAddr))=tmpold; // Keep CON IO as before return 0; } static int __initgpio_init(void){ int ret; ret = register_chrdev(IOPORT_MAJOR, DEVICE_NAME, &gpio_ctl_fops); if(ret < 0) { printk(DEVICE_NAME " can't get major number\n"); return ret; }// gpio_Major = ret; printk ("_____________________ board gpio registred: major= %d\n",IOPORT_MAJOR); return 0;} static void __exitgpio_cleanup(void){ int ret; /* * Unregister the device */ ret = unregister_chrdev (IOPORT_MAJOR, DEVICE_NAME); /* * If there's an error, report it */ if (ret < 0) { printk ("unregister_chrdev: error %d\n", ret); }}/*int init_module (void){int ret ; ret=gpio_init();} void cleanup_module (void){ int ret; ret=gpio_cleanup();} */ module_init(gpio_init);module_exit(gpio_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -