1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#include <platsupport/i2c.h>
14
15#include <string.h>
16#include <utils/util.h>
17#include <utils/zf_log_if.h>
18#include <assert.h>
19
20/**
21 * Register based I2C device
22 * We use copyin/out in order to automatically fix endianess and
23 * also because a write operation must be a contiguous stream of register
24 * address then data.
25 */
26#define ABS(x) ( ((x) < 0)? -x : x )
27
28#define BUFFER_SIZE 128
29
30/* Copy from data into buf while fixing endianess */
31static void
32_fill_data(char* buf, const char* data, enum kvfmt fmt, int count)
33{
34    int bytes = ABS(fmt);
35    int i, j;
36    for (j = 0; j < count; j++) {
37        for (i = 0; i < bytes; i++) {
38            int idx = (fmt > 0) ? i : (bytes - 1) - i;
39            buf[idx] = data[i];
40        }
41        data += bytes;
42        buf += bytes;
43    }
44}
45
46/* Copy reg into buf with required endianess */
47static int
48_fill_reg(char* buf, uint64_t reg, enum kvfmt fmt)
49{
50    int i;
51    int bytes = ABS(fmt);
52    for (i = 0; i < bytes; i++, reg >>= 8) {
53        int idx = (fmt > 0) ? i : (bytes - 1) - i;
54        buf[idx] = reg & 0xff;
55    }
56    return i;
57}
58
59/* Read no more than count registers into data with correct endianess */
60static int
61_do_kvread(i2c_kvslave_t* kvs, uint64_t reg, void* data, int count)
62{
63    int abytes, dbytes, bytes;
64    char d[BUFFER_SIZE];
65    assert(kvs);
66    assert(kvs->slave);
67    abytes = ABS(kvs->address_fmt);
68    dbytes = ABS(kvs->data_fmt);
69    assert(abytes < BUFFER_SIZE && dbytes < BUFFER_SIZE);
70    /* Limit the amount of data to read to fit our buffer */
71    if (count * dbytes > BUFFER_SIZE) {
72        count = BUFFER_SIZE / dbytes;
73    }
74    /* Send the register address */
75    ZF_LOGD("Seek register 0x%02llx", reg);
76    _fill_reg(d, reg, kvs->address_fmt);
77    bytes = i2c_slave_write(kvs->slave, d, abytes, true, NULL, NULL);
78    if (bytes != abytes) {
79        ZF_LOGE("Bus error on reg address select write.");
80        return -1;
81    }
82    /* Receive the reply */
83    ZF_LOGD("Read register %d", dbytes * count);
84    bytes = i2c_slave_read(kvs->slave, d, dbytes * count, false, NULL, NULL);
85    if (bytes < 0) {
86        ZF_LOGE("Failed to read I2C register.");
87        return bytes;
88    }
89    if (bytes != dbytes * count) {
90        ZF_LOGW("short read %d/%d", bytes, dbytes * count);
91    }
92    /* Fix endianess */
93    count = bytes / dbytes;
94    _fill_data(data, d, kvs->data_fmt, count);
95    return count;
96}
97
98/* Write no more than count registers from data */
99static int
100_do_kvwrite(i2c_kvslave_t* kvs, uint64_t reg, const void* data, int count)
101{
102    int abytes, dbytes, bytes;
103    char d[BUFFER_SIZE];
104    assert(kvs);
105    assert(kvs->slave);
106    abytes = ABS(kvs->address_fmt);
107    dbytes = ABS(kvs->data_fmt);
108    assert(abytes < BUFFER_SIZE && dbytes < BUFFER_SIZE);
109    /* Limit the amount of data to fit our buffer */
110    if (count * dbytes + abytes > BUFFER_SIZE) {
111        count = (BUFFER_SIZE - abytes) / dbytes;
112    }
113    /* Set up the register address */
114    ZF_LOGD("Seek register 0x%02llx", reg);
115    _fill_reg(d, reg, kvs->address_fmt);
116    /* Load up the data */
117    _fill_data(d + abytes, data, kvs->data_fmt, count);
118    /* Send the request */
119    bytes = i2c_slave_write(kvs->slave, d, abytes + count * dbytes, false, NULL, NULL);
120    if (bytes <= 0) {
121        ZF_LOGE("Bus error (%d)", bytes);
122        return bytes;
123    }
124    count = (bytes - abytes) / dbytes;
125    return count;
126}
127
128int
129i2c_slave_init(i2c_bus_t* i2c_bus, int address,
130               enum i2c_slave_address_size address_size,
131               enum i2c_slave_speed max_speed,
132               uint32_t i2c_opts,
133               i2c_slave_t* i2c_slave)
134{
135    ZF_LOGF_IF((!i2c_bus), "Handle to I2C controller not supplied!");
136    ZF_LOGF_IF((!i2c_bus->slave_init), "Unimplemented!");
137
138    switch (max_speed) {
139    case I2C_SLAVE_SPEED_STANDARD:
140    case I2C_SLAVE_SPEED_FAST:
141    case I2C_SLAVE_SPEED_FASTPLUS:
142    case I2C_SLAVE_SPEED_HIGHSPEED:
143        break;
144    default:
145        return -EINVAL;
146    }
147
148    if (address_size != I2C_SLAVE_ADDR_7BIT
149        && address_size != I2C_SLAVE_ADDR_10BIT) {
150        return -EINVAL;
151    }
152
153    if (!i2c_is_valid_address(i2c_extract_address(address))) {
154        return -ENODEV;
155    }
156
157    return i2c_bus->slave_init(i2c_bus, address,
158                               address_size, max_speed, i2c_opts, i2c_slave);
159}
160
161int
162i2c_kvslave_init(i2c_slave_t* is,
163                 enum kvfmt afmt, enum kvfmt dfmt,
164                 i2c_kvslave_t* kvs)
165{
166    ZF_LOGF_IF(!kvs, "Slave output handle not supplied!");
167    ZF_LOGF_IF(!is, "Controller handle not supplied!");
168
169    /* Validate address and data format arguments. */
170    switch (afmt) {
171    case BIG64:
172    case BIG32:
173    case BIG16:
174    case BIG8:
175    case STREAM:
176    case LITTLE8:
177    case LITTLE16:
178    case LITTLE32:
179    case LITTLE64:
180        break;
181    default:
182        ZF_LOGE("Invalid address format %d.", afmt);
183        return -EINVAL;
184    }
185
186    switch (dfmt) {
187    case BIG64:
188    case BIG32:
189    case BIG16:
190    case BIG8:
191    case STREAM:
192    case LITTLE8:
193    case LITTLE16:
194    case LITTLE32:
195    case LITTLE64:
196        break;
197    default:
198        ZF_LOGE("Invalid data format %d.", dfmt);
199        return -EINVAL;
200    }
201
202    kvs->slave = is;
203    kvs->data_fmt = dfmt;
204    kvs->address_fmt = afmt;
205    return 0;
206}
207
208
209/* Loop until count registers have been read or an error occurs */
210int
211i2c_kvslave_read(i2c_kvslave_t* kvs, uint64_t reg, void* vdata, int count)
212{
213    assert(kvs != NULL);
214
215    int dbytes = ABS(kvs->data_fmt);
216    char* data = (char*)vdata;
217    int this = -1;
218    int remain = count;
219
220    if (kvs->slave == NULL) {
221        ZF_LOGE("KV Slave lib doesn't have underlying slave instance.");
222        return -ENODEV;
223    }
224
225    /* For large reads, copyin/out requires that they be split reads */
226    while (remain > 0) {
227        this = _do_kvread(kvs, reg, data, remain);
228        if (this <= 0) {
229            break;
230        }
231        data += dbytes * this;
232        reg += dbytes * this;
233        remain -= this;
234    }
235    return count - remain;
236}
237
238
239/* Loop until count registers have been written or an error occurs */
240int
241i2c_kvslave_write(i2c_kvslave_t* kvs, uint64_t reg, const void* vdata, int count)
242{
243    assert(kvs != NULL);
244
245    int dbytes = ABS(kvs->data_fmt);
246    char* data = (char*)vdata;
247    int this = 0;
248    int remain = count;
249
250    if (kvs->slave == NULL) {
251        ZF_LOGE("KV Slave lib doesn't have underlying slave instance.");
252        return -ENODEV;
253    }
254
255    /* For large reads, copyin/out requires that they be split reads */
256    while (remain > 0) {
257        this = _do_kvwrite(kvs, reg, data, remain);
258        if (this <= 0) {
259            break;
260        }
261        data += dbytes * this;
262        remain -= this;
263        reg += this;
264    }
265    return count - remain;
266}
267
268int
269i2c_scan(i2c_bus_t* i2c_bus, int start, int* addr, int naddr)
270{
271    i2c_slave_t sl;
272
273    /* TODO:
274     * This should use the I2C Device-ID command. Currently it just attempts to
275     * read from each possible addressable ID on the bus.
276     *
277     * Ideally, it should still try each addressable ID in sequence, but it
278     * should first send out the Device-ID command, then follow it up with the
279     * current addressable ID, and repeat this in a loop.
280     *
281     * The Device-ID command was introduced in 2007, and is supported by devices
282     * that support the I2C protocol from version 3 upwards.
283     */
284    int ret;
285    int i;
286    int count;
287    char dummy[10];
288    for (count = 0, i = start & ~0x1; i < 0x100 && count < naddr; i += 2) {
289        /* Assume standard speed since we're just communicating with all the
290         * devices in sequence.
291         */
292        memset(&sl, 0, sizeof(sl));
293        ret = i2c_slave_init(i2c_bus, i,
294                             I2C_SLAVE_ADDR_7BIT, I2C_SLAVE_SPEED_STANDARD,
295                             0, &sl);
296        if (ret != 0) {
297            ZF_LOGW("Breaking out of scan early: failed to init slave "
298                    "structure for slave %d.", i);
299            break;
300        }
301
302        ret = i2c_slave_read(&sl, &dummy, 10, false, NULL, NULL);
303        if (ret == 10) {
304            *addr++ = i;
305            count++;
306        } else if (ret < 0) {
307        } else {
308            ZF_LOGE("Invalid response");
309        }
310    }
311    return count;
312}
313