at v6.13 1343 lines 33 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Greybus Lights protocol driver. 4 * 5 * Copyright 2015 Google Inc. 6 * Copyright 2015 Linaro Ltd. 7 */ 8 9#include <linux/kernel.h> 10#include <linux/leds.h> 11#include <linux/led-class-flash.h> 12#include <linux/module.h> 13#include <linux/slab.h> 14#include <linux/greybus.h> 15#include <media/v4l2-flash-led-class.h> 16 17#define NAMES_MAX 32 18 19struct gb_channel { 20 u8 id; 21 u32 flags; 22 u32 color; 23 char *color_name; 24 u8 fade_in; 25 u8 fade_out; 26 u32 mode; 27 char *mode_name; 28 struct attribute **attrs; 29 struct attribute_group *attr_group; 30 const struct attribute_group **attr_groups; 31 struct led_classdev *led; 32 struct led_classdev_flash fled; 33 struct led_flash_setting intensity_uA; 34 struct led_flash_setting timeout_us; 35 struct gb_light *light; 36 bool is_registered; 37 bool releasing; 38 bool strobe_state; 39 bool active; 40 struct mutex lock; 41}; 42 43struct gb_light { 44 u8 id; 45 char *name; 46 struct gb_lights *glights; 47 u32 flags; 48 u8 channels_count; 49 struct gb_channel *channels; 50 bool has_flash; 51 bool ready; 52#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS) 53 struct v4l2_flash *v4l2_flash; 54 struct v4l2_flash *v4l2_flash_ind; 55#endif 56}; 57 58struct gb_lights { 59 struct gb_connection *connection; 60 u8 lights_count; 61 struct gb_light *lights; 62 struct mutex lights_lock; 63}; 64 65static void gb_lights_channel_free(struct gb_channel *channel); 66 67static struct gb_connection *get_conn_from_channel(struct gb_channel *channel) 68{ 69 return channel->light->glights->connection; 70} 71 72static struct gb_connection *get_conn_from_light(struct gb_light *light) 73{ 74 return light->glights->connection; 75} 76 77static bool is_channel_flash(struct gb_channel *channel) 78{ 79 return !!(channel->mode & (GB_CHANNEL_MODE_FLASH | GB_CHANNEL_MODE_TORCH 80 | GB_CHANNEL_MODE_INDICATOR)); 81} 82 83static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev) 84{ 85 struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev); 86 87 return container_of(fled_cdev, struct gb_channel, fled); 88} 89 90static struct led_classdev *get_channel_cdev(struct gb_channel *channel) 91{ 92 return &channel->fled.led_cdev; 93} 94 95static struct gb_channel *get_channel_from_mode(struct gb_light *light, 96 u32 mode) 97{ 98 struct gb_channel *channel; 99 int i; 100 101 for (i = 0; i < light->channels_count; i++) { 102 channel = &light->channels[i]; 103 if (channel->mode == mode) 104 return channel; 105 } 106 return NULL; 107} 108 109static int __gb_lights_flash_intensity_set(struct gb_channel *channel, 110 u32 intensity) 111{ 112 struct gb_connection *connection = get_conn_from_channel(channel); 113 struct gb_bundle *bundle = connection->bundle; 114 struct gb_lights_set_flash_intensity_request req; 115 int ret; 116 117 if (channel->releasing) 118 return -ESHUTDOWN; 119 120 ret = gb_pm_runtime_get_sync(bundle); 121 if (ret < 0) 122 return ret; 123 124 req.light_id = channel->light->id; 125 req.channel_id = channel->id; 126 req.intensity_uA = cpu_to_le32(intensity); 127 128 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_INTENSITY, 129 &req, sizeof(req), NULL, 0); 130 131 gb_pm_runtime_put_autosuspend(bundle); 132 133 return ret; 134} 135 136static int __gb_lights_flash_brightness_set(struct gb_channel *channel) 137{ 138 u32 intensity; 139 140 /* If the channel is flash we need to get the attached torch channel */ 141 if (channel->mode & GB_CHANNEL_MODE_FLASH) 142 channel = get_channel_from_mode(channel->light, 143 GB_CHANNEL_MODE_TORCH); 144 145 if (!channel) 146 return -EINVAL; 147 148 /* For not flash we need to convert brightness to intensity */ 149 intensity = channel->intensity_uA.min + 150 (channel->intensity_uA.step * channel->led->brightness); 151 152 return __gb_lights_flash_intensity_set(channel, intensity); 153} 154 155static int gb_lights_color_set(struct gb_channel *channel, u32 color); 156static int gb_lights_fade_set(struct gb_channel *channel); 157 158static void led_lock(struct led_classdev *cdev) 159{ 160 mutex_lock(&cdev->led_access); 161} 162 163static void led_unlock(struct led_classdev *cdev) 164{ 165 mutex_unlock(&cdev->led_access); 166} 167 168#define gb_lights_fade_attr(__dir) \ 169static ssize_t fade_##__dir##_show(struct device *dev, \ 170 struct device_attribute *attr, \ 171 char *buf) \ 172{ \ 173 struct led_classdev *cdev = dev_get_drvdata(dev); \ 174 struct gb_channel *channel = get_channel_from_cdev(cdev); \ 175 \ 176 return sprintf(buf, "%u\n", channel->fade_##__dir); \ 177} \ 178 \ 179static ssize_t fade_##__dir##_store(struct device *dev, \ 180 struct device_attribute *attr, \ 181 const char *buf, size_t size) \ 182{ \ 183 struct led_classdev *cdev = dev_get_drvdata(dev); \ 184 struct gb_channel *channel = get_channel_from_cdev(cdev); \ 185 u8 fade; \ 186 int ret; \ 187 \ 188 led_lock(cdev); \ 189 if (led_sysfs_is_disabled(cdev)) { \ 190 ret = -EBUSY; \ 191 goto unlock; \ 192 } \ 193 \ 194 ret = kstrtou8(buf, 0, &fade); \ 195 if (ret < 0) { \ 196 dev_err(dev, "could not parse fade value %d\n", ret); \ 197 goto unlock; \ 198 } \ 199 if (channel->fade_##__dir == fade) \ 200 goto unlock; \ 201 channel->fade_##__dir = fade; \ 202 \ 203 ret = gb_lights_fade_set(channel); \ 204 if (ret < 0) \ 205 goto unlock; \ 206 \ 207 ret = size; \ 208unlock: \ 209 led_unlock(cdev); \ 210 return ret; \ 211} \ 212static DEVICE_ATTR_RW(fade_##__dir) 213 214gb_lights_fade_attr(in); 215gb_lights_fade_attr(out); 216 217static ssize_t color_show(struct device *dev, struct device_attribute *attr, 218 char *buf) 219{ 220 struct led_classdev *cdev = dev_get_drvdata(dev); 221 struct gb_channel *channel = get_channel_from_cdev(cdev); 222 223 return sprintf(buf, "0x%08x\n", channel->color); 224} 225 226static ssize_t color_store(struct device *dev, struct device_attribute *attr, 227 const char *buf, size_t size) 228{ 229 struct led_classdev *cdev = dev_get_drvdata(dev); 230 struct gb_channel *channel = get_channel_from_cdev(cdev); 231 u32 color; 232 int ret; 233 234 led_lock(cdev); 235 if (led_sysfs_is_disabled(cdev)) { 236 ret = -EBUSY; 237 goto unlock; 238 } 239 ret = kstrtou32(buf, 0, &color); 240 if (ret < 0) { 241 dev_err(dev, "could not parse color value %d\n", ret); 242 goto unlock; 243 } 244 245 ret = gb_lights_color_set(channel, color); 246 if (ret < 0) 247 goto unlock; 248 249 channel->color = color; 250 ret = size; 251unlock: 252 led_unlock(cdev); 253 return ret; 254} 255static DEVICE_ATTR_RW(color); 256 257static int channel_attr_groups_set(struct gb_channel *channel, 258 struct led_classdev *cdev) 259{ 260 int attr = 0; 261 int size = 0; 262 263 if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR) 264 size++; 265 if (channel->flags & GB_LIGHT_CHANNEL_FADER) 266 size += 2; 267 268 if (!size) 269 return 0; 270 271 /* Set attributes based in the channel flags */ 272 channel->attrs = kcalloc(size + 1, sizeof(*channel->attrs), GFP_KERNEL); 273 if (!channel->attrs) 274 return -ENOMEM; 275 channel->attr_group = kzalloc(sizeof(*channel->attr_group), GFP_KERNEL); 276 if (!channel->attr_group) 277 return -ENOMEM; 278 channel->attr_groups = kcalloc(2, sizeof(*channel->attr_groups), 279 GFP_KERNEL); 280 if (!channel->attr_groups) 281 return -ENOMEM; 282 283 if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR) 284 channel->attrs[attr++] = &dev_attr_color.attr; 285 if (channel->flags & GB_LIGHT_CHANNEL_FADER) { 286 channel->attrs[attr++] = &dev_attr_fade_in.attr; 287 channel->attrs[attr++] = &dev_attr_fade_out.attr; 288 } 289 290 channel->attr_group->attrs = channel->attrs; 291 292 channel->attr_groups[0] = channel->attr_group; 293 294 cdev->groups = channel->attr_groups; 295 296 return 0; 297} 298 299static int gb_lights_fade_set(struct gb_channel *channel) 300{ 301 struct gb_connection *connection = get_conn_from_channel(channel); 302 struct gb_bundle *bundle = connection->bundle; 303 struct gb_lights_set_fade_request req; 304 int ret; 305 306 if (channel->releasing) 307 return -ESHUTDOWN; 308 309 ret = gb_pm_runtime_get_sync(bundle); 310 if (ret < 0) 311 return ret; 312 313 req.light_id = channel->light->id; 314 req.channel_id = channel->id; 315 req.fade_in = channel->fade_in; 316 req.fade_out = channel->fade_out; 317 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FADE, 318 &req, sizeof(req), NULL, 0); 319 320 gb_pm_runtime_put_autosuspend(bundle); 321 322 return ret; 323} 324 325static int gb_lights_color_set(struct gb_channel *channel, u32 color) 326{ 327 struct gb_connection *connection = get_conn_from_channel(channel); 328 struct gb_bundle *bundle = connection->bundle; 329 struct gb_lights_set_color_request req; 330 int ret; 331 332 if (channel->releasing) 333 return -ESHUTDOWN; 334 335 ret = gb_pm_runtime_get_sync(bundle); 336 if (ret < 0) 337 return ret; 338 339 req.light_id = channel->light->id; 340 req.channel_id = channel->id; 341 req.color = cpu_to_le32(color); 342 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_COLOR, 343 &req, sizeof(req), NULL, 0); 344 345 gb_pm_runtime_put_autosuspend(bundle); 346 347 return ret; 348} 349 350static int __gb_lights_led_brightness_set(struct gb_channel *channel) 351{ 352 struct gb_lights_set_brightness_request req; 353 struct gb_connection *connection = get_conn_from_channel(channel); 354 struct gb_bundle *bundle = connection->bundle; 355 bool old_active; 356 int ret; 357 358 mutex_lock(&channel->lock); 359 ret = gb_pm_runtime_get_sync(bundle); 360 if (ret < 0) 361 goto out_unlock; 362 363 old_active = channel->active; 364 365 req.light_id = channel->light->id; 366 req.channel_id = channel->id; 367 req.brightness = (u8)channel->led->brightness; 368 369 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BRIGHTNESS, 370 &req, sizeof(req), NULL, 0); 371 if (ret < 0) 372 goto out_pm_put; 373 374 if (channel->led->brightness) 375 channel->active = true; 376 else 377 channel->active = false; 378 379 /* we need to keep module alive when turning to active state */ 380 if (!old_active && channel->active) 381 goto out_unlock; 382 383 /* 384 * on the other hand if going to inactive we still hold a reference and 385 * need to put it, so we could go to suspend. 386 */ 387 if (old_active && !channel->active) 388 gb_pm_runtime_put_autosuspend(bundle); 389 390out_pm_put: 391 gb_pm_runtime_put_autosuspend(bundle); 392out_unlock: 393 mutex_unlock(&channel->lock); 394 395 return ret; 396} 397 398static int __gb_lights_brightness_set(struct gb_channel *channel) 399{ 400 int ret; 401 402 if (channel->releasing) 403 return 0; 404 405 if (is_channel_flash(channel)) 406 ret = __gb_lights_flash_brightness_set(channel); 407 else 408 ret = __gb_lights_led_brightness_set(channel); 409 410 return ret; 411} 412 413static int gb_brightness_set(struct led_classdev *cdev, 414 enum led_brightness value) 415{ 416 struct gb_channel *channel = get_channel_from_cdev(cdev); 417 418 channel->led->brightness = value; 419 420 return __gb_lights_brightness_set(channel); 421} 422 423static enum led_brightness gb_brightness_get(struct led_classdev *cdev) 424 425{ 426 struct gb_channel *channel = get_channel_from_cdev(cdev); 427 428 return channel->led->brightness; 429} 430 431static int gb_blink_set(struct led_classdev *cdev, unsigned long *delay_on, 432 unsigned long *delay_off) 433{ 434 struct gb_channel *channel = get_channel_from_cdev(cdev); 435 struct gb_connection *connection = get_conn_from_channel(channel); 436 struct gb_bundle *bundle = connection->bundle; 437 struct gb_lights_blink_request req; 438 bool old_active; 439 int ret; 440 441 if (channel->releasing) 442 return -ESHUTDOWN; 443 444 if (!delay_on || !delay_off) 445 return -EINVAL; 446 447 mutex_lock(&channel->lock); 448 ret = gb_pm_runtime_get_sync(bundle); 449 if (ret < 0) 450 goto out_unlock; 451 452 old_active = channel->active; 453 454 req.light_id = channel->light->id; 455 req.channel_id = channel->id; 456 req.time_on_ms = cpu_to_le16(*delay_on); 457 req.time_off_ms = cpu_to_le16(*delay_off); 458 459 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BLINK, &req, 460 sizeof(req), NULL, 0); 461 if (ret < 0) 462 goto out_pm_put; 463 464 if (*delay_on) 465 channel->active = true; 466 else 467 channel->active = false; 468 469 /* we need to keep module alive when turning to active state */ 470 if (!old_active && channel->active) 471 goto out_unlock; 472 473 /* 474 * on the other hand if going to inactive we still hold a reference and 475 * need to put it, so we could go to suspend. 476 */ 477 if (old_active && !channel->active) 478 gb_pm_runtime_put_autosuspend(bundle); 479 480out_pm_put: 481 gb_pm_runtime_put_autosuspend(bundle); 482out_unlock: 483 mutex_unlock(&channel->lock); 484 485 return ret; 486} 487 488static void gb_lights_led_operations_set(struct gb_channel *channel, 489 struct led_classdev *cdev) 490{ 491 cdev->brightness_get = gb_brightness_get; 492 cdev->brightness_set_blocking = gb_brightness_set; 493 494 if (channel->flags & GB_LIGHT_CHANNEL_BLINK) 495 cdev->blink_set = gb_blink_set; 496} 497 498#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS) 499/* V4L2 specific helpers */ 500static const struct v4l2_flash_ops v4l2_flash_ops; 501 502static void __gb_lights_channel_v4l2_config(struct led_flash_setting *channel_s, 503 struct led_flash_setting *v4l2_s) 504{ 505 v4l2_s->min = channel_s->min; 506 v4l2_s->max = channel_s->max; 507 v4l2_s->step = channel_s->step; 508 /* For v4l2 val is the default value */ 509 v4l2_s->val = channel_s->max; 510} 511 512static int gb_lights_light_v4l2_register(struct gb_light *light) 513{ 514 struct gb_connection *connection = get_conn_from_light(light); 515 struct device *dev = &connection->bundle->dev; 516 struct v4l2_flash_config sd_cfg = { {0} }, sd_cfg_ind = { {0} }; 517 struct led_classdev_flash *fled; 518 struct led_classdev *iled = NULL; 519 struct gb_channel *channel_torch, *channel_ind, *channel_flash; 520 521 channel_torch = get_channel_from_mode(light, GB_CHANNEL_MODE_TORCH); 522 if (channel_torch) 523 __gb_lights_channel_v4l2_config(&channel_torch->intensity_uA, 524 &sd_cfg.intensity); 525 526 channel_ind = get_channel_from_mode(light, GB_CHANNEL_MODE_INDICATOR); 527 if (channel_ind) { 528 __gb_lights_channel_v4l2_config(&channel_ind->intensity_uA, 529 &sd_cfg_ind.intensity); 530 iled = &channel_ind->fled.led_cdev; 531 } 532 533 channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH); 534 if (!channel_flash) { 535 dev_err(dev, "failed to get flash channel from mode\n"); 536 return -EINVAL; 537 } 538 539 fled = &channel_flash->fled; 540 541 snprintf(sd_cfg.dev_name, sizeof(sd_cfg.dev_name), "%s", light->name); 542 snprintf(sd_cfg_ind.dev_name, sizeof(sd_cfg_ind.dev_name), 543 "%s indicator", light->name); 544 545 /* Set the possible values to faults, in our case all faults */ 546 sd_cfg.flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT | 547 LED_FAULT_OVER_TEMPERATURE | LED_FAULT_SHORT_CIRCUIT | 548 LED_FAULT_OVER_CURRENT | LED_FAULT_INDICATOR | 549 LED_FAULT_UNDER_VOLTAGE | LED_FAULT_INPUT_VOLTAGE | 550 LED_FAULT_LED_OVER_TEMPERATURE; 551 552 light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, &v4l2_flash_ops, 553 &sd_cfg); 554 if (IS_ERR(light->v4l2_flash)) 555 return PTR_ERR(light->v4l2_flash); 556 557 if (channel_ind) { 558 light->v4l2_flash_ind = 559 v4l2_flash_indicator_init(dev, NULL, iled, &sd_cfg_ind); 560 if (IS_ERR(light->v4l2_flash_ind)) { 561 v4l2_flash_release(light->v4l2_flash); 562 return PTR_ERR(light->v4l2_flash_ind); 563 } 564 } 565 566 return 0; 567} 568 569static void gb_lights_light_v4l2_unregister(struct gb_light *light) 570{ 571 v4l2_flash_release(light->v4l2_flash_ind); 572 v4l2_flash_release(light->v4l2_flash); 573} 574#else 575static int gb_lights_light_v4l2_register(struct gb_light *light) 576{ 577 struct gb_connection *connection = get_conn_from_light(light); 578 579 dev_err(&connection->bundle->dev, "no support for v4l2 subdevices\n"); 580 return 0; 581} 582 583static void gb_lights_light_v4l2_unregister(struct gb_light *light) 584{ 585} 586#endif 587 588#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH) 589/* Flash specific operations */ 590static int gb_lights_flash_intensity_set(struct led_classdev_flash *fcdev, 591 u32 brightness) 592{ 593 struct gb_channel *channel = container_of(fcdev, struct gb_channel, 594 fled); 595 int ret; 596 597 ret = __gb_lights_flash_intensity_set(channel, brightness); 598 if (ret < 0) 599 return ret; 600 601 fcdev->brightness.val = brightness; 602 603 return 0; 604} 605 606static int gb_lights_flash_intensity_get(struct led_classdev_flash *fcdev, 607 u32 *brightness) 608{ 609 *brightness = fcdev->brightness.val; 610 611 return 0; 612} 613 614static int gb_lights_flash_strobe_set(struct led_classdev_flash *fcdev, 615 bool state) 616{ 617 struct gb_channel *channel = container_of(fcdev, struct gb_channel, 618 fled); 619 struct gb_connection *connection = get_conn_from_channel(channel); 620 struct gb_bundle *bundle = connection->bundle; 621 struct gb_lights_set_flash_strobe_request req; 622 int ret; 623 624 if (channel->releasing) 625 return -ESHUTDOWN; 626 627 ret = gb_pm_runtime_get_sync(bundle); 628 if (ret < 0) 629 return ret; 630 631 req.light_id = channel->light->id; 632 req.channel_id = channel->id; 633 req.state = state ? 1 : 0; 634 635 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_STROBE, 636 &req, sizeof(req), NULL, 0); 637 if (!ret) 638 channel->strobe_state = state; 639 640 gb_pm_runtime_put_autosuspend(bundle); 641 642 return ret; 643} 644 645static int gb_lights_flash_strobe_get(struct led_classdev_flash *fcdev, 646 bool *state) 647{ 648 struct gb_channel *channel = container_of(fcdev, struct gb_channel, 649 fled); 650 651 *state = channel->strobe_state; 652 return 0; 653} 654 655static int gb_lights_flash_timeout_set(struct led_classdev_flash *fcdev, 656 u32 timeout) 657{ 658 struct gb_channel *channel = container_of(fcdev, struct gb_channel, 659 fled); 660 struct gb_connection *connection = get_conn_from_channel(channel); 661 struct gb_bundle *bundle = connection->bundle; 662 struct gb_lights_set_flash_timeout_request req; 663 int ret; 664 665 if (channel->releasing) 666 return -ESHUTDOWN; 667 668 ret = gb_pm_runtime_get_sync(bundle); 669 if (ret < 0) 670 return ret; 671 672 req.light_id = channel->light->id; 673 req.channel_id = channel->id; 674 req.timeout_us = cpu_to_le32(timeout); 675 676 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_TIMEOUT, 677 &req, sizeof(req), NULL, 0); 678 if (!ret) 679 fcdev->timeout.val = timeout; 680 681 gb_pm_runtime_put_autosuspend(bundle); 682 683 return ret; 684} 685 686static int gb_lights_flash_fault_get(struct led_classdev_flash *fcdev, 687 u32 *fault) 688{ 689 struct gb_channel *channel = container_of(fcdev, struct gb_channel, 690 fled); 691 struct gb_connection *connection = get_conn_from_channel(channel); 692 struct gb_bundle *bundle = connection->bundle; 693 struct gb_lights_get_flash_fault_request req; 694 struct gb_lights_get_flash_fault_response resp; 695 int ret; 696 697 if (channel->releasing) 698 return -ESHUTDOWN; 699 700 ret = gb_pm_runtime_get_sync(bundle); 701 if (ret < 0) 702 return ret; 703 704 req.light_id = channel->light->id; 705 req.channel_id = channel->id; 706 707 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_FLASH_FAULT, 708 &req, sizeof(req), &resp, sizeof(resp)); 709 if (!ret) 710 *fault = le32_to_cpu(resp.fault); 711 712 gb_pm_runtime_put_autosuspend(bundle); 713 714 return ret; 715} 716 717static const struct led_flash_ops gb_lights_flash_ops = { 718 .flash_brightness_set = gb_lights_flash_intensity_set, 719 .flash_brightness_get = gb_lights_flash_intensity_get, 720 .strobe_set = gb_lights_flash_strobe_set, 721 .strobe_get = gb_lights_flash_strobe_get, 722 .timeout_set = gb_lights_flash_timeout_set, 723 .fault_get = gb_lights_flash_fault_get, 724}; 725 726static int __gb_lights_channel_torch_attach(struct gb_channel *channel, 727 struct gb_channel *channel_torch) 728{ 729 char *name; 730 731 /* we can only attach torch to a flash channel */ 732 if (!(channel->mode & GB_CHANNEL_MODE_FLASH)) 733 return 0; 734 735 /* Move torch brightness to the destination */ 736 channel->led->max_brightness = channel_torch->led->max_brightness; 737 738 /* append mode name to flash name */ 739 name = kasprintf(GFP_KERNEL, "%s_%s", channel->led->name, 740 channel_torch->mode_name); 741 if (!name) 742 return -ENOMEM; 743 kfree(channel->led->name); 744 channel->led->name = name; 745 746 channel_torch->led = channel->led; 747 748 return 0; 749} 750 751static int __gb_lights_flash_led_register(struct gb_channel *channel) 752{ 753 struct gb_connection *connection = get_conn_from_channel(channel); 754 struct led_classdev_flash *fled = &channel->fled; 755 struct led_flash_setting *fset; 756 struct gb_channel *channel_torch; 757 int ret; 758 759 fled->ops = &gb_lights_flash_ops; 760 761 fled->led_cdev.flags |= LED_DEV_CAP_FLASH; 762 763 fset = &fled->brightness; 764 fset->min = channel->intensity_uA.min; 765 fset->max = channel->intensity_uA.max; 766 fset->step = channel->intensity_uA.step; 767 fset->val = channel->intensity_uA.max; 768 769 /* Only the flash mode have the timeout constraints settings */ 770 if (channel->mode & GB_CHANNEL_MODE_FLASH) { 771 fset = &fled->timeout; 772 fset->min = channel->timeout_us.min; 773 fset->max = channel->timeout_us.max; 774 fset->step = channel->timeout_us.step; 775 fset->val = channel->timeout_us.max; 776 } 777 778 /* 779 * If light have torch mode channel, this channel will be the led 780 * classdev of the registered above flash classdev 781 */ 782 channel_torch = get_channel_from_mode(channel->light, 783 GB_CHANNEL_MODE_TORCH); 784 if (channel_torch) { 785 ret = __gb_lights_channel_torch_attach(channel, channel_torch); 786 if (ret < 0) 787 goto fail; 788 } 789 790 ret = led_classdev_flash_register(&connection->bundle->dev, fled); 791 if (ret < 0) 792 goto fail; 793 794 channel->is_registered = true; 795 return 0; 796fail: 797 channel->led = NULL; 798 return ret; 799} 800 801static void __gb_lights_flash_led_unregister(struct gb_channel *channel) 802{ 803 if (!channel->is_registered) 804 return; 805 806 led_classdev_flash_unregister(&channel->fled); 807} 808 809static int gb_lights_channel_flash_config(struct gb_channel *channel) 810{ 811 struct gb_connection *connection = get_conn_from_channel(channel); 812 struct gb_lights_get_channel_flash_config_request req; 813 struct gb_lights_get_channel_flash_config_response conf; 814 struct led_flash_setting *fset; 815 int ret; 816 817 req.light_id = channel->light->id; 818 req.channel_id = channel->id; 819 820 ret = gb_operation_sync(connection, 821 GB_LIGHTS_TYPE_GET_CHANNEL_FLASH_CONFIG, 822 &req, sizeof(req), &conf, sizeof(conf)); 823 if (ret < 0) 824 return ret; 825 826 /* 827 * Intensity constraints for flash related modes: flash, torch, 828 * indicator. They will be needed for v4l2 registration. 829 */ 830 fset = &channel->intensity_uA; 831 fset->min = le32_to_cpu(conf.intensity_min_uA); 832 fset->max = le32_to_cpu(conf.intensity_max_uA); 833 fset->step = le32_to_cpu(conf.intensity_step_uA); 834 835 /* 836 * On flash type, max brightness is set as the number of intensity steps 837 * available. 838 */ 839 channel->led->max_brightness = (fset->max - fset->min) / fset->step; 840 841 /* Only the flash mode have the timeout constraints settings */ 842 if (channel->mode & GB_CHANNEL_MODE_FLASH) { 843 fset = &channel->timeout_us; 844 fset->min = le32_to_cpu(conf.timeout_min_us); 845 fset->max = le32_to_cpu(conf.timeout_max_us); 846 fset->step = le32_to_cpu(conf.timeout_step_us); 847 } 848 849 return 0; 850} 851#else 852static int gb_lights_channel_flash_config(struct gb_channel *channel) 853{ 854 struct gb_connection *connection = get_conn_from_channel(channel); 855 856 dev_err(&connection->bundle->dev, "no support for flash devices\n"); 857 return 0; 858} 859 860static int __gb_lights_flash_led_register(struct gb_channel *channel) 861{ 862 return 0; 863} 864 865static void __gb_lights_flash_led_unregister(struct gb_channel *channel) 866{ 867} 868 869#endif 870 871static int __gb_lights_led_register(struct gb_channel *channel) 872{ 873 struct gb_connection *connection = get_conn_from_channel(channel); 874 struct led_classdev *cdev = get_channel_cdev(channel); 875 int ret; 876 877 ret = led_classdev_register(&connection->bundle->dev, cdev); 878 if (ret < 0) 879 channel->led = NULL; 880 else 881 channel->is_registered = true; 882 return ret; 883} 884 885static int gb_lights_channel_register(struct gb_channel *channel) 886{ 887 /* Normal LED channel, just register in led classdev and we are done */ 888 if (!is_channel_flash(channel)) 889 return __gb_lights_led_register(channel); 890 891 /* 892 * Flash Type need more work, register flash classdev, indicator as 893 * flash classdev, torch will be led classdev of the flash classdev. 894 */ 895 if (!(channel->mode & GB_CHANNEL_MODE_TORCH)) 896 return __gb_lights_flash_led_register(channel); 897 898 return 0; 899} 900 901static void __gb_lights_led_unregister(struct gb_channel *channel) 902{ 903 struct led_classdev *cdev = get_channel_cdev(channel); 904 905 if (!channel->is_registered) 906 return; 907 908 led_classdev_unregister(cdev); 909 kfree(cdev->name); 910 cdev->name = NULL; 911 channel->led = NULL; 912} 913 914static void gb_lights_channel_unregister(struct gb_channel *channel) 915{ 916 /* The same as register, handle channels differently */ 917 if (!is_channel_flash(channel)) { 918 __gb_lights_led_unregister(channel); 919 return; 920 } 921 922 if (channel->mode & GB_CHANNEL_MODE_TORCH) 923 __gb_lights_led_unregister(channel); 924 else 925 __gb_lights_flash_led_unregister(channel); 926} 927 928static int gb_lights_channel_config(struct gb_light *light, 929 struct gb_channel *channel) 930{ 931 struct gb_lights_get_channel_config_response conf; 932 struct gb_lights_get_channel_config_request req; 933 struct gb_connection *connection = get_conn_from_light(light); 934 struct led_classdev *cdev = get_channel_cdev(channel); 935 char *name; 936 int ret; 937 938 req.light_id = light->id; 939 req.channel_id = channel->id; 940 941 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG, 942 &req, sizeof(req), &conf, sizeof(conf)); 943 if (ret < 0) 944 return ret; 945 946 channel->light = light; 947 channel->mode = le32_to_cpu(conf.mode); 948 channel->flags = le32_to_cpu(conf.flags); 949 channel->color = le32_to_cpu(conf.color); 950 channel->color_name = kstrndup(conf.color_name, NAMES_MAX, GFP_KERNEL); 951 if (!channel->color_name) 952 return -ENOMEM; 953 channel->mode_name = kstrndup(conf.mode_name, NAMES_MAX, GFP_KERNEL); 954 if (!channel->mode_name) 955 return -ENOMEM; 956 957 channel->led = cdev; 958 959 name = kasprintf(GFP_KERNEL, "%s:%s:%s", light->name, 960 channel->color_name, channel->mode_name); 961 if (!name) 962 return -ENOMEM; 963 964 cdev->name = name; 965 966 cdev->max_brightness = conf.max_brightness; 967 968 ret = channel_attr_groups_set(channel, cdev); 969 if (ret < 0) 970 return ret; 971 972 gb_lights_led_operations_set(channel, cdev); 973 974 /* 975 * If it is not a flash related channel (flash, torch or indicator) we 976 * are done here. If not, continue and fetch flash related 977 * configurations. 978 */ 979 if (!is_channel_flash(channel)) 980 return ret; 981 982 light->has_flash = true; 983 984 return gb_lights_channel_flash_config(channel); 985} 986 987static int gb_lights_light_config(struct gb_lights *glights, u8 id) 988{ 989 struct gb_light *light = &glights->lights[id]; 990 struct gb_lights_get_light_config_request req; 991 struct gb_lights_get_light_config_response conf; 992 int ret; 993 int i; 994 995 light->glights = glights; 996 light->id = id; 997 998 req.id = id; 999 1000 ret = gb_operation_sync(glights->connection, 1001 GB_LIGHTS_TYPE_GET_LIGHT_CONFIG, 1002 &req, sizeof(req), &conf, sizeof(conf)); 1003 if (ret < 0) 1004 return ret; 1005 1006 if (!conf.channel_count) 1007 return -EINVAL; 1008 if (!strlen(conf.name)) 1009 return -EINVAL; 1010 1011 light->channels_count = conf.channel_count; 1012 light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL); 1013 if (!light->name) 1014 return -ENOMEM; 1015 light->channels = kcalloc(light->channels_count, 1016 sizeof(struct gb_channel), GFP_KERNEL); 1017 if (!light->channels) 1018 return -ENOMEM; 1019 1020 /* First we collect all the configurations for all channels */ 1021 for (i = 0; i < light->channels_count; i++) { 1022 light->channels[i].id = i; 1023 ret = gb_lights_channel_config(light, &light->channels[i]); 1024 if (ret < 0) 1025 return ret; 1026 } 1027 1028 return 0; 1029} 1030 1031static int gb_lights_light_register(struct gb_light *light) 1032{ 1033 int ret; 1034 int i; 1035 1036 /* 1037 * Then, if everything went ok in getting configurations, we register 1038 * the classdev, flash classdev and v4l2 subsystem, if a flash device is 1039 * found. 1040 */ 1041 for (i = 0; i < light->channels_count; i++) { 1042 ret = gb_lights_channel_register(&light->channels[i]); 1043 if (ret < 0) 1044 return ret; 1045 1046 mutex_init(&light->channels[i].lock); 1047 } 1048 1049 light->ready = true; 1050 1051 if (light->has_flash) { 1052 ret = gb_lights_light_v4l2_register(light); 1053 if (ret < 0) { 1054 light->has_flash = false; 1055 return ret; 1056 } 1057 } 1058 1059 return 0; 1060} 1061 1062static void gb_lights_channel_free(struct gb_channel *channel) 1063{ 1064 kfree(channel->attrs); 1065 kfree(channel->attr_group); 1066 kfree(channel->attr_groups); 1067 kfree(channel->color_name); 1068 kfree(channel->mode_name); 1069 mutex_destroy(&channel->lock); 1070} 1071 1072static void gb_lights_channel_release(struct gb_channel *channel) 1073{ 1074 channel->releasing = true; 1075 1076 gb_lights_channel_unregister(channel); 1077 1078 gb_lights_channel_free(channel); 1079} 1080 1081static void gb_lights_light_release(struct gb_light *light) 1082{ 1083 int i; 1084 1085 light->ready = false; 1086 1087 if (light->has_flash) 1088 gb_lights_light_v4l2_unregister(light); 1089 light->has_flash = false; 1090 1091 for (i = 0; i < light->channels_count; i++) 1092 gb_lights_channel_release(&light->channels[i]); 1093 light->channels_count = 0; 1094 1095 kfree(light->channels); 1096 light->channels = NULL; 1097 kfree(light->name); 1098 light->name = NULL; 1099} 1100 1101static void gb_lights_release(struct gb_lights *glights) 1102{ 1103 int i; 1104 1105 if (!glights) 1106 return; 1107 1108 mutex_lock(&glights->lights_lock); 1109 if (!glights->lights) 1110 goto free_glights; 1111 1112 for (i = 0; i < glights->lights_count; i++) 1113 gb_lights_light_release(&glights->lights[i]); 1114 1115 kfree(glights->lights); 1116 1117free_glights: 1118 mutex_unlock(&glights->lights_lock); 1119 mutex_destroy(&glights->lights_lock); 1120 kfree(glights); 1121} 1122 1123static int gb_lights_get_count(struct gb_lights *glights) 1124{ 1125 struct gb_lights_get_lights_response resp; 1126 int ret; 1127 1128 ret = gb_operation_sync(glights->connection, GB_LIGHTS_TYPE_GET_LIGHTS, 1129 NULL, 0, &resp, sizeof(resp)); 1130 if (ret < 0) 1131 return ret; 1132 1133 if (!resp.lights_count) 1134 return -EINVAL; 1135 1136 glights->lights_count = resp.lights_count; 1137 1138 return 0; 1139} 1140 1141static int gb_lights_create_all(struct gb_lights *glights) 1142{ 1143 struct gb_connection *connection = glights->connection; 1144 int ret; 1145 int i; 1146 1147 mutex_lock(&glights->lights_lock); 1148 ret = gb_lights_get_count(glights); 1149 if (ret < 0) 1150 goto out; 1151 1152 glights->lights = kcalloc(glights->lights_count, 1153 sizeof(struct gb_light), GFP_KERNEL); 1154 if (!glights->lights) { 1155 ret = -ENOMEM; 1156 goto out; 1157 } 1158 1159 for (i = 0; i < glights->lights_count; i++) { 1160 ret = gb_lights_light_config(glights, i); 1161 if (ret < 0) { 1162 dev_err(&connection->bundle->dev, 1163 "Fail to configure lights device\n"); 1164 goto out; 1165 } 1166 } 1167 1168out: 1169 mutex_unlock(&glights->lights_lock); 1170 return ret; 1171} 1172 1173static int gb_lights_register_all(struct gb_lights *glights) 1174{ 1175 struct gb_connection *connection = glights->connection; 1176 int ret = 0; 1177 int i; 1178 1179 mutex_lock(&glights->lights_lock); 1180 for (i = 0; i < glights->lights_count; i++) { 1181 ret = gb_lights_light_register(&glights->lights[i]); 1182 if (ret < 0) { 1183 dev_err(&connection->bundle->dev, 1184 "Fail to enable lights device\n"); 1185 break; 1186 } 1187 } 1188 1189 mutex_unlock(&glights->lights_lock); 1190 return ret; 1191} 1192 1193static int gb_lights_request_handler(struct gb_operation *op) 1194{ 1195 struct gb_connection *connection = op->connection; 1196 struct device *dev = &connection->bundle->dev; 1197 struct gb_lights *glights = gb_connection_get_data(connection); 1198 struct gb_light *light; 1199 struct gb_message *request; 1200 struct gb_lights_event_request *payload; 1201 int ret = 0; 1202 u8 light_id; 1203 u8 event; 1204 1205 if (op->type != GB_LIGHTS_TYPE_EVENT) { 1206 dev_err(dev, "Unsupported unsolicited event: %u\n", op->type); 1207 return -EINVAL; 1208 } 1209 1210 request = op->request; 1211 1212 if (request->payload_size < sizeof(*payload)) { 1213 dev_err(dev, "Wrong event size received (%zu < %zu)\n", 1214 request->payload_size, sizeof(*payload)); 1215 return -EINVAL; 1216 } 1217 1218 payload = request->payload; 1219 light_id = payload->light_id; 1220 1221 if (light_id >= glights->lights_count || 1222 !glights->lights[light_id].ready) { 1223 dev_err(dev, "Event received for unconfigured light id: %d\n", 1224 light_id); 1225 return -EINVAL; 1226 } 1227 1228 event = payload->event; 1229 1230 if (event & GB_LIGHTS_LIGHT_CONFIG) { 1231 light = &glights->lights[light_id]; 1232 1233 mutex_lock(&glights->lights_lock); 1234 gb_lights_light_release(light); 1235 ret = gb_lights_light_config(glights, light_id); 1236 if (!ret) 1237 ret = gb_lights_light_register(light); 1238 if (ret < 0) 1239 gb_lights_light_release(light); 1240 mutex_unlock(&glights->lights_lock); 1241 } 1242 1243 return ret; 1244} 1245 1246static int gb_lights_probe(struct gb_bundle *bundle, 1247 const struct greybus_bundle_id *id) 1248{ 1249 struct greybus_descriptor_cport *cport_desc; 1250 struct gb_connection *connection; 1251 struct gb_lights *glights; 1252 int ret; 1253 1254 if (bundle->num_cports != 1) 1255 return -ENODEV; 1256 1257 cport_desc = &bundle->cport_desc[0]; 1258 if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LIGHTS) 1259 return -ENODEV; 1260 1261 glights = kzalloc(sizeof(*glights), GFP_KERNEL); 1262 if (!glights) 1263 return -ENOMEM; 1264 1265 mutex_init(&glights->lights_lock); 1266 1267 connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id), 1268 gb_lights_request_handler); 1269 if (IS_ERR(connection)) { 1270 ret = PTR_ERR(connection); 1271 goto out; 1272 } 1273 1274 glights->connection = connection; 1275 gb_connection_set_data(connection, glights); 1276 1277 greybus_set_drvdata(bundle, glights); 1278 1279 /* We aren't ready to receive an incoming request yet */ 1280 ret = gb_connection_enable_tx(connection); 1281 if (ret) 1282 goto error_connection_destroy; 1283 1284 /* 1285 * Setup all the lights devices over this connection, if anything goes 1286 * wrong tear down all lights 1287 */ 1288 ret = gb_lights_create_all(glights); 1289 if (ret < 0) 1290 goto error_connection_disable; 1291 1292 /* We are ready to receive an incoming request now, enable RX as well */ 1293 ret = gb_connection_enable(connection); 1294 if (ret) 1295 goto error_connection_disable; 1296 1297 /* Enable & register lights */ 1298 ret = gb_lights_register_all(glights); 1299 if (ret < 0) 1300 goto error_connection_disable; 1301 1302 gb_pm_runtime_put_autosuspend(bundle); 1303 1304 return 0; 1305 1306error_connection_disable: 1307 gb_connection_disable(connection); 1308error_connection_destroy: 1309 gb_connection_destroy(connection); 1310out: 1311 gb_lights_release(glights); 1312 return ret; 1313} 1314 1315static void gb_lights_disconnect(struct gb_bundle *bundle) 1316{ 1317 struct gb_lights *glights = greybus_get_drvdata(bundle); 1318 1319 if (gb_pm_runtime_get_sync(bundle)) 1320 gb_pm_runtime_get_noresume(bundle); 1321 1322 gb_connection_disable(glights->connection); 1323 gb_connection_destroy(glights->connection); 1324 1325 gb_lights_release(glights); 1326} 1327 1328static const struct greybus_bundle_id gb_lights_id_table[] = { 1329 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) }, 1330 { } 1331}; 1332MODULE_DEVICE_TABLE(greybus, gb_lights_id_table); 1333 1334static struct greybus_driver gb_lights_driver = { 1335 .name = "lights", 1336 .probe = gb_lights_probe, 1337 .disconnect = gb_lights_disconnect, 1338 .id_table = gb_lights_id_table, 1339}; 1340module_greybus_driver(gb_lights_driver); 1341 1342MODULE_DESCRIPTION("Greybus Lights protocol driver"); 1343MODULE_LICENSE("GPL v2");