mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-15 19:45:26 +00:00
platform-drivers-x86 for v6.2-3
Highlights: - Fix false positive apple_gmux backlight detection on older iGPU only MacBook models - Various other small fixes and hardware-id additions The following is an automated git shortlog grouped by driver: ACPI: - video: Fix apple gmux detection apple-gmux: - Add apple_gmux_detect() helper - Move port defines to apple-gmux.h asus-wmi: - Fix kbd_dock_devid tablet-switch reporting dell-wmi: - Add a keymap for KEY_MUTE in type 0x0010 table gigabyte-wmi: - add support for B450M DS3H WIFI-CF hp-wmi: - Fix cast to smaller integer type warning - Handle Omen Key event platform/x86/amd: - pmc: Add a module parameter to disable workarounds - pmc: Disable IRQ1 wakeup for RN/CZN thinkpad_acpi: - Fix profile modes on Intel platforms -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEEuvA7XScYQRpenhd+kuxHeUQDJ9wFAmPShrkUHGhkZWdvZWRl QHJlZGhhdC5jb20ACgkQkuxHeUQDJ9yo5wgAlfTc6R4vZrtg5W8O5y2ZghMLTNLM TsT5uzoFdz76xB62fh4RUPn4WWLftvKvOxXVTITSZe4rj3TR1voQM1vZedV6IcDX 6rFwMKpZDnerP5N07S7QlmGcDMIaFtsQGIjND6ZzcdS6RJRSdE/CcfyEO3IGgUxq C1AWHm8Rh0Iq9ZdudFT5i7PXiFjCJyEZvRJXXFb1ZhDFdpCsfV/1lDx1D05/Hbk8 Ovm9yL3QXwxTbsIPZ7tgyDX0Uw/F7uaROGyNoo7LCxrY9ow0hfDV4KWO02+Dwf6n Sl5rTwZZiQ13RL2h/3za05qFLemZ2o16xH7zntIuMuLkOzFPHF8Y7Gle5A== =ryVq -----END PGP SIGNATURE----- Merge tag 'platform-drivers-x86-v6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86 Pull x86 platform driver fixes from Hans de Goede: - Fix false positive apple_gmux backlight detection on older iGPU only MacBook models - Various other small fixes and hardware-id additions * tag 'platform-drivers-x86-v6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: platform/x86: thinkpad_acpi: Fix profile modes on Intel platforms ACPI: video: Fix apple gmux detection platform/x86: apple-gmux: Add apple_gmux_detect() helper platform/x86: apple-gmux: Move port defines to apple-gmux.h platform/x86: hp-wmi: Fix cast to smaller integer type warning platform/x86/amd: pmc: Add a module parameter to disable workarounds platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN platform/x86: asus-wmi: Fix kbd_dock_devid tablet-switch reporting platform/x86: gigabyte-wmi: add support for B450M DS3H WIFI-CF platform/x86: hp-wmi: Handle Omen Key event platform/x86: dell-wmi: Add a keymap for KEY_MUTE in type 0x0010 table
This commit is contained in:
commit
83abd4d4c4
9 changed files with 211 additions and 111 deletions
|
@ -110,26 +110,6 @@ static bool nvidia_wmi_ec_supported(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool apple_gmux_backlight_present(void)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
struct device *dev;
|
||||
|
||||
adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1);
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
dev = acpi_get_first_physical_node(adev);
|
||||
if (!dev)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* drivers/platform/x86/apple-gmux.c only supports old style
|
||||
* Apple GMUX with an IO-resource.
|
||||
*/
|
||||
return pnp_get_resource(to_pnp_dev(dev), IORESOURCE_IO, 0) != NULL;
|
||||
}
|
||||
|
||||
/* Force to use vendor driver when the ACPI device is known to be
|
||||
* buggy */
|
||||
static int video_detect_force_vendor(const struct dmi_system_id *d)
|
||||
|
@ -766,6 +746,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
|
|||
{
|
||||
static DEFINE_MUTEX(init_mutex);
|
||||
static bool nvidia_wmi_ec_present;
|
||||
static bool apple_gmux_present;
|
||||
static bool native_available;
|
||||
static bool init_done;
|
||||
static long video_caps;
|
||||
|
@ -779,6 +760,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
|
|||
ACPI_UINT32_MAX, find_video, NULL,
|
||||
&video_caps, NULL);
|
||||
nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
|
||||
apple_gmux_present = apple_gmux_detect(NULL, NULL);
|
||||
init_done = true;
|
||||
}
|
||||
if (native)
|
||||
|
@ -800,7 +782,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
|
|||
if (nvidia_wmi_ec_present)
|
||||
return acpi_backlight_nvidia_wmi_ec;
|
||||
|
||||
if (apple_gmux_backlight_present())
|
||||
if (apple_gmux_present)
|
||||
return acpi_backlight_apple_gmux;
|
||||
|
||||
/* Use ACPI video if available, except when native should be preferred. */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -160,6 +161,10 @@ static bool enable_stb;
|
|||
module_param(enable_stb, bool, 0644);
|
||||
MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
|
||||
|
||||
static bool disable_workarounds;
|
||||
module_param(disable_workarounds, bool, 0644);
|
||||
MODULE_PARM_DESC(disable_workarounds, "Disable workarounds for platform bugs");
|
||||
|
||||
static struct amd_pmc_dev pmc;
|
||||
static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
|
||||
static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
|
||||
|
@ -653,6 +658,33 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int amd_pmc_czn_wa_irq1(struct amd_pmc_dev *pdev)
|
||||
{
|
||||
struct device *d;
|
||||
int rc;
|
||||
|
||||
if (!pdev->major) {
|
||||
rc = amd_pmc_get_smu_version(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (pdev->major > 64 || (pdev->major == 64 && pdev->minor > 65))
|
||||
return 0;
|
||||
|
||||
d = bus_find_device_by_name(&serio_bus, NULL, "serio0");
|
||||
if (!d)
|
||||
return 0;
|
||||
if (device_may_wakeup(d)) {
|
||||
dev_info_once(d, "Disabling IRQ1 wakeup source to avoid platform firmware bug\n");
|
||||
disable_irq_wake(1);
|
||||
device_set_wakeup_enable(d, false);
|
||||
}
|
||||
put_device(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
|
||||
{
|
||||
struct rtc_device *rtc_device;
|
||||
|
@ -715,8 +747,8 @@ static void amd_pmc_s2idle_prepare(void)
|
|||
/* Reset and Start SMU logging - to monitor the s0i3 stats */
|
||||
amd_pmc_setup_smu_logging(pdev);
|
||||
|
||||
/* Activate CZN specific RTC functionality */
|
||||
if (pdev->cpu_id == AMD_CPU_ID_CZN) {
|
||||
/* Activate CZN specific platform bug workarounds */
|
||||
if (pdev->cpu_id == AMD_CPU_ID_CZN && !disable_workarounds) {
|
||||
rc = amd_pmc_verify_czn_rtc(pdev, &arg);
|
||||
if (rc) {
|
||||
dev_err(pdev->dev, "failed to set RTC: %d\n", rc);
|
||||
|
@ -782,6 +814,25 @@ static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
|
|||
.check = amd_pmc_s2idle_check,
|
||||
.restore = amd_pmc_s2idle_restore,
|
||||
};
|
||||
|
||||
static int __maybe_unused amd_pmc_suspend_handler(struct device *dev)
|
||||
{
|
||||
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (pdev->cpu_id == AMD_CPU_ID_CZN && !disable_workarounds) {
|
||||
int rc = amd_pmc_czn_wa_irq1(pdev);
|
||||
|
||||
if (rc) {
|
||||
dev_err(pdev->dev, "failed to adjust keyboard wakeup: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL);
|
||||
|
||||
#endif
|
||||
|
||||
static const struct pci_device_id pmc_pci_ids[] = {
|
||||
|
@ -980,6 +1031,9 @@ static struct platform_driver amd_pmc_driver = {
|
|||
.name = "amd_pmc",
|
||||
.acpi_match_table = amd_pmc_acpi_ids,
|
||||
.dev_groups = pmc_groups,
|
||||
#ifdef CONFIG_SUSPEND
|
||||
.pm = &amd_pmc_pm,
|
||||
#endif
|
||||
},
|
||||
.probe = amd_pmc_probe,
|
||||
.remove = amd_pmc_remove,
|
||||
|
|
|
@ -64,29 +64,6 @@ struct apple_gmux_data {
|
|||
|
||||
static struct apple_gmux_data *apple_gmux_data;
|
||||
|
||||
/*
|
||||
* gmux port offsets. Many of these are not yet used, but may be in the
|
||||
* future, and it's useful to have them documented here anyhow.
|
||||
*/
|
||||
#define GMUX_PORT_VERSION_MAJOR 0x04
|
||||
#define GMUX_PORT_VERSION_MINOR 0x05
|
||||
#define GMUX_PORT_VERSION_RELEASE 0x06
|
||||
#define GMUX_PORT_SWITCH_DISPLAY 0x10
|
||||
#define GMUX_PORT_SWITCH_GET_DISPLAY 0x11
|
||||
#define GMUX_PORT_INTERRUPT_ENABLE 0x14
|
||||
#define GMUX_PORT_INTERRUPT_STATUS 0x16
|
||||
#define GMUX_PORT_SWITCH_DDC 0x28
|
||||
#define GMUX_PORT_SWITCH_EXTERNAL 0x40
|
||||
#define GMUX_PORT_SWITCH_GET_EXTERNAL 0x41
|
||||
#define GMUX_PORT_DISCRETE_POWER 0x50
|
||||
#define GMUX_PORT_MAX_BRIGHTNESS 0x70
|
||||
#define GMUX_PORT_BRIGHTNESS 0x74
|
||||
#define GMUX_PORT_VALUE 0xc2
|
||||
#define GMUX_PORT_READ 0xd0
|
||||
#define GMUX_PORT_WRITE 0xd4
|
||||
|
||||
#define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4)
|
||||
|
||||
#define GMUX_INTERRUPT_ENABLE 0xff
|
||||
#define GMUX_INTERRUPT_DISABLE 0x00
|
||||
|
||||
|
@ -249,23 +226,6 @@ static void gmux_write32(struct apple_gmux_data *gmux_data, int port,
|
|||
gmux_pio_write32(gmux_data, port, val);
|
||||
}
|
||||
|
||||
static bool gmux_is_indexed(struct apple_gmux_data *gmux_data)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
outb(0xaa, gmux_data->iostart + 0xcc);
|
||||
outb(0x55, gmux_data->iostart + 0xcd);
|
||||
outb(0x00, gmux_data->iostart + 0xce);
|
||||
|
||||
val = inb(gmux_data->iostart + 0xcc) |
|
||||
(inb(gmux_data->iostart + 0xcd) << 8);
|
||||
|
||||
if (val == 0x55aa)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOC: Backlight control
|
||||
*
|
||||
|
@ -605,60 +565,43 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
|
|||
int ret = -ENXIO;
|
||||
acpi_status status;
|
||||
unsigned long long gpe;
|
||||
bool indexed = false;
|
||||
u32 version;
|
||||
|
||||
if (apple_gmux_data)
|
||||
return -EBUSY;
|
||||
|
||||
if (!apple_gmux_detect(pnp, &indexed)) {
|
||||
pr_info("gmux device not present\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL);
|
||||
if (!gmux_data)
|
||||
return -ENOMEM;
|
||||
pnp_set_drvdata(pnp, gmux_data);
|
||||
|
||||
res = pnp_get_resource(pnp, IORESOURCE_IO, 0);
|
||||
if (!res) {
|
||||
pr_err("Failed to find gmux I/O resource\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
gmux_data->iostart = res->start;
|
||||
gmux_data->iolen = resource_size(res);
|
||||
|
||||
if (gmux_data->iolen < GMUX_MIN_IO_LEN) {
|
||||
pr_err("gmux I/O region too small (%lu < %u)\n",
|
||||
gmux_data->iolen, GMUX_MIN_IO_LEN);
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (!request_region(gmux_data->iostart, gmux_data->iolen,
|
||||
"Apple gmux")) {
|
||||
pr_err("gmux I/O already in use\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalid version information may indicate either that the gmux
|
||||
* device isn't present or that it's a new one that uses indexed
|
||||
* io
|
||||
*/
|
||||
|
||||
ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
|
||||
ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
|
||||
ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
|
||||
if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
|
||||
if (gmux_is_indexed(gmux_data)) {
|
||||
u32 version;
|
||||
mutex_init(&gmux_data->index_lock);
|
||||
gmux_data->indexed = true;
|
||||
version = gmux_read32(gmux_data,
|
||||
GMUX_PORT_VERSION_MAJOR);
|
||||
ver_major = (version >> 24) & 0xff;
|
||||
ver_minor = (version >> 16) & 0xff;
|
||||
ver_release = (version >> 8) & 0xff;
|
||||
} else {
|
||||
pr_info("gmux device not present\n");
|
||||
ret = -ENODEV;
|
||||
goto err_release;
|
||||
}
|
||||
if (indexed) {
|
||||
mutex_init(&gmux_data->index_lock);
|
||||
gmux_data->indexed = true;
|
||||
version = gmux_read32(gmux_data, GMUX_PORT_VERSION_MAJOR);
|
||||
ver_major = (version >> 24) & 0xff;
|
||||
ver_minor = (version >> 16) & 0xff;
|
||||
ver_release = (version >> 8) & 0xff;
|
||||
} else {
|
||||
ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
|
||||
ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
|
||||
ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
|
||||
}
|
||||
pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor,
|
||||
ver_release, (gmux_data->indexed ? "indexed" : "classic"));
|
||||
|
|
|
@ -225,6 +225,7 @@ struct asus_wmi {
|
|||
|
||||
int tablet_switch_event_code;
|
||||
u32 tablet_switch_dev_id;
|
||||
bool tablet_switch_inverted;
|
||||
|
||||
enum fan_type fan_type;
|
||||
enum fan_type gpu_fan_type;
|
||||
|
@ -493,6 +494,13 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
|
|||
}
|
||||
|
||||
/* Input **********************************************************************/
|
||||
static void asus_wmi_tablet_sw_report(struct asus_wmi *asus, bool value)
|
||||
{
|
||||
input_report_switch(asus->inputdev, SW_TABLET_MODE,
|
||||
asus->tablet_switch_inverted ? !value : value);
|
||||
input_sync(asus->inputdev);
|
||||
}
|
||||
|
||||
static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event_code)
|
||||
{
|
||||
struct device *dev = &asus->platform_device->dev;
|
||||
|
@ -501,7 +509,7 @@ static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event
|
|||
result = asus_wmi_get_devstate_simple(asus, dev_id);
|
||||
if (result >= 0) {
|
||||
input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
|
||||
input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
|
||||
asus_wmi_tablet_sw_report(asus, result);
|
||||
asus->tablet_switch_dev_id = dev_id;
|
||||
asus->tablet_switch_event_code = event_code;
|
||||
} else if (result == -ENODEV) {
|
||||
|
@ -534,6 +542,7 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
|
|||
case asus_wmi_no_tablet_switch:
|
||||
break;
|
||||
case asus_wmi_kbd_dock_devid:
|
||||
asus->tablet_switch_inverted = true;
|
||||
asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_KBD_DOCK, NOTIFY_KBD_DOCK_CHANGE);
|
||||
break;
|
||||
case asus_wmi_lid_flip_devid:
|
||||
|
@ -573,10 +582,8 @@ static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus)
|
|||
return;
|
||||
|
||||
result = asus_wmi_get_devstate_simple(asus, asus->tablet_switch_dev_id);
|
||||
if (result >= 0) {
|
||||
input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
|
||||
input_sync(asus->inputdev);
|
||||
}
|
||||
if (result >= 0)
|
||||
asus_wmi_tablet_sw_report(asus, result);
|
||||
}
|
||||
|
||||
/* dGPU ********************************************************************/
|
||||
|
|
|
@ -261,6 +261,9 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = {
|
|||
{ KE_KEY, 0x57, { KEY_BRIGHTNESSDOWN } },
|
||||
{ KE_KEY, 0x58, { KEY_BRIGHTNESSUP } },
|
||||
|
||||
/*Speaker Mute*/
|
||||
{ KE_KEY, 0x109, { KEY_MUTE} },
|
||||
|
||||
/* Mic mute */
|
||||
{ KE_KEY, 0x150, { KEY_MICMUTE } },
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
|
|||
|
||||
static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
|
||||
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H-CF"),
|
||||
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H WIFI-CF"),
|
||||
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"),
|
||||
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE AX V2"),
|
||||
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"),
|
||||
|
|
|
@ -90,6 +90,7 @@ enum hp_wmi_event_ids {
|
|||
HPWMI_PEAKSHIFT_PERIOD = 0x0F,
|
||||
HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
|
||||
HPWMI_SANITIZATION_MODE = 0x17,
|
||||
HPWMI_OMEN_KEY = 0x1D,
|
||||
HPWMI_SMART_EXPERIENCE_APP = 0x21,
|
||||
};
|
||||
|
||||
|
@ -216,6 +217,8 @@ static const struct key_entry hp_wmi_keymap[] = {
|
|||
{ KE_KEY, 0x213b, { KEY_INFO } },
|
||||
{ KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } },
|
||||
{ KE_KEY, 0x216a, { KEY_SETUP } },
|
||||
{ KE_KEY, 0x21a5, { KEY_PROG2 } }, /* HP Omen Key */
|
||||
{ KE_KEY, 0x21a7, { KEY_FN_ESC } },
|
||||
{ KE_KEY, 0x21a9, { KEY_TOUCHPAD_OFF } },
|
||||
{ KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } },
|
||||
{ KE_KEY, 0x231b, { KEY_HELP } },
|
||||
|
@ -548,7 +551,7 @@ static int __init hp_wmi_enable_hotkeys(void)
|
|||
|
||||
static int hp_wmi_set_block(void *data, bool blocked)
|
||||
{
|
||||
enum hp_wmi_radio r = (enum hp_wmi_radio) data;
|
||||
enum hp_wmi_radio r = (long)data;
|
||||
int query = BIT(r + 8) | ((!blocked) << r);
|
||||
int ret;
|
||||
|
||||
|
@ -810,6 +813,7 @@ static void hp_wmi_notify(u32 value, void *context)
|
|||
case HPWMI_SMART_ADAPTER:
|
||||
break;
|
||||
case HPWMI_BEZEL_BUTTON:
|
||||
case HPWMI_OMEN_KEY:
|
||||
key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
|
||||
if (key_code < 0)
|
||||
break;
|
||||
|
|
|
@ -10496,8 +10496,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
|
|||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
|
||||
} else if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
|
||||
err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
@ -10525,14 +10524,16 @@ static void dytc_profile_refresh(void)
|
|||
err = dytc_command(DYTC_CMD_MMC_GET, &output);
|
||||
else
|
||||
err = dytc_cql_command(DYTC_CMD_GET, &output);
|
||||
} else if (dytc_capabilities & BIT(DYTC_FC_PSC))
|
||||
funcmode = DYTC_FUNCTION_MMC;
|
||||
} else if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
|
||||
err = dytc_command(DYTC_CMD_GET, &output);
|
||||
|
||||
/* Check if we are PSC mode, or have AMT enabled */
|
||||
funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF;
|
||||
}
|
||||
mutex_unlock(&dytc_mutex);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF;
|
||||
perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF;
|
||||
convert_dytc_to_profile(funcmode, perfmode, &profile);
|
||||
if (profile != dytc_current_profile) {
|
||||
|
|
|
@ -8,18 +8,118 @@
|
|||
#define LINUX_APPLE_GMUX_H
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pnp.h>
|
||||
|
||||
#define GMUX_ACPI_HID "APP000B"
|
||||
|
||||
/*
|
||||
* gmux port offsets. Many of these are not yet used, but may be in the
|
||||
* future, and it's useful to have them documented here anyhow.
|
||||
*/
|
||||
#define GMUX_PORT_VERSION_MAJOR 0x04
|
||||
#define GMUX_PORT_VERSION_MINOR 0x05
|
||||
#define GMUX_PORT_VERSION_RELEASE 0x06
|
||||
#define GMUX_PORT_SWITCH_DISPLAY 0x10
|
||||
#define GMUX_PORT_SWITCH_GET_DISPLAY 0x11
|
||||
#define GMUX_PORT_INTERRUPT_ENABLE 0x14
|
||||
#define GMUX_PORT_INTERRUPT_STATUS 0x16
|
||||
#define GMUX_PORT_SWITCH_DDC 0x28
|
||||
#define GMUX_PORT_SWITCH_EXTERNAL 0x40
|
||||
#define GMUX_PORT_SWITCH_GET_EXTERNAL 0x41
|
||||
#define GMUX_PORT_DISCRETE_POWER 0x50
|
||||
#define GMUX_PORT_MAX_BRIGHTNESS 0x70
|
||||
#define GMUX_PORT_BRIGHTNESS 0x74
|
||||
#define GMUX_PORT_VALUE 0xc2
|
||||
#define GMUX_PORT_READ 0xd0
|
||||
#define GMUX_PORT_WRITE 0xd4
|
||||
|
||||
#define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4)
|
||||
|
||||
#if IS_ENABLED(CONFIG_APPLE_GMUX)
|
||||
static inline bool apple_gmux_is_indexed(unsigned long iostart)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
outb(0xaa, iostart + 0xcc);
|
||||
outb(0x55, iostart + 0xcd);
|
||||
outb(0x00, iostart + 0xce);
|
||||
|
||||
val = inb(iostart + 0xcc) | (inb(iostart + 0xcd) << 8);
|
||||
if (val == 0x55aa)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* apple_gmux_present() - detect if gmux is built into the machine
|
||||
* apple_gmux_detect() - detect if gmux is built into the machine
|
||||
*
|
||||
* @pnp_dev: Device to probe or NULL to use the first matching device
|
||||
* @indexed_ret: Returns (by reference) if the gmux is indexed or not
|
||||
*
|
||||
* Detect if a supported gmux device is present by actually probing it.
|
||||
* This avoids the false positives returned on some models by
|
||||
* apple_gmux_present().
|
||||
*
|
||||
* Return: %true if a supported gmux ACPI device is detected and the kernel
|
||||
* was configured with CONFIG_APPLE_GMUX, %false otherwise.
|
||||
*/
|
||||
static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret)
|
||||
{
|
||||
u8 ver_major, ver_minor, ver_release;
|
||||
struct device *dev = NULL;
|
||||
struct acpi_device *adev;
|
||||
struct resource *res;
|
||||
bool indexed = false;
|
||||
bool ret = false;
|
||||
|
||||
if (!pnp_dev) {
|
||||
adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1);
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
dev = get_device(acpi_get_first_physical_node(adev));
|
||||
acpi_dev_put(adev);
|
||||
if (!dev)
|
||||
return false;
|
||||
|
||||
pnp_dev = to_pnp_dev(dev);
|
||||
}
|
||||
|
||||
res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0);
|
||||
if (!res || resource_size(res) < GMUX_MIN_IO_LEN)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Invalid version information may indicate either that the gmux
|
||||
* device isn't present or that it's a new one that uses indexed io.
|
||||
*/
|
||||
ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR);
|
||||
ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR);
|
||||
ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE);
|
||||
if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
|
||||
indexed = apple_gmux_is_indexed(res->start);
|
||||
if (!indexed)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (indexed_ret)
|
||||
*indexed_ret = indexed;
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
put_device(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* apple_gmux_present() - check if gmux ACPI device is present
|
||||
*
|
||||
* Drivers may use this to activate quirks specific to dual GPU MacBook Pros
|
||||
* and Mac Pros, e.g. for deferred probing, runtime pm and backlight.
|
||||
*
|
||||
* Return: %true if gmux is present and the kernel was configured
|
||||
* Return: %true if gmux ACPI device is present and the kernel was configured
|
||||
* with CONFIG_APPLE_GMUX, %false otherwise.
|
||||
*/
|
||||
static inline bool apple_gmux_present(void)
|
||||
|
@ -34,6 +134,11 @@ static inline bool apple_gmux_present(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_APPLE_GMUX */
|
||||
|
||||
#endif /* LINUX_APPLE_GMUX_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue