⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio_driv.c

📁 基于linux和s3c2440的gpio驱动程序
💻 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 + -