brintos

brintos / linux-shallow public Read only

0
0
Text · 2.7 KiB · 1ea7c44 Raw
120 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2/*3 * Copyright (C) 2012-2014, 2018-2019 Intel Corporation4 * Copyright (C) 2017 Intel Deutschland GmbH5 */6#include <linux/leds.h>7#include "iwl-io.h"8#include "iwl-csr.h"9#include "mvm.h"10 11static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)12{13	struct iwl_led_cmd led_cmd = {14		.status = cpu_to_le32(on),15	};16	struct iwl_host_cmd cmd = {17		.id = WIDE_ID(LONG_GROUP, LEDS_CMD),18		.len = { sizeof(led_cmd), },19		.data = { &led_cmd, },20		.flags = CMD_ASYNC,21	};22	int err;23 24	if (!iwl_mvm_firmware_running(mvm))25		return;26 27	err = iwl_mvm_send_cmd(mvm, &cmd);28 29	if (err)30		IWL_WARN(mvm, "LED command failed: %d\n", err);31}32 33static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)34{35	if (fw_has_capa(&mvm->fw->ucode_capa,36			IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT)) {37		iwl_mvm_send_led_fw_cmd(mvm, on);38		return;39	}40 41	iwl_write32(mvm->trans, CSR_LED_REG,42		    on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);43}44 45static void iwl_led_brightness_set(struct led_classdev *led_cdev,46				   enum led_brightness brightness)47{48	struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);49 50	iwl_mvm_led_set(mvm, brightness > 0);51}52 53int iwl_mvm_leds_init(struct iwl_mvm *mvm)54{55	int mode = iwlwifi_mod_params.led_mode;56	int ret;57 58	switch (mode) {59	case IWL_LED_BLINK:60		IWL_ERR(mvm, "Blink led mode not supported, used default\n");61		fallthrough;62	case IWL_LED_DEFAULT:63	case IWL_LED_RF_STATE:64		mode = IWL_LED_RF_STATE;65		break;66	case IWL_LED_DISABLE:67		IWL_INFO(mvm, "Led disabled\n");68		return 0;69	default:70		return -EINVAL;71	}72 73	mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",74				   wiphy_name(mvm->hw->wiphy));75	if (!mvm->led.name)76		return -ENOMEM;77 78	mvm->led.brightness_set = iwl_led_brightness_set;79	mvm->led.max_brightness = 1;80 81	if (mode == IWL_LED_RF_STATE)82		mvm->led.default_trigger =83			ieee80211_get_radio_led_name(mvm->hw);84 85	ret = led_classdev_register(mvm->trans->dev, &mvm->led);86	if (ret) {87		kfree(mvm->led.name);88		IWL_INFO(mvm, "Failed to enable led\n");89		return ret;90	}91 92	mvm->init_status |= IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;93	return 0;94}95 96void iwl_mvm_leds_sync(struct iwl_mvm *mvm)97{98	if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))99		return;100 101	/*102	 * if we control through the register, we're doing it103	 * even when the firmware isn't up, so no need to sync104	 */105	if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)106		return;107 108	iwl_mvm_led_set(mvm, mvm->led.brightness > 0);109}110 111void iwl_mvm_leds_exit(struct iwl_mvm *mvm)112{113	if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))114		return;115 116	led_classdev_unregister(&mvm->led);117	kfree(mvm->led.name);118	mvm->init_status &= ~IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;119}120