root/drivers/leds/leds-lp5562.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lp5562_wait_opmode_done
  2. lp5562_wait_enable_done
  3. lp5562_set_led_current
  4. lp5562_load_engine
  5. lp5562_stop_engine
  6. lp5562_run_engine
  7. lp5562_update_firmware
  8. lp5562_firmware_loaded
  9. lp5562_post_init_device
  10. lp5562_led_brightness
  11. lp5562_write_program_memory
  12. _is_pc_overflow
  13. lp5562_run_predef_led_pattern
  14. lp5562_store_pattern
  15. lp5562_store_engine_mux
  16. lp5562_probe
  17. lp5562_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * LP5562 LED driver
   4  *
   5  * Copyright (C) 2013 Texas Instruments
   6  *
   7  * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
   8  */
   9 
  10 #include <linux/delay.h>
  11 #include <linux/firmware.h>
  12 #include <linux/i2c.h>
  13 #include <linux/leds.h>
  14 #include <linux/module.h>
  15 #include <linux/mutex.h>
  16 #include <linux/of.h>
  17 #include <linux/platform_data/leds-lp55xx.h>
  18 #include <linux/slab.h>
  19 
  20 #include "leds-lp55xx-common.h"
  21 
  22 #define LP5562_PROGRAM_LENGTH           32
  23 #define LP5562_MAX_LEDS                 4
  24 
  25 /* ENABLE Register 00h */
  26 #define LP5562_REG_ENABLE               0x00
  27 #define LP5562_EXEC_ENG1_M              0x30
  28 #define LP5562_EXEC_ENG2_M              0x0C
  29 #define LP5562_EXEC_ENG3_M              0x03
  30 #define LP5562_EXEC_M                   0x3F
  31 #define LP5562_MASTER_ENABLE            0x40    /* Chip master enable */
  32 #define LP5562_LOGARITHMIC_PWM          0x80    /* Logarithmic PWM adjustment */
  33 #define LP5562_EXEC_RUN                 0x2A
  34 #define LP5562_ENABLE_DEFAULT   \
  35         (LP5562_MASTER_ENABLE | LP5562_LOGARITHMIC_PWM)
  36 #define LP5562_ENABLE_RUN_PROGRAM       \
  37         (LP5562_ENABLE_DEFAULT | LP5562_EXEC_RUN)
  38 
  39 /* OPMODE Register 01h */
  40 #define LP5562_REG_OP_MODE              0x01
  41 #define LP5562_MODE_ENG1_M              0x30
  42 #define LP5562_MODE_ENG2_M              0x0C
  43 #define LP5562_MODE_ENG3_M              0x03
  44 #define LP5562_LOAD_ENG1                0x10
  45 #define LP5562_LOAD_ENG2                0x04
  46 #define LP5562_LOAD_ENG3                0x01
  47 #define LP5562_RUN_ENG1                 0x20
  48 #define LP5562_RUN_ENG2                 0x08
  49 #define LP5562_RUN_ENG3                 0x02
  50 #define LP5562_ENG1_IS_LOADING(mode)    \
  51         ((mode & LP5562_MODE_ENG1_M) == LP5562_LOAD_ENG1)
  52 #define LP5562_ENG2_IS_LOADING(mode)    \
  53         ((mode & LP5562_MODE_ENG2_M) == LP5562_LOAD_ENG2)
  54 #define LP5562_ENG3_IS_LOADING(mode)    \
  55         ((mode & LP5562_MODE_ENG3_M) == LP5562_LOAD_ENG3)
  56 
  57 /* BRIGHTNESS Registers */
  58 #define LP5562_REG_R_PWM                0x04
  59 #define LP5562_REG_G_PWM                0x03
  60 #define LP5562_REG_B_PWM                0x02
  61 #define LP5562_REG_W_PWM                0x0E
  62 
  63 /* CURRENT Registers */
  64 #define LP5562_REG_R_CURRENT            0x07
  65 #define LP5562_REG_G_CURRENT            0x06
  66 #define LP5562_REG_B_CURRENT            0x05
  67 #define LP5562_REG_W_CURRENT            0x0F
  68 
  69 /* CONFIG Register 08h */
  70 #define LP5562_REG_CONFIG               0x08
  71 #define LP5562_PWM_HF                   0x40
  72 #define LP5562_PWRSAVE_EN               0x20
  73 #define LP5562_CLK_INT                  0x01    /* Internal clock */
  74 #define LP5562_DEFAULT_CFG              (LP5562_PWM_HF | LP5562_PWRSAVE_EN)
  75 
  76 /* RESET Register 0Dh */
  77 #define LP5562_REG_RESET                0x0D
  78 #define LP5562_RESET                    0xFF
  79 
  80 /* PROGRAM ENGINE Registers */
  81 #define LP5562_REG_PROG_MEM_ENG1        0x10
  82 #define LP5562_REG_PROG_MEM_ENG2        0x30
  83 #define LP5562_REG_PROG_MEM_ENG3        0x50
  84 
  85 /* LEDMAP Register 70h */
  86 #define LP5562_REG_ENG_SEL              0x70
  87 #define LP5562_ENG_SEL_PWM              0
  88 #define LP5562_ENG_FOR_RGB_M            0x3F
  89 #define LP5562_ENG_SEL_RGB              0x1B    /* R:ENG1, G:ENG2, B:ENG3 */
  90 #define LP5562_ENG_FOR_W_M              0xC0
  91 #define LP5562_ENG1_FOR_W               0x40    /* W:ENG1 */
  92 #define LP5562_ENG2_FOR_W               0x80    /* W:ENG2 */
  93 #define LP5562_ENG3_FOR_W               0xC0    /* W:ENG3 */
  94 
  95 /* Program Commands */
  96 #define LP5562_CMD_DISABLE              0x00
  97 #define LP5562_CMD_LOAD                 0x15
  98 #define LP5562_CMD_RUN                  0x2A
  99 #define LP5562_CMD_DIRECT               0x3F
 100 #define LP5562_PATTERN_OFF              0
 101 
 102 static inline void lp5562_wait_opmode_done(void)
 103 {
 104         /* operation mode change needs to be longer than 153 us */
 105         usleep_range(200, 300);
 106 }
 107 
 108 static inline void lp5562_wait_enable_done(void)
 109 {
 110         /* it takes more 488 us to update ENABLE register */
 111         usleep_range(500, 600);
 112 }
 113 
 114 static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current)
 115 {
 116         static const u8 addr[] = {
 117                 LP5562_REG_R_CURRENT,
 118                 LP5562_REG_G_CURRENT,
 119                 LP5562_REG_B_CURRENT,
 120                 LP5562_REG_W_CURRENT,
 121         };
 122 
 123         led->led_current = led_current;
 124         lp55xx_write(led->chip, addr[led->chan_nr], led_current);
 125 }
 126 
 127 static void lp5562_load_engine(struct lp55xx_chip *chip)
 128 {
 129         enum lp55xx_engine_index idx = chip->engine_idx;
 130         static const u8 mask[] = {
 131                 [LP55XX_ENGINE_1] = LP5562_MODE_ENG1_M,
 132                 [LP55XX_ENGINE_2] = LP5562_MODE_ENG2_M,
 133                 [LP55XX_ENGINE_3] = LP5562_MODE_ENG3_M,
 134         };
 135 
 136         static const u8 val[] = {
 137                 [LP55XX_ENGINE_1] = LP5562_LOAD_ENG1,
 138                 [LP55XX_ENGINE_2] = LP5562_LOAD_ENG2,
 139                 [LP55XX_ENGINE_3] = LP5562_LOAD_ENG3,
 140         };
 141 
 142         lp55xx_update_bits(chip, LP5562_REG_OP_MODE, mask[idx], val[idx]);
 143 
 144         lp5562_wait_opmode_done();
 145 }
 146 
 147 static void lp5562_stop_engine(struct lp55xx_chip *chip)
 148 {
 149         lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DISABLE);
 150         lp5562_wait_opmode_done();
 151 }
 152 
 153 static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
 154 {
 155         int ret;
 156         u8 mode;
 157         u8 exec;
 158 
 159         /* stop engine */
 160         if (!start) {
 161                 lp55xx_write(chip, LP5562_REG_ENABLE, LP5562_ENABLE_DEFAULT);
 162                 lp5562_wait_enable_done();
 163                 lp5562_stop_engine(chip);
 164                 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM);
 165                 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT);
 166                 lp5562_wait_opmode_done();
 167                 return;
 168         }
 169 
 170         /*
 171          * To run the engine,
 172          * operation mode and enable register should updated at the same time
 173          */
 174 
 175         ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode);
 176         if (ret)
 177                 return;
 178 
 179         ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec);
 180         if (ret)
 181                 return;
 182 
 183         /* change operation mode to RUN only when each engine is loading */
 184         if (LP5562_ENG1_IS_LOADING(mode)) {
 185                 mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1;
 186                 exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1;
 187         }
 188 
 189         if (LP5562_ENG2_IS_LOADING(mode)) {
 190                 mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2;
 191                 exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2;
 192         }
 193 
 194         if (LP5562_ENG3_IS_LOADING(mode)) {
 195                 mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3;
 196                 exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3;
 197         }
 198 
 199         lp55xx_write(chip, LP5562_REG_OP_MODE, mode);
 200         lp5562_wait_opmode_done();
 201 
 202         lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec);
 203         lp5562_wait_enable_done();
 204 }
 205 
 206 static int lp5562_update_firmware(struct lp55xx_chip *chip,
 207                                         const u8 *data, size_t size)
 208 {
 209         enum lp55xx_engine_index idx = chip->engine_idx;
 210         u8 pattern[LP5562_PROGRAM_LENGTH] = {0};
 211         static const u8 addr[] = {
 212                 [LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1,
 213                 [LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2,
 214                 [LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3,
 215         };
 216         unsigned cmd;
 217         char c[3];
 218         int program_size;
 219         int nrchars;
 220         int offset = 0;
 221         int ret;
 222         int i;
 223 
 224         /* clear program memory before updating */
 225         for (i = 0; i < LP5562_PROGRAM_LENGTH; i++)
 226                 lp55xx_write(chip, addr[idx] + i, 0);
 227 
 228         i = 0;
 229         while ((offset < size - 1) && (i < LP5562_PROGRAM_LENGTH)) {
 230                 /* separate sscanfs because length is working only for %s */
 231                 ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
 232                 if (ret != 1)
 233                         goto err;
 234 
 235                 ret = sscanf(c, "%2x", &cmd);
 236                 if (ret != 1)
 237                         goto err;
 238 
 239                 pattern[i] = (u8)cmd;
 240                 offset += nrchars;
 241                 i++;
 242         }
 243 
 244         /* Each instruction is 16bit long. Check that length is even */
 245         if (i % 2)
 246                 goto err;
 247 
 248         program_size = i;
 249         for (i = 0; i < program_size; i++)
 250                 lp55xx_write(chip, addr[idx] + i, pattern[i]);
 251 
 252         return 0;
 253 
 254 err:
 255         dev_err(&chip->cl->dev, "wrong pattern format\n");
 256         return -EINVAL;
 257 }
 258 
 259 static void lp5562_firmware_loaded(struct lp55xx_chip *chip)
 260 {
 261         const struct firmware *fw = chip->fw;
 262 
 263         /*
 264          * the firmware is encoded in ascii hex character, with 2 chars
 265          * per byte
 266          */
 267         if (fw->size > (LP5562_PROGRAM_LENGTH * 2)) {
 268                 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
 269                         fw->size);
 270                 return;
 271         }
 272 
 273         /*
 274          * Program memory sequence
 275          *  1) set engine mode to "LOAD"
 276          *  2) write firmware data into program memory
 277          */
 278 
 279         lp5562_load_engine(chip);
 280         lp5562_update_firmware(chip, fw->data, fw->size);
 281 }
 282 
 283 static int lp5562_post_init_device(struct lp55xx_chip *chip)
 284 {
 285         int ret;
 286         u8 cfg = LP5562_DEFAULT_CFG;
 287 
 288         /* Set all PWMs to direct control mode */
 289         ret = lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT);
 290         if (ret)
 291                 return ret;
 292 
 293         lp5562_wait_opmode_done();
 294 
 295         /* Update configuration for the clock setting */
 296         if (!lp55xx_is_extclk_used(chip))
 297                 cfg |= LP5562_CLK_INT;
 298 
 299         ret = lp55xx_write(chip, LP5562_REG_CONFIG, cfg);
 300         if (ret)
 301                 return ret;
 302 
 303         /* Initialize all channels PWM to zero -> leds off */
 304         lp55xx_write(chip, LP5562_REG_R_PWM, 0);
 305         lp55xx_write(chip, LP5562_REG_G_PWM, 0);
 306         lp55xx_write(chip, LP5562_REG_B_PWM, 0);
 307         lp55xx_write(chip, LP5562_REG_W_PWM, 0);
 308 
 309         /* Set LED map as register PWM by default */
 310         lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM);
 311 
 312         return 0;
 313 }
 314 
 315 static int lp5562_led_brightness(struct lp55xx_led *led)
 316 {
 317         struct lp55xx_chip *chip = led->chip;
 318         static const u8 addr[] = {
 319                 LP5562_REG_R_PWM,
 320                 LP5562_REG_G_PWM,
 321                 LP5562_REG_B_PWM,
 322                 LP5562_REG_W_PWM,
 323         };
 324         int ret;
 325 
 326         mutex_lock(&chip->lock);
 327         ret = lp55xx_write(chip, addr[led->chan_nr], led->brightness);
 328         mutex_unlock(&chip->lock);
 329 
 330         return ret;
 331 }
 332 
 333 static void lp5562_write_program_memory(struct lp55xx_chip *chip,
 334                                         u8 base, const u8 *rgb, int size)
 335 {
 336         int i;
 337 
 338         if (!rgb || size <= 0)
 339                 return;
 340 
 341         for (i = 0; i < size; i++)
 342                 lp55xx_write(chip, base + i, *(rgb + i));
 343 
 344         lp55xx_write(chip, base + i, 0);
 345         lp55xx_write(chip, base + i + 1, 0);
 346 }
 347 
 348 /* check the size of program count */
 349 static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn)
 350 {
 351         return ptn->size_r >= LP5562_PROGRAM_LENGTH ||
 352                ptn->size_g >= LP5562_PROGRAM_LENGTH ||
 353                ptn->size_b >= LP5562_PROGRAM_LENGTH;
 354 }
 355 
 356 static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode)
 357 {
 358         struct lp55xx_predef_pattern *ptn;
 359         int i;
 360 
 361         if (mode == LP5562_PATTERN_OFF) {
 362                 lp5562_run_engine(chip, false);
 363                 return 0;
 364         }
 365 
 366         ptn = chip->pdata->patterns + (mode - 1);
 367         if (!ptn || _is_pc_overflow(ptn)) {
 368                 dev_err(&chip->cl->dev, "invalid pattern data\n");
 369                 return -EINVAL;
 370         }
 371 
 372         lp5562_stop_engine(chip);
 373 
 374         /* Set LED map as RGB */
 375         lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_RGB);
 376 
 377         /* Load engines */
 378         for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
 379                 chip->engine_idx = i;
 380                 lp5562_load_engine(chip);
 381         }
 382 
 383         /* Clear program registers */
 384         lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1, 0);
 385         lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1 + 1, 0);
 386         lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2, 0);
 387         lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2 + 1, 0);
 388         lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3, 0);
 389         lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3 + 1, 0);
 390 
 391         /* Program engines */
 392         lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG1,
 393                                 ptn->r, ptn->size_r);
 394         lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG2,
 395                                 ptn->g, ptn->size_g);
 396         lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG3,
 397                                 ptn->b, ptn->size_b);
 398 
 399         /* Run engines */
 400         lp5562_run_engine(chip, true);
 401 
 402         return 0;
 403 }
 404 
 405 static ssize_t lp5562_store_pattern(struct device *dev,
 406                                 struct device_attribute *attr,
 407                                 const char *buf, size_t len)
 408 {
 409         struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 410         struct lp55xx_chip *chip = led->chip;
 411         struct lp55xx_predef_pattern *ptn = chip->pdata->patterns;
 412         int num_patterns = chip->pdata->num_patterns;
 413         unsigned long mode;
 414         int ret;
 415 
 416         ret = kstrtoul(buf, 0, &mode);
 417         if (ret)
 418                 return ret;
 419 
 420         if (mode > num_patterns || !ptn)
 421                 return -EINVAL;
 422 
 423         mutex_lock(&chip->lock);
 424         ret = lp5562_run_predef_led_pattern(chip, mode);
 425         mutex_unlock(&chip->lock);
 426 
 427         if (ret)
 428                 return ret;
 429 
 430         return len;
 431 }
 432 
 433 static ssize_t lp5562_store_engine_mux(struct device *dev,
 434                                      struct device_attribute *attr,
 435                                      const char *buf, size_t len)
 436 {
 437         struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 438         struct lp55xx_chip *chip = led->chip;
 439         u8 mask;
 440         u8 val;
 441 
 442         /* LED map
 443          * R ... Engine 1 (fixed)
 444          * G ... Engine 2 (fixed)
 445          * B ... Engine 3 (fixed)
 446          * W ... Engine 1 or 2 or 3
 447          */
 448 
 449         if (sysfs_streq(buf, "RGB")) {
 450                 mask = LP5562_ENG_FOR_RGB_M;
 451                 val = LP5562_ENG_SEL_RGB;
 452         } else if (sysfs_streq(buf, "W")) {
 453                 enum lp55xx_engine_index idx = chip->engine_idx;
 454 
 455                 mask = LP5562_ENG_FOR_W_M;
 456                 switch (idx) {
 457                 case LP55XX_ENGINE_1:
 458                         val = LP5562_ENG1_FOR_W;
 459                         break;
 460                 case LP55XX_ENGINE_2:
 461                         val = LP5562_ENG2_FOR_W;
 462                         break;
 463                 case LP55XX_ENGINE_3:
 464                         val = LP5562_ENG3_FOR_W;
 465                         break;
 466                 default:
 467                         return -EINVAL;
 468                 }
 469 
 470         } else {
 471                 dev_err(dev, "choose RGB or W\n");
 472                 return -EINVAL;
 473         }
 474 
 475         mutex_lock(&chip->lock);
 476         lp55xx_update_bits(chip, LP5562_REG_ENG_SEL, mask, val);
 477         mutex_unlock(&chip->lock);
 478 
 479         return len;
 480 }
 481 
 482 static LP55XX_DEV_ATTR_WO(led_pattern, lp5562_store_pattern);
 483 static LP55XX_DEV_ATTR_WO(engine_mux, lp5562_store_engine_mux);
 484 
 485 static struct attribute *lp5562_attributes[] = {
 486         &dev_attr_led_pattern.attr,
 487         &dev_attr_engine_mux.attr,
 488         NULL,
 489 };
 490 
 491 static const struct attribute_group lp5562_group = {
 492         .attrs = lp5562_attributes,
 493 };
 494 
 495 /* Chip specific configurations */
 496 static struct lp55xx_device_config lp5562_cfg = {
 497         .max_channel  = LP5562_MAX_LEDS,
 498         .reset = {
 499                 .addr = LP5562_REG_RESET,
 500                 .val  = LP5562_RESET,
 501         },
 502         .enable = {
 503                 .addr = LP5562_REG_ENABLE,
 504                 .val  = LP5562_ENABLE_DEFAULT,
 505         },
 506         .post_init_device   = lp5562_post_init_device,
 507         .set_led_current    = lp5562_set_led_current,
 508         .brightness_fn      = lp5562_led_brightness,
 509         .run_engine         = lp5562_run_engine,
 510         .firmware_cb        = lp5562_firmware_loaded,
 511         .dev_attr_group     = &lp5562_group,
 512 };
 513 
 514 static int lp5562_probe(struct i2c_client *client,
 515                         const struct i2c_device_id *id)
 516 {
 517         int ret;
 518         struct lp55xx_chip *chip;
 519         struct lp55xx_led *led;
 520         struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
 521         struct device_node *np = client->dev.of_node;
 522 
 523         if (!pdata) {
 524                 if (np) {
 525                         pdata = lp55xx_of_populate_pdata(&client->dev, np);
 526                         if (IS_ERR(pdata))
 527                                 return PTR_ERR(pdata);
 528                 } else {
 529                         dev_err(&client->dev, "no platform data\n");
 530                         return -EINVAL;
 531                 }
 532         }
 533 
 534         chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 535         if (!chip)
 536                 return -ENOMEM;
 537 
 538         led = devm_kcalloc(&client->dev,
 539                         pdata->num_channels, sizeof(*led), GFP_KERNEL);
 540         if (!led)
 541                 return -ENOMEM;
 542 
 543         chip->cl = client;
 544         chip->pdata = pdata;
 545         chip->cfg = &lp5562_cfg;
 546 
 547         mutex_init(&chip->lock);
 548 
 549         i2c_set_clientdata(client, led);
 550 
 551         ret = lp55xx_init_device(chip);
 552         if (ret)
 553                 goto err_init;
 554 
 555         ret = lp55xx_register_leds(led, chip);
 556         if (ret)
 557                 goto err_register_leds;
 558 
 559         ret = lp55xx_register_sysfs(chip);
 560         if (ret) {
 561                 dev_err(&client->dev, "registering sysfs failed\n");
 562                 goto err_register_sysfs;
 563         }
 564 
 565         return 0;
 566 
 567 err_register_sysfs:
 568         lp55xx_unregister_leds(led, chip);
 569 err_register_leds:
 570         lp55xx_deinit_device(chip);
 571 err_init:
 572         return ret;
 573 }
 574 
 575 static int lp5562_remove(struct i2c_client *client)
 576 {
 577         struct lp55xx_led *led = i2c_get_clientdata(client);
 578         struct lp55xx_chip *chip = led->chip;
 579 
 580         lp5562_stop_engine(chip);
 581 
 582         lp55xx_unregister_sysfs(chip);
 583         lp55xx_unregister_leds(led, chip);
 584         lp55xx_deinit_device(chip);
 585 
 586         return 0;
 587 }
 588 
 589 static const struct i2c_device_id lp5562_id[] = {
 590         { "lp5562", 0 },
 591         { }
 592 };
 593 MODULE_DEVICE_TABLE(i2c, lp5562_id);
 594 
 595 #ifdef CONFIG_OF
 596 static const struct of_device_id of_lp5562_leds_match[] = {
 597         { .compatible = "ti,lp5562", },
 598         {},
 599 };
 600 
 601 MODULE_DEVICE_TABLE(of, of_lp5562_leds_match);
 602 #endif
 603 
 604 static struct i2c_driver lp5562_driver = {
 605         .driver = {
 606                 .name   = "lp5562",
 607                 .of_match_table = of_match_ptr(of_lp5562_leds_match),
 608         },
 609         .probe          = lp5562_probe,
 610         .remove         = lp5562_remove,
 611         .id_table       = lp5562_id,
 612 };
 613 
 614 module_i2c_driver(lp5562_driver);
 615 
 616 MODULE_DESCRIPTION("Texas Instruments LP5562 LED Driver");
 617 MODULE_AUTHOR("Milo Kim");
 618 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */