diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 21a385074ec1..d7a1d8cbdf04 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -727,11 +727,11 @@ EXPORT_SYMBOL_GPL(rc_keydown_notimeout); /** * rc_validate_filter() - checks that the scancode and mask are valid and * provides sensible defaults - * @protocol: the protocol for the filter + * @dev: the struct rc_dev descriptor of the device * @filter: the scancode and mask * @return: 0 or -EINVAL if the filter is not valid */ -static int rc_validate_filter(enum rc_type protocol, +static int rc_validate_filter(struct rc_dev *dev, struct rc_scancode_filter *filter) { static u32 masks[] = { @@ -754,6 +754,7 @@ static int rc_validate_filter(enum rc_type protocol, [RC_TYPE_SHARP] = 0x1fff, }; u32 s = filter->data; + enum rc_type protocol = dev->wakeup_protocol; switch (protocol) { case RC_TYPE_NECX: @@ -779,6 +780,13 @@ static int rc_validate_filter(enum rc_type protocol, filter->data &= masks[protocol]; filter->mask &= masks[protocol]; + /* + * If we have to raw encode the IR for wakeup, we cannot have a mask + */ + if (dev->encode_wakeup && + filter->mask != 0 && filter->mask != masks[protocol]) + return -EINVAL; + return 0; } @@ -1044,7 +1052,6 @@ static int parse_protocol_change(u64 *protocols, const char *buf) } static void ir_raw_load_modules(u64 *protocols) - { u64 available; int i, ret; @@ -1292,8 +1299,7 @@ static ssize_t store_filter(struct device *device, * and the filter is valid for that protocol */ if (dev->wakeup_protocol != RC_TYPE_UNKNOWN) - ret = rc_validate_filter(dev->wakeup_protocol, - &new_filter); + ret = rc_validate_filter(dev, &new_filter); else ret = -EINVAL; @@ -1461,6 +1467,16 @@ static ssize_t store_wakeup_protocols(struct device *device, rc = -EINVAL; goto out; } + + if (dev->encode_wakeup) { + u64 mask = 1ULL << protocol; + + ir_raw_load_modules(&mask); + if (!mask) { + rc = -EINVAL; + goto out; + } + } } if (dev->wakeup_protocol != protocol) { diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 62d69b171bb6..cf9fabcee33e 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -83,6 +83,8 @@ enum rc_filter_type { * @input_dev: the input child device used to communicate events to userspace * @driver_type: specifies if protocol decoding is done in hardware or software * @idle: used to keep track of RX state + * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed + * wakeup protocols is the set of all raw encoders * @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 @@ -147,6 +149,7 @@ struct rc_dev { struct input_dev *input_dev; enum rc_driver_type driver_type; bool idle; + bool encode_wakeup; u64 allowed_protocols; u64 enabled_protocols; u64 allowed_wakeup_protocols; diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 40f36b8f762a..df7b032897bb 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -106,6 +106,15 @@ enum rc_type { RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ RC_BIT_XMP) +#define RC_BIT_ALL_IR_ENCODER \ + (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ + RC_BIT_JVC | \ + RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ + RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ + RC_BIT_SANYO | \ + RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ + RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | \ + RC_BIT_SHARP) #define RC_SCANCODE_UNKNOWN(x) (x) #define RC_SCANCODE_OTHER(x) (x)