Skip to content

Commit 1c1c59d

Browse files
committed
Add commandline option to set charger current limit
Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent 660e2bc commit 1c1c59d

File tree

7 files changed

+134
-0
lines changed

7 files changed

+134
-0
lines changed

EXAMPLES.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,46 @@ Battery Status
170170
Charge level: 92%
171171
Battery discharging
172172
```
173+
174+
### Setting a custom charger current limit
175+
176+
```
177+
# Set limit to 2A
178+
> sudo framework_tool --charge-current-limit 2000
179+
180+
# And then plug in a power adapter
181+
> sudo framework_tool --power
182+
Charger Status
183+
AC is: connected
184+
Charger Voltage: 17800mV
185+
Charger Current: 2000mA
186+
Chg Input Current:3084mA
187+
Battery SoC: 87%
188+
Battery Status
189+
AC is: connected
190+
Battery is: connected
191+
Battery LFCC: 3713 mAh (Last Full Charge Capacity)
192+
Battery Capacity: 3215 mAh
193+
56.953 Wh
194+
Charge level: 86%
195+
Battery charging
196+
197+
# Remove limit (highest USB-PD current is 5A)
198+
> sudo framework_tool --charge-current-limit 5000
199+
200+
> sudo framework_tool --power
201+
Charger Status
202+
AC is: connected
203+
Charger Voltage: 17800mV
204+
Charger Current: 2740mA
205+
Chg Input Current:3084mA
206+
Battery SoC: 92%
207+
Battery Status
208+
AC is: connected
209+
Battery is: connected
210+
Battery LFCC: 3713 mAh (Last Full Charge Capacity)
211+
Battery Capacity: 3387 mAh
212+
60.146 Wh
213+
Charge level: 91%
214+
Battery charging
215+
```

framework_lib/src/chromium_ec/command.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub enum EcCommands {
4141
ConsoleSnapshot = 0x0097,
4242
ConsoleRead = 0x0098,
4343
ChargeState = 0x00A0,
44+
ChargeCurrentLimit = 0x00A1,
4445
/// List the features supported by the firmware
4546
GetFeatures = 0x000D,
4647
/// Force reboot, causes host reboot as well

framework_lib/src/chromium_ec/commands.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,35 @@ impl EcRequest<EcResponseChargeStateGetV0> for EcRequestChargeStateGetV0 {
409409
}
410410
}
411411

412+
pub struct EcRequestCurrentLimitV0 {
413+
/// Current limit in mA
414+
pub current: u32,
415+
}
416+
417+
impl EcRequest<()> for EcRequestCurrentLimitV0 {
418+
fn command_id() -> EcCommands {
419+
EcCommands::ChargeCurrentLimit
420+
}
421+
}
422+
423+
pub struct EcRequestCurrentLimitV1 {
424+
/// Current limit in mA
425+
pub current: u32,
426+
/// Battery state of charge is the minimum charge percentage at which
427+
/// the battery charge current limit will apply.
428+
/// When not set, the limit will apply regardless of state of charge.
429+
pub battery_soc: u8,
430+
}
431+
432+
impl EcRequest<()> for EcRequestCurrentLimitV1 {
433+
fn command_id() -> EcCommands {
434+
EcCommands::ChargeCurrentLimit
435+
}
436+
fn command_version() -> u8 {
437+
1
438+
}
439+
}
440+
412441
/// Supported features
413442
#[derive(Debug, FromPrimitive)]
414443
pub enum EcFeatureCode {

framework_lib/src/chromium_ec/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,19 @@ impl CrosEc {
394394
Ok((limits.min_percentage, limits.max_percentage))
395395
}
396396

397+
pub fn set_charge_current_limit(&self, current: u32, battery_soc: Option<u32>) -> EcResult<()> {
398+
if let Some(battery_soc) = battery_soc {
399+
let battery_soc = battery_soc as u8;
400+
EcRequestCurrentLimitV1 {
401+
current,
402+
battery_soc,
403+
}
404+
.send_command(self)
405+
} else {
406+
EcRequestCurrentLimitV0 { current }.send_command(self)
407+
}
408+
}
409+
397410
pub fn set_fp_led_percentage(&self, percentage: u8) -> EcResult<()> {
398411
// Sending bytes manually because the Set command, as opposed to the Get command,
399412
// does not return any data

framework_lib/src/commandline/clap_std.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ struct ClapCli {
155155
#[arg(long)]
156156
charge_limit: Option<Option<u8>>,
157157

158+
/// Get or set max charge current limit
159+
#[arg(long)]
160+
#[clap(num_args = ..2)]
161+
charge_current_limit: Vec<u32>,
162+
158163
/// Get GPIO value by name
159164
#[arg(long)]
160165
get_gpio: Option<String>,
@@ -305,6 +310,14 @@ pub fn parse(args: &[String]) -> Cli {
305310
1 => Some((None, args.fansetrpm[0])),
306311
_ => None,
307312
};
313+
let charge_current_limit = match args.charge_current_limit.len() {
314+
2 => Some((
315+
args.charge_current_limit[0],
316+
Some(args.charge_current_limit[1]),
317+
)),
318+
1 => Some((args.charge_current_limit[0], None)),
319+
_ => None,
320+
};
308321

309322
Cli {
310323
verbosity: args.verbosity.log_level_filter(),
@@ -358,6 +371,7 @@ pub fn parse(args: &[String]) -> Cli {
358371
inputdeck_mode: args.inputdeck_mode,
359372
expansion_bay: args.expansion_bay,
360373
charge_limit: args.charge_limit,
374+
charge_current_limit,
361375
get_gpio: args.get_gpio,
362376
fp_led_level: args.fp_led_level,
363377
fp_brightness: args.fp_brightness,

framework_lib/src/commandline/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ pub struct Cli {
175175
pub inputdeck_mode: Option<InputDeckModeArg>,
176176
pub expansion_bay: bool,
177177
pub charge_limit: Option<Option<u8>>,
178+
pub charge_current_limit: Option<(u32, Option<u32>)>,
178179
pub get_gpio: Option<String>,
179180
pub fp_led_level: Option<Option<FpBrightnessArg>>,
180181
pub fp_brightness: Option<Option<u8>>,
@@ -762,6 +763,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
762763
}
763764
} else if let Some(maybe_limit) = args.charge_limit {
764765
print_err(handle_charge_limit(&ec, maybe_limit));
766+
} else if let Some((limit, soc)) = args.charge_current_limit {
767+
print_err(ec.set_charge_current_limit(limit, soc));
765768
} else if let Some(gpio_name) = &args.get_gpio {
766769
print!("Getting GPIO value {}: ", gpio_name);
767770
if let Ok(value) = ec.get_gpio(gpio_name) {
@@ -1081,6 +1084,7 @@ Options:
10811084
--inputdeck-mode Set input deck power mode [possible values: auto, off, on] (Framework 16 only)
10821085
--expansion-bay Show status of the expansion bay (Framework 16 only)
10831086
--charge-limit [<VAL>] Get or set battery charge limit (Percentage number as arg, e.g. '100')
1087+
--charge-current-limit [<VAL>] Get or set battery current charge limit (Percentage number as arg, e.g. '100')
10841088
--get-gpio <GET_GPIO> Get GPIO value by name
10851089
--fp-led-level [<VAL>] Get or set fingerprint LED brightness level [possible values: high, medium, low]
10861090
--fp-brightness [<VAL>]Get or set fingerprint LED brightness percentage

framework_lib/src/commandline/uefi.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub fn parse(args: &[String]) -> Cli {
8888
inputdeck_mode: None,
8989
expansion_bay: false,
9090
charge_limit: None,
91+
charge_current_limit: None,
9192
get_gpio: None,
9293
fp_led_level: None,
9394
fp_brightness: None,
@@ -266,6 +267,35 @@ pub fn parse(args: &[String]) -> Cli {
266267
Some(None)
267268
};
268269
found_an_option = true;
270+
} else if arg == "--charge-current-limit" {
271+
cli.charge_current_limit = if args.len() > i + 2 {
272+
let limit = args[i + 1].parse::<u32>();
273+
let soc = args[i + 2].parse::<u32>();
274+
if let (Ok(limit), Ok(soc)) = (limit, soc) {
275+
Some((limit, Some(soc)))
276+
} else {
277+
println!(
278+
"Invalid values for --charge-current-limit: '{} {}'. Must be u32 integers.",
279+
args[i + 1],
280+
args[i + 2]
281+
);
282+
None
283+
}
284+
} else if args.len() > i + 1 {
285+
if let Ok(limit) = args[i + 1].parse::<u32>() {
286+
Some((limit, None))
287+
} else {
288+
println!(
289+
"Invalid values for --charge-current-limit: '{}'. Must be an integer.",
290+
args[i + 1],
291+
);
292+
None
293+
}
294+
} else {
295+
println!("--charge-current-limit requires one or two. [limit] [soc] or [limit]");
296+
None
297+
};
298+
found_an_option = true;
269299
} else if arg == "--get-gpio" {
270300
cli.get_gpio = if args.len() > i + 1 {
271301
Some(args[i + 1].clone())

0 commit comments

Comments
 (0)