summaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig5
-rw-r--r--drivers/platform/x86/acer-wmi.c2
-rw-r--r--drivers/platform/x86/asus-wmi.c4
-rw-r--r--drivers/platform/x86/eeepc-laptop.c57
-rw-r--r--drivers/platform/x86/eeepc-wmi.c2
-rw-r--r--drivers/platform/x86/intel_pmic_gpio.c43
-rw-r--r--drivers/platform/x86/samsung-laptop.c17
-rw-r--r--drivers/platform/x86/sony-laptop.c195
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c9
9 files changed, 265 insertions, 69 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 2ee442c2a5d..485c09eef42 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -111,7 +111,7 @@ config DELL_WMI_AIO
All-In-One machines.
To compile this driver as a module, choose M here: the module will
- be called dell-wmi.
+ be called dell-wmi-aio.
config FUJITSU_LAPTOP
@@ -187,7 +187,8 @@ config MSI_LAPTOP
depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL
- depends on SERIO_I8042
+ depends on INPUT && SERIO_I8042
+ select INPUT_SPARSEKMAP
---help---
This is a driver for laptops built by MSI (MICRO-STAR
INTERNATIONAL):
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 5ea6c3477d1..ac4e7f83ce6 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -89,7 +89,7 @@ MODULE_LICENSE("GPL");
#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
-MODULE_ALIAS("wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3");
+MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
enum acer_wmi_event_ids {
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index efc776cb0c6..832a3fd7c1c 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -201,8 +201,8 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
if (!asus->inputdev)
return -ENOMEM;
- asus->inputdev->name = asus->driver->input_phys;
- asus->inputdev->phys = asus->driver->input_name;
+ asus->inputdev->name = asus->driver->input_name;
+ asus->inputdev->phys = asus->driver->input_phys;
asus->inputdev->id.bustype = BUS_HOST;
asus->inputdev->dev.parent = &asus->platform_device->dev;
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 5f2dd386152..2c1abf63957 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -585,8 +585,9 @@ static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
return true;
}
-static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
+static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
{
+ struct pci_dev *port;
struct pci_dev *dev;
struct pci_bus *bus;
bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
@@ -599,9 +600,16 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
mutex_lock(&eeepc->hotplug_lock);
if (eeepc->hotplug_slot) {
- bus = pci_find_bus(0, 1);
+ port = acpi_get_pci_dev(handle);
+ if (!port) {
+ pr_warning("Unable to find port\n");
+ goto out_unlock;
+ }
+
+ bus = port->subordinate;
+
if (!bus) {
- pr_warning("Unable to find PCI bus 1?\n");
+ pr_warning("Unable to find PCI bus?\n");
goto out_unlock;
}
@@ -609,6 +617,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
pr_err("Unable to read PCI config space?\n");
goto out_unlock;
}
+
absent = (l == 0xffffffff);
if (blocked != absent) {
@@ -647,6 +656,17 @@ out_unlock:
mutex_unlock(&eeepc->hotplug_lock);
}
+static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
+{
+ acpi_status status = AE_OK;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status))
+ eeepc_rfkill_hotplug(eeepc, handle);
+}
+
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
{
struct eeepc_laptop *eeepc = data;
@@ -654,7 +674,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
if (event != ACPI_NOTIFY_BUS_CHECK)
return;
- eeepc_rfkill_hotplug(eeepc);
+ eeepc_rfkill_hotplug(eeepc, handle);
}
static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
@@ -672,6 +692,11 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
eeepc);
if (ACPI_FAILURE(status))
pr_warning("Failed to register notify on %s\n", node);
+ /*
+ * Refresh pci hotplug in case the rfkill state was
+ * changed during setup.
+ */
+ eeepc_rfkill_hotplug(eeepc, handle);
} else
return -ENODEV;
@@ -693,6 +718,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
if (ACPI_FAILURE(status))
pr_err("Error removing rfkill notify handler %s\n",
node);
+ /*
+ * Refresh pci hotplug in case the rfkill
+ * state was changed after
+ * eeepc_unregister_rfkill_notifier()
+ */
+ eeepc_rfkill_hotplug(eeepc, handle);
}
}
@@ -816,11 +847,7 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
rfkill_destroy(eeepc->wlan_rfkill);
eeepc->wlan_rfkill = NULL;
}
- /*
- * Refresh pci hotplug in case the rfkill state was changed after
- * eeepc_unregister_rfkill_notifier()
- */
- eeepc_rfkill_hotplug(eeepc);
+
if (eeepc->hotplug_slot)
pci_hp_deregister(eeepc->hotplug_slot);
@@ -889,11 +916,6 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
- /*
- * Refresh pci hotplug in case the rfkill state was changed during
- * setup.
- */
- eeepc_rfkill_hotplug(eeepc);
exit:
if (result && result != -ENODEV)
@@ -928,8 +950,11 @@ static int eeepc_hotk_restore(struct device *device)
struct eeepc_laptop *eeepc = dev_get_drvdata(device);
/* Refresh both wlan rfkill state and pci hotplug */
- if (eeepc->wlan_rfkill)
- eeepc_rfkill_hotplug(eeepc);
+ if (eeepc->wlan_rfkill) {
+ eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
+ eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
+ eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
+ }
if (eeepc->bluetooth_rfkill)
rfkill_set_sw_state(eeepc->bluetooth_rfkill,
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 0ddc434fb93..649dcadd8ea 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -67,9 +67,11 @@ static const struct key_entry eeepc_wmi_keymap[] = {
{ KE_KEY, 0x82, { KEY_CAMERA } },
{ KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } },
{ KE_KEY, 0x88, { KEY_WLAN } },
+ { KE_KEY, 0xbd, { KEY_CAMERA } },
{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
{ KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */
{ KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */
+ { KE_KEY, 0xe8, { KEY_SCREENLOCK } },
{ KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
{ KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } },
{ KE_KEY, 0xec, { KEY_CAMERA_UP } },
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c
index d653104b59c..464bb3fc4d8 100644
--- a/drivers/platform/x86/intel_pmic_gpio.c
+++ b/drivers/platform/x86/intel_pmic_gpio.c
@@ -74,6 +74,19 @@ struct pmic_gpio {
u32 trigger_type;
};
+static void pmic_program_irqtype(int gpio, int type)
+{
+ if (type & IRQ_TYPE_EDGE_RISING)
+ intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20);
+ else
+ intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20);
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10);
+ else
+ intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10);
+};
+
static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
if (offset > 8) {
@@ -166,16 +179,38 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return pg->irq_base + offset;
}
+static void pmic_bus_lock(struct irq_data *data)
+{
+ struct pmic_gpio *pg = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&pg->buslock);
+}
+
+static void pmic_bus_sync_unlock(struct irq_data *data)
+{
+ struct pmic_gpio *pg = irq_data_get_irq_chip_data(data);
+
+ if (pg->update_type) {
+ unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE;
+
+ pmic_program_irqtype(gpio, pg->trigger_type);
+ pg->update_type = 0;
+ }
+ mutex_unlock(&pg->buslock);
+}
+
/* the gpiointr register is read-clear, so just do nothing. */
static void pmic_irq_unmask(struct irq_data *data) { }
static void pmic_irq_mask(struct irq_data *data) { }
static struct irq_chip pmic_irqchip = {
- .name = "PMIC-GPIO",
- .irq_mask = pmic_irq_mask,
- .irq_unmask = pmic_irq_unmask,
- .irq_set_type = pmic_irq_type,
+ .name = "PMIC-GPIO",
+ .irq_mask = pmic_irq_mask,
+ .irq_unmask = pmic_irq_unmask,
+ .irq_set_type = pmic_irq_type,
+ .irq_bus_lock = pmic_bus_lock,
+ .irq_bus_sync_unlock = pmic_bus_sync_unlock,
};
static irqreturn_t pmic_irq_handler(int irq, void *data)
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index de434c6dc2d..d347116d150 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -571,6 +571,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
.callback = dmi_check_cb,
},
{
+ .ident = "R410 Plus",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "R410P"),
+ DMI_MATCH(DMI_BOARD_NAME, "R460"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
.ident = "R518",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR,
@@ -591,12 +601,12 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
.callback = dmi_check_cb,
},
{
- .ident = "N150/N210/N220",
+ .ident = "N150/N210/N220/N230",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR,
"SAMSUNG ELECTRONICS CO., LTD."),
- DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
- DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"),
+ DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"),
},
.callback = dmi_check_cb,
},
@@ -771,6 +781,7 @@ static int __init samsung_init(void)
/* create a backlight device to talk to this one */
memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_PLATFORM;
props.max_brightness = sabi_config->max_brightness;
backlight_device = backlight_device_register("samsung", &sdev->dev,
NULL, &backlight_ops,
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index e642f5f2950..6fe8cd6e23b 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -138,6 +138,8 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
"1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
"(default: 0)");
+static void sony_nc_kbd_backlight_resume(void);
+
enum sony_nc_rfkill {
SONY_WIFI,
SONY_BLUETOOTH,
@@ -771,11 +773,6 @@ static int sony_nc_handles_setup(struct platform_device *pd)
if (!handles)
return -ENOMEM;
- sysfs_attr_init(&handles->devattr.attr);
- handles->devattr.attr.name = "handles";
- handles->devattr.attr.mode = S_IRUGO;
- handles->devattr.show = sony_nc_handles_show;
-
for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
if (!acpi_callsetfunc(sony_nc_acpi_handle,
"SN00", i + 0x20, &result)) {
@@ -785,11 +782,18 @@ static int sony_nc_handles_setup(struct platform_device *pd)
}
}
- /* allow reading capabilities via sysfs */
- if (device_create_file(&pd->dev, &handles->devattr)) {
- kfree(handles);
- handles = NULL;
- return -1;
+ if (debug) {
+ sysfs_attr_init(&handles->devattr.attr);
+ handles->devattr.attr.name = "handles";
+ handles->devattr.attr.mode = S_IRUGO;
+ handles->devattr.show = sony_nc_handles_show;
+
+ /* allow reading capabilities via sysfs */
+ if (device_create_file(&pd->dev, &handles->devattr)) {
+ kfree(handles);
+ handles = NULL;
+ return -1;
+ }
}
return 0;
@@ -798,7 +802,8 @@ static int sony_nc_handles_setup(struct platform_device *pd)
static int sony_nc_handles_cleanup(struct platform_device *pd)
{
if (handles) {
- device_remove_file(&pd->dev, &handles->devattr);
+ if (debug)
+ device_remove_file(&pd->dev, &handles->devattr);
kfree(handles);
handles = NULL;
}
@@ -808,6 +813,11 @@ static int sony_nc_handles_cleanup(struct platform_device *pd)
static int sony_find_snc_handle(int handle)
{
int i;
+
+ /* not initialized yet, return early */
+ if (!handles)
+ return -1;
+
for (i = 0; i < 0x10; i++) {
if (handles->cap[i] == handle) {
dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
@@ -924,6 +934,14 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
/*
* Backlight device
*/
+struct sony_backlight_props {
+ struct backlight_device *dev;
+ int handle;
+ u8 offset;
+ u8 maxlvl;
+};
+struct sony_backlight_props sony_bl_props;
+
static int sony_backlight_update_status(struct backlight_device *bd)
{
return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT",
@@ -944,21 +962,26 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd)
{
int result;
int *handle = (int *)bl_get_data(bd);
+ struct sony_backlight_props *sdev =
+ (struct sony_backlight_props *)bl_get_data(bd);
- sony_call_snc_handle(*handle, 0x0200, &result);
+ sony_call_snc_handle(sdev->handle, 0x0200, &result);
- return result & 0xff;
+ return (result & 0xff) - sdev->offset;
}
static int sony_nc_update_status_ng(struct backlight_device *bd)
{
int value, result;
int *handle = (int *)bl_get_data(bd);
+ struct sony_backlight_props *sdev =
+ (struct sony_backlight_props *)bl_get_data(bd);
- value = bd->props.brightness;
- sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result);
+ value = bd->props.brightness + sdev->offset;
+ if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result))
+ return -EIO;
- return sony_nc_get_brightness_ng(bd);
+ return value;
}
static const struct backlight_ops sony_backlight_ops = {
@@ -971,8 +994,6 @@ static const struct backlight_ops sony_backlight_ng_ops = {
.update_status = sony_nc_update_status_ng,
.get_brightness = sony_nc_get_brightness_ng,
};
-static int backlight_ng_handle;
-static struct backlight_device *sony_backlight_device;
/*
* New SNC-only Vaios event mapping to driver known keys
@@ -1168,6 +1189,9 @@ static int sony_nc_resume(struct acpi_device *device)
/* re-read rfkill state */
sony_nc_rfkill_update();
+ /* restore kbd backlight states */
+ sony_nc_kbd_backlight_resume();
+
return 0;
}
@@ -1355,6 +1379,7 @@ out_no_enum:
#define KBDBL_HANDLER 0x137
#define KBDBL_PRESENT 0xB00
#define SET_MODE 0xC00
+#define SET_STATE 0xD00
#define SET_TIMEOUT 0xE00
struct kbd_backlight {
@@ -1377,6 +1402,10 @@ static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
(value << 0x10) | SET_MODE, &result))
return -EIO;
+ /* Try to turn the light on/off immediately */
+ sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE,
+ &result);
+
kbdbl_handle->mode = value;
return 0;
@@ -1458,7 +1487,7 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
{
int result;
- if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result))
+ if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result))
return 0;
if (!(result & 0x02))
return 0;
@@ -1501,13 +1530,105 @@ outkzalloc:
static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
{
if (kbdbl_handle) {
+ int result;
+
device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
+
+ /* restore the default hw behaviour */
+ sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result);
+ sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result);
+
kfree(kbdbl_handle);
}
return 0;
}
+static void sony_nc_kbd_backlight_resume(void)
+{
+ int ignore = 0;
+
+ if (!kbdbl_handle)
+ return;
+
+ if (kbdbl_handle->mode == 0)
+ sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore);
+
+ if (kbdbl_handle->timeout != 0)
+ sony_call_snc_handle(KBDBL_HANDLER,
+ (kbdbl_handle->timeout << 0x10) | SET_TIMEOUT,
+ &ignore);
+}
+
+static void sony_nc_backlight_ng_read_limits(int handle,
+ struct sony_backlight_props *props)
+{
+ int offset;
+ acpi_status status;
+ u8 brlvl, i;
+ u8 min = 0xff, max = 0x00;
+ struct acpi_object_list params;
+ union acpi_object in_obj;
+ union acpi_object *lvl_enum;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ props->handle = handle;
+ props->offset = 0;
+ props->maxlvl = 0xff;
+
+ offset = sony_find_snc_handle(handle);
+ if (offset < 0)
+ return;
+
+ /* try to read the boundaries from ACPI tables, if we fail the above
+ * defaults should be reasonable
+ */
+ params.count = 1;
+ params.pointer = &in_obj;
+ in_obj.type = ACPI_TYPE_INTEGER;
+ in_obj.integer.value = offset;
+ status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", &params,
+ &buffer);
+ if (ACPI_FAILURE(status))
+ return;
+
+ lvl_enum = (union acpi_object *) buffer.pointer;
+ if (!lvl_enum) {
+ pr_err("No SN06 return object.");
+ return;
+ }
+ if (lvl_enum->type != ACPI_TYPE_BUFFER) {
+ pr_err("Invalid SN06 return object 0x%.2x\n",
+ lvl_enum->type);
+ goto out_invalid;
+ }
+
+ /* the buffer lists brightness levels available, brightness levels are
+ * from 0 to 8 in the array, other values are used by ALS control.
+ */
+ for (i = 0; i < 9 && i < lvl_enum->buffer.length; i++) {
+
+ brlvl = *(lvl_enum->buffer.pointer + i);
+ dprintk("Brightness level: %d\n", brlvl);
+
+ if (!brlvl)
+ break;
+
+ if (brlvl > max)
+ max = brlvl;
+ if (brlvl < min)
+ min = brlvl;
+ }
+ props->offset = min;
+ props->maxlvl = max;
+ dprintk("Brightness levels: min=%d max=%d\n", props->offset,
+ props->maxlvl);
+
+out_invalid:
+ kfree(buffer.pointer);
+ return;
+}
+
static void sony_nc_backlight_setup(void)
{
acpi_handle unused;
@@ -1516,14 +1637,14 @@ static void sony_nc_backlight_setup(void)
struct backlight_properties props;
if (sony_find_snc_handle(0x12f) != -1) {
- backlight_ng_handle = 0x12f;
ops = &sony_backlight_ng_ops;
- max_brightness = 0xff;
+ sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props);
+ max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
} else if (sony_find_snc_handle(0x137) != -1) {
- backlight_ng_handle = 0x137;
ops = &sony_backlight_ng_ops;
- max_brightness = 0xff;
+ sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props);
+ max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
} else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
&unused))) {
@@ -1536,22 +1657,22 @@ static void sony_nc_backlight_setup(void)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_PLATFORM;
props.max_brightness = max_brightness;
- sony_backlight_device = backlight_device_register("sony", NULL,
- &backlight_ng_handle,
- ops, &props);
+ sony_bl_props.dev = backlight_device_register("sony", NULL,
+ &sony_bl_props,
+ ops, &props);
- if (IS_ERR(sony_backlight_device)) {
- pr_warning(DRV_PFX "unable to register backlight device\n");
- sony_backlight_device = NULL;
+ if (IS_ERR(sony_bl_props.dev)) {
+ pr_warn(DRV_PFX "unable to register backlight device\n");
+ sony_bl_props.dev = NULL;
} else
- sony_backlight_device->props.brightness =
- ops->get_brightness(sony_backlight_device);
+ sony_bl_props.dev->props.brightness =
+ ops->get_brightness(sony_bl_props.dev);
}
static void sony_nc_backlight_cleanup(void)
{
- if (sony_backlight_device)
- backlight_device_unregister(sony_backlight_device);
+ if (sony_bl_props.dev)
+ backlight_device_unregister(sony_bl_props.dev);
}
static int sony_nc_add(struct acpi_device *device)
@@ -2549,7 +2670,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
mutex_lock(&spic_dev.lock);
switch (cmd) {
case SONYPI_IOCGBRT:
- if (sony_backlight_device == NULL) {
+ if (sony_bl_props.dev == NULL) {
ret = -EIO;
break;
}
@@ -2562,7 +2683,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
ret = -EFAULT;
break;
case SONYPI_IOCSBRT:
- if (sony_backlight_device == NULL) {
+ if (sony_bl_props.dev == NULL) {
ret = -EIO;
break;
}
@@ -2576,8 +2697,8 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
break;
}
/* sync the backlight device status */
- sony_backlight_device->props.brightness =
- sony_backlight_get_brightness(sony_backlight_device);
+ sony_bl_props.dev->props.brightness =
+ sony_backlight_get_brightness(sony_bl_props.dev);
break;
case SONYPI_IOCGBAT1CAP:
if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a08561f5349..562fcf0dd2b 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -128,7 +128,8 @@ enum {
};
/* ACPI HIDs */
-#define TPACPI_ACPI_HKEY_HID "IBM0068"
+#define TPACPI_ACPI_IBM_HKEY_HID "IBM0068"
+#define TPACPI_ACPI_LENOVO_HKEY_HID "LEN0068"
#define TPACPI_ACPI_EC_HID "PNP0C09"
/* Input IDs */
@@ -3879,7 +3880,8 @@ errexit:
}
static const struct acpi_device_id ibm_htk_device_ids[] = {
- {TPACPI_ACPI_HKEY_HID, 0},
+ {TPACPI_ACPI_IBM_HKEY_HID, 0},
+ {TPACPI_ACPI_LENOVO_HKEY_HID, 0},
{"", 0},
};
@@ -8618,8 +8620,7 @@ static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,
tpacpi_is_fw_digit(s[1]) &&
s[2] == t && s[3] == 'T' &&
tpacpi_is_fw_digit(s[4]) &&
- tpacpi_is_fw_digit(s[5]) &&
- s[6] == 'W' && s[7] == 'W';
+ tpacpi_is_fw_digit(s[5]);
}
/* returns 0 - probe ok, or < 0 - probe error.