基于platform驱动模型完成LED驱动的编写

添加设备树文件信息

复制代码
myplatform{
    compatible="hqyj,myplatform";//厂商信息,用于驱动端进行匹配
    interrupt-parent=<&gpiof>;
//关联中断父节点
    interrupts=<9 0>;
//和中断父节点的关系描述符
    led1-gpio=<&gpioe 10 0>;
led2-gpio=<&gpiof 10 0>;
led3-gpio=<&gpioe 8 0>;
//gpio管脚描述符信息
    reg=<0X12345678 0x50>;
//地址信息
    };

pdrv.c

复制代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
struct resource *res;
unsigned int irqno;
struct gpio_desc *gpiono[3];
int pdrv_probe(struct platform_device *pdev) // 当驱动和设备匹配成功后执行
{
    // 获取MEM类型的资源
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (res == NULL)
    {
        printk("获取MEM类型的资源失败\n");
        return -ENXIO;
    }
    // 获取中断类型资源
    irqno = platform_get_irq(pdev, 0);
    if (irqno < 0)
    {
        printk("获取中断类型资源失败\n");
        return -ENXIO;
    }
    printk("MEM类型资源为%x\n", res->start);
    printk("中断类型资源为%d\n", irqno);
    // 获取gpio信息
    gpiono[0] = gpiod_get_from_of_node(pdev->dev.of_node, "led1-gpio", 0, GPIOD_OUT_HIGH, NULL);
    if (IS_ERR(gpiono[0]))
    {
        printk("解析GPIO 0信息失败\n");
        return -PTR_ERR(gpiono[0]);
    }

    gpiono[1] = gpiod_get_from_of_node(pdev->dev.of_node, "led2-gpio", 0, GPIOD_OUT_HIGH, NULL);
    if (IS_ERR(gpiono[1]))
    {
        printk("解析GPIO 1信息失败\n");
        return -PTR_ERR(gpiono[1]);
    }

    gpiono[2] = gpiod_get_from_of_node(pdev->dev.of_node, "led3-gpio", 0, GPIOD_OUT_HIGH, NULL);
    if (IS_ERR(gpiono[2]))
    {
        printk("解析GPIO 2信息失败\n");
        return -PTR_ERR(gpiono[2]);
    }

    printk("解析GPIO信息成功,LED亮\n");
    return 0;
}

int pdrv_remove(struct platform_device *pdev) // 当设备和驱动分离时执行
{
    // 释放GPIO信息]

    gpiod_set_value(gpiono[0], 0);
    gpiod_put(gpiono[0]);

    gpiod_set_value(gpiono[1], 0);
    gpiod_put(gpiono[1]);

    gpiod_set_value(gpiono[2], 0);
    gpiod_put(gpiono[2]);
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
// 构建设备树匹配表
struct of_device_id oftable[] = {
    {
        .compatible = "hqyj,myplatform",
    },
    {
        .compatible = "hqyj,myplatform1",
    },
    {}, // 防止数组越界
};
// 1.分配驱动信息对象
struct platform_driver pdrv = {
    .probe = pdrv_probe,
    .remove = pdrv_remove,
    .driver = {
        .name = "bbbbb", // 驱动名
        .of_match_table = oftable,
    },

};
// 一键注册宏
module_platform_driver(pdrv);
MODULE_LICENSE("GPL");
相关推荐
AOI小白新手上路12 分钟前
韦东山《ARM 架构与编程》3-3 IMX6ULL 的 GPIO 操作方法 · 学习笔记
arm开发·学习·架构
Awh-20 分钟前
ARM 裸机开发 DAY5 学习笔记
arm开发·笔记·学习
Eloudy1 小时前
全文 - 第 01 章 CHI Issue.B specification
arm开发·issue
狂奔蜗牛(bradley)14 小时前
拒绝SOEM黑盒!死磕EtherCAT主站:ARM+FPGA架构、DC同步与状态机修复等,50+篇实战开发文档全公开
arm开发·fpga开发·架构
女神下凡19 小时前
芯参谋(31):SPI NOR Flash 电路设计指南
arm开发·单片机·嵌入式硬件·fpga开发·设计规范
程序员JerrySUN20 小时前
Jetson边缘嵌入式实战课程第四讲:用 Yocto 定制 Jetson 系统,从开发走向产品化
arm开发·人工智能·安全·计算机视觉·目标跟踪
女神下凡7 天前
嵌入式设计的各种存储芯片的硬件/软件设计规范,非常全面。
arm开发·单片机·嵌入式硬件
从零开始的嵌入式之旅7 天前
day47
arm开发·经验分享·笔记·嵌入式硬件
老当益壮梁奶奶7 天前
ARM汇编学习笔记(六):【i.MX6ULL】时钟系统与定时器(EPIT & GPT)
c语言·arm开发·嵌入式硬件·学习·51单片机
昌原的儿子LEO7 天前
IMX6ULL 时钟系统与 EPIT/GPT 定时器原理与配置
arm开发·学习