Ejemplo n.º 1
0
int iwl_mvm_leds_init(struct iwl_mvm *mvm)
{
	int mode = iwlwifi_mod_params.led_mode;
	int ret;

	switch (mode) {
	case IWL_LED_DEFAULT:
	case IWL_LED_RF_STATE:
		mode = IWL_LED_RF_STATE;
		break;
	case IWL_LED_DISABLE:
		IWL_INFO(mvm, "Led disabled\n");
		return 0;
	default:
		return -EINVAL;
	}

	mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
				   wiphy_name(mvm->hw->wiphy));
	mvm->led.brightness_set = iwl_led_brightness_set;
	mvm->led.max_brightness = 1;

	if (mode == IWL_LED_RF_STATE)
		mvm->led.default_trigger =
			ieee80211_get_radio_led_name(mvm->hw);

	ret = led_classdev_register(mvm->trans->dev, &mvm->led);
	if (ret) {
		kfree(mvm->led.name);
		IWL_INFO(mvm, "Failed to enable led\n");
		return ret;
	}

	return 0;
}
Ejemplo n.º 2
0
void ath_init_leds(struct ath_softc *sc)
{
	char *trigger;
	int ret;

	if (AR_SREV_9287(sc->sc_ah))
		sc->sc_ah->led_pin = ATH_LED_PIN_9287;
	else if (AR_SREV_9300(sc->sc_ah))
		sc->sc_ah->led_pin = ATH_LED_PIN_9300;
	else
		sc->sc_ah->led_pin = ATH_LED_PIN_DEF;

	/* Configure gpio 1 for output */
	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
	/* LED off, active low */
	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);

	if (led_blink)
		INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);

	trigger = ieee80211_get_radio_led_name(sc->hw);
	snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
		"ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
	ret = ath_register_led(sc, &sc->radio_led, trigger);
	sc->radio_led.led_type = ATH_LED_RADIO;
	if (ret)
		goto fail;

	trigger = ieee80211_get_assoc_led_name(sc->hw);
	snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
		"ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
	ret = ath_register_led(sc, &sc->assoc_led, trigger);
	sc->assoc_led.led_type = ATH_LED_ASSOC;
	if (ret)
		goto fail;

	trigger = ieee80211_get_tx_led_name(sc->hw);
	snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
		"ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
	ret = ath_register_led(sc, &sc->tx_led, trigger);
	sc->tx_led.led_type = ATH_LED_TX;
	if (ret)
		goto fail;

	trigger = ieee80211_get_rx_led_name(sc->hw);
	snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
		"ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
	ret = ath_register_led(sc, &sc->rx_led, trigger);
	sc->rx_led.led_type = ATH_LED_RX;
	if (ret)
		goto fail;

	return;

