写一个公用的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学习资料
写一个公用的gpio口驱动相关推荐
- 如何自己写一个公用的NPM包
以 markdown-clear ,创建过程为例,讲解整个NPM包创建和发布流程 1 如何创建一个包 1.1 创建并使用一个工程 在GitHub上新建一个仓库,其名markdown-clear clo ...
- Linux 通用gpio口驱动,rockchip
dts文件 gpio_rs485: gpio_rs485 {status = "okay";compatible = "gpio,px30-gpio";cnam ...
- linux gpio按键驱动程序,Linux GPIO Key 驱动的加载
gpio-keys是基于input子系统实现的一个通用的GPIO按键驱动,基于platform来实现,位于drivers/input/keyboard/gpio_keys.c,这个文件是硬件无关的,而 ...
- linux编写gpio驱动程序,linux driver ------ GPIO的驱动编写和调用
判断哪些文件被编译进内核: 1.通过 make menuconfig 查看 2.比如查看gpio类型的文件,输入 ls drivers/gpio/*.o,有生成.o文件表示被编译进内核 在编写驱动程序 ...
- 如何写一个树莓派的驱动来控制GPIO LED
一直以来,物联网开发者面对新的硬件都是一件头痛的事情.有些时候明明有现成的驱动,我们却没法直接利用.公司的PM/领导一句话下来,整套系统就要从新来,说明书一看就是一天,重复的软硬联调,日复一日的造轮子 ...
- MTK 驱动开发(3)---GPIO口的使用方法汇总
1简介 GPIO=General Purpose Input Output,通用输入输出.有时候简称为"IO口".通用,就是说它是万金油,干什么都行.输入输出,就是说既能当输入口使 ...
- 实战!手把手教你如何编写一个Linux驱动并写一个支持物联网的LED演示demo
目录 一.开发环境 二. 准备工作: 1. 创建一个项目工程目录 2. 创建输出与目标目录 3.头文件目录 4. 建立源代码src目录 5. 使用git管理你的项目 三.编写LED驱动 三.一 准备工 ...
- 被一个gpio口搞死的一天
今天是新项目调试的第一天. 我起的很早,起早的原因很简单,我家楠哥要我送他上学,他说爸爸没有起到一个当爸爸的责任,他也想让爸爸送他上学,然后我就送了. 7点30起来,8点出发,然后回来看了一下热火对阵 ...
- gpio-sunxi驱动应用gpio口终端操作
内核里gpiolib可以操作gpio口,但基本只能作输入或输出功能.而全志的gpio控制器除这两种功能外,还提供了其它功能,如配置gpio的上下拉,输出电流等级大小等.所以全志提供了类似gpiolib ...
最新文章
- fragment类onresume里面刷新操作处理
- 一个IO的传奇一生(8) -- elevator子系统
- 文巾解题 326. 3的幂
- DL之CNN优化技术:学习卷积神经网络CNN的优化、实践经验(练习调参)、从代码深刻认知CNN架构之练习技巧
- python自动华 (四)
- RUBY ON RAILS 插件收录: CACHE:Sweeper Generator
- flink查看operater链的中间结果+SingleOutputStreamOperator的用法
- keepalive之LVS-DR架构
- [学习笔记] 单位根反演
- python去掉字符串最外侧的引号_疯狂Python讲义第二章读书笔记
- 图的匹配问题与最大流问题(三)——最大流问题Ford-Fulkerson方法Java实现
- RabbitMQ消费端自定义监听(九)
- 烽烟通讯2100万限售股将于3月7日疏通流畅上市
- Mosets Tree开发笔记
- MacOS上 编译GMSSL
- 苹果电脑ping 不通本地网络
- PYTHON 用几何布朗运动模型和蒙特卡罗MONTE CARLO随机过程模拟股票价格可视化分析耐克NKE股价时间序列数据...
- 抗击疫情,程序员在家免费学这些!
- eclipse运行java总显示上一个程序的运行结果(解决方案)
- mysql实现物化视图详解及视图与物化视图区别
热门文章
- 停止过度设计,开发客户需要的软件
- mysql 主主互备实现
- 社交网站与网民隐私安全报告(2009)
- 急救WINDOWS内存错误
- r语言做断轴_R语言用nls做非线性回归以及函数模型的参数估计
- python将字符串写入csv_用Python将字符串值写入CSV文件
- python安装不了jupyter_python学习笔记——Windowns下Python3之安装jupyter
- python leetcode_leetcode 介绍和 python 数据结构与算法学习资料
- iOS 加载本地html文件详细操作
- 非法操作 login.php,阅文游戏中心 h5游戏接入wiki