remote: add remote led blink function to u211
authorQianggui Song <qianggui.song@amlogic.com>
Mon, 9 Apr 2018 04:23:54 +0000 (12:23 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Fri, 13 Apr 2018 02:57:02 +0000 (18:57 -0800)
PD#163342: add remote led blink function to u211

Change-Id: I92ba57af1f3c83e6d432a344d35021734dfecf3c
Signed-off-by: Qianggui Song <qianggui.song@amlogic.com>
arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts
arch/arm64/boot/dts/amlogic/mesong12a.dtsi
drivers/amlogic/input/remote/remote_core.c
drivers/amlogic/input/remote/remote_core.h
drivers/amlogic/input/remote/remote_meson.c
drivers/amlogic/input/remote/sysfs.c

index a6d9be8..bdfecfd 100644 (file)
                        gpios=<&gpio GPIOA_15 GPIO_ACTIVE_HIGH>;
                        default-state ="on";
                };
+
+               remote_led {
+                       label = "remote_led";
+                       gpios = <&gpio_ao GPIOAO_10 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+                       linux,default-trigger = "rc_feedback";
+               };
        };
 
        cvbsout {
index cc11848..4ba62be 100644 (file)
                        <0x0 0xff808000 0x00 0x20>; /*Legacy IR controller*/
                status = "okay";
                protocol = <REMOTE_TYPE_NEC>;
+               led_blink = <1>;
+               led_blink_frq = <100>;
                interrupts = <0 196 1>;
                pinctrl-names = "default";
                pinctrl-0 = <&remote_pins>;
index 1bb70b7..f9c25d5 100644 (file)
@@ -117,6 +117,9 @@ void remote_keydown(struct remote_dev *dev, int scancode, int status)
        unsigned long flags;
        u32 keycode;
 
+       if (dev->led_blink)
+               led_trigger_blink_oneshot(dev->led_feedback, &dev->delay_on,
+                        &dev->delay_off, 0);
 
        if (status != REMOTE_REPEAT) {
                if (dev->is_valid_custom &&
index ec8da62..6b2d623 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kfifo.h>
 #include <linux/device.h>
 #include <dt-bindings/input/meson_rc.h>
+#include <linux/leds.h>
 
 #define MULTI_IR_TYPE_MASK(type) (type & 0xff)  /*8bit*/
 #define LEGACY_IR_TYPE_MASK(type) ((type >> 8) & 0xff) /*8bit*/
@@ -68,6 +69,12 @@ struct remote_dev {
        struct remote_raw_handle *raw;
        spinlock_t keylock;
 
+#define DEFAULT_LED_BLINK_FRQ  100
+       struct led_trigger *led_feedback;
+       unsigned long delay_on;
+       unsigned long delay_off;
+       int led_blink;
+
        struct timer_list timer_keyup;
        unsigned long keyup_jiffies;
        unsigned long keyup_delay;
index fcbf5fa..b321e3f 100644 (file)
@@ -471,7 +471,7 @@ static int ir_get_devtree_pdata(struct platform_device *pdev)
        resource_size_t *res_start[2];
        struct pinctrl *p;
        int ret;
-       int value;
+       int value = 0;
        unsigned char i;
 
 
@@ -485,6 +485,26 @@ static int ir_get_devtree_pdata(struct platform_device *pdev)
        }
        dev_info(chip->dev, "protocol = 0x%x\n", chip->protocol);
 
+       ret = of_property_read_u32(pdev->dev.of_node,
+                       "led_blink", &chip->r_dev->led_blink);
+       if (ret) {
+               dev_err(chip->dev, "don't find the node <led_blink>\n");
+               chip->r_dev->led_blink = 0;
+       }
+       dev_info(chip->dev, "led_blink = %d\n", chip->r_dev->led_blink);
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                       "led_blink_frq", &value);
+       if (ret) {
+               dev_err(chip->dev, "don't find the node <led_blink_frq>\n");
+               chip->r_dev->delay_on = DEFAULT_LED_BLINK_FRQ;
+               chip->r_dev->delay_off = DEFAULT_LED_BLINK_FRQ;
+       } else {
+               chip->r_dev->delay_off = value;
+               chip->r_dev->delay_on = value;
+       }
+       dev_info(chip->dev, "led_blink_frq  = %ld\n", chip->r_dev->delay_on);
+
        p = devm_pinctrl_get_select_default(&pdev->dev);
        if (IS_ERR(p)) {
                dev_err(chip->dev, "pinctrl error, %ld\n", PTR_ERR(p));
@@ -644,6 +664,8 @@ static int remote_probe(struct platform_device *pdev)
        device_init_wakeup(&pdev->dev, 1);
        dev_pm_set_wake_irq(&pdev->dev, chip->irqno);
 
+       led_trigger_register_simple("rc_feedback", &dev->led_feedback);
+
        return 0;
 
 error_register_remote:
@@ -666,6 +688,7 @@ static int remote_remove(struct platform_device *pdev)
        tasklet_kill(&tasklet);
 
        free_irq(chip->irqno, chip); /*irq dev_id is chip address*/
+       led_trigger_unregister_simple(chip->r_dev->led_feedback);
        ir_cdev_free(chip);
        remote_unregister_device(chip->r_dev);
        remote_free_device(chip->r_dev);
index 9fbbdb6..c4cea39 100644 (file)
@@ -251,6 +251,63 @@ static ssize_t map_tables_show(struct device *dev,
        return len;
 }
 
+static ssize_t led_blink_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+
+       struct remote_chip *chip = dev_get_drvdata(dev);
+       struct remote_dev  *r_dev = chip->r_dev;
+
+       return sprintf(buf, "%u\n", r_dev->led_blink);
+}
+
+static ssize_t led_blink_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       int ret = 0;
+       int val = 0;
+
+       struct remote_chip *chip = dev_get_drvdata(dev);
+       struct remote_dev  *r_dev = chip->r_dev;
+
+       ret = kstrtoint(buf, 0, &val);
+       if (ret != 0)
+               return -EINVAL;
+       r_dev->led_blink = val;
+       return count;
+}
+
+static ssize_t led_frq_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+
+       struct remote_chip *chip = dev_get_drvdata(dev);
+       struct remote_dev  *r_dev = chip->r_dev;
+
+       return sprintf(buf, "%ld\n", r_dev->delay_on);
+}
+
+static ssize_t led_frq_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       int ret = 0;
+       int val = 0;
+
+       struct remote_chip *chip = dev_get_drvdata(dev);
+       struct remote_dev  *r_dev = chip->r_dev;
+
+       ret = kstrtoint(buf, 0, &val);
+       if (ret != 0)
+               return -EINVAL;
+       r_dev->delay_off = val;
+       r_dev->delay_on = val;
+       return count;
+}
+
+DEVICE_ATTR_RW(led_frq);
+DEVICE_ATTR_RW(led_blink);
 DEVICE_ATTR_RW(repeat_enable);
 DEVICE_ATTR_RW(protocol);
 DEVICE_ATTR_RW(keymap);
@@ -265,6 +322,8 @@ static struct attribute *remote_attrs[] = {
        &dev_attr_debug_enable.attr,
        &dev_attr_repeat_enable.attr,
        &dev_attr_debug_log.attr,
+       &dev_attr_led_blink.attr,
+       &dev_attr_led_frq.attr,
        NULL,
 };