Commit 847120f8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:
 "Two fixes for the HID subsystem:

   - regression fix for i2c-hid power management (Hans de Goede)

   - signed vs unsigned API fix for Wacom driver (Jason Gerecke)"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: wacom: generic: Treat serial number and related fields as unsigned
  HID: i2c-hid: Send power-on command after reset
parents 4dd58158 ff479731
......@@ -447,8 +447,12 @@ static int i2c_hid_hwreset(struct i2c_client *client)
if (ret) {
dev_err(&client->dev, "failed to reset device.\n");
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
goto out_unlock;
}
/* At least some SIS devices need this after reset */
ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
out_unlock:
mutex_unlock(&ihid->reset_lock);
return ret;
......
......@@ -202,6 +202,21 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
}
}
/*
* Convert a signed 32-bit integer to an unsigned n-bit integer. Undoes
* the normally-helpful work of 'hid_snto32' for fields that use signed
* ranges for questionable reasons.
*/
static inline __u32 wacom_s32tou(s32 value, __u8 n)
{
switch (n) {
case 8: return ((__u8)value);
case 16: return ((__u16)value);
case 32: return ((__u32)value);
}
return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value;
}
extern const struct hid_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
......
......@@ -2303,7 +2303,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
case HID_DG_TOOLSERIALNUMBER:
if (value) {
wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
wacom_wac->serial[0] |= (__u32)value;
wacom_wac->serial[0] |= wacom_s32tou(value, field->report_size);
}
return;
case HID_DG_TWIST:
......@@ -2319,15 +2319,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
return;
case WACOM_HID_WD_SERIALHI:
if (value) {
__u32 raw_value = wacom_s32tou(value, field->report_size);
wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
wacom_wac->serial[0] |= ((__u64)value) << 32;
wacom_wac->serial[0] |= ((__u64)raw_value) << 32;
/*
* Non-USI EMR devices may contain additional tool type
* information here. See WACOM_HID_WD_TOOLTYPE case for
* more details.
*/
if (value >> 20 == 1) {
wacom_wac->id[0] |= value & 0xFFFFF;
wacom_wac->id[0] |= raw_value & 0xFFFFF;
}
}
return;
......@@ -2339,7 +2341,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
* bitwise OR so the complete value can be built
* up over time :(
*/
wacom_wac->id[0] |= value;
wacom_wac->id[0] |= wacom_s32tou(value, field->report_size);
return;
case WACOM_HID_WD_OFFSETLEFT:
if (features->offset_left && value != features->offset_left)
......
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