基于设备树的led驱动程序
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/bitmap.h>
#include <asm/gpio.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/of.h> static volatile unsigned long *ledcon;
static volatile unsigned long *leddat;
static struct class *led_class;
static unsigned int pin_th;
dev_t led_dev;
struct cdev *cdev; /* 打开led灯 */
static int led_open(struct inode *inode, struct file *file)
{
*ledcon &= ~(0x3 << (pin_th * ));
*ledcon |= (0x1 << (pin_th * ));
*leddat &= ~( << pin_th);
return ;
} static struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
}; static int led_probe(struct platform_device *pdev)
{
int pin_info;
int phy_addr;
int io_base;
of_property_read_s32(pdev->dev.of_node, "pin", &pin_info);
printk("pin_info = 0x%x\n", pin_info);
of_property_read_s32(pdev->dev.of_node, "iobase", &io_base);
printk("io_base = 0x%x\n", io_base);
pin_th = pin_info & (0xffff);
phy_addr = (io_base | ((pin_info>>)<<));
ledcon = ioremap(phy_addr, );
leddat = ledcon + ; if (alloc_chrdev_region(&led_dev, MINOR(led_dev), , "led"))
return -;
cdev = cdev_alloc();
if (!cdev)
return -;
cdev_init(cdev, &led_fops);
cdev_add(cdev, led_dev, ); led_class = class_create(THIS_MODULE, "led");
device_create(led_class,NULL,led_dev,NULL,"led0"); // is /dev/led0 return ; } int led_remove(struct platform_device *pdev)
{
device_destroy(led_class, led_dev);
class_destroy(led_class);
cdev_del(cdev);
unregister_chrdev_region(led_dev, );
iounmap(ledcon);
return ;
} static struct of_device_id led_id[] = {
{.compatible = "jz2440_led"},
{},
}; static struct platform_driver led_drv = {
.probe = led_probe,
.remove = led_remove,
.driver = {
.name = "jz2440_led",
.of_match_table = led_id,
},
}; static int led_init(void)
{
platform_driver_register(&led_drv);
return ;
} static void led_exit(void)
{
platform_driver_unregister(&led_drv);
} module_init(led_init);
module_exit(led_exit); MODULE_LICENSE("GPL");
以上是驱动程序,下面是设备树dts文件:
#define S3C2440_GPA(_nr) ((0<<16) + (_nr))
#define S3C2440_GPB(_nr) ((1<<16) + (_nr))
#define S3C2440_GPC(_nr) ((2<<16) + (_nr))
#define S3C2440_GPD(_nr) ((3<<16) + (_nr))
#define S3C2440_GPE(_nr) ((4<<16) + (_nr))
#define S3C2440_GPF(_nr) ((5<<16) + (_nr))
#define S3C2440_GPG(_nr) ((6<<16) + (_nr))
#define S3C2440_GPH(_nr) ((7<<16) + (_nr))
#define S3C2440_GPJ(_nr) ((8<<16) + (_nr))
#define S3C2440_GPK(_nr) ((9<<16) + (_nr))
#define S3C2440_GPL(_nr) ((10<<16) + (_nr))
#define S3C2440_GPM(_nr) ((11<<16) + (_nr)) /dts-v1/; / {
model = "SMDK2440";
compatible = "samsung,smdk2440"; #address-cells = <>;
#size-cells = <>; memory@ {
device_type = "memory";
reg = <0x30000000 0x4000000>;
};
chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
}; led {
compatible = "jz2440_led";
pin = <S3C2440_GPF()>;
iobase = <0x56000000>;
};
};
基于设备树的led驱动程序的更多相关文章
- 基于设备树的controller学习(2)
作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux-4.10.17 概述 上一篇大概介绍了一下demo-controller的结构,下面结合驱动分析. 正文 ...
- 基于设备树的TQ2440触摸屏驱动移植
平台 开发板:tq2440 内核:Linux-4.9 u-boot:u-boot-2015.04 概述 之前移植了LCD驱动,下面继续移植触摸屏驱动,然后将tslib也移植上去. 正文 一.移植触 ...
- 基于设备树的TQ2440的中断(2)
下面以按键中断为例看看基于设备数的中断的用法: 设备树: tq2440_key { compatible = "tq2440,key"; interrupt-parent = &l ...
- 基于设备树的controller学习(1)
作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.10.17 概述 在设备树中我们经常见到诸如"#clock-cells"."# ...
- 基于设备树的TQ2440的中断(1)
作者 姓名:彭东林 E-mail:pengdonglin137@163.com QQ:405728433 平台 板子:TQ2440 内核:Linux-4.9 u-boot: 2015.04 工具链: ...
- 芯灵思Sinlinx A64 linux 通过设备树写LED驱动(附参考代码,未测试)
开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 全志A64设备树结构体 #inc ...
- 基于设备树的TQ2440 DMA学习(3)—— DMA控制器驱动
作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.9 概述 上一篇直接操作DMA控制器实现了一个mem2mem的DMA传输,但是这样不符合linux driv ...
- 基于设备树的TQ2440 DMA学习(4)—— client驱动
作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.9 概述 前面分析了DMA控制器驱动,下面我们调用DMAENGINE的API写一个MEM2MEM的驱动 正文 ...
- 基于设备树的TQ2440 DMA学习(2)—— 简单的DMA传输
作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux-4.9 概述 上一篇博客分析了DMA控制器的寄存器,循序渐进,下面我们直接操作DMA控制器的寄存器实 ...
随机推荐
- 网络威胁防护,Azure 靠的是它?
在当今数字化转型的浪潮中,越来越多的企业希望转型于云.使用云能帮助企业提高工作效率.降低 IT 成本.增强竞争优势,有效推动企业的业务发展.但是,在向云迁移的过程中,基于云的数据中心更有可能被攻击,所 ...
- ThinkPHP5专题
TinkPHP5中 1. model中select()后的查询结果是对象而不是数组 2. model中 假如有 $result=$this->field($fields)->where($ ...
- SVN:验证位置时发生错误解决方案
1. 2. 3.preferencens > svn >svn接口-选择SVNKit(Pure Java)设置后,再引用svn路径后,直接弹出输入用户名和密码就对了. 4.
- cs229 斯坦福机器学习笔记(一)-- 入门与LR模型
版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/Dinosoft/article/details/34960693 前言 说到机器学习,非常多人推荐的学习资 ...
- 在Spring整合aspectj实现aop的两种方式
-----------------------------基于XML配置方案目标对象接口1 public interface IUserService { public void add(); pub ...
- MVC学习三:Razor视图引擎
1.Razor视图引擎,主要是把View的HTML代码编译到View视图类对象中
- P4722 【模板】最大流
P4722 [模板]最大流 加强版 / 预流推进 今日心血来潮,打算学习hlpp 然后学了一阵子.发现反向边建错了.容量并不是0.qwq 然后就荒废了一晚上. 算法流程的话.有时间补上 #includ ...
- 9.Element-ui的校验规则Rules
Element-ui的校验规则Rules <el-form label-position="left" label-width="80px" :model ...
- oracle-02 用户管理
一.创建用户概述:在oracle中要创建一个新的用户使用create user语句,一般是具有dba(数据库管理员)的权限才能使用.create user 用户名 identified by 密码; ...
- Flask—04-文件上传与邮件发送(自带优化)
文件上传与邮件发送 可以按照标题分别直接粘贴对应的文件夹,运行直接用: 原生上传 模板文件 <form method="post" enctype="multipa ...