Commit 8d023a57 authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab

media: rc: imon_raw: use fls rather than loop per bit

Previously, the code would loop for each of the 40 bits. Now it will
branch for each edge in the IR, which will be much less.
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent cea1c41d
...@@ -14,51 +14,50 @@ struct imon { ...@@ -14,51 +14,50 @@ struct imon {
struct device *dev; struct device *dev;
struct urb *ir_urb; struct urb *ir_urb;
struct rc_dev *rcdev; struct rc_dev *rcdev;
u8 ir_buf[8]; u8 ir_buf[8] __aligned(__alignof__(u64));
char phys[64]; char phys[64];
}; };
/* /*
* ffs/find_next_bit() searches in the wrong direction, so open-code our own. * The first 5 bytes of data represent IR pulse or space. Each bit, starting
* from highest bit in the first byte, represents 250µs of data. It is 1
* for space and 0 for pulse.
*
* The station sends 10 packets, and the 7th byte will be number 1 to 10, so
* when we receive 10 we assume all the data has arrived.
*/ */
static inline int is_bit_set(const u8 *buf, int bit)
{
return buf[bit / 8] & (0x80 >> (bit & 7));
}
static void imon_ir_data(struct imon *imon) static void imon_ir_data(struct imon *imon)
{ {
struct ir_raw_event rawir = {}; struct ir_raw_event rawir = {};
int offset = 0, size = 5 * 8; u64 d = be64_to_cpup((__be64 *)imon->ir_buf) >> 24;
int offset = 40;
int bit; int bit;
dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf);
while (offset < size) { do {
bit = offset; bit = fls64(d & (BIT_ULL(offset) - 1));
while (!is_bit_set(imon->ir_buf, bit) && bit < size) if (bit < offset) {
bit++; dev_dbg(imon->dev, "pulse: %d bits", offset - bit);
dev_dbg(imon->dev, "pulse: %d bits", bit - offset);
if (bit > offset) {
rawir.pulse = true; rawir.pulse = true;
rawir.duration = (bit - offset) * BIT_DURATION; rawir.duration = (offset - bit) * BIT_DURATION;
ir_raw_event_store_with_filter(imon->rcdev, &rawir); ir_raw_event_store_with_filter(imon->rcdev, &rawir);
}
if (bit >= size) if (bit == 0)
break; break;
offset = bit; offset = bit;
while (is_bit_set(imon->ir_buf, bit) && bit < size) }
bit++;
dev_dbg(imon->dev, "space: %d bits", bit - offset); bit = fls64(~d & (BIT_ULL(offset) - 1));
dev_dbg(imon->dev, "space: %d bits", offset - bit);
rawir.pulse = false; rawir.pulse = false;
rawir.duration = (bit - offset) * BIT_DURATION; rawir.duration = (offset - bit) * BIT_DURATION;
ir_raw_event_store_with_filter(imon->rcdev, &rawir); ir_raw_event_store_with_filter(imon->rcdev, &rawir);
offset = bit; offset = bit;
} } while (offset > 0);
if (imon->ir_buf[7] == 0x0a) { if (imon->ir_buf[7] == 0x0a) {
ir_raw_event_set_idle(imon->rcdev, true); ir_raw_event_set_idle(imon->rcdev, true);
......
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