写一个公用的gpio口驱动

因为项目需要控制的GPIO口比较多,如果每个GPIO口都写一个驱动就显得比骄麻烦,所以就写了一个通用的GPIO口驱动。只要dts里面配置好设备GPIO相关信息就可以自动加载了。可以很充分的体现多个设备一个驱动的优良性。

dts文件

    gpio_rs485: gpio_rs485 {status = "okay";compatible = "gpio,px30-gpio";cname = "rs485";en-gpio = <&gpio3 12 GPIO_ACTIVE_HIGH>;};

驱动源代码

#include <dt-bindings/gpio/gpio.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/slab.h>struct gpio_dev_data {int en_pin;int en_val;int gpio_val;
};static struct of_device_id gpio_of_match[] = {{ .compatible = "gpio,px30-gpio" },{ }
};MODULE_DEVICE_TABLE(of, gpio_of_match);static ssize_t gpio_store_en(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct gpio_dev_data *dev_data = dev_get_drvdata(dev);unsigned long value = 0;int ret;/*将echo进来的buf转换成整型*/ret = kstrtoul(buf, 16, &value);if (ret < 0) {printk( "%s:kstrtoul failed, ret=%d\n", __func__, ret);return ret;}printk("%s: en value : %d\n", __func__, (int)value);if (value) {gpio_direction_output(dev_data->en_pin, dev_data->en_val);dev_data->gpio_val = 1;} else {gpio_direction_output(dev_data->en_pin, !dev_data->en_val);dev_data->gpio_val = 0;}return count;
}static  char mybuf[10]="123";/*cat命令时,将会调用该函数*/
static ssize_t gpio_show_en(struct device *dev,struct device_attribute *attr, char *buf)       
{struct gpio_dev_data *dev_data = dev_get_drvdata(dev);snprintf(mybuf,sizeof(mybuf),"%d",dev_data->gpio_val);return sprintf(buf, "%s\n", mybuf);
}static DEVICE_ATTR(gpio_en, S_IWUSR, gpio_show_en, gpio_store_en);static int gpio_probe(struct platform_device *pdev)
{struct device_node *node = pdev->dev.of_node;enum of_gpio_flags flags;int gpio;int ret;int en_value;struct class *dev_class;struct device *ctl_dev;struct gpio_dev_data *dev_data;int err;const char *class_name;printk("%s enter: %d\n", __func__, __LINE__);if (!node)return -ENODEV;/*获取gpio口*/gpio = of_get_named_gpio_flags(node, "en-gpio", 0, &flags);en_value = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0;if (!gpio_is_valid(gpio)) {dev_err(&pdev->dev, "invalid en gpio%d\n", gpio);}ret = devm_gpio_request(&pdev->dev, gpio, "onoff");if (ret) {dev_err(&pdev->dev,"failed to request GPIO%d for \n",gpio);return -EINVAL;}/*设置probe的默认电平*/gpio_direction_output(gpio, !en_value);dev_data = kzalloc(sizeof(struct gpio_dev_data), GFP_KERNEL);if (dev_data == NULL) {printk("Failed to malloc gpio_dev_data\n");return -ENOMEM;}if(en_value > 0)dev_data->gpio_val = 0;elsedev_data->gpio_val = 1;/*创建class节点*/err = of_property_read_string(node, "cname", &class_name);if(err){printk("%s get class name error %d\n",__FUNCTION__,__LINE__);return -EINVAL;}dev_class = class_create(THIS_MODULE, class_name);ctl_dev = device_create(dev_class, NULL, 0, NULL, "onoff");if (IS_ERR(ctl_dev)) {dev_err(ctl_dev, "Failed to create device\n");ret = PTR_ERR(ctl_dev);goto err_create_dev;}err = device_create_file(ctl_dev, &dev_attr_gpio_en);if (err)printk("driver_create_file = %d\n", err);/*获取的gpio赋值全局变量*/dev_data->en_pin = gpio;dev_data->en_val = en_value;dev_info(ctl_dev, "%s: %d\n", __func__, __LINE__);dev_info(&pdev->dev, "%s: %d\n", __func__, __LINE__);dev_set_drvdata(ctl_dev, dev_data);dev_set_drvdata(&pdev->dev, dev_data);return 0;err_create_dev:kfree(dev_data);return ret;
}static int gpio_remove(struct platform_device *pdev)
{printk("%s: %d\n", __func__, __LINE__);return 0;
}#ifdef CONFIG_PM_SLEEP
static int gpio_suspend(struct device *dev)
{struct gpio_dev_data *dev_data = dev_get_drvdata(dev);dev_info(dev, "%s: %d\n", __func__, __LINE__);gpio_direction_output(dev_data->en_pin, !dev_data->en_val);return 0;
}static int gpio_resume(struct device *dev)
{printk("%s: %d\n", __func__, __LINE__);return 0;
}
#endifstatic const struct dev_pm_ops gpio_pm_ops = {
#ifdef CONFIG_PM_SLEEP.suspend = gpio_suspend,.resume = gpio_resume,.poweroff = gpio_suspend,.restore = gpio_resume,
#endif
};static struct platform_driver gpio_driver = {.driver		= {.name	= "gpio-en",.owner	= THIS_MODULE,.pm		= &gpio_pm_ops,.of_match_table	= of_match_ptr(gpio_of_match),},.probe		= gpio_probe,.remove		= gpio_remove,
};module_platform_driver(gpio_driver);MODULE_AUTHOR("Weiqifa <329410527@qq.com>");
MODULE_DESCRIPTION("simple gpio driver");
MODULE_LICENSE("GPL");

Makefile文件

obj-$(CONFIG_GPIO_CONTROL) += gpio_control.o

Kconfig

config GPIO_CONTROLtristate "GPIO control driver"default nhelpGPIO control driver.	

  回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467875.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(5)

文章目录各种算法选择排序插入排序希尔排序***快速排序***归并排序二分查找各种算法 def bubble_sort(alist):"""冒泡排序"""n len(alist)for j in range(n-1):count 0for i in range(0, n-1-j):# 班长从头走到尾if alist[i] > alist[i1]:a…

大神们都应该去哪里工作?

接上一篇文章。文中提到我认识了一个做嵌入式的大神&#xff0c;技术真的非常厉害。我们在调试过程中&#xff0c;遇到问题&#xff0c;他总是能告诉我们排查的手段&#xff0c;而且针对一个问题&#xff0c;他能想到几种不同的解决方案。嵌入式驱动跟其他软件有点不一样&#…

堆喷射

堆喷射主要用于绕过ASLR。下面演示堆喷射分析与效果。 1.代码 void heap_spray(){   char chunk[LEN] { 0 };   memset(chunk, 0x90, LEN - 10);   strcat(chunk, "shellcode");   for (int i 0;i < 100;i)   {     void *p malloc(LEN);    …

大华管理平台用户名_智能财务引领商业与管理变革——浙大EMBA首席财务官研习社走进大华股份...

杭商传媒记者 周 珂/文 徐青青/摄编辑 何影丹当前经济环境和市场需求瞬息万变&#xff0c;企业竞争日益激烈&#xff0c;盈利持续下降&#xff0c;产品、服务同质化严重&#xff0c;这不仅对业务部门提出了挑战&#xff0c;也对传统的财务管理产生了巨大的冲击。财务不能高…

【深度】韦东山:一文看尽 linux对中断处理的前世今生

作者&#xff1a;韦东山前言&#xff1a;本文&#xff0c;4200字&#xff0c;研究代码花了一天&#xff0c;写出来花了一天&#xff1b;录视频估计又得花半天&#xff1b;真怀念以前简单粗暴的生活啊&#xff1a;拿起话筒就录视频&#xff0c;先画好图&#xff1f;那是不需要的…

数据结构(6)二叉树

文章目录二叉树二叉树三种遍历二叉树知中及先或后序&#xff0c;求二叉树二叉树 class Node(object):""""""def __init__(self, item):self.elem itemself.lchild Noneself.rchild Noneclass Tree(object):"""二叉树"&qu…

鼠标中间无法打开新标签_还记得鼠标有几个键?Win10环境鼠标中键的妙用

大家经常使用鼠标&#xff0c;但有多少人还能意识到&#xff0c;其实鼠标是有三个键的&#xff1f;除了常用的左键右键&#xff0c;鼠标中间的滚轮也可以按下去&#xff0c;然而鼠标的这个中键&#xff0c;却日常坐冷板凳&#xff0c;几乎被人所遗忘。其实&#xff0c;鼠标中键…

vue技术栈

1 vue 说明:vue生命周期&#xff1a;技术点&#xff1a;1&#xff1a;常用的API:computed&#xff0c;methods&#xff0c;props&#xff0c;mounted&#xff0c;created&#xff0c;components 2vue-cli说明:vue绞手架&#xff0c;用于快速搭建项目&#xff0c;并管理项目技术…

python中pillow库怎么使用_Python 图像库Pillow使用

需求是将一张含有透明度的图片和一张正常图片进行常规合并&#xff0c;并在图片上添加文字&#xff0c;代码如下&#xff1a;from PIL import Imageimport cv2base_image Image.open(图片的绝对路径) # 有透明度的图片target Image.new(RGB, base_image.size, (0, 0, 0, 0)) …

找不到问题的核心,你永远解决不了问题。

上学那会儿&#xff0c;我是个数学常拿60分的人&#xff08;满分150分&#xff09;&#xff0c;我却喜欢做几何题。根据已知的条件&#xff0c;推导出所需的其他条件&#xff0c;所有需要的条件得出后&#xff0c;再根据正确的公式算出所求的值。这个不断求解的过程其实挺有意思…

.net MVC路由

首先&#xff0c;在MVC应用程序的入口函数Application_Start()中(在事件在GLOBAL文件中)&#xff0c;通过RouteConfig.RegisterRoutes(RouteTable.Routes)注册路由集合信息。RouteTable.Routes是一个公开的路由集对象&#xff0c;用于保存路由信息集合信息&#xff0c;类型问Ro…

浏览器访问pdf 的url怎么加密_怎么解决加密的pdf文件?

加密版的PDF文件我们每次打开时都需要输入密码才能进行阅读&#xff0c;而且一般不能直接进行复制和打印&#xff0c;这样会非常的麻烦。那如果我门想要解决这一问题呢就要将pdf文件的密码进行解除&#xff0c;可是如果是平民的我们不会解决怎么办呢&#xff1f;毕竟我们又不是…

范文100篇(2)

文章目录Should College Students Follow Fashion?思路翻译词汇句型Should College Students Follow Fashion? Today’s college students live in a word of fashion and some of them are keen on pursuing all the time.In fact, it is not uncommon to see some college…

Linux Storage入门学习

前言本文大量代码基于linux 0.11&#xff0c;因为早期linux的版本更加适合初学者入门。虽然代码比较早&#xff0c;但是不妨碍我们学习Linux Storage的精髓。一、hello world1.1 Demo#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include&l…

地铁客流检测训练问题记录

一 报错&#xff1a; File "/home/jz/py-faster-rcnn/tools/../lib/datasets/pascal_voc.py", line 183, in _load_pascal_annotation tree ET.parse(filename) File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1182, in parse tree.parse(sou…

python价值观测试程序例子_PyBrains学习迷宫的例子。国家价值观与全球政策

现在我添加了另一个约束-通过在迷宫.py现在我在1000次跑步后得到了这种行为&#xff0c;每次跑步有200次互动&#xff1a;现在哪种方式有意义-机器人试图从另一边绕墙&#xff0c;避开状态(1&#xff0c;7)所以&#xff0c;我得到了奇怪的结果&#xff0c;因为特工过去总是从随…

记一次和摄像头的摩擦经历

因为时间的原因&#xff0c;这次点亮摄像头的时间特别短&#xff0c;昨天下午模组到公司&#xff0c;今天下午点亮。几个人一起调试&#xff0c;发现的问题也很多&#xff0c;今天下午发现有一个怀疑的问题&#xff0c;我马上驱车几十公里去模组厂调试&#xff0c;回来的时候&a…

算法题

简单题 整数反转 给出一个 32 位的有符号整数&#xff0c;你需要将这个整数中每位上的数字进行反转。 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: 假设我们的环境只能存储得下 32 位的有符号整数&#xff0c;则其数值范围…

ES6箭头函数(节选自《ECMAScript 6 入门》)

基本用法 ES6 允许使用“箭头”&#xff08;>&#xff09;定义函数。 var f v > v; 上面的箭头函数等同于&#xff1a; var f function(v) {return v; }; 如果箭头函数不需要参数或需要多个参数&#xff0c;就使用一个圆括号代表参数部分。 var f () > 5; // 等同于…

声明为指针,定义为数组,声明为数组,定义为指针

之前写发的那篇指针和数组的文章&#xff0c;有网友评论觉得不是很舒服&#xff0c;我自己看了&#xff0c;觉得很不满意。所以想再写写&#xff0c;尽量把这个东西讲清楚。#定义为数组&#xff0c;声明为指针1.c中#include "stdio.h" char array[] "abcd"…