1 // SPDX-License-Identifier: GPL-2.0+ 2 // Expose the Chromebook Pixel lightbar to userspace 3 // 4 // Copyright (C) 2014 Google, Inc. 5 6 #include <linux/ctype.h> 7 #include <linux/delay.h> 8 #include <linux/device.h> 9 #include <linux/fs.h> 10 #include <linux/kobject.h> 11 #include <linux/kstrtox.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/platform_data/cros_ec_commands.h> 15 #include <linux/platform_data/cros_ec_proto.h> 16 #include <linux/platform_device.h> 17 #include <linux/sched.h> 18 #include <linux/types.h> 19 #include <linux/uaccess.h> 20 #include <linux/slab.h> 21 22 #define DRV_NAME "cros-ec-lightbar" 23 24 /* Rate-limit the lightbar interface to prevent DoS. */ 25 static unsigned long lb_interval_jiffies = 50 * HZ / 1000; 26 27 /* 28 * Whether or not we have given userspace control of the lightbar. 29 * If this is true, we won't do anything during suspend/resume. 30 */ 31 static bool userspace_control; 32 33 /* 34 * Whether or not the lightbar supports the manual suspend commands. 35 * The Pixel 2013 (Link) does not while all other devices with a 36 * lightbar do. 37 */ 38 static bool has_manual_suspend; 39 40 static ssize_t interval_msec_show(struct device *dev, 41 struct device_attribute *attr, char *buf) 42 { 43 unsigned long msec = lb_interval_jiffies * 1000 / HZ; 44 45 return sysfs_emit(buf, "%lu\n", msec); 46 } 47 48 static ssize_t interval_msec_store(struct device *dev, 49 struct device_attribute *attr, 50 const char *buf, size_t count) 51 { 52 unsigned long msec; 53 54 if (kstrtoul(buf, 0, &msec)) 55 return -EINVAL; 56 57 lb_interval_jiffies = msec * HZ / 1000; 58 59 return count; 60 } 61 62 static DEFINE_MUTEX(lb_mutex); 63 /* Return 0 if able to throttle correctly, error otherwise */ 64 static int lb_throttle(void) 65 { 66 static unsigned long last_access; 67 unsigned long now, next_timeslot; 68 long delay; 69 int ret = 0; 70 71 mutex_lock(&lb_mutex); 72 73 now = jiffies; 74 next_timeslot = last_access + lb_interval_jiffies; 75 76 if (time_before(now, next_timeslot)) { 77 delay = (long)(next_timeslot) - (long)now; 78 set_current_state(TASK_INTERRUPTIBLE); 79 if (schedule_timeout(delay) > 0) { 80 /* interrupted - just abort */ 81 ret = -EINTR; 82 goto out; 83 } 84 now = jiffies; 85 } 86 87 last_access = now; 88 out: 89 mutex_unlock(&lb_mutex); 90 91 return ret; 92 } 93 94 static struct cros_ec_command *alloc_lightbar_cmd_msg(struct cros_ec_dev *ec) 95 { 96 struct cros_ec_command *msg; 97 int len; 98 99 len = max(sizeof(struct ec_params_lightbar), 100 sizeof(struct ec_response_lightbar)); 101 102 msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL); 103 if (!msg) 104 return NULL; 105 106 msg->version = 0; 107 msg->command = EC_CMD_LIGHTBAR_CMD + ec->cmd_offset; 108 msg->outsize = sizeof(struct ec_params_lightbar); 109 msg->insize = sizeof(struct ec_response_lightbar); 110 111 return msg; 112 } 113 114 static int get_lightbar_version(struct cros_ec_dev *ec, 115 uint32_t *ver_ptr, uint32_t *flg_ptr) 116 { 117 struct ec_params_lightbar *param; 118 struct ec_response_lightbar *resp; 119 struct cros_ec_command *msg; 120 int ret; 121 122 msg = alloc_lightbar_cmd_msg(ec); 123 if (!msg) 124 return 0; 125 126 param = (struct ec_params_lightbar *)msg->data; 127 param->cmd = LIGHTBAR_CMD_VERSION; 128 msg->outsize = sizeof(param->cmd); 129 msg->result = sizeof(resp->version); 130 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 131 if (ret < 0 && ret != -EINVAL) { 132 ret = 0; 133 goto exit; 134 } 135 136 switch (msg->result) { 137 case EC_RES_INVALID_PARAM: 138 /* Pixel had no version command. */ 139 if (ver_ptr) 140 *ver_ptr = 0; 141 if (flg_ptr) 142 *flg_ptr = 0; 143 ret = 1; 144 goto exit; 145 146 case EC_RES_SUCCESS: 147 resp = (struct ec_response_lightbar *)msg->data; 148 149 /* Future devices w/lightbars should implement this command */ 150 if (ver_ptr) 151 *ver_ptr = resp->version.num; 152 if (flg_ptr) 153 *flg_ptr = resp->version.flags; 154 ret = 1; 155 goto exit; 156 } 157 158 /* Anything else (ie, EC_RES_INVALID_COMMAND) - no lightbar */ 159 ret = 0; 160 exit: 161 kfree(msg); 162 return ret; 163 } 164 165 static ssize_t version_show(struct device *dev, 166 struct device_attribute *attr, char *buf) 167 { 168 uint32_t version = 0, flags = 0; 169 struct cros_ec_dev *ec = to_cros_ec_dev(dev); 170 int ret; 171 172 ret = lb_throttle(); 173 if (ret) 174 return ret; 175 176 /* This should always succeed, because we check during init. */ 177 if (!get_lightbar_version(ec, &version, &flags)) 178 return -EIO; 179 180 return sysfs_emit(buf, "%d %d\n", version, flags); 181 } 182 183 static ssize_t brightness_store(struct device *dev, 184 struct device_attribute *attr, 185 const char *buf, size_t count) 186 { 187 struct ec_params_lightbar *param; 188 struct cros_ec_command *msg; 189 int ret; 190 unsigned int val; 191 struct cros_ec_dev *ec = to_cros_ec_dev(dev); 192 193 if (kstrtouint(buf, 0, &val)) 194 return -EINVAL; 195 196 msg = alloc_lightbar_cmd_msg(ec); 197 if (!msg) 198 return -ENOMEM; 199 200 param = (struct ec_params_lightbar *)msg->data; 201 param->cmd = LIGHTBAR_CMD_SET_BRIGHTNESS; 202 param->set_brightness.num = val; 203 ret = lb_throttle(); 204 if (ret) 205 goto exit; 206 207 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 208 if (ret < 0) 209 goto exit; 210 211 ret = count; 212 exit: 213 kfree(msg); 214 return ret; 215 } 216 217 218 /* 219 * We expect numbers, and we'll keep reading until we find them, skipping over 220 * any whitespace (sysfs guarantees that the input is null-terminated). Every 221 * four numbers are sent to the lightbar as <LED,R,G,B>. We fail at the first 222 * parsing error, if we don't parse any numbers, or if we have numbers left 223 * over. 224 */ 225 static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr, 226 const char *buf, size_t count) 227 { 228 struct ec_params_lightbar *param; 229 struct cros_ec_command *msg; 230 struct cros_ec_dev *ec = to_cros_ec_dev(dev); 231 unsigned int val[4]; 232 int ret, i = 0, j = 0, ok = 0; 233 234 msg = alloc_lightbar_cmd_msg(ec); 235 if (!msg) 236 return -ENOMEM; 237 238 do { 239 /* Skip any whitespace */ 240 while (*buf && isspace(*buf)) 241 buf++; 242 243 if (!*buf) 244 break; 245 246 ret = sscanf(buf, "%i", &val[i++]); 247 if (ret == 0) 248 goto exit; 249 250 if (i == 4) { 251 param = (struct ec_params_lightbar *)msg->data; 252 param->cmd = LIGHTBAR_CMD_SET_RGB; 253 param->set_rgb.led = val[0]; 254 param->set_rgb.red = val[1]; 255 param->set_rgb.green = val[2]; 256 param->set_rgb.blue = val[3]; 257 /* 258 * Throttle only the first of every four transactions, 259 * so that the user can update all four LEDs at once. 260 */ 261 if ((j++ % 4) == 0) { 262 ret = lb_throttle(); 263 if (ret) 264 goto exit; 265 } 266 267 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 268 if (ret < 0) 269 goto exit; 270 271 i = 0; 272 ok = 1; 273 } 274 275 /* Skip over the number we just read */ 276 while (*buf && !isspace(*buf)) 277 buf++; 278 279 } while (*buf); 280 281 exit: 282 kfree(msg); 283 return (ok && i == 0) ? count : -EINVAL; 284 } 285 286 static char const *seqname[] = { 287 "ERROR", "S5", "S3", "S0", "S5S3", "S3S0", 288 "S0S3", "S3S5", "STOP", "RUN", "KONAMI", 289 "TAP", "PROGRAM", 290 }; 291 292 static ssize_t sequence_show(struct device *dev, 293 struct device_attribute *attr, char *buf) 294 { 295 struct ec_params_lightbar *param; 296 struct ec_response_lightbar *resp; 297 struct cros_ec_command *msg; 298 int ret; 299 struct cros_ec_dev *ec = to_cros_ec_dev(dev); 300 301 msg = alloc_lightbar_cmd_msg(ec); 302 if (!msg) 303 return -ENOMEM; 304 305 param = (struct ec_params_lightbar *)msg->data; 306 param->cmd = LIGHTBAR_CMD_GET_SEQ; 307 ret = lb_throttle(); 308 if (ret) 309 goto exit; 310 311 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 312 if (ret < 0) { 313 ret = sysfs_emit(buf, "XFER / EC ERROR %d / %d\n", ret, msg->result); 314 goto exit; 315 } 316 317 resp = (struct ec_response_lightbar *)msg->data; 318 if (resp->get_seq.num >= ARRAY_SIZE(seqname)) 319 ret = sysfs_emit(buf, "%d\n", resp->get_seq.num); 320 else 321 ret = sysfs_emit(buf, "%s\n", seqname[resp->get_seq.num]); 322 323 exit: 324 kfree(msg); 325 return ret; 326 } 327 328 static int lb_send_empty_cmd(struct cros_ec_dev *ec, uint8_t cmd) 329 { 330 struct ec_params_lightbar *param; 331 struct cros_ec_command *msg; 332 int ret; 333 334 msg = alloc_lightbar_cmd_msg(ec); 335 if (!msg) 336 return -ENOMEM; 337 338 param = (struct ec_params_lightbar *)msg->data; 339 param->cmd = cmd; 340 341 ret = lb_throttle(); 342 if (ret) 343 goto error; 344 345 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 346 if (ret < 0) 347 goto error; 348 349 ret = 0; 350 error: 351 kfree(msg); 352 353 return ret; 354 } 355 356 static int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable) 357 { 358 struct ec_params_lightbar *param; 359 struct cros_ec_command *msg; 360 int ret; 361 362 msg = alloc_lightbar_cmd_msg(ec); 363 if (!msg) 364 return -ENOMEM; 365 366 param = (struct ec_params_lightbar *)msg->data; 367 368 param->cmd = LIGHTBAR_CMD_MANUAL_SUSPEND_CTRL; 369 param->manual_suspend_ctrl.enable = enable; 370 371 ret = lb_throttle(); 372 if (ret) 373 goto error; 374 375 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 376 if (ret < 0) 377 goto error; 378 379 ret = 0; 380 error: 381 kfree(msg); 382 383 return ret; 384 } 385 386 static ssize_t sequence_store(struct device *dev, struct device_attribute *attr, 387 const char *buf, size_t count) 388 { 389 struct ec_params_lightbar *param; 390 struct cros_ec_command *msg; 391 unsigned int num; 392 int ret, len; 393 struct cros_ec_dev *ec = to_cros_ec_dev(dev); 394 395 for (len = 0; len < count; len++) 396 if (!isalnum(buf[len])) 397 break; 398 399 for (num = 0; num < ARRAY_SIZE(seqname); num++) 400 if (!strncasecmp(seqname[num], buf, len)) 401 break; 402 403 if (num >= ARRAY_SIZE(seqname)) { 404 ret = kstrtouint(buf, 0, &num); 405 if (ret) 406 return ret; 407 } 408 409 msg = alloc_lightbar_cmd_msg(ec); 410 if (!msg) 411 return -ENOMEM; 412 413 param = (struct ec_params_lightbar *)msg->data; 414 param->cmd = LIGHTBAR_CMD_SEQ; 415 param->seq.num = num; 416 ret = lb_throttle(); 417 if (ret) 418 goto exit; 419 420 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 421 if (ret < 0) 422 goto exit; 423 424 ret = count; 425 exit: 426 kfree(msg); 427 return ret; 428 } 429 430 static ssize_t program_store(struct device *dev, struct device_attribute *attr, 431 const char *buf, size_t count) 432 { 433 int extra_bytes, max_size, ret; 434 struct ec_params_lightbar *param; 435 struct cros_ec_command *msg; 436 struct cros_ec_dev *ec = to_cros_ec_dev(dev); 437 438 /* 439 * We might need to reject the program for size reasons. The EC 440 * enforces a maximum program size, but we also don't want to try 441 * and send a program that is too big for the protocol. In order 442 * to ensure the latter, we also need to ensure we have extra bytes 443 * to represent the rest of the packet. 444 */ 445 extra_bytes = sizeof(*param) - sizeof(param->set_program.data); 446 max_size = min(EC_LB_PROG_LEN, ec->ec_dev->max_request - extra_bytes); 447 if (count > max_size) { 448 dev_err(dev, "Program is %u bytes, too long to send (max: %u)", 449 (unsigned int)count, max_size); 450 451 return -EINVAL; 452 } 453 454 msg = alloc_lightbar_cmd_msg(ec); 455 if (!msg) 456 return -ENOMEM; 457 458 ret = lb_throttle(); 459 if (ret) 460 goto exit; 461 462 dev_info(dev, "Copying %zu byte program to EC", count); 463 464 param = (struct ec_params_lightbar *)msg->data; 465 param->cmd = LIGHTBAR_CMD_SET_PROGRAM; 466 467 param->set_program.size = count; 468 memcpy(param->set_program.data, buf, count); 469 470 /* 471 * We need to set the message size manually or else it will use 472 * EC_LB_PROG_LEN. This might be too long, and the program 473 * is unlikely to use all of the space. 474 */ 475 msg->outsize = count + extra_bytes; 476 477 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 478 if (ret < 0) 479 goto exit; 480 481 ret = count; 482 exit: 483 kfree(msg); 484 485 return ret; 486 } 487 488 static ssize_t userspace_control_show(struct device *dev, 489 struct device_attribute *attr, 490 char *buf) 491 { 492 return sysfs_emit(buf, "%d\n", userspace_control); 493 } 494 495 static ssize_t userspace_control_store(struct device *dev, 496 struct device_attribute *attr, 497 const char *buf, 498 size_t count) 499 { 500 bool enable; 501 int ret; 502 503 ret = kstrtobool(buf, &enable); 504 if (ret < 0) 505 return ret; 506 507 userspace_control = enable; 508 509 return count; 510 } 511 512 /* Module initialization */ 513 514 static DEVICE_ATTR_RW(interval_msec); 515 static DEVICE_ATTR_RO(version); 516 static DEVICE_ATTR_WO(brightness); 517 static DEVICE_ATTR_WO(led_rgb); 518 static DEVICE_ATTR_RW(sequence); 519 static DEVICE_ATTR_WO(program); 520 static DEVICE_ATTR_RW(userspace_control); 521 522 static struct attribute *__lb_cmds_attrs[] = { 523 &dev_attr_interval_msec.attr, 524 &dev_attr_version.attr, 525 &dev_attr_brightness.attr, 526 &dev_attr_led_rgb.attr, 527 &dev_attr_sequence.attr, 528 &dev_attr_program.attr, 529 &dev_attr_userspace_control.attr, 530 NULL, 531 }; 532 533 static const struct attribute_group cros_ec_lightbar_attr_group = { 534 .name = "lightbar", 535 .attrs = __lb_cmds_attrs, 536 }; 537 538 static int cros_ec_lightbar_probe(struct platform_device *pd) 539 { 540 struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); 541 struct cros_ec_platform *pdata = dev_get_platdata(ec_dev->dev); 542 struct device *dev = &pd->dev; 543 int ret; 544 545 /* 546 * Only instantiate the lightbar if the EC name is 'cros_ec'. Other EC 547 * devices like 'cros_pd' doesn't have a lightbar. 548 */ 549 if (strcmp(pdata->ec_name, CROS_EC_DEV_NAME) != 0) 550 return -ENODEV; 551 552 /* 553 * Ask then for the lightbar version, if it's 0 then the 'cros_ec' 554 * doesn't have a lightbar. 555 */ 556 if (!get_lightbar_version(ec_dev, NULL, NULL)) 557 return -ENODEV; 558 559 /* Take control of the lightbar from the EC. */ 560 has_manual_suspend = (lb_manual_suspend_ctrl(ec_dev, 1) != -EINVAL); 561 562 ret = sysfs_create_group(&ec_dev->class_dev.kobj, 563 &cros_ec_lightbar_attr_group); 564 if (ret < 0) 565 dev_err(dev, "failed to create %s attributes. err=%d\n", 566 cros_ec_lightbar_attr_group.name, ret); 567 568 return ret; 569 } 570 571 static void cros_ec_lightbar_remove(struct platform_device *pd) 572 { 573 struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); 574 575 sysfs_remove_group(&ec_dev->class_dev.kobj, 576 &cros_ec_lightbar_attr_group); 577 578 /* Let the EC take over the lightbar again. */ 579 if (has_manual_suspend) 580 lb_manual_suspend_ctrl(ec_dev, 0); 581 } 582 583 static int __maybe_unused cros_ec_lightbar_resume(struct device *dev) 584 { 585 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); 586 587 if (userspace_control || !has_manual_suspend) 588 return 0; 589 590 return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_RESUME); 591 } 592 593 static int __maybe_unused cros_ec_lightbar_suspend(struct device *dev) 594 { 595 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); 596 597 if (userspace_control || !has_manual_suspend) 598 return 0; 599 600 return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_SUSPEND); 601 } 602 603 static SIMPLE_DEV_PM_OPS(cros_ec_lightbar_pm_ops, 604 cros_ec_lightbar_suspend, cros_ec_lightbar_resume); 605 606 static const struct platform_device_id cros_ec_lightbar_id[] = { 607 { DRV_NAME, 0 }, 608 {} 609 }; 610 MODULE_DEVICE_TABLE(platform, cros_ec_lightbar_id); 611 612 static struct platform_driver cros_ec_lightbar_driver = { 613 .driver = { 614 .name = DRV_NAME, 615 .pm = &cros_ec_lightbar_pm_ops, 616 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 617 }, 618 .probe = cros_ec_lightbar_probe, 619 .remove = cros_ec_lightbar_remove, 620 .id_table = cros_ec_lightbar_id, 621 }; 622 623 module_platform_driver(cros_ec_lightbar_driver); 624 625 MODULE_LICENSE("GPL"); 626 MODULE_DESCRIPTION("Expose the Chromebook Pixel's lightbar to userspace"); 627