基于rk3128的leds灯闪问题

来源:互联网 发布:apache配置域名访问 编辑:程序博客网 时间:2024/05/12 03:10
rk3128原生安卓代码里。按红外遥控器的时候,灯是不闪的。在这里,我把如何进行灯闪的问题解决一下。哈!
在\kernel\src\arch\arm\boot\dts\rk3128-box-rk88.dts增加gpio控制led的节点
rockchip_leds_gpio {
        compatible = "rockchip-leds-gpio";
led-gpios = <&gpio0 GPIO_D2 GPIO_ACTIVE_LOW>, <&gpio0 GPIO_B0 GPIO_ACTIVE_LOW>;
status = "okay";
};
 gpio_poweroff {
compatible = "gpio-poweroff";
gpios = <&gpio1 GPIO_A2 GPIO_ACTIVE_LOW>;
};
在\kernel\src\arch\arm\configs\rockchip_defconfig里,配置leds。

CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y

然后增加代码目录路径    \kernel\src\drivers\leds\rockchip-leds-gpio.c
/* * LEDs driver for GPIOs * * Copyright (C) 2007 8D Technologies inc. * Raphael Assenat <raph@8d.com> * Copyright (C) 2008 Freescale Semiconductor, Inc. * * 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/kernel.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/gpio.h>#include <linux/leds.h>#include <linux/of_platform.h>#include <linux/of_gpio.h>#include <linux/rk_fb.h>#include <linux/slab.h>#include <linux/workqueue.h>#include <linux/module.h>#include <linux/pinctrl/consumer.h>#include <linux/err.h>#define TAG "ROCKCHIP_LEDS_GPIO"#if 0#define D(fmt, arg...) printk("D>>> %s->%s(%d): " fmt, TAG, __FUNCTION__, __LINE__, ##arg)#else#define D(fmt, arg...)#endif#define E(fmt, arg...) printk("E>>> %s->%s(%d): " fmt, TAG, __FUNCTION__, __LINE__, ##arg)#define I(fmt, arg...) printk("I>>> %s->%s(%d): " fmt, TAG, __FUNCTION__, __LINE__, ##arg)#define GPIO_LOW0#define GPIO_HIGH1#define LED_ON          0#define LED_OFF         1struct rk_gpio_leds_ctl_io {unsigned int power_green;unsigned int power_red;unsigned int ir_red;};struct rk_gpio_leds_priv {struct rk_gpio_leds_ctl_io leds;struct timer_list led_timer;unsigned int ir_red_status;unsigned int ir_red_first_resume;unsigned int suspend_state; };struct rk_gpio_leds_priv *g_privdata = NULL;static ssize_t led_store(struct device *dev, struct device_attribute *attr, const char *cmd, size_t count){struct platform_device *pdev = to_platform_device(dev);struct rk_gpio_leds_priv *priv = platform_get_drvdata(pdev);    // I("led_store(): cmd = %s \n", cmd);        if (true == priv->suspend_state)    {        return count;    }    if(0 == strcmp("IR_LED_ON", cmd))    {        gpio_set_value(priv->leds.ir_red, GPIO_HIGH);    }    else if(0 == strcmp("IR_LED_OFF", cmd))    {        gpio_set_value(priv->leds.ir_red, GPIO_LOW);    }        return count;}static ssize_t led_show(struct device *dev, struct device_attribute *attr, char *buf){       return 0; }static DEVICE_ATTR(led_ctl, 0777, led_show, led_store);static void rk_gpio_led_early_suspend(void){struct rk_gpio_leds_priv *priv = g_privdata;if (priv){    //POWER_LED_RED        gpio_set_value(priv->leds.power_green, GPIO_LOW);        gpio_set_value(priv->leds.power_red, GPIO_HIGH);}return;}static void rk_gpio_led_early_resume(void){struct rk_gpio_leds_priv *priv = g_privdata;if (priv){    //POWER_LED_GREEN        gpio_set_value(priv->leds.power_green, GPIO_HIGH);        gpio_set_value(priv->leds.power_red, GPIO_LOW);                // IR_LED        if (false == priv->ir_red_first_resume) // 开机时,系统会调用 rk_gpio_led_early_resume ,此时红外灯不应该闪烁。        {            mod_timer(&priv->led_timer, jiffies + msecs_to_jiffies(50));        }        else        {            priv->ir_red_first_resume = false;        }    }        return;}static int rk_gpio_led_event_notify(struct notifier_block *self,      unsigned long action, void *data){struct fb_event *event = data;int blank_mode = *((int *)event->data);if (action == FB_EARLY_EVENT_BLANK) {switch (blank_mode) {case FB_BLANK_UNBLANK:break;default:rk_gpio_led_early_suspend();break;}} else if (action == FB_EVENT_BLANK) {switch (blank_mode) {case FB_BLANK_UNBLANK:    rk_gpio_led_early_resume();break;default:break;}}return NOTIFY_OK;}static struct notifier_block rk_gpio_led_notifier = {.notifier_call = rk_gpio_led_event_notify,};static void rk_gpio_led_timer(unsigned long _data){    struct rk_gpio_leds_priv *priv;priv =  (struct rk_gpio_leds_priv *)_data;if (LED_OFF == priv->ir_red_status)   // turn on{    priv->ir_red_status = LED_ON;    gpio_set_value(priv->leds.ir_red, GPIO_HIGH);        mod_timer(&priv->led_timer, jiffies + msecs_to_jiffies(300));}else    // turn off{    priv->ir_red_status = LED_OFF;    gpio_set_value(priv->leds.ir_red, GPIO_LOW);}}static int rk_gpio_led_probe(struct platform_device *pdev){struct rk_gpio_leds_priv *priv;struct device_node *np = pdev->dev.of_node;int ret;I ("rk_gpio_led v1.0 init");priv = devm_kzalloc(&pdev->dev, sizeof(struct rk_gpio_leds_priv),     GFP_KERNEL);if (!priv) {dev_err(&pdev->dev, "failed to allocate memory\n");return -ENOMEM;}g_privdata = priv;priv->leds.power_green = of_get_named_gpio(np,"led-gpios", 0);priv->leds.power_red   = of_get_named_gpio(np,"led-gpios", 1);//priv->leds.ir_red      = of_get_named_gpio(np,"led-gpios", 2);    if(priv->leds.power_green)    {        ret = gpio_request(priv->leds.power_green, "power_green");        if (!ret)        {            gpio_direction_output(priv->leds.power_green, GPIO_HIGH);        }        else        {            I("power_green request gpio fail!");        }    }    if(priv->leds.power_red)    {        ret = gpio_request(priv->leds.power_red, "power_red");        if (!ret)        {            gpio_direction_output(priv->leds.power_red, GPIO_LOW);        }        else        {            I("power_red request gpio fail!");        }    }        if(priv->leds.ir_red)    {        ret = gpio_request(priv->leds.ir_red, "ir_red");        if (!ret)        {            gpio_direction_output(priv->leds.ir_red, GPIO_LOW);        }        else        {            I("ir_red request gpio fail!");        }    }    priv->ir_red_status = LED_OFF;    priv->ir_red_first_resume = true;    priv->suspend_state = false;    setup_timer(&priv->led_timer, rk_gpio_led_timer, (unsigned long)priv);    ret = device_create_file(&pdev->dev, &dev_attr_led_ctl);if (ret) {return ret;}    fb_register_client(&rk_gpio_led_notifier);platform_set_drvdata(pdev, priv);return 0;}static int rk_gpio_led_remove(struct platform_device *pdev){D("Enter function! \n");platform_set_drvdata(pdev, NULL);return 0;}#ifdef CONFIG_PMstatic int rk_gpio_led_suspend(struct device *dev){struct platform_device *pdev = to_platform_device(dev);struct rk_gpio_leds_priv *priv = platform_get_drvdata(pdev);priv->suspend_state = true;return 0;}static int rk_gpio_led_resume(struct device *dev){struct platform_device *pdev = to_platform_device(dev);struct rk_gpio_leds_priv *priv = platform_get_drvdata(pdev);    priv->suspend_state = false;return 0;}static const struct dev_pm_ops rk_gpio_led_pm_ops = {.suspend_late = rk_gpio_led_suspend,.resume_early = rk_gpio_led_resume,};#endifstatic const struct of_device_id of_gpio_leds_match[] = {{ .compatible = "rockchip-leds-gpio", },{},};MODULE_DEVICE_TABLE(of, of_gpio_leds_match);static struct platform_driver gpio_led_driver = {.probe= rk_gpio_led_probe,.remove= rk_gpio_led_remove,.driver= {.name= "rockchip-leds-gpio",.owner= THIS_MODULE,.of_match_table = of_match_ptr(of_gpio_leds_match),#ifdef CONFIG_PM.pm = &rk_gpio_led_pm_ops,#endif},};module_platform_driver(gpio_led_driver);MODULE_AUTHOR("Fengminxi <fmx@rock-chips.com>");MODULE_DESCRIPTION("Rockchip GPIO LED driver");MODULE_LICENSE("GPL");MODULE_ALIAS("platform:rockchip-leds-gpio");
在\kernel\src\drivers\leds\makefile文件里增加下面代码。
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGERS) += trigger/

在\kernel\src\drivers\leds\Kconfig里增加
config LEDS_GPIO_REGISTERboolhelp  This option provides the function gpio_led_register_device.  As this function is used by arch code it must not be compiled as a  module.menuconfig NEW_LEDSbool "LED Support"help  Say Y to enable Linux LED support.  This allows control of supported  LEDs from both userspace and optionally, by kernel events (triggers).  This is not related to standard keyboard LEDs which are controlled  via the input system.if NEW_LEDSconfig LEDS_CLASStristate "LED Class Support"help  This option enables the led sysfs class in /sys/class/leds.  You'll  need this to do anything useful with LEDs.  If unsure, say N.comment "LED drivers"

这样linux层配置好。我们需要通过安卓层来调用。

在/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java,直接去控制底层的gpio的leds。
    static final int FREQUENCY = 10;     private int mKeyDownCount = 0;     private long mKeyDownTime = 0;++    private void updateLEDState(String cmd) {+        File f = new File("/sys/devices/rockchip_leds_gpio.17/led_ctl");+        OutputStream output = null;+        OutputStreamWriter outputWrite = null;+        PrintWriter print = null;+        StringBuffer strbuf = new StringBuffer("");+        strbuf.append(cmd);+        try {+            output = new FileOutputStream(f);+            outputWrite = new OutputStreamWriter(output);+            print = new PrintWriter(outputWrite);+            print.print(strbuf.toString());+            print.flush();+            output.close();+        }catch (FileNotFoundException e){+            e.printStackTrace();+        }catch (IOException e){+            e.printStackTrace();+        }+    }+ //$_rbox_$_modify_$_end     @Override     public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {@@ -4267,6 +4289,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;         final boolean canceled = event.isCanceled();         final int keyCode = event.getKeyCode();+        +        if (down)+        {+            updateLEDState ("IR_LED_ON");+        }+        else+        {+            updateLEDState ("IR_LED_OFF");+        }+                 //<!-- $_rbox_$_modify_$_huangjc -->         if("true".equals(SystemProperties.get("persist.sys.realsleep"))){           if((SystemProperties.getInt("persist.sys.poweroff", 0) == 1)&&!(keyCode == KeyEvent.KEYCODE_POWER)){


0 0
原创粉丝点击