Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -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
+7 −6
Original line number Diff line number Diff line
@@ -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.

+10 −3
Original line number Diff line number Diff line
@@ -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);
}

+19 −2
Original line number Diff line number Diff line
@@ -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;
+18 −8
Original line number Diff line number Diff line
@@ -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 {
Loading