aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-sensor-hub.c8
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c87
-rw-r--r--drivers/hid/uhid.c95
4 files changed, 176 insertions, 16 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index eb2ee11b6412..fe3a59e2a5ba 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -729,7 +729,7 @@ static int hid_scan_report(struct hid_device *hid)
729 item.type == HID_ITEM_TYPE_MAIN && 729 item.type == HID_ITEM_TYPE_MAIN &&
730 item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && 730 item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION &&
731 (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && 731 (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL &&
732 hid->bus == BUS_USB) 732 (hid->bus == BUS_USB || hid->bus == BUS_I2C))
733 hid->group = HID_GROUP_SENSOR_HUB; 733 hid->group = HID_GROUP_SENSOR_HUB;
734 } 734 }
735 735
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 0bc58bd8d4f5..7d96db367477 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -605,16 +605,12 @@ static void sensor_hub_remove(struct hid_device *hdev)
605} 605}
606 606
607static const struct hid_device_id sensor_hub_devices[] = { 607static const struct hid_device_id sensor_hub_devices[] = {
608 { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, 608 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
609 HID_ANY_ID) },
609 { } 610 { }
610}; 611};
611MODULE_DEVICE_TABLE(hid, sensor_hub_devices); 612MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
612 613
613static const struct hid_usage_id sensor_hub_grabbed_usages[] = {
614 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
615 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 }
616};
617
618static struct hid_driver sensor_hub_driver = { 614static struct hid_driver sensor_hub_driver = {
619 .name = "hid-sensor-hub", 615 .name = "hid-sensor-hub",
620 .id_table = sensor_hub_devices, 616 .id_table = sensor_hub_devices,
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index e766b5614ef5..ec7930217a6d 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -34,6 +34,7 @@
34#include <linux/kernel.h> 34#include <linux/kernel.h>
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 38
38#include <linux/i2c/i2c-hid.h> 39#include <linux/i2c/i2c-hid.h>
39 40
@@ -139,6 +140,8 @@ struct i2c_hid {
139 unsigned long flags; /* device flags */ 140 unsigned long flags; /* device flags */
140 141
141 wait_queue_head_t wait; /* For waiting the interrupt */ 142 wait_queue_head_t wait; /* For waiting the interrupt */
143
144 struct i2c_hid_platform_data pdata;
142}; 145};
143 146
144static int __i2c_hid_command(struct i2c_client *client, 147static int __i2c_hid_command(struct i2c_client *client,
@@ -821,6 +824,70 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
821 return 0; 824 return 0;
822} 825}
823 826
827#ifdef CONFIG_ACPI
828static int i2c_hid_acpi_pdata(struct i2c_client *client,
829 struct i2c_hid_platform_data *pdata)
830{
831 static u8 i2c_hid_guid[] = {
832 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
833 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
834 };
835 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
836 union acpi_object params[4], *obj;
837 struct acpi_object_list input;
838 struct acpi_device *adev;
839 acpi_handle handle;
840
841 handle = ACPI_HANDLE(&client->dev);
842 if (!handle || acpi_bus_get_device(handle, &adev))
843 return -ENODEV;
844
845 input.count = ARRAY_SIZE(params);
846 input.pointer = params;
847
848 params[0].type = ACPI_TYPE_BUFFER;
849 params[0].buffer.length = sizeof(i2c_hid_guid);
850 params[0].buffer.pointer = i2c_hid_guid;
851 params[1].type = ACPI_TYPE_INTEGER;
852 params[1].integer.value = 1;
853 params[2].type = ACPI_TYPE_INTEGER;
854 params[2].integer.value = 1; /* HID function */
855 params[3].type = ACPI_TYPE_INTEGER;
856 params[3].integer.value = 0;
857
858 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) {
859 dev_err(&client->dev, "device _DSM execution failed\n");
860 return -ENODEV;
861 }
862
863 obj = (union acpi_object *)buf.pointer;
864 if (obj->type != ACPI_TYPE_INTEGER) {
865 dev_err(&client->dev, "device _DSM returned invalid type: %d\n",
866 obj->type);
867 kfree(buf.pointer);
868 return -EINVAL;
869 }
870
871 pdata->hid_descriptor_address = obj->integer.value;
872
873 kfree(buf.pointer);
874 return 0;
875}
876
877static const struct acpi_device_id i2c_hid_acpi_match[] = {
878 {"ACPI0C50", 0 },
879 {"PNP0C50", 0 },
880 { },
881};
882MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
883#else
884static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
885 struct i2c_hid_platform_data *pdata)
886{
887 return -ENODEV;
888}
889#endif
890
824static int i2c_hid_probe(struct i2c_client *client, 891static int i2c_hid_probe(struct i2c_client *client,
825 const struct i2c_device_id *dev_id) 892 const struct i2c_device_id *dev_id)
826{ 893{
@@ -832,11 +899,6 @@ static int i2c_hid_probe(struct i2c_client *client,
832 899
833 dbg_hid("HID probe called for i2c 0x%02x\n", client->addr); 900 dbg_hid("HID probe called for i2c 0x%02x\n", client->addr);
834 901
835 if (!platform_data) {
836 dev_err(&client->dev, "HID register address not provided\n");
837 return -EINVAL;
838 }
839
840 if (!client->irq) { 902 if (!client->irq) {
841 dev_err(&client->dev, 903 dev_err(&client->dev,
842 "HID over i2c has not been provided an Int IRQ\n"); 904 "HID over i2c has not been provided an Int IRQ\n");
@@ -847,11 +909,22 @@ static int i2c_hid_probe(struct i2c_client *client,
847 if (!ihid) 909 if (!ihid)
848 return -ENOMEM; 910 return -ENOMEM;
849 911
912 if (!platform_data) {
913 ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
914 if (ret) {
915 dev_err(&client->dev,
916 "HID register address not provided\n");
917 goto err;
918 }
919 } else {
920 ihid->pdata = *platform_data;
921 }
922
850 i2c_set_clientdata(client, ihid); 923 i2c_set_clientdata(client, ihid);
851 924
852 ihid->client = client; 925 ihid->client = client;
853 926
854 hidRegister = platform_data->hid_descriptor_address; 927 hidRegister = ihid->pdata.hid_descriptor_address;
855 ihid->wHIDDescRegister = cpu_to_le16(hidRegister); 928 ihid->wHIDDescRegister = cpu_to_le16(hidRegister);
856 929
857 init_waitqueue_head(&ihid->wait); 930 init_waitqueue_head(&ihid->wait);
@@ -884,6 +957,7 @@ static int i2c_hid_probe(struct i2c_client *client,
884 hid->hid_get_raw_report = i2c_hid_get_raw_report; 957 hid->hid_get_raw_report = i2c_hid_get_raw_report;
885 hid->hid_output_raw_report = i2c_hid_output_raw_report; 958 hid->hid_output_raw_report = i2c_hid_output_raw_report;
886 hid->dev.parent = &client->dev; 959 hid->dev.parent = &client->dev;
960 ACPI_HANDLE_SET(&hid->dev, ACPI_HANDLE(&client->dev));
887 hid->bus = BUS_I2C; 961 hid->bus = BUS_I2C;
888 hid->version = le16_to_cpu(ihid->hdesc.bcdVersion); 962 hid->version = le16_to_cpu(ihid->hdesc.bcdVersion);
889 hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); 963 hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID);
@@ -975,6 +1049,7 @@ static struct i2c_driver i2c_hid_driver = {
975 .name = "i2c_hid", 1049 .name = "i2c_hid",
976 .owner = THIS_MODULE, 1050 .owner = THIS_MODULE,
977 .pm = &i2c_hid_pm, 1051 .pm = &i2c_hid_pm,
1052 .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
978 }, 1053 },
979 1054
980 .probe = i2c_hid_probe, 1055 .probe = i2c_hid_probe,
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 714cd8cc9579..fc307e0422af 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/atomic.h> 13#include <linux/atomic.h>
14#include <linux/compat.h>
14#include <linux/device.h> 15#include <linux/device.h>
15#include <linux/fs.h> 16#include <linux/fs.h>
16#include <linux/hid.h> 17#include <linux/hid.h>
@@ -276,6 +277,94 @@ static struct hid_ll_driver uhid_hid_driver = {
276 .parse = uhid_hid_parse, 277 .parse = uhid_hid_parse,
277}; 278};
278 279
280#ifdef CONFIG_COMPAT
281
282/* Apparently we haven't stepped on these rakes enough times yet. */
283struct uhid_create_req_compat {
284 __u8 name[128];
285 __u8 phys[64];
286 __u8 uniq[64];
287
288 compat_uptr_t rd_data;
289 __u16 rd_size;
290
291 __u16 bus;
292 __u32 vendor;
293 __u32 product;
294 __u32 version;
295 __u32 country;
296} __attribute__((__packed__));
297
298static int uhid_event_from_user(const char __user *buffer, size_t len,
299 struct uhid_event *event)
300{
301 if (is_compat_task()) {
302 u32 type;
303
304 if (get_user(type, buffer))
305 return -EFAULT;
306
307 if (type == UHID_CREATE) {
308 /*
309 * This is our messed up request with compat pointer.
310 * It is largish (more than 256 bytes) so we better
311 * allocate it from the heap.
312 */
313 struct uhid_create_req_compat *compat;
314
315 compat = kmalloc(sizeof(*compat), GFP_KERNEL);
316 if (!compat)
317 return -ENOMEM;
318
319 buffer += sizeof(type);
320 len -= sizeof(type);
321 if (copy_from_user(compat, buffer,
322 min(len, sizeof(*compat)))) {
323 kfree(compat);
324 return -EFAULT;
325 }
326
327 /* Shuffle the data over to proper structure */
328 event->type = type;
329
330 memcpy(event->u.create.name, compat->name,
331 sizeof(compat->name));
332 memcpy(event->u.create.phys, compat->phys,
333 sizeof(compat->phys));
334 memcpy(event->u.create.uniq, compat->uniq,
335 sizeof(compat->uniq));
336
337 event->u.create.rd_data = compat_ptr(compat->rd_data);
338 event->u.create.rd_size = compat->rd_size;
339
340 event->u.create.bus = compat->bus;
341 event->u.create.vendor = compat->vendor;
342 event->u.create.product = compat->product;
343 event->u.create.version = compat->version;
344 event->u.create.country = compat->country;
345
346 kfree(compat);
347 return 0;
348 }
349 /* All others can be copied directly */
350 }
351
352 if (copy_from_user(event, buffer, min(len, sizeof(*event))))
353 return -EFAULT;
354
355 return 0;
356}
357#else
358static int uhid_event_from_user(const char __user *buffer, size_t len,
359 struct uhid_event *event)
360{
361 if (copy_from_user(event, buffer, min(len, sizeof(*event))))
362 return -EFAULT;
363
364 return 0;
365}
366#endif
367
279static int uhid_dev_create(struct uhid_device *uhid, 368static int uhid_dev_create(struct uhid_device *uhid,
280 const struct uhid_event *ev) 369 const struct uhid_event *ev)
281{ 370{
@@ -498,10 +587,10 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
498 587
499 memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); 588 memset(&uhid->input_buf, 0, sizeof(uhid->input_buf));
500 len = min(count, sizeof(uhid->input_buf)); 589 len = min(count, sizeof(uhid->input_buf));
501 if (copy_from_user(&uhid->input_buf, buffer, len)) { 590
502 ret = -EFAULT; 591 ret = uhid_event_from_user(buffer, len, &uhid->input_buf);
592 if (ret)
503 goto unlock; 593 goto unlock;
504 }
505 594
506 switch (uhid->input_buf.type) { 595 switch (uhid->input_buf.type) {
507 case UHID_CREATE: 596 case UHID_CREATE: