diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index c69bb703f483569e4f8069affe1da123be5a4365..2f9026d314440b370297b8b9c71fdc090aa0fd8f 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -309,8 +309,8 @@ config COMPAL_LAPTOP This is a driver for laptops built by Compal, and some models by other brands (e.g. Dell, Toshiba). - It adds support for rfkill, Bluetooth, WLAN and LCD brightness - control. + It adds support for rfkill, Bluetooth, WLAN, LCD brightness, hwmon + and battery charging level control. For a (possibly incomplete) list of supported laptops, please refer to: Documentation/platform/x86-laptop-drivers.txt diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index f2706d27adff39fe93f77ff7a4204ef34664d928..e1c2b6d4b24ab5959d816dc1cc772678c42dccb3 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c @@ -151,6 +151,8 @@ #define BAT_STATUS2 0xF1 #define BAT_STOP_CHARGE1 0xF2 #define BAT_STOP_CHARGE2 0xF3 +#define BAT_CHARGE_LIMIT 0x03 +#define BAT_CHARGE_LIMIT_MAX 100 #define BAT_S0_DISCHARGE (1 << 0) #define BAT_S0_DISCHRG_CRITICAL (1 << 2) @@ -601,6 +603,12 @@ static int bat_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_NOW: val->intval = ec_read_u16(BAT_CHARGE_NOW) * 1000; break; + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + val->intval = ec_read_u8(BAT_CHARGE_LIMIT); + break; + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: + val->intval = BAT_CHARGE_LIMIT_MAX; + break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = ec_read_u8(BAT_CAPACITY); break; @@ -634,6 +642,36 @@ static int bat_get_property(struct power_supply *psy, return 0; } +static int bat_set_property(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + int level; + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + level = val->intval; + if (level < 0 || level > BAT_CHARGE_LIMIT_MAX) + return -EINVAL; + if (ec_write(BAT_CHARGE_LIMIT, level) < 0) + return -EIO; + break; + default: + break; + } + return 0; +} + +static int bat_writeable_property(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + return 1; + default: + return 0; + } +} @@ -726,6 +764,8 @@ static enum power_supply_property compal_bat_properties[] = { POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY_LEVEL, POWER_SUPPLY_PROP_TEMP, @@ -880,11 +920,12 @@ static const struct power_supply_desc psy_bat_desc = { .properties = compal_bat_properties, .num_properties = ARRAY_SIZE(compal_bat_properties), .get_property = bat_get_property, + .set_property = bat_set_property, + .property_is_writeable = bat_writeable_property, }; static void initialize_power_supply_data(struct compal_data *data) { - ec_read_sequence(BAT_MANUFACTURER_NAME_ADDR, data->bat_manufacturer_name, BAT_MANUFACTURER_NAME_LEN);