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