1/* 2 * leds-lm3533.c -- LM3533 LED driver 3 * 4 * Copyright (C) 2011-2012 Texas Instruments 5 * 6 * Author: Johan Hovold <jhovold@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14#include <linux/module.h> 15#include <linux/leds.h> 16#include <linux/mfd/core.h> 17#include <linux/mutex.h> 18#include <linux/platform_device.h> 19#include <linux/slab.h> 20#include <linux/workqueue.h> 21 22#include <linux/mfd/lm3533.h> 23 24 25#define LM3533_LVCTRLBANK_MIN 2 26#define LM3533_LVCTRLBANK_MAX 5 27#define LM3533_LVCTRLBANK_COUNT 4 28#define LM3533_RISEFALLTIME_MAX 7 29#define LM3533_ALS_CHANNEL_LV_MIN 1 30#define LM3533_ALS_CHANNEL_LV_MAX 2 31 32#define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b 33#define LM3533_REG_PATTERN_ENABLE 0x28 34#define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71 35#define LM3533_REG_PATTERN_HIGH_TIME_BASE 0x72 36#define LM3533_REG_PATTERN_RISETIME_BASE 0x74 37#define LM3533_REG_PATTERN_FALLTIME_BASE 0x75 38 39#define LM3533_REG_PATTERN_STEP 0x10 40 41#define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK 0x04 42#define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK 0x02 43#define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK 0x01 44 45#define LM3533_LED_FLAG_PATTERN_ENABLE 1 46 47 48struct lm3533_led { 49 struct lm3533 *lm3533; 50 struct lm3533_ctrlbank cb; 51 struct led_classdev cdev; 52 int id; 53 54 struct mutex mutex; 55 unsigned long flags; 56 57 struct work_struct work; 58 u8 new_brightness; 59}; 60 61 62static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev) 63{ 64 return container_of(cdev, struct lm3533_led, cdev); 65} 66 67static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led) 68{ 69 return led->id + 2; 70} 71 72static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base) 73{ 74 return base + led->id; 75} 76 77static inline u8 lm3533_led_get_pattern(struct lm3533_led *led) 78{ 79 return led->id; 80} 81 82static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led, 83 u8 base) 84{ 85 return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP; 86} 87 88static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable) 89{ 90 u8 mask; 91 u8 val; 92 int pattern; 93 int state; 94 int ret = 0; 95 96 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable); 97 98 mutex_lock(&led->mutex); 99 100 state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags); 101 if ((enable && state) || (!enable && !state)) 102 goto out; 103 104 pattern = lm3533_led_get_pattern(led); 105 mask = 1 << (2 * pattern); 106 107 if (enable) 108 val = mask; 109 else 110 val = 0; 111 112 ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask); 113 if (ret) { 114 dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n", 115 pattern, enable); 116 goto out; 117 } 118 119 __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags); 120out: 121 mutex_unlock(&led->mutex); 122 123 return ret; 124} 125 126static void lm3533_led_work(struct work_struct *work) 127{ 128 struct lm3533_led *led = container_of(work, struct lm3533_led, work); 129 130 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, led->new_brightness); 131 132 if (led->new_brightness == 0) 133 lm3533_led_pattern_enable(led, 0); /* disable blink */ 134 135 lm3533_ctrlbank_set_brightness(&led->cb, led->new_brightness); 136} 137 138static void lm3533_led_set(struct led_classdev *cdev, 139 enum led_brightness value) 140{ 141 struct lm3533_led *led = to_lm3533_led(cdev); 142 143 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value); 144 145 led->new_brightness = value; 146 schedule_work(&led->work); 147} 148 149static enum led_brightness lm3533_led_get(struct led_classdev *cdev) 150{ 151 struct lm3533_led *led = to_lm3533_led(cdev); 152 u8 val; 153 int ret; 154 155 ret = lm3533_ctrlbank_get_brightness(&led->cb, &val); 156 if (ret) 157 return ret; 158 159 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val); 160 161 return val; 162} 163 164/* Pattern generator defines (delays in us). */ 165#define LM3533_LED_DELAY1_VMIN 0x00 166#define LM3533_LED_DELAY2_VMIN 0x3d 167#define LM3533_LED_DELAY3_VMIN 0x80 168 169#define LM3533_LED_DELAY1_VMAX (LM3533_LED_DELAY2_VMIN - 1) 170#define LM3533_LED_DELAY2_VMAX (LM3533_LED_DELAY3_VMIN - 1) 171#define LM3533_LED_DELAY3_VMAX 0xff 172 173#define LM3533_LED_DELAY1_TMIN 16384U 174#define LM3533_LED_DELAY2_TMIN 1130496U 175#define LM3533_LED_DELAY3_TMIN 10305536U 176 177#define LM3533_LED_DELAY1_TMAX 999424U 178#define LM3533_LED_DELAY2_TMAX 9781248U 179#define LM3533_LED_DELAY3_TMAX 76890112U 180 181/* t_step = (t_max - t_min) / (v_max - v_min) */ 182#define LM3533_LED_DELAY1_TSTEP 16384 183#define LM3533_LED_DELAY2_TSTEP 131072 184#define LM3533_LED_DELAY3_TSTEP 524288 185 186/* Delay limits for hardware accelerated blinking (in ms). */ 187#define LM3533_LED_DELAY_ON_MAX \ 188 ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000) 189#define LM3533_LED_DELAY_OFF_MAX \ 190 ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000) 191 192/* 193 * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step 194 * size of t_step, where 195 * 196 * t_step = (t_max - t_min) / (v_max - v_min) 197 * 198 * and updates *t to reflect the mapped value. 199 */ 200static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step, 201 u8 v_min, u8 v_max) 202{ 203 unsigned val; 204 205 val = (*t + t_step / 2 - t_min) / t_step + v_min; 206 207 *t = t_step * (val - v_min) + t_min; 208 209 return (u8)val; 210} 211 212/* 213 * Returns time code corresponding to *delay (in ms) and updates *delay to 214 * reflect actual hardware delay. 215 * 216 * Hardware supports 256 discrete delay times, divided into three groups with 217 * the following ranges and step-sizes: 218 * 219 * [ 16, 999] [0x00, 0x3e] step 16 ms 220 * [ 1130, 9781] [0x3d, 0x7f] step 131 ms 221 * [10306, 76890] [0x80, 0xff] step 524 ms 222 * 223 * Note that delay group 3 is only available for delay_off. 224 */ 225static u8 lm3533_led_get_hw_delay(unsigned *delay) 226{ 227 unsigned t; 228 u8 val; 229 230 t = *delay * 1000; 231 232 if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) { 233 t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX); 234 val = time_to_val(&t, LM3533_LED_DELAY3_TMIN, 235 LM3533_LED_DELAY3_TSTEP, 236 LM3533_LED_DELAY3_VMIN, 237 LM3533_LED_DELAY3_VMAX); 238 } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) { 239 t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX); 240 val = time_to_val(&t, LM3533_LED_DELAY2_TMIN, 241 LM3533_LED_DELAY2_TSTEP, 242 LM3533_LED_DELAY2_VMIN, 243 LM3533_LED_DELAY2_VMAX); 244 } else { 245 t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX); 246 val = time_to_val(&t, LM3533_LED_DELAY1_TMIN, 247 LM3533_LED_DELAY1_TSTEP, 248 LM3533_LED_DELAY1_VMIN, 249 LM3533_LED_DELAY1_VMAX); 250 } 251 252 *delay = (t + 500) / 1000; 253 254 return val; 255} 256 257/* 258 * Set delay register base to *delay (in ms) and update *delay to reflect 259 * actual hardware delay used. 260 */ 261static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base, 262 unsigned long *delay) 263{ 264 unsigned t; 265 u8 val; 266 u8 reg; 267 int ret; 268 269 t = (unsigned)*delay; 270 271 /* Delay group 3 is only available for low time (delay off). */ 272 if (base != LM3533_REG_PATTERN_LOW_TIME_BASE) 273 t = min(t, LM3533_LED_DELAY2_TMAX / 1000); 274 275 val = lm3533_led_get_hw_delay(&t); 276 277 dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__, 278 *delay, t, val); 279 reg = lm3533_led_get_pattern_reg(led, base); 280 ret = lm3533_write(led->lm3533, reg, val); 281 if (ret) 282 dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg); 283 284 *delay = t; 285 286 return ret; 287} 288 289static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t) 290{ 291 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t); 292} 293 294static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t) 295{ 296 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t); 297} 298 299static int lm3533_led_blink_set(struct led_classdev *cdev, 300 unsigned long *delay_on, 301 unsigned long *delay_off) 302{ 303 struct lm3533_led *led = to_lm3533_led(cdev); 304 int ret; 305 306 dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__, 307 *delay_on, *delay_off); 308 309 if (*delay_on > LM3533_LED_DELAY_ON_MAX || 310 *delay_off > LM3533_LED_DELAY_OFF_MAX) 311 return -EINVAL; 312 313 if (*delay_on == 0 && *delay_off == 0) { 314 *delay_on = 500; 315 *delay_off = 500; 316 } 317 318 ret = lm3533_led_delay_on_set(led, delay_on); 319 if (ret) 320 return ret; 321 322 ret = lm3533_led_delay_off_set(led, delay_off); 323 if (ret) 324 return ret; 325 326 return lm3533_led_pattern_enable(led, 1); 327} 328 329static ssize_t show_id(struct device *dev, 330 struct device_attribute *attr, char *buf) 331{ 332 struct led_classdev *led_cdev = dev_get_drvdata(dev); 333 struct lm3533_led *led = to_lm3533_led(led_cdev); 334 335 return scnprintf(buf, PAGE_SIZE, "%d\n", led->id); 336} 337 338/* 339 * Pattern generator rise/fall times: 340 * 341 * 0 - 2048 us (default) 342 * 1 - 262 ms 343 * 2 - 524 ms 344 * 3 - 1.049 s 345 * 4 - 2.097 s 346 * 5 - 4.194 s 347 * 6 - 8.389 s 348 * 7 - 16.78 s 349 */ 350static ssize_t show_risefalltime(struct device *dev, 351 struct device_attribute *attr, 352 char *buf, u8 base) 353{ 354 struct led_classdev *led_cdev = dev_get_drvdata(dev); 355 struct lm3533_led *led = to_lm3533_led(led_cdev); 356 ssize_t ret; 357 u8 reg; 358 u8 val; 359 360 reg = lm3533_led_get_pattern_reg(led, base); 361 ret = lm3533_read(led->lm3533, reg, &val); 362 if (ret) 363 return ret; 364 365 return scnprintf(buf, PAGE_SIZE, "%x\n", val); 366} 367 368static ssize_t show_risetime(struct device *dev, 369 struct device_attribute *attr, char *buf) 370{ 371 return show_risefalltime(dev, attr, buf, 372 LM3533_REG_PATTERN_RISETIME_BASE); 373} 374 375static ssize_t show_falltime(struct device *dev, 376 struct device_attribute *attr, char *buf) 377{ 378 return show_risefalltime(dev, attr, buf, 379 LM3533_REG_PATTERN_FALLTIME_BASE); 380} 381 382static ssize_t store_risefalltime(struct device *dev, 383 struct device_attribute *attr, 384 const char *buf, size_t len, u8 base) 385{ 386 struct led_classdev *led_cdev = dev_get_drvdata(dev); 387 struct lm3533_led *led = to_lm3533_led(led_cdev); 388 u8 val; 389 u8 reg; 390 int ret; 391 392 if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX) 393 return -EINVAL; 394 395 reg = lm3533_led_get_pattern_reg(led, base); 396 ret = lm3533_write(led->lm3533, reg, val); 397 if (ret) 398 return ret; 399 400 return len; 401} 402 403static ssize_t store_risetime(struct device *dev, 404 struct device_attribute *attr, 405 const char *buf, size_t len) 406{ 407 return store_risefalltime(dev, attr, buf, len, 408 LM3533_REG_PATTERN_RISETIME_BASE); 409} 410 411static ssize_t store_falltime(struct device *dev, 412 struct device_attribute *attr, 413 const char *buf, size_t len) 414{ 415 return store_risefalltime(dev, attr, buf, len, 416 LM3533_REG_PATTERN_FALLTIME_BASE); 417} 418 419static ssize_t show_als_channel(struct device *dev, 420 struct device_attribute *attr, char *buf) 421{ 422 struct led_classdev *led_cdev = dev_get_drvdata(dev); 423 struct lm3533_led *led = to_lm3533_led(led_cdev); 424 unsigned channel; 425 u8 reg; 426 u8 val; 427 int ret; 428 429 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 430 ret = lm3533_read(led->lm3533, reg, &val); 431 if (ret) 432 return ret; 433 434 channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1; 435 436 return scnprintf(buf, PAGE_SIZE, "%u\n", channel); 437} 438 439static ssize_t store_als_channel(struct device *dev, 440 struct device_attribute *attr, 441 const char *buf, size_t len) 442{ 443 struct led_classdev *led_cdev = dev_get_drvdata(dev); 444 struct lm3533_led *led = to_lm3533_led(led_cdev); 445 unsigned channel; 446 u8 reg; 447 u8 val; 448 u8 mask; 449 int ret; 450 451 if (kstrtouint(buf, 0, &channel)) 452 return -EINVAL; 453 454 if (channel < LM3533_ALS_CHANNEL_LV_MIN || 455 channel > LM3533_ALS_CHANNEL_LV_MAX) 456 return -EINVAL; 457 458 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 459 mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK; 460 val = channel - 1; 461 462 ret = lm3533_update(led->lm3533, reg, val, mask); 463 if (ret) 464 return ret; 465 466 return len; 467} 468 469static ssize_t show_als_en(struct device *dev, 470 struct device_attribute *attr, char *buf) 471{ 472 struct led_classdev *led_cdev = dev_get_drvdata(dev); 473 struct lm3533_led *led = to_lm3533_led(led_cdev); 474 bool enable; 475 u8 reg; 476 u8 val; 477 int ret; 478 479 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 480 ret = lm3533_read(led->lm3533, reg, &val); 481 if (ret) 482 return ret; 483 484 enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK; 485 486 return scnprintf(buf, PAGE_SIZE, "%d\n", enable); 487} 488 489static ssize_t store_als_en(struct device *dev, 490 struct device_attribute *attr, 491 const char *buf, size_t len) 492{ 493 struct led_classdev *led_cdev = dev_get_drvdata(dev); 494 struct lm3533_led *led = to_lm3533_led(led_cdev); 495 unsigned enable; 496 u8 reg; 497 u8 mask; 498 u8 val; 499 int ret; 500 501 if (kstrtouint(buf, 0, &enable)) 502 return -EINVAL; 503 504 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 505 mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK; 506 507 if (enable) 508 val = mask; 509 else 510 val = 0; 511 512 ret = lm3533_update(led->lm3533, reg, val, mask); 513 if (ret) 514 return ret; 515 516 return len; 517} 518 519static ssize_t show_linear(struct device *dev, 520 struct device_attribute *attr, char *buf) 521{ 522 struct led_classdev *led_cdev = dev_get_drvdata(dev); 523 struct lm3533_led *led = to_lm3533_led(led_cdev); 524 u8 reg; 525 u8 val; 526 int linear; 527 int ret; 528 529 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 530 ret = lm3533_read(led->lm3533, reg, &val); 531 if (ret) 532 return ret; 533 534 if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK) 535 linear = 1; 536 else 537 linear = 0; 538 539 return scnprintf(buf, PAGE_SIZE, "%x\n", linear); 540} 541 542static ssize_t store_linear(struct device *dev, 543 struct device_attribute *attr, 544 const char *buf, size_t len) 545{ 546 struct led_classdev *led_cdev = dev_get_drvdata(dev); 547 struct lm3533_led *led = to_lm3533_led(led_cdev); 548 unsigned long linear; 549 u8 reg; 550 u8 mask; 551 u8 val; 552 int ret; 553 554 if (kstrtoul(buf, 0, &linear)) 555 return -EINVAL; 556 557 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 558 mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK; 559 560 if (linear) 561 val = mask; 562 else 563 val = 0; 564 565 ret = lm3533_update(led->lm3533, reg, val, mask); 566 if (ret) 567 return ret; 568 569 return len; 570} 571 572static ssize_t show_pwm(struct device *dev, 573 struct device_attribute *attr, 574 char *buf) 575{ 576 struct led_classdev *led_cdev = dev_get_drvdata(dev); 577 struct lm3533_led *led = to_lm3533_led(led_cdev); 578 u8 val; 579 int ret; 580 581 ret = lm3533_ctrlbank_get_pwm(&led->cb, &val); 582 if (ret) 583 return ret; 584 585 return scnprintf(buf, PAGE_SIZE, "%u\n", val); 586} 587 588static ssize_t store_pwm(struct device *dev, 589 struct device_attribute *attr, 590 const char *buf, size_t len) 591{ 592 struct led_classdev *led_cdev = dev_get_drvdata(dev); 593 struct lm3533_led *led = to_lm3533_led(led_cdev); 594 u8 val; 595 int ret; 596 597 if (kstrtou8(buf, 0, &val)) 598 return -EINVAL; 599 600 ret = lm3533_ctrlbank_set_pwm(&led->cb, val); 601 if (ret) 602 return ret; 603 604 return len; 605} 606 607static LM3533_ATTR_RW(als_channel); 608static LM3533_ATTR_RW(als_en); 609static LM3533_ATTR_RW(falltime); 610static LM3533_ATTR_RO(id); 611static LM3533_ATTR_RW(linear); 612static LM3533_ATTR_RW(pwm); 613static LM3533_ATTR_RW(risetime); 614 615static struct attribute *lm3533_led_attributes[] = { 616 &dev_attr_als_channel.attr, 617 &dev_attr_als_en.attr, 618 &dev_attr_falltime.attr, 619 &dev_attr_id.attr, 620 &dev_attr_linear.attr, 621 &dev_attr_pwm.attr, 622 &dev_attr_risetime.attr, 623 NULL, 624}; 625 626static umode_t lm3533_led_attr_is_visible(struct kobject *kobj, 627 struct attribute *attr, int n) 628{ 629 struct device *dev = container_of(kobj, struct device, kobj); 630 struct led_classdev *led_cdev = dev_get_drvdata(dev); 631 struct lm3533_led *led = to_lm3533_led(led_cdev); 632 umode_t mode = attr->mode; 633 634 if (attr == &dev_attr_als_channel.attr || 635 attr == &dev_attr_als_en.attr) { 636 if (!led->lm3533->have_als) 637 mode = 0; 638 } 639 640 return mode; 641}; 642 643static struct attribute_group lm3533_led_attribute_group = { 644 .is_visible = lm3533_led_attr_is_visible, 645 .attrs = lm3533_led_attributes 646}; 647 648static const struct attribute_group *lm3533_led_attribute_groups[] = { 649 &lm3533_led_attribute_group, 650 NULL 651}; 652 653static int lm3533_led_setup(struct lm3533_led *led, 654 struct lm3533_led_platform_data *pdata) 655{ 656 int ret; 657 658 ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current); 659 if (ret) 660 return ret; 661 662 return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm); 663} 664 665static int lm3533_led_probe(struct platform_device *pdev) 666{ 667 struct lm3533 *lm3533; 668 struct lm3533_led_platform_data *pdata; 669 struct lm3533_led *led; 670 int ret; 671 672 dev_dbg(&pdev->dev, "%s\n", __func__); 673 674 lm3533 = dev_get_drvdata(pdev->dev.parent); 675 if (!lm3533) 676 return -EINVAL; 677 678 pdata = dev_get_platdata(&pdev->dev); 679 if (!pdata) { 680 dev_err(&pdev->dev, "no platform data\n"); 681 return -EINVAL; 682 } 683 684 if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) { 685 dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id); 686 return -EINVAL; 687 } 688 689 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); 690 if (!led) 691 return -ENOMEM; 692 693 led->lm3533 = lm3533; 694 led->cdev.name = pdata->name; 695 led->cdev.default_trigger = pdata->default_trigger; 696 led->cdev.brightness_set = lm3533_led_set; 697 led->cdev.brightness_get = lm3533_led_get; 698 led->cdev.blink_set = lm3533_led_blink_set; 699 led->cdev.brightness = LED_OFF; 700 led->cdev.groups = lm3533_led_attribute_groups, 701 led->id = pdev->id; 702 703 mutex_init(&led->mutex); 704 INIT_WORK(&led->work, lm3533_led_work); 705 706 /* The class framework makes a callback to get brightness during 707 * registration so use parent device (for error reporting) until 708 * registered. 709 */ 710 led->cb.lm3533 = lm3533; 711 led->cb.id = lm3533_led_get_ctrlbank_id(led); 712 led->cb.dev = lm3533->dev; 713 714 platform_set_drvdata(pdev, led); 715 716 ret = led_classdev_register(pdev->dev.parent, &led->cdev); 717 if (ret) { 718 dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id); 719 return ret; 720 } 721 722 led->cb.dev = led->cdev.dev; 723 724 ret = lm3533_led_setup(led, pdata); 725 if (ret) 726 goto err_unregister; 727 728 ret = lm3533_ctrlbank_enable(&led->cb); 729 if (ret) 730 goto err_unregister; 731 732 return 0; 733 734err_unregister: 735 led_classdev_unregister(&led->cdev); 736 flush_work(&led->work); 737 738 return ret; 739} 740 741static int lm3533_led_remove(struct platform_device *pdev) 742{ 743 struct lm3533_led *led = platform_get_drvdata(pdev); 744 745 dev_dbg(&pdev->dev, "%s\n", __func__); 746 747 lm3533_ctrlbank_disable(&led->cb); 748 led_classdev_unregister(&led->cdev); 749 flush_work(&led->work); 750 751 return 0; 752} 753 754static void lm3533_led_shutdown(struct platform_device *pdev) 755{ 756 757 struct lm3533_led *led = platform_get_drvdata(pdev); 758 759 dev_dbg(&pdev->dev, "%s\n", __func__); 760 761 lm3533_ctrlbank_disable(&led->cb); 762 lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */ 763 flush_work(&led->work); 764} 765 766static struct platform_driver lm3533_led_driver = { 767 .driver = { 768 .name = "lm3533-leds", 769 }, 770 .probe = lm3533_led_probe, 771 .remove = lm3533_led_remove, 772 .shutdown = lm3533_led_shutdown, 773}; 774module_platform_driver(lm3533_led_driver); 775 776MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>"); 777MODULE_DESCRIPTION("LM3533 LED driver"); 778MODULE_LICENSE("GPL"); 779MODULE_ALIAS("platform:lm3533-leds"); 780