fail:
	if (led_blink)
		cancel_delayed_work_sync(&sc->ath_led_blink_work);
	ath_deinit_leds(sc);
}
Ejemplo n.º 3
0
int p54_init_leds(struct p54_common *priv)
{
	int err;

	/*
	 * TODO:
	 * Figure out if the EEPROM contains some hints about the number
	 * of available/programmable LEDs of the device.
	 */

	INIT_DELAYED_WORK(&priv->led_work, p54_update_leds);

	err = p54_register_led(priv, 0, "assoc",
			       ieee80211_get_assoc_led_name(priv->hw));
	if (err)
		return err;

	err = p54_register_led(priv, 1, "tx",
			       ieee80211_get_tx_led_name(priv->hw));
	if (err)
		return err;

	err = p54_register_led(priv, 2, "rx",
			       ieee80211_get_rx_led_name(priv->hw));
	if (err)
		return err;

	err = p54_register_led(priv, 3, "radio",
			       ieee80211_get_radio_led_name(priv->hw));
	if (err)
		return err;

	err = p54_set_leds(priv);
	return err;
}
Ejemplo n.º 4
0
void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
{
	struct rtl8187_priv *priv = dev->priv;
	char name[RTL8187_LED_MAX_NAME_LEN + 1];
	u8 ledpin;
	int err;

	/* According to the vendor driver, the LED operation depends on the
	 * customer ID encoded in the EEPROM
	 */
	printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid);
	switch (custid) {
	case EEPROM_CID_RSVD0:
	case EEPROM_CID_RSVD1:
	case EEPROM_CID_SERCOMM_PS:
	case EEPROM_CID_QMI:
	case EEPROM_CID_DELL:
	case EEPROM_CID_TOSHIBA:
		ledpin = LED_PIN_GPIO0;
		break;
	case EEPROM_CID_ALPHA0:
		ledpin = LED_PIN_LED0;
		break;
	case EEPROM_CID_HW:
		ledpin = LED_PIN_HW;
		break;
	default:
		ledpin = LED_PIN_GPIO0;
	}

	INIT_DELAYED_WORK(&priv->led_on, led_turn_on);
	INIT_DELAYED_WORK(&priv->led_off, led_turn_off);

	snprintf(name, sizeof(name),
		 "rtl8187-%s::radio", wiphy_name(dev->wiphy));
	err = rtl8187_register_led(dev, &priv->led_radio, name,
			 ieee80211_get_radio_led_name(dev), ledpin, true);
	if (err)
		return;

	snprintf(name, sizeof(name),
		 "rtl8187-%s::tx", wiphy_name(dev->wiphy));
	err = rtl8187_register_led(dev, &priv->led_tx, name,
			 ieee80211_get_tx_led_name(dev), ledpin, false);
	if (err)
		goto err_tx;

	snprintf(name, sizeof(name),
		 "rtl8187-%s::rx", wiphy_name(dev->wiphy));
	err = rtl8187_register_led(dev, &priv->led_rx, name,
			 ieee80211_get_rx_led_name(dev), ledpin, false);
	if (!err)
		return;

	/* registration of RX LED failed - unregister */
	rtl8187_unregister_led(&priv->led_tx);
err_tx:
	rtl8187_unregister_led(&priv->led_radio);
}
static void b43_map_led(struct b43_wldev *dev,
			u8 led_index,
			enum b43_led_behaviour behaviour,
			bool activelow)
{
	struct ieee80211_hw *hw = dev->wl->hw;
	char name[B43_LED_MAX_NAME_LEN + 1];

	/* Map the b43 specific LED behaviour value to the
	 * generic LED triggers. */
	switch (behaviour) {
	case B43_LED_INACTIVE:
	case B43_LED_OFF:
	case B43_LED_ON:
		break;
	case B43_LED_ACTIVITY:
	case B43_LED_TRANSFER:
	case B43_LED_APTRANSFER:
		snprintf(name, sizeof(name),
			 "b43-%s::tx", wiphy_name(hw->wiphy));
		b43_register_led(dev, &dev->wl->leds.led_tx, name,
				 ieee80211_get_tx_led_name(hw),
				 led_index, activelow);
		snprintf(name, sizeof(name),
			 "b43-%s::rx", wiphy_name(hw->wiphy));
		b43_register_led(dev, &dev->wl->leds.led_rx, name,
				 ieee80211_get_rx_led_name(hw),
				 led_index, activelow);
		break;
	case B43_LED_RADIO_ALL:
	case B43_LED_RADIO_A:
	case B43_LED_RADIO_B:
	case B43_LED_MODE_BG:
		snprintf(name, sizeof(name),
			 "b43-%s::radio", wiphy_name(hw->wiphy));
		b43_register_led(dev, &dev->wl->leds.led_radio, name,
				 ieee80211_get_radio_led_name(hw),
				 led_index, activelow);
		break;
	case B43_LED_WEIRD:
	case B43_LED_ASSOC:
		snprintf(name, sizeof(name),
			 "b43-%s::assoc", wiphy_name(hw->wiphy));
		b43_register_led(dev, &dev->wl->leds.led_assoc, name,
				 ieee80211_get_assoc_led_name(hw),
				 led_index, activelow);
		break;
	default:
		b43warn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n",
			behaviour);
		break;
	}
}
Ejemplo n.º 6
0
void iwl_leds_init(struct iwl_priv *priv)
{
	int mode = led_mode;
	int ret;

	if (mode == IWL_LED_DEFAULT)
		mode = priv->cfg->led_mode;

	priv->led.name = kasprintf(GFP_KERNEL, "%s-led",
				   wiphy_name(priv->hw->wiphy));
	priv->led.brightness_set = iwl_led_brightness_set;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25))
	priv->led.blink_set = iwl_led_blink_set;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
	priv->led.max_brightness = 1;
