xref: /linux/drivers/net/dsa/qca/qca8k-leds.c (revision 0e2b2a76278153d1ac312b0691cb65dabb9aef3e)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/regmap.h>
3 #include <net/dsa.h>
4 
5 #include "qca8k.h"
6 #include "qca8k_leds.h"
7 
8 static u32 qca8k_phy_to_port(int phy)
9 {
10 	/* Internal PHY 0 has port at index 1.
11 	 * Internal PHY 1 has port at index 2.
12 	 * Internal PHY 2 has port at index 3.
13 	 * Internal PHY 3 has port at index 4.
14 	 * Internal PHY 4 has port at index 5.
15 	 */
16 
17 	return phy + 1;
18 }
19 
20 static int
21 qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
22 {
23 	switch (port_num) {
24 	case 0:
25 		reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
26 		reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
27 		break;
28 	case 1:
29 	case 2:
30 	case 3:
31 		/* Port 123 are controlled on a different reg */
32 		reg_info->reg = QCA8K_LED_CTRL3_REG;
33 		reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num);
34 		break;
35 	case 4:
36 		reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
37 		reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
38 		break;
39 	default:
40 		return -EINVAL;
41 	}
42 
43 	return 0;
44 }
45 
46 static int
47 qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
48 {
49 	reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
50 
51 	/* 6 total control rule:
52 	 * 3 control rules for phy0-3 that applies to all their leds
53 	 * 3 control rules for phy4
54 	 */
55 	if (port_num == 4)
56 		reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
57 	else
58 		reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
59 
60 	return 0;
61 }
62 
63 static int
64 qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger)
65 {
66 	/* Parsing specific to netdev trigger */
67 	if (test_bit(TRIGGER_NETDEV_TX, &rules))
68 		*offload_trigger |= QCA8K_LED_TX_BLINK_MASK;
69 	if (test_bit(TRIGGER_NETDEV_RX, &rules))
70 		*offload_trigger |= QCA8K_LED_RX_BLINK_MASK;
71 	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
72 		*offload_trigger |= QCA8K_LED_LINK_10M_EN_MASK;
73 	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
74 		*offload_trigger |= QCA8K_LED_LINK_100M_EN_MASK;
75 	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
76 		*offload_trigger |= QCA8K_LED_LINK_1000M_EN_MASK;
77 	if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
78 		*offload_trigger |= QCA8K_LED_HALF_DUPLEX_MASK;
79 	if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
80 		*offload_trigger |= QCA8K_LED_FULL_DUPLEX_MASK;
81 
82 	if (rules && !*offload_trigger)
83 		return -EOPNOTSUPP;
84 
85 	/* Enable some default rule by default to the requested mode:
86 	 * - Blink at 4Hz by default
87 	 */
88 	*offload_trigger |= QCA8K_LED_BLINK_4HZ;
89 
90 	return 0;
91 }
92 
93 static int
94 qca8k_led_brightness_set(struct qca8k_led *led,
95 			 enum led_brightness brightness)
96 {
97 	struct qca8k_led_pattern_en reg_info;
98 	struct qca8k_priv *priv = led->priv;
99 	u32 mask, val;
100 
101 	qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
102 
103 	val = QCA8K_LED_ALWAYS_OFF;
104 	if (brightness)
105 		val = QCA8K_LED_ALWAYS_ON;
106 
107 	/* HW regs to control brightness is special and port 1-2-3
108 	 * are placed in a different reg.
109 	 *
110 	 * To control port 0 brightness:
111 	 * - the 2 bit (15, 14) of:
112 	 *   - QCA8K_LED_CTRL0_REG for led1
113 	 *   - QCA8K_LED_CTRL1_REG for led2
114 	 *   - QCA8K_LED_CTRL2_REG for led3
115 	 *
116 	 * To control port 4:
117 	 * - the 2 bit (31, 30) of:
118 	 *   - QCA8K_LED_CTRL0_REG for led1
119 	 *   - QCA8K_LED_CTRL1_REG for led2
120 	 *   - QCA8K_LED_CTRL2_REG for led3
121 	 *
122 	 * To control port 1:
123 	 *   - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1
124 	 *   - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2
125 	 *   - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3
126 	 *
127 	 * To control port 2:
128 	 *   - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1
129 	 *   - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2
130 	 *   - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3
131 	 *
132 	 * To control port 3:
133 	 *   - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1
134 	 *   - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2
135 	 *   - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3
136 	 *
137 	 * To abstract this and have less code, we use the port and led numm
138 	 * to calculate the shift and the correct reg due to this problem of
139 	 * not having a 1:1 map of LED with the regs.
140 	 */
141 	if (led->port_num == 0 || led->port_num == 4) {
142 		mask = QCA8K_LED_PATTERN_EN_MASK;
143 		val <<= QCA8K_LED_PATTERN_EN_SHIFT;
144 	} else {
145 		mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
146 	}
147 
148 	return regmap_update_bits(priv->regmap, reg_info.reg,
149 				  mask << reg_info.shift,
150 				  val << reg_info.shift);
151 }
152 
153 static int
154 qca8k_cled_brightness_set_blocking(struct led_classdev *ldev,
155 				   enum led_brightness brightness)
156 {
157 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
158 
159 	return qca8k_led_brightness_set(led, brightness);
160 }
161 
162 static enum led_brightness
163 qca8k_led_brightness_get(struct qca8k_led *led)
164 {
165 	struct qca8k_led_pattern_en reg_info;
166 	struct qca8k_priv *priv = led->priv;
167 	u32 val;
168 	int ret;
169 
170 	qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
171 
172 	ret = regmap_read(priv->regmap, reg_info.reg, &val);
173 	if (ret)
174 		return 0;
175 
176 	val >>= reg_info.shift;
177 
178 	if (led->port_num == 0 || led->port_num == 4) {
179 		val &= QCA8K_LED_PATTERN_EN_MASK;
180 		val >>= QCA8K_LED_PATTERN_EN_SHIFT;
181 	} else {
182 		val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
183 	}
184 
185 	/* Assume brightness ON only when the LED is set to always ON */
186 	return val == QCA8K_LED_ALWAYS_ON;
187 }
188 
189 static int
190 qca8k_cled_blink_set(struct led_classdev *ldev,
191 		     unsigned long *delay_on,
192 		     unsigned long *delay_off)
193 {
194 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
195 	u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ;
196 	struct qca8k_led_pattern_en reg_info;
197 	struct qca8k_priv *priv = led->priv;
198 
199 	if (*delay_on == 0 && *delay_off == 0) {
200 		*delay_on = 125;
201 		*delay_off = 125;
202 	}
203 
204 	if (*delay_on != 125 || *delay_off != 125) {
205 		/* The hardware only supports blinking at 4Hz. Fall back
206 		 * to software implementation in other cases.
207 		 */
208 		return -EINVAL;
209 	}
210 
211 	qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
212 
213 	if (led->port_num == 0 || led->port_num == 4) {
214 		mask = QCA8K_LED_PATTERN_EN_MASK;
215 		val <<= QCA8K_LED_PATTERN_EN_SHIFT;
216 	} else {
217 		mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
218 	}
219 
220 	regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
221 			   val << reg_info.shift);
222 
223 	return 0;
224 }
225 
226 static int
227 qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable)
228 {
229 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
230 
231 	struct qca8k_led_pattern_en reg_info;
232 	struct qca8k_priv *priv = led->priv;
233 	u32 mask, val = QCA8K_LED_ALWAYS_OFF;
234 
235 	qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
236 
237 	if (enable)
238 		val = QCA8K_LED_RULE_CONTROLLED;
239 
240 	if (led->port_num == 0 || led->port_num == 4) {
241 		mask = QCA8K_LED_PATTERN_EN_MASK;
242 		val <<= QCA8K_LED_PATTERN_EN_SHIFT;
243 	} else {
244 		mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
245 	}
246 
247 	return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
248 				  val << reg_info.shift);
249 }
250 
251 static bool
252 qca8k_cled_hw_control_status(struct led_classdev *ldev)
253 {
254 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
255 
256 	struct qca8k_led_pattern_en reg_info;
257 	struct qca8k_priv *priv = led->priv;
258 	u32 val;
259 
260 	qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
261 
262 	regmap_read(priv->regmap, reg_info.reg, &val);
263 
264 	val >>= reg_info.shift;
265 
266 	if (led->port_num == 0 || led->port_num == 4) {
267 		val &= QCA8K_LED_PATTERN_EN_MASK;
268 		val >>= QCA8K_LED_PATTERN_EN_SHIFT;
269 	} else {
270 		val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
271 	}
272 
273 	return val == QCA8K_LED_RULE_CONTROLLED;
274 }
275 
276 static int
277 qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
278 {
279 	u32 offload_trigger = 0;
280 
281 	return qca8k_parse_netdev(rules, &offload_trigger);
282 }
283 
284 static int
285 qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules)
286 {
287 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
288 	struct qca8k_led_pattern_en reg_info;
289 	struct qca8k_priv *priv = led->priv;
290 	u32 offload_trigger = 0;
291 	int ret;
292 
293 	ret = qca8k_parse_netdev(rules, &offload_trigger);
294 	if (ret)
295 		return ret;
296 
297 	ret = qca8k_cled_trigger_offload(ldev, true);
298 	if (ret)
299 		return ret;
300 
301 	qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
302 
303 	return regmap_update_bits(priv->regmap, reg_info.reg,
304 				  QCA8K_LED_RULE_MASK << reg_info.shift,
305 				  offload_trigger << reg_info.shift);
306 }
307 
308 static int
309 qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
310 {
311 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
312 	struct qca8k_led_pattern_en reg_info;
313 	struct qca8k_priv *priv = led->priv;
314 	u32 val;
315 	int ret;
316 
317 	/* With hw control not active return err */
318 	if (!qca8k_cled_hw_control_status(ldev))
319 		return -EINVAL;
320 
321 	qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
322 
323 	ret = regmap_read(priv->regmap, reg_info.reg, &val);
324 	if (ret)
325 		return ret;
326 
327 	val >>= reg_info.shift;
328 	val &= QCA8K_LED_RULE_MASK;
329 
330 	/* Parsing specific to netdev trigger */
331 	if (val & QCA8K_LED_TX_BLINK_MASK)
332 		set_bit(TRIGGER_NETDEV_TX, rules);
333 	if (val & QCA8K_LED_RX_BLINK_MASK)
334 		set_bit(TRIGGER_NETDEV_RX, rules);
335 	if (val & QCA8K_LED_LINK_10M_EN_MASK)
336 		set_bit(TRIGGER_NETDEV_LINK_10, rules);
337 	if (val & QCA8K_LED_LINK_100M_EN_MASK)
338 		set_bit(TRIGGER_NETDEV_LINK_100, rules);
339 	if (val & QCA8K_LED_LINK_1000M_EN_MASK)
340 		set_bit(TRIGGER_NETDEV_LINK_1000, rules);
341 	if (val & QCA8K_LED_HALF_DUPLEX_MASK)
342 		set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
343 	if (val & QCA8K_LED_FULL_DUPLEX_MASK)
344 		set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
345 
346 	return 0;
347 }
348 
349 static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev)
350 {
351 	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
352 	struct qca8k_priv *priv = led->priv;
353 	struct dsa_port *dp;
354 
355 	dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num));
356 	if (!dp)
357 		return NULL;
358 	if (dp->slave)
359 		return &dp->slave->dev;
360 	return NULL;
361 }
362 
363 static int
364 qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
365 {
366 	struct fwnode_handle *led = NULL, *leds = NULL;
367 	struct led_init_data init_data = { };
368 	struct dsa_switch *ds = priv->ds;
369 	enum led_default_state state;
370 	struct qca8k_led *port_led;
371 	int led_num, led_index;
372 	int ret;
373 
374 	leds = fwnode_get_named_child_node(port, "leds");
375 	if (!leds) {
376 		dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n",
377 			port_num);
378 		return 0;
379 	}
380 
381 	fwnode_for_each_child_node(leds, led) {
382 		/* Reg represent the led number of the port.
383 		 * Each port can have at most 3 leds attached
384 		 * Commonly:
385 		 * 1. is gigabit led
386 		 * 2. is mbit led
387 		 * 3. additional status led
388 		 */
389 		if (fwnode_property_read_u32(led, "reg", &led_num))
390 			continue;
391 
392 		if (led_num >= QCA8K_LED_PORT_COUNT) {
393 			dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
394 				 led_num, port_num);
395 			continue;
396 		}
397 
398 		led_index = QCA8K_LED_PORT_INDEX(port_num, led_num);
399 
400 		port_led = &priv->ports_led[led_index];
401 		port_led->port_num = port_num;
402 		port_led->led_num = led_num;
403 		port_led->priv = priv;
404 
405 		state = led_init_default_state_get(led);
406 		switch (state) {
407 		case LEDS_DEFSTATE_ON:
408 			port_led->cdev.brightness = 1;
409 			qca8k_led_brightness_set(port_led, 1);
410 			break;
411 		case LEDS_DEFSTATE_KEEP:
412 			port_led->cdev.brightness =
413 					qca8k_led_brightness_get(port_led);
414 			break;
415 		default:
416 			port_led->cdev.brightness = 0;
417 			qca8k_led_brightness_set(port_led, 0);
418 		}
419 
420 		port_led->cdev.max_brightness = 1;
421 		port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
422 		port_led->cdev.blink_set = qca8k_cled_blink_set;
423 		port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
424 		port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
425 		port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
426 		port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device;
427 		port_led->cdev.hw_control_trigger = "netdev";
428 		init_data.default_label = ":port";
429 		init_data.fwnode = led;
430 		init_data.devname_mandatory = true;
431 		init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id,
432 						 port_num);
433 		if (!init_data.devicename)
434 			return -ENOMEM;
435 
436 		ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
437 		if (ret)
438 			dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num);
439 
440 		kfree(init_data.devicename);
441 	}
442 
443 	return 0;
444 }
445 
446 int
447 qca8k_setup_led_ctrl(struct qca8k_priv *priv)
448 {
449 	struct fwnode_handle *ports, *port;
450 	int port_num;
451 	int ret;
452 
453 	ports = device_get_named_child_node(priv->dev, "ports");
454 	if (!ports) {
455 		dev_info(priv->dev, "No ports node specified in device tree!");
456 		return 0;
457 	}
458 
459 	fwnode_for_each_child_node(ports, port) {
460 		if (fwnode_property_read_u32(port, "reg", &port_num))
461 			continue;
462 
463 		/* Skip checking for CPU port 0 and CPU port 6 as not supported */
464 		if (port_num == 0 || port_num == 6)
465 			continue;
466 
467 		/* Each port can have at most 3 different leds attached.
468 		 * Switch port starts from 0 to 6, but port 0 and 6 are CPU
469 		 * port. The port index needs to be decreased by one to identify
470 		 * the correct port for LED setup.
471 		 */
472 		ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
473 		if (ret)
474 			return ret;
475 	}
476 
477 	return 0;
478 }
479