113 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <net/mac80211.h>3#include <linux/bcma/bcma_driver_chipcommon.h>4#include <linux/gpio/driver.h>5#include <linux/gpio/machine.h>6#include <linux/gpio/consumer.h>7 8#include "mac80211_if.h"9#include "pub.h"10#include "main.h"11#include "led.h"12 13 /* number of leds */14#define BRCMS_LED_NO 415 /* behavior mask */16#define BRCMS_LED_BEH_MASK 0x7f17 /* activelow (polarity) bit */18#define BRCMS_LED_AL_MASK 0x8019 /* radio enabled */20#define BRCMS_LED_RADIO 321 22static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)23{24 if (!wl->radio_led.gpiod)25 return;26 27 if (state)28 gpiod_set_value(wl->radio_led.gpiod, 1);29 else30 gpiod_set_value(wl->radio_led.gpiod, 0);31}32 33 34/* Callback from the LED subsystem. */35static void brcms_led_brightness_set(struct led_classdev *led_dev,36 enum led_brightness brightness)37{38 struct brcms_info *wl = container_of(led_dev,39 struct brcms_info, led_dev);40 brcms_radio_led_ctrl(wl, brightness);41}42 43void brcms_led_unregister(struct brcms_info *wl)44{45 if (wl->led_dev.dev)46 led_classdev_unregister(&wl->led_dev);47 if (wl->radio_led.gpiod)48 gpiochip_free_own_desc(wl->radio_led.gpiod);49}50 51int brcms_led_register(struct brcms_info *wl)52{53 int i, err;54 struct brcms_led *radio_led = &wl->radio_led;55 /* get CC core */56 struct bcma_drv_cc *cc_drv = &wl->wlc->hw->d11core->bus->drv_cc;57 struct gpio_chip *bcma_gpio = &cc_drv->gpio;58 struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;59 u8 *leds[] = { &sprom->gpio0,60 &sprom->gpio1,61 &sprom->gpio2,62 &sprom->gpio3 };63 int hwnum = -1;64 enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH;65 66 /* find radio enabled LED */67 for (i = 0; i < BRCMS_LED_NO; i++) {68 u8 led = *leds[i];69 if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {70 hwnum = i;71 if (led & BRCMS_LED_AL_MASK)72 lflags = GPIO_ACTIVE_LOW;73 break;74 }75 }76 77 /* No LED, bail out */78 if (hwnum == -1)79 return -ENODEV;80 81 /* Try to obtain this LED GPIO line */82 radio_led->gpiod = gpiochip_request_own_desc(bcma_gpio, hwnum,83 "radio on", lflags,84 GPIOD_OUT_LOW);85 86 if (IS_ERR(radio_led->gpiod)) {87 err = PTR_ERR(radio_led->gpiod);88 wiphy_err(wl->wiphy, "requesting led GPIO failed (err: %d)\n",89 err);90 return err;91 }92 93 snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),94 "brcmsmac-%s:radio", wiphy_name(wl->wiphy));95 96 wl->led_dev.name = wl->radio_led.name;97 wl->led_dev.default_trigger =98 ieee80211_get_radio_led_name(wl->pub->ieee_hw);99 wl->led_dev.brightness_set = brcms_led_brightness_set;100 err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);101 102 if (err) {103 wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",104 wl->radio_led.name, err);105 return err;106 }107 108 wiphy_info(wl->wiphy, "registered radio enabled led device: %s\n",109 wl->radio_led.name);110 111 return 0;112}113