aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2013-06-13 03:50:35 -0400
committerJiri Kosina <jkosina@suse.cz>2013-07-31 06:10:31 -0400
commit3d7d248cf484fe37595698e0ca31a9bcecc85a42 (patch)
tree33b668ffdf0409e3efda2b6f12a3ffe1e57aa87b
parent3366dd9fa887ebbda4872e9554f853eaeda764be (diff)
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: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--Documentation/devicetree/bindings/hid/hid-over-i2c.txt28
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c44
-rw-r--r--include/linux/i2c/i2c-hid.h3
3 files changed, 73 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/hid/hid-over-i2c.txt b/Documentation/devicetree/bindings/hid/hid-over-i2c.txt
new file mode 100644
index 000000000000..488edcb264c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/hid/hid-over-i2c.txt
@@ -0,0 +1,28 @@
1* HID over I2C Device-Tree bindings
2
3HID over I2C provides support for various Human Interface Devices over the
4I2C bus. These devices can be for example touchpads, keyboards, touch screens
5or sensors.
6
7The specification has been written by Microsoft and is currently available here:
8http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx
9
10If this binding is used, the kernel module i2c-hid will handle the communication
11with the device and the generic hid core layer will handle the protocol.
12
13Required properties:
14- compatible: must be "hid-over-i2c"
15- reg: i2c slave address
16- hid-descr-addr: HID descriptor address
17- interrupt-parent: the phandle for the interrupt controller
18- interrupts: interrupt line
19
20Example:
21
22 i2c-hid-dev@2c {
23 compatible = "hid-over-i2c";
24 reg = <0x2c>;
25 hid-descr-addr = <0x0020>;
26 interrupt-parent = <&gpx3>;
27 interrupts = <3 2>;
28 };
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 879b0ed701a3..fc9d92cb3f39 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -35,6 +35,7 @@
35#include <linux/hid.h> 35#include <linux/hid.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/acpi.h> 37#include <linux/acpi.h>
38#include <linux/of.h>
38 39
39#include <linux/i2c/i2c-hid.h> 40#include <linux/i2c/i2c-hid.h>
40 41
@@ -933,6 +934,42 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
933} 934}
934#endif 935#endif
935 936
937#ifdef CONFIG_OF
938static int i2c_hid_of_probe(struct i2c_client *client,
939 struct i2c_hid_platform_data *pdata)
940{
941 struct device *dev = &client->dev;
942 u32 val;
943 int ret;
944
945 ret = of_property_read_u32(dev->of_node, "hid-descr-addr", &val);
946 if (ret) {
947 dev_err(&client->dev, "HID register address not provided\n");
948 return -ENODEV;
949 }
950 if (val >> 16) {
951 dev_err(&client->dev, "Bad HID register address: 0x%08x\n",
952 val);
953 return -EINVAL;
954 }
955 pdata->hid_descriptor_address = val;
956
957 return 0;
958}
959
960static const struct of_device_id i2c_hid_of_match[] = {
961 { .compatible = "hid-over-i2c" },
962 {},
963};
964MODULE_DEVICE_TABLE(of, i2c_hid_of_match);
965#else
966static inline int i2c_hid_of_probe(struct i2c_client *client,
967 struct i2c_hid_platform_data *pdata)
968{
969 return -ENODEV;
970}
971#endif
972
936static int i2c_hid_probe(struct i2c_client *client, 973static int i2c_hid_probe(struct i2c_client *client,
937 const struct i2c_device_id *dev_id) 974 const struct i2c_device_id *dev_id)
938{ 975{
@@ -954,7 +991,11 @@ static int i2c_hid_probe(struct i2c_client *client,
954 if (!ihid) 991 if (!ihid)
955 return -ENOMEM; 992 return -ENOMEM;
956 993
957 if (!platform_data) { 994 if (client->dev.of_node) {
995 ret = i2c_hid_of_probe(client, &ihid->pdata);
996 if (ret)
997 goto err;
998 } else if (!platform_data) {
958 ret = i2c_hid_acpi_pdata(client, &ihid->pdata); 999 ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
959 if (ret) { 1000 if (ret) {
960 dev_err(&client->dev, 1001 dev_err(&client->dev,
@@ -1095,6 +1136,7 @@ static struct i2c_driver i2c_hid_driver = {
1095 .owner = THIS_MODULE, 1136 .owner = THIS_MODULE,
1096 .pm = &i2c_hid_pm, 1137 .pm = &i2c_hid_pm,
1097 .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match), 1138 .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
1139 .of_match_table = of_match_ptr(i2c_hid_of_match),
1098 }, 1140 },
1099 1141
1100 .probe = i2c_hid_probe, 1142 .probe = i2c_hid_probe,
diff --git a/include/linux/i2c/i2c-hid.h b/include/linux/i2c/i2c-hid.h
index 60e411d764d4..7aa901d92058 100644
--- a/include/linux/i2c/i2c-hid.h
+++ b/include/linux/i2c/i2c-hid.h
@@ -19,7 +19,8 @@
19 * @hid_descriptor_address: i2c register where the HID descriptor is stored. 19 * @hid_descriptor_address: i2c register where the HID descriptor is stored.
20 * 20 *
21 * Note that it is the responsibility of the platform driver (or the acpi 5.0 21 * Note that it is the responsibility of the platform driver (or the acpi 5.0
22 * driver) to setup the irq related to the gpio in the struct i2c_board_info. 22 * driver, or the flattened device tree) to setup the irq related to the gpio in
23 * the struct i2c_board_info.
23 * The platform driver should also setup the gpio according to the device: 24 * The platform driver should also setup the gpio according to the device:
24 * 25 *
25 * A typical example is the following: 26 * A typical example is the following: