第一部分 说明
1、创建了misc设备
2、创建设备属性文件,并实现操作接口
第二部分 代码;例程
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/proc_fs.h>
#include <linux/input/mt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/err.h>
#include <linux/miscdevice.h>
//写一份代码实现拉对应gpio的管脚
//-----------------------dts----------------------
/*
mynode :test_node {
compatible = "huangzb,test_node";
test-gpio = <&pio 45 0>;//45表示gpio的编号
};
*/
//-----------------------drv----------------------
const struct of_device_id proc_test_of_match[] = {
{ .compatible = "huangzb,test_node", },
{}
};
//------------------------创建设备节点:/sys/class/test_node-------------
static int test_gpio;
static int status=-1;
void gpio_status_exchange(int cmd)
{
gpio_set_value(test_gpio,cmd);
status = cmd;
return;
}
static ssize_t test_device_read(struct device *dev,struct device_attribute *attr, char *buf)
{
return sprintf(buf,"status=%d\n",status);
}
static ssize_t test_device_write(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
int cmd=0;
sscanf(buf, "%d", &cmd);
gpio_status_exchange(cmd);
return count;
}
DEVICE_ATTR(test_device, 0664, test_device_read, test_device_write);
static struct attribute *my_device_attributes[] = {
&dev_attr_test_device.attr,
NULL
};
static struct attribute_group my_device_group = {
.attrs = my_device_attributes
};
int shf_open (struct inode *node, struct file *file)
{
printk("%s() begin!\n", __func__);
return 0;
}
int shf_release (struct inode *node, struct file *file)
{
printk("%s() begin!\n", __func__);
return 0;
}
struct file_operations shf_fops = {
.owner = THIS_MODULE,
.open= shf_open,
.release = shf_release,
};
struct miscdevice shf_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "shf",
.fops = &shf_fops,
};
static int test_node_create_device(void)
{
int ret;
ret = misc_register(&shf_device);
if(ret<0){
printk("%s() misc_register error!\n", __func__);
}
ret = sysfs_create_group(&shf_device.this_device->kobj, &my_device_group);
if (ret < 0) {
printk("%s() sysfs_create_group error!\n", __func__);
goto dev_err;
}
dev_err:
return ret;
}
static int test_node_init(void)
{
struct device_node *test_node = NULL;//定义一个节点
int ret;
printk("%s() begin!\n", __func__);
//通过compatible找到dts中的节点
test_node = of_find_matching_node(test_node,&proc_test_of_match[0]);
if (IS_ERR(test_node)) {
printk("----^_^ %s---dts'node has found---------\n",__FUNCTION__);
}
//获取gpio号
test_gpio = of_get_named_gpio(test_node, "test-gpio", 0);
if(test_gpio<0){
printk("get gpio error,failed");
return -1;
}
ret = test_node_create_device();
if(ret<0){
printk("%s error,failed\n",__func__);
}
printk("%s() ok!\n", __func__);
return 0;
}
static void test_node_exit(void)
{
sysfs_remove_group(NULL, &my_device_group);
printk("%s()!\n", __func__);
}
module_init(test_node_init);
module_exit(test_node_exit);
MODULE_DESCRIPTION("MTK gpio driver");
MODULE_AUTHOR("<huangzb>");
MODULE_LICENSE("GPL");