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