source: src/linux/universal/linux-4.9/drivers/hid/hid-sensor-hub.c @ 31859

Last change on this file since 31859 was 31859, checked in by brainslayer, 2 months ago

kernel update

File size: 24.6 KB
Line 
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19
20#include <linux/device.h>
21#include <linux/hid.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/mfd/core.h>
25#include <linux/list.h>
26#include <linux/hid-sensor-ids.h>
27#include <linux/hid-sensor-hub.h>
28#include "hid-ids.h"
29
30#define HID_SENSOR_HUB_ENUM_QUIRK       0x01
31
32/**
33 * struct sensor_hub_data - Hold a instance data for a HID hub device
34 * @hsdev:              Stored hid instance for current hub device.
35 * @mutex:              Mutex to serialize synchronous request.
36 * @lock:               Spin lock to protect pending request structure.
37 * @dyn_callback_list:  Holds callback function
38 * @dyn_callback_lock:  spin lock to protect callback list
39 * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance.
40 * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached).
41 * @ref_cnt:            Number of MFD clients have opened this device
42 */
43struct sensor_hub_data {
44        struct mutex mutex;
45        spinlock_t lock;
46        struct list_head dyn_callback_list;
47        spinlock_t dyn_callback_lock;
48        struct mfd_cell *hid_sensor_hub_client_devs;
49        int hid_sensor_client_cnt;
50        unsigned long quirks;
51        int ref_cnt;
52};
53
54/**
55 * struct hid_sensor_hub_callbacks_list - Stores callback list
56 * @list:               list head.
57 * @usage_id:           usage id for a physical device.
58 * @usage_callback:     Stores registered callback functions.
59 * @priv:               Private data for a physical device.
60 */
61struct hid_sensor_hub_callbacks_list {
62        struct list_head list;
63        u32 usage_id;
64        struct hid_sensor_hub_device *hsdev;
65        struct hid_sensor_hub_callbacks *usage_callback;
66        void *priv;
67};
68
69static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
70                                                int dir)
71{
72        struct hid_report *report;
73
74        list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) {
75                if (report->id == id)
76                        return report;
77        }
78        hid_warn(hdev, "No report with id 0x%x found\n", id);
79
80        return NULL;
81}
82
83static int sensor_hub_get_physical_device_count(struct hid_device *hdev)
84{
85        int i;
86        int count = 0;
87
88        for (i = 0; i < hdev->maxcollection; ++i) {
89                struct hid_collection *collection = &hdev->collection[i];
90                if (collection->type == HID_COLLECTION_PHYSICAL ||
91                    collection->type == HID_COLLECTION_APPLICATION)
92                        ++count;
93        }
94
95        return count;
96}
97
98static void sensor_hub_fill_attr_info(
99                struct hid_sensor_hub_attribute_info *info,
100                s32 index, s32 report_id, struct hid_field *field)
101{
102        info->index = index;
103        info->report_id = report_id;
104        info->units = field->unit;
105        info->unit_expo = field->unit_exponent;
106        info->size = (field->report_size * field->report_count)/8;
107        info->logical_minimum = field->logical_minimum;
108        info->logical_maximum = field->logical_maximum;
109}
110
111static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(
112                                        struct hid_device *hdev,
113                                        u32 usage_id,
114                                        int collection_index,
115                                        struct hid_sensor_hub_device **hsdev,
116                                        void **priv)
117{
118        struct hid_sensor_hub_callbacks_list *callback;
119        struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
120        unsigned long flags;
121
122        spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
123        list_for_each_entry(callback, &pdata->dyn_callback_list, list)
124                if ((callback->usage_id == usage_id ||
125                     callback->usage_id == HID_USAGE_SENSOR_COLLECTION) &&
126                        (collection_index >=
127                                callback->hsdev->start_collection_index) &&
128                        (collection_index <
129                                callback->hsdev->end_collection_index)) {
130                        *priv = callback->priv;
131                        *hsdev = callback->hsdev;
132                        spin_unlock_irqrestore(&pdata->dyn_callback_lock,
133                                               flags);
134                        return callback->usage_callback;
135                }
136        spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
137
138        return NULL;
139}
140
141int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
142                        u32 usage_id,
143                        struct hid_sensor_hub_callbacks *usage_callback)
144{
145        struct hid_sensor_hub_callbacks_list *callback;
146        struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
147        unsigned long flags;
148
149        spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
150        list_for_each_entry(callback, &pdata->dyn_callback_list, list)
151                if (callback->usage_id == usage_id &&
152                                                callback->hsdev == hsdev) {
153                        spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
154                        return -EINVAL;
155                }
156        callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
157        if (!callback) {
158                spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
159                return -ENOMEM;
160        }
161        callback->hsdev = hsdev;
162        callback->usage_callback = usage_callback;
163        callback->usage_id = usage_id;
164        callback->priv = NULL;
165        /*
166         * If there is a handler registered for the collection type, then
167         * it will handle all reports for sensors in this collection. If
168         * there is also an individual sensor handler registration, then
169         * we want to make sure that the reports are directed to collection
170         * handler, as this may be a fusion sensor. So add collection handlers
171         * to the beginning of the list, so that they are matched first.
172         */
173        if (usage_id == HID_USAGE_SENSOR_COLLECTION)
174                list_add(&callback->list, &pdata->dyn_callback_list);
175        else
176                list_add_tail(&callback->list, &pdata->dyn_callback_list);
177        spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
178
179        return 0;
180}
181EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
182
183int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
184                                u32 usage_id)
185{
186        struct hid_sensor_hub_callbacks_list *callback;
187        struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
188        unsigned long flags;
189
190        spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
191        list_for_each_entry(callback, &pdata->dyn_callback_list, list)
192                if (callback->usage_id == usage_id &&
193                                                callback->hsdev == hsdev) {
194                        list_del(&callback->list);
195                        kfree(callback);
196                        break;
197                }
198        spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
199
200        return 0;
201}
202EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);
203
204int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
205                           u32 field_index, int buffer_size, void *buffer)
206{
207        struct hid_report *report;
208        struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
209        __s32 *buf32 = buffer;
210        int i = 0;
211        int remaining_bytes;
212        __s32 value;
213        int ret = 0;
214
215        mutex_lock(&data->mutex);
216        report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
217        if (!report || (field_index >= report->maxfield)) {
218                ret = -EINVAL;
219                goto done_proc;
220        }
221
222        remaining_bytes = buffer_size % sizeof(__s32);
223        buffer_size = buffer_size / sizeof(__s32);
224        if (buffer_size) {
225                for (i = 0; i < buffer_size; ++i) {
226                        hid_set_field(report->field[field_index], i,
227                                      (__force __s32)cpu_to_le32(*buf32));
228                        ++buf32;
229                }
230        }
231        if (remaining_bytes) {
232                value = 0;
233                memcpy(&value, (u8 *)buf32, remaining_bytes);
234                hid_set_field(report->field[field_index], i,
235                              (__force __s32)cpu_to_le32(value));
236        }
237        hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT);
238        hid_hw_wait(hsdev->hdev);
239
240done_proc:
241        mutex_unlock(&data->mutex);
242
243        return ret;
244}
245EXPORT_SYMBOL_GPL(sensor_hub_set_feature);
246
247int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
248                           u32 field_index, int buffer_size, void *buffer)
249{
250        struct hid_report *report;
251        struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
252        int report_size;
253        int ret = 0;
254        u8 *val_ptr;
255        int buffer_index = 0;
256        int i;
257
258        memset(buffer, 0, buffer_size);
259
260        mutex_lock(&data->mutex);
261        report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
262        if (!report || (field_index >= report->maxfield) ||
263            report->field[field_index]->report_count < 1) {
264                ret = -EINVAL;
265                goto done_proc;
266        }
267        hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
268        hid_hw_wait(hsdev->hdev);
269
270        /* calculate number of bytes required to read this field */
271        report_size = DIV_ROUND_UP(report->field[field_index]->report_size,
272                                   8) *
273                                   report->field[field_index]->report_count;
274        if (!report_size) {
275                ret = -EINVAL;
276                goto done_proc;
277        }
278        ret = min(report_size, buffer_size);
279
280        val_ptr = (u8 *)report->field[field_index]->value;
281        for (i = 0; i < report->field[field_index]->report_count; ++i) {
282                if (buffer_index >= ret)
283                        break;
284
285                memcpy(&((u8 *)buffer)[buffer_index], val_ptr,
286                       report->field[field_index]->report_size / 8);
287                val_ptr += sizeof(__s32);
288                buffer_index += (report->field[field_index]->report_size / 8);
289        }
290
291done_proc:
292        mutex_unlock(&data->mutex);
293
294        return ret;
295}
296EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
297
298
299int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
300                                        u32 usage_id,
301                                        u32 attr_usage_id, u32 report_id,
302                                        enum sensor_hub_read_flags flag)
303{
304        struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
305        unsigned long flags;
306        struct hid_report *report;
307        int ret_val = 0;
308
309        report = sensor_hub_report(report_id, hsdev->hdev,
310                                   HID_INPUT_REPORT);
311        if (!report)
312                return -EINVAL;
313
314        mutex_lock(hsdev->mutex_ptr);
315        if (flag == SENSOR_HUB_SYNC) {
316                memset(&hsdev->pending, 0, sizeof(hsdev->pending));
317                init_completion(&hsdev->pending.ready);
318                hsdev->pending.usage_id = usage_id;
319                hsdev->pending.attr_usage_id = attr_usage_id;
320                hsdev->pending.raw_size = 0;
321
322                spin_lock_irqsave(&data->lock, flags);
323                hsdev->pending.status = true;
324                spin_unlock_irqrestore(&data->lock, flags);
325        }
326        mutex_lock(&data->mutex);
327        hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
328        mutex_unlock(&data->mutex);
329        if (flag == SENSOR_HUB_SYNC) {
330                wait_for_completion_interruptible_timeout(
331                                                &hsdev->pending.ready, HZ*5);
332                switch (hsdev->pending.raw_size) {
333                case 1:
334                        ret_val = *(u8 *)hsdev->pending.raw_data;
335                        break;
336                case 2:
337                        ret_val = *(u16 *)hsdev->pending.raw_data;
338                        break;
339                case 4:
340                        ret_val = *(u32 *)hsdev->pending.raw_data;
341                        break;
342                default:
343                        ret_val = 0;
344                }
345                kfree(hsdev->pending.raw_data);
346                hsdev->pending.status = false;
347        }
348        mutex_unlock(hsdev->mutex_ptr);
349
350        return ret_val;
351}
352EXPORT_SYMBOL_GPL(sensor_hub_input_attr_get_raw_value);
353
354int hid_sensor_get_usage_index(struct hid_sensor_hub_device *hsdev,
355                                u32 report_id, int field_index, u32 usage_id)
356{
357        struct hid_report *report;
358        struct hid_field *field;
359        int i;
360
361        report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
362        if (!report || (field_index >= report->maxfield))
363                goto done_proc;
364
365        field = report->field[field_index];
366        for (i = 0; i < field->maxusage; ++i) {
367                if (field->usage[i].hid == usage_id)
368                        return field->usage[i].usage_index;
369        }
370
371done_proc:
372        return -EINVAL;
373}
374EXPORT_SYMBOL_GPL(hid_sensor_get_usage_index);
375
376int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
377                                u8 type,
378                                u32 usage_id,
379                                u32 attr_usage_id,
380                                struct hid_sensor_hub_attribute_info *info)
381{
382        int ret = -1;
383        int i;
384        struct hid_report *report;
385        struct hid_field *field;
386        struct hid_report_enum *report_enum;
387        struct hid_device *hdev = hsdev->hdev;
388
389        /* Initialize with defaults */
390        info->usage_id = usage_id;
391        info->attrib_id = attr_usage_id;
392        info->report_id = -1;
393        info->index = -1;
394        info->units = -1;
395        info->unit_expo = -1;
396
397        report_enum = &hdev->report_enum[type];
398        list_for_each_entry(report, &report_enum->report_list, list) {
399                for (i = 0; i < report->maxfield; ++i) {
400                        field = report->field[i];
401                        if (field->maxusage) {
402                                if (field->physical == usage_id &&
403                                        (field->logical == attr_usage_id ||
404                                        field->usage[0].hid ==
405                                                        attr_usage_id) &&
406                                        (field->usage[0].collection_index >=
407                                        hsdev->start_collection_index) &&
408                                        (field->usage[0].collection_index <
409                                        hsdev->end_collection_index)) {
410
411                                        sensor_hub_fill_attr_info(info, i,
412                                                                report->id,
413                                                                field);
414                                        ret = 0;
415                                        break;
416                                }
417                        }
418                }
419
420        }
421
422        return ret;
423}
424EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
425
426#ifdef CONFIG_PM
427static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
428{
429        struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
430        struct hid_sensor_hub_callbacks_list *callback;
431        unsigned long flags;
432
433        hid_dbg(hdev, " sensor_hub_suspend\n");
434        spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
435        list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
436                if (callback->usage_callback->suspend)
437                        callback->usage_callback->suspend(
438                                        callback->hsdev, callback->priv);
439        }
440        spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
441
442        return 0;
443}
444
445static int sensor_hub_resume(struct hid_device *hdev)
446{
447        struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
448        struct hid_sensor_hub_callbacks_list *callback;
449        unsigned long flags;
450
451        hid_dbg(hdev, " sensor_hub_resume\n");
452        spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
453        list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
454                if (callback->usage_callback->resume)
455                        callback->usage_callback->resume(
456                                        callback->hsdev, callback->priv);
457        }
458        spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
459
460        return 0;
461}
462
463static int sensor_hub_reset_resume(struct hid_device *hdev)
464{
465        return 0;
466}
467#endif
468
469/*
470 * Handle raw report as sent by device
471 */
472static int sensor_hub_raw_event(struct hid_device *hdev,
473                struct hid_report *report, u8 *raw_data, int size)
474{
475        int i;
476        u8 *ptr;
477        int sz;
478        struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
479        unsigned long flags;
480        struct hid_sensor_hub_callbacks *callback = NULL;
481        struct hid_collection *collection = NULL;
482        void *priv = NULL;
483        struct hid_sensor_hub_device *hsdev = NULL;
484
485        hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
486                         report->id, size, report->type);
487        hid_dbg(hdev, "maxfield:%d\n", report->maxfield);
488        if (report->type != HID_INPUT_REPORT)
489                return 1;
490
491        ptr = raw_data;
492        ptr++; /* Skip report id */
493
494        spin_lock_irqsave(&pdata->lock, flags);
495
496        for (i = 0; i < report->maxfield; ++i) {
497                hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",
498                                i, report->field[i]->usage->collection_index,
499                                report->field[i]->usage->hid,
500                                (report->field[i]->report_size *
501                                        report->field[i]->report_count)/8);
502                sz = (report->field[i]->report_size *
503                                        report->field[i]->report_count)/8;
504                collection = &hdev->collection[
505                                report->field[i]->usage->collection_index];
506                hid_dbg(hdev, "collection->usage %x\n",
507                                        collection->usage);
508
509                callback = sensor_hub_get_callback(hdev,
510                                report->field[i]->physical,
511                                report->field[i]->usage[0].collection_index,
512                                &hsdev, &priv);
513                if (!callback) {
514                        ptr += sz;
515                        continue;
516                }
517                if (hsdev->pending.status && (hsdev->pending.attr_usage_id ==
518                                              report->field[i]->usage->hid ||
519                                              hsdev->pending.attr_usage_id ==
520                                              report->field[i]->logical)) {
521                        hid_dbg(hdev, "data was pending ...\n");
522                        hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
523                        if (hsdev->pending.raw_data)
524                                hsdev->pending.raw_size = sz;
525                        else
526                                hsdev->pending.raw_size = 0;
527                        complete(&hsdev->pending.ready);
528                }
529                if (callback->capture_sample) {
530                        if (report->field[i]->logical)
531                                callback->capture_sample(hsdev,
532                                        report->field[i]->logical, sz, ptr,
533                                        callback->pdev);
534                        else
535                                callback->capture_sample(hsdev,
536                                        report->field[i]->usage->hid, sz, ptr,
537                                        callback->pdev);
538                }
539                ptr += sz;
540        }
541        if (callback && collection && callback->send_event)
542                callback->send_event(hsdev, collection->usage,
543                                callback->pdev);
544        spin_unlock_irqrestore(&pdata->lock, flags);
545
546        return 1;
547}
548
549int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
550{
551        int ret = 0;
552        struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
553
554        mutex_lock(&data->mutex);
555        if (!data->ref_cnt) {
556                ret = hid_hw_open(hsdev->hdev);
557                if (ret) {
558                        hid_err(hsdev->hdev, "failed to open hid device\n");
559                        mutex_unlock(&data->mutex);
560                        return ret;
561                }
562        }
563        data->ref_cnt++;
564        mutex_unlock(&data->mutex);
565
566        return ret;
567}
568EXPORT_SYMBOL_GPL(sensor_hub_device_open);
569
570void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
571{
572        struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
573
574        mutex_lock(&data->mutex);
575        data->ref_cnt--;
576        if (!data->ref_cnt)
577                hid_hw_close(hsdev->hdev);
578        mutex_unlock(&data->mutex);
579}
580EXPORT_SYMBOL_GPL(sensor_hub_device_close);
581
582static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc,
583                unsigned int *rsize)
584{
585        int index;
586        struct sensor_hub_data *sd =  hid_get_drvdata(hdev);
587        unsigned char report_block[] = {
588                                0x0a,  0x16, 0x03, 0x15, 0x00, 0x25, 0x05};
589        unsigned char power_block[] = {
590                                0x0a,  0x19, 0x03, 0x15, 0x00, 0x25, 0x05};
591
592        if (!(sd->quirks & HID_SENSOR_HUB_ENUM_QUIRK)) {
593                hid_dbg(hdev, "No Enum quirks\n");
594                return rdesc;
595        }
596
597        /* Looks for power and report state usage id and force to 1 */
598        for (index = 0; index < *rsize; ++index) {
599                if (((*rsize - index) > sizeof(report_block)) &&
600                        !memcmp(&rdesc[index], report_block,
601                                                sizeof(report_block))) {
602                        rdesc[index + 4] = 0x01;
603                        index += sizeof(report_block);
604                }
605                if (((*rsize - index) > sizeof(power_block)) &&
606                        !memcmp(&rdesc[index], power_block,
607                                                sizeof(power_block))) {
608                        rdesc[index + 4] = 0x01;
609                        index += sizeof(power_block);
610                }
611        }
612
613        /* Checks if the report descriptor of Thinkpad Helix 2 has a logical
614         * minimum for magnetic flux axis greater than the maximum */
615        if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&
616                *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&
617                rdesc[915] == 0x81 && rdesc[916] == 0x08 &&
618                rdesc[917] == 0x00 && rdesc[918] == 0x27 &&
619                rdesc[921] == 0x07 && rdesc[922] == 0x00) {
620                /* Sets negative logical minimum for mag x, y and z */
621                rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;
622                rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;
623                rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;
624                rdesc[917] = rdesc[938] = rdesc[959] = 0xff;
625        }
626
627        return rdesc;
628}
629
630static int sensor_hub_probe(struct hid_device *hdev,
631                                const struct hid_device_id *id)
632{
633        int ret;
634        struct sensor_hub_data *sd;
635        int i;
636        char *name;
637        int dev_cnt;
638        struct hid_sensor_hub_device *hsdev;
639        struct hid_sensor_hub_device *last_hsdev = NULL;
640        struct hid_sensor_hub_device *collection_hsdev = NULL;
641
642        sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);
643        if (!sd) {
644                hid_err(hdev, "cannot allocate Sensor data\n");
645                return -ENOMEM;
646        }
647
648        hid_set_drvdata(hdev, sd);
649        sd->quirks = id->driver_data;
650
651        spin_lock_init(&sd->lock);
652        spin_lock_init(&sd->dyn_callback_lock);
653        mutex_init(&sd->mutex);
654        ret = hid_parse(hdev);
655        if (ret) {
656                hid_err(hdev, "parse failed\n");
657                return ret;
658        }
659        INIT_LIST_HEAD(&hdev->inputs);
660
661        ret = hid_hw_start(hdev, 0);
662        if (ret) {
663                hid_err(hdev, "hw start failed\n");
664                return ret;
665        }
666        INIT_LIST_HEAD(&sd->dyn_callback_list);
667        sd->hid_sensor_client_cnt = 0;
668
669        dev_cnt = sensor_hub_get_physical_device_count(hdev);
670        if (dev_cnt > HID_MAX_PHY_DEVICES) {
671                hid_err(hdev, "Invalid Physical device count\n");
672                ret = -EINVAL;
673                goto err_stop_hw;
674        }
675        sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt *
676                                                      sizeof(struct mfd_cell),
677                                                      GFP_KERNEL);
678        if (sd->hid_sensor_hub_client_devs == NULL) {
679                hid_err(hdev, "Failed to allocate memory for mfd cells\n");
680                ret = -ENOMEM;
681                goto err_stop_hw;
682        }
683
684        for (i = 0; i < hdev->maxcollection; ++i) {
685                struct hid_collection *collection = &hdev->collection[i];
686
687                if (collection->type == HID_COLLECTION_PHYSICAL ||
688                    collection->type == HID_COLLECTION_APPLICATION) {
689
690                        hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev),
691                                             GFP_KERNEL);
692                        if (!hsdev) {
693                                hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
694                                ret = -ENOMEM;
695                                goto err_stop_hw;
696                        }
697                        hsdev->hdev = hdev;
698                        hsdev->vendor_id = hdev->vendor;
699                        hsdev->product_id = hdev->product;
700                        hsdev->usage = collection->usage;
701                        hsdev->mutex_ptr = devm_kzalloc(&hdev->dev,
702                                                        sizeof(struct mutex),
703                                                        GFP_KERNEL);
704                        if (!hsdev->mutex_ptr) {
705                                ret = -ENOMEM;
706                                goto err_stop_hw;
707                        }
708                        mutex_init(hsdev->mutex_ptr);
709                        hsdev->start_collection_index = i;
710                        if (last_hsdev)
711                                last_hsdev->end_collection_index = i;
712                        last_hsdev = hsdev;
713                        name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
714                                              "HID-SENSOR-%x",
715                                              collection->usage);
716                        if (name == NULL) {
717                                hid_err(hdev, "Failed MFD device name\n");
718                                ret = -ENOMEM;
719                                goto err_stop_hw;
720                        }
721                        sd->hid_sensor_hub_client_devs[
722                                sd->hid_sensor_client_cnt].name = name;
723                        sd->hid_sensor_hub_client_devs[
724                                sd->hid_sensor_client_cnt].platform_data =
725                                                        hsdev;
726                        sd->hid_sensor_hub_client_devs[
727                                sd->hid_sensor_client_cnt].pdata_size =
728                                                        sizeof(*hsdev);
729                        hid_dbg(hdev, "Adding %s:%d\n", name,
730                                        hsdev->start_collection_index);
731                        sd->hid_sensor_client_cnt++;
732                        if (collection_hsdev)
733                                collection_hsdev->end_collection_index = i;
734                        if (collection->type == HID_COLLECTION_APPLICATION &&
735                            collection->usage == HID_USAGE_SENSOR_COLLECTION)
736                                collection_hsdev = hsdev;
737                }
738        }
739        if (last_hsdev)
740                last_hsdev->end_collection_index = i;
741        if (collection_hsdev)
742                collection_hsdev->end_collection_index = i;
743
744        ret = mfd_add_hotplug_devices(&hdev->dev,
745                        sd->hid_sensor_hub_client_devs,
746                        sd->hid_sensor_client_cnt);
747        if (ret < 0)
748                goto err_stop_hw;
749
750        return ret;
751
752err_stop_hw:
753        hid_hw_stop(hdev);
754
755        return ret;
756}
757
758static void sensor_hub_remove(struct hid_device *hdev)
759{
760        struct sensor_hub_data *data = hid_get_drvdata(hdev);
761        unsigned long flags;
762        int i;
763
764        hid_dbg(hdev, " hardware removed\n");
765        hid_hw_close(hdev);
766        hid_hw_stop(hdev);
767        spin_lock_irqsave(&data->lock, flags);
768        for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
769                struct hid_sensor_hub_device *hsdev =
770                        data->hid_sensor_hub_client_devs[i].platform_data;
771                if (hsdev->pending.status)
772                        complete(&hsdev->pending.ready);
773        }
774        spin_unlock_irqrestore(&data->lock, flags);
775        mfd_remove_devices(&hdev->dev);
776        hid_set_drvdata(hdev, NULL);
777        mutex_destroy(&data->mutex);
778}
779
780static const struct hid_device_id sensor_hub_devices[] = {
781        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
782                        USB_DEVICE_ID_INTEL_HID_SENSOR_0),
783                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
784        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
785                        USB_DEVICE_ID_INTEL_HID_SENSOR_0),
786                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
787        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
788                        USB_DEVICE_ID_INTEL_HID_SENSOR_1),
789                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
790        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
791                        USB_DEVICE_ID_MS_SURFACE_PRO_2),
792                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
793        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
794                        USB_DEVICE_ID_MS_TOUCH_COVER_2),
795                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
796        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
797                        USB_DEVICE_ID_MS_TYPE_COVER_2),
798                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
799        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
800                        0x07bd), /* Microsoft Surface 3 */
801                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
802        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROCHIP,
803                        0x0f01), /* MM7150 */
804                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
805        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
806                        USB_DEVICE_ID_STM_HID_SENSOR),
807                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
808        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
809                        USB_DEVICE_ID_STM_HID_SENSOR_1),
810                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
811        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS,
812                        USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA),
813                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
814        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE,
815                        USB_DEVICE_ID_ITE_LENOVO_YOGA),
816                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
817        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE,
818                        USB_DEVICE_ID_ITE_LENOVO_YOGA2),
819                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
820        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE,
821                        USB_DEVICE_ID_ITE_LENOVO_YOGA900),
822                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
823        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
824                        0x22D8),
825                        .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
826        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
827                     HID_ANY_ID) },
828        { }
829};
830MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
831
832static struct hid_driver sensor_hub_driver = {
833        .name = "hid-sensor-hub",
834        .id_table = sensor_hub_devices,
835        .probe = sensor_hub_probe,
836        .remove = sensor_hub_remove,
837        .raw_event = sensor_hub_raw_event,
838        .report_fixup = sensor_hub_report_fixup,
839#ifdef CONFIG_PM
840        .suspend = sensor_hub_suspend,
841        .resume = sensor_hub_resume,
842        .reset_resume = sensor_hub_reset_resume,
843#endif
844};
845module_hid_driver(sensor_hub_driver);
846
847MODULE_DESCRIPTION("HID Sensor Hub driver");
848MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
849MODULE_LICENSE("GPL");
Note: See TracBrowser for help on using the repository browser.