Commit 847120f8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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;
+15 −0
Original line number Diff line number Diff line
@@ -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);
+6 −4
Original line number Diff line number Diff line
@@ -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)