因为项目需要控制的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口驱动相关推荐

  1. 如何自己写一个公用的NPM包

    以 markdown-clear ,创建过程为例,讲解整个NPM包创建和发布流程 1 如何创建一个包 1.1 创建并使用一个工程 在GitHub上新建一个仓库,其名markdown-clear clo ...

  2. Linux 通用gpio口驱动,rockchip

    dts文件 gpio_rs485: gpio_rs485 {status = "okay";compatible = "gpio,px30-gpio";cnam ...

  3. linux gpio按键驱动程序,Linux GPIO Key 驱动的加载

    gpio-keys是基于input子系统实现的一个通用的GPIO按键驱动,基于platform来实现,位于drivers/input/keyboard/gpio_keys.c,这个文件是硬件无关的,而 ...

  4. linux编写gpio驱动程序,linux driver ------ GPIO的驱动编写和调用

    判断哪些文件被编译进内核: 1.通过 make menuconfig 查看 2.比如查看gpio类型的文件,输入 ls drivers/gpio/*.o,有生成.o文件表示被编译进内核 在编写驱动程序 ...

  5. 如何写一个树莓派的驱动来控制GPIO LED

    一直以来,物联网开发者面对新的硬件都是一件头痛的事情.有些时候明明有现成的驱动,我们却没法直接利用.公司的PM/领导一句话下来,整套系统就要从新来,说明书一看就是一天,重复的软硬联调,日复一日的造轮子 ...

  6. MTK 驱动开发(3)---GPIO口的使用方法汇总

    1简介 GPIO=General Purpose Input Output,通用输入输出.有时候简称为"IO口".通用,就是说它是万金油,干什么都行.输入输出,就是说既能当输入口使 ...

  7. 实战!手把手教你如何编写一个Linux驱动并写一个支持物联网的LED演示demo

    目录 一.开发环境 二. 准备工作: 1. 创建一个项目工程目录 2. 创建输出与目标目录 3.头文件目录 4. 建立源代码src目录 5. 使用git管理你的项目 三.编写LED驱动 三.一 准备工 ...

  8. 被一个gpio口搞死的一天

    今天是新项目调试的第一天. 我起的很早,起早的原因很简单,我家楠哥要我送他上学,他说爸爸没有起到一个当爸爸的责任,他也想让爸爸送他上学,然后我就送了. 7点30起来,8点出发,然后回来看了一下热火对阵 ...

  9. gpio-sunxi驱动应用gpio口终端操作

    内核里gpiolib可以操作gpio口,但基本只能作输入或输出功能.而全志的gpio控制器除这两种功能外,还提供了其它功能,如配置gpio的上下拉,输出电流等级大小等.所以全志提供了类似gpiolib ...

最新文章

  1. fragment类onresume里面刷新操作处理
  2. 一个IO的传奇一生(8) -- elevator子系统
  3. 文巾解题 326. 3的幂
  4. DL之CNN优化技术:学习卷积神经网络CNN的优化、实践经验(练习调参)、从代码深刻认知CNN架构之练习技巧
  5. python自动华 (四)
  6. RUBY ON RAILS 插件收录: CACHE:Sweeper Generator
  7. flink查看operater链的中间结果+SingleOutputStreamOperator的用法
  8. keepalive之LVS-DR架构
  9. [学习笔记] 单位根反演
  10. python去掉字符串最外侧的引号_疯狂Python讲义第二章读书笔记
  11. 图的匹配问题与最大流问题(三)——最大流问题Ford-Fulkerson方法Java实现
  12. RabbitMQ消费端自定义监听(九)
  13. 烽烟通讯2100万限售股将于3月7日疏通流畅上市
  14. Mosets Tree开发笔记
  15. MacOS上 编译GMSSL
  16. 苹果电脑ping 不通本地网络
  17. PYTHON 用几何布朗运动模型和蒙特卡罗MONTE CARLO随机过程模拟股票价格可视化分析耐克NKE股价时间序列数据...
  18. 抗击疫情,程序员在家免费学这些!
  19. eclipse运行java总显示上一个程序的运行结果(解决方案)
  20. mysql实现物化视图详解及视图与物化视图区别

热门文章

  1. 停止过度设计,开发客户需要的软件
  2. mysql 主主互备实现
  3. 社交网站与网民隐私安全报告(2009)
  4. 急救WINDOWS内存错误
  5. r语言做断轴_R语言用nls做非线性回归以及函数模型的参数估计
  6. python将字符串写入csv_用Python将字符串值写入CSV文件
  7. python安装不了jupyter_python学习笔记——Windowns下Python3之安装jupyter
  8. python leetcode_leetcode 介绍和 python 数据结构与算法学习资料
  9. iOS 加载本地html文件详细操作
  10. 非法操作 login.php,阅文游戏中心 h5游戏接入wiki