RK3288 7.1 ioremap 控制 gpio led

1、通过 echo "on" >dev/io_led0 点亮 gpio7_b5 led

     通过  echo "off" >dev/io_led0 熄灭 gpio7_b5 led

/*************************************************************************
    > File Name: chr_dev.c
    > Author: Bond
    > Created Time: 2021年03月30日 星期三 13时44分36秒
 ************************************************************************/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <asm/io.h>

#define DBUG true
#define DEBUG(x...) if(DBUG){printk(x);}

#define DEV_MAJOR               230
#define MAYJOR_MAGIC           'c'
#define GLOBALMEM_SIZE           0x1000 
#define DEVICE_NUM             1
#define MEM_CLEAR               _IOWR(MAYJOR_MAGIC,0,int)

volatile unsigned long *grf_gpio7b_iomux = NULL;
volatile unsigned long *grf_gpio7b_p = NULL;
volatile unsigned long *grf_gpio7b_spdr = NULL;
volatile unsigned long *grf_gpio7b_spdd = NULL;

static int devmem_major = DEV_MAJOR;
module_param(devmem_major,int,S_IRUGO);

struct chrmem_dev{
    struct device *dev_devcie;
    struct cdev c_dev;
};

struct class *dev_class;
static struct chrmem_dev *pchrmem_dev;

static int chr_dev_open(struct inode *inode, struct file *filp){
    return 0;
}
static int chr_dev_release(struct inode *inode,struct file* filp){
    return 0;
}

static long chr_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
    return 0;
}

static ssize_t chr_dev_read(struct file *filp, char __user *buffer, size_t size, loff_t *f_pos){
    int ret=0;    
    return ret;
}

static ssize_t chr_dev_write(struct file *filp, 
                                    const char __user *buffer,  
                                    size_t size, 
                                loff_t *f_pos) 

    int ret;    
    char kbuf[10];
     memset(kbuf,0,10);
    ret = copy_from_user(kbuf,buffer,size);
    if(ret){
        return -EFAULT;
    }
    *grf_gpio7b_iomux = (~((1<<11)|(1<<10)))|(0xffff<<16);
    *grf_gpio7b_spdd |=(1<<13);
    if(!strncmp("on",kbuf,strlen("on"))){
        *grf_gpio7b_spdr |=(1<<13);
    }else if(!strncmp("off",kbuf,strlen("off"))){
    
        *grf_gpio7b_spdr &=~(1<<13);
    }

    return size;
}
static loff_t chr_dev_llseek(struct file *filp, loff_t offset, int orignal){

    loff_t ret = 0;
    

    return ret;
}
static const struct file_operations chr_dev_fops = {
    .owner        = THIS_MODULE,
    .open        = chr_dev_open,
    .read        = chr_dev_read,
    .write      = chr_dev_write,
    .llseek        = chr_dev_llseek,
    .release    = chr_dev_release,
    .unlocked_ioctl = chr_dev_ioctl,
};
static int chr_dev_setup(struct chrmem_dev *dev,struct class *dev_class,int index){
    int err,devno;
    devno = MKDEV(devmem_major,index);
    cdev_init(&dev->c_dev,&chr_dev_fops);
    dev->c_dev.owner = THIS_MODULE;
    err = cdev_add(&dev->c_dev,devno,1);
    dev->dev_devcie = device_create(dev_class,NULL,devno,NULL,"io_led%d",index);
    return err;
}

static int __init chr_dev_init(void){
    int ret = 0,i = 0;
    
    dev_t devno = MKDEV(DEV_MAJOR,0);
    grf_gpio7b_iomux = (volatile unsigned long*)ioremap(0xff770070,4);
    grf_gpio7b_p     = (volatile unsigned long*)ioremap(0xff7701a4,4);
    grf_gpio7b_spdr  = (volatile unsigned long*)ioremap(0xff7e0000,4);
    grf_gpio7b_spdd  = (volatile unsigned long*)ioremap(0xff7e0004,4);
    
    if(devmem_major){    
        ret = register_chrdev_region(devno,DEVICE_NUM,"chrdevmem");
    }else{
        ret = alloc_chrdev_region(&devno,0,DEVICE_NUM,"chrdevmem");
        devmem_major = MAJOR(devno);
    }
    if(ret){
        return -ENOTBLK;
    }
    pchrmem_dev = kzalloc(sizeof(struct chrmem_dev)*DEVICE_NUM,GFP_KERNEL);
    if(!pchrmem_dev){
        ret = -ENOMEM;
        goto fail_kzalloc;    
    }
    dev_class = class_create(THIS_MODULE,"io_chr");
    for(i=0;i<DEVICE_NUM;i++){
        chr_dev_setup(pchrmem_dev+i,dev_class,i);
    }
    return ret;
fail_kzalloc:
    unregister_chrdev_region(devno,DEVICE_NUM);
    return ret;
}

static void __exit chr_dev_exit(void){
    int i=0;
    iounmap(grf_gpio7b_iomux);
    iounmap(grf_gpio7b_p);
    iounmap(grf_gpio7b_spdd);
    iounmap(grf_gpio7b_spdr);
    unregister_chrdev_region(MKDEV(devmem_major,0), DEVICE_NUM); // жÔØ
    kfree(pchrmem_dev);
    for(i=0;i<DEVICE_NUM;i++){
        device_destroy(dev_class,MKDEV(devmem_major,i));
    }
    class_destroy(dev_class);

}


module_init(chr_dev_init);
module_exit(chr_dev_exit);


MODULE_AUTHOR("Bond <xxxx@163.com>");  
MODULE_DESCRIPTION("char dev driver");  
MODULE_LICENSE("GPL"); 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值