diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-16 09:32:27 -0600 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-16 09:32:27 -0600 |
commit | 605f884d05cc0de8c3bde36281d58216011f51a5 (patch) | |
tree | 28d62f20b36b059c397bbf8e7e9a033b638990d0 /drivers/platform/x86/ideapad-laptop.c | |
parent | 49899007b9401486421c99bb269db89b88136e47 (diff) | |
parent | 186e4e89a0922d75fba476f15b723e541cc34bea (diff) |
Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
Pull x86 platform driver updates from Matthew Garrett:
"A moderate number of changes, but nothing awfully significant.
A lot of const cleanups, some reworking and additions to the rfkill
quirks in the asus driver, a new driver for generating falling laptop
events on Toshibas and some misc fixes.
Maybe vendors have stopped inventing things"
* 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86: (41 commits)
platform/x86: Enable build support for toshiba_haps
Documentation: Add file about toshiba_haps module
platform/x86: Toshiba HDD Active Protection Sensor
asus-nb-wmi: Add wapf4 quirk for the U32U
alienware-wmi: make hdmi_mux enabled on case-by-case basis
ideapad-laptop: Constify DMI table and other r/o variables
asus-nb-wmi.c: Rename x401u quirk to wapf4
compal-laptop: correct invalid hwmon name
toshiba_acpi: Add Qosmio X75-A to the alt keymap dmi list
toshiba_acpi: Add extra check to backlight code
Fix log message about future removal of interface
ideapad-laptop: Disable touchpad interface on Yoga models
asus-nb-wmi: Add wapf4 quirk for the X550CC
intel_ips: Make ips_mcp_limits variables static
thinkpad_acpi: Mark volume_alsa_control_{vol,mute} as __initdata
fujitsu-laptop: Mark fujitsu_dmi_table[] DMI table as __initconst
hp-wmi: Add missing __init annotations to initialization code
hp_accel: Constify ACPI and DMI tables
fujitsu-tablet: Mark DMI callbacks as __init code
dell-laptop: Mark dell_quirks[] DMI table as __initconst
...
Diffstat (limited to 'drivers/platform/x86/ideapad-laptop.c')
-rw-r--r-- | drivers/platform/x86/ideapad-laptop.c | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index b4c495a62eec..fc468a3d95ce 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -87,6 +87,8 @@ struct ideapad_private { struct backlight_device *blightdev; struct dentry *debug; unsigned long cfg; + bool has_hw_rfkill_switch; + bool has_touchpad_control; }; static bool no_bt_rfkill; @@ -439,7 +441,7 @@ static umode_t ideapad_is_visible(struct kobject *kobj, return supported ? attr->mode : 0; } -static struct attribute_group ideapad_attribute_group = { +static const struct attribute_group ideapad_attribute_group = { .is_visible = ideapad_is_visible, .attrs = ideapad_attributes }; @@ -454,7 +456,7 @@ struct ideapad_rfk_data { int type; }; -const struct ideapad_rfk_data ideapad_rfk_data[] = { +const const struct ideapad_rfk_data ideapad_rfk_data[] = { { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, @@ -473,12 +475,14 @@ static struct rfkill_ops ideapad_rfk_ops = { static void ideapad_sync_rfk_state(struct ideapad_private *priv) { - unsigned long hw_blocked; + unsigned long hw_blocked = 0; int i; - if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) - return; - hw_blocked = !hw_blocked; + if (priv->has_hw_rfkill_switch) { + if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) + return; + hw_blocked = !hw_blocked; + } for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) if (priv->rfk[i]) @@ -763,6 +767,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { unsigned long value; + if (!priv->has_touchpad_control) + return; + /* Without reading from EC touchpad LED doesn't switch state */ if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only @@ -821,14 +828,39 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) } } -/* Blacklist for devices where the ideapad rfkill interface does not work */ -static struct dmi_system_id rfkill_blacklist[] = { - /* The Lenovo Yoga 2 11 always reports everything as blocked */ +/* + * Some ideapads don't have a hardware rfkill switch, reading VPCCMD_R_RF + * always results in 0 on these models, causing ideapad_laptop to wrongly + * report all radios as hardware-blocked. + */ +static struct dmi_system_id no_hw_rfkill_list[] = { { - .ident = "Lenovo Yoga 2 11", + .ident = "Lenovo Yoga 2 11 / 13 / Pro", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), + }, + }, + {} +}; + +/* + * Some models don't offer touchpad ctrl through the ideapad interface, causing + * ideapad_sync_touchpad_state to send wrong touchpad enable/disable events. + */ +static struct dmi_system_id no_touchpad_ctrl_list[] = { + { + .ident = "Lenovo Yoga 1 series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga"), + }, + }, + { + .ident = "Lenovo Yoga 2 11 / 13 / Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), }, }, {} @@ -856,6 +888,8 @@ static int ideapad_acpi_add(struct platform_device *pdev) priv->cfg = cfg; priv->adev = adev; priv->platform_device = pdev; + priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list); + priv->has_touchpad_control = !dmi_check_system(no_touchpad_ctrl_list); ret = ideapad_sysfs_init(priv); if (ret) @@ -869,11 +903,17 @@ static int ideapad_acpi_add(struct platform_device *pdev) if (ret) goto input_failed; - if (!dmi_check_system(rfkill_blacklist)) { - for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(priv, i); - } + /* + * On some models without a hw-switch (the yoga 2 13 at least) + * VPCCMD_W_RF must be explicitly set to 1 for the wifi to work. + */ + if (!priv->has_hw_rfkill_switch) + write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1); + + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) + if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) + ideapad_register_rfkill(priv, i); + ideapad_sync_rfk_state(priv); ideapad_sync_touchpad_state(priv); |