.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * lp5523.c - LP5523, LP55231 LED 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> |
---|
.. | .. |
---|
36 | 23 | |
---|
37 | 24 | #define LP5523_PROGRAM_LENGTH 32 /* bytes */ |
---|
38 | 25 | /* Memory is used like this: |
---|
39 | | - 0x00 engine 1 program |
---|
40 | | - 0x10 engine 2 program |
---|
41 | | - 0x20 engine 3 program |
---|
42 | | - 0x30 engine 1 muxing info |
---|
43 | | - 0x40 engine 2 muxing info |
---|
44 | | - 0x50 engine 3 muxing info |
---|
45 | | -*/ |
---|
| 26 | + * 0x00 engine 1 program |
---|
| 27 | + * 0x10 engine 2 program |
---|
| 28 | + * 0x20 engine 3 program |
---|
| 29 | + * 0x30 engine 1 muxing info |
---|
| 30 | + * 0x40 engine 2 muxing info |
---|
| 31 | + * 0x50 engine 3 muxing info |
---|
| 32 | + */ |
---|
46 | 33 | #define LP5523_MAX_LEDS 9 |
---|
47 | 34 | |
---|
48 | 35 | /* Registers */ |
---|
.. | .. |
---|
339 | 326 | const u8 *data, size_t size) |
---|
340 | 327 | { |
---|
341 | 328 | u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; |
---|
342 | | - unsigned cmd; |
---|
| 329 | + unsigned int cmd; |
---|
343 | 330 | char c[3]; |
---|
344 | 331 | int nrchars; |
---|
345 | 332 | int ret; |
---|
.. | .. |
---|
481 | 468 | static void lp5523_mux_to_array(u16 led_mux, char *array) |
---|
482 | 469 | { |
---|
483 | 470 | int i, pos = 0; |
---|
| 471 | + |
---|
484 | 472 | for (i = 0; i < LP5523_MAX_LEDS; i++) |
---|
485 | 473 | pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i)); |
---|
486 | 474 | |
---|
.. | .. |
---|
519 | 507 | if (ret) |
---|
520 | 508 | return ret; |
---|
521 | 509 | |
---|
522 | | - ret = lp55xx_write(chip, LP5523_REG_PROG_MEM , (u8)(mux >> 8)); |
---|
| 510 | + ret = lp55xx_write(chip, LP5523_REG_PROG_MEM, (u8)(mux >> 8)); |
---|
523 | 511 | if (ret) |
---|
524 | 512 | return ret; |
---|
525 | 513 | |
---|
.. | .. |
---|
804 | 792 | return ret; |
---|
805 | 793 | } |
---|
806 | 794 | |
---|
| 795 | +static int lp5523_multicolor_brightness(struct lp55xx_led *led) |
---|
| 796 | +{ |
---|
| 797 | + struct lp55xx_chip *chip = led->chip; |
---|
| 798 | + int ret; |
---|
| 799 | + int i; |
---|
| 800 | + |
---|
| 801 | + mutex_lock(&chip->lock); |
---|
| 802 | + for (i = 0; i < led->mc_cdev.num_colors; i++) { |
---|
| 803 | + ret = lp55xx_write(chip, |
---|
| 804 | + LP5523_REG_LED_PWM_BASE + |
---|
| 805 | + led->mc_cdev.subled_info[i].channel, |
---|
| 806 | + led->mc_cdev.subled_info[i].brightness); |
---|
| 807 | + if (ret) |
---|
| 808 | + break; |
---|
| 809 | + } |
---|
| 810 | + mutex_unlock(&chip->lock); |
---|
| 811 | + return ret; |
---|
| 812 | +} |
---|
| 813 | + |
---|
807 | 814 | static int lp5523_led_brightness(struct lp55xx_led *led) |
---|
808 | 815 | { |
---|
809 | 816 | struct lp55xx_chip *chip = led->chip; |
---|
.. | .. |
---|
870 | 877 | .max_channel = LP5523_MAX_LEDS, |
---|
871 | 878 | .post_init_device = lp5523_post_init_device, |
---|
872 | 879 | .brightness_fn = lp5523_led_brightness, |
---|
| 880 | + .multicolor_brightness_fn = lp5523_multicolor_brightness, |
---|
873 | 881 | .set_led_current = lp5523_set_led_current, |
---|
874 | 882 | .firmware_cb = lp5523_firmware_loaded, |
---|
875 | 883 | .run_engine = lp5523_run_engine, |
---|
.. | .. |
---|
883 | 891 | struct lp55xx_chip *chip; |
---|
884 | 892 | struct lp55xx_led *led; |
---|
885 | 893 | struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); |
---|
886 | | - struct device_node *np = client->dev.of_node; |
---|
| 894 | + struct device_node *np = dev_of_node(&client->dev); |
---|
| 895 | + |
---|
| 896 | + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); |
---|
| 897 | + if (!chip) |
---|
| 898 | + return -ENOMEM; |
---|
| 899 | + |
---|
| 900 | + chip->cfg = &lp5523_cfg; |
---|
887 | 901 | |
---|
888 | 902 | if (!pdata) { |
---|
889 | 903 | if (np) { |
---|
890 | | - pdata = lp55xx_of_populate_pdata(&client->dev, np); |
---|
| 904 | + pdata = lp55xx_of_populate_pdata(&client->dev, np, |
---|
| 905 | + chip); |
---|
891 | 906 | if (IS_ERR(pdata)) |
---|
892 | 907 | return PTR_ERR(pdata); |
---|
893 | 908 | } else { |
---|
.. | .. |
---|
896 | 911 | } |
---|
897 | 912 | } |
---|
898 | 913 | |
---|
899 | | - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); |
---|
900 | | - if (!chip) |
---|
901 | | - return -ENOMEM; |
---|
902 | | - |
---|
903 | 914 | led = devm_kcalloc(&client->dev, |
---|
904 | 915 | pdata->num_channels, sizeof(*led), GFP_KERNEL); |
---|
905 | 916 | if (!led) |
---|
.. | .. |
---|
907 | 918 | |
---|
908 | 919 | chip->cl = client; |
---|
909 | 920 | chip->pdata = pdata; |
---|
910 | | - chip->cfg = &lp5523_cfg; |
---|
911 | 921 | |
---|
912 | 922 | mutex_init(&chip->lock); |
---|
913 | 923 | |
---|
.. | .. |
---|
921 | 931 | |
---|
922 | 932 | ret = lp55xx_register_leds(led, chip); |
---|
923 | 933 | if (ret) |
---|
924 | | - goto err_register_leds; |
---|
| 934 | + goto err_out; |
---|
925 | 935 | |
---|
926 | 936 | ret = lp55xx_register_sysfs(chip); |
---|
927 | 937 | if (ret) { |
---|
928 | 938 | dev_err(&client->dev, "registering sysfs failed\n"); |
---|
929 | | - goto err_register_sysfs; |
---|
| 939 | + goto err_out; |
---|
930 | 940 | } |
---|
931 | 941 | |
---|
932 | 942 | return 0; |
---|
933 | 943 | |
---|
934 | | -err_register_sysfs: |
---|
935 | | - lp55xx_unregister_leds(led, chip); |
---|
936 | | -err_register_leds: |
---|
| 944 | +err_out: |
---|
937 | 945 | lp55xx_deinit_device(chip); |
---|
938 | 946 | err_init: |
---|
939 | 947 | return ret; |
---|
.. | .. |
---|
946 | 954 | |
---|
947 | 955 | lp5523_stop_all_engines(chip); |
---|
948 | 956 | lp55xx_unregister_sysfs(chip); |
---|
949 | | - lp55xx_unregister_leds(led, chip); |
---|
950 | 957 | lp55xx_deinit_device(chip); |
---|
951 | 958 | |
---|
952 | 959 | return 0; |
---|