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