This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM3730的GPIO输入输出问题(驱动,我写的输出可以输入感觉不对)



各位大哥看看我的驱动gpio的输入那里不对,也就是read的方法

 

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/access.h>

#include "CMD.h"

#define GPIO_10 0x48002A18
#define GPIO_OE 0x48310034
#define GPIO_CLEARDATAOUT 0x48310090
#define GPIO_SETDATAOUT  0x48310094
#define GPIO_DATAIN 0x48310038

MODULE_LICENSE("Dual BSD/GPK");

static int major = 260;
static int minor = 0;
static dev_t devno;
static struct cdev gpio_cdev;
static volatile unsigned long *gpio_10,*gpio_oe,*gpio_cleardataout,*gpio_setdataout,*gpio_datain;
struct class *gpio_class = NULL;

static int gpio_open(struct inode *inode,struct file *filp)
{
 printk(KERN_INFO "gpio device is open");
 return 0;
}

static int gpio_release(struct inode *inode,struct file *filp)
{
 printk(KERN_INFO "gpio device is close");
 return 0;
}

static int gpio_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
 int val = 0;
 switch(cmd)
 {
 case high:
  
  val = readl(gpio_setdataout);
  val &= ~(0x1 << 10);
  val |= (0X1 << 10);
  writel(val,gpio_setdataout);

  break;

 case low:
  
  val = readl(gpio_cleardataout);
  val &= ~(0x1 << 10);
  val |= (0x1 << 10);
  writel(val,gpio_cleardataout);

  break;

 default:
  printk(KERN_INFO "fail no this commond");
  break;
 }

 return 0;
}

ssize_t gpio_read(struct file *filp,char __user *buf,size_t count,loff_t *offp)
{
 unsigned int val;

 val = readl(gpio_datain);
 val &= ~(0xFFFFFBFF);

 if(val & (0x1 << 10))
 {
  copy_to_user(buf,"1",1);
 }else
 {
  copy_to_user(buf,"0",1);
 }

 return count;
}

 

struct file_operations fops = {

 .owner = THIS_MODULE,
 .open = gpio_open,
 .release = gpio_release,
 .ioctl = gpio_ioctl,
 .read = gpio_read,
};

 


static int gpio__init(void)
{
 int result;
 unsigned int val;
// int err = -1;
// struct device *temp = NULL;

 devno = MKDEV(major,minor);
 
 result = register_chrdev_region(devno,1,"gpio");
 if(result < 0)
 {
  printk(KERN_WARNING "fail to register_chrdev_region");
  return result;
 }
 
 gpio_10 = (unsigned long *)ioremap(GPIO_10,4);
 gpio_oe = (unsigned long *)ioremap(GPIO_OE,4);
 gpio_cleardataout = (unsigned long *)ioremap(GPIO_CLEARDATAOUT,4);
 gpio_setdataout = (unsigned long *)ioremap(GPIO_SETDATAOUT,4);
 gpio_datain = (unsigned long *)ioremap(GPIO_DATAIN,4);

 //对gpio引脚进行配置(因为是复用,所以配置时要注意)
 val = readl(gpio_10);
 val &= ~0xFFFFFFFF;
 val |= 0x01040104;
 writel(val,gpio_10);

 // 对gpio_oe进行配置为out_put模式
 val = readl(gpio_oe);
 val &= ~0xFFFFFFFF;
 val |= 0x0;
 writel(val,gpio_oe);
/*
 gpio_class = class_create(THIS_MODULE,"my_gpio");
 if(IS_ERR(gpio_class))
 {
  err = PTR_ERR(gpio_class);
  printk(KERN_ALERT "fail to set up dev %s\n",err);
  return -1;
 }

 temp = device_create(gpio_class,NULL,MKDEV(major,minor),NULL,"my_gpio");
 if(IS_ERR(temp))
 {
  err = PTR_ERR(temp);
  printk(KERN_ALERT "fail to create my_gpio_device");
  return -1;
 }

*/
 cdev_init(&gpio_cdev,&fops);
 gpio_cdev.owner = THIS_MODULE;
 cdev_add(&gpio_cdev,devno,1);

 return 0;
}

static void gpio__exit(void)
{
 iounmap(gpio_10);
 iounmap(gpio_oe);
 iounmap(gpio_cleardataout);
 iounmap(gpio_setdataout);
 iounmap(gpio_datain);
 
 cdev_del(&gpio_cdev);

 unregister_chrdev_region(devno,1);

 printk(KERN_INFO "module gpio device is exit");
}


module_init(gpio__init);
module_exit(gpio__exit);