* [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes
@ 2014-01-26 21:50 Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 1/5] rc-core: Add defintions needed for sysfs callback Antti Seppälä
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Antti Seppälä @ 2014-01-26 21:50 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Sean Young, Antti Seppälä
I'm resending the patch series as it seems that my initial attempt was
not delivered to patchwork or linux-media list. Apologies for duplicate
emails to people who may have received the first attempt.
Patches 1 & 2 in this series introduce a simple sysfs file interface for
reading and writing wakeup scancodes or ir samples to rc drivers.
The interface is designed to be flexible yet easy enough to adapt to. It
can support almost any kind of known wakeup scancode and sample formats.
Patches 3-5 in the series port some existing drivers to use this
interface.
Changes in v2:
- Added wakeup_protocols file to control which protocol to use with
wakeup
- Renamed interface to wakeup_code
- Clean-up device attribute registration
- Ported winbond-cir to use this interface
- Brought interface closer to
https://patchwork.linuxtv.org/patch/21625/
Antti Seppälä (5):
rc-core: Add defintions needed for sysfs callback
rc-core: Add support for reading/writing wakeup codes via sysfs
rc-loopback: Add support for reading/writing wakeup scancodes via
sysfs
nuvoton-cir: Add support for reading/writing wakeup samples via sysfs
winbond-cir: Add support for reading/writing wakeup scancodes via
sysfs
drivers/media/rc/nuvoton-cir.c | 118 +++++++++++++++++++++++++++
drivers/media/rc/nuvoton-cir.h | 2 +
drivers/media/rc/rc-loopback.c | 40 +++++++++
drivers/media/rc/rc-main.c | 179 +++++++++++++++++++++++++++++++++++++----
drivers/media/rc/winbond-cir.c | 66 ++++++++++-----
include/media/rc-core.h | 17 ++++
6 files changed, 390 insertions(+), 32 deletions(-)
--
1.8.3.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFCv2 PATCH 1/5] rc-core: Add defintions needed for sysfs callback
2014-01-26 21:50 [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes Antti Seppälä
@ 2014-01-26 21:50 ` Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 2/5] rc-core: Add support for reading/writing wakeup codes via sysfs Antti Seppälä
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Antti Seppälä @ 2014-01-26 21:50 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Sean Young, Antti Seppälä
Introduce a list for wake code values and add callback for reading
/ writing it via sysfs.
Also introduce bitfields for setting which protocols are allowed and
enabled for wakeup.
Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
---
include/media/rc-core.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 2f6f1f7..e0e5699 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -20,6 +20,7 @@
#include <linux/kfifo.h>
#include <linux/time.h>
#include <linux/timer.h>
+#include <linux/list.h>
#include <media/rc-map.h>
extern int rc_core_debug;
@@ -35,6 +36,16 @@ enum rc_driver_type {
};
/**
+ * struct rc_wakeup_code - represents a single IR scancode or pulse/space
+ * @value: scan code value or pulse (+) / space (-) length
+ * @list: linked list pointer
+ */
+struct rc_wakeup_code {
+ s32 value;
+ struct list_head list_item;
+};
+
+/**
* struct rc_dev - represents a remote control device
* @dev: driver model's view of this device
* @input_name: name of the input child device
@@ -52,6 +63,8 @@ enum rc_driver_type {
* @idle: used to keep track of RX state
* @allowed_protos: bitmask with the supported RC_BIT_* protocols
* @enabled_protocols: bitmask with the enabled RC_BIT_* protocols
+ * @allowed_wake_protos: bitmask with the supported RC_BIT_* protocols for wakeup
+ * @enabled_wake_protos: bitmask with the enabled RC_BIT_* protocols for wakeup
* @scanmask: some hardware decoders are not capable of providing the full
* scancode to the application. As this is a hardware limit, we can't do
* anything with it. Yet, as the same keycode table can be used with other
@@ -84,6 +97,7 @@ enum rc_driver_type {
* device doesn't interrupt host until it sees IR pulses
* @s_learning_mode: enable wide band receiver used for learning
* @s_carrier_report: enable carrier reports
+ * @s_wakeup_codes: set/get IR scancode to wake hardware from sleep states
*/
struct rc_dev {
struct device dev;
@@ -101,6 +115,8 @@ struct rc_dev {
bool idle;
u64 allowed_protos;
u64 enabled_protocols;
+ u64 allowed_wake_protos;
+ u64 enabled_wake_protos;
u32 users;
u32 scanmask;
void *priv;
@@ -127,6 +143,7 @@ struct rc_dev {
void (*s_idle)(struct rc_dev *dev, bool enable);
int (*s_learning_mode)(struct rc_dev *dev, int enable);
int (*s_carrier_report) (struct rc_dev *dev, int enable);
+ int (*s_wakeup_codes) (struct rc_dev *dev, struct list_head *wakeup_code_list, int write);
};
#define to_rc_dev(d) container_of(d, struct rc_dev, dev)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFCv2 PATCH 2/5] rc-core: Add support for reading/writing wakeup codes via sysfs
2014-01-26 21:50 [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 1/5] rc-core: Add defintions needed for sysfs callback Antti Seppälä
@ 2014-01-26 21:50 ` Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 3/5] rc-loopback: Add support for reading/writing wakeup scancodes " Antti Seppälä
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Antti Seppälä @ 2014-01-26 21:50 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Sean Young, Antti Seppälä
This patch adds support for two files in sysfs controlling the wakeup
(scan)codes that are written to hardware.
* /sys/class/rc/rc?/wakeup_protocols:
This file has the same syntax as rc protocols file
(/sys/class/rc/rc?/protocols). When read it displays the wakeup
protocols the underlying IR driver supports. Protocol can be changed by
writing it to the file. The active protocol defines how actual
wakeup_code is to be interpreted.
Note: Only one protocol can be active at a time.
* /sys/class/rc/rc?/wakeup_codes:
This file contains the currently active wakeup (scan)code(s).
New values can be written to activate a new wakeup code.
The contents of the wakeup_code file are simply white space separated
values.
Note: Protocol "other" has a special meaning: if activated then
wakeup_codes file will contain raw IR samples. Positive values
represent pulses and negative values spaces.
How to read:
cat /sys/class/rc/rc?/wakeup_codes
How to write:
echo "rc-6" > /sys/class/rc/rc?/wakeup_protocols
echo "0xd1ab" > /sys/class/rc/rc?/wakeup_codes
Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
---
drivers/media/rc/rc-main.c | 179 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 165 insertions(+), 14 deletions(-)
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 02e2f38..cde17e2 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -797,7 +797,7 @@ static struct {
/**
* show_protocols() - shows the current IR protocol(s)
* @device: the device descriptor
- * @mattr: the device attribute struct (unused)
+ * @mattr: the device attribute struct
* @buf: a pointer to the output buffer
*
* This routine is a callback routine for input read the IR protocol type(s).
@@ -822,14 +822,19 @@ static ssize_t show_protocols(struct device *device,
mutex_lock(&dev->lock);
- enabled = dev->enabled_protocols;
- if (dev->driver_type == RC_DRIVER_SCANCODE)
- allowed = dev->allowed_protos;
- else if (dev->raw)
- allowed = ir_raw_get_allowed_protocols();
- else {
- mutex_unlock(&dev->lock);
- return -ENODEV;
+ if (strcmp(mattr->attr.name, "wakeup_protocols") == 0) {
+ enabled = dev->enabled_wake_protos;
+ allowed = dev->allowed_wake_protos;
+ } else {
+ enabled = dev->enabled_protocols;
+ if (dev->driver_type == RC_DRIVER_SCANCODE)
+ allowed = dev->allowed_protos;
+ else if (dev->raw)
+ allowed = ir_raw_get_allowed_protocols();
+ else {
+ mutex_unlock(&dev->lock);
+ return -ENODEV;
+ }
}
IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
@@ -858,7 +863,7 @@ static ssize_t show_protocols(struct device *device,
/**
* store_protocols() - changes the current IR protocol(s)
* @device: the device descriptor
- * @mattr: the device attribute struct (unused)
+ * @mattr: the device attribute struct
* @buf: a pointer to the input buffer
* @len: length of the input buffer
*
@@ -884,7 +889,7 @@ static ssize_t store_protocols(struct device *device,
const char *tmp;
u64 type;
u64 mask;
- int rc, i, count = 0;
+ int rc, i, wake = 0, count = 0, enablecount = 0;
ssize_t ret;
/* Device is being removed */
@@ -898,7 +903,13 @@ static ssize_t store_protocols(struct device *device,
ret = -EINVAL;
goto out;
}
- type = dev->enabled_protocols;
+
+ if (strcmp(mattr->attr.name, "wakeup_protocols") == 0) {
+ wake = 1;
+ type = dev->enabled_wake_protos;
+ } else {
+ type = dev->enabled_protocols;
+ }
while ((tmp = strsep((char **) &data, " \n")) != NULL) {
if (!*tmp)
@@ -920,6 +931,8 @@ static ssize_t store_protocols(struct device *device,
for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
if (!strcasecmp(tmp, proto_names[i].name)) {
mask = proto_names[i].type;
+ if (wake && (enable || (!enable && !disable)))
+ enablecount++;
break;
}
}
@@ -946,7 +959,7 @@ static ssize_t store_protocols(struct device *device,
goto out;
}
- if (dev->change_protocol) {
+ if (dev->change_protocol && !wake) {
rc = dev->change_protocol(dev, &type);
if (rc < 0) {
IR_dprintk(1, "Error setting protocols to 0x%llx\n",
@@ -956,7 +969,16 @@ static ssize_t store_protocols(struct device *device,
}
}
- dev->enabled_protocols = type;
+ if (wake && enablecount > 1) {
+ IR_dprintk(1, "Only one wake protocol can be enabled "
+ "at a time\n");
+ ret = -EINVAL;
+ goto out;
+ } else if (wake) {
+ dev->enabled_wake_protos = type;
+ } else {
+ dev->enabled_protocols = type;
+ }
IR_dprintk(1, "Current protocol(s): 0x%llx\n",
(long long)type);
@@ -967,6 +989,121 @@ out:
return ret;
}
+/**
+ * show_wakeup_codes() - shows the current IR wake code(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct (unused)
+ * @buf: a pointer to the output buffer
+ *
+ * This routine is a callback routine for input read the IR wake code(s).
+ * it is trigged by reading /sys/class/rc/rc?/wakeup_codes.
+ * It returns the currently active IR wake code or empty buffer if wake
+ * code is not active.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_wakeup_codes and show_wakeup_codes.
+ */
+static ssize_t show_wakeup_codes(struct device *device,
+ struct device_attribute *mattr, char *buf)
+{
+ int ret, pos = 0;
+ struct rc_wakeup_code *code, *next;
+ LIST_HEAD(wakeup_code_list);
+ struct rc_dev *dev = to_rc_dev(device);
+
+ if (!dev || !dev->s_wakeup_codes)
+ return -ENODEV;
+
+ mutex_lock(&dev->lock);
+
+ ret = dev->s_wakeup_codes(dev, &wakeup_code_list, 0);
+
+ list_for_each_entry_safe(code, next, &wakeup_code_list, list_item) {
+ if (dev->enabled_wake_protos & RC_BIT_OTHER)
+ pos += scnprintf(buf + pos, PAGE_SIZE - pos, "%d ",
+ code->value);
+ else
+ pos += scnprintf(buf + pos, PAGE_SIZE - pos, "0x%x ",
+ code->value);
+ list_del(&code->list_item);
+ kfree(code);
+ }
+ pos += scnprintf(buf + pos, PAGE_SIZE - pos, "\n");
+
+ mutex_unlock(&dev->lock);
+
+ if (ret < 0)
+ return ret;
+
+ return pos;
+}
+
+/**
+ * store_wakeup_codes() - changes the current IR wake code(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct (unused)
+ * @buf: a pointer to the input buffer
+ * @len: length of the input buffer
+ *
+ * This routine is for changing the IR wake code.
+ * It is trigged by writing to /sys/class/rc/rc?/wakeup_codes.
+ * Writing bytes separated by white space will pass them to the hardware.
+ * Writing "" (empty) will clear active wake code.
+ * Returns -EINVAL if too many values or invalid values were used
+ * otherwise @len.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_wakeup_codes and show_wakeup_codes.
+ */
+static ssize_t store_wakeup_codes(struct device *device,
+ struct device_attribute *mattr,
+ const char *data,
+ size_t len)
+{
+ int ret = 0;
+ char *tmp;
+ long value;
+ struct rc_wakeup_code *code, *next;
+ LIST_HEAD(wakeup_code_list);
+ struct rc_dev *dev = to_rc_dev(device);
+
+ if (!dev || !dev->s_wakeup_codes)
+ return -ENODEV;
+
+ mutex_lock(&dev->lock);
+
+ while ((tmp = strsep((char **) &data, " ,\t\n")) != NULL) {
+ if (!*tmp)
+ break;
+
+ ret = kstrtol(tmp, 0, &value);
+ if (ret < 0) {
+ IR_dprintk(1, "Error parsing value of %s", tmp);
+ break;
+ }
+
+ code = kmalloc(sizeof(struct rc_wakeup_code), GFP_KERNEL);
+ if (!code) {
+ ret = -ENOMEM;
+ break;
+ }
+ code->value = value;
+ list_add_tail(&code->list_item, &wakeup_code_list);
+ }
+
+ if (!ret)
+ ret = dev->s_wakeup_codes(dev, &wakeup_code_list, 1);
+
+ list_for_each_entry_safe(code, next, &wakeup_code_list, list_item) {
+ list_del(&code->list_item);
+ kfree(code);
+ }
+
+ mutex_unlock(&dev->lock);
+
+ return ret ? ret : len;
+}
+
static void rc_dev_release(struct device *device)
{
}
@@ -998,6 +1135,10 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
*/
static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
show_protocols, store_protocols);
+static DEVICE_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR,
+ show_protocols, store_protocols);
+static DEVICE_ATTR(wakeup_codes, S_IRUGO | S_IWUSR,
+ show_wakeup_codes, store_wakeup_codes);
static struct attribute *rc_dev_attrs[] = {
&dev_attr_protocols.attr,
@@ -1175,6 +1316,16 @@ int rc_register_device(struct rc_dev *dev)
dev->enabled_protocols = rc_type;
}
+ /* Create sysfs entry only if device has wake code support */
+ if (dev->s_wakeup_codes) {
+ rc = device_create_file(&dev->dev, &dev_attr_wakeup_codes);
+ if (rc < 0)
+ goto out_raw;
+ rc = device_create_file(&dev->dev, &dev_attr_wakeup_protocols);
+ if (rc < 0)
+ goto out_raw;
+ }
+
mutex_unlock(&dev->lock);
IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n",
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFCv2 PATCH 3/5] rc-loopback: Add support for reading/writing wakeup scancodes via sysfs
2014-01-26 21:50 [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 1/5] rc-core: Add defintions needed for sysfs callback Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 2/5] rc-core: Add support for reading/writing wakeup codes via sysfs Antti Seppälä
@ 2014-01-26 21:50 ` Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 4/5] nuvoton-cir: Add support for reading/writing wakeup samples " Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes " Antti Seppälä
4 siblings, 0 replies; 8+ messages in thread
From: Antti Seppälä @ 2014-01-26 21:50 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Sean Young, Antti Seppälä
This patch adds sample support for reading/writing the wakeup scancodes
to rc-loopback device driver.
Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
---
drivers/media/rc/rc-loopback.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 53d0282..46e76ad 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -26,6 +26,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <media/rc-core.h>
#define DRIVER_NAME "rc-loopback"
@@ -45,6 +46,7 @@ struct loopback_dev {
bool carrierreport;
u32 rxcarriermin;
u32 rxcarriermax;
+ u32 wakeup_scancode;
};
static struct loopback_dev loopdev;
@@ -176,6 +178,41 @@ static int loop_set_carrier_report(struct rc_dev *dev, int enable)
return 0;
}
+static int loop_wakeup_codes(struct rc_dev *dev,
+ struct list_head *wakeup_code_list, int write)
+{
+ u32 value = 0;
+ struct rc_wakeup_code *code;
+ struct loopback_dev *lodev = dev->priv;
+
+ dprintk("%sing wakeup codes\n", write ? "writ" : "read");
+
+ if (write) {
+ code = list_first_entry_or_null(wakeup_code_list,
+ struct rc_wakeup_code,
+ list_item);
+ if (code)
+ value = code->value;
+
+ if (dev->enabled_wake_protos & RC_BIT_RC5) {
+ if (value > 0xFFF)
+ return -EINVAL;
+ } else if (dev->enabled_wake_protos & RC_BIT_RC6_0) {
+ if (value > 0xFFFF)
+ return -EINVAL;
+ }
+
+ lodev->wakeup_scancode = value;
+ } else {
+ code = kmalloc(sizeof(struct rc_wakeup_code), GFP_KERNEL);
+ if (!code)
+ return -ENOMEM;
+ code->value = lodev->wakeup_scancode;
+ list_add_tail(&code->list_item, wakeup_code_list);
+ }
+ return 0;
+}
+
static int __init loop_init(void)
{
struct rc_dev *rc;
@@ -196,6 +233,8 @@ static int __init loop_init(void)
rc->priv = &loopdev;
rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protos = RC_BIT_ALL;
+ rc->allowed_wake_protos = RC_BIT_RC6_0 | RC_BIT_RC5;
+ rc->enabled_wake_protos = RC_BIT_RC6_0;
rc->timeout = 100 * 1000 * 1000; /* 100 ms */
rc->min_timeout = 1;
rc->max_timeout = UINT_MAX;
@@ -209,6 +248,7 @@ static int __init loop_init(void)
rc->s_idle = loop_set_idle;
rc->s_learning_mode = loop_set_learning_mode;
rc->s_carrier_report = loop_set_carrier_report;
+ rc->s_wakeup_codes = loop_wakeup_codes;
loopdev.txmask = RXMASK_REGULAR;
loopdev.txcarrier = 36000;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFCv2 PATCH 4/5] nuvoton-cir: Add support for reading/writing wakeup samples via sysfs
2014-01-26 21:50 [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes Antti Seppälä
` (2 preceding siblings ...)
2014-01-26 21:50 ` [RFCv2 PATCH 3/5] rc-loopback: Add support for reading/writing wakeup scancodes " Antti Seppälä
@ 2014-01-26 21:50 ` Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes " Antti Seppälä
4 siblings, 0 replies; 8+ messages in thread
From: Antti Seppälä @ 2014-01-26 21:50 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Sean Young, Antti Seppälä
This patch adds support for reading/writing wakeup samples via sysfs
to nuvoton-cir hardware.
The sysfs interface for nuvoton-cir contains raw IR pulse/space lengths.
If value is negative it is a space, otherwise it is a pulse.
Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
---
drivers/media/rc/nuvoton-cir.c | 118 +++++++++++++++++++++++++++++++++++++++++
drivers/media/rc/nuvoton-cir.h | 2 +
2 files changed, 120 insertions(+)
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 21ee0dc..015f3a8 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -531,6 +531,121 @@ static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
return 0;
}
+static int nvt_validate_wakeup_codes(struct list_head *wakeup_code_list)
+{
+ int i = 0;
+ const int MAX_SAMPLE = US_TO_NS(BUF_LEN_MASK * SAMPLE_PERIOD);
+ struct rc_wakeup_code *code;
+ list_for_each_entry(code, wakeup_code_list, list_item) {
+
+ /* Prevent writing too many or invalid codes */
+ if (++i > WAKE_FIFO_LEN)
+ return -EINVAL;
+ if (abs(code->value) > MAX_SAMPLE)
+ return -EINVAL;
+ }
+
+ return i;
+}
+
+static int nvt_wakeup_codes(struct rc_dev *dev,
+ struct list_head *wakeup_code_list, int write)
+{
+ int i = 0;
+ u8 cnt, val, reg, reg_learn_mode;
+ unsigned long flags;
+ struct rc_wakeup_code *code;
+ struct nvt_dev *nvt = dev->priv;
+
+ nvt_dbg_wake("%sing wakeup codes", write ? "writ" : "read");
+
+ if (write) {
+
+ /* Validate wake codes (count and values) */
+ i = nvt_validate_wakeup_codes(wakeup_code_list);
+ if (i < 0)
+ return -EINVAL;
+
+ reg = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON);
+ reg_learn_mode = reg & ~CIR_WAKE_IRCON_MODE0;
+ reg_learn_mode |= CIR_WAKE_IRCON_MODE1;
+
+ /* Lock the learn area to prevent racing with wake-isr */
+ spin_lock_irqsave(&nvt->nvt_lock, flags);
+
+ /* Enable fifo writes */
+ nvt_cir_wake_reg_write(nvt, reg_learn_mode, CIR_WAKE_IRCON);
+
+ /* Clear cir wake rx fifo */
+ nvt_clear_cir_wake_fifo(nvt);
+
+ pr_info("Wake samples (%d) =", i);
+
+ /* Write wake samples to fifo */
+ list_for_each_entry(code, wakeup_code_list, list_item) {
+
+ /* Convert to driver format */
+ val = DIV_ROUND_UP(abs(code->value), 1000L)
+ / SAMPLE_PERIOD;
+
+ if (code->value > 0)
+ val |= BUF_PULSE_BIT;
+
+ pr_cont(" %02x", val);
+ nvt_cir_wake_reg_write(nvt, val,
+ CIR_WAKE_WR_FIFO_DATA);
+ }
+ pr_cont("\n");
+
+ /* Switch cir to wakeup mode and disable fifo writing */
+ nvt_cir_wake_reg_write(nvt, reg, CIR_WAKE_IRCON);
+
+ /* Set number of bytes needed for wake */
+ nvt_cir_wake_reg_write(nvt, i ? i :
+ CIR_WAKE_FIFO_CMP_BYTES,
+ CIR_WAKE_FIFO_CMP_DEEP);
+
+ spin_unlock_irqrestore(&nvt->nvt_lock, flags);
+
+ } else {
+
+ /* Scroll to index 0 */
+ while (nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)) {
+ nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY);
+
+ /* Stuck index guardian */
+ if (++i > 255) {
+ nvt_dbg_wake("Idx reg is stuck!");
+ break;
+ }
+ }
+
+ /* Get size of wake fifo and allocate memory for the bytes */
+ cnt = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT);
+
+ for (i = 0; i < cnt; i++) {
+ code = kmalloc(sizeof(struct rc_wakeup_code),
+ GFP_KERNEL | GFP_ATOMIC);
+ if (!code)
+ return -ENOMEM;
+
+ val = nvt_cir_wake_reg_read(nvt,
+ CIR_WAKE_RD_FIFO_ONLY);
+
+ /* Convert to human readable sample-pulse format */
+ code->value = US_TO_NS((val & BUF_LEN_MASK)
+ * SAMPLE_PERIOD);
+ if (!(val & BUF_PULSE_BIT))
+ code->value *= -1;
+
+ list_add_tail(&code->list_item, wakeup_code_list);
+ }
+
+ return cnt;
+ }
+
+ return 0;
+}
/*
* nvt_tx_ir
*
@@ -1043,10 +1158,13 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
rdev->priv = nvt;
rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protos = RC_BIT_ALL;
+ rdev->allowed_wake_protos = RC_BIT_OTHER;
+ rdev->enabled_wake_protos = RC_BIT_OTHER;
rdev->open = nvt_open;
rdev->close = nvt_close;
rdev->tx_ir = nvt_tx_ir;
rdev->s_tx_carrier = nvt_set_tx_carrier;
+ rdev->s_wakeup_codes = nvt_wakeup_codes;
rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
rdev->input_phys = "nuvoton/cir0";
rdev->input_id.bustype = BUS_HOST;
diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h
index 07e8310..24ff630 100644
--- a/drivers/media/rc/nuvoton-cir.h
+++ b/drivers/media/rc/nuvoton-cir.h
@@ -64,6 +64,8 @@ static int debug;
#define TX_BUF_LEN 256
#define RX_BUF_LEN 32
+#define WAKE_FIFO_LEN 67
+
struct nvt_dev {
struct pnp_dev *pdev;
struct rc_dev *rdev;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes via sysfs
2014-01-26 21:50 [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes Antti Seppälä
` (3 preceding siblings ...)
2014-01-26 21:50 ` [RFCv2 PATCH 4/5] nuvoton-cir: Add support for reading/writing wakeup samples " Antti Seppälä
@ 2014-01-26 21:50 ` Antti Seppälä
2014-01-30 19:24 ` Sean Young
4 siblings, 1 reply; 8+ messages in thread
From: Antti Seppälä @ 2014-01-26 21:50 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Sean Young, Antti Seppälä
This patch adds support for reading/writing wakeup scancodes via sysfs
to nuvoton-cir hardware.
The existing mechanism of setting wakeup scancodes by using module
parameters is left untouched. If set the module parameters function as
default values for sysfs files.
Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
---
drivers/media/rc/winbond-cir.c | 66 ++++++++++++++++++++++++++++++------------
1 file changed, 48 insertions(+), 18 deletions(-)
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 904baf4..c63a56e 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -683,6 +683,29 @@ wbcir_tx(struct rc_dev *dev, unsigned *b, unsigned count)
return count;
}
+static int wbcir_wakeup_codes(struct rc_dev *dev,
+ struct list_head *wakeup_code_list, int write)
+{
+ u32 value = 0x800F040C;
+ struct rc_wakeup_code *code;
+ if (write) {
+ code = list_first_entry_or_null(wakeup_code_list,
+ struct rc_wakeup_code,
+ list_item);
+ if (code)
+ value = code->value;
+
+ wake_sc = value;
+ } else {
+ code = kmalloc(sizeof(struct rc_wakeup_code), GFP_KERNEL);
+ if (!code)
+ return -ENOMEM;
+ code->value = wake_sc;
+ list_add_tail(&code->list_item, wakeup_code_list);
+ }
+ return 0;
+}
+
/*****************************************************************************
*
* SETUP/INIT/SUSPEND/RESUME FUNCTIONS
@@ -708,12 +731,11 @@ wbcir_shutdown(struct pnp_dev *device)
goto finish;
}
- switch (protocol) {
- case IR_PROTOCOL_RC5:
+ if (data->dev->enabled_wake_protos & RC_BIT_RC5) {
if (wake_sc > 0xFFF) {
do_wake = false;
dev_err(dev, "RC5 - Invalid wake scancode\n");
- break;
+ goto finish;
}
/* Mask = 13 bits, ex toggle */
@@ -726,13 +748,11 @@ wbcir_shutdown(struct pnp_dev *device)
if (!(wake_sc & 0x0040)) /* 2nd start bit */
match[1] |= 0x10;
- break;
-
- case IR_PROTOCOL_NEC:
+ } else if (data->dev->enabled_wake_protos & RC_BIT_NEC) {
if (wake_sc > 0xFFFFFF) {
do_wake = false;
dev_err(dev, "NEC - Invalid wake scancode\n");
- break;
+ goto finish;
}
mask[0] = mask[1] = mask[2] = mask[3] = 0xFF;
@@ -745,16 +765,12 @@ wbcir_shutdown(struct pnp_dev *device)
match[2] = bitrev8((wake_sc & 0xFF0000) >> 16);
else
match[2] = ~match[3];
-
- break;
-
- case IR_PROTOCOL_RC6:
-
+ } else if (data->dev->enabled_wake_protos & RC_BIT_RC6_0) {
if (wake_rc6mode == 0) {
if (wake_sc > 0xFFFF) {
do_wake = false;
dev_err(dev, "RC6 - Invalid wake scancode\n");
- break;
+ goto finish;
}
/* Command */
@@ -810,7 +826,7 @@ wbcir_shutdown(struct pnp_dev *device)
} else {
do_wake = false;
dev_err(dev, "RC6 - Invalid wake scancode\n");
- break;
+ goto finish;
}
/* Header */
@@ -824,11 +840,8 @@ wbcir_shutdown(struct pnp_dev *device)
dev_err(dev, "RC6 - Invalid wake mode\n");
}
- break;
-
- default:
+ } else {
do_wake = false;
- break;
}
finish:
@@ -1077,12 +1090,29 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
data->dev->s_carrier_report = wbcir_set_carrier_report;
data->dev->s_tx_mask = wbcir_txmask;
data->dev->s_tx_carrier = wbcir_txcarrier;
+ data->dev->s_wakeup_codes = wbcir_wakeup_codes;
data->dev->tx_ir = wbcir_tx;
data->dev->priv = data;
data->dev->dev.parent = &device->dev;
data->dev->timeout = MS_TO_NS(100);
data->dev->rx_resolution = US_TO_NS(2);
data->dev->allowed_protos = RC_BIT_ALL;
+ data->dev->allowed_wake_protos = RC_BIT_RC5 | RC_BIT_RC6_0 | RC_BIT_NEC;
+ /* Utilize default protocol from module parameter */
+ switch (protocol) {
+ case IR_PROTOCOL_RC5:
+ data->dev->enabled_wake_protos = RC_BIT_RC5;
+ break;
+ case IR_PROTOCOL_RC6:
+ data->dev->enabled_wake_protos = RC_BIT_RC6_0;
+ break;
+ case IR_PROTOCOL_NEC:
+ data->dev->enabled_wake_protos = RC_BIT_NEC;
+ break;
+ default:
+ data->dev->enabled_wake_protos = RC_BIT_NONE;
+ break;
+ }
err = rc_register_device(data->dev);
if (err)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes via sysfs
2014-01-26 21:50 ` [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes " Antti Seppälä
@ 2014-01-30 19:24 ` Sean Young
2014-01-31 13:34 ` Antti Seppälä
0 siblings, 1 reply; 8+ messages in thread
From: Sean Young @ 2014-01-30 19:24 UTC (permalink / raw)
To: Antti Seppälä; +Cc: linux-media, Mauro Carvalho Chehab
On Sun, Jan 26, 2014 at 11:50:26PM +0200, Antti Seppälä wrote:
> This patch adds support for reading/writing wakeup scancodes via sysfs
> to nuvoton-cir hardware.
>
> The existing mechanism of setting wakeup scancodes by using module
> parameters is left untouched. If set the module parameters function as
> default values for sysfs files.
>
> Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
> ---
> drivers/media/rc/winbond-cir.c | 66 ++++++++++++++++++++++++++++++------------
> 1 file changed, 48 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
> index 904baf4..c63a56e 100644
> --- a/drivers/media/rc/winbond-cir.c
> +++ b/drivers/media/rc/winbond-cir.c
> @@ -683,6 +683,29 @@ wbcir_tx(struct rc_dev *dev, unsigned *b, unsigned count)
> return count;
> }
>
> +static int wbcir_wakeup_codes(struct rc_dev *dev,
> + struct list_head *wakeup_code_list, int write)
> +{
> + u32 value = 0x800F040C;
> + struct rc_wakeup_code *code;
> + if (write) {
I think it would be better to have a read/write function rather passing it
as an argument; they are distinct functions.
> + code = list_first_entry_or_null(wakeup_code_list,
> + struct rc_wakeup_code,
> + list_item);
> + if (code)
> + value = code->value;
If more than one value is provided then that should be an error; if no
value is provided then that is an error too. Sure the scancode can default
to mce sleep/rc6 on startup.
> +
> + wake_sc = value;
> + } else {
> + code = kmalloc(sizeof(struct rc_wakeup_code), GFP_KERNEL);
> + if (!code)
> + return -ENOMEM;
> + code->value = wake_sc;
> + list_add_tail(&code->list_item, wakeup_code_list);
> + }
> + return 0;
> +}
> +
> /*****************************************************************************
> *
> * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
> @@ -708,12 +731,11 @@ wbcir_shutdown(struct pnp_dev *device)
> goto finish;
> }
>
> - switch (protocol) {
> - case IR_PROTOCOL_RC5:
> + if (data->dev->enabled_wake_protos & RC_BIT_RC5) {
> if (wake_sc > 0xFFF) {
> do_wake = false;
> dev_err(dev, "RC5 - Invalid wake scancode\n");
> - break;
> + goto finish;
> }
>
> /* Mask = 13 bits, ex toggle */
> @@ -726,13 +748,11 @@ wbcir_shutdown(struct pnp_dev *device)
> if (!(wake_sc & 0x0040)) /* 2nd start bit */
> match[1] |= 0x10;
>
> - break;
> -
> - case IR_PROTOCOL_NEC:
> + } else if (data->dev->enabled_wake_protos & RC_BIT_NEC) {
> if (wake_sc > 0xFFFFFF) {
> do_wake = false;
> dev_err(dev, "NEC - Invalid wake scancode\n");
> - break;
> + goto finish;
> }
>
> mask[0] = mask[1] = mask[2] = mask[3] = 0xFF;
> @@ -745,16 +765,12 @@ wbcir_shutdown(struct pnp_dev *device)
> match[2] = bitrev8((wake_sc & 0xFF0000) >> 16);
> else
> match[2] = ~match[3];
> -
> - break;
> -
> - case IR_PROTOCOL_RC6:
> -
> + } else if (data->dev->enabled_wake_protos & RC_BIT_RC6_0) {
> if (wake_rc6mode == 0) {
> if (wake_sc > 0xFFFF) {
> do_wake = false;
> dev_err(dev, "RC6 - Invalid wake scancode\n");
> - break;
> + goto finish;
> }
>
> /* Command */
> @@ -810,7 +826,7 @@ wbcir_shutdown(struct pnp_dev *device)
> } else {
> do_wake = false;
> dev_err(dev, "RC6 - Invalid wake scancode\n");
> - break;
> + goto finish;
> }
>
> /* Header */
> @@ -824,11 +840,8 @@ wbcir_shutdown(struct pnp_dev *device)
> dev_err(dev, "RC6 - Invalid wake mode\n");
> }
>
> - break;
> -
> - default:
> + } else {
> do_wake = false;
> - break;
> }
>
> finish:
> @@ -1077,12 +1090,29 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
> data->dev->s_carrier_report = wbcir_set_carrier_report;
> data->dev->s_tx_mask = wbcir_txmask;
> data->dev->s_tx_carrier = wbcir_txcarrier;
> + data->dev->s_wakeup_codes = wbcir_wakeup_codes;
> data->dev->tx_ir = wbcir_tx;
> data->dev->priv = data;
> data->dev->dev.parent = &device->dev;
> data->dev->timeout = MS_TO_NS(100);
> data->dev->rx_resolution = US_TO_NS(2);
> data->dev->allowed_protos = RC_BIT_ALL;
> + data->dev->allowed_wake_protos = RC_BIT_RC5 | RC_BIT_RC6_0 | RC_BIT_NEC;
> + /* Utilize default protocol from module parameter */
> + switch (protocol) {
> + case IR_PROTOCOL_RC5:
> + data->dev->enabled_wake_protos = RC_BIT_RC5;
> + break;
> + case IR_PROTOCOL_RC6:
> + data->dev->enabled_wake_protos = RC_BIT_RC6_0;
> + break;
> + case IR_PROTOCOL_NEC:
> + data->dev->enabled_wake_protos = RC_BIT_NEC;
> + break;
> + default:
> + data->dev->enabled_wake_protos = RC_BIT_NONE;
> + break;
> + }
You might as well remove the module parameters, I'd say.
>
> err = rc_register_device(data->dev);
> if (err)
> --
> 1.8.3.2
Sean
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes via sysfs
2014-01-30 19:24 ` Sean Young
@ 2014-01-31 13:34 ` Antti Seppälä
0 siblings, 0 replies; 8+ messages in thread
From: Antti Seppälä @ 2014-01-31 13:34 UTC (permalink / raw)
To: Sean Young; +Cc: linux-media, Mauro Carvalho Chehab
On 30 January 2014 21:24, Sean Young <sean@mess.org> wrote:
> On Sun, Jan 26, 2014 at 11:50:26PM +0200, Antti Seppälä wrote:
>> This patch adds support for reading/writing wakeup scancodes via sysfs
>> to nuvoton-cir hardware.
>>
>> The existing mechanism of setting wakeup scancodes by using module
>> parameters is left untouched. If set the module parameters function as
>> default values for sysfs files.
>>
>> Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
>> ---
>> drivers/media/rc/winbond-cir.c | 66 ++++++++++++++++++++++++++++++------------
>> 1 file changed, 48 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
>> index 904baf4..c63a56e 100644
>> --- a/drivers/media/rc/winbond-cir.c
>> +++ b/drivers/media/rc/winbond-cir.c
>> @@ -683,6 +683,29 @@ wbcir_tx(struct rc_dev *dev, unsigned *b, unsigned count)
>> return count;
>> }
>>
>> +static int wbcir_wakeup_codes(struct rc_dev *dev,
>> + struct list_head *wakeup_code_list, int write)
>> +{
>> + u32 value = 0x800F040C;
>> + struct rc_wakeup_code *code;
>> + if (write) {
>
> I think it would be better to have a read/write function rather passing it
> as an argument; they are distinct functions.
>
I modeled the wakeup code callback after other s_* callbacks found in rc-core
some of which have similar kind of enable/disable type flag.
I guess I can split the callback into a more readable version at the expense of
some added code lines in each driver.
>> + code = list_first_entry_or_null(wakeup_code_list,
>> + struct rc_wakeup_code,
>> + list_item);
>> + if (code)
>> + value = code->value;
>
> If more than one value is provided then that should be an error; if no
> value is provided then that is an error too. Sure the scancode can default
> to mce sleep/rc6 on startup.
>
I'll add stricter sanity checking here.
>> +
>> + wake_sc = value;
>> + } else {
>> + code = kmalloc(sizeof(struct rc_wakeup_code), GFP_KERNEL);
>> + if (!code)
>> + return -ENOMEM;
>> + code->value = wake_sc;
>> + list_add_tail(&code->list_item, wakeup_code_list);
>> + }
>> + return 0;
>> +}
>> +
>> /*****************************************************************************
>> *
>> * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
>> @@ -708,12 +731,11 @@ wbcir_shutdown(struct pnp_dev *device)
>> goto finish;
>> }
>>
>> - switch (protocol) {
>> - case IR_PROTOCOL_RC5:
>> + if (data->dev->enabled_wake_protos & RC_BIT_RC5) {
>> if (wake_sc > 0xFFF) {
>> do_wake = false;
>> dev_err(dev, "RC5 - Invalid wake scancode\n");
>> - break;
>> + goto finish;
>> }
>>
>> /* Mask = 13 bits, ex toggle */
>> @@ -726,13 +748,11 @@ wbcir_shutdown(struct pnp_dev *device)
>> if (!(wake_sc & 0x0040)) /* 2nd start bit */
>> match[1] |= 0x10;
>>
>> - break;
>> -
>> - case IR_PROTOCOL_NEC:
>> + } else if (data->dev->enabled_wake_protos & RC_BIT_NEC) {
>> if (wake_sc > 0xFFFFFF) {
>> do_wake = false;
>> dev_err(dev, "NEC - Invalid wake scancode\n");
>> - break;
>> + goto finish;
>> }
>>
>> mask[0] = mask[1] = mask[2] = mask[3] = 0xFF;
>> @@ -745,16 +765,12 @@ wbcir_shutdown(struct pnp_dev *device)
>> match[2] = bitrev8((wake_sc & 0xFF0000) >> 16);
>> else
>> match[2] = ~match[3];
>> -
>> - break;
>> -
>> - case IR_PROTOCOL_RC6:
>> -
>> + } else if (data->dev->enabled_wake_protos & RC_BIT_RC6_0) {
>> if (wake_rc6mode == 0) {
>> if (wake_sc > 0xFFFF) {
>> do_wake = false;
>> dev_err(dev, "RC6 - Invalid wake scancode\n");
>> - break;
>> + goto finish;
>> }
>>
>> /* Command */
>> @@ -810,7 +826,7 @@ wbcir_shutdown(struct pnp_dev *device)
>> } else {
>> do_wake = false;
>> dev_err(dev, "RC6 - Invalid wake scancode\n");
>> - break;
>> + goto finish;
>> }
>>
>> /* Header */
>> @@ -824,11 +840,8 @@ wbcir_shutdown(struct pnp_dev *device)
>> dev_err(dev, "RC6 - Invalid wake mode\n");
>> }
>>
>> - break;
>> -
>> - default:
>> + } else {
>> do_wake = false;
>> - break;
>> }
>>
>> finish:
>> @@ -1077,12 +1090,29 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
>> data->dev->s_carrier_report = wbcir_set_carrier_report;
>> data->dev->s_tx_mask = wbcir_txmask;
>> data->dev->s_tx_carrier = wbcir_txcarrier;
>> + data->dev->s_wakeup_codes = wbcir_wakeup_codes;
>> data->dev->tx_ir = wbcir_tx;
>> data->dev->priv = data;
>> data->dev->dev.parent = &device->dev;
>> data->dev->timeout = MS_TO_NS(100);
>> data->dev->rx_resolution = US_TO_NS(2);
>> data->dev->allowed_protos = RC_BIT_ALL;
>> + data->dev->allowed_wake_protos = RC_BIT_RC5 | RC_BIT_RC6_0 | RC_BIT_NEC;
>> + /* Utilize default protocol from module parameter */
>> + switch (protocol) {
>> + case IR_PROTOCOL_RC5:
>> + data->dev->enabled_wake_protos = RC_BIT_RC5;
>> + break;
>> + case IR_PROTOCOL_RC6:
>> + data->dev->enabled_wake_protos = RC_BIT_RC6_0;
>> + break;
>> + case IR_PROTOCOL_NEC:
>> + data->dev->enabled_wake_protos = RC_BIT_NEC;
>> + break;
>> + default:
>> + data->dev->enabled_wake_protos = RC_BIT_NONE;
>> + break;
>> + }
>
> You might as well remove the module parameters, I'd say.
>
I can add a patch removing all the other wake_* parameters but it seems
that wake_rc6mode needs to stay.
This is because the wakeup_protocols file (or protocols for that matter) is not
able to differentiate between rc6 and rc6a and this distinction is needed for
wakeup in winbond-cir.
-Antti
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-01-31 13:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-26 21:50 [RFCv2 PATCH 0/5] rc: Add generic sysfs interface for handling wakeup codes Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 1/5] rc-core: Add defintions needed for sysfs callback Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 2/5] rc-core: Add support for reading/writing wakeup codes via sysfs Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 3/5] rc-loopback: Add support for reading/writing wakeup scancodes " Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 4/5] nuvoton-cir: Add support for reading/writing wakeup samples " Antti Seppälä
2014-01-26 21:50 ` [RFCv2 PATCH 5/5] winbond-cir: Add support for reading/writing wakeup scancodes " Antti Seppälä
2014-01-30 19:24 ` Sean Young
2014-01-31 13:34 ` Antti Seppälä
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox