Commit 0751d33c authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab

[media] rc: change wakeup_protocols to list all protocol variants

For IR wakeup, a driver has to program the hardware to wakeup at a
specific IR sequence, so it makes no sense to allow multiple wakeup
protocols to be selected. In the same manner the sysfs interface only
allows one scancode to be provided.

In addition, we need to know the specific variant of the protocol.

In short, these changes are made to the wakeup_protocols sysfs entry:
 - list all the protocol variants rather than the protocol groups,
   e.g. "nec nec-x nec-32" rather than just "nec".
 - only allow one protocol variant to be selected rather than multiple
 - wakeup_filter can only be set once a protocol has been selected in
   wakeup_protocols.

This is an API change, however the only user of this API is the img-ir,
but the wakeup code was never merged to mainline, so it was never used.
Signed-off-by: default avatarSean Young <sean@mess.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Sifan Naeem <sifan.naeem@imgtec.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 0fcd3f0a
......@@ -62,18 +62,18 @@ Description:
This value may be reset to 0 if the current protocol is altered.
What: /sys/class/rc/rcN/wakeup_protocols
Date: Feb 2014
KernelVersion: 3.15
Date: Feb 2017
KernelVersion: 4.11
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
Description:
Reading this file returns a list of available protocols to use
for the wakeup filter, something like:
"rc5 rc6 nec jvc [sony]"
"rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce"
Note that protocol variants are listed, so "nec", "sony",
"rc-5", "rc-6" have their different bit length encodings
listed if available.
The enabled wakeup protocol is shown in [] brackets.
Writing "+proto" will add a protocol to the list of enabled
wakeup protocols.
Writing "-proto" will remove a protocol from the list of enabled
wakeup protocols.
Only one protocol can be selected at a time.
Writing "proto" will use "proto" for wakeup events.
Writing "none" will disable wakeup.
Write fails with EINVAL if an invalid protocol combination or
......
......@@ -92,15 +92,16 @@ This value may be reset to 0 if the current protocol is altered.
Reading this file returns a list of available protocols to use for the
wakeup filter, something like:
``rc5 rc6 nec jvc [sony]``
``rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce``
The enabled wakeup protocol is shown in [] brackets.
Note that protocol variants are listed, so "nec", "sony", "rc-5", "rc-6"
have their different bit length encodings listed if available.
Writing "+proto" will add a protocol to the list of enabled wakeup
protocols.
Note that all protocol variants are listed.
Writing "-proto" will remove a protocol from the list of enabled wakeup
protocols.
The enabled wakeup protocol is shown in [] brackets.
Only one protocol can be selected at a time.
Writing "proto" will use "proto" for wakeup events.
......
......@@ -488,7 +488,15 @@ static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type,
/* convert scancode filter to raw filter */
filter.minlen = 0;
filter.maxlen = ~0;
ret = hw->decoder->filter(sc_filter, &filter, hw->enabled_protocols);
if (type == RC_FILTER_NORMAL) {
/* guess scancode from protocol */
ret = hw->decoder->filter(sc_filter, &filter,
dev->enabled_protocols);
} else {
/* for wakeup user provided exact protocol variant */
ret = hw->decoder->filter(sc_filter, &filter,
1ULL << dev->wakeup_protocol);
}
if (ret)
goto unlock;
dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n",
......@@ -581,6 +589,7 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
/* clear the wakeup scancode filter */
rdev->scancode_wakeup_filter.data = 0;
rdev->scancode_wakeup_filter.mask = 0;
rdev->wakeup_protocol = RC_TYPE_UNKNOWN;
/* clear raw filters */
_img_ir_set_filter(priv, NULL);
......@@ -685,7 +694,6 @@ static int img_ir_change_protocol(struct rc_dev *dev, u64 *ir_type)
if (!hw->decoder || !hw->decoder->filter)
wakeup_protocols = 0;
rdev->allowed_wakeup_protocols = wakeup_protocols;
rdev->enabled_wakeup_protocols = wakeup_protocols;
return 0;
}
......@@ -701,7 +709,6 @@ static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto)
mutex_lock(&rdev->lock);
rdev->enabled_protocols = proto;
rdev->allowed_wakeup_protocols = proto;
rdev->enabled_wakeup_protocols = proto;
mutex_unlock(&rdev->lock);
}
......
......@@ -11,6 +11,7 @@
#include "img-ir-hw.h"
#include <linux/bitrev.h>
#include <linux/log2.h>
/* Convert NEC data to a scancode */
static int img_ir_nec_scancode(int len, u64 raw, u64 enabled_protocols,
......@@ -62,7 +63,23 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in,
data = in->data & 0xff;
data_m = in->mask & 0xff;
if ((in->data | in->mask) & 0xff000000) {
protocols &= RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32;
/*
* If only one bit is set, we were requested to do an exact
* protocol. This should be the case for wakeup filters; for
* normal filters, guess the protocol from the scancode.
*/
if (!is_power_of_2(protocols)) {
if ((in->data | in->mask) & 0xff000000)
protocols = RC_BIT_NEC32;
else if ((in->data | in->mask) & 0x00ff0000)
protocols = RC_BIT_NECX;
else
protocols = RC_BIT_NEC;
}
if (protocols == RC_BIT_NEC32) {
/* 32-bit NEC (used by Apple and TiVo remotes) */
/* scan encoding: as transmitted, MSBit = first received bit */
addr = bitrev8(in->data >> 24);
......@@ -73,7 +90,7 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in,
data_m = bitrev8(in->mask >> 8);
data_inv = bitrev8(in->data >> 0);
data_inv_m = bitrev8(in->mask >> 0);
} else if ((in->data | in->mask) & 0x00ff0000) {
} else if (protocols == RC_BIT_NECX) {
/* Extended NEC */
/* scan encoding AAaaDD */
addr = (in->data >> 16) & 0xff;
......
......@@ -68,19 +68,29 @@ static int img_ir_sony_filter(const struct rc_scancode_filter *in,
func = (in->data >> 0) & 0x7f;
func_m = (in->mask >> 0) & 0x7f;
if (subdev & subdev_m) {
protocols &= RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20;
/*
* If only one bit is set, we were requested to do an exact
* protocol. This should be the case for wakeup filters; for
* normal filters, guess the protocol from the scancode.
*/
if (!is_power_of_2(protocols)) {
if (subdev & subdev_m)
protocols = RC_BIT_SONY20;
else if (dev & dev_m & 0xe0)
protocols = RC_BIT_SONY15;
else
protocols = RC_BIT_SONY12;
}
if (protocols == RC_BIT_SONY20) {
/* can't encode subdev and higher device bits */
if (dev & dev_m & 0xe0)
return -EINVAL;
/* subdevice (extended) bits only in 20 bit encoding */
if (!(protocols & RC_BIT_SONY20))
return -EINVAL;
len = 20;
dev_m &= 0x1f;
} else if (dev & dev_m & 0xe0) {
/* upper device bits only in 15 bit encoding */
if (!(protocols & RC_BIT_SONY15))
return -EINVAL;
} else if (protocols == RC_BIT_SONY15) {
len = 15;
subdev_m = 0;
} else {
......
......@@ -235,7 +235,6 @@ static void ir_raw_disable_protocols(struct rc_dev *dev, u64 protocols)
{
mutex_lock(&dev->lock);
dev->enabled_protocols &= ~protocols;
dev->enabled_wakeup_protocols &= ~protocols;
mutex_unlock(&dev->lock);
}
......
This diff is collapsed.
......@@ -86,7 +86,8 @@ enum rc_filter_type {
* @allowed_protocols: bitmask with the supported RC_BIT_* protocols
* @enabled_protocols: bitmask with the enabled RC_BIT_* protocols
* @allowed_wakeup_protocols: bitmask with the supported RC_BIT_* wakeup protocols
* @enabled_wakeup_protocols: bitmask with the enabled RC_BIT_* wakeup protocols
* @wakeup_protocol: the enabled RC_TYPE_* wakeup protocol or
* RC_TYPE_UNKNOWN if disabled.
* @scancode_filter: scancode filter
* @scancode_wakeup_filter: scancode wakeup filters
* @scancode_mask: some hardware decoders are not capable of providing the full
......@@ -110,8 +111,6 @@ enum rc_filter_type {
* @rx_resolution : resolution (in ns) of input sampler
* @tx_resolution: resolution (in ns) of output sampler
* @change_protocol: allow changing the protocol used on hardware decoders
* @change_wakeup_protocol: allow changing the protocol used for wakeup
* filtering
* @open: callback to allow drivers to enable polling/irq when IR input device
* is opened.
* @close: callback to allow drivers to disable polling/irq when IR input device
......@@ -126,7 +125,9 @@ enum rc_filter_type {
* @s_learning_mode: enable wide band receiver used for learning
* @s_carrier_report: enable carrier reports
* @s_filter: set the scancode filter
* @s_wakeup_filter: set the wakeup scancode filter
* @s_wakeup_filter: set the wakeup scancode filter. If the mask is zero
* then wakeup should be disabled. wakeup_protocol will be set to
* a valid protocol if mask is nonzero.
* @s_timeout: set hardware timeout in ns
*/
struct rc_dev {
......@@ -149,7 +150,7 @@ struct rc_dev {
u64 allowed_protocols;
u64 enabled_protocols;
u64 allowed_wakeup_protocols;
u64 enabled_wakeup_protocols;
enum rc_type wakeup_protocol;
struct rc_scancode_filter scancode_filter;
struct rc_scancode_filter scancode_wakeup_filter;
u32 scancode_mask;
......@@ -169,7 +170,6 @@ struct rc_dev {
u32 rx_resolution;
u32 tx_resolution;
int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
int (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type);
int (*open)(struct rc_dev *dev);
void (*close)(struct rc_dev *dev);
int (*s_tx_mask)(struct rc_dev *dev, u32 mask);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment