root/drivers/staging/greybus/hid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gb_hid_get_desc
  2. gb_hid_get_report_desc
  3. gb_hid_set_power
  4. gb_hid_get_report
  5. gb_hid_set_report
  6. gb_hid_request_handler
  7. gb_hid_report_len
  8. gb_hid_find_max_report
  9. gb_hid_free_buffers
  10. gb_hid_alloc_buffers
  11. gb_hid_init_report
  12. gb_hid_init_reports
  13. __gb_hid_get_raw_report
  14. __gb_hid_output_raw_report
  15. gb_hid_raw_request
  16. gb_hid_parse
  17. gb_hid_start
  18. gb_hid_stop
  19. gb_hid_open
  20. gb_hid_close
  21. gb_hid_power
  22. gb_hid_init
  23. gb_hid_probe
  24. gb_hid_disconnect

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * HID class driver for the Greybus.
   4  *
   5  * Copyright 2014 Google Inc.
   6  * Copyright 2014 Linaro Ltd.
   7  */
   8 
   9 #include <linux/bitops.h>
  10 #include <linux/hid.h>
  11 #include <linux/kernel.h>
  12 #include <linux/module.h>
  13 #include <linux/mutex.h>
  14 #include <linux/slab.h>
  15 #include <linux/greybus.h>
  16 
  17 /* Greybus HID device's structure */
  18 struct gb_hid {
  19         struct gb_bundle *bundle;
  20         struct gb_connection            *connection;
  21 
  22         struct hid_device               *hid;
  23         struct gb_hid_desc_response     hdesc;
  24 
  25         unsigned long                   flags;
  26 #define GB_HID_STARTED                  0x01
  27 #define GB_HID_READ_PENDING             0x04
  28 
  29         unsigned int                    bufsize;
  30         char                            *inbuf;
  31 };
  32 
  33 /* Routines to get controller's information over greybus */
  34 
  35 /* Operations performed on greybus */
  36 static int gb_hid_get_desc(struct gb_hid *ghid)
  37 {
  38         return gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_DESC, NULL,
  39                                  0, &ghid->hdesc, sizeof(ghid->hdesc));
  40 }
  41 
  42 static int gb_hid_get_report_desc(struct gb_hid *ghid, char *rdesc)
  43 {
  44         int ret;
  45 
  46         ret = gb_pm_runtime_get_sync(ghid->bundle);
  47         if (ret)
  48                 return ret;
  49 
  50         ret = gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_REPORT_DESC,
  51                                 NULL, 0, rdesc,
  52                                 le16_to_cpu(ghid->hdesc.wReportDescLength));
  53 
  54         gb_pm_runtime_put_autosuspend(ghid->bundle);
  55 
  56         return ret;
  57 }
  58 
  59 static int gb_hid_set_power(struct gb_hid *ghid, int type)
  60 {
  61         int ret;
  62 
  63         ret = gb_pm_runtime_get_sync(ghid->bundle);
  64         if (ret)
  65                 return ret;
  66 
  67         ret = gb_operation_sync(ghid->connection, type, NULL, 0, NULL, 0);
  68 
  69         gb_pm_runtime_put_autosuspend(ghid->bundle);
  70 
  71         return ret;
  72 }
  73 
  74 static int gb_hid_get_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
  75                              unsigned char *buf, int len)
  76 {
  77         struct gb_hid_get_report_request request;
  78         int ret;
  79 
  80         ret = gb_pm_runtime_get_sync(ghid->bundle);
  81         if (ret)
  82                 return ret;
  83 
  84         request.report_type = report_type;
  85         request.report_id = report_id;
  86 
  87         ret = gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_REPORT,
  88                                 &request, sizeof(request), buf, len);
  89 
  90         gb_pm_runtime_put_autosuspend(ghid->bundle);
  91 
  92         return ret;
  93 }
  94 
  95 static int gb_hid_set_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
  96                              unsigned char *buf, int len)
  97 {
  98         struct gb_hid_set_report_request *request;
  99         struct gb_operation *operation;
 100         int ret, size = sizeof(*request) + len - 1;
 101 
 102         ret = gb_pm_runtime_get_sync(ghid->bundle);
 103         if (ret)
 104                 return ret;
 105 
 106         operation = gb_operation_create(ghid->connection,
 107                                         GB_HID_TYPE_SET_REPORT, size, 0,
 108                                         GFP_KERNEL);
 109         if (!operation) {
 110                 gb_pm_runtime_put_autosuspend(ghid->bundle);
 111                 return -ENOMEM;
 112         }
 113 
 114         request = operation->request->payload;
 115         request->report_type = report_type;
 116         request->report_id = report_id;
 117         memcpy(request->report, buf, len);
 118 
 119         ret = gb_operation_request_send_sync(operation);
 120         if (ret) {
 121                 dev_err(&operation->connection->bundle->dev,
 122                         "failed to set report: %d\n", ret);
 123         } else {
 124                 ret = len;
 125         }
 126 
 127         gb_operation_put(operation);
 128         gb_pm_runtime_put_autosuspend(ghid->bundle);
 129 
 130         return ret;
 131 }
 132 
 133 static int gb_hid_request_handler(struct gb_operation *op)
 134 {
 135         struct gb_connection *connection = op->connection;
 136         struct gb_hid *ghid = gb_connection_get_data(connection);
 137         struct gb_hid_input_report_request *request = op->request->payload;
 138 
 139         if (op->type != GB_HID_TYPE_IRQ_EVENT) {
 140                 dev_err(&connection->bundle->dev,
 141                         "unsupported unsolicited request\n");
 142                 return -EINVAL;
 143         }
 144 
 145         if (test_bit(GB_HID_STARTED, &ghid->flags))
 146                 hid_input_report(ghid->hid, HID_INPUT_REPORT,
 147                                  request->report, op->request->payload_size, 1);
 148 
 149         return 0;
 150 }
 151 
 152 static int gb_hid_report_len(struct hid_report *report)
 153 {
 154         return ((report->size - 1) >> 3) + 1 +
 155                 report->device->report_enum[report->type].numbered;
 156 }
 157 
 158 static void gb_hid_find_max_report(struct hid_device *hid, unsigned int type,
 159                                    unsigned int *max)
 160 {
 161         struct hid_report *report;
 162         unsigned int size;
 163 
 164         list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
 165                 size = gb_hid_report_len(report);
 166                 if (*max < size)
 167                         *max = size;
 168         }
 169 }
 170 
 171 static void gb_hid_free_buffers(struct gb_hid *ghid)
 172 {
 173         kfree(ghid->inbuf);
 174         ghid->inbuf = NULL;
 175         ghid->bufsize = 0;
 176 }
 177 
 178 static int gb_hid_alloc_buffers(struct gb_hid *ghid, size_t bufsize)
 179 {
 180         ghid->inbuf = kzalloc(bufsize, GFP_KERNEL);
 181         if (!ghid->inbuf)
 182                 return -ENOMEM;
 183 
 184         ghid->bufsize = bufsize;
 185 
 186         return 0;
 187 }
 188 
 189 /* Routines dealing with reports */
 190 static void gb_hid_init_report(struct gb_hid *ghid, struct hid_report *report)
 191 {
 192         unsigned int size;
 193 
 194         size = gb_hid_report_len(report);
 195         if (gb_hid_get_report(ghid, report->type, report->id, ghid->inbuf,
 196                               size))
 197                 return;
 198 
 199         /*
 200          * hid->driver_lock is held as we are in probe function,
 201          * we just need to setup the input fields, so using
 202          * hid_report_raw_event is safe.
 203          */
 204         hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, size, 1);
 205 }
 206 
 207 static void gb_hid_init_reports(struct gb_hid *ghid)
 208 {
 209         struct hid_device *hid = ghid->hid;
 210         struct hid_report *report;
 211 
 212         list_for_each_entry(report,
 213                             &hid->report_enum[HID_INPUT_REPORT].report_list,
 214                             list)
 215                 gb_hid_init_report(ghid, report);
 216 
 217         list_for_each_entry(report,
 218                             &hid->report_enum[HID_FEATURE_REPORT].report_list,
 219                             list)
 220                 gb_hid_init_report(ghid, report);
 221 }
 222 
 223 static int __gb_hid_get_raw_report(struct hid_device *hid,
 224                 unsigned char report_number, __u8 *buf, size_t count,
 225                 unsigned char report_type)
 226 {
 227         struct gb_hid *ghid = hid->driver_data;
 228         int ret;
 229 
 230         if (report_type == HID_OUTPUT_REPORT)
 231                 return -EINVAL;
 232 
 233         ret = gb_hid_get_report(ghid, report_type, report_number, buf, count);
 234         if (!ret)
 235                 ret = count;
 236 
 237         return ret;
 238 }
 239 
 240 static int __gb_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
 241                                       size_t len, unsigned char report_type)
 242 {
 243         struct gb_hid *ghid = hid->driver_data;
 244         int report_id = buf[0];
 245         int ret;
 246 
 247         if (report_type == HID_INPUT_REPORT)
 248                 return -EINVAL;
 249 
 250         if (report_id) {
 251                 buf++;
 252                 len--;
 253         }
 254 
 255         ret = gb_hid_set_report(ghid, report_type, report_id, buf, len);
 256         if (report_id && ret >= 0)
 257                 ret++; /* add report_id to the number of transfered bytes */
 258 
 259         return 0;
 260 }
 261 
 262 static int gb_hid_raw_request(struct hid_device *hid, unsigned char reportnum,
 263                               __u8 *buf, size_t len, unsigned char rtype,
 264                               int reqtype)
 265 {
 266         switch (reqtype) {
 267         case HID_REQ_GET_REPORT:
 268                 return __gb_hid_get_raw_report(hid, reportnum, buf, len, rtype);
 269         case HID_REQ_SET_REPORT:
 270                 if (buf[0] != reportnum)
 271                         return -EINVAL;
 272                 return __gb_hid_output_raw_report(hid, buf, len, rtype);
 273         default:
 274                 return -EIO;
 275         }
 276 }
 277 
 278 /* HID Callbacks */
 279 static int gb_hid_parse(struct hid_device *hid)
 280 {
 281         struct gb_hid *ghid = hid->driver_data;
 282         unsigned int rsize;
 283         char *rdesc;
 284         int ret;
 285 
 286         rsize = le16_to_cpu(ghid->hdesc.wReportDescLength);
 287         if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
 288                 dbg_hid("weird size of report descriptor (%u)\n", rsize);
 289                 return -EINVAL;
 290         }
 291 
 292         rdesc = kzalloc(rsize, GFP_KERNEL);
 293         if (!rdesc) {
 294                 return -ENOMEM;
 295         }
 296 
 297         ret = gb_hid_get_report_desc(ghid, rdesc);
 298         if (ret) {
 299                 hid_err(hid, "reading report descriptor failed\n");
 300                 goto free_rdesc;
 301         }
 302 
 303         ret = hid_parse_report(hid, rdesc, rsize);
 304         if (ret)
 305                 dbg_hid("parsing report descriptor failed\n");
 306 
 307 free_rdesc:
 308         kfree(rdesc);
 309 
 310         return ret;
 311 }
 312 
 313 static int gb_hid_start(struct hid_device *hid)
 314 {
 315         struct gb_hid *ghid = hid->driver_data;
 316         unsigned int bufsize = HID_MIN_BUFFER_SIZE;
 317         int ret;
 318 
 319         gb_hid_find_max_report(hid, HID_INPUT_REPORT, &bufsize);
 320         gb_hid_find_max_report(hid, HID_OUTPUT_REPORT, &bufsize);
 321         gb_hid_find_max_report(hid, HID_FEATURE_REPORT, &bufsize);
 322 
 323         if (bufsize > HID_MAX_BUFFER_SIZE)
 324                 bufsize = HID_MAX_BUFFER_SIZE;
 325 
 326         ret = gb_hid_alloc_buffers(ghid, bufsize);
 327         if (ret)
 328                 return ret;
 329 
 330         if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
 331                 gb_hid_init_reports(ghid);
 332 
 333         return 0;
 334 }
 335 
 336 static void gb_hid_stop(struct hid_device *hid)
 337 {
 338         struct gb_hid *ghid = hid->driver_data;
 339 
 340         gb_hid_free_buffers(ghid);
 341 }
 342 
 343 static int gb_hid_open(struct hid_device *hid)
 344 {
 345         struct gb_hid *ghid = hid->driver_data;
 346         int ret;
 347 
 348         ret = gb_hid_set_power(ghid, GB_HID_TYPE_PWR_ON);
 349         if (ret < 0)
 350                 return ret;
 351 
 352         set_bit(GB_HID_STARTED, &ghid->flags);
 353         return 0;
 354 }
 355 
 356 static void gb_hid_close(struct hid_device *hid)
 357 {
 358         struct gb_hid *ghid = hid->driver_data;
 359         int ret;
 360 
 361         clear_bit(GB_HID_STARTED, &ghid->flags);
 362 
 363         /* Save some power */
 364         ret = gb_hid_set_power(ghid, GB_HID_TYPE_PWR_OFF);
 365         if (ret)
 366                 dev_err(&ghid->connection->bundle->dev,
 367                         "failed to power off (%d)\n", ret);
 368 }
 369 
 370 static int gb_hid_power(struct hid_device *hid, int lvl)
 371 {
 372         struct gb_hid *ghid = hid->driver_data;
 373 
 374         switch (lvl) {
 375         case PM_HINT_FULLON:
 376                 return gb_hid_set_power(ghid, GB_HID_TYPE_PWR_ON);
 377         case PM_HINT_NORMAL:
 378                 return gb_hid_set_power(ghid, GB_HID_TYPE_PWR_OFF);
 379         }
 380 
 381         return 0;
 382 }
 383 
 384 /* HID structure to pass callbacks */
 385 static struct hid_ll_driver gb_hid_ll_driver = {
 386         .parse = gb_hid_parse,
 387         .start = gb_hid_start,
 388         .stop = gb_hid_stop,
 389         .open = gb_hid_open,
 390         .close = gb_hid_close,
 391         .power = gb_hid_power,
 392         .raw_request = gb_hid_raw_request,
 393 };
 394 
 395 static int gb_hid_init(struct gb_hid *ghid)
 396 {
 397         struct hid_device *hid = ghid->hid;
 398         int ret;
 399 
 400         ret = gb_hid_get_desc(ghid);
 401         if (ret)
 402                 return ret;
 403 
 404         hid->version = le16_to_cpu(ghid->hdesc.bcdHID);
 405         hid->vendor = le16_to_cpu(ghid->hdesc.wVendorID);
 406         hid->product = le16_to_cpu(ghid->hdesc.wProductID);
 407         hid->country = ghid->hdesc.bCountryCode;
 408 
 409         hid->driver_data = ghid;
 410         hid->ll_driver = &gb_hid_ll_driver;
 411         hid->dev.parent = &ghid->connection->bundle->dev;
 412 //      hid->bus = BUS_GREYBUS; /* Need a bustype for GREYBUS in <linux/input.h> */
 413 
 414         /* Set HID device's name */
 415         snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X",
 416                  dev_name(&ghid->connection->bundle->dev),
 417                  hid->vendor, hid->product);
 418 
 419         return 0;
 420 }
 421 
 422 static int gb_hid_probe(struct gb_bundle *bundle,
 423                         const struct greybus_bundle_id *id)
 424 {
 425         struct greybus_descriptor_cport *cport_desc;
 426         struct gb_connection *connection;
 427         struct hid_device *hid;
 428         struct gb_hid *ghid;
 429         int ret;
 430 
 431         if (bundle->num_cports != 1)
 432                 return -ENODEV;
 433 
 434         cport_desc = &bundle->cport_desc[0];
 435         if (cport_desc->protocol_id != GREYBUS_PROTOCOL_HID)
 436                 return -ENODEV;
 437 
 438         ghid = kzalloc(sizeof(*ghid), GFP_KERNEL);
 439         if (!ghid)
 440                 return -ENOMEM;
 441 
 442         connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
 443                                           gb_hid_request_handler);
 444         if (IS_ERR(connection)) {
 445                 ret = PTR_ERR(connection);
 446                 goto err_free_ghid;
 447         }
 448 
 449         gb_connection_set_data(connection, ghid);
 450         ghid->connection = connection;
 451 
 452         hid = hid_allocate_device();
 453         if (IS_ERR(hid)) {
 454                 ret = PTR_ERR(hid);
 455                 goto err_connection_destroy;
 456         }
 457 
 458         ghid->hid = hid;
 459         ghid->bundle = bundle;
 460 
 461         greybus_set_drvdata(bundle, ghid);
 462 
 463         ret = gb_connection_enable(connection);
 464         if (ret)
 465                 goto err_destroy_hid;
 466 
 467         ret = gb_hid_init(ghid);
 468         if (ret)
 469                 goto err_connection_disable;
 470 
 471         ret = hid_add_device(hid);
 472         if (ret) {
 473                 hid_err(hid, "can't add hid device: %d\n", ret);
 474                 goto err_connection_disable;
 475         }
 476 
 477         gb_pm_runtime_put_autosuspend(bundle);
 478 
 479         return 0;
 480 
 481 err_connection_disable:
 482         gb_connection_disable(connection);
 483 err_destroy_hid:
 484         hid_destroy_device(hid);
 485 err_connection_destroy:
 486         gb_connection_destroy(connection);
 487 err_free_ghid:
 488         kfree(ghid);
 489 
 490         return ret;
 491 }
 492 
 493 static void gb_hid_disconnect(struct gb_bundle *bundle)
 494 {
 495         struct gb_hid *ghid = greybus_get_drvdata(bundle);
 496 
 497         if (gb_pm_runtime_get_sync(bundle))
 498                 gb_pm_runtime_get_noresume(bundle);
 499 
 500         hid_destroy_device(ghid->hid);
 501         gb_connection_disable(ghid->connection);
 502         gb_connection_destroy(ghid->connection);
 503         kfree(ghid);
 504 }
 505 
 506 static const struct greybus_bundle_id gb_hid_id_table[] = {
 507         { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_HID) },
 508         { }
 509 };
 510 MODULE_DEVICE_TABLE(greybus, gb_hid_id_table);
 511 
 512 static struct greybus_driver gb_hid_driver = {
 513         .name           = "hid",
 514         .probe          = gb_hid_probe,
 515         .disconnect     = gb_hid_disconnect,
 516         .id_table       = gb_hid_id_table,
 517 };
 518 module_greybus_driver(gb_hid_driver);
 519 
 520 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */