diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/device/i2c.h | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/src/include/device/i2c.h b/src/include/device/i2c.h index 997d201341..da9d1bcb3c 100644 --- a/src/include/device/i2c.h +++ b/src/include/device/i2c.h @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2014 Google, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,11 +21,83 @@ #define _DEVICE_I2C_H_ #include <stdint.h> +#include <stdlib.h> -/* note: chip is the 7-bit I2C address */ -int i2c_read(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, uint8_t *buf, unsigned len); -int i2c_write(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, const uint8_t *buf, unsigned len); +struct i2c_seg +{ + int read; + uint8_t chip; + uint8_t *buf; + int len; +}; + +int i2c_transfer(unsigned bus, struct i2c_seg *segments, int count); + +/* + * Read a raw chunk of data in one segment and one frame. + * + * [start][slave addr][r][data][stop] + */ +static inline int i2c_read_raw(unsigned bus, uint8_t chip, uint8_t *data, + int len) +{ + struct i2c_seg seg = + { .read = 1, .chip = chip, .buf = data, .len = len }; + return i2c_transfer(bus, &seg, 1); +} + +/* + * Write a raw chunk of data in one segment and one frame. + * + * [start][slave addr][w][data][stop] + */ +static inline int i2c_write_raw(unsigned bus, uint8_t chip, uint8_t *data, + int len) +{ + struct i2c_seg seg = + { .read = 0, .chip = chip, .buf = data, .len = len }; + return i2c_transfer(bus, &seg, 1); +} + +/** + * Read a byte with two segments in one frame + * + * [start][slave addr][w][register addr][start][slave addr][r][data][stop] + */ +static inline int i2c_readb(unsigned bus, uint8_t chip, uint8_t reg, + uint8_t *data) +{ + struct i2c_seg seg[2]; + + seg[0].read = 0; + seg[0].chip = chip; + seg[0].buf = ® + seg[0].len = 1; + seg[1].read = 1; + seg[1].chip = chip; + seg[1].buf = data; + seg[1].len = 1; + + return i2c_transfer(bus, seg, ARRAY_SIZE(seg)); +} + +/** + * Write a byte with one segment in one frame. + * + * [start][slave addr][w][register addr][data][stop] + */ +static inline int i2c_writeb(unsigned bus, uint8_t chip, uint8_t reg, + uint8_t data) +{ + struct i2c_seg seg; + uint8_t buf[] = {reg, data}; + + seg.read = 0; + seg.chip = chip; + seg.buf = buf; + seg.len = ARRAY_SIZE(buf); + + return i2c_transfer(bus, &seg, 1); +} #endif /* _DEVICE_I2C_H_ */ |