#endif

	switch (mode) {
	case IWL_LED_DEFAULT:
		WARN_ON(1);
		break;
	case IWL_LED_BLINK:
		priv->led.default_trigger =
			ieee80211_create_tpt_led_trigger(priv->hw,
					IEEE80211_TPT_LEDTRIG_FL_CONNECTED,
					iwl_blink, ARRAY_SIZE(iwl_blink));
		break;
	case IWL_LED_RF_STATE:
		priv->led.default_trigger =
			ieee80211_get_radio_led_name(priv->hw);
		break;
	}

	ret = led_classdev_register(&priv->pci_dev->dev, &priv->led);
	if (ret) {
		kfree(priv->led.name);
		return;
	}

	priv->led_registered = true;
}
Ejemplo n.º 7
0
void ath_init_leds(struct ath_softc *sc)
{
	int ret;

	if (AR_SREV_9100(sc->sc_ah))
		return;

	if (sc->sc_ah->led_pin < 0) {
		if (AR_SREV_9287(sc->sc_ah))
			sc->sc_ah->led_pin = ATH_LED_PIN_9287;
		else if (AR_SREV_9485(sc->sc_ah))
			sc->sc_ah->led_pin = ATH_LED_PIN_9485;
		else if (AR_SREV_9300(sc->sc_ah))
			sc->sc_ah->led_pin = ATH_LED_PIN_9300;
		else if (AR_SREV_9462(sc->sc_ah))
			sc->sc_ah->led_pin = ATH_LED_PIN_9462;
		else
			sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
	}

	/* Configure gpio 1 for output */
	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
	/* LED off, active low */
	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);

	if (!led_blink)
		sc->led_cdev.default_trigger =
			ieee80211_get_radio_led_name(sc->hw);

	snprintf(sc->led_name, sizeof(sc->led_name),
		"ath9k-%s", wiphy_name(sc->hw->wiphy));
	sc->led_cdev.name = sc->led_name;
	sc->led_cdev.brightness_set = ath_led_brightness;

	ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
	if (ret < 0)
		return;

	sc->led_registered = true;
}
Ejemplo n.º 8
0
void ath_init_leds(struct ath_softc *sc)
{
	int ret;

	if (AR_SREV_9100(sc->sc_ah))
		return;

	if (!led_blink)
		sc->led_cdev.default_trigger =
			ieee80211_get_radio_led_name(sc->hw);

	snprintf(sc->led_name, sizeof(sc->led_name),
		"ath9k-%s", wiphy_name(sc->hw->wiphy));
	sc->led_cdev.name = sc->led_name;
	sc->led_cdev.brightness_set = ath_led_brightness;

	ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
	if (ret < 0)
		return;

	sc->led_registered = true;
}
Ejemplo n.º 9
0
/* Register all led handler */
int iwl_leds_register(struct iwl_priv *priv)
{
	char *trigger;
	int ret;

	priv->last_blink_rate = 0;
	priv->led_tpt = 0;
	priv->last_blink_time = 0;
	priv->allow_blinking = 0;

	trigger = ieee80211_get_radio_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_RADIO].name,
		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
		 wiphy_name(priv->hw->wiphy));

	priv->led[IWL_LED_TRG_RADIO].led_on = iwl_led_on_reg;
	priv->led[IWL_LED_TRG_RADIO].led_off = iwl_led_off_reg;
	priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;

	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
				   IWL_LED_TRG_RADIO, 1, trigger);
	if (ret)
		goto exit_fail;

	trigger = ieee80211_get_assoc_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
		 wiphy_name(priv->hw->wiphy));

	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
				   IWL_LED_TRG_ASSOC, 0, trigger);

	/* for assoc always turn led on */
	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
	priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;

	if (ret)
		goto exit_fail;

	trigger = ieee80211_get_rx_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_RX].name,
		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
		 wiphy_name(priv->hw->wiphy));

	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
				   IWL_LED_TRG_RX, 0, trigger);

	priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
	priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
	priv->led[IWL_LED_TRG_RX].led_pattern = iwl_led_pattern;

	if (ret)
		goto exit_fail;

	trigger = ieee80211_get_tx_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_TX].name,
		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
		 wiphy_name(priv->hw->wiphy));

	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
				   IWL_LED_TRG_TX, 0, trigger);

	priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
	priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
	priv->led[IWL_LED_TRG_TX].led_pattern = iwl_led_pattern;

	if (ret)
		goto exit_fail;

	return 0;

exit_fail:
	iwl_leds_unregister(priv);
	return ret;
}
Ejemplo n.º 10
0
/* Send led command */
static int iwl_send_led_cmd(struct iwl3945_priv *priv,
			    struct iwl3945_led_cmd *led_cmd)
{
	struct iwl3945_host_cmd cmd = {
		.id = REPLY_LEDS_CMD,
		.len = sizeof(struct iwl3945_led_cmd),
		.data = led_cmd,
		.meta.flags = CMD_ASYNC,
		.meta.u.callback = iwl3945_led_cmd_callback,
	};

	return iwl3945_send_cmd(priv, &cmd);
}



/* Set led on command */
static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
			       unsigned int idx)
{
	struct iwl3945_led_cmd led_cmd = {
		.id = led_id,
		.interval = IWL_DEF_LED_INTRVL
	};

	BUG_ON(idx > IWL_MAX_BLINK_TBL);

	led_cmd.on = blink_tbl[idx].on_time;
	led_cmd.off = blink_tbl[idx].off_time;

	return iwl_send_led_cmd(priv, &led_cmd);
}


#if 1
/* Set led on command */
static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
{
	struct iwl3945_led_cmd led_cmd = {
		.id = led_id,
		.on = IWL_LED_SOLID,
		.off = 0,
		.interval = IWL_DEF_LED_INTRVL
	};
	return iwl_send_led_cmd(priv, &led_cmd);
}

/* Set led off command */
static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
{
	struct iwl3945_led_cmd led_cmd = {
		.id = led_id,
		.on = 0,
		.off = 0,
		.interval = IWL_DEF_LED_INTRVL
	};
	IWL_DEBUG_LED("led off %d\n", led_id);
	return iwl_send_led_cmd(priv, &led_cmd);
}
#endif


/*
 * brightness call back function for Tx/Rx LED
 */
static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
{
	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
	    !test_bit(STATUS_READY, &priv->status))
		return 0;


	/* start counting Tx/Rx bytes */
	if (!priv->last_blink_time && priv->allow_blinking)
		priv->last_blink_time = jiffies;
	return 0;
}

/*
 * brightness call back for association and radio
 */
