#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/mach/map.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#if 0
backlight {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
};
#endif
/*驱动入口函数*/
static int __init dtsof_init(void)
{
struct device_node * bl_nd1=NULL;//设备树节点
struct property *com;//获取到的属性
int elem;//属性元素的数量
const char *a;
int ret=0;
int i=0;
u32 *brial;//申请内存指针
char aac[100]="xiongxiao";
printk("%s\n",aac);
#if 0
/*以节点名获取设备节点*/
bl_nd=of_find_node_by_name(NULL,"backlight");
if(bl_nd=NULL)
{
printk("of_find_node_by_name failed\r\n");
return -EINVAL;
}
# endif
/*以路径名获取设备节点*/
bl_nd1=of_find_node_by_path("/backlight");
if(bl_nd1==NULL)
{
printk("of_find_node_by_path failed\r\n");
return -EINVAL;
}
/*获取compatible的属性内容*/
com=of_find_property(bl_nd1,"compatible",NULL);
if(com==NULL)
{
printk("of_find_property failed\r\n");
return -EINVAL;
}else{
printk("compatible=%s\r\n",(char *)com->value);
}
//读取brightness-levels属性中元素的数量
elem=of_property_count_elems_of_size(bl_nd1,"brightness-levels",sizeof(u32));
printk("%d\n",elem);
//以字符串的形式读取status的属性值
ret=of_property_read_string(bl_nd1,"status",&a);
if(ret==0){
printk("status=%s\r\n",a);
printk("\n");
}
/*获取属性brightness-levels = <0 4 8 16 32 64 128 255>中元素的内容*/
brial=kmalloc(elem*sizeof(u32),GFP_KERNEL);//申请一段内存
if(!brial)
{
kfree(brial);
ret=-EINVAL;
}
ret=of_property_read_u32_array(bl_nd1,"brightness-levels",brial,elem);//读取 //"brightness-levels"属性内容
if(ret<0)
{
printk("of_property_read_u32_array\n");
}else{
for(i=0;i<elem;i++)
{
printk("brightness-levels[%d]=%d\n",i,*(brial+i));
}
}
kfree(brial);//释放内存
return 0;
}
/*驱动出口函数*/
static void __exit dtsof_exit(void)
{
}
/*模块的加载与注销*/
module_init(dtsof_init);
module_exit(dtsof_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("liuchuanqiang");
程序说明:
1、struct device_node *of_find_node_by_name(struct device_node *from, const char *name); 通过节点名字查找指定的节点
from:开始查找的节点,如果为NULL表示从根节点开始查找整个设备树。
name:要查找的节点名字
返回值:找到的节点,如果为 NULL 表示查找失败。
2、inline struct device_node *of_find_node_by_path(const char *path) 通过路劲名来查找设备节点
path:带有全路径的节点名,可以使用节点的别名,比如“/backlight”就是 backlight 这个节点的全路径。
返回值:找到的节点,如果为 NULL 表示查找失败
3、struct property *of_find_property(const struct device_node *np, const char *name, int *lenp) 用来查找指定的属性
函数参数和返回值含义如下:
np:设备节点。
name: 属性名字。
lenp:属性值的字节数。
返回值:找到的属性。
com=of_find_property(bl_nd1,"compatible",NULL);其中com是struct property *类型。可以使用com这个指针变量去访问(char *)com->value得到具体的属性内容。
4、of_property_count_elems_of_size 函数用于获取属性中元素的数量。
int of_property_count_elems_of_size(const struct device_node *np, const char *propname, int elem_size)
函数参数和返回值含义如下:
np:设备节点。
proname: 需要统计元素数量的属性名字。
elem_size:元素长度。单个元素所占的字节数
返回值:得到的属性元素数量。
5、int of_property_read_u32_array(const struct device_node *np, const char *propname,
u32 *out_values, size_t sz)
一次读出数据中所有的数据,读取到的数据保存到
np:设备节点。
proname: 要读取的属性名字。
out_value:读取到的数组值,分别为 u8、u16、u32 和 u64。
sz:要读取的数组元素数量。
返回值:0,读取成功,负值,读取失败,-EINVAL 表示属性不存在,-ENODATA 表示没
有要读取的数据,-EOVERFLOW 表示属性值列表太小。
6、brial=kmalloc(elem*sizeof(u32),GFP_KERNEL);//申请一段内存,程序执行完以后需要使用kfree(brial);释放内存。
7、of_property_read_string 函数用于读取属性中字符串值,函数原型如下:
int of_property_read_string(struct device_node *np, const char *propname, const char **out_string)
函数参数和返回值含义如下:
np:设备节点。
proname: 要读取的属性名字。
out_string:读取到的字符串值。out_string数组地址的取址。
返回值:0,读取成功,负值,读取失败。