diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2013-06-13 03:50:35 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-07-31 06:10:31 -0400 |
commit | 3d7d248cf484fe37595698e0ca31a9bcecc85a42 (patch) | |
tree | 33b668ffdf0409e3efda2b6f12a3ffe1e57aa87b /drivers/hid/i2c-hid/i2c-hid.c | |
parent | 3366dd9fa887ebbda4872e9554f853eaeda764be (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>
Diffstat (limited to 'drivers/hid/i2c-hid/i2c-hid.c')
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 44 |
1 files changed, 43 insertions, 1 deletions
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 | ||
938 | static 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 | |||
960 | static const struct of_device_id i2c_hid_of_match[] = { | ||
961 | { .compatible = "hid-over-i2c" }, | ||
962 | {}, | ||
963 | }; | ||
964 | MODULE_DEVICE_TABLE(of, i2c_hid_of_match); | ||
965 | #else | ||
966 | static 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 | |||
936 | static int i2c_hid_probe(struct i2c_client *client, | 973 | static 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, |