linux/drivers/hid/hid-sensor-hub.c
<<
>>
Prefs
   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        /*
 586         * Checks if the report descriptor of Thinkpad Helix 2 has a logical
 587         * minimum for magnetic flux axis greater than the maximum.
 588         */
 589        if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&
 590                *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&
 591                rdesc[915] == 0x81 && rdesc[916] == 0x08 &&
 592                rdesc[917] == 0x00 && rdesc[918] == 0x27 &&
 593                rdesc[921] == 0x07 && rdesc[922] == 0x00) {
 594                /* Sets negative logical minimum for mag x, y and z */
 595                rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;
 596                rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;
 597                rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;
 598                rdesc[917] = rdesc[938] = rdesc[959] = 0xff;
 599        }
 600
 601        return rdesc;
 602}
 603
 604static int sensor_hub_probe(struct hid_device *hdev,
 605                                const struct hid_device_id *id)
 606{
 607        int ret;
 608        struct sensor_hub_data *sd;
 609        int i;
 610        char *name;
 611        int dev_cnt;
 612        struct hid_sensor_hub_device *hsdev;
 613        struct hid_sensor_hub_device *last_hsdev = NULL;
 614        struct hid_sensor_hub_device *collection_hsdev = NULL;
 615
 616        sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);
 617        if (!sd) {
 618                hid_err(hdev, "cannot allocate Sensor data\n");
 619                return -ENOMEM;
 620        }
 621
 622        hid_set_drvdata(hdev, sd);
 623        sd->quirks = id->driver_data;
 624
 625        spin_lock_init(&sd->lock);
 626        spin_lock_init(&sd->dyn_callback_lock);
 627        mutex_init(&sd->mutex);
 628        ret = hid_parse(hdev);
 629        if (ret) {
 630                hid_err(hdev, "parse failed\n");
 631                return ret;
 632        }
 633        INIT_LIST_HEAD(&hdev->inputs);
 634
 635        ret = hid_hw_start(hdev, 0);
 636        if (ret) {
 637                hid_err(hdev, "hw start failed\n");
 638                return ret;
 639        }
 640        INIT_LIST_HEAD(&sd->dyn_callback_list);
 641        sd->hid_sensor_client_cnt = 0;
 642
 643        dev_cnt = sensor_hub_get_physical_device_count(hdev);
 644        if (dev_cnt > HID_MAX_PHY_DEVICES) {
 645                hid_err(hdev, "Invalid Physical device count\n");
 646                ret = -EINVAL;
 647                goto err_stop_hw;
 648        }
 649        sd->hid_sensor_hub_client_devs = devm_kcalloc(&hdev->dev,
 650                                                      dev_cnt,
 651                                                      sizeof(struct mfd_cell),
 652                                                      GFP_KERNEL);
 653        if (sd->hid_sensor_hub_client_devs == NULL) {
 654                hid_err(hdev, "Failed to allocate memory for mfd cells\n");
 655                ret = -ENOMEM;
 656                goto err_stop_hw;
 657        }
 658
 659        for (i = 0; i < hdev->maxcollection; ++i) {
 660                struct hid_collection *collection = &hdev->collection[i];
 661
 662                if (collection->type == HID_COLLECTION_PHYSICAL ||
 663                    collection->type == HID_COLLECTION_APPLICATION) {
 664
 665                        hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev),
 666                                             GFP_KERNEL);
 667                        if (!hsdev) {
 668                                hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
 669                                ret = -ENOMEM;
 670                                goto err_stop_hw;
 671                        }
 672                        hsdev->hdev = hdev;
 673                        hsdev->vendor_id = hdev->vendor;
 674                        hsdev->product_id = hdev->product;
 675                        hsdev->usage = collection->usage;
 676                        hsdev->mutex_ptr = devm_kzalloc(&hdev->dev,
 677                                                        sizeof(struct mutex),
 678                                                        GFP_KERNEL);
 679                        if (!hsdev->mutex_ptr) {
 680                                ret = -ENOMEM;
 681                                goto err_stop_hw;
 682                        }
 683                        mutex_init(hsdev->mutex_ptr);
 684                        hsdev->start_collection_index = i;
 685                        if (last_hsdev)
 686                                last_hsdev->end_collection_index = i;
 687                        last_hsdev = hsdev;
 688                        name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
 689                                              "HID-SENSOR-%x",
 690                                              collection->usage);
 691                        if (name == NULL) {
 692                                hid_err(hdev, "Failed MFD device name\n");
 693                                ret = -ENOMEM;
 694                                goto err_stop_hw;
 695                        }
 696                        sd->hid_sensor_hub_client_devs[
 697                                sd->hid_sensor_client_cnt].name = name;
 698                        sd->hid_sensor_hub_client_devs[
 699                                sd->hid_sensor_client_cnt].platform_data =
 700                                                        hsdev;
 701                        sd->hid_sensor_hub_client_devs[
 702                                sd->hid_sensor_client_cnt].pdata_size =
 703                                                        sizeof(*hsdev);
 704                        hid_dbg(hdev, "Adding %s:%d\n", name,
 705                                        hsdev->start_collection_index);
 706                        sd->hid_sensor_client_cnt++;
 707                        if (collection_hsdev)
 708                                collection_hsdev->end_collection_index = i;
 709                        if (collection->type == HID_COLLECTION_APPLICATION &&
 710                            collection->usage == HID_USAGE_SENSOR_COLLECTION)
 711                                collection_hsdev = hsdev;
 712                }
 713        }
 714        if (last_hsdev)
 715                last_hsdev->end_collection_index = i;
 716        if (collection_hsdev)
 717                collection_hsdev->end_collection_index = i;
 718
 719        ret = mfd_add_hotplug_devices(&hdev->dev,
 720                        sd->hid_sensor_hub_client_devs,
 721                        sd->hid_sensor_client_cnt);
 722        if (ret < 0)
 723                goto err_stop_hw;
 724
 725        return ret;
 726
 727err_stop_hw:
 728        hid_hw_stop(hdev);
 729
 730        return ret;
 731}
 732
 733static void sensor_hub_remove(struct hid_device *hdev)
 734{
 735        struct sensor_hub_data *data = hid_get_drvdata(hdev);
 736        unsigned long flags;
 737        int i;
 738
 739        hid_dbg(hdev, " hardware removed\n");
 740        hid_hw_close(hdev);
 741        hid_hw_stop(hdev);
 742        spin_lock_irqsave(&data->lock, flags);
 743        for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
 744                struct hid_sensor_hub_device *hsdev =
 745                        data->hid_sensor_hub_client_devs[i].platform_data;
 746                if (hsdev->pending.status)
 747                        complete(&hsdev->pending.ready);
 748        }
 749        spin_unlock_irqrestore(&data->lock, flags);
 750        mfd_remove_devices(&hdev->dev);
 751        hid_set_drvdata(hdev, NULL);
 752        mutex_destroy(&data->mutex);
 753}
 754
 755static const struct hid_device_id sensor_hub_devices[] = {
 756        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
 757                     HID_ANY_ID) },
 758        { }
 759};
 760MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
 761
 762static struct hid_driver sensor_hub_driver = {
 763        .name = "hid-sensor-hub",
 764        .id_table = sensor_hub_devices,
 765        .probe = sensor_hub_probe,
 766        .remove = sensor_hub_remove,
 767        .raw_event = sensor_hub_raw_event,
 768        .report_fixup = sensor_hub_report_fixup,
 769#ifdef CONFIG_PM
 770        .suspend = sensor_hub_suspend,
 771        .resume = sensor_hub_resume,
 772        .reset_resume = sensor_hub_reset_resume,
 773#endif
 774};
 775module_hid_driver(sensor_hub_driver);
 776
 777MODULE_DESCRIPTION("HID Sensor Hub driver");
 778MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
 779MODULE_LICENSE("GPL");
 780