mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
Implement board-level I2C arbitration
Add a way for boards to permit or deny access to the I2C port. This works in a board-specific manner. All I2C master traffic requires that board_i2c_claim() be called first. A dummy function is provided for boards which do not require this. BUG=chrome-os-partner:10888 TEST=manual: build for all boards boot on snow (cannot test i2c as it is broken) Change-Id: I786d4ae17f1d798faf13b303b5389679fb6720cb Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/26141
This commit is contained in:
@@ -70,6 +70,23 @@ static inline void disable_ack(int port)
|
||||
STM32_I2C_CR1(port) &= ~(1 << 10);
|
||||
}
|
||||
|
||||
int __board_i2c_claim(int port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_i2c_claim(int port)
|
||||
__attribute__((weak, alias("__board_i2c_claim")));
|
||||
|
||||
|
||||
void __board_i2c_release(int port)
|
||||
{
|
||||
}
|
||||
|
||||
void board_i2c_release(int port)
|
||||
__attribute__((weak, alias("__board_i2c_release")));
|
||||
|
||||
|
||||
static int wait_tx(int port)
|
||||
{
|
||||
static timestamp_t deadline;
|
||||
@@ -554,6 +571,12 @@ static int i2c_xfer(int port, int slave_addr, uint8_t *out, int out_bytes,
|
||||
ASSERT(in || !in_bytes);
|
||||
|
||||
mutex_lock(&i2c_mutex);
|
||||
|
||||
if (board_i2c_claim(port)) {
|
||||
rv = EC_ERROR_BUSY;
|
||||
goto err_claim;
|
||||
}
|
||||
|
||||
disable_i2c_interrupt(port);
|
||||
|
||||
rv = i2c_master_transmit(port, slave_addr, out, out_bytes,
|
||||
@@ -563,6 +586,10 @@ static int i2c_xfer(int port, int slave_addr, uint8_t *out, int out_bytes,
|
||||
handle_i2c_error(port, rv);
|
||||
|
||||
enable_i2c_interrupt(port);
|
||||
|
||||
board_i2c_release(port);
|
||||
|
||||
err_claim:
|
||||
mutex_unlock(&i2c_mutex);
|
||||
|
||||
return rv;
|
||||
|
||||
@@ -48,4 +48,32 @@ int i2c_write8(int port, int slave_addr, int offset, int data);
|
||||
int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data,
|
||||
int len);
|
||||
|
||||
/**
|
||||
* Claim an I2C port for use in master mode
|
||||
*
|
||||
* If this function succeed, then you must later call board_i2c_release()
|
||||
* to release the claim.
|
||||
*
|
||||
* This function may optionally be implemented by a board file. If provided
|
||||
* then it should check the port number and arbitrate as needed.
|
||||
*
|
||||
* This function will not be called to claim an already-claimed port.
|
||||
*
|
||||
* @param port Port to claim (0 for first, 1 for second, etc.)
|
||||
* @return 0 if claimed successfully, -1 if it is in use
|
||||
*/
|
||||
int board_i2c_claim(int port);
|
||||
|
||||
/**
|
||||
* Release an I2C port (after previously being claimed)
|
||||
*
|
||||
* This function may optionally be implemented by a board file. If provided
|
||||
* then it should check the port number and arbitrate as needed.
|
||||
*
|
||||
* This function will not be called to release an already-released port.
|
||||
*
|
||||
* @param port Port to claim (0 for first, 1 for second, etc.)
|
||||
*/
|
||||
void board_i2c_release(int port);
|
||||
|
||||
#endif /* __CROS_EC_I2C_H */
|
||||
|
||||
Reference in New Issue
Block a user