当前位置: 首页 > news >正文

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\n");  
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\n");  
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"\tinitialized\n");   
  
  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.");    

 

 

 

 

 

----------

转载于:https://www.cnblogs.com/Ph-one/p/4676014.html

相关文章:

  • misc_register、 register_chrdev 的区别总结
  • linux设备驱动那点事儿之平台设备理论篇
  • linux多线程驱动中调用udelay()对整个系统造成的影响(by liukun321咕唧咕唧)...
  • udelay、mdelay、ndelay、msleep使用比较说明
  • A8下超级终端调试问题
  • Linux多线程编程(不限Linux)转
  • Linux 线程优先级
  • 男儿当自强
  • JNI编程(一) —— 编写一个最简单的JNI程序
  • JNI编程(二) —— 让C++和Java相互调用(1)
  • JNI编程(二) —— 让C++和Java相互调用(2)
  • char*,const char*和string的相互转换
  • 请问什么是UTF字符串?
  • jni数据问题
  • sprintf
  • [PHP内核探索]PHP中的哈希表
  • 《剑指offer》分解让复杂问题更简单
  • 【EOS】Cleos基础
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Angular4 模板式表单用法以及验证
  • es6--symbol
  • Flannel解读
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • k个最大的数及变种小结
  • magento2项目上线注意事项
  • spring cloud gateway 源码解析(4)跨域问题处理
  • Vim Clutch | 面向脚踏板编程……
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 初识 webpack
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 订阅Forge Viewer所有的事件
  • 给github项目添加CI badge
  • 基于axios的vue插件,让http请求更简单
  • 学习ES6 变量的解构赋值
  • 学习HTTP相关知识笔记
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​你们这样子,耽误我的工作进度怎么办?
  • #include<初见C语言之指针(5)>
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (C++20) consteval立即函数
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (四)鸿鹄云架构一服务注册中心
  • .Net CF下精确的计时器
  • .NET Core 2.1路线图
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net 验证控件和javaScript的冲突问题
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .net通用权限框架B/S (三)--MODEL层(2)