| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * LP5521 LED chip driver. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> |
|---|
| 8 | 9 | * Milo(Woogyom) Kim <milo.kim@ti.com> |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or |
|---|
| 11 | | - * modify it under the terms of the GNU General Public License |
|---|
| 12 | | - * version 2 as published by the Free Software Foundation. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 15 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 17 | | - * General Public License for more details. |
|---|
| 18 | | - * |
|---|
| 19 | | - * You should have received a copy of the GNU General Public License |
|---|
| 20 | | - * along with this program; if not, write to the Free Software |
|---|
| 21 | | - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
|---|
| 22 | | - * 02110-1301 USA |
|---|
| 23 | 10 | */ |
|---|
| 24 | 11 | |
|---|
| 25 | 12 | #include <linux/delay.h> |
|---|
| .. | .. |
|---|
| 362 | 349 | return 0; |
|---|
| 363 | 350 | } |
|---|
| 364 | 351 | |
|---|
| 352 | +static int lp5521_multicolor_brightness(struct lp55xx_led *led) |
|---|
| 353 | +{ |
|---|
| 354 | + struct lp55xx_chip *chip = led->chip; |
|---|
| 355 | + int ret; |
|---|
| 356 | + int i; |
|---|
| 357 | + |
|---|
| 358 | + mutex_lock(&chip->lock); |
|---|
| 359 | + for (i = 0; i < led->mc_cdev.num_colors; i++) { |
|---|
| 360 | + ret = lp55xx_write(chip, |
|---|
| 361 | + LP5521_REG_LED_PWM_BASE + |
|---|
| 362 | + led->mc_cdev.subled_info[i].channel, |
|---|
| 363 | + led->mc_cdev.subled_info[i].brightness); |
|---|
| 364 | + if (ret) |
|---|
| 365 | + break; |
|---|
| 366 | + } |
|---|
| 367 | + mutex_unlock(&chip->lock); |
|---|
| 368 | + return ret; |
|---|
| 369 | +} |
|---|
| 370 | + |
|---|
| 365 | 371 | static int lp5521_led_brightness(struct lp55xx_led *led) |
|---|
| 366 | 372 | { |
|---|
| 367 | 373 | struct lp55xx_chip *chip = led->chip; |
|---|
| .. | .. |
|---|
| 503 | 509 | .max_channel = LP5521_MAX_LEDS, |
|---|
| 504 | 510 | .post_init_device = lp5521_post_init_device, |
|---|
| 505 | 511 | .brightness_fn = lp5521_led_brightness, |
|---|
| 512 | + .multicolor_brightness_fn = lp5521_multicolor_brightness, |
|---|
| 506 | 513 | .set_led_current = lp5521_set_led_current, |
|---|
| 507 | 514 | .firmware_cb = lp5521_firmware_loaded, |
|---|
| 508 | 515 | .run_engine = lp5521_run_engine, |
|---|
| .. | .. |
|---|
| 516 | 523 | struct lp55xx_chip *chip; |
|---|
| 517 | 524 | struct lp55xx_led *led; |
|---|
| 518 | 525 | struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); |
|---|
| 519 | | - struct device_node *np = client->dev.of_node; |
|---|
| 526 | + struct device_node *np = dev_of_node(&client->dev); |
|---|
| 527 | + |
|---|
| 528 | + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); |
|---|
| 529 | + if (!chip) |
|---|
| 530 | + return -ENOMEM; |
|---|
| 531 | + |
|---|
| 532 | + chip->cfg = &lp5521_cfg; |
|---|
| 520 | 533 | |
|---|
| 521 | 534 | if (!pdata) { |
|---|
| 522 | 535 | if (np) { |
|---|
| 523 | | - pdata = lp55xx_of_populate_pdata(&client->dev, np); |
|---|
| 536 | + pdata = lp55xx_of_populate_pdata(&client->dev, np, |
|---|
| 537 | + chip); |
|---|
| 524 | 538 | if (IS_ERR(pdata)) |
|---|
| 525 | 539 | return PTR_ERR(pdata); |
|---|
| 526 | 540 | } else { |
|---|
| .. | .. |
|---|
| 529 | 543 | } |
|---|
| 530 | 544 | } |
|---|
| 531 | 545 | |
|---|
| 532 | | - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); |
|---|
| 533 | | - if (!chip) |
|---|
| 534 | | - return -ENOMEM; |
|---|
| 535 | | - |
|---|
| 536 | 546 | led = devm_kcalloc(&client->dev, |
|---|
| 537 | 547 | pdata->num_channels, sizeof(*led), GFP_KERNEL); |
|---|
| 538 | 548 | if (!led) |
|---|
| .. | .. |
|---|
| 540 | 550 | |
|---|
| 541 | 551 | chip->cl = client; |
|---|
| 542 | 552 | chip->pdata = pdata; |
|---|
| 543 | | - chip->cfg = &lp5521_cfg; |
|---|
| 544 | 553 | |
|---|
| 545 | 554 | mutex_init(&chip->lock); |
|---|
| 546 | 555 | |
|---|
| .. | .. |
|---|
| 554 | 563 | |
|---|
| 555 | 564 | ret = lp55xx_register_leds(led, chip); |
|---|
| 556 | 565 | if (ret) |
|---|
| 557 | | - goto err_register_leds; |
|---|
| 566 | + goto err_out; |
|---|
| 558 | 567 | |
|---|
| 559 | 568 | ret = lp55xx_register_sysfs(chip); |
|---|
| 560 | 569 | if (ret) { |
|---|
| 561 | 570 | dev_err(&client->dev, "registering sysfs failed\n"); |
|---|
| 562 | | - goto err_register_sysfs; |
|---|
| 571 | + goto err_out; |
|---|
| 563 | 572 | } |
|---|
| 564 | 573 | |
|---|
| 565 | 574 | return 0; |
|---|
| 566 | 575 | |
|---|
| 567 | | -err_register_sysfs: |
|---|
| 568 | | - lp55xx_unregister_leds(led, chip); |
|---|
| 569 | | -err_register_leds: |
|---|
| 576 | +err_out: |
|---|
| 570 | 577 | lp55xx_deinit_device(chip); |
|---|
| 571 | 578 | err_init: |
|---|
| 572 | 579 | return ret; |
|---|
| .. | .. |
|---|
| 579 | 586 | |
|---|
| 580 | 587 | lp5521_stop_all_engines(chip); |
|---|
| 581 | 588 | lp55xx_unregister_sysfs(chip); |
|---|
| 582 | | - lp55xx_unregister_leds(led, chip); |
|---|
| 583 | 589 | lp55xx_deinit_device(chip); |
|---|
| 584 | 590 | |
|---|
| 585 | 591 | return 0; |
|---|