summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/i2c-x1000.c
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-02-27 22:08:58 +0000
committerAidan MacDonald <amachronic@protonmail.com>2021-03-28 00:01:37 +0000
commit3ec66893e377b088c1284d2d23adb2aeea6d7965 (patch)
treeb647717f83ad56b15dc42cfdef5d04d68cd9bd6b /firmware/target/mips/ingenic_x1000/i2c-x1000.c
parent83fcbedc65f4b9ae7e491ecf6f07c0af4b245f74 (diff)
downloadrockbox-3ec66893e377b088c1284d2d23adb2aeea6d7965.tar.gz
rockbox-3ec66893e377b088c1284d2d23adb2aeea6d7965.zip
New port: FiiO M3K on bare metal
Change-Id: I7517e7d5459e129dcfc9465c6fbd708619888fbe
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/i2c-x1000.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/i2c-x1000.c478
1 files changed, 478 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/i2c-x1000.c b/firmware/target/mips/ingenic_x1000/i2c-x1000.c
new file mode 100644
index 0000000000..8bf606227b
--- /dev/null
+++ b/firmware/target/mips/ingenic_x1000/i2c-x1000.c
@@ -0,0 +1,478 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* #define LOGF_ENABLE */
23#include "i2c-x1000.h"
24#include "system.h"
25#include "kernel.h"
26#include "panic.h"
27#include "logf.h"
28#include "gpio-x1000.h"
29#include "clk-x1000.h"
30#include "irq-x1000.h"
31#include "x1000/i2c.h"
32#include "x1000/cpm.h"
33
34#if I2C_ASYNC_BUS_COUNT != 3
35# error "Wrong I2C_ASYNC_BUS_COUNT (should be 3)"
36#endif
37
38#define FIFO_SIZE 64 /* Size of data FIFOs */
39#define FIFO_TX_THRESH 16 /* Wake up when TX FIFO gets to this level */
40#define FIFO_RX_SLACK 2 /* Slack space to leave, avoids RX FIFO overflow */
41
42typedef struct i2c_x1000_bus {
43 /* Hardware channel, this is just equal to i2c-async bus number. */
44 int chn;
45
46 /* Buffer/count usage depends on what phase the bus is processing:
47 *
48 * - Phase1: writing out descriptor's buffer[0] for both READs and WRITEs.
49 * - Phase2: writing out descriptor's buffer[1] for WRITEs, or issuing a
50 * series of read requests for READs.
51 *
52 * In phase1, buffer[1] and count[1] are equal to the descriptor's copy.
53 * buffer[0] and count[0] get incremented/decremented as we send bytes.
54 * Phase1 is only visited if we actually need to send bytes; if there
55 * would be no data in this phase then __i2c_async_submit() sets up the
56 * driver to go directly to phase2.
57 *
58 * Phase2 begins after phase1 writes out its last byte, or if phase1 was
59 * skipped at submit time. For WRITEs phase2 is identical to phase1 so we
60 * copy over buffer[1] and count[1] to buffer[0] and count[0], and zero
61 * out buffer[1] and count[1].
62 *
63 * For READs phase2 sets buffer[0] to NULL and count[0] equal to count[1].
64 * Now count[0] counts the number of bytes left to request, and count[1]
65 * counts the number of bytes left to receive. i2c_x1000_fifo_write() sees
66 * that buffer[0] is NULL and sends read requests instead of data bytes.
67 * buffer[1] is advanced by i2c_x1000_fifo_read() we receive bytes.
68 */
69 unsigned char* buffer[2];
70 int count[2];
71 bool phase1;
72
73 /* Copied fields from descriptor */
74 uint8_t bus_cond;
75 uint8_t tran_mode;
76
77 /* Counter to keep track of when to send end conditions */
78 int byte_cnt;
79 int byte_cnt_end;
80
81 /* Current bus frequency, used to calculate timeout durations */
82 long freq;
83
84 /* Timeout to reset the bus in case of buggy devices */
85 struct timeout tmo;
86
87 /* Flag used to indicate a reset is processing */
88 int resetting;
89} i2c_x1000_bus;
90
91static i2c_x1000_bus i2c_x1000_busses[3];
92
93static void i2c_x1000_fifo_write(i2c_x1000_bus* bus)
94{
95 int tx_free, tx_n;
96
97 /* Get free space in FIFO */
98 tx_free = FIFO_SIZE - REG_I2C_TXFLR(bus->chn);
99
100 _again:
101 /* Leave some slack space when reading. If we submit a full FIFO's worth
102 * of read requests, there's a small chance that a byte "on the wire" is
103 * unaccounted for and causes an RX FIFO overrun. Slack space is meant to
104 * avoid this situation.
105 */
106 if(bus->tran_mode == I2C_READ) {
107 tx_free -= FIFO_RX_SLACK;
108 if(tx_free <= 0)
109 goto _end;
110 }
111
112 /* Calculate number of bytes needed to send/request */
113 tx_n = MIN(tx_free, bus->count[0]);
114
115 /* Account for bytes we're about to send/request */
116 bus->count[0] -= tx_n;
117 tx_free -= tx_n;
118
119 for(; tx_n > 0; --tx_n) {
120 bus->byte_cnt += 1;
121
122 /* Read data byte or set read request bit */
123 uint32_t dc = bus->buffer[0] ? *bus->buffer[0]++ : jz_orm(I2C_DC, CMD);
124
125 /* Check for first byte & apply RESTART.
126 * Note the HW handles RESTART automatically when changing the
127 * direction of the transfer, so we don't need to check for that.
128 */
129 if(bus->byte_cnt == 1 && (bus->bus_cond & I2C_RESTART))
130 dc |= jz_orm(I2C_DC, RESTART);
131
132 /* Check for last byte & apply STOP */
133 if(bus->byte_cnt == bus->byte_cnt_end && (bus->bus_cond & I2C_STOP))
134 dc |= jz_orm(I2C_DC, STOP);
135
136 /* Add entry to FIFO */
137 REG_I2C_DC(bus->chn) = dc;
138 }
139
140 /* FIFO full and current phase still has data to send.
141 * Configure interrupt to fire when there's a good amount of free space.
142 */
143 if(bus->count[0] > 0) {
144 _end:
145 REG_I2C_TXTL(bus->chn) = FIFO_TX_THRESH;
146 jz_writef(I2C_INTMSK(bus->chn), TXEMP(1), RXFL(0));
147 return;
148 }
149
150 /* Advance to second phase if needed */
151 if(bus->phase1 && bus->count[1] > 0) {
152 bus->buffer[0] = bus->tran_mode == I2C_WRITE ? bus->buffer[1] : NULL;
153 bus->count[0] = bus->count[1];
154 bus->phase1 = false;
155
156 /* Submit further data if possible; else wait for TX space */
157 if(tx_free > 0)
158 goto _again;
159 else
160 goto _end;
161 }
162
163 /* All phases are done. Now we just need to wake up when the whole
164 * operation is complete, either by waiting for TX to drain or RX to
165 * fill to the appropriate level. */
166 if(bus->tran_mode == I2C_WRITE) {
167 REG_I2C_TXTL(bus->chn) = 0;
168 jz_writef(I2C_INTMSK(bus->chn), TXEMP(1), RXFL(0));
169 } else {
170 REG_I2C_RXTL(bus->chn) = bus->count[1] - 1;
171 jz_writef(I2C_INTMSK(bus->chn), TXEMP(0), RXFL(1));
172 }
173}
174
175static void i2c_x1000_fifo_read(i2c_x1000_bus* bus)
176{
177 /* Get number of bytes in the RX FIFO */
178 int rx_n = REG_I2C_RXFLR(bus->chn);
179
180 /* Shouldn't happen, but check just in case */
181 if(rx_n > bus->count[1]) {
182 panicf("i2c_x1000(%d): expected %d bytes in RX fifo, got %d",
183 bus->chn, bus->count[1], rx_n);
184 }
185
186 /* Fill buffer with data from FIFO */
187 bus->count[1] -= rx_n;
188 for(; rx_n != 0; --rx_n) {
189 *bus->buffer[1]++ = jz_readf(I2C_DC(bus->chn), DAT);
190 }
191}
192
193static void i2c_x1000_interrupt(i2c_x1000_bus* bus)
194{
195 int intr = REG_I2C_INTST(bus->chn);
196 int status = I2C_STATUS_OK;
197
198 /* Bus error; we can't prevent this from happening. As I understand
199 * it, we cannot get a TXABT when the bus is idle, so it should be
200 * safe to leave this interrupt unmasked all the time.
201 */
202 if(intr & jz_orm(I2C_INTST, TXABT)) {
203 logf("i2c_x1000(%d): got TXABT (%08lx)",
204 bus->chn, REG_I2C_ABTSRC(bus->chn));
205
206 REG_I2C_CTXABT(bus->chn);
207 status = I2C_STATUS_ERROR;
208 goto _done;
209 }
210
211 /* FIFO errors shouldn't occur unless driver did something dumb */
212 if(intr & jz_orm(I2C_INTST, RXUF, TXOF, RXOF)) {
213#if 1
214 panicf("i2c_x1000(%d): fifo error (%08x)", bus->chn, intr);
215#else
216 /* This is how the error condition would be cleared */
217 REG_I2C_CTXOF(bus->chn);
218 REG_I2C_CRXOF(bus->chn);
219 REG_I2C_CRXUF(bus->chn);
220 status = I2C_STATUS_ERROR;
221 goto _done;
222#endif
223 }
224
225 /* Read from FIFO on reads, and check if we have sent/received
226 * the expected amount of data. If so, complete the descriptor. */
227 if(bus->tran_mode == I2C_READ) {
228 i2c_x1000_fifo_read(bus);
229 if(bus->count[1] == 0)
230 goto _done;
231 } else if(bus->count[0] == 0) {
232 goto _done;
233 }
234
235 /* Still need to send or request data -- issue commands to FIFO */
236 i2c_x1000_fifo_write(bus);
237 return;
238
239 _done:
240 jz_writef(I2C_INTMSK(bus->chn), TXEMP(0), RXFL(0));
241 timeout_cancel(&bus->tmo);
242 __i2c_async_complete_callback(bus->chn, status);
243}
244
245void I2C0(void)
246{
247 i2c_x1000_interrupt(&i2c_x1000_busses[0]);
248}
249
250void I2C1(void)
251{
252 i2c_x1000_interrupt(&i2c_x1000_busses[1]);
253}
254
255void I2C2(void)
256{
257 i2c_x1000_interrupt(&i2c_x1000_busses[2]);
258}
259
260static int i2c_x1000_bus_timeout(struct timeout* tmo)
261{
262 /* Buggy device is preventing the operation from completing, so we
263 * can't do much except reset the bus and hope for the best. Device
264 * drivers can aid us by detecting the TIMEOUT status we return and
265 * resetting the device to get it out of a bugged state. */
266
267 i2c_x1000_bus* bus = (i2c_x1000_bus*)tmo->data;
268 switch(bus->resetting) {
269 default:
270 /* Start of reset. Disable the controller */
271 REG_I2C_INTMSK(bus->chn) = 0;
272 bus->resetting = 1;
273 jz_writef(I2C_ENABLE(bus->chn), ACTIVE(0));
274 return 1;
275 case 1:
276 /* Check if controller is disabled yet */
277 if(jz_readf(I2C_ENBST(bus->chn), ACTIVE))
278 return 1;
279
280 /* Wait 10 ms after disabling to give time for bus to clear */
281 bus->resetting = 2;
282 return HZ/100;
283 case 2:
284 /* Re-enable the controller */
285 bus->resetting = 3;
286 jz_writef(I2C_ENABLE(bus->chn), ACTIVE(1));
287 return 1;
288 case 3:
289 /* Check that controller is enabled */
290 if(jz_readf(I2C_ENBST(bus->chn), ACTIVE) == 0)
291 return 1;
292
293 /* Reset complete */
294 bus->resetting = 0;
295 jz_overwritef(I2C_INTMSK(bus->chn), RXFL(0), TXEMP(0),
296 TXABT(1), TXOF(1), RXOF(1), RXUF(1));
297 __i2c_async_complete_callback(bus->chn, I2C_STATUS_TIMEOUT);
298 return 0;
299 }
300}
301
302void __i2c_async_submit(int busnr, i2c_descriptor* desc)
303{
304 i2c_x1000_bus* bus = &i2c_x1000_busses[busnr];
305
306 if(desc->tran_mode == I2C_READ) {
307 if(desc->count[0] > 0) {
308 /* Handle initial write as phase1 */
309 bus->buffer[0] = desc->buffer[0];
310 bus->count[0] = desc->count[0];
311 bus->phase1 = true;
312 } else {
313 /* No initial write, skip directly to phase2 */
314 bus->buffer[0] = NULL;
315 bus->count[0] = desc->count[1];
316 bus->phase1 = false;
317 }
318
319 /* Set buffer/count for phase2 read */
320 bus->buffer[1] = desc->buffer[1];
321 bus->count[1] = desc->count[1];
322 } else {
323 /* Writes always have to have buffer[0] populated; buffer[1] is
324 * allowed to be NULL (and thus count[1] = 0). This matches our
325 * phase logic so no need for anything special
326 */
327 bus->buffer[0] = desc->buffer[0];
328 bus->count[0] = desc->count[0];
329 bus->buffer[1] = desc->buffer[1];
330 bus->count[1] = desc->count[1];
331 bus->phase1 = true;
332 }
333
334 /* Save bus condition and transfer mode */
335 bus->bus_cond = desc->bus_cond;
336 bus->tran_mode = desc->tran_mode;
337
338 /* Byte counter is used to check for first and last byte and apply
339 * the requested end mode */
340 bus->byte_cnt = 0;
341 bus->byte_cnt_end = desc->count[0] + desc->count[1];
342
343 /* Ensure interrupts are cleared */
344 REG_I2C_CINT(busnr);
345
346 /* Program target address */
347 jz_overwritef(I2C_TAR(busnr), ADDR(desc->slave_addr & ~I2C_10BIT_ADDR),
348 10BITS(desc->slave_addr & I2C_10BIT_ADDR ? 1 : 0));
349
350 /* Do the initial FIFO fill; this sets up the needed interrupts. */
351 i2c_x1000_fifo_write(bus);
352
353 /* Software timeout to deal with buggy slave devices that pull the bus
354 * high forever and leave us hanging. Use 100ms + whatever time should
355 * be needed to handle data transmission. Account for 9 bits per byte
356 * because of the ACKs necessary after each byte.
357 */
358 long ticks = (HZ/10) + (HZ * 9 * bus->byte_cnt_end / bus->freq);
359 timeout_register(&bus->tmo, i2c_x1000_bus_timeout, ticks, (intptr_t)bus);
360}
361
362void i2c_init(void)
363{
364 /* Initialize core */
365 __i2c_async_init();
366
367 /* Initialize our bus data structures */
368 for(int i = 0; i < 3; ++i) {
369 i2c_x1000_busses[i].chn = i;
370 i2c_x1000_busses[i].freq = 0;
371 i2c_x1000_busses[i].resetting = 0;
372 }
373}
374
375/* Stuff only required during initialization is below, basically the same as
376 * the old driver except for how the IRQs are initially set up. */
377
378static const struct {
379 int port;
380 unsigned pins;
381 int func;
382} i2c_x1000_gpio_data[] = {
383 {GPIO_B, 3 << 23, GPIO_DEVICE(0)},
384 {GPIO_C, 3 << 26, GPIO_DEVICE(0)},
385 /* Note: I2C1 is also on the following pins (normally used by LCD) */
386 /* {GPIO_A, 3 << 0, GPIO_DEVICE(2)}, */
387 {GPIO_D, 3 << 0, GPIO_DEVICE(1)},
388};
389
390static void i2c_x1000_gate(int chn, int gate)
391{
392 switch(chn) {
393 case 0: jz_writef(CPM_CLKGR, I2C0(gate)); break;
394 case 1: jz_writef(CPM_CLKGR, I2C1(gate)); break;
395 case 2: jz_writef(CPM_CLKGR, I2C2(gate)); break;
396 default: break;
397 }
398}
399
400static void i2c_x1000_enable(int chn)
401{
402 /* Enable controller */
403 jz_writef(I2C_ENABLE(chn), ACTIVE(1));
404 while(jz_readf(I2C_ENBST(chn), ACTIVE) == 0);
405
406 /* Set up interrutpts */
407 jz_overwritef(I2C_INTMSK(chn), RXFL(0), TXEMP(0),
408 TXABT(1), TXOF(1), RXOF(1), RXUF(1));
409 system_enable_irq(IRQ_I2C(chn));
410}
411
412static void i2c_x1000_disable(int chn)
413{
414 /* Disable interrupts */
415 system_disable_irq(IRQ_I2C(chn));
416 REG_I2C_INTMSK(chn) = 0;
417
418 /* Disable controller */
419 jz_writef(I2C_ENABLE(chn), ACTIVE(0));
420 while(jz_readf(I2C_ENBST(chn), ACTIVE));
421}
422
423void i2c_x1000_set_freq(int chn, int freq)
424{
425 /* Store frequency */
426 i2c_x1000_busses[chn].freq = freq;
427
428 /* Disable the channel if previously active */
429 i2c_x1000_gate(chn, 0);
430 if(jz_readf(I2C_ENBST(chn), ACTIVE) == 1)
431 i2c_x1000_disable(chn);
432
433 /* Request to shut down the channel */
434 if(freq == 0) {
435 i2c_x1000_gate(chn, 1);
436 return;
437 }
438
439 /* Calculate timing parameters */
440 unsigned pclk = clk_get(X1000_CLK_PCLK);
441 unsigned t_SU_DAT = pclk / (freq * 8);
442 unsigned t_HD_DAT = pclk / (freq * 12);
443 unsigned t_LOW = pclk / (freq * 2);
444 unsigned t_HIGH = pclk / (freq * 2);
445 if(t_SU_DAT > 1) t_SU_DAT -= 1;
446 if(t_SU_DAT > 255) t_SU_DAT = 255;
447 if(t_SU_DAT == 0) t_SU_DAT = 0;
448 if(t_HD_DAT > 0xffff) t_HD_DAT = 0xfff;
449 if(t_LOW < 8) t_LOW = 8;
450 if(t_HIGH < 6) t_HIGH = 6;
451
452 /* Control register setting */
453 unsigned reg = jz_orf(I2C_CON, SLVDIS(1), RESTART(1), MD(1));
454 if(freq <= I2C_FREQ_100K)
455 reg |= jz_orf(I2C_CON, SPEED_V(100K));
456 else
457 reg |= jz_orf(I2C_CON, SPEED_V(400K));
458
459 /* Write the new controller settings */
460 jz_write(I2C_CON(chn), reg);
461 jz_write(I2C_SDASU(chn), t_SU_DAT);
462 jz_write(I2C_SDAHD(chn), t_HD_DAT);
463 if(freq <= I2C_FREQ_100K) {
464 jz_write(I2C_SLCNT(chn), t_LOW);
465 jz_write(I2C_SHCNT(chn), t_HIGH);
466 } else {
467 jz_write(I2C_FLCNT(chn), t_LOW);
468 jz_write(I2C_FHCNT(chn), t_HIGH);
469 }
470
471 /* Claim pins */
472 gpio_config(i2c_x1000_gpio_data[chn].port,
473 i2c_x1000_gpio_data[chn].pins,
474 i2c_x1000_gpio_data[chn].func);
475
476 /* Enable the controller */
477 i2c_x1000_enable(chn);
478}