static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
				enum led_brightness brightness)
{
	struct iwl3945_led *led = container_of(led_cdev,
					       struct iwl3945_led, led_dev);
	struct iwl3945_priv *priv = led->priv;

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	switch (brightness) {
	case LED_FULL:
		if (led->type == IWL_LED_TRG_ASSOC) {
			priv->allow_blinking = 1;
			IWL_DEBUG_LED("MAC is  associated\n");
		}
		if (led->led_on)
			led->led_on(priv, IWL_LED_LINK);
		break;
	case LED_OFF:
		if (led->type == IWL_LED_TRG_ASSOC) {
			priv->allow_blinking = 0;
			IWL_DEBUG_LED("MAC is disassociated\n");
		}
		if (led->led_off)
			led->led_off(priv, IWL_LED_LINK);
		break;
	default:
		if (led->led_pattern) {
			int idx = iwl3945_brightness_to_idx(brightness);
			led->led_pattern(priv, IWL_LED_LINK, idx);
		}
		break;
	}
}



/*
 * Register led class with the system
 */
static int iwl3945_led_register_led(struct iwl3945_priv *priv,
				   struct iwl3945_led *led,
				   enum led_type type, u8 set_led,
				   char *trigger)
{
	struct device *device = wiphy_dev(priv->hw->wiphy);
	int ret;

	led->led_dev.name = led->name;
	led->led_dev.brightness_set = iwl3945_led_brightness_set;
	led->led_dev.default_trigger = trigger;

	led->priv = priv;
	led->type = type;

	ret = led_classdev_register(device, &led->led_dev);
	if (ret) {
		IWL_ERROR("Error: failed to register led handler.\n");
		return ret;
	}

	led->registered = 1;

	if (set_led && led->led_on)
		led->led_on(priv, IWL_LED_LINK);
	return 0;
}


/*
 * calculate blink rate according to last 2 sec Tx/Rx activities
 */
static inline u8 get_blink_rate(struct iwl3945_priv *priv)
{
	int index;
	u64 current_tpt = priv->rxtxpackets;
	s64 tpt = current_tpt - priv->led_tpt;

	if (tpt < 0)
		tpt = -tpt;
	priv->led_tpt = current_tpt;

	if (!priv->allow_blinking)
		index = IWL_MAX_BLINK_TBL;
	else
		for (index = 0; index < IWL_MAX_BLINK_TBL; index++)
			if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE))
				break;
	return index;
}

static inline int is_rf_kill(struct iwl3945_priv *priv)
{
	return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
		test_bit(STATUS_RF_KILL_SW, &priv->status);
}

/*
 * this function called from handler. Since setting Led command can
 * happen very frequent we postpone led command to be called from
 * REPLY handler so we know ucode is up
 */
void iwl3945_led_background(struct iwl3945_priv *priv)
{
	u8 blink_idx;

	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
		priv->last_blink_time = 0;
		return;
	}
	if (is_rf_kill(priv)) {
		priv->last_blink_time = 0;
		return;
	}

	if (!priv->allow_blinking) {
		priv->last_blink_time = 0;
		if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
			priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
			iwl3945_led_pattern(priv, IWL_LED_LINK,
					    IWL_SOLID_BLINK_IDX);
		}
		return;
	}
	if (!priv->last_blink_time ||
	    !time_after(jiffies, priv->last_blink_time +
			msecs_to_jiffies(1000)))
		return;

	blink_idx = get_blink_rate(priv);

	/* call only if blink rate change */
	if (blink_idx != priv->last_blink_rate)
		iwl3945_led_pattern(priv, IWL_LED_LINK, blink_idx);

	priv->last_blink_time = jiffies;
	priv->last_blink_rate = blink_idx;
	priv->rxtxpackets = 0;
}


