media: imon_raw: simplify and explain bit operations
This code needs some explanation. Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:

committed by
Mauro Carvalho Chehab

parent
1b09a2afa4
commit
e70d13f7ac
@@ -14,7 +14,7 @@ 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] __aligned(__alignof__(u64));
|
__be64 ir_buf;
|
||||||
char phys[64];
|
char phys[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,14 +29,35 @@ struct imon {
|
|||||||
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 = {};
|
||||||
u64 d = be64_to_cpup((__be64 *)imon->ir_buf) >> 24;
|
u64 data = be64_to_cpu(imon->ir_buf);
|
||||||
|
u8 packet_no = data & 0xff;
|
||||||
int offset = 40;
|
int offset = 40;
|
||||||
int bit;
|
int bit;
|
||||||
|
|
||||||
dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf);
|
if (packet_no == 0xff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_dbg(imon->dev, "data: %*ph", 8, &imon->ir_buf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only the first 5 bytes contain IR data. Right shift so we move
|
||||||
|
* the IR bits to the lower 40 bits.
|
||||||
|
*/
|
||||||
|
data >>= 24;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bit = fls64(d & (BIT_ULL(offset) - 1));
|
/*
|
||||||
|
* Find highest set bit which is less or equal to offset
|
||||||
|
*
|
||||||
|
* offset is the bit above (base 0) where we start looking.
|
||||||
|
*
|
||||||
|
* data & (BIT_ULL(offset) - 1) masks off any unwanted bits,
|
||||||
|
* so we have just bits less than offset.
|
||||||
|
*
|
||||||
|
* fls will tell us the highest bit set plus 1 (or 0 if no
|
||||||
|
* bits are set).
|
||||||
|
*/
|
||||||
|
bit = fls64(data & (BIT_ULL(offset) - 1));
|
||||||
if (bit < offset) {
|
if (bit < offset) {
|
||||||
dev_dbg(imon->dev, "pulse: %d bits", offset - bit);
|
dev_dbg(imon->dev, "pulse: %d bits", offset - bit);
|
||||||
rawir.pulse = true;
|
rawir.pulse = true;
|
||||||
@@ -49,7 +70,12 @@ static void imon_ir_data(struct imon *imon)
|
|||||||
offset = bit;
|
offset = bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bit = fls64(~d & (BIT_ULL(offset) - 1));
|
/*
|
||||||
|
* Find highest clear bit which is less than offset.
|
||||||
|
*
|
||||||
|
* Just invert the data and use same trick as above.
|
||||||
|
*/
|
||||||
|
bit = fls64(~data & (BIT_ULL(offset) - 1));
|
||||||
dev_dbg(imon->dev, "space: %d bits", offset - bit);
|
dev_dbg(imon->dev, "space: %d bits", offset - bit);
|
||||||
|
|
||||||
rawir.pulse = false;
|
rawir.pulse = false;
|
||||||
@@ -59,7 +85,7 @@ static void imon_ir_data(struct imon *imon)
|
|||||||
offset = bit;
|
offset = bit;
|
||||||
} while (offset > 0);
|
} while (offset > 0);
|
||||||
|
|
||||||
if (imon->ir_buf[7] == 0x0a) {
|
if (packet_no == 0x0a) {
|
||||||
ir_raw_event_set_idle(imon->rcdev, true);
|
ir_raw_event_set_idle(imon->rcdev, true);
|
||||||
ir_raw_event_handle(imon->rcdev);
|
ir_raw_event_handle(imon->rcdev);
|
||||||
}
|
}
|
||||||
@@ -72,8 +98,7 @@ static void imon_ir_rx(struct urb *urb)
|
|||||||
|
|
||||||
switch (urb->status) {
|
switch (urb->status) {
|
||||||
case 0:
|
case 0:
|
||||||
if (imon->ir_buf[7] != 0xff)
|
imon_ir_data(imon);
|
||||||
imon_ir_data(imon);
|
|
||||||
break;
|
break;
|
||||||
case -ECONNRESET:
|
case -ECONNRESET:
|
||||||
case -ENOENT:
|
case -ENOENT:
|
||||||
@@ -129,7 +154,7 @@ static int imon_probe(struct usb_interface *intf,
|
|||||||
imon->dev = &intf->dev;
|
imon->dev = &intf->dev;
|
||||||
usb_fill_int_urb(imon->ir_urb, udev,
|
usb_fill_int_urb(imon->ir_urb, udev,
|
||||||
usb_rcvintpipe(udev, ir_ep->bEndpointAddress),
|
usb_rcvintpipe(udev, ir_ep->bEndpointAddress),
|
||||||
imon->ir_buf, sizeof(imon->ir_buf),
|
&imon->ir_buf, sizeof(imon->ir_buf),
|
||||||
imon_ir_rx, imon, ir_ep->bInterval);
|
imon_ir_rx, imon, ir_ep->bInterval);
|
||||||
|
|
||||||
rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_IR_RAW);
|
rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_IR_RAW);
|
||||||
|
Reference in New Issue
Block a user