android11控制led状态灯

目录

一、简介

二、解决方法

A、底层驱动

B、上层调用

C、验证


一、简介

1、需求:这里是用2个gpio口来控制LED灯,开机时默认亮蓝灯,按开机键,休眠亮红灯,唤醒亮蓝灯。

原理图:

这里由于主板上电阻R635未贴,所以led_sleep不启用。

2、分析:

a.一开始是想将这2个gpio口的控制写在背光pwm驱动中,但是该设备是不接屏幕(mipi/edp/lvds)的,直接由cpu输出信号到hdmi屏,所以无法控制背光pwm。

同理,想写在和屏启动相关的驱动里面,也是无法控制的。例如由i2c控制的gm8775c。

b.所以想到在底层驱动写一个文件节点,由上层应用去控制。

二、解决方法

A、底层驱动

这里写了一个c文件,gpio_led.c

/*
 * Driver for keys on GPIO lines capable of generating interrupts.
 *
 * Copyright (C) 2015, Fuzhou Rockchip Electronics Co., Ltd
 * Copyright 2005 Phil Blundell
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/wakelock.h>

#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>


struct vanzeak_gpio_drvdata {
	struct gpio_desc *power_gpio;
	struct gpio_desc *sleep_gpio;
};


static const struct of_device_id vanzeak_gpio_match[] = {
	{ .compatible = "vanzeak,gpio", .data = NULL},
	{},
};
MODULE_DEVICE_TABLE(of, vanzeak_gpio_match);

static ssize_t led_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
	struct vanzeak_gpio_drvdata *ddata = dev_get_drvdata(dev);
        int val = val = simple_strtol(buf, NULL, 8);
	if(val){
		gpiod_direction_output(ddata->power_gpio, 1);
		gpiod_direction_output(ddata->sleep_gpio, 0);
	}else{
		gpiod_direction_output(ddata->power_gpio, 0);
		gpiod_direction_output(ddata->sleep_gpio, 1);
	}
        return size;
}

static ssize_t led_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
        return 0;
}

static DEVICE_ATTR(led_enable, 0644, led_enable_show, led_enable_store);

static struct attribute *led_enable_attrs[] = {
	        &dev_attr_led_enable.attr,
		        NULL,
};

static struct attribute_group led_enable_attr_group = {
	        .name   = "led_enable",
		        .attrs  = led_enable_attrs,
};

static int vanzeak_gpio_probe(struct platform_device *pdev)
{
	struct vanzeak_gpio_drvdata *ddata = NULL;
	struct device *dev = &pdev->dev;
	int ret;

	ddata = devm_kzalloc(dev, sizeof(struct vanzeak_gpio_drvdata),
			GFP_KERNEL);
//	if(ddata = NULL)
//		return -1;

	platform_set_drvdata(pdev, ddata);
	dev_set_drvdata(&pdev->dev, ddata);
	ddata->power_gpio = devm_gpiod_get_optional(dev, "enable", 0);
	if (IS_ERR(ddata->power_gpio)) {
		ret = PTR_ERR(ddata->power_gpio);
		dev_err(dev, "failed to request power GPIO: %d\n", ret);
		goto fail0;
	}
	ddata->sleep_gpio = devm_gpiod_get_optional(dev, "sleep", 0);
	if (IS_ERR(ddata->sleep_gpio)) {
		ret = PTR_ERR(ddata->sleep_gpio);
		dev_err(dev, "failed to request sleep GPIO: %d\n", ret);
		goto fail0;
	}
	gpiod_direction_output(ddata->power_gpio, 1);
	gpiod_direction_output(ddata->sleep_gpio, 0);
	ret = sysfs_create_group(&pdev->dev.kobj, &led_enable_attr_group);
	 if (ret) {
	          pr_err("failed to create attr group\n");
         }


	return 0;

fail0:
	platform_set_drvdata(pdev, NULL);


	return -1;
}

static int vanzeak_gpio_remove(struct platform_device *pdev)
{
	return 0;
}

#ifdef CONFIG_PM
static int vanzeak_gpio_suspend(struct device *dev)
{
	struct vanzeak_gpio_drvdata *ddata = dev_get_drvdata(dev);

	printk("DICKE printk %s : %d\n", __func__, __LINE__);
	gpiod_direction_output(ddata->power_gpio, 0);
	return 0;
}

static int vanzeak_gpio_resume(struct device *dev)
{
	struct vanzeak_gpio_drvdata *ddata = dev_get_drvdata(dev);

	printk("DICKE printk %s : %d\n", __func__, __LINE__);
	gpiod_direction_output(ddata->power_gpio, 1);
	return 0;
}

static const struct dev_pm_ops vanzeak_gpio_pm_ops = {
	.suspend	= vanzeak_gpio_suspend,
	.resume		= vanzeak_gpio_resume,
};
#endif

static struct platform_driver vanzeak_gpio_device_driver = {
	.probe		= vanzeak_gpio_probe,
	.remove		= vanzeak_gpio_remove,
	.driver		= {
		.name	= "vanzeak-gpio",
		.owner	= THIS_MODULE,
		.of_match_table = vanzeak_gpio_match,
#ifdef CONFIG_PM
		.pm	= &vanzeak_gpio_pm_ops,
#endif
	}
};

static int __init vanzeak_gpio_driver_init(void)
{
	return platform_driver_register(&vanzeak_gpio_device_driver);
}

static void __exit vanzeak_gpio_driver_exit(void)
{
	platform_driver_unregister(&vanzeak_gpio_device_driver);
}

module_init(vanzeak_gpio_driver_init);
module_exit(vanzeak_gpio_driver_exit);

B、上层调用

由上层的休眠唤醒来控制LED的亮灭。

diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index af7d91cf7ba6..1bbc51a9ed91 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -119,6 +119,14 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.BufferedWriter;
+
 /**
  * The power manager service is responsible for coordinating power management
  * functions on the device.
@@ -1598,6 +1606,46 @@ public final class PowerManagerService extends SystemService
         }
     }
 
+   private void closeLed(int i){
+        String path = "/sys/devices/platform/vanzeak-gpio/led_enable/led_enable";
+        String value;
+	if(i == 1)
+		value = "1";
+	else if(i == 0)
+		value = "0";
+	else{
+		Slog.e(TAG, "data error");
+		return;
+	}
+        //  Log.i(TAG,"setGpioValue, path = [" + path + "] value = [" + value + "]");
+        File file = new File(path); 
+        if (!file.exists()) {
+            Slog.i("dxb","initOpenGpio , file is not exist!!!!");
+            return;
+        }
+        FileOutputStream fileOutputStream = null;
+        BufferedWriter bufferedWriter = null;
+        try {
+            fileOutputStream = new FileOutputStream(file);
+            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, "utf-8")); 
+            bufferedWriter.write(value);
+            bufferedWriter.flush();
+            bufferedWriter.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            Slog.i("dxb","input data error " + e.getMessage());
+        } finally {
+            if (bufferedWriter != null) {
+                try {
+                    bufferedWriter.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+    }
+
     private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
         if (DEBUG_SPEW) {
             Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
@@ -1690,6 +1738,8 @@ public final class PowerManagerService extends SystemService
 
         Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
         try {
+		Slog.i(TAG, "ctrol led to working mode");
+		closeLed(1);
             Slog.i(TAG, "Waking up from "
                     + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
                     + " (uid=" + reasonUid
@@ -1748,6 +1798,8 @@ public final class PowerManagerService extends SystemService
         try {
             reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
                     Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
+		Slog.i(TAG, "ctrol led to sleeping mode");
+		closeLed(0);
             Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
                     + " (uid " + uid + ")...");
 
C、验证

按开机键,休眠亮红灯,唤醒亮蓝灯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值