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

Commit 3d7d248c authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina
Browse files

HID: i2c-hid: add DT bindings



Add device tree based support for HID over I2C devices.

Tested on an Odroid-X board with a Synaptics touchpad.

Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 3366dd9f
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
* HID over I2C Device-Tree bindings

HID over I2C provides support for various Human Interface Devices over the
I2C bus. These devices can be for example touchpads, keyboards, touch screens
or sensors.

The specification has been written by Microsoft and is currently available here:
http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx

If this binding is used, the kernel module i2c-hid will handle the communication
with the device and the generic hid core layer will handle the protocol.

Required properties:
- compatible: must be "hid-over-i2c"
- reg: i2c slave address
- hid-descr-addr: HID descriptor address
- interrupt-parent: the phandle for the interrupt controller
- interrupts: interrupt line

Example:

	i2c-hid-dev@2c {
		compatible = "hid-over-i2c";
		reg = <0x2c>;
		hid-descr-addr = <0x0020>;
		interrupt-parent = <&gpx3>;
		interrupts = <3 2>;
	};
+43 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <linux/of.h>

#include <linux/i2c/i2c-hid.h>

@@ -933,6 +934,42 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
}
#endif

#ifdef CONFIG_OF
static int i2c_hid_of_probe(struct i2c_client *client,
		struct i2c_hid_platform_data *pdata)
{
	struct device *dev = &client->dev;
	u32 val;
	int ret;

	ret = of_property_read_u32(dev->of_node, "hid-descr-addr", &val);
	if (ret) {
		dev_err(&client->dev, "HID register address not provided\n");
		return -ENODEV;
	}
	if (val >> 16) {
		dev_err(&client->dev, "Bad HID register address: 0x%08x\n",
			val);
		return -EINVAL;
	}
	pdata->hid_descriptor_address = val;

	return 0;
}

static const struct of_device_id i2c_hid_of_match[] = {
	{ .compatible = "hid-over-i2c" },
	{},
};
MODULE_DEVICE_TABLE(of, i2c_hid_of_match);
#else
static inline int i2c_hid_of_probe(struct i2c_client *client,
		struct i2c_hid_platform_data *pdata)
{
	return -ENODEV;
}
#endif

static int i2c_hid_probe(struct i2c_client *client,
			 const struct i2c_device_id *dev_id)
{
@@ -954,7 +991,11 @@ static int i2c_hid_probe(struct i2c_client *client,
	if (!ihid)
		return -ENOMEM;

	if (!platform_data) {
	if (client->dev.of_node) {
		ret = i2c_hid_of_probe(client, &ihid->pdata);
		if (ret)
			goto err;
	} else if (!platform_data) {
		ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
		if (ret) {
			dev_err(&client->dev,
@@ -1095,6 +1136,7 @@ static struct i2c_driver i2c_hid_driver = {
		.owner	= THIS_MODULE,
		.pm	= &i2c_hid_pm,
		.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
		.of_match_table = of_match_ptr(i2c_hid_of_match),
	},

	.probe		= i2c_hid_probe,
+2 −1
Original line number Diff line number Diff line
@@ -19,7 +19,8 @@
 * @hid_descriptor_address: i2c register where the HID descriptor is stored.
 *
 * Note that it is the responsibility of the platform driver (or the acpi 5.0
 * driver) to setup the irq related to the gpio in the struct i2c_board_info.
 * driver, or the flattened device tree) to setup the irq related to the gpio in
 * the struct i2c_board_info.
 * The platform driver should also setup the gpio according to the device:
 *
 * A typical example is the following: