diff options
-rw-r--r-- | drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 38 |
2 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index 90268479d3ad..c8cee4a24755 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -1443,6 +1443,8 @@ struct rtl8xxxu_cfo_tracking { u32 packet_count_pre; }; +#define RTL8XXXU_HW_LED_CONTROL 2 + struct rtl8xxxu_priv { struct ieee80211_hw *hw; struct usb_device *udev; @@ -1564,6 +1566,10 @@ struct rtl8xxxu_priv { struct rtl8xxxu_ra_report ra_report; struct rtl8xxxu_cfo_tracking cfo_tracking; struct rtl8xxxu_ra_info ra_info; + + bool led_registered; + char led_name[32]; + struct led_classdev led_cdev; }; struct rtl8xxxu_rx_urb { @@ -1613,6 +1619,8 @@ struct rtl8xxxu_fileops { u32 rts_rate); void (*set_crystal_cap) (struct rtl8xxxu_priv *priv, u8 crystal_cap); s8 (*cck_rssi) (struct rtl8xxxu_priv *priv, u8 cck_agc_rpt); + int (*led_classdev_brightness_set) (struct led_classdev *led_cdev, + enum led_brightness brightness); int writeN_block_size; int rx_agg_buf_size; char tx_desc_size; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 35dc777c1fba..b25c7efcdec8 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -6955,6 +6955,40 @@ exit: return ret; } +static void rtl8xxxu_init_led(struct rtl8xxxu_priv *priv) +{ + struct led_classdev *led = &priv->led_cdev; + + if (!priv->fops->led_classdev_brightness_set) + return; + + led->brightness_set_blocking = priv->fops->led_classdev_brightness_set; + + snprintf(priv->led_name, sizeof(priv->led_name), + "rtl8xxxu-usb%s", dev_name(&priv->udev->dev)); + led->name = priv->led_name; + led->max_brightness = RTL8XXXU_HW_LED_CONTROL; + + if (led_classdev_register(&priv->udev->dev, led)) + return; + + priv->led_registered = true; + + led->brightness = led->max_brightness; + priv->fops->led_classdev_brightness_set(led, led->brightness); +} + +static void rtl8xxxu_deinit_led(struct rtl8xxxu_priv *priv) +{ + struct led_classdev *led = &priv->led_cdev; + + if (!priv->led_registered) + return; + + priv->fops->led_classdev_brightness_set(led, LED_OFF); + led_classdev_unregister(led); +} + static int rtl8xxxu_probe(struct usb_interface *interface, const struct usb_device_id *id) { @@ -7135,6 +7169,8 @@ static int rtl8xxxu_probe(struct usb_interface *interface, goto err_set_intfdata; } + rtl8xxxu_init_led(priv); + return 0; err_set_intfdata: @@ -7159,6 +7195,8 @@ static void rtl8xxxu_disconnect(struct usb_interface *interface) hw = usb_get_intfdata(interface); priv = hw->priv; + rtl8xxxu_deinit_led(priv); + ieee80211_unregister_hw(hw); priv->fops->power_off(priv); |