Skip to content

Commit de2884c

Browse files
jellyij-intel
authored andcommitted
platform/x86: samsung-laptop: Expose charge_types
Support the newly introduced charge_types sysfs attribute as a replacement for the custom `battery_life_extender` attribute. Setting charge_types to `Long Life` enables battery life extending mode. This change is similar to the recent Ideapad patch adding support for charge_types. Signed-off-by: Jelle van der Waa <jvanderwaa@redhat.com> Link: https://lore.kernel.org/r/20250702182844.107706-1-jvanderwaa@redhat.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1 parent 4ff3aeb commit de2884c

4 files changed

Lines changed: 121 additions & 11 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
What: /sys/devices/platform/samsung/battery_life_extender
2+
Date: December 1, 2011
3+
KernelVersion: 3.3
4+
Contact: Corentin Chary <corentin.chary@gmail.com>
5+
Description: Max battery charge level can be modified, battery cycle
6+
life can be extended by reducing the max battery charge
7+
level.
8+
9+
- 0 means normal battery mode (100% charge)
10+
- 1 means battery life extender mode (80% charge)

Documentation/ABI/testing/sysfs-driver-samsung-laptop

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,6 @@ Description: Some Samsung laptops have different "performance levels"
2020
and it's still unknown if this value even changes
2121
anything, other than making the user feel a bit better.
2222

23-
What: /sys/devices/platform/samsung/battery_life_extender
24-
Date: December 1, 2011
25-
KernelVersion: 3.3
26-
Contact: Corentin Chary <corentin.chary@gmail.com>
27-
Description: Max battery charge level can be modified, battery cycle
28-
life can be extended by reducing the max battery charge
29-
level.
30-
31-
- 0 means normal battery mode (100% charge)
32-
- 1 means battery life extender mode (80% charge)
33-
3423
What: /sys/devices/platform/samsung/usb_charge
3524
Date: December 1, 2011
3625
KernelVersion: 3.3

drivers/platform/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ config SAMSUNG_LAPTOP
619619
tristate "Samsung Laptop driver"
620620
depends on RFKILL || RFKILL = n
621621
depends on ACPI_VIDEO || ACPI_VIDEO = n
622+
depends on ACPI_BATTERY
622623
depends on BACKLIGHT_CLASS_DEVICE
623624
select LEDS_CLASS
624625
select NEW_LEDS

drivers/platform/x86/samsung-laptop.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
#include <linux/leds.h>
1717
#include <linux/dmi.h>
1818
#include <linux/platform_device.h>
19+
#include <linux/power_supply.h>
1920
#include <linux/rfkill.h>
2021
#include <linux/acpi.h>
2122
#include <linux/seq_file.h>
2223
#include <linux/debugfs.h>
2324
#include <linux/ctype.h>
2425
#include <linux/efi.h>
2526
#include <linux/suspend.h>
27+
#include <acpi/battery.h>
2628
#include <acpi/video.h>
2729

