Commit 392cacf2 authored by Nikita Kravets's avatar Nikita Kravets Committed by Hans de Goede
Browse files

platform/x86: Add new msi-ec driver

Add a new driver to allow various MSI laptops' functionalities to be
controlled from userspace. This includes such features as power
profiles (aka shift modes), fan speed, charge thresholds, LEDs, etc.

This driver contains EC memory configurations for different firmware
versions and exports battery charge thresholds to userspace (note,
that start and end thresholds control the same EC parameter
and are always 10% apart).

Link: https://github.com/BeardOverflow/msi-ec/
Link: https://github.com/BeardOverflow/msi-ec/pull/13


Cc: Aakash Singh <mail@singhaakash.dev>
Cc: Jose Angel Pastrana <japp0005@red.ujaen.es>
Signed-off-by: default avatarNikita Kravets <teackot@gmail.com>
Link: https://lore.kernel.org/r/20230320225509.3559-1-teackot@gmail.com


Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent fd5aadaa
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -14138,6 +14138,13 @@ S: Odd Fixes
F:	Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
F:	drivers/net/ieee802154/mrf24j40.c
MSI EC DRIVER
M:	Nikita Kravets <teackot@gmail.com>
L:	platform-driver-x86@vger.kernel.org
S:	Maintained
W:	https://github.com/BeardOverflow/msi-ec
F:	drivers/platform/x86/msi-ec.*
MSI LAPTOP SUPPORT
M:	"Lee, Chun-Yi" <jlee@suse.com>
L:	platform-driver-x86@vger.kernel.org
+8 −0
Original line number Diff line number Diff line
@@ -635,6 +635,14 @@ config THINKPAD_LMI

source "drivers/platform/x86/intel/Kconfig"

config MSI_EC
	tristate "MSI EC Extras"
	depends on ACPI
	depends on ACPI_BATTERY
	help
	  This driver allows various MSI laptops' functionalities to be
	  controlled from userspace, including battery charge threshold.

config MSI_LAPTOP
	tristate "MSI Laptop Extras"
	depends on ACPI
+1 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ obj-$(CONFIG_THINKPAD_LMI) += think-lmi.o
obj-y				+= intel/

# MSI
obj-$(CONFIG_MSI_EC)		+= msi-ec.o
obj-$(CONFIG_MSI_LAPTOP)	+= msi-laptop.o
obj-$(CONFIG_MSI_WMI)		+= msi-wmi.o

+897 −0

File added.

Preview size limit exceeded, changes collapsed.

+122 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-or-later */

/*
 * msi-ec: MSI laptops' embedded controller driver.
 *
 * Copyright (C) 2023 Jose Angel Pastrana <japp0005@red.ujaen.es>
 * Copyright (C) 2023 Aakash Singh <mail@singhaakash.dev>
 * Copyright (C) 2023 Nikita Kravets <teackot@gmail.com>
 */

#ifndef _MSI_EC_H_
#define _MSI_EC_H_

#include <linux/types.h>

#define MSI_EC_DRIVER_NAME "msi-ec"

#define MSI_EC_ADDR_UNKNOWN 0xff01 // unknown address
#define MSI_EC_ADDR_UNSUPP  0xff01 // unsupported parameter

// Firmware info addresses are universal
#define MSI_EC_FW_VERSION_ADDRESS 0xa0
#define MSI_EC_FW_DATE_ADDRESS    0xac
#define MSI_EC_FW_TIME_ADDRESS    0xb4
#define MSI_EC_FW_VERSION_LENGTH  12
#define MSI_EC_FW_DATE_LENGTH     8
#define MSI_EC_FW_TIME_LENGTH     8

struct msi_ec_charge_control_conf {
	int address;
	int offset_start;
	int offset_end;
	int range_min;
	int range_max;
};

struct msi_ec_webcam_conf {
	int address;
	int block_address;
	int bit;
};

struct msi_ec_fn_super_swap_conf {
	int address;
	int bit;
};

struct msi_ec_cooler_boost_conf {
	int address;
	int bit;
};

#define MSI_EC_MODE_NULL { NULL, 0 }
struct msi_ec_mode {
	const char *name;
	int value;
};

struct msi_ec_shift_mode_conf {
	int address;
	struct msi_ec_mode modes[5]; // fixed size for easier hard coding
};

struct msi_ec_super_battery_conf {
	int address;
	int mask;
};

struct msi_ec_fan_mode_conf {
	int address;
	struct msi_ec_mode modes[5]; // fixed size for easier hard coding
};

struct msi_ec_cpu_conf {
	int rt_temp_address;
	int rt_fan_speed_address; // realtime
	int rt_fan_speed_base_min;
	int rt_fan_speed_base_max;
	int bs_fan_speed_address; // basic
	int bs_fan_speed_base_min;
	int bs_fan_speed_base_max;
};

struct msi_ec_gpu_conf {
	int rt_temp_address;
	int rt_fan_speed_address; // realtime
};

struct msi_ec_led_conf {
	int micmute_led_address;
	int mute_led_address;
	int bit;
};

#define MSI_EC_KBD_BL_STATE_MASK 0x3
struct msi_ec_kbd_bl_conf {
	int bl_mode_address;
	int bl_modes[2];
	int max_mode;

	int bl_state_address;
	int state_base_value;
	int max_state;
};

struct msi_ec_conf {
	const char * const *allowed_fw;

	struct msi_ec_charge_control_conf charge_control;
	struct msi_ec_webcam_conf         webcam;
	struct msi_ec_fn_super_swap_conf  fn_super_swap;
	struct msi_ec_cooler_boost_conf   cooler_boost;
	struct msi_ec_shift_mode_conf     shift_mode;
	struct msi_ec_super_battery_conf  super_battery;
	struct msi_ec_fan_mode_conf       fan_mode;
	struct msi_ec_cpu_conf            cpu;
	struct msi_ec_gpu_conf            gpu;
	struct msi_ec_led_conf            leds;
	struct msi_ec_kbd_bl_conf         kbd_bl;
};

#endif // _MSI_EC_H_