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