summaryrefslogtreecommitdiff
path: root/drivers/platform/x86/msi-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/msi-laptop.c')
-rw-r--r--drivers/platform/x86/msi-laptop.c180
1 files changed, 64 insertions, 116 deletions
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index 62f8030b9e77..c4b150fa093f 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*-*-linux-c-*-*/
/*
Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
*/
/*
@@ -64,8 +51,7 @@
#include <linux/i8042.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
-
-#define MSI_DRIVER_VERSION "0.5"
+#include <acpi/video.h>
#define MSI_LCD_LEVEL_MAX 9
@@ -222,7 +208,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
return -EINVAL;
if (quirks->ec_read_only)
- return -EOPNOTSUPP;
+ return 0;
/* read current device state */
result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
@@ -331,7 +317,7 @@ static ssize_t show_wlan(struct device *dev,
if (ret < 0)
return ret;
- return sprintf(buf, "%i\n", enabled);
+ return sysfs_emit(buf, "%i\n", enabled);
}
static ssize_t store_wlan(struct device *dev,
@@ -355,7 +341,7 @@ static ssize_t show_bluetooth(struct device *dev,
if (ret < 0)
return ret;
- return sprintf(buf, "%i\n", enabled);
+ return sysfs_emit(buf, "%i\n", enabled);
}
static ssize_t store_bluetooth(struct device *dev,
@@ -378,7 +364,7 @@ static ssize_t show_threeg(struct device *dev,
if (ret < 0)
return ret;
- return sprintf(buf, "%i\n", threeg_s);
+ return sysfs_emit(buf, "%i\n", threeg_s);
}
static ssize_t store_threeg(struct device *dev,
@@ -397,7 +383,7 @@ static ssize_t show_lcd_level(struct device *dev,
if (ret < 0)
return ret;
- return sprintf(buf, "%i\n", ret);
+ return sysfs_emit(buf, "%i\n", ret);
}
static ssize_t store_lcd_level(struct device *dev,
@@ -427,7 +413,7 @@ static ssize_t show_auto_brightness(struct device *dev,
if (ret < 0)
return ret;
- return sprintf(buf, "%i\n", ret);
+ return sysfs_emit(buf, "%i\n", ret);
}
static ssize_t store_auto_brightness(struct device *dev,
@@ -457,7 +443,7 @@ static ssize_t show_touchpad(struct device *dev,
if (result < 0)
return result;
- return sprintf(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_TOUCHPAD_MASK));
+ return sysfs_emit(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_TOUCHPAD_MASK));
}
static ssize_t show_turbo(struct device *dev,
@@ -471,7 +457,7 @@ static ssize_t show_turbo(struct device *dev,
if (result < 0)
return result;
- return sprintf(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_TURBO_MASK));
+ return sysfs_emit(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_TURBO_MASK));
}
static ssize_t show_eco(struct device *dev,
@@ -485,7 +471,7 @@ static ssize_t show_eco(struct device *dev,
if (result < 0)
return result;
- return sprintf(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_ECO_MASK));
+ return sysfs_emit(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_ECO_MASK));
}
static ssize_t show_turbo_cooldown(struct device *dev,
@@ -499,7 +485,7 @@ static ssize_t show_turbo_cooldown(struct device *dev,
if (result < 0)
return result;
- return sprintf(buf, "%i\n", (!!(rdata & MSI_STANDARD_EC_TURBO_MASK)) |
+ return sysfs_emit(buf, "%i\n", (!!(rdata & MSI_STANDARD_EC_TURBO_MASK)) |
(!!(rdata & MSI_STANDARD_EC_TURBO_COOLDOWN_MASK) << 1));
}
@@ -514,7 +500,7 @@ static ssize_t show_auto_fan(struct device *dev,
if (result < 0)
return result;
- return sprintf(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_AUTOFAN_MASK));
+ return sysfs_emit(buf, "%i\n", !!(rdata & MSI_STANDARD_EC_AUTOFAN_MASK));
}
static ssize_t store_auto_fan(struct device *dev,
@@ -562,18 +548,17 @@ static struct attribute *msipf_old_attributes[] = {
NULL
};
-static struct attribute_group msipf_attribute_group = {
+static const struct attribute_group msipf_attribute_group = {
.attrs = msipf_attributes
};
-static struct attribute_group msipf_old_attribute_group = {
+static const struct attribute_group msipf_old_attribute_group = {
.attrs = msipf_old_attributes
};
static struct platform_driver msipf_driver = {
.driver = {
.name = "msi-laptop-pf",
- .owner = THIS_MODULE,
.pm = &msi_laptop_pm,
},
};
@@ -605,15 +590,22 @@ static int dmi_check_cb(const struct dmi_system_id *dmi)
return 1;
}
-static struct dmi_system_id __initdata msi_dmi_table[] = {
+static unsigned long msi_work_delay(int msecs)
+{
+ if (quirks->ec_delay)
+ return msecs_to_jiffies(msecs);
+
+ return 0;
+}
+
+static const struct dmi_system_id msi_dmi_table[] __initconst = {
{
.ident = "MSI S270",
.matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
+ DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"),
DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
- DMI_MATCH(DMI_CHASSIS_VENDOR,
- "MICRO-STAR INT'L CO.,LTD")
+ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT")
},
.driver_data = &quirk_old_ec_model,
.callback = dmi_check_cb
@@ -646,8 +638,7 @@ static struct dmi_system_id __initdata msi_dmi_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
- DMI_MATCH(DMI_CHASSIS_VENDOR,
- "MICRO-STAR INT'L CO.,LTD")
+ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT")
},
.driver_data = &quirk_old_ec_model,
.callback = dmi_check_cb
@@ -718,6 +709,7 @@ static struct dmi_system_id __initdata msi_dmi_table[] = {
},
{ }
};
+MODULE_DEVICE_TABLE(dmi, msi_dmi_table);
static int rfkill_bluetooth_set(void *data, bool blocked)
{
@@ -798,7 +790,6 @@ static void msi_update_rfkill(struct work_struct *ignored)
msi_rfkill_set_state(rfk_threeg, !threeg_s);
}
static DECLARE_DELAYED_WORK(msi_rfkill_dwork, msi_update_rfkill);
-static DECLARE_WORK(msi_rfkill_work, msi_update_rfkill);
static void msi_send_touchpad_key(struct work_struct *ignored)
{
@@ -814,14 +805,13 @@ static void msi_send_touchpad_key(struct work_struct *ignored)
KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF, 1, true);
}
static DECLARE_DELAYED_WORK(msi_touchpad_dwork, msi_send_touchpad_key);
-static DECLARE_WORK(msi_touchpad_work, msi_send_touchpad_key);
-static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
- struct serio *port)
+static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, struct serio *port,
+ void *context)
{
static bool extended;
- if (str & 0x20)
+ if (str & I8042_STR_AUXDATA)
return false;
/* 0x54 wwan, 0x62 bluetooth, 0x76 wlan, 0xE4 touchpad toggle*/
@@ -832,20 +822,12 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
extended = false;
switch (data) {
case 0xE4:
- if (quirks->ec_delay) {
- schedule_delayed_work(&msi_touchpad_dwork,
- round_jiffies_relative(0.5 * HZ));
- } else
- schedule_work(&msi_touchpad_work);
+ schedule_delayed_work(&msi_touchpad_dwork, msi_work_delay(500));
break;
case 0x54:
case 0x62:
case 0x76:
- if (quirks->ec_delay) {
- schedule_delayed_work(&msi_rfkill_dwork,
- round_jiffies_relative(0.5 * HZ));
- } else
- schedule_work(&msi_rfkill_work);
+ schedule_delayed_work(&msi_rfkill_dwork, msi_work_delay(500));
break;
}
}
@@ -856,15 +838,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
static void msi_init_rfkill(struct work_struct *ignored)
{
if (rfk_wlan) {
- rfkill_set_sw_state(rfk_wlan, !wlan_s);
+ msi_rfkill_set_state(rfk_wlan, !wlan_s);
rfkill_wlan_set(NULL, !wlan_s);
}
if (rfk_bluetooth) {
- rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
+ msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s);
rfkill_bluetooth_set(NULL, !bluetooth_s);
}
if (rfk_threeg) {
- rfkill_set_sw_state(rfk_threeg, !threeg_s);
+ msi_rfkill_set_state(rfk_threeg, !threeg_s);
rfkill_threeg_set(NULL, !threeg_s);
}
}
@@ -912,12 +894,7 @@ static int rfkill_init(struct platform_device *sdev)
}
/* schedule to run rfkill state initial */
- if (quirks->ec_delay) {
- schedule_delayed_work(&msi_rfkill_init,
- round_jiffies_relative(1 * HZ));
- } else
- schedule_work(&msi_rfkill_work);
-
+ schedule_delayed_work(&msi_rfkill_init, msi_work_delay(1000));
return 0;
err_threeg:
@@ -934,8 +911,7 @@ err_bluetooth:
return retval;
}
-#ifdef CONFIG_PM_SLEEP
-static int msi_laptop_resume(struct device *device)
+static int msi_scm_disable_hw_fn_handling(void)
{
u8 data;
int result;
@@ -955,6 +931,12 @@ static int msi_laptop_resume(struct device *device)
return 0;
}
+
+#ifdef CONFIG_PM_SLEEP
+static int msi_laptop_resume(struct device *device)
+{
+ return msi_scm_disable_hw_fn_handling();
+}
#endif
static int __init msi_laptop_input_setup(void)
@@ -976,26 +958,17 @@ static int __init msi_laptop_input_setup(void)
err = input_register_device(msi_laptop_input_dev);
if (err)
- goto err_free_keymap;
+ goto err_free_dev;
return 0;
-err_free_keymap:
- sparse_keymap_free(msi_laptop_input_dev);
err_free_dev:
input_free_device(msi_laptop_input_dev);
return err;
}
-static void msi_laptop_input_destroy(void)
-{
- sparse_keymap_free(msi_laptop_input_dev);
- input_unregister_device(msi_laptop_input_dev);
-}
-
static int __init load_scm_model_init(struct platform_device *sdev)
{
- u8 data;
int result;
if (!quirks->ec_read_only) {
@@ -1009,12 +982,7 @@ static int __init load_scm_model_init(struct platform_device *sdev)
}
/* disable hardware control by fn key */
- result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
- if (result < 0)
- return result;
-
- result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
- data | MSI_STANDARD_EC_SCM_LOAD_MASK);
+ result = msi_scm_disable_hw_fn_handling();
if (result < 0)
return result;
@@ -1028,7 +996,7 @@ static int __init load_scm_model_init(struct platform_device *sdev)
if (result)
goto fail_input;
- result = i8042_install_filter(msi_laptop_i8042_filter);
+ result = i8042_install_filter(msi_laptop_i8042_filter, NULL);
if (result) {
pr_err("Unable to install key filter\n");
goto fail_filter;
@@ -1037,15 +1005,25 @@ static int __init load_scm_model_init(struct platform_device *sdev)
return 0;
fail_filter:
- msi_laptop_input_destroy();
+ input_unregister_device(msi_laptop_input_dev);
fail_input:
rfkill_cleanup();
fail_rfkill:
-
return result;
+}
+static void msi_scm_model_exit(void)
+{
+ if (!quirks->load_scm_model)
+ return;
+
+ i8042_remove_filter(msi_laptop_i8042_filter);
+ cancel_delayed_work_sync(&msi_touchpad_dwork);
+ input_unregister_device(msi_laptop_input_dev);
+ cancel_delayed_work_sync(&msi_rfkill_dwork);
+ rfkill_cleanup();
}
static int __init msi_init(void)
@@ -1069,10 +1047,8 @@ static int __init msi_init(void)
return -EINVAL;
/* Register backlight stuff */
-
- if (!quirks->old_ec_model || acpi_video_backlight_support()) {
- pr_info("Brightness ignored, must be controlled by ACPI video driver\n");
- } else {
+ if (quirks->old_ec_model &&
+ acpi_video_get_backlight_type() == acpi_backlight_vendor) {
struct backlight_properties props;
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_PLATFORM;
@@ -1090,7 +1066,7 @@ static int __init msi_init(void)
/* Register platform stuff */
- msipf_device = platform_device_alloc("msi-laptop-pf", -1);
+ msipf_device = platform_device_alloc("msi-laptop-pf", PLATFORM_DEVID_NONE);
if (!msipf_device) {
ret = -ENOMEM;
goto fail_platform_driver;
@@ -1130,19 +1106,12 @@ static int __init msi_init(void)
set_auto_brightness(auto_brightness);
}
- pr_info("driver " MSI_DRIVER_VERSION " successfully loaded\n");
-
return 0;
fail_create_attr:
sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
fail_create_group:
- if (quirks->load_scm_model) {
- i8042_remove_filter(msi_laptop_i8042_filter);
- cancel_delayed_work_sync(&msi_rfkill_dwork);
- cancel_work_sync(&msi_rfkill_work);
- rfkill_cleanup();
- }
+ msi_scm_model_exit();
fail_scm_model_init:
platform_device_del(msipf_device);
fail_device_add:
@@ -1157,14 +1126,7 @@ fail_backlight:
static void __exit msi_cleanup(void)
{
- if (quirks->load_scm_model) {
- i8042_remove_filter(msi_laptop_i8042_filter);
- msi_laptop_input_destroy();
- cancel_delayed_work_sync(&msi_rfkill_dwork);
- cancel_work_sync(&msi_rfkill_work);
- rfkill_cleanup();
- }
-
+ msi_scm_model_exit();
sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
if (!quirks->old_ec_model && threeg_exists)
device_remove_file(&msipf_device->dev, &dev_attr_threeg);
@@ -1177,8 +1139,6 @@ static void __exit msi_cleanup(void)
if (auto_brightness != 2)
set_auto_brightness(1);
}
-
- pr_info("driver unloaded\n");
}
module_init(msi_init);
@@ -1186,16 +1146,4 @@ module_exit(msi_cleanup);
MODULE_AUTHOR("Lennart Poettering");
MODULE_DESCRIPTION("MSI Laptop Support");
-MODULE_VERSION(MSI_DRIVER_VERSION);
MODULE_LICENSE("GPL");
-
-MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
-MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
-MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
-MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
-MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*");
-MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N051:*");
-MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N014:*");
-MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnCR620:*");
-MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnU270series:*");
-MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnU90/U100:*");