2830
/*
@@ -348,6 +350,8 @@ struct samsung_laptop {
348350

349351
struct notifier_block pm_nb;
350352

353+
struct acpi_battery_hook battery_hook;
354+
351355
bool handle_backlight;
352356
bool has_stepping_quirk;
353357

@@ -697,6 +701,11 @@ static ssize_t set_performance_level(struct device *dev,
697701
static DEVICE_ATTR(performance_level, 0644,
698702
get_performance_level, set_performance_level);
699703

704+
static void show_battery_life_extender_deprecation_warning(struct device *dev)
705+
{
706+
dev_warn_once(dev, "battery_life_extender attribute has been deprecated, see charge_types.\n");
707+
}
708+
700709
static int read_battery_life_extender(struct samsung_laptop *samsung)
701710
{
702711
const struct sabi_commands *commands = &samsung->config->commands;
@@ -739,6 +748,8 @@ static ssize_t get_battery_life_extender(struct device *dev,
739748
struct samsung_laptop *samsung = dev_get_drvdata(dev);
740749
int ret;
741750

751+
show_battery_life_extender_deprecation_warning(dev);
752+
742753
ret = read_battery_life_extender(samsung);
743754
if (ret < 0)
744755
return ret;
@@ -753,6 +764,8 @@ static ssize_t set_battery_life_extender(struct device *dev,
753764
struct samsung_laptop *samsung = dev_get_drvdata(dev);
754765
int ret, value;
755766

767+
show_battery_life_extender_deprecation_warning(dev);
768+
756769
if (!count || kstrtoint(buf, 0, &value) != 0)
757770
return -EINVAL;
758771

@@ -766,6 +779,84 @@ static ssize_t set_battery_life_extender(struct device *dev,
766779
static DEVICE_ATTR(battery_life_extender, 0644,
767780
get_battery_life_extender, set_battery_life_extender);
768781

782+
static int samsung_psy_ext_set_prop(struct power_supply *psy,
783+
const struct power_supply_ext *ext,
784+
void *ext_data,
785+
enum power_supply_property psp,
786+
const union power_supply_propval *val)
787+
{
788+
struct samsung_laptop *samsung = ext_data;
789+
790+
switch (val->intval) {
791+
case POWER_SUPPLY_CHARGE_TYPE_LONGLIFE:
792+
return write_battery_life_extender(samsung, 1);
793+
case POWER_SUPPLY_CHARGE_TYPE_STANDARD:
794+
return write_battery_life_extender(samsung, 0);
795+
default:
796+
return -EINVAL;
797+
}
798+
}
799+
800+
static int samsung_psy_ext_get_prop(struct power_supply *psy,
801+
const struct power_supply_ext *ext,
802+
void *ext_data,
803+
enum power_supply_property psp,
804+
union power_supply_propval *val)
805+
{
806+
struct samsung_laptop *samsung = ext_data;
807+
int ret;
808+
809+
ret = read_battery_life_extender(samsung);
810+
if (ret < 0)
811+
return ret;
812+
813+
if (ret == 1)
814+
val->intval = POWER_SUPPLY_CHARGE_TYPE_LONGLIFE;
815+
else
816+
val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
817+
818+
return 0;
819+
}
820+
821+
static int samsung_psy_prop_is_writeable(struct power_supply *psy,
822+
const struct power_supply_ext *ext,
823+
void *data,
824+
enum power_supply_property psp)
825+
{
826+
return true;
827+
}
828+
829+
static const enum power_supply_property samsung_power_supply_props[] = {
830+
POWER_SUPPLY_PROP_CHARGE_TYPES,
831+
};
832+
833+
static const struct power_supply_ext samsung_battery_ext = {
834+
.name = "samsung_laptop",
835+
.properties = samsung_power_supply_props,
836+
.num_properties = ARRAY_SIZE(samsung_power_supply_props),
837+
.charge_types = (BIT(POWER_SUPPLY_CHARGE_TYPE_STANDARD) |
838+
BIT(POWER_SUPPLY_CHARGE_TYPE_LONGLIFE)),
839+
.get_property = samsung_psy_ext_get_prop,
840+
.set_property = samsung_psy_ext_set_prop,
841+
.property_is_writeable = samsung_psy_prop_is_writeable,
842+
};
843+
844+
static int samsung_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)
845+
{
846+
struct samsung_laptop *samsung = container_of(hook, struct samsung_laptop, battery_hook);
847+
848+
return power_supply_register_extension(battery, &samsung_battery_ext,
849+
&samsung->platform_device->dev, samsung);
850+
}
851+
852+
static int samsung_battery_remove(struct power_supply *battery,
853+
struct acpi_battery_hook *hook)
854+
{
855+
power_supply_unregister_extension(battery, &samsung_battery_ext);
856+
857+
return 0;
858+
}
859+
769860
static int read_usb_charge(struct samsung_laptop *samsung)
770861
{
771862
const struct sabi_commands *commands = &samsung->config->commands;
@@ -1043,6 +1134,21 @@ static int __init samsung_lid_handling_init(struct samsung_laptop *samsung)
10431134
return retval;
10441135
}
10451136

1137+
static int __init samsung_battery_hook_init(struct samsung_laptop *samsung)
1138+
{
1139+
int retval = 0;
1140+
1141+
if (samsung->config->commands.get_battery_life_extender != 0xFFFF) {
1142+
samsung->battery_hook.add_battery = samsung_battery_add;
1143+
samsung->battery_hook.remove_battery = samsung_battery_remove;
1144+
samsung->battery_hook.name = "Samsung Battery Extension";
1145+
retval = devm_battery_hook_register(&samsung->platform_device->dev,
1146+
&samsung->battery_hook);
1147+
}
1148+
1149+
return retval;
1150+
}
1151+
10461152
static int kbd_backlight_enable(struct samsung_laptop *samsung)
10471153
{
10481154
const struct sabi_commands *commands = &samsung->config->commands;
@@ -1604,6 +1710,10 @@ static int __init samsung_init(void)
16041710
if (ret)
16051711
goto error_lid_handling;
16061712

1713+
ret = samsung_battery_hook_init(samsung);
1714+
if (ret)
1715+
goto error_lid_handling;
1716+
16071717
samsung_debugfs_init(samsung);
16081718

16091719
samsung->pm_nb.notifier_call = samsung_pm_notification;

0 commit comments

Comments
 (0)