Android 驱动-点灯例子

Android 驱动-点灯方法

一,通过设备树属性
 

1. 设备树
&leds_test_node
{
    compatible = "leds_test";
    status = "disable";
    // 添加属性 of_get_name_gpio(node, "gpios1", 0)
    gpios1 = <&gpl2  0 GPIO_ACTIVE_HIGH>;
    gpios2 = <&gpk1 1 GPIO_ACTIVE_HIGH>;
}

2. 解析设备树
int gpio_pin[2] = {-1, -1};

static int leds_probe(struct platform_device *pdev)
{
    int ret;
    struct pinctl *pinctl;
    struct device *dev = &pdev->dev;

    pinctl = devm_pinctl_get_select_default(dev);

    // gpio编号
    gpio_pin[0] = of_get_name_gpio(node, "gpios1", 0);
    gpio_pin[1] = of_get_name_gpio(node, "gpios2", 0);

    // 申请
    ret = gpio_request(gpio_pin[0], "led1");
    if (ret != 0)
    {
        printk("gpio request failed\n");
        return ret;
    }

    ret = gpio_request(gpio_pin[1], "led2");
    if (ret != 0)
    {
        printk("gpio request failed\n");
        return ret;
    }

    gpio_free(gpio_pin[0]);
    gpio_free(gpio_pin[1]);

    gpio_direction_output(gpio_pin[0], 0);
    gpio_set_value(gpio_pin[0], 1);

    gpio_direction_output(gpio_pin[1], 0);
    gpio_set_value(gpio_pin[1], 1);
    return 0;
}

二,通过设备树引脚

1. 设备树
&leds_test_node
{
    status = "okay";
    pinctrl - names = "itop-leds1-on", "itop-leds1-off";
    pinctrl - 0 = <&leds_gpios1_on>;
    pinctrl - 1 = <&leds_gpios1_off>;
};

2. 解析设备树
static int leds_probe(struct platform_device *pdev)
{
    int ret;
    struct pinctl *pinctl;
    struct pinctl_state *state;
    struct device *dev = &pdev->dev;

    pinctl = devm_pinctl_get();
    if (IS_ERR(pinctl))
    {
        printk("%d\n", PTR_ERR(pinctl));
    }

    state = pinctl_lookup_state(pinctl, "itop-leds1-on");
    if (IS_ERR(state))
    {
        printk("%d\n", PTR_ERR(state));
    }

    ret = pinctl_select_state(pinctl, state);
    if (ret < 0)
    {
    }

    // 释放句柄
    devm_pinctl_put(pinctl);

    // pinctl = devm_pinctl_get_select_default(&pdev->dev);
    return 0;
}

完整代码
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/pinctl/consumer.h>

#define DEVICE_NAME "leds_test"

int gpio_pin[2] = {-1, -1};

int leds_open(struct inode *inode, struct file *filp)
{
    printk("open\n");
    return nonseekable_open(inode, filp);
}

int leds_release(struct inode *inode, struct file *filp)
{
    printk("close\n");
    return 0;
}

long leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    printk("ioctl\n");
    switch (cmd)
    {
    case 0:
    case 1:
        gpio_set_value(gpio_pin[arg], cmd);
        break;
    default:
        return -1;
    }
    return 0;
}

static struct file_operations leds_ops = {
    .owner = THIS_MODULE,
    .open = leds_open,
    .release = leds_release,
    .unlocked_ioctl = leds_ioctl,
};

// static struct miscdevice leds_dev = {
//     .minor = MISC_DYNAMIC_MINOR,
//     .fops = &leds_ops,
//     .name = DRIVER_NAME,
// };

static int leds_probe(struct platform_device *pdev)
{
    // struct device_node *node = pdev->dev.of_node;
    int ret;
    struct pinctl *pinctl;
    struct pinctl_state *state;
    printk("probe\n");

    struct device *dev = &pdev->dev;
    pinctl = devm_pinctl_get();
    if (IS_ERR(pinctl))
    {
        printk("%d\n", PTR_ERR(pinctl));
    }

    state = pinctl_lookup_state(pinctl, "itop-leds1-on");
    if (IS_ERR(state))
    {
        printk("%d\n", PTR_ERR(state));
    }

    ret = pinctl_select_state(pinctl, state);
    if (ret < 0)
    {
    }

    // 释放句柄
    devm_pinctl_put(pinctl);

    // pinctl = devm_pinctl_get_select_default(&pdev->dev);

    // // gpio编号
    // gpio_pin[0] = of_get_name_gpio(node, "gpios1", 0);
    // gpio_pin[1] = of_get_name_gpio(node, "gpios2", 0);

    // // 申请
    // ret = gpio_request(gpio_pin[0], "led1");
    // if (ret != 0)
    // {
    //     printk("gpio request failed\n");
    //     return ret;
    // }

    // ret = gpio_request(gpio_pin[1], "led2");
    // if (ret != 0)
    // {
    //     printk("gpio request failed\n");
    //     return ret;
    // }

    // gpio_free(gpio_pin[0]);
    // gpio_free(gpio_pin[1]);

    // gpio_direction_output(gpio_pin[0], 0);
    // gpio_set_value(gpio_pin[0], 1);

    // gpio_direction_output(gpio_pin[1], 0);
    // gpio_set_value(gpio_pin[1], 1);

    // 杂项设备注冊
    // ret = misc_register(&leds_dev);
    // if (ret < 0)
    // {
    //     printk("register error\n");
    //     goto exit;
    // }

    printk("probe ok\n");
    return 0;
    // exit:
    //     misc_deregister(&leds_dev);
    //     return ret;
}

static int leds_remove(struct platform_device *pdev)
{
    // misc_deregister(&leds_dev);
    return 0;
}

// 平台设备驱动
static struct of_device_id of_my_match[] = {
    {.compatible = "myled"},
    {}};

static struct platform_device my_platform_device = {
    .remove = leds_release,
    .probe = leds_probe,
    .driver = {
        .name = "myled",
        .owner = THIS_MODULE,
        .of_match_table = of_my_match,
    },
};

static int __init led_module_init(void)
{
    printk("%s\n", __FUNCTION__)
        platform_device_register(&my_platform_device);
    return 0;
}

static void __exit led_module_cleanup(void)
{
    platform_device_unregister(&my_platform_device);
}

subys_initcall(led_module_init);
module_init(led_module_init);
module_exit(led_module_cleanup);
MODULE_LICENSE("GPL");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值