基于设备树的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控制器的寄存器实 ...
随机推荐
- mysql的sql_mode介绍和修改
原文链接: http://blog.csdn.net/wulantian/article/details/8905573 mysql目录下有一个配置文件my.conf. mysql数据库有一个环境 ...
- oracle数据库建表设置自增主键
create sequence userlogin_ID increment by 1 start with 1 minvalue 1 maxvalue 9999999999999999 nocach ...
- sqlserver学习2---java执行存储过程
一.存储过程 1.新增操作存储过程 --------------1.新建 增加学生的存储过程---------------------------- set IDENTITY_INSERT stude ...
- 再学UML-Bug管理系统UML2.0建模实例(一)
1.项目概述 随着软件项目规模和复杂性的增大,有效跟踪和管理项目中存在的缺陷Bug变得越来越重要.每一个软件企业都需要妥善处理软件中的缺陷,这将直接关系到软件过程质量与软件产品质量,但并非 ...
- how find a record import other database.
question:how find a record import other database. answer: solution one:you user insert into table_na ...
- (EXPDP) Fails With Errors ORA-39079 ORA-25306 On One Node In RAC Environment
分类: Oracle DataPump export on one certain RAC instance fails with errors: ORA-39006: internal errorO ...
- C/C++中构造函数和析构函数能否被继承
http://bbs.csdn.net/topics/390160673 标准方面做了要求的.Even though destructors are not inherited 构造函数和析构函数是不 ...
- IOS 照片浏览器总结(思想步骤)
1. 界面分析========================================1> 需要读取或修改属性的控件需要设置属性// 序号标签// 图片// 图片描述// 左边按钮// ...
- Android(java)学习笔记19:Java中InetAddress类概述和使用
1. 要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机. 在TCP/IP协议中,这个标识号就是IP地址. 那么,我们如果获取和 ...
- poj 2356 抽屉原理
基本原理: n+1个鸽子放到n个笼子里,至少有一个笼子里有两只及其以上的鸽子.若有n个笼子,kn+1个鸽子,至少有一个笼子里面有k+1个鸽子: 题意:给定N个数,挑出一些数,他们和和是n的整数倍: 分 ...