[Linux Device Driver] 通过设备节点的方式控制GPIO

直接上代码了,Kconfig、defconfig、makefile那些请自己配置。

0. vendor/qcom/proprietary/devicetree-4.19/qcom/lagoon-mtp.dtsi

&soc {
  
   ......
	logo_led {
		compatible = "qcom,logo-led-v2";
		qcom,msm-logo-enable-gpio =   <&tlmm 87 0x00>;
	};

};

1. kernel/msm-4.19/drivers/logoled/logo.c

#include <linux/init.h>
#include <linux/kernel.h>  
#include <linux/module.h> 
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/power_supply.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/leds-qpnp-flash.h>
#include <linux/leds-qpnp-flash-v2.h>
#include <linux/qpnp/qpnp-revid.h>
#include <linux/log2.h>

static int logo_gpio = 0;

static ssize_t pm6150l_wled_enable_show(struct device *dev,
                                 struct device_attribute *attr, char *buf)
{
	int val;
	val =  gpio_get_value(logo_gpio);
	return sprintf(buf, "%d\n", val);
}

static ssize_t pm6150l_wled_enable_store(struct device *dev,
                                      struct device_attribute *attr,
                                      const char *buf, size_t size)
{
	ssize_t ret;

	unsigned int state;
	pr_err("#nigulasi-logo#,debug1,fun=%s,logo_gpio=%d\n",__func__,logo_gpio);

	ret = kstrtouint(buf, 10, &state);
	if (state) {
		gpio_direction_output(logo_gpio, 1);
		pr_err("#nigulasi-logo#,debug2,fun=%s,logo_gpio=%d\n",__func__,logo_gpio);
	}else{
		gpio_direction_output(logo_gpio, 0);
		pr_err("#nigulasi-logo#,debug3,fun=%s,logo_gpio=%d\n",__func__,logo_gpio);
	}

	return size;
}

static DEVICE_ATTR(wled_enable, S_IRUGO | S_IWUSR, pm6150l_wled_enable_show, pm6150l_wled_enable_store);

static int qpnp_logo_led_probe(struct platform_device *pdev)
{
	int rc = 0;
	const char *logo_enable_gpio = "qcom,msm-logo-enable-gpio";
	logo_gpio = of_get_named_gpio(pdev->dev.of_node, logo_enable_gpio, 0);
	rc = gpio_request(logo_gpio, "msm-logo-enable-gpio");
	pr_err("#nigulasi-logo#,debug,fun=%s,logo_gpio=%d\n",__func__,logo_gpio);

	rc = device_create_file(&pdev->dev, &dev_attr_wled_enable);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to create WLED enable sysfs node rc:%d\n",
			rc);
		return rc;
	}
	gpio_direction_output(logo_gpio, 0);
	return rc;

}

static int qpnp_logo_led_remove(struct platform_device *pdev)
{

	return 0;
}

const struct of_device_id qpnp_logo_led_match_table[] = {
	{ .compatible = "qcom,logo-led-v2",},
	{ },
};

static struct platform_driver logo_led_driver = {
	.driver		= {
		.name = "qcom,logo-led-v2",
		.of_match_table = qpnp_logo_led_match_table,
	},
	.probe		= qpnp_logo_led_probe,
	.remove		= qpnp_logo_led_remove,
};

static int logo_init(void)
{ 
	printk("enter the fun=%s!\n",__func__);
	return platform_driver_register(&logo_led_driver);
} 
static void logo_exit(void)
{
	printk("enter the fun=%s!\n",__func__);
	platform_driver_unregister(&logo_led_driver);
	return;
} 
module_init(logo_init);
module_exit(logo_exit);
MODULE_LICENSE("GPL");

之后就可以通过设备节点操控这个GPIO87了。用echo和cat操控gpio拉高拉低,然后cat /d/gpio会看到对应的gpio被配置为输出,high和low。

/sys/bus/platform/devices/soc:logo_led # cat wled_enable
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值