Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09256360 authored by Andrew Duggan's avatar Andrew Duggan Committed by Jiri Kosina
Browse files

HID: rmi: Disable scanning if the device is not a wake source



Some touchpads are configured with firmware which continues to scan for
fingers at a minimal scan rate even after receiving the HID power sleep
command. This allows a finger touching the touchpad to genrate a wake
event. This patch ensures that scanning is disabled if the touchpad is
not a wake source and ensures scanning is enabled on resume.

Signed-off-by: default avatarAndrew Duggan <aduggan@synaptics.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.com>
parent 67db8a80
Loading
Loading
Loading
Loading
+55 −1
Original line number Original line Diff line number Diff line
@@ -33,6 +33,9 @@
#define RMI_READ_DATA_PENDING		1
#define RMI_READ_DATA_PENDING		1
#define RMI_STARTED			2
#define RMI_STARTED			2


#define RMI_SLEEP_NORMAL		0x0
#define RMI_SLEEP_DEEP_SLEEP		0x1

/* device flags */
/* device flags */
#define RMI_DEVICE			BIT(0)
#define RMI_DEVICE			BIT(0)
#define RMI_DEVICE_HAS_PHYS_BUTTONS	BIT(1)
#define RMI_DEVICE_HAS_PHYS_BUTTONS	BIT(1)
@@ -126,6 +129,8 @@ struct rmi_data {


	unsigned long device_flags;
	unsigned long device_flags;
	unsigned long firmware_id;
	unsigned long firmware_id;

	u8 f01_ctrl0;
};
};


#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
@@ -532,9 +537,51 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field,
}
}


#ifdef CONFIG_PM
#ifdef CONFIG_PM
static int rmi_set_sleep_mode(struct hid_device *hdev, int sleep_mode)
{
	struct rmi_data *data = hid_get_drvdata(hdev);
	int ret;
	u8 f01_ctrl0;

	f01_ctrl0 = (data->f01_ctrl0 & ~0x3) | sleep_mode;

	ret = rmi_write(hdev, data->f01.control_base_addr,
			&f01_ctrl0);
	if (ret) {
		hid_err(hdev, "can not write sleep mode\n");
		return ret;
	}

	return 0;
}

static int rmi_suspend(struct hid_device *hdev, pm_message_t message)
{
	if (!device_may_wakeup(hdev->dev.parent))
		return rmi_set_sleep_mode(hdev, RMI_SLEEP_DEEP_SLEEP);

	return 0;
}

static int rmi_post_reset(struct hid_device *hdev)
static int rmi_post_reset(struct hid_device *hdev)
{
{
	return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS);
	int ret;

	ret = rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS);
	if (ret) {
		hid_err(hdev, "can not set rmi mode\n");
		return ret;
	}

	if (!device_may_wakeup(hdev->dev.parent)) {
		ret = rmi_set_sleep_mode(hdev, RMI_SLEEP_NORMAL);
		if (ret) {
			hid_err(hdev, "can not write sleep mode\n");
			return ret;
		}
	}

	return ret;
}
}


static int rmi_post_resume(struct hid_device *hdev)
static int rmi_post_resume(struct hid_device *hdev)
@@ -732,6 +779,12 @@ static int rmi_populate_f01(struct hid_device *hdev)
		data->firmware_id += info[2] * 65536;
		data->firmware_id += info[2] * 65536;
	}
	}


	ret = rmi_read(hdev, data->f01.control_base_addr, &data->f01_ctrl0);

	if (ret) {
		hid_err(hdev, "can not read f01 ctrl0\n");
		return ret;
	}
	return 0;
	return 0;
}
}


@@ -1273,6 +1326,7 @@ static struct hid_driver rmi_driver = {
	.input_mapping		= rmi_input_mapping,
	.input_mapping		= rmi_input_mapping,
	.input_configured	= rmi_input_configured,
	.input_configured	= rmi_input_configured,
#ifdef CONFIG_PM
#ifdef CONFIG_PM
	.suspend		= rmi_suspend,
	.resume			= rmi_post_resume,
	.resume			= rmi_post_resume,
	.reset_resume		= rmi_post_reset,
	.reset_resume		= rmi_post_reset,
#endif
#endif