diff options
-rw-r--r-- | drivers/leds/Kconfig | 9 | ||||
-rw-r--r-- | drivers/leds/Makefile | 1 | ||||
-rw-r--r-- | drivers/leds/leds-ti-lmu-common.c | 156 | ||||
-rw-r--r-- | include/linux/leds-ti-lmu-common.h | 47 |
4 files changed, 213 insertions, 0 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 71be87bdb926..4e262696be19 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -783,6 +783,15 @@ config LEDS_NIC78BX | |||
783 | To compile this driver as a module, choose M here: the module | 783 | To compile this driver as a module, choose M here: the module |
784 | will be called leds-nic78bx. | 784 | will be called leds-nic78bx. |
785 | 785 | ||
786 | config LEDS_TI_LMU_COMMON | ||
787 | tristate "LED driver for TI LMU" | ||
788 | depends on LEDS_CLASS | ||
789 | depends on REGMAP | ||
790 | help | ||
791 | Say Y to enable the LED driver for TI LMU devices. | ||
792 | This supports common features between the TI LM3532, LM3631, LM3632, | ||
793 | LM3633, LM3695 and LM3697. | ||
794 | |||
786 | comment "LED Triggers" | 795 | comment "LED Triggers" |
787 | source "drivers/leds/trigger/Kconfig" | 796 | source "drivers/leds/trigger/Kconfig" |
788 | 797 | ||
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 1e9702ebffee..84c49339a8e3 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -81,6 +81,7 @@ obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o | |||
81 | obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o | 81 | obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o |
82 | obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o | 82 | obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o |
83 | obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o | 83 | obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o |
84 | obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o | ||
84 | 85 | ||
85 | # LED SPI Drivers | 86 | # LED SPI Drivers |
86 | obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o | 87 | obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o |
diff --git a/drivers/leds/leds-ti-lmu-common.c b/drivers/leds/leds-ti-lmu-common.c new file mode 100644 index 000000000000..adc7293004f1 --- /dev/null +++ b/drivers/leds/leds-ti-lmu-common.c | |||
@@ -0,0 +1,156 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright 2015 Texas Instruments | ||
3 | // Copyright 2018 Sebastian Reichel | ||
4 | // Copyright 2018 Pavel Machek <pavel@ucw.cz> | ||
5 | // TI LMU LED common framework, based on previous work from | ||
6 | // Milo Kim <milo.kim@ti.com> | ||
7 | |||
8 | #include <linux/bitops.h> | ||
9 | #include <linux/err.h> | ||
10 | #include <linux/of_device.h> | ||
11 | |||
12 | #include <linux/leds-ti-lmu-common.h> | ||
13 | |||
14 | const static int ramp_table[16] = {2048, 262000, 524000, 1049000, 2090000, | ||
15 | 4194000, 8389000, 16780000, 33550000, 41940000, | ||
16 | 50330000, 58720000, 67110000, 83880000, | ||
17 | 100660000, 117440000}; | ||
18 | |||
19 | static int ti_lmu_common_update_brightness(struct ti_lmu_bank *lmu_bank, | ||
20 | int brightness) | ||
21 | { | ||
22 | struct regmap *regmap = lmu_bank->regmap; | ||
23 | u8 reg, val; | ||
24 | int ret; | ||
25 | |||
26 | /* | ||
27 | * Brightness register update | ||
28 | * | ||
29 | * 11 bit dimming: update LSB bits and write MSB byte. | ||
30 | * MSB brightness should be shifted. | ||
31 | * 8 bit dimming: write MSB byte. | ||
32 | */ | ||
33 | if (lmu_bank->max_brightness == MAX_BRIGHTNESS_11BIT) { | ||
34 | reg = lmu_bank->lsb_brightness_reg; | ||
35 | ret = regmap_update_bits(regmap, reg, | ||
36 | LMU_11BIT_LSB_MASK, | ||
37 | brightness); | ||
38 | if (ret) | ||
39 | return ret; | ||
40 | |||
41 | val = brightness >> LMU_11BIT_MSB_SHIFT; | ||
42 | } else { | ||
43 | val = brightness; | ||
44 | } | ||
45 | |||
46 | reg = lmu_bank->msb_brightness_reg; | ||
47 | |||
48 | return regmap_write(regmap, reg, val); | ||
49 | } | ||
50 | |||
51 | int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness) | ||
52 | { | ||
53 | return ti_lmu_common_update_brightness(lmu_bank, brightness); | ||
54 | } | ||
55 | EXPORT_SYMBOL(ti_lmu_common_set_brightness); | ||
56 | |||
57 | static int ti_lmu_common_convert_ramp_to_index(unsigned int usec) | ||
58 | { | ||
59 | int size = ARRAY_SIZE(ramp_table); | ||
60 | int i; | ||
61 | |||
62 | if (usec <= ramp_table[0]) | ||
63 | return 0; | ||
64 | |||
65 | if (usec > ramp_table[size - 1]) | ||
66 | return size - 1; | ||
67 | |||
68 | for (i = 1; i < size; i++) { | ||
69 | if (usec == ramp_table[i]) | ||
70 | return i; | ||
71 | |||
72 | /* Find an approximate index by looking up the table */ | ||
73 | if (usec > ramp_table[i - 1] && usec < ramp_table[i]) { | ||
74 | if (usec - ramp_table[i - 1] < ramp_table[i] - usec) | ||
75 | return i - 1; | ||
76 | else | ||
77 | return i; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank) | ||
85 | { | ||
86 | struct regmap *regmap = lmu_bank->regmap; | ||
87 | u8 ramp, ramp_up, ramp_down; | ||
88 | |||
89 | if (lmu_bank->ramp_up_usec == 0 && lmu_bank->ramp_down_usec == 0) { | ||
90 | ramp_up = 0; | ||
91 | ramp_down = 0; | ||
92 | } else { | ||
93 | ramp_up = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_up_usec); | ||
94 | ramp_down = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_down_usec); | ||
95 | } | ||
96 | |||
97 | if (ramp_up < 0 || ramp_down < 0) | ||
98 | return -EINVAL; | ||
99 | |||
100 | ramp = (ramp_up << 4) | ramp_down; | ||
101 | |||
102 | return regmap_write(regmap, lmu_bank->runtime_ramp_reg, ramp); | ||
103 | |||
104 | } | ||
105 | EXPORT_SYMBOL(ti_lmu_common_set_ramp); | ||
106 | |||
107 | int ti_lmu_common_get_ramp_params(struct device *dev, | ||
108 | struct fwnode_handle *child, | ||
109 | struct ti_lmu_bank *lmu_data) | ||
110 | { | ||
111 | int ret; | ||
112 | |||
113 | ret = fwnode_property_read_u32(child, "ramp-up-us", | ||
114 | &lmu_data->ramp_up_usec); | ||
115 | if (ret) | ||
116 | dev_warn(dev, "ramp-up-us property missing\n"); | ||
117 | |||
118 | |||
119 | ret = fwnode_property_read_u32(child, "ramp-down-us", | ||
120 | &lmu_data->ramp_down_usec); | ||
121 | if (ret) | ||
122 | dev_warn(dev, "ramp-down-us property missing\n"); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | EXPORT_SYMBOL(ti_lmu_common_get_ramp_params); | ||
127 | |||
128 | int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child, | ||
129 | struct ti_lmu_bank *lmu_data) | ||
130 | { | ||
131 | int ret; | ||
132 | |||
133 | ret = device_property_read_u32(dev, "ti,brightness-resolution", | ||
134 | &lmu_data->max_brightness); | ||
135 | if (ret) | ||
136 | ret = fwnode_property_read_u32(child, | ||
137 | "ti,brightness-resolution", | ||
138 | &lmu_data->max_brightness); | ||
139 | if (lmu_data->max_brightness <= 0) { | ||
140 | lmu_data->max_brightness = MAX_BRIGHTNESS_8BIT; | ||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | if (lmu_data->max_brightness > MAX_BRIGHTNESS_11BIT) | ||
145 | lmu_data->max_brightness = MAX_BRIGHTNESS_11BIT; | ||
146 | |||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | EXPORT_SYMBOL(ti_lmu_common_get_brt_res); | ||
151 | |||
152 | MODULE_DESCRIPTION("TI LMU common LED framework"); | ||
153 | MODULE_AUTHOR("Sebastian Reichel"); | ||
154 | MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); | ||
155 | MODULE_LICENSE("GPL v2"); | ||
156 | MODULE_ALIAS("ti-lmu-led-common"); | ||
diff --git a/include/linux/leds-ti-lmu-common.h b/include/linux/leds-ti-lmu-common.h new file mode 100644 index 000000000000..5eb111f38803 --- /dev/null +++ b/include/linux/leds-ti-lmu-common.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | // TI LMU Common Core | ||
3 | // Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ | ||
4 | |||
5 | #ifndef _TI_LMU_COMMON_H_ | ||
6 | #define _TI_LMU_COMMON_H_ | ||
7 | |||
8 | #include <linux/delay.h> | ||
9 | #include <linux/device.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/leds.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <uapi/linux/uleds.h> | ||
16 | |||
17 | #define LMU_11BIT_LSB_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
18 | #define LMU_11BIT_MSB_SHIFT 3 | ||
19 | |||
20 | #define MAX_BRIGHTNESS_8BIT 255 | ||
21 | #define MAX_BRIGHTNESS_11BIT 2047 | ||
22 | |||
23 | struct ti_lmu_bank { | ||
24 | struct regmap *regmap; | ||
25 | |||
26 | int max_brightness; | ||
27 | |||
28 | u8 lsb_brightness_reg; | ||
29 | u8 msb_brightness_reg; | ||
30 | |||
31 | u8 runtime_ramp_reg; | ||
32 | u32 ramp_up_usec; | ||
33 | u32 ramp_down_usec; | ||
34 | }; | ||
35 | |||
36 | int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness); | ||
37 | |||
38 | int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank); | ||
39 | |||
40 | int ti_lmu_common_get_ramp_params(struct device *dev, | ||
41 | struct fwnode_handle *child, | ||
42 | struct ti_lmu_bank *lmu_data); | ||
43 | |||
44 | int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child, | ||
45 | struct ti_lmu_bank *lmu_data); | ||
46 | |||
47 | #endif /* _TI_LMU_COMMON_H_ */ | ||