mediatek: copy patches-6.1 to patches-6.6
[openwrt/staging/stintel.git] / target / linux / mediatek / patches-6.6 / 731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch
1 From c66937b0f8dbb4c6c043663c702b1053fb47fab2 Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Mon, 14 Aug 2023 02:58:14 +0100
4 Subject: [PATCH] net: phy: mediatek-ge-soc: support PHY LEDs
5
6 Implement netdev trigger and primitive bliking offloading as well as
7 simple set_brigthness function for both PHY LEDs of the in-SoC PHYs
8 found in MT7981 and MT7988.
9
10 For MT7988, read boottrap register and apply LED polarities accordingly
11 to get uniform behavior from all LEDs on MT7988.
12 This requires syscon phandle 'mediatek,pio' present in parenting MDIO bus
13 which should point to the syscon holding the boottrap register.
14
15 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
16 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
17 Link: https://lore.kernel.org/r/dc324d48c00cd7350f3a506eaa785324cae97372.1691977904.git.daniel@makrotopia.org
18 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
19 ---
20 drivers/net/phy/mediatek-ge-soc.c | 435 +++++++++++++++++++++++++++++-
21 1 file changed, 426 insertions(+), 9 deletions(-)
22
23 --- a/drivers/net/phy/mediatek-ge-soc.c
24 +++ b/drivers/net/phy/mediatek-ge-soc.c
25 @@ -1,11 +1,14 @@
26 // SPDX-License-Identifier: GPL-2.0+
27 #include <linux/bitfield.h>
28 +#include <linux/bitmap.h>
29 +#include <linux/mfd/syscon.h>
30 #include <linux/module.h>
31 #include <linux/nvmem-consumer.h>
32 #include <linux/of_address.h>
33 #include <linux/of_platform.h>
34 #include <linux/pinctrl/consumer.h>
35 #include <linux/phy.h>
36 +#include <linux/regmap.h>
37
38 #define MTK_GPHY_ID_MT7981 0x03a29461
39 #define MTK_GPHY_ID_MT7988 0x03a29481
40 @@ -208,9 +211,42 @@
41 #define MTK_PHY_DA_TX_R50_PAIR_C 0x53f
42 #define MTK_PHY_DA_TX_R50_PAIR_D 0x540
43
44 +/* Registers on MDIO_MMD_VEND2 */
45 +#define MTK_PHY_LED0_ON_CTRL 0x24
46 +#define MTK_PHY_LED1_ON_CTRL 0x26
47 +#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
48 +#define MTK_PHY_LED_ON_LINK1000 BIT(0)
49 +#define MTK_PHY_LED_ON_LINK100 BIT(1)
50 +#define MTK_PHY_LED_ON_LINK10 BIT(2)
51 +#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
52 +#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
53 +#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
54 +#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
55 +#define MTK_PHY_LED_ON_POLARITY BIT(14)
56 +#define MTK_PHY_LED_ON_ENABLE BIT(15)
57 +
58 +#define MTK_PHY_LED0_BLINK_CTRL 0x25
59 +#define MTK_PHY_LED1_BLINK_CTRL 0x27
60 +#define MTK_PHY_LED_BLINK_1000TX BIT(0)
61 +#define MTK_PHY_LED_BLINK_1000RX BIT(1)
62 +#define MTK_PHY_LED_BLINK_100TX BIT(2)
63 +#define MTK_PHY_LED_BLINK_100RX BIT(3)
64 +#define MTK_PHY_LED_BLINK_10TX BIT(4)
65 +#define MTK_PHY_LED_BLINK_10RX BIT(5)
66 +#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
67 +#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
68 +#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
69 +#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
70 +
71 +#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
72 +
73 #define MTK_PHY_RG_BG_RASEL 0x115
74 #define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
75
76 +/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
77 +#define RG_GPIO_MISC_TPBANK0 0x6f0
78 +#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8)
79 +
80 /* These macro privides efuse parsing for internal phy. */
81 #define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
82 #define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
83 @@ -238,13 +274,6 @@ enum {
84 PAIR_D,
85 };
86
87 -enum {
88 - GPHY_PORT0,
89 - GPHY_PORT1,
90 - GPHY_PORT2,
91 - GPHY_PORT3,
92 -};
93 -
94 enum calibration_mode {
95 EFUSE_K,
96 SW_K
97 @@ -263,6 +292,19 @@ enum CAL_MODE {
98 SW_M
99 };
100
101 +#define MTK_PHY_LED_STATE_FORCE_ON 0
102 +#define MTK_PHY_LED_STATE_FORCE_BLINK 1
103 +#define MTK_PHY_LED_STATE_NETDEV 2
104 +
105 +struct mtk_socphy_priv {
106 + unsigned long led_state;
107 +};
108 +
109 +struct mtk_socphy_shared {
110 + u32 boottrap;
111 + struct mtk_socphy_priv priv[4];
112 +};
113 +
114 static int mtk_socphy_read_page(struct phy_device *phydev)
115 {
116 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
117 @@ -1073,6 +1115,371 @@ static int mt798x_phy_config_init(struct
118 return mt798x_phy_calibration(phydev);
119 }
120
121 +static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
122 + bool on)
123 +{
124 + unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
125 + struct mtk_socphy_priv *priv = phydev->priv;
126 + bool changed;
127 +
128 + if (on)
129 + changed = !test_and_set_bit(bit_on, &priv->led_state);
130 + else
131 + changed = !!test_and_clear_bit(bit_on, &priv->led_state);
132 +
133 + changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
134 + (index ? 16 : 0), &priv->led_state);
135 + if (changed)
136 + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
137 + MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
138 + MTK_PHY_LED_ON_MASK,
139 + on ? MTK_PHY_LED_ON_FORCE_ON : 0);
140 + else
141 + return 0;
142 +}
143 +
144 +static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
145 + bool blinking)
146 +{
147 + unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
148 + struct mtk_socphy_priv *priv = phydev->priv;
149 + bool changed;
150 +
151 + if (blinking)
152 + changed = !test_and_set_bit(bit_blink, &priv->led_state);
153 + else
154 + changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
155 +
156 + changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
157 + (index ? 16 : 0), &priv->led_state);
158 + if (changed)
159 + return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
160 + MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
161 + blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
162 + else
163 + return 0;
164 +}
165 +
166 +static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
167 + unsigned long *delay_on,
168 + unsigned long *delay_off)
169 +{
170 + bool blinking = false;
171 + int err = 0;
172 +
173 + if (index > 1)
174 + return -EINVAL;
175 +
176 + if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
177 + blinking = true;
178 + *delay_on = 50;
179 + *delay_off = 50;
180 + }
181 +
182 + err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
183 + if (err)
184 + return err;
185 +
186 + return mt798x_phy_hw_led_on_set(phydev, index, false);
187 +}
188 +
189 +static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
190 + u8 index, enum led_brightness value)
191 +{
192 + int err;
193 +
194 + err = mt798x_phy_hw_led_blink_set(phydev, index, false);
195 + if (err)
196 + return err;
197 +
198 + return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
199 +}
200 +
201 +static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
202 + BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
203 + BIT(TRIGGER_NETDEV_LINK) |
204 + BIT(TRIGGER_NETDEV_LINK_10) |
205 + BIT(TRIGGER_NETDEV_LINK_100) |
206 + BIT(TRIGGER_NETDEV_LINK_1000) |
207 + BIT(TRIGGER_NETDEV_RX) |
208 + BIT(TRIGGER_NETDEV_TX));
209 +
210 +static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
211 + unsigned long rules)
212 +{
213 + if (index > 1)
214 + return -EINVAL;
215 +
216 + /* All combinations of the supported triggers are allowed */
217 + if (rules & ~supported_triggers)
218 + return -EOPNOTSUPP;
219 +
220 + return 0;
221 +};
222 +
223 +static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
224 + unsigned long *rules)
225 +{
226 + unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
227 + unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
228 + unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
229 + struct mtk_socphy_priv *priv = phydev->priv;
230 + int on, blink;
231 +
232 + if (index > 1)
233 + return -EINVAL;
234 +
235 + on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
236 + index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
237 +
238 + if (on < 0)
239 + return -EIO;
240 +
241 + blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
242 + index ? MTK_PHY_LED1_BLINK_CTRL :
243 + MTK_PHY_LED0_BLINK_CTRL);
244 + if (blink < 0)
245 + return -EIO;
246 +
247 + if ((on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 |
248 + MTK_PHY_LED_ON_LINK10)) ||
249 + (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX |
250 + MTK_PHY_LED_BLINK_10RX | MTK_PHY_LED_BLINK_1000TX |
251 + MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX)))
252 + set_bit(bit_netdev, &priv->led_state);
253 + else
254 + clear_bit(bit_netdev, &priv->led_state);
255 +
256 + if (on & MTK_PHY_LED_ON_FORCE_ON)
257 + set_bit(bit_on, &priv->led_state);
258 + else
259 + clear_bit(bit_on, &priv->led_state);
260 +
261 + if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
262 + set_bit(bit_blink, &priv->led_state);
263 + else
264 + clear_bit(bit_blink, &priv->led_state);
265 +
266 + if (!rules)
267 + return 0;
268 +
269 + if (on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK10))
270 + *rules |= BIT(TRIGGER_NETDEV_LINK);
271 +
272 + if (on & MTK_PHY_LED_ON_LINK10)
273 + *rules |= BIT(TRIGGER_NETDEV_LINK_10);
274 +
275 + if (on & MTK_PHY_LED_ON_LINK100)
276 + *rules |= BIT(TRIGGER_NETDEV_LINK_100);
277 +
278 + if (on & MTK_PHY_LED_ON_LINK1000)
279 + *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
280 +
281 + if (on & MTK_PHY_LED_ON_FDX)
282 + *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
283 +
284 + if (on & MTK_PHY_LED_ON_HDX)
285 + *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
286 +
287 + if (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX | MTK_PHY_LED_BLINK_10RX))
288 + *rules |= BIT(TRIGGER_NETDEV_RX);
289 +
290 + if (blink & (MTK_PHY_LED_BLINK_1000TX | MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX))
291 + *rules |= BIT(TRIGGER_NETDEV_TX);
292 +
293 + return 0;
294 +};
295 +
296 +static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
297 + unsigned long rules)
298 +{
299 + unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
300 + struct mtk_socphy_priv *priv = phydev->priv;
301 + u16 on = 0, blink = 0;
302 + int ret;
303 +
304 + if (index > 1)
305 + return -EINVAL;
306 +
307 + if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
308 + on |= MTK_PHY_LED_ON_FDX;
309 +
310 + if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
311 + on |= MTK_PHY_LED_ON_HDX;
312 +
313 + if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
314 + on |= MTK_PHY_LED_ON_LINK10;
315 +
316 + if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
317 + on |= MTK_PHY_LED_ON_LINK100;
318 +
319 + if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
320 + on |= MTK_PHY_LED_ON_LINK1000;
321 +
322 + if (rules & BIT(TRIGGER_NETDEV_RX)) {
323 + blink |= MTK_PHY_LED_BLINK_10RX |
324 + MTK_PHY_LED_BLINK_100RX |
325 + MTK_PHY_LED_BLINK_1000RX;
326 + }
327 +
328 + if (rules & BIT(TRIGGER_NETDEV_TX)) {
329 + blink |= MTK_PHY_LED_BLINK_10TX |
330 + MTK_PHY_LED_BLINK_100TX |
331 + MTK_PHY_LED_BLINK_1000TX;
332 + }
333 +
334 + if (blink || on)
335 + set_bit(bit_netdev, &priv->led_state);
336 + else
337 + clear_bit(bit_netdev, &priv->led_state);
338 +
339 + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
340 + MTK_PHY_LED1_ON_CTRL :
341 + MTK_PHY_LED0_ON_CTRL,
342 + MTK_PHY_LED_ON_FDX |
343 + MTK_PHY_LED_ON_HDX |
344 + MTK_PHY_LED_ON_LINK10 |
345 + MTK_PHY_LED_ON_LINK100 |
346 + MTK_PHY_LED_ON_LINK1000,
347 + on);
348 +
349 + if (ret)
350 + return ret;
351 +
352 + return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
353 + MTK_PHY_LED1_BLINK_CTRL :
354 + MTK_PHY_LED0_BLINK_CTRL, blink);
355 +};
356 +
357 +static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
358 +{
359 + struct mtk_socphy_shared *priv = phydev->shared->priv;
360 + u32 polarities;
361 +
362 + if (led_num == 0)
363 + polarities = ~(priv->boottrap);
364 + else
365 + polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
366 +
367 + if (polarities & BIT(phydev->mdio.addr))
368 + return true;
369 +
370 + return false;
371 +}
372 +
373 +static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
374 +{
375 + struct pinctrl *pinctrl;
376 + int index;
377 +
378 + /* Setup LED polarity according to bootstrap use of LED pins */
379 + for (index = 0; index < 2; ++index)
380 + phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
381 + MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
382 + MTK_PHY_LED_ON_POLARITY,
383 + mt7988_phy_led_get_polarity(phydev, index) ?
384 + MTK_PHY_LED_ON_POLARITY : 0);
385 +
386 + /* Only now setup pinctrl to avoid bogus blinking */
387 + pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
388 + if (IS_ERR(pinctrl))
389 + dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
390 +
391 + return 0;
392 +}
393 +
394 +static int mt7988_phy_probe_shared(struct phy_device *phydev)
395 +{
396 + struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
397 + struct mtk_socphy_shared *shared = phydev->shared->priv;
398 + struct regmap *regmap;
399 + u32 reg;
400 + int ret;
401 +
402 + /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
403 + * LED_C and LED_D respectively. At the same time those pins are used to
404 + * bootstrap configuration of the reference clock source (LED_A),
405 + * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
406 + * In practise this is done using a LED and a resistor pulling the pin
407 + * either to GND or to VIO.
408 + * The detected value at boot time is accessible at run-time using the
409 + * TPBANK0 register located in the gpio base of the pinctrl, in order
410 + * to read it here it needs to be referenced by a phandle called
411 + * 'mediatek,pio' in the MDIO bus hosting the PHY.
412 + * The 4 bits in TPBANK0 are kept as package shared data and are used to
413 + * set LED polarity for each of the LED0.
414 + */
415 + regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
416 + if (IS_ERR(regmap))
417 + return PTR_ERR(regmap);
418 +
419 + ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
420 + if (ret)
421 + return ret;
422 +
423 + shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
424 +
425 + return 0;
426 +}
427 +
428 +static void mt798x_phy_leds_state_init(struct phy_device *phydev)
429 +{
430 + int i;
431 +
432 + for (i = 0; i < 2; ++i)
433 + mt798x_phy_led_hw_control_get(phydev, i, NULL);
434 +}
435 +
436 +static int mt7988_phy_probe(struct phy_device *phydev)
437 +{
438 + struct mtk_socphy_shared *shared;
439 + struct mtk_socphy_priv *priv;
440 + int err;
441 +
442 + if (phydev->mdio.addr > 3)
443 + return -EINVAL;
444 +
445 + err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
446 + sizeof(struct mtk_socphy_shared));
447 + if (err)
448 + return err;
449 +
450 + if (phy_package_probe_once(phydev)) {
451 + err = mt7988_phy_probe_shared(phydev);
452 + if (err)
453 + return err;
454 + }
455 +
456 + shared = phydev->shared->priv;
457 + priv = &shared->priv[phydev->mdio.addr];
458 +
459 + phydev->priv = priv;
460 +
461 + mt798x_phy_leds_state_init(phydev);
462 +
463 + err = mt7988_phy_fix_leds_polarities(phydev);
464 + if (err)
465 + return err;
466 +
467 + return mt798x_phy_calibration(phydev);
468 +}
469 +
470 +static int mt7981_phy_probe(struct phy_device *phydev)
471 +{
472 + struct mtk_socphy_priv *priv;
473 +
474 + priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
475 + GFP_KERNEL);
476 + if (!priv)
477 + return -ENOMEM;
478 +
479 + phydev->priv = priv;
480 +
481 + mt798x_phy_leds_state_init(phydev);
482 +
483 + return mt798x_phy_calibration(phydev);
484 +}
485 +
486 static struct phy_driver mtk_socphy_driver[] = {
487 {
488 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
489 @@ -1080,11 +1487,16 @@ static struct phy_driver mtk_socphy_driv
490 .config_init = mt798x_phy_config_init,
491 .config_intr = genphy_no_config_intr,
492 .handle_interrupt = genphy_handle_interrupt_no_ack,
493 - .probe = mt798x_phy_calibration,
494 + .probe = mt7981_phy_probe,
495 .suspend = genphy_suspend,
496 .resume = genphy_resume,
497 .read_page = mtk_socphy_read_page,
498 .write_page = mtk_socphy_write_page,
499 + .led_blink_set = mt798x_phy_led_blink_set,
500 + .led_brightness_set = mt798x_phy_led_brightness_set,
501 + .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
502 + .led_hw_control_set = mt798x_phy_led_hw_control_set,
503 + .led_hw_control_get = mt798x_phy_led_hw_control_get,
504 },
505 {
506 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
507 @@ -1092,11 +1504,16 @@ static struct phy_driver mtk_socphy_driv
508 .config_init = mt798x_phy_config_init,
509 .config_intr = genphy_no_config_intr,
510 .handle_interrupt = genphy_handle_interrupt_no_ack,
511 - .probe = mt798x_phy_calibration,
512 + .probe = mt7988_phy_probe,
513 .suspend = genphy_suspend,
514 .resume = genphy_resume,
515 .read_page = mtk_socphy_read_page,
516 .write_page = mtk_socphy_write_page,
517 + .led_blink_set = mt798x_phy_led_blink_set,
518 + .led_brightness_set = mt798x_phy_led_brightness_set,
519 + .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
520 + .led_hw_control_set = mt798x_phy_led_hw_control_set,
521 + .led_hw_control_get = mt798x_phy_led_hw_control_get,
522 },
523 };
524