Path: blob/main/sys/contrib/dev/iwlwifi/mvm/led.c
107830 views
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause1/*2* Copyright (C) 2012-2014, 2018-2019, 2025 Intel Corporation3* Copyright (C) 2017 Intel Deutschland GmbH4*/5#include <linux/leds.h>6#include "iwl-io.h"7#include "iwl-csr.h"8#include "mvm.h"910static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)11{12struct iwl_led_cmd led_cmd = {13.status = cpu_to_le32(on),14};15struct iwl_host_cmd cmd = {16.id = WIDE_ID(LONG_GROUP, LEDS_CMD),17.len = { sizeof(led_cmd), },18.data = { &led_cmd, },19.flags = CMD_ASYNC,20};21int err;2223if (!iwl_mvm_firmware_running(mvm))24return;2526err = iwl_mvm_send_cmd(mvm, &cmd);2728if (err)29IWL_WARN(mvm, "LED command failed: %d\n", err);30}3132static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)33{34if (fw_has_capa(&mvm->fw->ucode_capa,35IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT)) {36iwl_mvm_send_led_fw_cmd(mvm, on);37return;38}3940iwl_write32(mvm->trans, CSR_LED_REG,41on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);42}4344static void iwl_led_brightness_set(struct led_classdev *led_cdev,45enum led_brightness brightness)46{47struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);4849iwl_mvm_led_set(mvm, brightness > 0);50}5152int iwl_mvm_leds_init(struct iwl_mvm *mvm)53{54int mode = iwlwifi_mod_params.led_mode;55int ret;5657switch (mode) {58case IWL_LED_BLINK:59IWL_ERR(mvm, "Blink led mode not supported, used default\n");60fallthrough;61case IWL_LED_DEFAULT:62case IWL_LED_RF_STATE:63mode = IWL_LED_RF_STATE;64break;65case IWL_LED_DISABLE:66IWL_INFO(mvm, "Led disabled\n");67return 0;68default:69return -EINVAL;70}7172mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",73wiphy_name(mvm->hw->wiphy));74if (!mvm->led.name)75return -ENOMEM;7677mvm->led.brightness_set = iwl_led_brightness_set;78mvm->led.max_brightness = 1;7980if (mode == IWL_LED_RF_STATE)81mvm->led.default_trigger =82ieee80211_get_radio_led_name(mvm->hw);8384ret = led_classdev_register(mvm->trans->dev, &mvm->led);85if (ret) {86kfree(mvm->led.name);87IWL_INFO(mvm, "Failed to enable led\n");88return ret;89}9091mvm->init_status |= IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;92return 0;93}9495void iwl_mvm_leds_sync(struct iwl_mvm *mvm)96{97if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))98return;99100/*101* if we control through the register, we're doing it102* even when the firmware isn't up, so no need to sync103*/104if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000)105return;106107iwl_mvm_led_set(mvm, mvm->led.brightness > 0);108}109110void iwl_mvm_leds_exit(struct iwl_mvm *mvm)111{112if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))113return;114115led_classdev_unregister(&mvm->led);116kfree(mvm->led.name);117mvm->init_status &= ~IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;118}119120121