From 537cf2650a8fa652ff7a51aa9ed3aedb544bb09b Mon Sep 17 00:00:00 2001 From: Qianggui Song Date: Mon, 9 Apr 2018 12:23:54 +0800 Subject: [PATCH] remote: add remote led blink function to u211 PD#163342: add remote led blink function to u211 Change-Id: I92ba57af1f3c83e6d432a344d35021734dfecf3c Signed-off-by: Qianggui Song --- .../boot/dts/amlogic/g12a_s905x2_u211.dts | 7 +++ arch/arm64/boot/dts/amlogic/mesong12a.dtsi | 2 + drivers/amlogic/input/remote/remote_core.c | 3 + drivers/amlogic/input/remote/remote_core.h | 7 +++ drivers/amlogic/input/remote/remote_meson.c | 25 +++++++- drivers/amlogic/input/remote/sysfs.c | 59 +++++++++++++++++++ 6 files changed, 102 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts index a6d9be84bcb6..bdfecfda6121 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts @@ -157,6 +157,13 @@ 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 { diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index cc118488ba9f..4ba62be9d221 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -781,6 +781,8 @@ <0x0 0xff808000 0x00 0x20>; /*Legacy IR controller*/ status = "okay"; protocol = ; + led_blink = <1>; + led_blink_frq = <100>; interrupts = <0 196 1>; pinctrl-names = "default"; pinctrl-0 = <&remote_pins>; diff --git a/drivers/amlogic/input/remote/remote_core.c b/drivers/amlogic/input/remote/remote_core.c index 1bb70b727182..f9c25d5f83d5 100644 --- a/drivers/amlogic/input/remote/remote_core.c +++ b/drivers/amlogic/input/remote/remote_core.c @@ -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 && diff --git a/drivers/amlogic/input/remote/remote_core.h b/drivers/amlogic/input/remote/remote_core.h index ec8da62c8402..6b2d623991f3 100644 --- a/drivers/amlogic/input/remote/remote_core.h +++ b/drivers/amlogic/input/remote/remote_core.h @@ -23,6 +23,7 @@ #include #include #include +#include #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; diff --git a/drivers/amlogic/input/remote/remote_meson.c b/drivers/amlogic/input/remote/remote_meson.c index fcbf5fa0afc8..b321e3fa5719 100644 --- a/drivers/amlogic/input/remote/remote_meson.c +++ b/drivers/amlogic/input/remote/remote_meson.c @@ -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 \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 \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); diff --git a/drivers/amlogic/input/remote/sysfs.c b/drivers/amlogic/input/remote/sysfs.c index 9fbbdb66e0a5..c4cea3957a3b 100644 --- a/drivers/amlogic/input/remote/sysfs.c +++ b/drivers/amlogic/input/remote/sysfs.c @@ -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, };