Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/app/main/smfi.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,24 @@ static enum Result cmd_fan_set_pwm(void) {
return RES_ERR;
}

static enum Result cmd_fan_get_rpm(void) {
switch (smfi_cmd[SMFI_CMD_DATA]) {
case 1:
smfi_cmd[SMFI_CMD_DATA + 1] = (uint8_t)fan1_rpm;
smfi_cmd[SMFI_CMD_DATA + 2] = (uint8_t)(fan1_rpm >> 8);
return RES_OK;
#ifdef FAN2_PWM
case 2:
smfi_cmd[SMFI_CMD_DATA + 1] = (uint8_t)fan2_rpm;
smfi_cmd[SMFI_CMD_DATA + 2] = (uint8_t)(fan2_rpm >> 8);
return RES_OK;
#endif
}

// Failed if fan not found
return RES_ERR;
}

static enum Result cmd_fan_get_mode(void) {
smfi_cmd[SMFI_CMD_DATA] = fan_get_mode();
return RES_OK;
Expand Down Expand Up @@ -443,6 +461,9 @@ void smfi_event(void) {
break;
#endif // CONFIG_SECURITY

case CMD_FAN_GET_RPM:
smfi_cmd[SMFI_CMD_RES] = cmd_fan_get_rpm();
break;
case CMD_FAN_GET_MODE:
smfi_cmd[SMFI_CMD_RES] = cmd_fan_get_mode();
break;
Expand Down
10 changes: 8 additions & 2 deletions src/common/include/common/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,16 @@ enum Command {
CMD_SECURITY_GET = 20,
// Set security state
CMD_SECURITY_SET = 21,
// Get fan RPM
CMD_FAN_GET_RPM = 22,
// Get fan control mode
CMD_FAN_GET_MODE = 22,
CMD_FAN_GET_MODE = 23,
// Set fan control mode
CMD_FAN_SET_MODE = 23,
CMD_FAN_SET_MODE = 24,
// Get case revision
CMD_CASE_REV_GET = 25,
// Set case revision
CMD_CASE_REV_SET = 26,
};

enum Result {
Expand Down
28 changes: 26 additions & 2 deletions tools/system76_ectool/src/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ enum Cmd {
SetNoInput = 19,
SecurityGet = 20,
SecuritySet = 21,
FanGetMode = 22,
FanSetMode = 23,
FanGetRpm = 22,
FanGetMode = 23,
FanSetMode = 24,
CaseRevGet = 25,
CaseRevSet = 26,
}

const CMD_SPI_FLAG_READ: u8 = 1 << 0;
Expand Down Expand Up @@ -318,6 +321,14 @@ impl<A: Access> Ec<A> {
unsafe { self.command(Cmd::SecuritySet, &mut data) }
}

/// Get fan tachometer.
pub unsafe fn fan_get_rpm(&mut self, index: u8) -> Result<u16, Error> {
let mut data = [index, 0, 0];
data[0] = index;
unsafe { self.command(Cmd::FanGetRpm, &mut data)? };
Ok((data[1] as u16) | ((data[2] as u16) << 8))
}

/// Get fan control mode.
pub unsafe fn fan_get_mode(&mut self) -> Result<FanMode, Error> {
let mut data = [0];
Expand All @@ -331,6 +342,19 @@ impl<A: Access> Ec<A> {
unsafe { self.command(Cmd::FanSetMode, &mut data) }
}

/// Get case revision
pub unsafe fn case_rev_get(&mut self) -> Result<u32, Error> {
let mut data = [0; 4];
unsafe { self.command(Cmd::CaseRevGet, &mut data)? };
Ok(u32::from_le_bytes(data))
}

/// Set case revision
pub unsafe fn case_rev_set(&mut self, rev: u32) -> Result<(), Error> {
let mut data = rev.to_le_bytes();
unsafe { self.command(Cmd::CaseRevSet, &mut data) }
}

pub fn into_dyn(self) -> Ec<Box<dyn Access>>
where
A: 'static,
Expand Down
63 changes: 60 additions & 3 deletions tools/system76_ectool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,13 @@ unsafe fn fan_set_pwm(ec: &mut Ec<Box<dyn Access>>, index: u8, duty: u8) -> Resu
unsafe { ec.fan_set_pwm(index, duty) }
}

unsafe fn fan_get_rpm(ec: &mut Ec<Box<dyn Access>>, index: u8) -> Result<(), Error> {
let rpm = unsafe { ec.fan_get_rpm(index)? };
println!("{}", rpm);

Ok(())
}

unsafe fn fan_get_mode(ec: &mut Ec<Box<dyn Access>>) -> Result<(), Error> {
let mode = unsafe { ec.fan_get_mode()? };
println!("{}", mode);
Expand All @@ -285,6 +292,17 @@ unsafe fn fan_set_mode(ec: &mut Ec<Box<dyn Access>>, mode: ectool::FanMode) -> R
unsafe { ec.fan_set_mode(mode) }
}

unsafe fn case_rev_get(ec: &mut Ec<Box<dyn Access>>) -> Result<(), Error> {
let rev = unsafe { ec.case_rev_get()? };
println!("{}", rev);

Ok(())
}

unsafe fn case_rev_set(ec: &mut Ec<Box<dyn Access>>, rev: u32) -> Result<(), Error> {
unsafe { ec.case_rev_set(rev) }
}

unsafe fn keymap_get(
ec: &mut Ec<Box<dyn Access>>,
layer: u8,
Expand Down Expand Up @@ -333,13 +351,19 @@ fn parse_color(s: &str) -> Result<(u8, u8, u8), String> {
#[derive(Parser)]
#[clap(rename_all = "snake_case")]
enum SubCommand {
CaseRev {
rev: Option<u32>,
},
Console,
FanMode {
mode: Option<ectool::FanMode>,
},
FanPwm {
index: u8,
duty: Option<u8>,
},
FanMode {
mode: Option<ectool::FanMode>,
FanRpm {
index: u8,
},
Flash {
path: String,
Expand Down Expand Up @@ -426,7 +450,13 @@ fn main() {
// System76 launch_2
(0x3384, 0x0006, 1) |
// System76 launch_heavy_1
(0x3384, 0x0007, 1) => {
(0x3384, 0x0007, 1) |
// System76 launch_3
(0x3384, 0x0009, 1) |
// System76 launch_heavy_3
(0x3384, 0x000A, 1) |
// System76 thelio_io_2
(0x3384, 0x000B, 1) => {
let device = info.open_device(&api)?;
let access = AccessHid::new(device, 10, 100)?;
return Ok(Ec::new(access)?.into_dyn());
Expand All @@ -448,6 +478,24 @@ fn main() {
};

match args.subcommand {
SubCommand::CaseRev {
rev,
} => match rev {
Some(rev) => match unsafe { case_rev_set(&mut ec, rev) } {
Ok(()) => (),
Err(err) => {
eprintln!("failed to set case revision {}: {:X?}", rev, err);
process::exit(1);
}
},
None => match unsafe { case_rev_get(&mut ec) } {
Ok(()) => (),
Err(err) => {
eprintln!("failed to get case revision: {:X?}", err);
process::exit(1);
}
},
},
SubCommand::Console => match unsafe { console(&mut ec) } {
Ok(()) => (),
Err(err) => {
Expand Down Expand Up @@ -492,6 +540,15 @@ fn main() {
}
},
},
SubCommand::FanRpm {
index,
} => match unsafe { fan_get_rpm(&mut ec, index) } {
Ok(()) => (),
Err(err) => {
eprintln!("failed to get fan rpm {}: {:X?}", index, err);
process::exit(1);
}
},
SubCommand::Flash {
path,
} => match unsafe { flash(&mut ec, &path, SpiTarget::Main) } {
Expand Down