root/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. brcms_radio_led_ctrl
  2. brcms_led_brightness_set
  3. brcms_led_unregister
  4. brcms_led_register

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <net/mac80211.h>
   3 #include <linux/bcma/bcma_driver_chipcommon.h>
   4 #include <linux/gpio.h>
   5 
   6 #include "mac80211_if.h"
   7 #include "pub.h"
   8 #include "main.h"
   9 #include "led.h"
  10 
  11         /* number of leds */
  12 #define  BRCMS_LED_NO           4
  13         /* behavior mask */
  14 #define  BRCMS_LED_BEH_MASK     0x7f
  15         /* activelow (polarity) bit */
  16 #define  BRCMS_LED_AL_MASK      0x80
  17         /* radio enabled */
  18 #define  BRCMS_LED_RADIO        3
  19 
  20 static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
  21 {
  22         if (wl->radio_led.gpio == -1)
  23                 return;
  24 
  25         if (wl->radio_led.active_low)
  26                 state = !state;
  27 
  28         if (state)
  29                 gpio_set_value(wl->radio_led.gpio, 1);
  30         else
  31                 gpio_set_value(wl->radio_led.gpio, 0);
  32 }
  33 
  34 
  35 /* Callback from the LED subsystem. */
  36 static void brcms_led_brightness_set(struct led_classdev *led_dev,
  37                                    enum led_brightness brightness)
  38 {
  39         struct brcms_info *wl = container_of(led_dev,
  40                 struct brcms_info, led_dev);
  41         brcms_radio_led_ctrl(wl, brightness);
  42 }
  43 
  44 void brcms_led_unregister(struct brcms_info *wl)
  45 {
  46         if (wl->led_dev.dev)
  47                 led_classdev_unregister(&wl->led_dev);
  48         if (wl->radio_led.gpio != -1)
  49                 gpio_free(wl->radio_led.gpio);
  50 }
  51 
  52 int brcms_led_register(struct brcms_info *wl)
  53 {
  54         int i, err;
  55         struct brcms_led *radio_led = &wl->radio_led;
  56         /* get CC core */
  57         struct bcma_drv_cc *cc_drv  = &wl->wlc->hw->d11core->bus->drv_cc;
  58         struct gpio_chip *bcma_gpio = &cc_drv->gpio;
  59         struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;
  60         u8 *leds[] = { &sprom->gpio0,
  61                 &sprom->gpio1,
  62                 &sprom->gpio2,
  63                 &sprom->gpio3 };
  64         unsigned gpio = -1;
  65         bool active_low = false;
  66 
  67         /* none by default */
  68         radio_led->gpio = -1;
  69         radio_led->active_low = false;
  70 
  71         if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
  72                 return -ENODEV;
  73 
  74         /* find radio enabled LED */
  75         for (i = 0; i < BRCMS_LED_NO; i++) {
  76                 u8 led = *leds[i];
  77                 if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
  78                         gpio = bcma_gpio->base + i;
  79                         if (led & BRCMS_LED_AL_MASK)
  80                                 active_low = true;
  81                         break;
  82                 }
  83         }
  84 
  85         if (gpio == -1 || !gpio_is_valid(gpio))
  86                 return -ENODEV;
  87 
  88         /* request and configure LED gpio */
  89         err = gpio_request_one(gpio,
  90                                 active_low ? GPIOF_OUT_INIT_HIGH
  91                                         : GPIOF_OUT_INIT_LOW,
  92                                 "radio on");
  93         if (err) {
  94                 wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
  95                           gpio, err);
  96                 return err;
  97         }
  98         err = gpio_direction_output(gpio, 1);
  99         if (err) {
 100                 wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
 101                           gpio, err);
 102                 return err;
 103         }
 104 
 105         snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),
 106                  "brcmsmac-%s:radio", wiphy_name(wl->wiphy));
 107 
 108         wl->led_dev.name = wl->radio_led.name;
 109         wl->led_dev.default_trigger =
 110                 ieee80211_get_radio_led_name(wl->pub->ieee_hw);
 111         wl->led_dev.brightness_set = brcms_led_brightness_set;
 112         err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
 113 
 114         if (err) {
 115                 wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",
 116                           wl->radio_led.name, err);
 117                 return err;
 118         }
 119 
 120         wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
 121                    wl->radio_led.name,
 122                    gpio);
 123         radio_led->gpio = gpio;
 124         radio_led->active_low = active_low;
 125 
 126         return 0;
 127 }

/* [<][>][^][v][top][bottom][index][help] */