blob: da9d1bcb3c697837f839f8c10d7ed4b5a697cecf [file] [log] [blame]
David Hendricksf4c35082012-12-27 14:15:51 -08001/*
David Hendrickscfb73602013-04-05 13:42:39 -07002 * This file is part of the coreboot project.
David Hendricksf4c35082012-12-27 14:15:51 -08003 *
Gabe Blackcdb61a62014-04-07 18:45:14 -07004 * Copyright (C) 2014 Google, Inc.
David Hendricksf4c35082012-12-27 14:15:51 -08005 *
David Hendrickscfb73602013-04-05 13:42:39 -07006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
David Hendricksf4c35082012-12-27 14:15:51 -08009 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
David Hendrickscfb73602013-04-05 13:42:39 -070017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
David Hendricksf4c35082012-12-27 14:15:51 -080018 */
19
David Hendrickscfb73602013-04-05 13:42:39 -070020#ifndef _DEVICE_I2C_H_
21#define _DEVICE_I2C_H_
David Hendricksf4c35082012-12-27 14:15:51 -080022
Gabe Blacka5dc0912013-06-30 03:47:33 -070023#include <stdint.h>
Gabe Blackcdb61a62014-04-07 18:45:14 -070024#include <stdlib.h>
Gabe Blacka5dc0912013-06-30 03:47:33 -070025
Gabe Blackcdb61a62014-04-07 18:45:14 -070026struct i2c_seg
27{
28 int read;
29 uint8_t chip;
30 uint8_t *buf;
31 int len;
32};
33
34int i2c_transfer(unsigned bus, struct i2c_seg *segments, int count);
35
36/*
37 * Read a raw chunk of data in one segment and one frame.
38 *
39 * [start][slave addr][r][data][stop]
40 */
41static inline int i2c_read_raw(unsigned bus, uint8_t chip, uint8_t *data,
42 int len)
43{
44 struct i2c_seg seg =
45 { .read = 1, .chip = chip, .buf = data, .len = len };
46 return i2c_transfer(bus, &seg, 1);
47}
48
49/*
50 * Write a raw chunk of data in one segment and one frame.
51 *
52 * [start][slave addr][w][data][stop]
53 */
54static inline int i2c_write_raw(unsigned bus, uint8_t chip, uint8_t *data,
55 int len)
56{
57 struct i2c_seg seg =
58 { .read = 0, .chip = chip, .buf = data, .len = len };
59 return i2c_transfer(bus, &seg, 1);
60}
61
62/**
63 * Read a byte with two segments in one frame
64 *
65 * [start][slave addr][w][register addr][start][slave addr][r][data][stop]
66 */
67static inline int i2c_readb(unsigned bus, uint8_t chip, uint8_t reg,
68 uint8_t *data)
69{
70 struct i2c_seg seg[2];
71
72 seg[0].read = 0;
73 seg[0].chip = chip;
74 seg[0].buf = &reg;
75 seg[0].len = 1;
76 seg[1].read = 1;
77 seg[1].chip = chip;
78 seg[1].buf = data;
79 seg[1].len = 1;
80
81 return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
82}
83
84/**
85 * Write a byte with one segment in one frame.
86 *
87 * [start][slave addr][w][register addr][data][stop]
88 */
89static inline int i2c_writeb(unsigned bus, uint8_t chip, uint8_t reg,
90 uint8_t data)
91{
92 struct i2c_seg seg;
93 uint8_t buf[] = {reg, data};
94
95 seg.read = 0;
96 seg.chip = chip;
97 seg.buf = buf;
98 seg.len = ARRAY_SIZE(buf);
99
100 return i2c_transfer(bus, &seg, 1);
101}
David Hendricksf4c35082012-12-27 14:15:51 -0800102
David Hendrickscfb73602013-04-05 13:42:39 -0700103#endif /* _DEVICE_I2C_H_ */