diff options
author | Sheng-Liang Song <ssl@chromium.org> | 2014-07-24 09:22:11 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-08-29 02:57:00 +0000 |
commit | 7bea5174a19b6d3b4cd9f5a7e96f7d492a24fc8f (patch) | |
tree | 4bf5f92421086f20668dd19d85ee129cfd6e93f7 /include | |
parent | b7f1d5261917c88e734d0e788de74b2bc419c431 (diff) | |
download | chrome-ec-7bea5174a19b6d3b4cd9f5a7e96f7d492a24fc8f.tar.gz |
EC: Add smbus interface read & write APIs
Ref: http://smbus.org/specs/smbus20.pdf
- Support software CRC8 generation and checking.
- Support read/write word (2-bytes)
- Support read/write blocks (up to 32 bytes)
BUG=chrome-os-partner:24741
BRANCH=ToT,glimmer
TEST=Verified with smart battery firmware update application on glimmer.
Passed LGC & Simplo Battery.
Change-Id: Ic2e7f759af80c06741ed49fee1826213429fbf8a
Signed-off-by: Sheng-Liang Song <ssl@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/209747
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/common.h | 2 | ||||
-rw-r--r-- | include/config.h | 8 | ||||
-rw-r--r-- | include/crc8.h | 21 | ||||
-rw-r--r-- | include/i2c.h | 5 | ||||
-rw-r--r-- | include/smbus.h | 158 |
5 files changed, 193 insertions, 1 deletions
diff --git a/include/common.h b/include/common.h index cddcde31fa..eb4ebd7c32 100644 --- a/include/common.h +++ b/include/common.h @@ -88,6 +88,8 @@ enum ec_error_list { EC_ERROR_NOT_POWERED = 8, /* Failed because component is not calibrated */ EC_ERROR_NOT_CALIBRATED = 9, + /* Failed because CRC error */ + EC_ERROR_CRC = 10, /* Invalid console command param (PARAMn means parameter n is bad) */ EC_ERROR_PARAM1 = 11, EC_ERROR_PARAM2 = 12, diff --git a/include/config.h b/include/config.h index 609d0943b2..8e0f1dd10a 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -376,6 +376,9 @@ */ #undef CONFIG_CONSOLE_RESTRICTED_INPUT +/* Include CRC-8 utility function */ +#undef CONFIG_CRC8 + /*****************************************************************************/ /* * Debugging config @@ -803,6 +806,9 @@ /* Emulate the CLZ (Count Leading Zeros) in software for CPU lacking support */ #undef CONFIG_SOFTWARE_CLZ +/* Support smbus interface */ +#undef CONFIG_SMBUS + /* Support SPI interfaces */ #undef CONFIG_SPI diff --git a/include/crc8.h b/include/crc8.h new file mode 100644 index 0000000000..94980effc5 --- /dev/null +++ b/include/crc8.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Very simple 8-bit CRC function. + */ +#ifndef __EC_CRC8_H__ +#define __EC_CRC8_H__ + +/** + * crc8 + * Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. A table-based + * algorithm would be faster, but for only a few bytes it isn't worth the code + * size. + * @param data uint8_t *, input, a pointer to input data + * @param len int, input, size of iput data in byte + * @return the crc-8 of the input data. + */ +uint8_t crc8(const uint8_t *data, int len); + +#endif /* __EC_CRC8_H__ */ diff --git a/include/i2c.h b/include/i2c.h index 9cb884ba19..a4e105ddac 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -151,6 +151,11 @@ int i2c_read8(int port, int slave_addr, int offset, int *data); int i2c_write8(int port, int slave_addr, int offset, int data); /** + * @return non-zero if i2c bus is busy + */ +int i2c_is_busy(int port); + +/** * Attempt to unwedge an I2C bus. * * @param port I2C port diff --git a/include/smbus.h b/include/smbus.h new file mode 100644 index 0000000000..8f1bfeb9c9 --- /dev/null +++ b/include/smbus.h @@ -0,0 +1,158 @@ +/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * @file smbus.h + * @brief smbus interface APIs + * @see http://smbus.org/specs/smbus20.pdf + */ +#ifndef __EC_SMBUS_H__ +#define __EC_SMBUS_H__ + +/** Maximum transfer of a SMBUS block transfer */ +#define SMBUS_MAX_BLOCK_SIZE 32 + +/** + * smbus write word + * write 2 byte data + 1 byte pec + */ +struct smbus_wr_word { + uint8_t slave_addr;/**< i2c_addr << 1 */ + uint8_t smbus_cmd; /**< smbus cmd */ + uint8_t data[3]; /**< smbus data */ +} __packed; + +/** + * smbus write block data + * smbus write 1 byte size + 32 byte data + 1 byte pec + */ +struct smbus_wr_block { + uint8_t slave_addr;/**< i2c_addr << 1 */ + uint8_t smbus_cmd; /**< smbus cmd */ + uint8_t size; /**< write size */ + uint8_t data[SMBUS_MAX_BLOCK_SIZE+1]; +} __packed; + +/** + * smbus read word + * smbus read 2 byte + 1 pec + */ +struct smbus_rd_word { + uint8_t slave_addr; /**< i2c_addr << 1 */ + uint8_t smbus_cmd; /**< smbus cmd */ + uint8_t slave_addr_rd;/**< (i2c_addr << 1) | 0x1 */ + uint8_t data[3]; /**< smbus data */ +} __packed; + +/** + * smbus read block data + * smbus read 1 byte size + 32 byte data + 1 byte pec + */ +struct smbus_rd_block { + uint8_t slave_addr; /**< i2c_addr << 1 */ + uint8_t smbus_cmd; /**< smbus cmd */ + uint8_t slave_addr_rd;/**< (i2c_addr << 1) | 0x1 */ + uint8_t size; /**< read block size */ + uint8_t data[SMBUS_MAX_BLOCK_SIZE+1]; /**< smbus data */ +} __packed; + +/** + * smbus_write_word + * smbus write 2 bytes + * @param i2c_port uint8_t, i2c port address + * @param slave_addr uint8_t, i2c slave address:= (i2c_addr << 1) + * @param smbus_cmd uint8_t, smbus command + * @param d16 uint16_t, 2-bytes data + * @return error_code + * EC_SUCCESS if success; none-zero if fail + * EC_ERROR_BUSY if interface is bussy + * none zero error code if fail + */ +int smbus_write_word(uint8_t i2c_port, uint8_t slave_addr, + uint8_t smbus_cmd, uint16_t d16); + +/** + * smbus_write_block + * smbus write upto 32 bytes + * case 1: n-1 byte data, 1 byte PEC + * [S][i2c Address][Wr=0][A][cmd][A] ...[Di][Ai]... [PEC][A][P] + * + * case 2: 1 byte data-size, n -2 byte data, 1 byte PEC + * [S][i2c Address][Wr=0][A][cmd][A][size][A] ...[Di][Ai]... [PEC][A][P] + * + * @param i2c_port uint8_t, i2c port address + * @param slave_addr uint8_t, i2c slave address:= (i2c_addr << 1) + * @param smbus_cmd uint8_t, smbus command + * @param data uint8_t *, n-bytes data + * @param len uint8_t, data length + * @return error_code + * EC_SUCCESS if success; none-zero if fail + * EC_ERROR_BUSY if interface is bussy + * none zero error code if fail + */ +int smbus_write_block(uint8_t i2c_port, uint8_t slave_addr, + uint8_t smbus_cmd, uint8_t *data, uint8_t len); + +/** + * smbus_read_word + * smbus read 2 bytes + * @param i2c_port uint8_t, i2c port address + * @param slave_addr uint8_t, i2c slave address:= (i2c_addr << 1) + * @param smbus_cmd uint8_t, smbus command + * @param p16 uint16_t *, a pointer to 2-bytes data + * @return error_code + * EC_SUCCESS if success; none-zero if fail + * EC_ERROR_BUSY if interface is bussy + * none zero error code if fail + */ +int smbus_read_word(uint8_t i2c_port, uint8_t slave_addr, + uint8_t smbus_cmd, uint16_t *p16); + +/** + * smbus_read_block + * smbus read upto 32 bytes + * case 1: n-1 byte data, 1 byte PEC + * [S][i2c addr][Wr=0][A][cmd][A] + * [S][i2c addr][Rd=1][A]...[Di][Ai]...[PEC][A][P] + * + * case 2: 1 byte data-size, n - 2 byte data, 1 byte PEC + * [S][i2c addr][Wr=0][A][cmd][A] + * [S][i2c addr][Rd=1][A][size][A]...[Di][Ai]...[PEC][A][P] + * + * @param i2c_port uint8_t, i2c port address + * @param slave_addr uint8_t, i2c slave address:= (i2c_addr << 1) + * @param smbus_cmd uint8_t, smbus command + * @param data uint8_t *, n-bytes data + * @param plen uint8_t *, a pointer data length + * @return error_code + * EC_SUCCESS if success; none-zero if fail + * EC_ERROR_BUSY if interface is bussy + * none zero error code if fail + */ +int smbus_read_block(uint8_t i2c_port, uint8_t slave_addr, + uint8_t smbus_cmd, uint8_t *data, uint8_t *plen); + +/** + * smbus_read_string + * smbus read ascii string (upto 32-byte data + 1-byte NULL) + * Read bytestream from <slaveaddr>:<smbus_cmd> with format: + * [length_N] [byte_0] [byte_1] ... [byte_N-1][byte_N='\0'] + * + * <len> : the max length of receving buffer. to read N bytes + * ascii, len should be at least N+1 to include the + * terminating 0 (NULL). + * + * @param i2c_port uint8_t, i2c port address + * @param slave_addr uint8_t, i2c slave address:= (i2c_addr << 1) + * @param smbus_cmd uint8_t, smbus command + * @param data uint8_t *, n-bytes data + * @param len uint8_t, data length + * @return error_code + * EC_SUCCESS if success; none-zero if fail + * EC_ERROR_BUSY if interface is bussy + * none zero error code if fail + */ +int smbus_read_string(int i2c_port, uint8_t slave_addr, uint8_t smbus_cmd, + uint8_t *data, uint8_t len); + +#endif /* __EC_SMBUS_H__ */ |