// SPDX-License-Identifier: GPL-2.0-or-later
/*

  Broadcom B43 wireless driver
  LED control

  Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
  Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
  Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
  Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
  Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>


*/

#include "b43legacy.h"
#include "leds.h"
#include "rfkill.h"


static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index,
			    bool activelow)
{
	struct b43legacy_wl *wl = dev->wl;
	unsigned long flags;
	u16 ctl;

	spin_lock_irqsave(&wl->leds_lock, flags);
	ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
	if (activelow)
		ctl &= ~(1 << led_index);
	else
		ctl |= (1 << led_index);
	b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl);
	spin_unlock_irqrestore(&wl->leds_lock, flags);
}

static void b43legacy_led_turn_off(struct b43legacy_wldev *dev, u8 led_index,
			     bool activelow)
{
	struct b43legacy_wl *wl = dev->wl;
	unsigned long flags;
	u16 ctl;

	spin_lock_irqsave(&wl->leds_lock, flags);
	ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
	if (activelow)
		ctl |= (1 << led_index);
	else
		ctl &= ~(1 << led_index);
	b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl);
	spin_unlock_irqrestore(&wl->leds_lock, flags);
}

/* Callback from the LED subsystem. */
static void b43legacy_led_brightness_set(struct led_classdev *led_dev,
				   enum led_brightness brightness)
{
	struct b43legacy_led *led = container_of(led_dev, struct b43legacy_led,
				    led_dev);
	struct b43legacy_wldev *dev = led->dev;
	bool radio_enabled;

	/* Checking the radio-enabled status here is slightly racy,
	 * but we want to avoid the locking overhead and we don't care
	 * whether the LED has the wrong state for a second. */
	radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable);

	if (brightness == LED_OFF || !radio_enabled)
		b43legacy_led_turn_off(dev, led->index, led->activelow);
	else
		b43legacy_led_turn_on(dev, led->index, led->activelow);
}

static int b43legacy_register_led(struct b43legacy_wldev *dev,
				  struct b43legacy_led *led,
				  const char *name,
				  const char *default_trigger,
				  u8 led_index, bool activelow)
{
	int err;

	b43legacy_led_turn_off(dev, led_index, activelow);
	if (led->dev)
		return -EEXIST;
	if (!default_trigger)
		return -EINVAL;
	led->dev = dev;
	led->index = led_index;
	led->activelow = activelow;
	strlcpy(led->name, name, sizeof(led->name));

	led->led_dev.name = led->name;
	led->led_dev.default_trigger = default_trigger;
	led->led_dev.brightness_set = b43legacy_led_brightness_set;

	err = led_classdev_register(dev->dev->dev, &led->led_dev);
	if (err) {
		b43legacywarn(dev->wl, "LEDs: Failed to register %s\n", name);
		led->dev = NULL;
		return err;
	}
	return 0;
}

static void b43legacy_unregister_led(struct b43legacy_led *led)
{
	if (!led->dev)
		return;
	led_classdev_unregister(&led->led_dev);
	b43legacy_led_turn_off(led->dev, led->index, led->activelow);
	led->dev = NULL;
}

static void b43legacy_map_led(struct b43legacy_wldev *dev,
			u8 led_index,
			enum b43legacy_led_behaviour behaviour,
			bool activelow)
{
	struct ieee80211_hw *hw = dev->wl->hw;
	char name[B43legacy_LED_MAX_NAME_LEN + 1];

	/* Map the b43 specific LED behaviour value to the
	 * generic LED triggers. */
	switch (behaviour) {
	case B43legacy_LED_INACTIVE:
		break;
	case B43legacy_LED_OFF:
		b43legacy_led_turn_off(dev, led_index, activelow);
		break;
	case B43legacy_LED_ON:
		b43legacy_led_turn_on(dev, led_index, activelow);
		break;
	case B43legacy_LED_ACTIVITY:
	case B43legacy_LED_TRANSFER:
	case B43legacy_LED_APTRANSFER:
		snprintf(name, sizeof(name),
			 "b43legacy-%s::tx", wiphy_name(hw->wiphy));
		b43legacy_register_led(dev, &dev->led_tx, name,
				 ieee80211_get_tx_led_name(hw),
				 led_index, activelow);
		snprintf(name, sizeof(name),
			 "b43legacy-%s::rx", wiphy_name(hw->wiphy));
		b43legacy_register_led(dev, &dev->led_rx, name,
				 ieee80211_get_rx_led_name(hw),
				 led_index, activelow);
		break;
	case B43legacy_LED_RADIO_ALL:
	case B43legacy_LED_RADIO_A:
	case B43legacy_LED_RADIO_B:
	case B43legacy_LED_MODE_BG:
		snprintf(name, sizeof(name),
			 "b43legacy-%s::radio", wiphy_name(hw->wiphy));
		b43legacy_register_led(dev, &dev->led_radio, name,
				 ieee80211_get_radio_led_name(hw),
				 led_index, activelow);
		/* Sync the RF-kill LED state with radio and switch states. */
		if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev))
			b43legacy_led_turn_on(dev, led_index, activelow);
		break;
	case B43legacy_LED_WEIRD:
	case B43legacy_LED_ASSOC:
		snprintf(name, sizeof(name),
			 "b43legacy-%s::assoc", wiphy_name(hw->wiphy));
		b43legacy_register_led(dev, &dev->led_assoc, name,
				 ieee80211_get_assoc_led_name(hw),
				 led_index, activelow);
		break;
	default:
		b43legacywarn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n",
			behaviour);
		break;
	}
}

void b43legacy_leds_init(struct b43legacy_wldev *dev)
{
	struct ssb_bus *bus = dev->dev->bus;
	u8 sprom[4];
	int i;
	enum b43legacy_led_behaviour behaviour;
	bool activelow;

	sprom[0] = bus->sprom.gpio0;
	sprom[1] = bus->sprom.gpio1;
	sprom[2] = bus->sprom.gpio2;
	sprom[3] = bus->sprom.gpio3;

	for (i = 0; i < 4; i++) {
		if (sprom[i] == 0xFF) {
			/* There is no LED information in the SPROM
			 * for this LED. Hardcode it here. */
			activelow = false;
			switch (i) {
			case 0:
				behaviour = B43legacy_LED_ACTIVITY;
				activelow = true;
				if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
					behaviour = B43legacy_LED_RADIO_ALL;
				break;
			case 1:
				behaviour = B43legacy_LED_RADIO_B;
				if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
					behaviour = B43legacy_LED_ASSOC;
				break;
			case 2:
				behaviour = B43legacy_LED_RADIO_A;
				break;
			case 3:
				behaviour = B43legacy_LED_OFF;
				break;
			default:
				B43legacy_WARN_ON(1);
				return;
			}
		} else {
			behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR;
			activelow = !!(sprom[i] & B43legacy_LED_ACTIVELOW);
		}
		b43legacy_map_led(dev, i, behaviour, activelow);
	}
}

void b43legacy_leds_exit(struct b43legacy_wldev *dev)
{
	b43legacy_unregister_led(&dev->led_tx);
	b43legacy_unregister_led(&dev->led_rx);
	b43legacy_unregister_led(&dev->led_assoc);
	b43legacy_unregister_led(&dev->led_radio);
}