/* Register all led handler */
int iwl3945_led_register(struct iwl3945_priv *priv)
{
	char *trigger;
	int ret;

	priv->last_blink_rate = 0;
	priv->rxtxpackets = 0;
	priv->led_tpt = 0;
	priv->last_blink_time = 0;
	priv->allow_blinking = 0;

	trigger = ieee80211_get_radio_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_RADIO].name,
		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
		 wiphy_name(priv->hw->wiphy));

	priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
	priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
	priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;

	ret = iwl3945_led_register_led(priv,
				   &priv->led[IWL_LED_TRG_RADIO],
				   IWL_LED_TRG_RADIO, 1, trigger);

	if (ret)
		goto exit_fail;

	trigger = ieee80211_get_assoc_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
		 wiphy_name(priv->hw->wiphy));

	ret = iwl3945_led_register_led(priv,
				   &priv->led[IWL_LED_TRG_ASSOC],
				   IWL_LED_TRG_ASSOC, 0, trigger);

	/* for assoc always turn led on */
	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
	priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;

	if (ret)
		goto exit_fail;

	trigger = ieee80211_get_rx_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_RX].name,
		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
		 wiphy_name(priv->hw->wiphy));

	ret = iwl3945_led_register_led(priv,
				   &priv->led[IWL_LED_TRG_RX],
				   IWL_LED_TRG_RX, 0, trigger);

	priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
	priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
	priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;

	if (ret)
		goto exit_fail;

	trigger = ieee80211_get_tx_led_name(priv->hw);
	snprintf(priv->led[IWL_LED_TRG_TX].name,
		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
		 wiphy_name(priv->hw->wiphy));

	ret = iwl3945_led_register_led(priv,
				   &priv->led[IWL_LED_TRG_TX],
				   IWL_LED_TRG_TX, 0, trigger);

	priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
	priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
	priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;

	if (ret)
		goto exit_fail;

	return 0;

exit_fail:
	iwl3945_led_unregister(priv);
	return ret;
}
Ejemplo n.º 11
0
Archivo: led.c Proyecto: Anjali05/linux
static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)
{
	struct iwl_led_cmd led_cmd = {
		.status = cpu_to_le32(on),
	};
	struct iwl_host_cmd cmd = {
		.id = WIDE_ID(LONG_GROUP, LEDS_CMD),
		.len = { sizeof(led_cmd), },
		.data = { &led_cmd, },
		.flags = CMD_ASYNC,
	};
	int err;

	if (!iwl_mvm_firmware_running(mvm))
		return;

	err = iwl_mvm_send_cmd(mvm, &cmd);

	if (err)
		IWL_WARN(mvm, "LED command failed: %d\n", err);
}

static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)
{
	if (fw_has_capa(&mvm->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT)) {
		iwl_mvm_send_led_fw_cmd(mvm, on);
		return;
	}

	iwl_write32(mvm->trans, CSR_LED_REG,
		    on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);
}

static void iwl_led_brightness_set(struct led_classdev *led_cdev,
				   enum led_brightness brightness)
{
	struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);

	iwl_mvm_led_set(mvm, brightness > 0);
}

int iwl_mvm_leds_init(struct iwl_mvm *mvm)
{
	int mode = iwlwifi_mod_params.led_mode;
	int ret;

	switch (mode) {
	case IWL_LED_BLINK:
		IWL_ERR(mvm, "Blink led mode not supported, used default\n");
		/* fall through */
	case IWL_LED_DEFAULT:
	case IWL_LED_RF_STATE:
		mode = IWL_LED_RF_STATE;
		break;
	case IWL_LED_DISABLE:
		IWL_INFO(mvm, "Led disabled\n");
		return 0;
	default:
		return -EINVAL;
	}

	mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
				   wiphy_name(mvm->hw->wiphy));
	mvm->led.brightness_set = iwl_led_brightness_set;
	mvm->led.max_brightness = 1;

	if (mode == IWL_LED_RF_STATE)
		mvm->led.default_trigger =
			ieee80211_get_radio_led_name(mvm->hw);

	ret = led_classdev_register(mvm->trans->dev, &mvm->led);
	if (ret) {
		kfree(mvm->led.name);
		IWL_INFO(mvm, "Failed to enable led\n");
		return ret;
	}

	mvm->init_status |= IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;
	return 0;
}