@@ -14,15 +14,34 @@ use crate::util::{assert_win_len, Config, Platform};
1414
1515use super :: * ;
1616
17+ const _HPI_FLASH_ENTER_SIGNATURE: char = 'P' ;
18+ const _HPI_JUMP_TO_ALT_SIGNATURE: char = 'A' ;
19+ const _HPI_JUMP_TO_BOOT_SIGNATURE: char = 'J' ;
20+ const HPI_RESET_SIGNATURE : char = 'R' ;
21+ const _HPI_FLASH_RW_SIGNATURE: char = 'F' ;
22+ const HPI_RESET_DEV_CMD : u8 = 1 ;
23+ const _HPI_FLASH_READ_CMD: u8 = 0 ;
24+ const _HPI_FLASH_WRITE_CMD: u8 = 1 ;
25+
26+ #[ derive( Debug , Copy , Clone ) ]
1727enum ControlRegisters {
1828 DeviceMode = 0 ,
1929 SiliconId = 2 , // Two bytes long, First LSB, then MSB
30+ _InterruptStatus = 0x06 ,
31+ _JumpToBoot = 0x07 ,
32+ ResetRequest = 0x08 ,
33+ _FlashmodeEnter = 0x0A ,
34+ _ValidateFw = 0x0B ,
35+ _FlashSignature = 0x0C ,
2036 BootLoaderVersion = 0x10 ,
2137 Firmware1Version = 0x18 ,
2238 Firmware2Version = 0x20 ,
39+ PdPortsEnable = 0x2C ,
40+ _ResponseType = 0x7E ,
41+ _FlashRwMem = 0x0200 ,
2342}
2443
25- #[ derive( Debug ) ]
44+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
2645pub enum PdPort {
2746 Left01 ,
2847 Right23 ,
@@ -130,7 +149,7 @@ pub struct PdController {
130149 ec : CrosEc ,
131150}
132151
133- #[ derive( Debug , PartialEq ) ]
152+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
134153pub enum FwMode {
135154 BootLoader = 0 ,
136155 /// Backup CCGX firmware (No 1)
@@ -182,6 +201,21 @@ impl PdController {
182201 )
183202 }
184203
204+ pub fn i2c_write ( & self , addr : u16 , data : & [ u8 ] ) -> EcResult < EcI2cPassthruResponse > {
205+ trace ! (
206+ "I2C passthrough from I2C Port {} to I2C Addr {}" ,
207+ self . port. i2c_port( ) ?,
208+ self . port. i2c_address( ) ?
209+ ) ;
210+ i2c_write (
211+ & self . ec ,
212+ self . port . i2c_port ( ) ?,
213+ self . port . i2c_address ( ) ?,
214+ addr,
215+ data,
216+ )
217+ }
218+
185219 fn ccgx_read ( & self , reg : ControlRegisters , len : u16 ) -> EcResult < Vec < u8 > > {
186220 let mut data: Vec < u8 > = Vec :: with_capacity ( len. into ( ) ) ;
187221
@@ -204,6 +238,35 @@ impl PdController {
204238 Ok ( data)
205239 }
206240
241+ fn ccgx_write ( & self , reg : ControlRegisters , data : & [ u8 ] ) -> EcResult < ( ) > {
242+ let addr = reg as u16 ;
243+ trace ! (
244+ "ccgx_write(reg: {:?}, addr: {}, data.len(): {}" ,
245+ reg,
246+ addr,
247+ data. len( )
248+ ) ;
249+ let mut data_written = 0 ;
250+
251+ while data_written < data. len ( ) {
252+ let chunk_len = std:: cmp:: min ( MAX_I2C_CHUNK , data. len ( ) ) ;
253+ let buffer = & data[ data_written..data_written + chunk_len] ;
254+ let offset = addr + data_written as u16 ;
255+
256+ let i2c_response = self . i2c_write ( offset, buffer) ?;
257+ if let Err ( EcError :: DeviceError ( err) ) = i2c_response. is_successful ( ) {
258+ return Err ( EcError :: DeviceError ( format ! (
259+ "I2C write was not successful: {:?}" ,
260+ err
261+ ) ) ) ;
262+ }
263+
264+ data_written += chunk_len;
265+ }
266+
267+ Ok ( ( ) )
268+ }
269+
207270 pub fn get_silicon_id ( & self ) -> EcResult < u16 > {
208271 let data = self . ccgx_read ( ControlRegisters :: SiliconId , 2 ) ?;
209272 assert_win_len ( data. len ( ) , 2 ) ;
@@ -295,4 +358,24 @@ impl PdController {
295358 base_ver, app_ver
296359 ) ;
297360 }
361+
362+ pub fn reset_device ( & self ) -> EcResult < ( ) > {
363+ self . ccgx_write (
364+ ControlRegisters :: ResetRequest ,
365+ & [ HPI_RESET_SIGNATURE as u8 , HPI_RESET_DEV_CMD ] ,
366+ ) ?;
367+ Ok ( ( ) )
368+ }
369+
370+ pub fn enable_ports ( & self , enable : bool ) -> EcResult < ( ) > {
371+ let mask = if enable { 0b11 } else { 0b00 } ;
372+ self . ccgx_write ( ControlRegisters :: PdPortsEnable , & [ mask] ) ?;
373+ Ok ( ( ) )
374+ }
375+
376+ pub fn get_port_status ( & self ) -> EcResult < u8 > {
377+ let data = self . ccgx_read ( ControlRegisters :: PdPortsEnable , 1 ) ?;
378+ assert_win_len ( data. len ( ) , 1 ) ;
379+ Ok ( data[ 0 ] )
380+ }
298381}
0 commit comments