summaryrefslogtreecommitdiff
path: root/drivers/media/rc/rc-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/rc/rc-main.c')
-rw-r--r--drivers/media/rc/rc-main.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 1cf382a0b277..46da365c9c84 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -16,6 +16,7 @@
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/input.h>
+#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -31,6 +32,7 @@
/* Used to keep track of known keymaps */
static LIST_HEAD(rc_map_list);
static DEFINE_SPINLOCK(rc_map_lock);
+static struct led_trigger *led_feedback;
static struct rc_map_list *seek_rc_map(const char *name)
{
@@ -535,6 +537,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync)
IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
input_report_key(dev->input_dev, dev->last_keycode, 0);
+ led_trigger_event(led_feedback, LED_OFF);
if (sync)
input_sync(dev->input_dev);
dev->keypressed = false;
@@ -648,6 +651,7 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
input_report_key(dev->input_dev, keycode, 1);
}
+ led_trigger_event(led_feedback, LED_FULL);
input_sync(dev->input_dev);
}
@@ -699,19 +703,50 @@ void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle)
}
EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
+int rc_open(struct rc_dev *rdev)
+{
+ int rval = 0;
+
+ if (!rdev)
+ return -EINVAL;
+
+ mutex_lock(&rdev->lock);
+ if (!rdev->users++ && rdev->open != NULL)
+ rval = rdev->open(rdev);
+
+ if (rval)
+ rdev->users--;
+
+ mutex_unlock(&rdev->lock);
+
+ return rval;
+}
+EXPORT_SYMBOL_GPL(rc_open);
+
static int ir_open(struct input_dev *idev)
{
struct rc_dev *rdev = input_get_drvdata(idev);
- return rdev->open(rdev);
+ return rc_open(rdev);
+}
+
+void rc_close(struct rc_dev *rdev)
+{
+ if (rdev) {
+ mutex_lock(&rdev->lock);
+
+ if (!--rdev->users && rdev->close != NULL)
+ rdev->close(rdev);
+
+ mutex_unlock(&rdev->lock);
+ }
}
+EXPORT_SYMBOL_GPL(rc_close);
static void ir_close(struct input_dev *idev)
{
struct rc_dev *rdev = input_get_drvdata(idev);
-
- if (rdev)
- rdev->close(rdev);
+ rc_close(rdev);
}
/* class for /sys/class/rc */
@@ -1076,7 +1111,14 @@ int rc_register_device(struct rc_dev *dev)
memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
dev->input_dev->phys = dev->input_phys;
dev->input_dev->name = dev->input_name;
+
+ /* input_register_device can call ir_open, so unlock mutex here */
+ mutex_unlock(&dev->lock);
+
rc = input_register_device(dev->input_dev);
+
+ mutex_lock(&dev->lock);
+
if (rc)
goto out_table;
@@ -1184,6 +1226,7 @@ static int __init rc_core_init(void)
return rc;
}
+ led_trigger_register_simple("rc-feedback", &led_feedback);
rc_map_register(&empty_map);
return 0;
@@ -1192,6 +1235,7 @@ static int __init rc_core_init(void)
static void __exit rc_core_exit(void)
{
class_unregister(&rc_class);
+ led_trigger_unregister_simple(led_feedback);
rc_map_unregister(&empty_map);
}