All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] samsung-laptop: enable better lid handling
@ 2014-12-11 21:18 Julijonas Kikutis
  2015-01-27  2:52 ` Darren Hart
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Julijonas Kikutis @ 2014-12-11 21:18 UTC (permalink / raw)
  To: corentin.chary; +Cc: linux-kernel, platform-driver-x86, Julijonas Kikutis

Some Samsung laptops with SABI3 delay the sleep for 10 seconds after
the lid is closed and do not wake up from sleep after the lid is opened.
A SABI command is needed to enable the better behavior.

Command = 0x6e, d0 = 0x81 enables this behavior. Returns d0 = 0x01.
Command = 0x6e, d0 = 0x80 disables this behavior. Returns d0 = 0x00.

Command = 0x6d and any d0 queries the state. This returns:
d0 = 0x00000*01, d1 = 0x00, d2 = 0x00, d3 = 0x0* when it is enabled.
d0 = 0x00000*00, d1 = 0x00, d2 = 0x00, d3 = 0x0* when it is disabled.
Where * is 0 - laptop has never slept or hibernated after switch on,
           1 - laptop has hibernated just before,
           2 - laptop has slept just before.

Patch addresses bug https://bugzilla.kernel.org/show_bug.cgi?id=75901.
It adds a sysfs attribute lid_handling with description and also an
addition to the quirks structure to enable the mode by default.

However, a user with another laptop in the bug report says that "power
button has to be pressed twice to wake the machine" in this mode.
Therefore, it is enabled by default only for the single laptop that I
have tested.

This mode is also needed in UEFI, but there samsung-laptop is
unfortunately disabled.

Signed-off-by: Julijonas Kikutis <julijonas.kikutis@gmail.com>
---
 .../ABI/testing/sysfs-driver-samsung-laptop        |   8 ++
 drivers/platform/x86/samsung-laptop.c              | 121 ++++++++++++++++++++-
 2 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
index 678819a..63c1ad0 100644
--- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
@@ -35,3 +35,11 @@ Contact:	Corentin Chary <corentin.chary@gmail.com>
 Description:	Use your USB ports to charge devices, even
 		when your laptop is powered off.
 		1 means enabled, 0 means disabled.
+
+What:		/sys/devices/platform/samsung/lid_handling
+Date:		December 11, 2014
+KernelVersion:	3.19
+Contact:	Julijonas Kikutis <julijonas.kikutis@gmail.com>
+Description:	Some Samsung laptops handle lid closing quicker and
+		only handle lid opening with this mode enabled.
+		1 means enabled, 0 means disabled.
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index ff765d8..6518930 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -124,6 +124,10 @@ struct sabi_commands {
 	u16 get_wireless_status;
 	u16 set_wireless_status;
 
+	/* 0x80 is off, 0x81 is on */
+	u16 get_lid_handling;
+	u16 set_lid_handling;
+
 	/* 0x81 to read, (0x82 | level << 8) to set, 0xaabb to enable */
 	u16 kbd_backlight;
 
@@ -194,6 +198,9 @@ static const struct sabi_config sabi_configs[] = {
 			.get_wireless_status = 0xFFFF,
 			.set_wireless_status = 0xFFFF,
 
+			.get_lid_handling = 0xFFFF,
+			.set_lid_handling = 0xFFFF,
+
 			.kbd_backlight = 0xFFFF,
 
 			.set_linux = 0x0a,
@@ -254,6 +261,9 @@ static const struct sabi_config sabi_configs[] = {
 			.get_wireless_status = 0x69,
 			.set_wireless_status = 0x6a,
 
+			.get_lid_handling = 0x6d,
+			.set_lid_handling = 0x6e,
+
 			.kbd_backlight = 0x78,
 
 			.set_linux = 0xff,
@@ -353,6 +363,7 @@ struct samsung_quirks {
 	bool broken_acpi_video;
 	bool four_kbd_backlight_levels;
 	bool enable_kbd_backlight;
+	bool lid_handling;
 };
 
 static struct samsung_quirks samsung_unknown = {};
@@ -366,6 +377,10 @@ static struct samsung_quirks samsung_np740u3e = {
 	.enable_kbd_backlight = true,
 };
 
+static struct samsung_quirks samsung_lid_handling = {
+	.lid_handling = true,
+};
+
 static bool force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force,
@@ -830,10 +845,76 @@ static ssize_t set_usb_charge(struct device *dev,
 static DEVICE_ATTR(usb_charge, S_IWUSR | S_IRUGO,
 		   get_usb_charge, set_usb_charge);
 
+static int read_lid_handling(struct samsung_laptop *samsung)
+{
+	const struct sabi_commands *commands = &samsung->config->commands;
+	struct sabi_data data;
+	int retval;
+
+	if (commands->get_lid_handling == 0xFFFF)
+		return -ENODEV;
+
+	memset(&data, 0, sizeof(data));
+	retval = sabi_command(samsung, commands->get_lid_handling,
+			      &data, &data);
+
+	if (retval)
+		return retval;
+
+	return data.data[0] & 0x1;
+}
+
+static int write_lid_handling(struct samsung_laptop *samsung,
+			      int enabled)
+{
+	const struct sabi_commands *commands = &samsung->config->commands;
+	struct sabi_data data;
+
+	memset(&data, 0, sizeof(data));
+	data.data[0] = 0x80 | enabled;
+	return sabi_command(samsung, commands->set_lid_handling,
+			    &data, NULL);
+}
+
+static ssize_t get_lid_handling(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct samsung_laptop *samsung = dev_get_drvdata(dev);
+	int ret;
+
+	ret = read_lid_handling(samsung);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t set_lid_handling(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct samsung_laptop *samsung = dev_get_drvdata(dev);
+	int ret, value;
+
+	if (!count || sscanf(buf, "%i", &value) != 1)
+		return -EINVAL;
+
+	ret = write_lid_handling(samsung, !!value);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(lid_handling, S_IWUSR | S_IRUGO,
+		   get_lid_handling, set_lid_handling);
+
 static struct attribute *platform_attributes[] = {
 	&dev_attr_performance_level.attr,
 	&dev_attr_battery_life_extender.attr,
 	&dev_attr_usb_charge.attr,
+	&dev_attr_lid_handling.attr,
 	NULL
 };
 
@@ -956,6 +1037,22 @@ static int __init samsung_rfkill_init(struct samsung_laptop *samsung)
 	return 0;
 }
 
+static void samsung_lid_handling_exit(struct samsung_laptop *samsung)
+{
+	if (samsung->quirks->lid_handling)
+		write_lid_handling(samsung, 0);
+}
+
+static int __init samsung_lid_handling_init(struct samsung_laptop *samsung)
+{
+	int retval = 0;
+
+	if (samsung->quirks->lid_handling)
+		retval = write_lid_handling(samsung, 1);
+
+	return retval;
+}
+
 static int kbd_backlight_enable(struct samsung_laptop *samsung)
 {
 	const struct sabi_commands *commands = &samsung->config->commands;
@@ -1111,7 +1208,7 @@ static int __init samsung_backlight_init(struct samsung_laptop *samsung)
 }
 
 static umode_t samsung_sysfs_is_visible(struct kobject *kobj,
-				       struct attribute *attr, int idx)
+					struct attribute *attr, int idx)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct platform_device *pdev = to_platform_device(dev);
@@ -1124,6 +1221,8 @@ static umode_t samsung_sysfs_is_visible(struct kobject *kobj,
 		ok = !!(read_battery_life_extender(samsung) >= 0);
 	if (attr == &dev_attr_usb_charge.attr)
 		ok = !!(read_usb_charge(samsung) >= 0);
+	if (attr == &dev_attr_lid_handling.attr)
+		ok = !!(read_lid_handling(samsung) >= 0);
 
 	return ok ? attr->mode : 0;
 }
@@ -1436,6 +1535,10 @@ static int samsung_pm_notification(struct notifier_block *nb,
 	    samsung->quirks->enable_kbd_backlight)
 		kbd_backlight_enable(samsung);
 
+	if (val == PM_POST_HIBERNATION &&
+	    samsung->quirks->lid_handling)
+		write_lid_handling(samsung, 1);
+
 	return 0;
 }
 
@@ -1578,6 +1681,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
 		},
 	 .driver_data = &samsung_np740u3e,
 	},
+	{
+	 .callback = samsung_dmi_matched,
+	 .ident = "300V3Z/300V4Z/300V5Z",
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "300V3Z/300V4Z/300V5Z"),
+		},
+	 .driver_data = &samsung_lid_handling,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
@@ -1648,6 +1760,10 @@ static int __init samsung_init(void)
 	if (ret)
 		goto error_leds;
 
+	ret = samsung_lid_handling_init(samsung);
+	if (ret)
+		goto error_lid_handling;
+
 	ret = samsung_debugfs_init(samsung);
 	if (ret)
 		goto error_debugfs;
@@ -1659,6 +1775,8 @@ static int __init samsung_init(void)
 	return ret;
 
 error_debugfs:
+	samsung_lid_handling_exit(samsung);
+error_lid_handling:
 	samsung_leds_exit(samsung);
 error_leds:
 	samsung_rfkill_exit(samsung);
@@ -1683,6 +1801,7 @@ static void __exit samsung_exit(void)
 	unregister_pm_notifier(&samsung->pm_nb);
 
 	samsung_debugfs_exit(samsung);
+	samsung_lid_handling_exit(samsung);
 	samsung_leds_exit(samsung);
 	samsung_rfkill_exit(samsung);
 	samsung_backlight_exit(samsung);
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [PATCH] samsung-laptop: enable better lid handling
@ 2015-04-07  9:13 Lars Schuetze
  0 siblings, 0 replies; 17+ messages in thread
From: Lars Schuetze @ 2015-04-07  9:13 UTC (permalink / raw)
  To: platform-driver-x86; +Cc: dvhart, corentin.chary, dev

Enable better lid handling for Samsung Series 7 Chronos 700Z3A
and other models of this product line by whitelisting models
700Z3A/700Z4A/700Z5A/700Z5B. Those use SABI in order to
resume upon lide open when in sleep.

It is a follow up of
Commit b0dcaf4fbb36 ("samsung-laptop: enable better lid handling")

Signed-off-by: Lars Schütze <dev@larsschuetze.de>

diff --git a/drivers/platform/x86/samsung-laptop.c
b/drivers/platform/x86/samsung-laptop.c
index 9e701b2..4ecfcd1 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -1694,6 +1694,15 @@ static struct dmi_system_id __initdata
samsung_dmi_table[] = {
  },
  .driver_data = &samsung_lid_handling,
  },
+ {
+ .callback = samsung_dmi_matched,
+ .ident = "700Z3A/700Z4A/700Z5A/700Z5B",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "700Z3A/700Z4A/700Z5A/700Z5B"),
+ },
+ .driver_data = &samsung_lid_handling,
+ },
  { },
 };
 MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);

^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [PATCH] samsung-laptop: enable better lid handling
@ 2015-04-07 10:37 Lars Schuetze
  0 siblings, 0 replies; 17+ messages in thread
From: Lars Schuetze @ 2015-04-07 10:37 UTC (permalink / raw)
  To: dev; +Cc: dvhart, platform-driver-x86, corentin.chary

Enable better lid handling for Samsung Series 7 Chronos 700Z3A
and other models of this product line by whitelisting models
700Z3A/700Z4A/700Z5A/700Z5B. Those use SABI in order to
resume upon lide open when in sleep.

It is a follow up of
Commit b0dcaf4fbb36 ("samsung-laptop: enable better lid handling")

Signed-off-by: Lars Schütze <dev@larsschuetze.de>
---
diff --git a/drivers/platform/x86/samsung-laptop.c
b/drivers/platform/x86/samsung-laptop.c
index 9e701b2..4ecfcd1 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -1694,6 +1694,15 @@ static struct dmi_system_id __initdata
samsung_dmi_table[] = {
  },
  .driver_data = &samsung_lid_handling,
  },
+ {
+ .callback = samsung_dmi_matched,
+ .ident = "700Z3A/700Z4A/700Z5A/700Z5B",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "700Z3A/700Z4A/700Z5A/700Z5B"),
+ },
+ .driver_data = &samsung_lid_handling,
+ },
  { },
 };
 MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-04-07 10:37 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-11 21:18 [PATCH] samsung-laptop: enable better lid handling Julijonas Kikutis
2015-01-27  2:52 ` Darren Hart
2015-01-27  9:54   ` Corentin Chary
2015-01-27  9:54     ` Corentin Chary
2015-01-27 13:35   ` Julijonas Kikutis
2015-01-27 13:26 ` [PATCH v2] " Julijonas Kikutis
2015-01-27 13:26   ` Julijonas Kikutis
2015-01-29  5:20   ` Darren Hart
2015-01-29  5:20     ` Darren Hart
2015-01-29 13:12     ` Julijonas Kikutis
2015-01-29 13:12       ` Julijonas Kikutis
2015-01-29 13:04 ` [PATCH v3] " Julijonas Kikutis
2015-01-29 13:04   ` Julijonas Kikutis
2015-02-07  2:38   ` Darren Hart
2015-02-07  2:38     ` Darren Hart
2015-04-07  9:13 [PATCH] " Lars Schuetze
2015-04-07 10:37 Lars Schuetze

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.