summaryrefslogtreecommitdiff
path: root/drivers/platform/x86/asus-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/asus-laptop.c')
-rw-r--r--drivers/platform/x86/asus-laptop.c195
1 files changed, 85 insertions, 110 deletions
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index c4768be24ba9..a0a411b4f2d6 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -1,26 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* asus-laptop.c - Asus Laptop Support
*
- *
* Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
* Copyright (C) 2006-2007 Corentin Chary
* Copyright (C) 2011 Wind River Systems
*
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
* The development page for this driver is located at
* http://sourceforge.net/projects/acpi4asus/
*
@@ -43,13 +28,11 @@
#include <linux/err.h>
#include <linux/proc_fs.h>
#include <linux/backlight.h>
-#include <linux/fb.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
-#include <linux/input-polldev.h>
#include <linux/rfkill.h>
#include <linux/slab.h>
#include <linux/dmi.h>
@@ -259,7 +242,7 @@ struct asus_laptop {
struct input_dev *inputdev;
struct key_entry *keymap;
- struct input_polled_dev *pega_accel_poll;
+ struct input_dev *pega_accel_poll;
struct asus_led wled;
struct asus_led bled;
@@ -443,11 +426,14 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
{
+ unsigned long long val = (unsigned long long)curr;
+ acpi_status status;
int i, delta;
- unsigned long long val;
- for (i = 0; i < PEGA_ACC_RETRIES; i++) {
- acpi_evaluate_integer(asus->handle, method, NULL, &val);
+ for (i = 0; i < PEGA_ACC_RETRIES; i++) {
+ status = acpi_evaluate_integer(asus->handle, method, NULL, &val);
+ if (ACPI_FAILURE(status))
+ continue;
/* The output is noisy. From reading the ASL
* dissassembly, timeout errors are returned with 1's
* in the high word, and the lack of locking around
@@ -461,9 +447,9 @@ static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
return clamp_val((short)val, -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP);
}
-static void pega_accel_poll(struct input_polled_dev *ipd)
+static void pega_accel_poll(struct input_dev *input)
{
- struct device *parent = ipd->input->dev.parent;
+ struct device *parent = input->dev.parent;
struct asus_laptop *asus = dev_get_drvdata(parent);
/* In some cases, the very first call to poll causes a
@@ -472,10 +458,10 @@ static void pega_accel_poll(struct input_polled_dev *ipd)
* device, and perhaps a firmware bug. Fake the first report. */
if (!asus->pega_acc_live) {
asus->pega_acc_live = true;
- input_report_abs(ipd->input, ABS_X, 0);
- input_report_abs(ipd->input, ABS_Y, 0);
- input_report_abs(ipd->input, ABS_Z, 0);
- input_sync(ipd->input);
+ input_report_abs(input, ABS_X, 0);
+ input_report_abs(input, ABS_Y, 0);
+ input_report_abs(input, ABS_Z, 0);
+ input_sync(input);
return;
}
@@ -486,25 +472,24 @@ static void pega_accel_poll(struct input_polled_dev *ipd)
/* Note transform, convert to "right/up/out" in the native
* landscape orientation (i.e. the vector is the direction of
* "real up" in the device's cartiesian coordinates). */
- input_report_abs(ipd->input, ABS_X, -asus->pega_acc_x);
- input_report_abs(ipd->input, ABS_Y, -asus->pega_acc_y);
- input_report_abs(ipd->input, ABS_Z, asus->pega_acc_z);
- input_sync(ipd->input);
+ input_report_abs(input, ABS_X, -asus->pega_acc_x);
+ input_report_abs(input, ABS_Y, -asus->pega_acc_y);
+ input_report_abs(input, ABS_Z, asus->pega_acc_z);
+ input_sync(input);
}
static void pega_accel_exit(struct asus_laptop *asus)
{
if (asus->pega_accel_poll) {
- input_unregister_polled_device(asus->pega_accel_poll);
- input_free_polled_device(asus->pega_accel_poll);
+ input_unregister_device(asus->pega_accel_poll);
+ asus->pega_accel_poll = NULL;
}
- asus->pega_accel_poll = NULL;
}
static int pega_accel_init(struct asus_laptop *asus)
{
int err;
- struct input_polled_dev *ipd;
+ struct input_dev *input;
if (!asus->is_pega_lucid)
return -ENODEV;
@@ -514,37 +499,39 @@ static int pega_accel_init(struct asus_laptop *asus)
acpi_check_handle(asus->handle, METHOD_XLRZ, NULL))
return -ENODEV;
- ipd = input_allocate_polled_device();
- if (!ipd)
+ input = input_allocate_device();
+ if (!input)
return -ENOMEM;
- ipd->poll = pega_accel_poll;
- ipd->poll_interval = 125;
- ipd->poll_interval_min = 50;
- ipd->poll_interval_max = 2000;
-
- ipd->input->name = PEGA_ACCEL_DESC;
- ipd->input->phys = PEGA_ACCEL_NAME "/input0";
- ipd->input->dev.parent = &asus->platform_device->dev;
- ipd->input->id.bustype = BUS_HOST;
+ input->name = PEGA_ACCEL_DESC;
+ input->phys = PEGA_ACCEL_NAME "/input0";
+ input->dev.parent = &asus->platform_device->dev;
+ input->id.bustype = BUS_HOST;
- set_bit(EV_ABS, ipd->input->evbit);
- input_set_abs_params(ipd->input, ABS_X,
+ input_set_abs_params(input, ABS_X,
-PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
- input_set_abs_params(ipd->input, ABS_Y,
+ input_set_abs_params(input, ABS_Y,
-PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
- input_set_abs_params(ipd->input, ABS_Z,
+ input_set_abs_params(input, ABS_Z,
-PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
- err = input_register_polled_device(ipd);
+ err = input_setup_polling(input, pega_accel_poll);
+ if (err)
+ goto exit;
+
+ input_set_poll_interval(input, 125);
+ input_set_min_poll_interval(input, 50);
+ input_set_max_poll_interval(input, 2000);
+
+ err = input_register_device(input);
if (err)
goto exit;
- asus->pega_accel_poll = ipd;
+ asus->pega_accel_poll = input;
return 0;
exit:
- input_free_polled_device(ipd);
+ input_free_device(input);
return err;
}
@@ -655,22 +642,15 @@ static enum led_brightness asus_kled_cdev_get(struct led_classdev *led_cdev)
static void asus_led_exit(struct asus_laptop *asus)
{
- if (!IS_ERR_OR_NULL(asus->wled.led.dev))
- led_classdev_unregister(&asus->wled.led);
- if (!IS_ERR_OR_NULL(asus->bled.led.dev))
- led_classdev_unregister(&asus->bled.led);
- if (!IS_ERR_OR_NULL(asus->mled.led.dev))
- led_classdev_unregister(&asus->mled.led);
- if (!IS_ERR_OR_NULL(asus->tled.led.dev))
- led_classdev_unregister(&asus->tled.led);
- if (!IS_ERR_OR_NULL(asus->pled.led.dev))
- led_classdev_unregister(&asus->pled.led);
- if (!IS_ERR_OR_NULL(asus->rled.led.dev))
- led_classdev_unregister(&asus->rled.led);
- if (!IS_ERR_OR_NULL(asus->gled.led.dev))
- led_classdev_unregister(&asus->gled.led);
- if (!IS_ERR_OR_NULL(asus->kled.led.dev))
- led_classdev_unregister(&asus->kled.led);
+ led_classdev_unregister(&asus->wled.led);
+ led_classdev_unregister(&asus->bled.led);
+ led_classdev_unregister(&asus->mled.led);
+ led_classdev_unregister(&asus->tled.led);
+ led_classdev_unregister(&asus->pled.led);
+ led_classdev_unregister(&asus->rled.led);
+ led_classdev_unregister(&asus->gled.led);
+ led_classdev_unregister(&asus->kled.led);
+
if (asus->led_workqueue) {
destroy_workqueue(asus->led_workqueue);
asus->led_workqueue = NULL;
@@ -840,7 +820,7 @@ static int asus_backlight_init(struct asus_laptop *asus)
asus->backlight_device = bd;
bd->props.brightness = asus_read_brightness(bd);
- bd->props.power = FB_BLANK_UNBLANK;
+ bd->props.power = BACKLIGHT_POWER_ON;
backlight_update_status(bd);
return 0;
}
@@ -874,8 +854,8 @@ static ssize_t infos_show(struct device *dev, struct device_attribute *attr,
* so we don't set eof to 1
*/
- len += sprintf(page, ASUS_LAPTOP_NAME " " ASUS_LAPTOP_VERSION "\n");
- len += sprintf(page + len, "Model reference : %s\n", asus->name);
+ len += sysfs_emit_at(page, len, ASUS_LAPTOP_NAME " " ASUS_LAPTOP_VERSION "\n");
+ len += sysfs_emit_at(page, len, "Model reference : %s\n", asus->name);
/*
* The SFUN method probably allows the original driver to get the list
* of features supported by a given model. For now, 0x0100 or 0x0800
@@ -883,8 +863,8 @@ static ssize_t infos_show(struct device *dev, struct device_attribute *attr,
* The significance of others is yet to be found.
*/
rv = acpi_evaluate_integer(asus->handle, "SFUN", NULL, &temp);
- if (!ACPI_FAILURE(rv))
- len += sprintf(page + len, "SFUN value : %#x\n",
+ if (ACPI_SUCCESS(rv))
+ len += sysfs_emit_at(page, len, "SFUN value : %#x\n",
(uint) temp);
/*
* The HWRS method return informations about the hardware.
@@ -895,8 +875,8 @@ static ssize_t infos_show(struct device *dev, struct device_attribute *attr,
* takes several seconds to run on some systems.
*/
rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp);
- if (!ACPI_FAILURE(rv))
- len += sprintf(page + len, "HWRS value : %#x\n",
+ if (ACPI_SUCCESS(rv))
+ len += sysfs_emit_at(page, len, "HWRS value : %#x\n",
(uint) temp);
/*
* Another value for userspace: the ASYM method returns 0x02 for
@@ -906,26 +886,26 @@ static ssize_t infos_show(struct device *dev, struct device_attribute *attr,
* silently ignored.
*/
rv = acpi_evaluate_integer(asus->handle, "ASYM", NULL, &temp);
- if (!ACPI_FAILURE(rv))
- len += sprintf(page + len, "ASYM value : %#x\n",
+ if (ACPI_SUCCESS(rv))
+ len += sysfs_emit_at(page, len, "ASYM value : %#x\n",
(uint) temp);
if (asus->dsdt_info) {
snprintf(buf, 16, "%d", asus->dsdt_info->length);
- len += sprintf(page + len, "DSDT length : %s\n", buf);
+ len += sysfs_emit_at(page, len, "DSDT length : %s\n", buf);
snprintf(buf, 16, "%d", asus->dsdt_info->checksum);
- len += sprintf(page + len, "DSDT checksum : %s\n", buf);
+ len += sysfs_emit_at(page, len, "DSDT checksum : %s\n", buf);
snprintf(buf, 16, "%d", asus->dsdt_info->revision);
- len += sprintf(page + len, "DSDT revision : %s\n", buf);
+ len += sysfs_emit_at(page, len, "DSDT revision : %s\n", buf);
snprintf(buf, 7, "%s", asus->dsdt_info->oem_id);
- len += sprintf(page + len, "OEM id : %s\n", buf);
+ len += sysfs_emit_at(page, len, "OEM id : %s\n", buf);
snprintf(buf, 9, "%s", asus->dsdt_info->oem_table_id);
- len += sprintf(page + len, "OEM table id : %s\n", buf);
+ len += sysfs_emit_at(page, len, "OEM table id : %s\n", buf);
snprintf(buf, 16, "%x", asus->dsdt_info->oem_revision);
- len += sprintf(page + len, "OEM revision : 0x%s\n", buf);
+ len += sysfs_emit_at(page, len, "OEM revision : 0x%s\n", buf);
snprintf(buf, 5, "%s", asus->dsdt_info->asl_compiler_id);
- len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
+ len += sysfs_emit_at(page, len, "ASL comp vendor id : %s\n", buf);
snprintf(buf, 16, "%x", asus->dsdt_info->asl_compiler_revision);
- len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf);
+ len += sysfs_emit_at(page, len, "ASL comp revision : 0x%s\n", buf);
}
return len;
@@ -955,7 +935,7 @@ static ssize_t ledd_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "0x%08x\n", asus->ledd_status);
+ return sysfs_emit(buf, "0x%08x\n", asus->ledd_status);
}
static ssize_t ledd_store(struct device *dev, struct device_attribute *attr,
@@ -1015,7 +995,7 @@ static ssize_t wlan_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus_wireless_status(asus, WL_RSTS));
+ return sysfs_emit(buf, "%d\n", asus_wireless_status(asus, WL_RSTS));
}
static ssize_t wlan_store(struct device *dev, struct device_attribute *attr,
@@ -1044,7 +1024,7 @@ static ssize_t bluetooth_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus_wireless_status(asus, BT_RSTS));
+ return sysfs_emit(buf, "%d\n", asus_wireless_status(asus, BT_RSTS));
}
static ssize_t bluetooth_store(struct device *dev,
@@ -1074,7 +1054,7 @@ static ssize_t wimax_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS));
+ return sysfs_emit(buf, "%d\n", asus_wireless_status(asus, WM_RSTS));
}
static ssize_t wimax_store(struct device *dev, struct device_attribute *attr,
@@ -1103,7 +1083,7 @@ static ssize_t wwan_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS));
+ return sysfs_emit(buf, "%d\n", asus_wireless_status(asus, WW_RSTS));
}
static ssize_t wwan_store(struct device *dev, struct device_attribute *attr,
@@ -1163,7 +1143,7 @@ static void asus_als_switch(struct asus_laptop *asus, int value)
ret = write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value);
}
if (ret)
- pr_warning("Error setting light sensor switch\n");
+ pr_warn("Error setting light sensor switch\n");
asus->light_switch = value;
}
@@ -1173,7 +1153,7 @@ static ssize_t ls_switch_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus->light_switch);
+ return sysfs_emit(buf, "%d\n", asus->light_switch);
}
static ssize_t ls_switch_store(struct device *dev,
@@ -1204,7 +1184,7 @@ static ssize_t ls_level_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus->light_level);
+ return sysfs_emit(buf, "%d\n", asus->light_level);
}
static ssize_t ls_level_store(struct device *dev, struct device_attribute *attr,
@@ -1250,7 +1230,7 @@ static ssize_t ls_value_show(struct device *dev, struct device_attribute *attr,
if (!err)
err = pega_int_read(asus, PEGA_READ_ALS_L, &lo);
if (!err)
- return sprintf(buf, "%d\n", 10 * hi + lo);
+ return sysfs_emit(buf, "%d\n", 10 * hi + lo);
return err;
}
static DEVICE_ATTR_RO(ls_value);
@@ -1286,7 +1266,7 @@ static ssize_t gps_show(struct device *dev, struct device_attribute *attr,
{
struct asus_laptop *asus = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", asus_gps_status(asus));
+ return sysfs_emit(buf, "%d\n", asus_gps_status(asus));
}
static ssize_t gps_store(struct device *dev, struct device_attribute *attr,
@@ -1565,8 +1545,7 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event)
/* Accelerometer "coarse orientation change" event */
if (asus->pega_accel_poll && event == 0xEA) {
- kobject_uevent(&asus->pega_accel_poll->input->dev.kobj,
- KOBJ_CHANGE);
+ kobject_uevent(&asus->pega_accel_poll->dev.kobj, KOBJ_CHANGE);
return ;
}
@@ -1592,9 +1571,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
struct attribute *attr,
int idx)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
- struct asus_laptop *asus = platform_get_drvdata(pdev);
+ struct device *dev = kobj_to_dev(kobj);
+ struct asus_laptop *asus = dev_get_drvdata(dev);
acpi_handle handle = asus->handle;
bool supported;
@@ -1657,7 +1635,7 @@ static int asus_platform_init(struct asus_laptop *asus)
{
int result;
- asus->platform_device = platform_device_alloc(ASUS_LAPTOP_FILE, -1);
+ asus->platform_device = platform_device_alloc(ASUS_LAPTOP_FILE, PLATFORM_DEVID_NONE);
if (!asus->platform_device)
return -ENOMEM;
platform_set_drvdata(asus->platform_device, asus);
@@ -1840,9 +1818,8 @@ static void asus_dmi_check(void)
return;
/* On L1400B WLED control the sound card, don't mess with it ... */
- if (strncmp(model, "L1400B", 6) == 0) {
+ if (strncmp(model, "L1400B", 6) == 0)
wlan_status = -1;
- }
}
static bool asus_device_present;
@@ -1858,8 +1835,8 @@ static int asus_acpi_add(struct acpi_device *device)
if (!asus)
return -ENOMEM;
asus->handle = device->handle;
- strcpy(acpi_device_name(device), ASUS_LAPTOP_DEVICE_NAME);
- strcpy(acpi_device_class(device), ASUS_LAPTOP_CLASS);
+ strscpy(acpi_device_name(device), ASUS_LAPTOP_DEVICE_NAME);
+ strscpy(acpi_device_class(device), ASUS_LAPTOP_CLASS);
device->driver_data = asus;
asus->device = device;
@@ -1925,7 +1902,7 @@ fail_platform:
return result;
}
-static int asus_acpi_remove(struct acpi_device *device)
+static void asus_acpi_remove(struct acpi_device *device)
{
struct asus_laptop *asus = acpi_driver_data(device);
@@ -1938,7 +1915,6 @@ static int asus_acpi_remove(struct acpi_device *device)
kfree(asus->name);
kfree(asus);
- return 0;
}
static const struct acpi_device_id asus_device_ids[] = {
@@ -1951,7 +1927,6 @@ MODULE_DEVICE_TABLE(acpi, asus_device_ids);
static struct acpi_driver asus_acpi_driver = {
.name = ASUS_LAPTOP_NAME,
.class = ASUS_LAPTOP_CLASS,
- .owner = THIS_MODULE,
.ids = asus_device_ids,
.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {