video: tegra: dc: Add quick for Vizio P series
[linux-3.10.git] / drivers / hid / hid-sensor-hub.c
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 #include <linux/device.h>
20 #include <linux/hid.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/mfd/core.h>
24 #include <linux/list.h>
25 #include <linux/hid-sensor-ids.h>
26 #include <linux/hid-sensor-hub.h>
27 #include "hid-ids.h"
28
29 /**
30  * struct sensor_hub_pending - Synchronous read pending information
31  * @status:             Pending status true/false.
32  * @ready:              Completion synchronization data.
33  * @usage_id:           Usage id for physical device, E.g. Gyro usage id.
34  * @attr_usage_id:      Usage Id of a field, E.g. X-AXIS for a gyro.
35  * @raw_size:           Response size for a read request.
36  * @raw_data:           Place holder for received response.
37  */
38 struct sensor_hub_pending {
39         bool status;
40         struct completion ready;
41         u32 usage_id;
42         u32 attr_usage_id;
43         int raw_size;
44         u8  *raw_data;
45 };
46
47 /**
48  * struct sensor_hub_data - Hold a instance data for a HID hub device
49  * @hsdev:              Stored hid instance for current hub device.
50  * @mutex:              Mutex to serialize synchronous request.
51  * @lock:               Spin lock to protect pending request structure.
52  * @pending:            Holds information of pending sync read request.
53  * @dyn_callback_list:  Holds callback function
54  * @dyn_callback_lock:  spin lock to protect callback list
55  * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance.
56  * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached).
57  */
58 struct sensor_hub_data {
59         struct hid_sensor_hub_device *hsdev;
60         struct mutex mutex;
61         spinlock_t lock;
62         struct sensor_hub_pending pending;
63         struct list_head dyn_callback_list;
64         spinlock_t dyn_callback_lock;
65         struct mfd_cell *hid_sensor_hub_client_devs;
66         int hid_sensor_client_cnt;
67 };
68
69 /**
70  * struct hid_sensor_hub_callbacks_list - Stores callback list
71  * @list:               list head.
72  * @usage_id:           usage id for a physical device.
73  * @usage_callback:     Stores registered callback functions.
74  * @priv:               Private data for a physical device.
75  */
76 struct hid_sensor_hub_callbacks_list {
77         struct list_head list;
78         u32 usage_id;
79         struct hid_sensor_hub_callbacks *usage_callback;
80         void *priv;
81 };
82
83 static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
84                                                 int dir)
85 {
86         struct hid_report *report;
87
88         list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) {
89                 if (report->id == id)
90                         return report;
91         }
92         hid_warn(hdev, "No report with id 0x%x found\n", id);
93
94         return NULL;
95 }
96
97 static int sensor_hub_get_physical_device_count(
98                                 struct hid_report_enum *report_enum)
99 {
100         struct hid_report *report;
101         struct hid_field *field;
102         int cnt = 0;
103
104         list_for_each_entry(report, &report_enum->report_list, list) {
105                 field = report->field[0];
106                 if (report->maxfield && field &&
107                                         field->physical)
108                         cnt++;
109         }
110
111         return cnt;
112 }
113
114 static void sensor_hub_fill_attr_info(
115                 struct hid_sensor_hub_attribute_info *info,
116                 s32 index, s32 report_id, s32 units, s32 unit_expo, s32 size)
117 {
118         info->index = index;
119         info->report_id = report_id;
120         info->units = units;
121         info->unit_expo = unit_expo;
122         info->size = size/8;
123 }
124
125 static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(
126                                         struct hid_device *hdev,
127                                         u32 usage_id, void **priv)
128 {
129         struct hid_sensor_hub_callbacks_list *callback;
130         struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
131
132         spin_lock(&pdata->dyn_callback_lock);
133         list_for_each_entry(callback, &pdata->dyn_callback_list, list)
134                 if (callback->usage_id == usage_id) {
135                         *priv = callback->priv;
136                         spin_unlock(&pdata->dyn_callback_lock);
137                         return callback->usage_callback;
138                 }
139         spin_unlock(&pdata->dyn_callback_lock);
140
141         return NULL;
142 }
143
144 int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
145                         u32 usage_id,
146                         struct hid_sensor_hub_callbacks *usage_callback)
147 {
148         struct hid_sensor_hub_callbacks_list *callback;
149         struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
150
151         spin_lock(&pdata->dyn_callback_lock);
152         list_for_each_entry(callback, &pdata->dyn_callback_list, list)
153                 if (callback->usage_id == usage_id) {
154                         spin_unlock(&pdata->dyn_callback_lock);
155                         return -EINVAL;
156                 }
157         callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
158         if (!callback) {
159                 spin_unlock(&pdata->dyn_callback_lock);
160                 return -ENOMEM;
161         }
162         callback->usage_callback = usage_callback;
163         callback->usage_id = usage_id;
164         callback->priv = NULL;
165         list_add_tail(&callback->list, &pdata->dyn_callback_list);
166         spin_unlock(&pdata->dyn_callback_lock);
167
168         return 0;
169 }
170 EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
171
172 int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
173                                 u32 usage_id)
174 {
175         struct hid_sensor_hub_callbacks_list *callback;
176         struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
177
178         spin_lock(&pdata->dyn_callback_lock);
179         list_for_each_entry(callback, &pdata->dyn_callback_list, list)
180                 if (callback->usage_id == usage_id) {
181                         list_del(&callback->list);
182                         kfree(callback);
183                         break;
184                 }
185         spin_unlock(&pdata->dyn_callback_lock);
186
187         return 0;
188 }
189 EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);
190
191 int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
192                                 u32 field_index, s32 value)
193 {
194         struct hid_report *report;
195         struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
196         int ret = 0;
197
198         mutex_lock(&data->mutex);
199         report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
200         if (!report || (field_index >=  report->maxfield)) {
201                 ret = -EINVAL;
202                 goto done_proc;
203         }
204         hid_set_field(report->field[field_index], 0, value);
205         hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT);
206         hid_hw_wait(hsdev->hdev);
207
208 done_proc:
209         mutex_unlock(&data->mutex);
210
211         return ret;
212 }
213 EXPORT_SYMBOL_GPL(sensor_hub_set_feature);
214
215 int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
216                                 u32 field_index, s32 *value)
217 {
218         struct hid_report *report;
219         struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
220         int ret = 0;
221
222         mutex_lock(&data->mutex);
223         report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
224         if (!report || (field_index >=  report->maxfield) ||
225             report->field[field_index]->report_count < 1) {
226                 ret = -EINVAL;
227                 goto done_proc;
228         }
229         hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
230         hid_hw_wait(hsdev->hdev);
231         *value = report->field[field_index]->value[0];
232
233 done_proc:
234         mutex_unlock(&data->mutex);
235
236         return ret;
237 }
238 EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
239
240
241 int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
242                                         u32 usage_id,
243                                         u32 attr_usage_id, u32 report_id)
244 {
245         struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
246         unsigned long flags;
247         struct hid_report *report;
248         int ret_val = 0;
249
250         mutex_lock(&data->mutex);
251         memset(&data->pending, 0, sizeof(data->pending));
252         init_completion(&data->pending.ready);
253         data->pending.usage_id = usage_id;
254         data->pending.attr_usage_id = attr_usage_id;
255         data->pending.raw_size = 0;
256
257         spin_lock_irqsave(&data->lock, flags);
258         data->pending.status = true;
259         report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT);
260         if (!report) {
261                 spin_unlock_irqrestore(&data->lock, flags);
262                 goto err_free;
263         }
264         hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
265         spin_unlock_irqrestore(&data->lock, flags);
266         wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5);
267         switch (data->pending.raw_size) {
268         case 1:
269                 ret_val = *(u8 *)data->pending.raw_data;
270                 break;
271         case 2:
272                 ret_val = *(u16 *)data->pending.raw_data;
273                 break;
274         case 4:
275                 ret_val = *(u32 *)data->pending.raw_data;
276                 break;
277         default:
278                 ret_val = 0;
279         }
280         kfree(data->pending.raw_data);
281
282 err_free:
283         data->pending.status = false;
284         mutex_unlock(&data->mutex);
285
286         return ret_val;
287 }
288 EXPORT_SYMBOL_GPL(sensor_hub_input_attr_get_raw_value);
289
290 int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
291                                 u8 type,
292                                 u32 usage_id,
293                                 u32 attr_usage_id,
294                                 struct hid_sensor_hub_attribute_info *info)
295 {
296         int ret = -1;
297         int i, j;
298         int collection_index = -1;
299         struct hid_report *report;
300         struct hid_field *field;
301         struct hid_report_enum *report_enum;
302         struct hid_device *hdev = hsdev->hdev;
303
304         /* Initialize with defaults */
305         info->usage_id = usage_id;
306         info->attrib_id =  attr_usage_id;
307         info->report_id = -1;
308         info->index = -1;
309         info->units = -1;
310         info->unit_expo = -1;
311
312         for (i = 0; i < hdev->maxcollection; ++i) {
313                 struct hid_collection *collection = &hdev->collection[i];
314                 if (usage_id == collection->usage) {
315                         collection_index = i;
316                         break;
317                 }
318         }
319         if (collection_index == -1)
320                 goto err_ret;
321
322         report_enum = &hdev->report_enum[type];
323         list_for_each_entry(report, &report_enum->report_list, list) {
324                 for (i = 0; i < report->maxfield; ++i) {
325                         field = report->field[i];
326                         if (field->physical == usage_id &&
327                                 field->logical == attr_usage_id) {
328                                 sensor_hub_fill_attr_info(info, i, report->id,
329                                         field->unit, field->unit_exponent,
330                                         field->report_size *
331                                                         field->report_count);
332                                 ret = 0;
333                         } else {
334                                 for (j = 0; j < field->maxusage; ++j) {
335                                         if (field->usage[j].hid ==
336                                         attr_usage_id &&
337                                         field->usage[j].collection_index ==
338                                         collection_index)  {
339                                                 sensor_hub_fill_attr_info(info,
340                                                         i, report->id,
341                                                         field->unit,
342                                                         field->unit_exponent,
343                                                         field->report_size *
344                                                         field->report_count);
345                                                 ret = 0;
346                                                 break;
347                                         }
348                                 }
349                         }
350                         if (ret == 0)
351                                 break;
352                 }
353         }
354
355 err_ret:
356         return ret;
357 }
358 EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
359
360 #ifdef CONFIG_PM
361 static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
362 {
363         struct sensor_hub_data *pdata =  hid_get_drvdata(hdev);
364         struct hid_sensor_hub_callbacks_list *callback;
365
366         hid_dbg(hdev, " sensor_hub_suspend\n");
367         spin_lock(&pdata->dyn_callback_lock);
368         list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
369                 if (callback->usage_callback->suspend)
370                         callback->usage_callback->suspend(
371                                         pdata->hsdev, callback->priv);
372         }
373         spin_unlock(&pdata->dyn_callback_lock);
374
375         return 0;
376 }
377
378 static int sensor_hub_resume(struct hid_device *hdev)
379 {
380         struct sensor_hub_data *pdata =  hid_get_drvdata(hdev);
381         struct hid_sensor_hub_callbacks_list *callback;
382
383         hid_dbg(hdev, " sensor_hub_resume\n");
384         spin_lock(&pdata->dyn_callback_lock);
385         list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
386                 if (callback->usage_callback->resume)
387                         callback->usage_callback->resume(
388                                         pdata->hsdev, callback->priv);
389         }
390         spin_unlock(&pdata->dyn_callback_lock);
391
392         return 0;
393 }
394
395 static int sensor_hub_reset_resume(struct hid_device *hdev)
396 {
397         return 0;
398 }
399 #endif
400 /*
401  * Handle raw report as sent by device
402  */
403 static int sensor_hub_raw_event(struct hid_device *hdev,
404                 struct hid_report *report, u8 *raw_data, int size)
405 {
406         int i;
407         u8 *ptr;
408         int sz;
409         struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
410         unsigned long flags;
411         struct hid_sensor_hub_callbacks *callback = NULL;
412         struct hid_collection *collection = NULL;
413         void *priv = NULL;
414
415         hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
416                          report->id, size, report->type);
417         hid_dbg(hdev, "maxfield:%d\n", report->maxfield);
418         if (report->type != HID_INPUT_REPORT)
419                 return 1;
420
421         ptr = raw_data;
422         ptr++; /*Skip report id*/
423
424         spin_lock_irqsave(&pdata->lock, flags);
425
426         for (i = 0; i < report->maxfield; ++i) {
427
428                 hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",
429                                 i, report->field[i]->usage->collection_index,
430                                 report->field[i]->usage->hid,
431                                 (report->field[i]->report_size *
432                                         report->field[i]->report_count)/8);
433                 sz = (report->field[i]->report_size *
434                                         report->field[i]->report_count)/8;
435                 if (pdata->pending.status && pdata->pending.attr_usage_id ==
436                                 report->field[i]->usage->hid) {
437                         hid_dbg(hdev, "data was pending ...\n");
438                         pdata->pending.raw_data = kmalloc(sz, GFP_ATOMIC);
439                         if (pdata->pending.raw_data) {
440                                 memcpy(pdata->pending.raw_data, ptr, sz);
441                                 pdata->pending.raw_size  = sz;
442                         } else
443                                 pdata->pending.raw_size = 0;
444                         complete(&pdata->pending.ready);
445                 }
446                 collection = &hdev->collection[
447                                 report->field[i]->usage->collection_index];
448                 hid_dbg(hdev, "collection->usage %x\n",
449                                         collection->usage);
450                 callback = sensor_hub_get_callback(pdata->hsdev->hdev,
451                                                 report->field[i]->physical,
452                                                         &priv);
453                 if (callback && callback->capture_sample) {
454                         if (report->field[i]->logical)
455                                 callback->capture_sample(pdata->hsdev,
456                                         report->field[i]->logical, sz, ptr,
457                                         callback->pdev);
458                         else
459                                 callback->capture_sample(pdata->hsdev,
460                                         report->field[i]->usage->hid, sz, ptr,
461                                         callback->pdev);
462                 }
463                 ptr += sz;
464         }
465         if (callback && collection && callback->send_event)
466                 callback->send_event(pdata->hsdev, collection->usage,
467                                 callback->pdev);
468         spin_unlock_irqrestore(&pdata->lock, flags);
469
470         return 1;
471 }
472
473 static int sensor_hub_probe(struct hid_device *hdev,
474                                 const struct hid_device_id *id)
475 {
476         int ret;
477         struct sensor_hub_data *sd;
478         int i;
479         char *name;
480         struct hid_report *report;
481         struct hid_report_enum *report_enum;
482         struct hid_field *field;
483         int dev_cnt;
484
485         sd = kzalloc(sizeof(struct sensor_hub_data), GFP_KERNEL);
486         if (!sd) {
487                 hid_err(hdev, "cannot allocate Sensor data\n");
488                 return -ENOMEM;
489         }
490         sd->hsdev = kzalloc(sizeof(struct hid_sensor_hub_device), GFP_KERNEL);
491         if (!sd->hsdev) {
492                 hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
493                 ret = -ENOMEM;
494                 goto err_free_hub;
495         }
496         hid_set_drvdata(hdev, sd);
497         sd->hsdev->hdev = hdev;
498         sd->hsdev->vendor_id = hdev->vendor;
499         sd->hsdev->product_id = hdev->product;
500         spin_lock_init(&sd->lock);
501         spin_lock_init(&sd->dyn_callback_lock);
502         mutex_init(&sd->mutex);
503         ret = hid_parse(hdev);
504         if (ret) {
505                 hid_err(hdev, "parse failed\n");
506                 goto err_free;
507         }
508         INIT_LIST_HEAD(&hdev->inputs);
509
510         ret = hid_hw_start(hdev, 0);
511         if (ret) {
512                 hid_err(hdev, "hw start failed\n");
513                 goto err_free;
514         }
515         ret = hid_hw_open(hdev);
516         if (ret) {
517                 hid_err(hdev, "failed to open input interrupt pipe\n");
518                 goto err_stop_hw;
519         }
520
521         INIT_LIST_HEAD(&sd->dyn_callback_list);
522         sd->hid_sensor_client_cnt = 0;
523         report_enum = &hdev->report_enum[HID_INPUT_REPORT];
524
525         dev_cnt = sensor_hub_get_physical_device_count(report_enum);
526         if (dev_cnt > HID_MAX_PHY_DEVICES) {
527                 hid_err(hdev, "Invalid Physical device count\n");
528                 ret = -EINVAL;
529                 goto err_close;
530         }
531         sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt *
532                                                 sizeof(struct mfd_cell),
533                                                 GFP_KERNEL);
534         if (sd->hid_sensor_hub_client_devs == NULL) {
535                 hid_err(hdev, "Failed to allocate memory for mfd cells\n");
536                         ret = -ENOMEM;
537                         goto err_close;
538         }
539         list_for_each_entry(report, &report_enum->report_list, list) {
540                 hid_dbg(hdev, "Report id:%x\n", report->id);
541                 field = report->field[0];
542                 if (report->maxfield && field &&
543                                         field->physical) {
544                         name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x",
545                                                 field->physical);
546                         if (name  == NULL) {
547                                 hid_err(hdev, "Failed MFD device name\n");
548                                         ret = -ENOMEM;
549                                         goto err_free_names;
550                         }
551                         sd->hid_sensor_hub_client_devs[
552                                 sd->hid_sensor_client_cnt].name = name;
553                         sd->hid_sensor_hub_client_devs[
554                                 sd->hid_sensor_client_cnt].platform_data =
555                                                 sd->hsdev;
556                         sd->hid_sensor_hub_client_devs[
557                                 sd->hid_sensor_client_cnt].pdata_size =
558                                                 sizeof(*sd->hsdev);
559                         hid_dbg(hdev, "Adding %s:%p\n", name, sd);
560                         sd->hid_sensor_client_cnt++;
561                 }
562         }
563         ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs,
564                 sd->hid_sensor_client_cnt, NULL, 0, NULL);
565         if (ret < 0)
566                 goto err_free_names;
567
568         return ret;
569
570 err_free_names:
571         for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
572                 kfree(sd->hid_sensor_hub_client_devs[i].name);
573         kfree(sd->hid_sensor_hub_client_devs);
574 err_close:
575         hid_hw_close(hdev);
576 err_stop_hw:
577         hid_hw_stop(hdev);
578 err_free:
579         kfree(sd->hsdev);
580 err_free_hub:
581         kfree(sd);
582
583         return ret;
584 }
585
586 static void sensor_hub_remove(struct hid_device *hdev)
587 {
588         struct sensor_hub_data *data = hid_get_drvdata(hdev);
589         unsigned long flags;
590         int i;
591
592         hid_dbg(hdev, " hardware removed\n");
593         hid_hw_close(hdev);
594         hid_hw_stop(hdev);
595         spin_lock_irqsave(&data->lock, flags);
596         if (data->pending.status)
597                 complete(&data->pending.ready);
598         spin_unlock_irqrestore(&data->lock, flags);
599         mfd_remove_devices(&hdev->dev);
600         for (i = 0; i < data->hid_sensor_client_cnt ; ++i)
601                 kfree(data->hid_sensor_hub_client_devs[i].name);
602         kfree(data->hid_sensor_hub_client_devs);
603         hid_set_drvdata(hdev, NULL);
604         mutex_destroy(&data->mutex);
605         kfree(data->hsdev);
606         kfree(data);
607 }
608
609 static const struct hid_device_id sensor_hub_devices[] = {
610         { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
611                      HID_ANY_ID) },
612         { }
613 };
614 MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
615
616 static struct hid_driver sensor_hub_driver = {
617         .name = "hid-sensor-hub",
618         .id_table = sensor_hub_devices,
619         .probe = sensor_hub_probe,
620         .remove = sensor_hub_remove,
621         .raw_event = sensor_hub_raw_event,
622 #ifdef CONFIG_PM
623         .suspend = sensor_hub_suspend,
624         .resume =  sensor_hub_resume,
625         .reset_resume =  sensor_hub_reset_resume,
626 #endif
627 };
628 module_hid_driver(sensor_hub_driver);
629
630 MODULE_DESCRIPTION("HID Sensor Hub driver");
631 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
632 MODULE_LICENSE("GPL");