92b20c3b9c2ea288977b51a06afb31d57004af8d
[openwrt/staging/wigyori.git] /
1 From f14aa5ea415b8add245e976bfab96a12986c6843 Mon Sep 17 00:00:00 2001
2 From: Kate Hsuan <hpa@redhat.com>
3 Date: Fri, 31 May 2024 13:41:19 +0200
4 Subject: leds: rgb: leds-ktd202x: Get device properties through fwnode to
5 support ACPI
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 This LED controller is installed on a Xiaomi pad2 and it is an x86
11 platform. The original driver is based on the device tree and can't be
12 used for this ACPI based system. This patch migrated the driver to use
13 fwnode to access the properties. Moreover, the fwnode API supports the
14 device tree so this work won't affect the original implementations.
15
16 Signed-off-by: Kate Hsuan <hpa@redhat.com>
17 Tested-by: André Apitzsch <git@apitzsch.eu> # on BQ Aquaris M5
18 Reviewed-by: Hans de Goede <hdegoede@redhat.com>
19 Reviewed-by: Andy Shevchenko <andy@kernel.org>
20 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
21 Link: https://lore.kernel.org/r/20240531114124.45346-2-hdegoede@redhat.com
22 Signed-off-by: Lee Jones <lee@kernel.org>
23 ---
24 drivers/leds/rgb/Kconfig | 1 -
25 drivers/leds/rgb/leds-ktd202x.c | 64 ++++++++++++++++++++++-------------------
26 2 files changed, 34 insertions(+), 31 deletions(-)
27
28 (limited to 'drivers/leds/rgb')
29
30 --- a/drivers/leds/rgb/Kconfig
31 +++ b/drivers/leds/rgb/Kconfig
32 @@ -17,7 +17,6 @@ config LEDS_GROUP_MULTICOLOR
33 config LEDS_KTD202X
34 tristate "LED support for KTD202x Chips"
35 depends on I2C
36 - depends on OF
37 select REGMAP_I2C
38 help
39 This option enables support for the Kinetic KTD2026/KTD2027
40 --- a/drivers/leds/rgb/leds-ktd202x.c
41 +++ b/drivers/leds/rgb/leds-ktd202x.c
42 @@ -99,7 +99,7 @@ struct ktd202x {
43 struct device *dev;
44 struct regmap *regmap;
45 bool enabled;
46 - int num_leds;
47 + unsigned long num_leds;
48 struct ktd202x_led leds[] __counted_by(num_leds);
49 };
50
51 @@ -381,16 +381,19 @@ static int ktd202x_blink_mc_set(struct l
52 mc->num_colors);
53 }
54
55 -static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np,
56 +static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwnode,
57 struct ktd202x_led *led, struct led_init_data *init_data)
58 {
59 + struct fwnode_handle *child;
60 struct led_classdev *cdev;
61 - struct device_node *child;
62 struct mc_subled *info;
63 int num_channels;
64 int i = 0;
65
66 - num_channels = of_get_available_child_count(np);
67 + num_channels = 0;
68 + fwnode_for_each_available_child_node(fwnode, child)
69 + num_channels++;
70 +
71 if (!num_channels || num_channels > chip->num_leds)
72 return -EINVAL;
73
74 @@ -398,22 +401,22 @@ static int ktd202x_setup_led_rgb(struct
75 if (!info)
76 return -ENOMEM;
77
78 - for_each_available_child_of_node(np, child) {
79 + fwnode_for_each_available_child_node(fwnode, child) {
80 u32 mono_color;
81 u32 reg;
82 int ret;
83
84 - ret = of_property_read_u32(child, "reg", &reg);
85 + ret = fwnode_property_read_u32(child, "reg", &reg);
86 if (ret != 0 || reg >= chip->num_leds) {
87 - dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child);
88 - of_node_put(child);
89 - return -EINVAL;
90 + dev_err(chip->dev, "invalid 'reg' of %pfw\n", child);
91 + fwnode_handle_put(child);
92 + return ret;
93 }
94
95 - ret = of_property_read_u32(child, "color", &mono_color);
96 + ret = fwnode_property_read_u32(child, "color", &mono_color);
97 if (ret < 0 && ret != -EINVAL) {
98 - dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child);
99 - of_node_put(child);
100 + dev_err(chip->dev, "failed to parse 'color' of %pfw\n", child);
101 + fwnode_handle_put(child);
102 return ret;
103 }
104
105 @@ -433,16 +436,16 @@ static int ktd202x_setup_led_rgb(struct
106 return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data);
107 }
108
109 -static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np,
110 +static int ktd202x_setup_led_single(struct ktd202x *chip, struct fwnode_handle *fwnode,
111 struct ktd202x_led *led, struct led_init_data *init_data)
112 {
113 struct led_classdev *cdev;
114 u32 reg;
115 int ret;
116
117 - ret = of_property_read_u32(np, "reg", &reg);
118 + ret = fwnode_property_read_u32(fwnode, "reg", &reg);
119 if (ret != 0 || reg >= chip->num_leds) {
120 - dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np);
121 + dev_err(chip->dev, "invalid 'reg' of %pfw\n", fwnode);
122 return -EINVAL;
123 }
124 led->index = reg;
125 @@ -454,7 +457,7 @@ static int ktd202x_setup_led_single(stru
126 return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data);
127 }
128
129 -static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index)
130 +static int ktd202x_add_led(struct ktd202x *chip, struct fwnode_handle *fwnode, unsigned int index)
131 {
132 struct ktd202x_led *led = &chip->leds[index];
133 struct led_init_data init_data = {};
134 @@ -463,21 +466,21 @@ static int ktd202x_add_led(struct ktd202
135 int ret;
136
137 /* Color property is optional in single color case */
138 - ret = of_property_read_u32(np, "color", &color);
139 + ret = fwnode_property_read_u32(fwnode, "color", &color);
140 if (ret < 0 && ret != -EINVAL) {
141 - dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np);
142 + dev_err(chip->dev, "failed to parse 'color' of %pfw\n", fwnode);
143 return ret;
144 }
145
146 led->chip = chip;
147 - init_data.fwnode = of_fwnode_handle(np);
148 + init_data.fwnode = fwnode;
149
150 if (color == LED_COLOR_ID_RGB) {
151 cdev = &led->mcdev.led_cdev;
152 - ret = ktd202x_setup_led_rgb(chip, np, led, &init_data);
153 + ret = ktd202x_setup_led_rgb(chip, fwnode, led, &init_data);
154 } else {
155 cdev = &led->cdev;
156 - ret = ktd202x_setup_led_single(chip, np, led, &init_data);
157 + ret = ktd202x_setup_led_single(chip, fwnode, led, &init_data);
158 }
159
160 if (ret) {
161 @@ -490,15 +493,14 @@ static int ktd202x_add_led(struct ktd202
162 return 0;
163 }
164
165 -static int ktd202x_probe_dt(struct ktd202x *chip)
166 +static int ktd202x_probe_fw(struct ktd202x *chip)
167 {
168 - struct device_node *np = dev_of_node(chip->dev), *child;
169 + struct fwnode_handle *child;
170 + struct device *dev = chip->dev;
171 int count;
172 int i = 0;
173
174 - chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev);
175 -
176 - count = of_get_available_child_count(np);
177 + count = device_get_child_node_count(dev);
178 if (!count || count > chip->num_leds)
179 return -EINVAL;
180
181 @@ -507,11 +509,11 @@ static int ktd202x_probe_dt(struct ktd20
182 /* Allow the device to execute the complete reset */
183 usleep_range(200, 300);
184
185 - for_each_available_child_of_node(np, child) {
186 + device_for_each_child_node(dev, child) {
187 int ret = ktd202x_add_led(chip, child, i);
188
189 if (ret) {
190 - of_node_put(child);
191 + fwnode_handle_put(child);
192 return ret;
193 }
194 i++;
195 @@ -554,6 +556,8 @@ static int ktd202x_probe(struct i2c_clie
196 return ret;
197 }
198
199 + chip->num_leds = (unsigned long)i2c_get_match_data(client);
200 +
201 chip->regulators[0].supply = "vin";
202 chip->regulators[1].supply = "vio";
203 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
204 @@ -568,7 +572,7 @@ static int ktd202x_probe(struct i2c_clie
205 return ret;
206 }
207
208 - ret = ktd202x_probe_dt(chip);
209 + ret = ktd202x_probe_fw(chip);
210 if (ret < 0) {
211 regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
212 return ret;
213 @@ -605,7 +609,7 @@ static void ktd202x_shutdown(struct i2c_
214 static const struct of_device_id ktd202x_match_table[] = {
215 { .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS },
216 { .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS },
217 - {},
218 + {}
219 };
220 MODULE_DEVICE_TABLE(of, ktd202x_match_table);
221