@@ -121,6 +121,66 @@ pub fn i2c_read(
121121 } )
122122}
123123
124+ /// I2C read with 16-bit addressing (for larger EEPROMs like 24C32+)
125+ /// Always sends a 2-byte address, even for addr=0
126+ pub fn i2c_read_16bit_addr (
127+ ec : & CrosEc ,
128+ i2c_port : u8 ,
129+ i2c_addr : u16 ,
130+ addr : u16 ,
131+ len : u16 ,
132+ ) -> EcResult < EcI2cPassthruResponse > {
133+ trace ! (
134+ "i2c_read_16bit_addr(i2c_port: 0x{:X}, i2c_addr: 0x{:X}, addr: 0x{:X}, len: 0x{:X})" ,
135+ i2c_port,
136+ i2c_addr,
137+ addr,
138+ len
139+ ) ;
140+ if usize:: from ( len) > MAX_I2C_CHUNK {
141+ return EcResult :: Err ( EcError :: DeviceError ( format ! (
142+ "i2c_read too long. Must be <128, is: {}" ,
143+ len
144+ ) ) ) ;
145+ }
146+ // Always use 16-bit addressing (big-endian for EEPROM)
147+ let addr_bytes = u16:: to_be_bytes ( addr) . to_vec ( ) ;
148+ let messages = vec ! [
149+ EcParamsI2cPassthruMsg {
150+ addr_and_flags: i2c_addr,
151+ transfer_len: addr_bytes. len( ) as u16 ,
152+ } ,
153+ EcParamsI2cPassthruMsg {
154+ addr_and_flags: i2c_addr + I2C_READ_FLAG ,
155+ transfer_len: len, // How much to read
156+ } ,
157+ ] ;
158+ let msgs_len = size_of :: < EcParamsI2cPassthruMsg > ( ) * messages. len ( ) ;
159+ let msgs_buffer: & [ u8 ] = unsafe { util:: any_vec_as_u8_slice ( & messages) } ;
160+
161+ let params = EcParamsI2cPassthru {
162+ port : i2c_port,
163+ messages : messages. len ( ) as u8 ,
164+ msg : [ ] , // Messages are copied right after this struct
165+ } ;
166+ let params_len = size_of :: < EcParamsI2cPassthru > ( ) ;
167+ let params_buffer: & [ u8 ] = unsafe { util:: any_as_u8_slice ( & params) } ;
168+
169+ let mut buffer: Vec < u8 > = vec ! [ 0 ; params_len + msgs_len + addr_bytes. len( ) ] ;
170+ buffer[ 0 ..params_len] . copy_from_slice ( params_buffer) ;
171+ buffer[ params_len..params_len + msgs_len] . copy_from_slice ( msgs_buffer) ;
172+ buffer[ params_len + msgs_len..] . copy_from_slice ( & addr_bytes) ;
173+
174+ let data = ec. send_command ( EcCommands :: I2cPassthrough as u16 , 0 , & buffer) ?;
175+ let res: _EcI2cPassthruResponse = unsafe { std:: ptr:: read ( data. as_ptr ( ) as * const _ ) } ;
176+ let res_data = & data[ size_of :: < _EcI2cPassthruResponse > ( ) ..] ;
177+ debug_assert ! ( res. messages as usize == messages. len( ) || res. messages == 0 ) ;
178+ Ok ( EcI2cPassthruResponse {
179+ i2c_status : res. i2c_status ,
180+ data : res_data. to_vec ( ) ,
181+ } )
182+ }
183+
124184/* Write address and bytes in a single I2C transfer */
125185pub fn i2c_write_block (
126186 ec : & CrosEc ,
0 commit comments