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

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
* 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>;
};
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/hid.h> #include <linux/hid.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/of.h>
#include <linux/i2c/i2c-hid.h> #include <linux/i2c/i2c-hid.h>
...@@ -933,6 +934,42 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client, ...@@ -933,6 +934,42 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
} }
#endif #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, static int i2c_hid_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id) const struct i2c_device_id *dev_id)
{ {
...@@ -954,7 +991,11 @@ static int i2c_hid_probe(struct i2c_client *client, ...@@ -954,7 +991,11 @@ static int i2c_hid_probe(struct i2c_client *client,
if (!ihid) if (!ihid)
return -ENOMEM; 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); ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
if (ret) { if (ret) {
dev_err(&client->dev, dev_err(&client->dev,
...@@ -1095,6 +1136,7 @@ static struct i2c_driver i2c_hid_driver = { ...@@ -1095,6 +1136,7 @@ static struct i2c_driver i2c_hid_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &i2c_hid_pm, .pm = &i2c_hid_pm,
.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match), .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
.of_match_table = of_match_ptr(i2c_hid_of_match),
}, },
.probe = i2c_hid_probe, .probe = i2c_hid_probe,
......
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
* @hid_descriptor_address: i2c register where the HID descriptor is stored. * @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 * 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: * The platform driver should also setup the gpio according to the device:
* *
* A typical example is the following: * A typical example is the following:
......
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