|
@@ -270,7 +270,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
|
|
|
* Read data value from item.
|
|
|
*/
|
|
|
|
|
|
-static __inline__ __u32 item_udata(struct hid_item *item)
|
|
|
+static u32 item_udata(struct hid_item *item)
|
|
|
{
|
|
|
switch (item->size) {
|
|
|
case 1: return item->data.u8;
|
|
@@ -280,7 +280,7 @@ static __inline__ __u32 item_udata(struct hid_item *item)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static __inline__ __s32 item_sdata(struct hid_item *item)
|
|
|
+static s32 item_sdata(struct hid_item *item)
|
|
|
{
|
|
|
switch (item->size) {
|
|
|
case 1: return item->data.s8;
|
|
@@ -727,7 +727,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
|
|
|
* done by hand.
|
|
|
*/
|
|
|
|
|
|
-static __inline__ __s32 snto32(__u32 value, unsigned n)
|
|
|
+static s32 snto32(__u32 value, unsigned n)
|
|
|
{
|
|
|
switch (n) {
|
|
|
case 8: return ((__s8)value);
|
|
@@ -741,9 +741,9 @@ static __inline__ __s32 snto32(__u32 value, unsigned n)
|
|
|
* Convert a signed 32-bit integer to a signed n-bit integer.
|
|
|
*/
|
|
|
|
|
|
-static __inline__ __u32 s32ton(__s32 value, unsigned n)
|
|
|
+static u32 s32ton(__s32 value, unsigned n)
|
|
|
{
|
|
|
- __s32 a = value >> (n - 1);
|
|
|
+ s32 a = value >> (n - 1);
|
|
|
if (a && a != -1)
|
|
|
return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
|
|
|
return value & ((1 << n) - 1);
|
|
@@ -751,30 +751,55 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n)
|
|
|
|
|
|
/*
|
|
|
* Extract/implement a data field from/to a little endian report (bit array).
|
|
|
+ *
|
|
|
+ * Code sort-of follows HID spec:
|
|
|
+ * http://www.usb.org/developers/devclass_docs/HID1_11.pdf
|
|
|
+ *
|
|
|
+ * While the USB HID spec allows unlimited length bit fields in "report
|
|
|
+ * descriptors", most devices never use more than 16 bits.
|
|
|
+ * One model of UPS is claimed to report "LINEV" as a 32-bit field.
|
|
|
+ * Search linux-kernel and linux-usb-devel archives for "hid-core extract".
|
|
|
*/
|
|
|
|
|
|
static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
|
|
|
{
|
|
|
- u32 x;
|
|
|
+ u64 x;
|
|
|
+
|
|
|
+ WARN_ON(n > 32);
|
|
|
|
|
|
report += offset >> 3; /* adjust byte index */
|
|
|
- offset &= 8 - 1;
|
|
|
- x = get_unaligned((u32 *) report);
|
|
|
- x = le32_to_cpu(x);
|
|
|
- x = (x >> offset) & ((1 << n) - 1);
|
|
|
- return x;
|
|
|
+ offset &= 7; /* now only need bit offset into one byte */
|
|
|
+ x = get_unaligned((u64 *) report);
|
|
|
+ x = le64_to_cpu(x);
|
|
|
+ x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */
|
|
|
+ return (u32) x;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * "implement" : set bits in a little endian bit stream.
|
|
|
+ * Same concepts as "extract" (see comments above).
|
|
|
+ * The data mangled in the bit stream remains in little endian
|
|
|
+ * order the whole time. It make more sense to talk about
|
|
|
+ * endianness of register values by considering a register
|
|
|
+ * a "cached" copy of the little endiad bit stream.
|
|
|
+ */
|
|
|
static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
|
|
|
{
|
|
|
- u32 x;
|
|
|
+ u64 x;
|
|
|
+ u64 m = (1ULL << n) - 1;
|
|
|
+
|
|
|
+ WARN_ON(n > 32);
|
|
|
+
|
|
|
+ WARN_ON(value > m);
|
|
|
+ value &= m;
|
|
|
|
|
|
report += offset >> 3;
|
|
|
- offset &= 8 - 1;
|
|
|
- x = get_unaligned((u32 *)report);
|
|
|
- x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset));
|
|
|
- x |= cpu_to_le32(value << offset);
|
|
|
- put_unaligned(x,(u32 *)report);
|
|
|
+ offset &= 7;
|
|
|
+
|
|
|
+ x = get_unaligned((u64 *)report);
|
|
|
+ x &= cpu_to_le64(~(m << offset));
|
|
|
+ x |= cpu_to_le64(((u64) value) << offset);
|
|
|
+ put_unaligned(x, (u64 *) report);
|
|
|
}
|
|
|
|
|
|
/*
|