Support getting signed and unsigned HID data.
Submitted by: Alex Deiter Reviewed by: Hans Petter Selaksy
This commit is contained in:
parent
f006c8aa86
commit
f7f314b3e7
@ -63,13 +63,17 @@ hid_get_data(const void *p, const hid_item_t *h)
|
||||
data = 0;
|
||||
for (i = 0; i <= end; i++)
|
||||
data |= buf[offs + i] << (i*8);
|
||||
|
||||
/* Correctly shift down data */
|
||||
data >>= hpos % 8;
|
||||
data &= (1 << hsize) - 1;
|
||||
if (h->logical_minimum < 0) {
|
||||
/* Need to sign extend */
|
||||
hsize = sizeof data * 8 - hsize;
|
||||
data = (data << hsize) >> hsize;
|
||||
}
|
||||
hsize = 32 - hsize;
|
||||
|
||||
/* Mask and sign extend in one */
|
||||
if ((h->logical_minimum < 0) || (h->logical_maximum < 0))
|
||||
data = (int32_t)((int32_t)data << hsize) >> hsize;
|
||||
else
|
||||
data = (uint32_t)((uint32_t)data << hsize) >> hsize;
|
||||
|
||||
return (data);
|
||||
}
|
||||
|
||||
|
@ -646,8 +646,9 @@ hid_locate(const void *desc, usb_size_t size, uint32_t u, enum hid_kind k,
|
||||
/*------------------------------------------------------------------------*
|
||||
* hid_get_data
|
||||
*------------------------------------------------------------------------*/
|
||||
uint32_t
|
||||
hid_get_data(const uint8_t *buf, usb_size_t len, struct hid_location *loc)
|
||||
static uint32_t
|
||||
hid_get_data_sub(const uint8_t *buf, usb_size_t len, struct hid_location *loc,
|
||||
int is_signed)
|
||||
{
|
||||
uint32_t hpos = loc->pos;
|
||||
uint32_t hsize = loc->size;
|
||||
@ -676,16 +677,31 @@ hid_get_data(const uint8_t *buf, usb_size_t len, struct hid_location *loc)
|
||||
|
||||
/* Correctly shift down data */
|
||||
data = (data >> (hpos % 8));
|
||||
n = 32 - hsize;
|
||||
|
||||
/* Mask and sign extend in one */
|
||||
n = 32 - hsize;
|
||||
data = ((int32_t)data << n) >> n;
|
||||
if (is_signed != 0)
|
||||
data = (int32_t)((int32_t)data << n) >> n;
|
||||
else
|
||||
data = (uint32_t)((uint32_t)data << n) >> n;
|
||||
|
||||
DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n",
|
||||
loc->pos, loc->size, (long)data);
|
||||
return (data);
|
||||
}
|
||||
|
||||
int32_t
|
||||
hid_get_data(const uint8_t *buf, usb_size_t len, struct hid_location *loc)
|
||||
{
|
||||
return (hid_get_data_sub(buf, len, loc, 1));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
hid_get_data_unsigned(const uint8_t *buf, usb_size_t len, struct hid_location *loc)
|
||||
{
|
||||
return (hid_get_data_sub(buf, len, loc, 0));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* hid_is_collection
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -229,7 +229,9 @@ int hid_report_size(const void *buf, usb_size_t len, enum hid_kind k,
|
||||
int hid_locate(const void *desc, usb_size_t size, uint32_t usage,
|
||||
enum hid_kind kind, uint8_t index, struct hid_location *loc,
|
||||
uint32_t *flags, uint8_t *id);
|
||||
uint32_t hid_get_data(const uint8_t *buf, usb_size_t len,
|
||||
int32_t hid_get_data(const uint8_t *buf, usb_size_t len,
|
||||
struct hid_location *loc);
|
||||
uint32_t hid_get_data_unsigned(const uint8_t *buf, usb_size_t len,
|
||||
struct hid_location *loc);
|
||||
int hid_is_collection(const void *desc, usb_size_t size, uint32_t usage);
|
||||
struct usb_hid_descriptor *hid_get_descriptor_from_usb(
|
||||
|
Loading…
Reference in New Issue
Block a user