zoukankan      html  css  js  c++  java
  • 基于设备树的led驱动程序

      1 #include <linux/module.h>
      2 #include <linux/kernel.h>
      3 #include <linux/fs.h>
      4 #include <linux/init.h>
      5 #include <linux/delay.h>
      6 #include <asm/io.h>
      7 #include <linux/cdev.h>
      8 #include <linux/device.h>
      9 #include <linux/bitmap.h>
     10 #include <asm/gpio.h>
     11 #include <linux/platform_device.h>
     12 #include <linux/slab.h>
     13 #include <linux/sched.h>
     14 #include <linux/of.h>
     15 
     16 static volatile unsigned long *ledcon;
     17 static volatile unsigned long *leddat;
     18 static struct class *led_class;
     19 static unsigned int pin_th;
     20 dev_t led_dev;
     21 struct cdev *cdev;
     22 
     23 
     24 /* 打开led灯 */
     25 static int led_open(struct inode *inode, struct file *file)
     26 {
     27      *ledcon &= ~(0x3 << (pin_th * 2));
     28      *ledcon |= (0x1 << (pin_th * 2));
     29      *leddat &= ~(1 << pin_th);
     30      return 0;
     31 }
     32 
     33 static struct file_operations led_fops = {
     34                .owner = THIS_MODULE,
     35                .open = led_open,
     36 };
     37 
     38 static int led_probe(struct platform_device *pdev)
     39 {
     40    int pin_info;
     41    int phy_addr;
     42    int io_base;
     43    of_property_read_s32(pdev->dev.of_node, "pin", &pin_info); 
     44    printk("pin_info = 0x%x
    ", pin_info);
     45    of_property_read_s32(pdev->dev.of_node, "iobase", &io_base); 
     46    printk("io_base = 0x%x
    ", io_base);
     47    pin_th = pin_info & (0xffff);
     48    phy_addr = (io_base | ((pin_info>>16)<<4));
     49    ledcon = ioremap(phy_addr, 2);
     50    leddat = ledcon + 1;
     51    
     52    if (alloc_chrdev_region(&led_dev, MINOR(led_dev), 1, "led"))
     53           return -1;
     54    cdev = cdev_alloc();
     55    if (!cdev)
     56           return -1;
     57    cdev_init(cdev, &led_fops);
     58    cdev_add(cdev, led_dev, 1);
     59 
     60    led_class = class_create(THIS_MODULE, "led");
     61    device_create(led_class,NULL,led_dev,NULL,"led0");   // is /dev/led0
     62 
     63    return 0;
     64    
     65 }
     66 
     67 int led_remove(struct platform_device *pdev)
     68 {
     69     device_destroy(led_class, led_dev);
     70     class_destroy(led_class);
     71     cdev_del(cdev);
     72     unregister_chrdev_region(led_dev, 1);
     73     iounmap(ledcon);
     74     return 0;
     75 }
     76 
     77 static struct of_device_id led_id[] = {
     78               {.compatible = "jz2440_led"},
     79               {},
     80 };
     81 
     82 static struct platform_driver led_drv = {
     83     .probe = led_probe,
     84     .remove = led_remove,   
     85      .driver = {
     86         .name  = "jz2440_led",
     87         .of_match_table = led_id,
     88     },
     89 };
     90 
     91 static int led_init(void)
     92 {
     93     platform_driver_register(&led_drv);
     94     return 0;
     95 }
     96 
     97 static void led_exit(void)
     98 {
     99      platform_driver_unregister(&led_drv);
    100 }
    101 
    102 module_init(led_init);
    103 module_exit(led_exit);
    104 
    105 MODULE_LICENSE("GPL");

    以上是驱动程序,下面是设备树dts文件:

     1 #define S3C2440_GPA(_nr)    ((0<<16) + (_nr))
     2 #define S3C2440_GPB(_nr)    ((1<<16) + (_nr))
     3 #define S3C2440_GPC(_nr)    ((2<<16) + (_nr))
     4 #define S3C2440_GPD(_nr)    ((3<<16) + (_nr))
     5 #define S3C2440_GPE(_nr)    ((4<<16) + (_nr))
     6 #define S3C2440_GPF(_nr)    ((5<<16) + (_nr))
     7 #define S3C2440_GPG(_nr)    ((6<<16) + (_nr))
     8 #define S3C2440_GPH(_nr)    ((7<<16) + (_nr))
     9 #define S3C2440_GPJ(_nr)    ((8<<16) + (_nr))
    10 #define S3C2440_GPK(_nr)    ((9<<16) + (_nr))
    11 #define S3C2440_GPL(_nr)    ((10<<16) + (_nr))
    12 #define S3C2440_GPM(_nr)    ((11<<16) + (_nr))
    13  
    14 /dts-v1/;
    15 
    16 / {
    17     model = "SMDK2440";
    18     compatible = "samsung,smdk2440";
    19 
    20     #address-cells = <1>;
    21     #size-cells = <1>;
    22         
    23     memory@30000000 {
    24         device_type = "memory";
    25         reg =  <0x30000000 0x4000000>;
    26     };
    34 chosen { 35 bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200"; 36 }; 37 38 39 led { 40 compatible = "jz2440_led"; 41 pin = <S3C2440_GPF(5)>; 42 iobase = <0x56000000>; 43 }; 44 };
  • 相关阅读:
    axios跨域问题(包括开发环境和生产环境)
    vue高亮一级、二级导航
    vue配置路由时报错 Error in render: "RangeError: Maximum call stack size exceeded"
    win10使用L2TP连接失败,报远程服务器未响应错误解决办法,亲测可用!
    pywinauto教程
    Python结合Pywinauto 进行 Windows UI 自动化
    Pywinauto自动化操作PC微信提取好友微信号
    Debian9 配置kali(xfce4、Metasploit、wireshark)
    Kali开启ssh
    从域环境搭建到域渗透
  • 原文地址:https://www.cnblogs.com/zhu-g5may/p/10316990.html
Copyright © 2011-2022 走看看