直接上代码了,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