1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * LP5812 LED driver 4 * 5 * Copyright (C) 2025 Texas Instruments 6 * 7 * Author: Jared Zhou <jared-zhou@ti.com> 8 */ 9 10 #include <linux/delay.h> 11 #include <linux/i2c.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/led-class-multicolor.h> 15 #include <linux/leds.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/sysfs.h> 19 #include <linux/types.h> 20 21 #include "leds-lp5812.h" 22 23 static const struct lp5812_mode_mapping chip_mode_map[] = { 24 {"direct_mode", 0, 0, 0, 0, 0, 0}, 25 {"tcm:1:0", 1, 0, 0, 0, 0, 0}, 26 {"tcm:1:1", 1, 1, 0, 0, 0, 0}, 27 {"tcm:1:2", 1, 2, 0, 0, 0, 0}, 28 {"tcm:1:3", 1, 3, 0, 0, 0, 0}, 29 {"tcm:2:0:1", 2, 0, 1, 0, 0, 0}, 30 {"tcm:2:0:2", 2, 0, 2, 0, 0, 0}, 31 {"tcm:2:0:3", 2, 0, 3, 0, 0, 0}, 32 {"tcm:2:1:2", 2, 1, 2, 0, 0, 0}, 33 {"tcm:2:1:3", 2, 1, 3, 0, 0, 0}, 34 {"tcm:2:2:3", 2, 2, 3, 0, 0, 0}, 35 {"tcm:3:0:1:2", 3, 0, 1, 2, 0, 0}, 36 {"tcm:3:0:1:3", 3, 0, 1, 3, 0, 0}, 37 {"tcm:3:0:2:3", 3, 0, 2, 3, 0, 0}, 38 {"tcm:4:0:1:2:3", 4, 0, 1, 2, 3, 0}, 39 {"mix:1:0:1", 5, 1, 0, 0, 0, 0}, 40 {"mix:1:0:2", 5, 2, 0, 0, 0, 0}, 41 {"mix:1:0:3", 5, 3, 0, 0, 0, 0}, 42 {"mix:1:1:0", 5, 0, 0, 0, 0, 1}, 43 {"mix:1:1:2", 5, 2, 0, 0, 0, 1}, 44 {"mix:1:1:3", 5, 3, 0, 0, 0, 1}, 45 {"mix:1:2:0", 5, 0, 0, 0, 0, 2}, 46 {"mix:1:2:1", 5, 1, 0, 0, 0, 2}, 47 {"mix:1:2:3", 5, 3, 0, 0, 0, 2}, 48 {"mix:1:3:0", 5, 0, 0, 0, 0, 3}, 49 {"mix:1:3:1", 5, 1, 0, 0, 0, 3}, 50 {"mix:1:3:2", 5, 2, 0, 0, 0, 3}, 51 {"mix:2:0:1:2", 6, 1, 2, 0, 0, 0}, 52 {"mix:2:0:1:3", 6, 1, 3, 0, 0, 0}, 53 {"mix:2:0:2:3", 6, 2, 3, 0, 0, 0}, 54 {"mix:2:1:0:2", 6, 0, 2, 0, 0, 1}, 55 {"mix:2:1:0:3", 6, 0, 3, 0, 0, 1}, 56 {"mix:2:1:2:3", 6, 2, 3, 0, 0, 1}, 57 {"mix:2:2:0:1", 6, 0, 1, 0, 0, 2}, 58 {"mix:2:2:0:3", 6, 0, 3, 0, 0, 2}, 59 {"mix:2:2:1:3", 6, 1, 3, 0, 0, 2}, 60 {"mix:2:3:0:1", 6, 0, 1, 0, 0, 3}, 61 {"mix:2:3:0:2", 6, 0, 2, 0, 0, 3}, 62 {"mix:2:3:1:2", 6, 1, 2, 0, 0, 3}, 63 {"mix:3:0:1:2:3", 7, 1, 2, 3, 0, 0}, 64 {"mix:3:1:0:2:3", 7, 0, 2, 3, 0, 1}, 65 {"mix:3:2:0:1:3", 7, 0, 1, 3, 0, 2}, 66 {"mix:3:3:0:1:2", 7, 0, 1, 2, 0, 3} 67 }; 68 69 static int lp5812_write(struct lp5812_chip *chip, u16 reg, u8 val) 70 { 71 struct device *dev = &chip->client->dev; 72 struct i2c_msg msg; 73 u8 buf[LP5812_DATA_LENGTH]; 74 u8 reg_addr_bit8_9; 75 int ret; 76 77 /* Extract register address bits 9 and 8 for Address Byte 1 */ 78 reg_addr_bit8_9 = (reg >> LP5812_REG_ADDR_HIGH_SHIFT) & LP5812_REG_ADDR_BIT_8_9_MASK; 79 80 /* Prepare payload: Address Byte 2 (bits [7:0]) and value to write */ 81 buf[LP5812_DATA_BYTE_0_IDX] = (u8)(reg & LP5812_REG_ADDR_LOW_MASK); 82 buf[LP5812_DATA_BYTE_1_IDX] = val; 83 84 /* Construct I2C message for a write operation */ 85 msg.addr = (chip->client->addr << LP5812_CHIP_ADDR_SHIFT) | reg_addr_bit8_9; 86 msg.flags = 0; 87 msg.len = sizeof(buf); 88 msg.buf = buf; 89 90 ret = i2c_transfer(chip->client->adapter, &msg, 1); 91 if (ret == 1) 92 return 0; 93 94 dev_err(dev, "I2C write error, ret=%d\n", ret); 95 return ret < 0 ? ret : -EIO; 96 } 97 98 static int lp5812_read(struct lp5812_chip *chip, u16 reg, u8 *val) 99 { 100 struct device *dev = &chip->client->dev; 101 struct i2c_msg msgs[LP5812_READ_MSG_LENGTH]; 102 u8 ret_val; 103 u8 reg_addr_bit8_9; 104 u8 converted_reg; 105 int ret; 106 107 /* Extract register address bits 9 and 8 for Address Byte 1 */ 108 reg_addr_bit8_9 = (reg >> LP5812_REG_ADDR_HIGH_SHIFT) & LP5812_REG_ADDR_BIT_8_9_MASK; 109 110 /* Lower 8 bits go in Address Byte 2 */ 111 converted_reg = (u8)(reg & LP5812_REG_ADDR_LOW_MASK); 112 113 /* Prepare I2C write message to set register address */ 114 msgs[LP5812_MSG_0_IDX].addr = 115 (chip->client->addr << LP5812_CHIP_ADDR_SHIFT) | reg_addr_bit8_9; 116 msgs[LP5812_MSG_0_IDX].flags = 0; 117 msgs[LP5812_MSG_0_IDX].len = 1; 118 msgs[LP5812_MSG_0_IDX].buf = &converted_reg; 119 120 /* Prepare I2C read message to retrieve register value */ 121 msgs[LP5812_MSG_1_IDX].addr = 122 (chip->client->addr << LP5812_CHIP_ADDR_SHIFT) | reg_addr_bit8_9; 123 msgs[LP5812_MSG_1_IDX].flags = I2C_M_RD; 124 msgs[LP5812_MSG_1_IDX].len = 1; 125 msgs[LP5812_MSG_1_IDX].buf = &ret_val; 126 127 ret = i2c_transfer(chip->client->adapter, msgs, LP5812_READ_MSG_LENGTH); 128 if (ret == LP5812_READ_MSG_LENGTH) { 129 *val = ret_val; 130 return 0; 131 } 132 133 dev_err(dev, "I2C read error, ret=%d\n", ret); 134 *val = 0; 135 return ret < 0 ? ret : -EIO; 136 } 137 138 static int lp5812_read_tsd_config_status(struct lp5812_chip *chip, u8 *reg_val) 139 { 140 return lp5812_read(chip, LP5812_TSD_CONFIG_STATUS, reg_val); 141 } 142 143 static int lp5812_update_regs_config(struct lp5812_chip *chip) 144 { 145 u8 reg_val; 146 int ret; 147 148 ret = lp5812_write(chip, LP5812_CMD_UPDATE, LP5812_UPDATE_CMD_VAL); 149 if (ret) 150 return ret; 151 152 ret = lp5812_read_tsd_config_status(chip, ®_val); 153 if (ret) 154 return ret; 155 156 return reg_val & LP5812_CFG_ERR_STATUS_MASK; 157 } 158 159 static ssize_t parse_drive_mode(struct lp5812_chip *chip, const char *str) 160 { 161 int i; 162 163 chip->drive_mode.bits.mix_sel_led_0 = false; 164 chip->drive_mode.bits.mix_sel_led_1 = false; 165 chip->drive_mode.bits.mix_sel_led_2 = false; 166 chip->drive_mode.bits.mix_sel_led_3 = false; 167 168 if (sysfs_streq(str, LP5812_MODE_DIRECT_NAME)) { 169 chip->drive_mode.bits.led_mode = LP5812_MODE_DIRECT_VALUE; 170 return 0; 171 } 172 173 for (i = 0; i < ARRAY_SIZE(chip_mode_map); i++) { 174 if (!sysfs_streq(str, chip_mode_map[i].mode_name)) 175 continue; 176 177 chip->drive_mode.bits.led_mode = chip_mode_map[i].mode; 178 chip->scan_order.bits.order0 = chip_mode_map[i].scan_order_0; 179 chip->scan_order.bits.order1 = chip_mode_map[i].scan_order_1; 180 chip->scan_order.bits.order2 = chip_mode_map[i].scan_order_2; 181 chip->scan_order.bits.order3 = chip_mode_map[i].scan_order_3; 182 183 switch (chip_mode_map[i].selection_led) { 184 case LP5812_MODE_MIX_SELECT_LED_0: 185 chip->drive_mode.bits.mix_sel_led_0 = true; 186 break; 187 case LP5812_MODE_MIX_SELECT_LED_1: 188 chip->drive_mode.bits.mix_sel_led_1 = true; 189 break; 190 case LP5812_MODE_MIX_SELECT_LED_2: 191 chip->drive_mode.bits.mix_sel_led_2 = true; 192 break; 193 case LP5812_MODE_MIX_SELECT_LED_3: 194 chip->drive_mode.bits.mix_sel_led_3 = true; 195 break; 196 default: 197 return -EINVAL; 198 } 199 200 return 0; 201 } 202 203 return -EINVAL; 204 } 205 206 static int lp5812_set_drive_mode_scan_order(struct lp5812_chip *chip) 207 { 208 u8 val; 209 int ret; 210 211 val = chip->drive_mode.val; 212 ret = lp5812_write(chip, LP5812_DEV_CONFIG1, val); 213 if (ret) 214 return ret; 215 216 val = chip->scan_order.val; 217 ret = lp5812_write(chip, LP5812_DEV_CONFIG2, val); 218 219 return ret; 220 } 221 222 static int lp5812_set_led_mode(struct lp5812_chip *chip, int led_number, 223 enum control_mode mode) 224 { 225 u8 reg_val; 226 u16 reg; 227 int ret; 228 229 /* 230 * Select device configuration register. 231 * Reg3 for LED_0–LED_3, LED_A0–A2, LED_B0 232 * Reg4 for LED_B1–B2, LED_C0–C2, LED_D0–D2 233 */ 234 if (led_number < LP5812_NUMBER_LED_IN_REG) 235 reg = LP5812_DEV_CONFIG3; 236 else 237 reg = LP5812_DEV_CONFIG4; 238 239 ret = lp5812_read(chip, reg, ®_val); 240 if (ret) 241 return ret; 242 243 if (mode == LP5812_MODE_MANUAL) 244 reg_val &= ~(LP5812_ENABLE << (led_number % LP5812_NUMBER_LED_IN_REG)); 245 else 246 reg_val |= (LP5812_ENABLE << (led_number % LP5812_NUMBER_LED_IN_REG)); 247 248 ret = lp5812_write(chip, reg, reg_val); 249 if (ret) 250 return ret; 251 252 ret = lp5812_update_regs_config(chip); 253 254 return ret; 255 } 256 257 static int lp5812_manual_dc_pwm_control(struct lp5812_chip *chip, int led_number, 258 u8 val, enum dimming_type dimming_type) 259 { 260 u16 led_base_reg; 261 int ret; 262 263 if (dimming_type == LP5812_DIMMING_ANALOG) 264 led_base_reg = LP5812_MANUAL_DC_BASE; 265 else 266 led_base_reg = LP5812_MANUAL_PWM_BASE; 267 268 ret = lp5812_write(chip, led_base_reg + led_number, val); 269 270 return ret; 271 } 272 273 static int lp5812_multicolor_brightness(struct lp5812_led *led) 274 { 275 struct lp5812_chip *chip = led->chip; 276 int ret, i; 277 278 guard(mutex)(&chip->lock); 279 for (i = 0; i < led->mc_cdev.num_colors; i++) { 280 ret = lp5812_manual_dc_pwm_control(chip, led->mc_cdev.subled_info[i].channel, 281 led->mc_cdev.subled_info[i].brightness, 282 LP5812_DIMMING_PWM); 283 if (ret) 284 return ret; 285 } 286 287 return 0; 288 } 289 290 static int lp5812_led_brightness(struct lp5812_led *led) 291 { 292 struct lp5812_chip *chip = led->chip; 293 struct lp5812_led_config *led_cfg; 294 int ret; 295 296 led_cfg = &chip->led_config[led->chan_nr]; 297 298 guard(mutex)(&chip->lock); 299 ret = lp5812_manual_dc_pwm_control(chip, led_cfg->led_id[0], 300 led->brightness, LP5812_DIMMING_PWM); 301 302 return ret; 303 } 304 305 static int lp5812_set_brightness(struct led_classdev *cdev, 306 enum led_brightness brightness) 307 { 308 struct lp5812_led *led = container_of(cdev, struct lp5812_led, cdev); 309 310 led->brightness = (u8)brightness; 311 312 return lp5812_led_brightness(led); 313 } 314 315 static int lp5812_set_mc_brightness(struct led_classdev *cdev, 316 enum led_brightness brightness) 317 { 318 struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev); 319 struct lp5812_led *led = container_of(mc_dev, struct lp5812_led, mc_cdev); 320 321 led_mc_calc_color_components(&led->mc_cdev, brightness); 322 323 return lp5812_multicolor_brightness(led); 324 } 325 326 static int lp5812_init_led(struct lp5812_led *led, struct lp5812_chip *chip, int chan) 327 { 328 struct device *dev = &chip->client->dev; 329 struct mc_subled *mc_led_info; 330 struct led_classdev *led_cdev; 331 int i, ret; 332 333 if (chip->led_config[chan].name) { 334 led->cdev.name = chip->led_config[chan].name; 335 } else { 336 led->cdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s:channel%d", 337 chip->label ? : chip->client->name, chan); 338 if (!led->cdev.name) 339 return -ENOMEM; 340 } 341 342 if (!chip->led_config[chan].is_sc_led) { 343 mc_led_info = devm_kcalloc(dev, chip->led_config[chan].num_colors, 344 sizeof(*mc_led_info), GFP_KERNEL); 345 if (!mc_led_info) 346 return -ENOMEM; 347 348 led_cdev = &led->mc_cdev.led_cdev; 349 led_cdev->name = led->cdev.name; 350 led_cdev->brightness_set_blocking = lp5812_set_mc_brightness; 351 led->mc_cdev.num_colors = chip->led_config[chan].num_colors; 352 353 for (i = 0; i < led->mc_cdev.num_colors; i++) { 354 mc_led_info[i].color_index = chip->led_config[chan].color_id[i]; 355 mc_led_info[i].channel = chip->led_config[chan].led_id[i]; 356 } 357 358 led->mc_cdev.subled_info = mc_led_info; 359 } else { 360 led->cdev.brightness_set_blocking = lp5812_set_brightness; 361 } 362 363 led->chan_nr = chan; 364 365 if (chip->led_config[chan].is_sc_led) { 366 ret = devm_led_classdev_register(dev, &led->cdev); 367 if (ret == 0) 368 led->cdev.dev->platform_data = led; 369 } else { 370 ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev); 371 if (ret == 0) 372 led->mc_cdev.led_cdev.dev->platform_data = led; 373 } 374 375 return ret; 376 } 377 378 static int lp5812_register_leds(struct lp5812_led *leds, struct lp5812_chip *chip) 379 { 380 struct lp5812_led *led; 381 int num_channels = chip->num_channels; 382 u8 reg_val; 383 u16 reg; 384 int ret, i, j; 385 386 for (i = 0; i < num_channels; i++) { 387 led = &leds[i]; 388 ret = lp5812_init_led(led, chip, i); 389 if (ret) 390 goto err_init_led; 391 392 led->chip = chip; 393 394 for (j = 0; j < chip->led_config[i].num_colors; j++) { 395 ret = lp5812_write(chip, 396 LP5812_AUTO_DC_BASE + chip->led_config[i].led_id[j], 397 chip->led_config[i].max_current[j]); 398 if (ret) 399 goto err_init_led; 400 401 ret = lp5812_manual_dc_pwm_control(chip, chip->led_config[i].led_id[j], 402 chip->led_config[i].max_current[j], 403 LP5812_DIMMING_ANALOG); 404 if (ret) 405 goto err_init_led; 406 407 ret = lp5812_set_led_mode(chip, chip->led_config[i].led_id[j], 408 LP5812_MODE_MANUAL); 409 if (ret) 410 goto err_init_led; 411 412 reg = (chip->led_config[i].led_id[j] < LP5812_NUMBER_LED_IN_REG) ? 413 LP5812_LED_EN_1 : LP5812_LED_EN_2; 414 415 ret = lp5812_read(chip, reg, ®_val); 416 if (ret) 417 goto err_init_led; 418 419 reg_val |= (LP5812_ENABLE << (chip->led_config[i].led_id[j] % 420 LP5812_NUMBER_LED_IN_REG)); 421 422 ret = lp5812_write(chip, reg, reg_val); 423 if (ret) 424 goto err_init_led; 425 } 426 } 427 428 return 0; 429 430 err_init_led: 431 return ret; 432 } 433 434 static int lp5812_init_device(struct lp5812_chip *chip) 435 { 436 int ret; 437 438 usleep_range(LP5812_WAIT_DEVICE_STABLE_MIN, LP5812_WAIT_DEVICE_STABLE_MAX); 439 440 ret = lp5812_write(chip, LP5812_REG_ENABLE, LP5812_ENABLE); 441 if (ret) { 442 dev_err(&chip->client->dev, "failed to enable LP5812 device\n"); 443 return ret; 444 } 445 446 ret = lp5812_write(chip, LP5812_DEV_CONFIG12, LP5812_LSD_LOD_START_UP); 447 if (ret) { 448 dev_err(&chip->client->dev, "failed to configure device safety thresholds\n"); 449 return ret; 450 } 451 452 ret = parse_drive_mode(chip, chip->scan_mode); 453 if (ret) 454 return ret; 455 456 ret = lp5812_set_drive_mode_scan_order(chip); 457 if (ret) 458 return ret; 459 460 ret = lp5812_update_regs_config(chip); 461 if (ret) { 462 dev_err(&chip->client->dev, "failed to apply configuration updates\n"); 463 return ret; 464 } 465 466 return 0; 467 } 468 469 static void lp5812_deinit_device(struct lp5812_chip *chip) 470 { 471 lp5812_write(chip, LP5812_LED_EN_1, LP5812_DISABLE); 472 lp5812_write(chip, LP5812_LED_EN_2, LP5812_DISABLE); 473 lp5812_write(chip, LP5812_REG_ENABLE, LP5812_DISABLE); 474 } 475 476 static int lp5812_parse_led_channel(struct device_node *np, 477 struct lp5812_led_config *cfg, 478 int color_number) 479 { 480 int color_id, reg, ret; 481 u32 max_cur; 482 483 ret = of_property_read_u32(np, "reg", ®); 484 if (ret) 485 return ret; 486 487 cfg->led_id[color_number] = reg; 488 489 ret = of_property_read_u32(np, "led-max-microamp", &max_cur); 490 if (ret) 491 max_cur = 0; 492 /* Convert microamps to driver units */ 493 cfg->max_current[color_number] = max_cur / 100; 494 495 ret = of_property_read_u32(np, "color", &color_id); 496 if (ret) 497 color_id = 0; 498 cfg->color_id[color_number] = color_id; 499 500 return 0; 501 } 502 503 static int lp5812_parse_led(struct device_node *np, 504 struct lp5812_led_config *cfg, 505 int led_index) 506 { 507 int num_colors, ret; 508 509 of_property_read_string(np, "label", &cfg[led_index].name); 510 511 ret = of_property_read_u32(np, "reg", &cfg[led_index].chan_nr); 512 if (ret) 513 return ret; 514 515 num_colors = 0; 516 for_each_available_child_of_node_scoped(np, child) { 517 ret = lp5812_parse_led_channel(child, &cfg[led_index], num_colors); 518 if (ret) 519 return ret; 520 521 num_colors++; 522 } 523 524 if (num_colors == 0) { 525 ret = lp5812_parse_led_channel(np, &cfg[led_index], 0); 526 if (ret) 527 return ret; 528 529 num_colors = 1; 530 cfg[led_index].is_sc_led = true; 531 } else { 532 cfg[led_index].is_sc_led = false; 533 } 534 535 cfg[led_index].num_colors = num_colors; 536 537 return 0; 538 } 539 540 static int lp5812_of_probe(struct device *dev, 541 struct device_node *np, 542 struct lp5812_chip *chip) 543 { 544 struct lp5812_led_config *cfg; 545 int num_channels, i = 0, ret; 546 547 num_channels = of_get_available_child_count(np); 548 if (num_channels == 0) { 549 dev_err(dev, "no LED channels\n"); 550 return -EINVAL; 551 } 552 553 cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL); 554 if (!cfg) 555 return -ENOMEM; 556 557 chip->led_config = &cfg[0]; 558 chip->num_channels = num_channels; 559 560 for_each_available_child_of_node_scoped(np, child) { 561 ret = lp5812_parse_led(child, cfg, i); 562 if (ret) 563 return -EINVAL; 564 i++; 565 } 566 567 ret = of_property_read_string(np, "ti,scan-mode", &chip->scan_mode); 568 if (ret) 569 chip->scan_mode = LP5812_MODE_DIRECT_NAME; 570 571 of_property_read_string(np, "label", &chip->label); 572 573 return 0; 574 } 575 576 static int lp5812_probe(struct i2c_client *client) 577 { 578 struct lp5812_chip *chip; 579 struct device_node *np = dev_of_node(&client->dev); 580 struct lp5812_led *leds; 581 int ret; 582 583 if (!np) 584 return -EINVAL; 585 586 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 587 if (!chip) 588 return -ENOMEM; 589 590 ret = lp5812_of_probe(&client->dev, np, chip); 591 if (ret) 592 return ret; 593 594 leds = devm_kcalloc(&client->dev, chip->num_channels, sizeof(*leds), GFP_KERNEL); 595 if (!leds) 596 return -ENOMEM; 597 598 chip->client = client; 599 mutex_init(&chip->lock); 600 i2c_set_clientdata(client, chip); 601 602 ret = lp5812_init_device(chip); 603 if (ret) 604 return ret; 605 606 ret = lp5812_register_leds(leds, chip); 607 if (ret) 608 goto err_out; 609 610 return 0; 611 612 err_out: 613 lp5812_deinit_device(chip); 614 return ret; 615 } 616 617 static void lp5812_remove(struct i2c_client *client) 618 { 619 struct lp5812_chip *chip = i2c_get_clientdata(client); 620 621 lp5812_deinit_device(chip); 622 } 623 624 static const struct of_device_id of_lp5812_match[] = { 625 { .compatible = "ti,lp5812" }, 626 { /* sentinel */ } 627 }; 628 MODULE_DEVICE_TABLE(of, of_lp5812_match); 629 630 static struct i2c_driver lp5812_driver = { 631 .driver = { 632 .name = "lp5812", 633 .of_match_table = of_lp5812_match, 634 }, 635 .probe = lp5812_probe, 636 .remove = lp5812_remove, 637 }; 638 module_i2c_driver(lp5812_driver); 639 640 MODULE_DESCRIPTION("Texas Instruments LP5812 LED Driver"); 641 MODULE_AUTHOR("Jared Zhou <jared-zhou@ti.com>"); 642 MODULE_LICENSE("GPL"); 643