zoukankan      html  css  js  c++  java
  • platform_driver与file_operations两种方法开发led驱动

    下面是两个LED灯的驱动程序 一个用platform_driver 另一个用file_operations

    #include <linux/kernel.h>  
    #include <linux/init.h>  
    #include <linux/platform_device.h>  
    #include <linux/leds.h>  
      
    #include <mach/hardware.h>  
    #include <mach/regs-gpio.h>  
    #include <mach/leds-gpio.h>  
      
    /* our context */  
      
    struct s3c24xx_gpio_led {  
    struct led_classdev cdev;  
    struct s3c24xx_led_platdata *pdata;  
    };  
      
    static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev)  
    {  
    return platform_get_drvdata(dev);  
    }  
      
    static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev)  
    {  
    return container_of(led_cdev, struct s3c24xx_gpio_led, cdev);  
    }  
      
    static void s3c24xx_led_set(struct led_classdev *led_cdev,  
    enum led_brightness value)  
    {  
    struct s3c24xx_gpio_led *led = to_gpio(led_cdev);  
    struct s3c24xx_led_platdata *pd = led->pdata;  
      
    /* there will be a short delay between setting the output and 
    * going from output to input when using tristate. */  
      
    s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^  
    (pd->flags & S3C24XX_LEDF_ACTLOW));  
      
    if (pd->flags & S3C24XX_LEDF_TRISTATE)  
    s3c2410_gpio_cfgpin(pd->gpio,  
    value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);  
      
    }  
      
    static int s3c24xx_led_remove(struct platform_device *dev)  
    {  
    struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);  
      
    led_classdev_unregister(&led->cdev);  
    kfree(led);  
      
    return 0;  
    }  
      
    static int s3c24xx_led_probe(struct platform_device *dev)  
    {  
    struct s3c24xx_led_platdata *pdata = dev->dev.platform_data;  
    struct s3c24xx_gpio_led *led;  
    int ret;  
      
    led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL);  
    if (led == NULL) {  
    dev_err(&dev->dev, "No memory for device
    ");  
    return -ENOMEM;  
    }  
      
    platform_set_drvdata(dev, led);  
      
    led->cdev.brightness_set = s3c24xx_led_set;  
    led->cdev.default_trigger = pdata->def_trigger;  
    led->cdev.name = pdata->name;  
      
    led->pdata = pdata;  
      
    /* no point in having a pull-up if we are always driving */  
      
    if (pdata->flags & S3C24XX_LEDF_TRISTATE) {  
    s3c2410_gpio_setpin(pdata->gpio, 0);  
    s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT);  
    } else {  
    s3c2410_gpio_pullup(pdata->gpio, 0);  
    s3c2410_gpio_setpin(pdata->gpio, 0);  
    s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT);  
    }  
      
    /* register our new led device */  
      
    ret = led_classdev_register(&dev->dev, &led->cdev);  
    if (ret < 0) {  
    dev_err(&dev->dev, "led_classdev_register failed
    ");  
    goto exit_err1;  
    }  
      
    return 0;  
      
     exit_err1:  
    kfree(led);  
    return ret;  
    }  
      
      
    #ifdef CONFIG_PM  
    static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state)  
    {  
    struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);  
      
    led_classdev_suspend(&led->cdev);  
    return 0;  
    }  
      
    static int s3c24xx_led_resume(struct platform_device *dev)  
    {  
    struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);  
      
    led_classdev_resume(&led->cdev);  
    return 0;  
    }  
    #else  
    #define s3c24xx_led_suspend NULL  
    #define s3c24xx_led_resume NULL  
    #endif  
      
    static struct platform_driver s3c24xx_led_driver = {  
    .probe = s3c24xx_led_probe,  
    .remove = s3c24xx_led_remove,  
    .suspend = s3c24xx_led_suspend,  
    .resume = s3c24xx_led_resume,  
    .driver = {  
    .name = "s3c24xx_led",  
    .owner = THIS_MODULE,  
    },  
    };  
      
    static int __init s3c24xx_led_init(void)  
    {  
    return platform_driver_register(&s3c24xx_led_driver);  
    }  
      
    static void __exit s3c24xx_led_exit(void)  
    {  
    platform_driver_unregister(&s3c24xx_led_driver);  
    }  
      
    module_init(s3c24xx_led_init);  
    module_exit(s3c24xx_led_exit);  
      
    MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");  
    MODULE_DESCRIPTION("S3C24XX LED driver");  
    MODULE_LICENSE("GPL");  
    MODULE_ALIAS("platform:s3c24xx_led");  

    ---------------------------

     #include <asm/uaccess.h>   
      #include <asm/atomic.h>   
      #include <asm/unistd.h>   
      
      #define DEVICE_NAME "leds"   
      
      static unsigned long led_table [] = {   
      S3C2410_GPB5,   
      
      S3C2410_GPB6,   
      S3C2410_GPB7,   
      S3C2410_GPB8,   
    };   
      
    static unsigned int led_cfg_table [] = {   
      S3C2410_GPB5_OUTP,   
      
      S3C2410_GPB6_OUTP,   
      S3C2410_GPB7_OUTP,   
      S3C2410_GPB8_OUTP,   
    };   
      
    static int sbc2440_leds_ioctl(   
      struct inode *inode,   
      struct file *file,   
      unsigned int cmd,   
      unsigned long arg)   
    {   
      switch(cmd) {   
      case 0:   
      case 1:   
      if (arg > 4) {   
      return -EINVAL;   
      }   
      s3c2410_gpio_setpin(led_table[arg], !cmd);   
      return 0;   
      default:   
      return -EINVAL;   
      }   
    }   
      
    static struct file_operations dev_fops = {   
      .owner = THIS_MODULE,   
      .ioctl = sbc2440_leds_ioctl,   
    };   
      
    static struct miscdevice misc = {   
      .minor = MISC_DYNAMIC_MINOR,   
      .name = DEVICE_NAME,   
      .fops = &dev_fops,   
    };   
      
    static int __init dev_init(void)   
      {   
      int ret;   
      
      int i;   
      
      for (i = 0; i < 4; i++) {   
      s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);   
      s3c2410_gpio_setpin(led_table[i], 0);   
      }   
      
      ret = misc_register(&misc);   
      
      printk (DEVICE_NAME"	initialized
    ");   
      
      return ret;   
    }   
      
    static void __exit dev_exit(void)   
    {   
      misc_deregister(&misc);   
    }   
      
    module_init(dev_init);   
    module_exit(dev_exit);   
    MODULE_LICENSE("GPL");   
    MODULE_AUTHOR("FriendlyARM Inc.");    

    ----------

  • 相关阅读:
    InfluxDB执行语句管理(query management)
    InfluxDB数据备份和恢复方法,支持本地和远程备份
    WordPress多本小说主题–WNovel主题发布,十分钟搭建小说站! 现已更新至1.2版本
    InfluxDB安装后web页面无法访问的解决方案
    Influxdb原理详解
    InfluxDB学习之InfluxDB连续查询(Continuous Queries)
    InfluxDB学习之InfluxDB数据保留策略(Retention Policies)
    InfluxDB学习之InfluxDB的HTTP API查询操作
    玩游戏,王者荣耀,记录
    开源抓包工具PowerSniff(支持lua,c语言作为脚本实时分析)
  • 原文地址:https://www.cnblogs.com/Ph-one/p/4676014.html
Copyright © 2011-2022 走看看