1/* $OpenBSD: dwiic.c,v 1.15 2023/08/29 12:09:40 kettenis Exp $ */
2/*
3 * Synopsys DesignWare I2C controller
4 *
5 * Copyright (c) 2015-2017 joshua stein <jcs@openbsd.org>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/param.h>
21#include <sys/systm.h>
22#include <sys/kernel.h>
23
24#ifdef __HAVE_ACPI
25#include <dev/acpi/acpireg.h>
26#include <dev/acpi/acpivar.h>
27#include <dev/acpi/acpidev.h>
28#include <dev/acpi/amltypes.h>
29#include <dev/acpi/dsdt.h>
30#endif
31
32#include <dev/i2c/i2cvar.h>
33
34#include <dev/ic/dwiicvar.h>
35
36struct cfdriver dwiic_cd = {
37	NULL, "dwiic", DV_DULL
38};
39
40int
41dwiic_activate(struct device *self, int act)
42{
43	struct dwiic_softc *sc = (struct dwiic_softc *)self;
44
45	switch (act) {
46	case DVACT_SUSPEND:
47		/* disable controller */
48		dwiic_enable(sc, 0);
49
50		/* disable interrupts */
51		dwiic_write(sc, DW_IC_INTR_MASK, 0);
52		dwiic_read(sc, DW_IC_CLR_INTR);
53
54#if notyet
55		/* power down the controller */
56		dwiic_acpi_power(sc, 0);
57#endif
58		break;
59	case DVACT_WAKEUP:
60#if notyet
61		/* power up the controller */
62		dwiic_acpi_power(sc, 1);
63#endif
64		dwiic_init(sc);
65
66		break;
67	}
68
69	config_activate_children(self, act);
70
71	return 0;
72}
73
74int
75dwiic_i2c_print(void *aux, const char *pnp)
76{
77	struct i2c_attach_args *ia = aux;
78
79	if (pnp != NULL)
80		printf("\"%s\" at %s", ia->ia_name, pnp);
81
82	printf(" addr 0x%x", ia->ia_addr);
83
84	return UNCONF;
85}
86
87uint32_t
88dwiic_read(struct dwiic_softc *sc, int offset)
89{
90	u_int32_t b = bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset);
91
92	DPRINTF(("%s: read at 0x%x = 0x%x\n", sc->sc_dev.dv_xname, offset, b));
93
94	return b;
95}
96
97void
98dwiic_write(struct dwiic_softc *sc, int offset, uint32_t val)
99{
100	DPRINTF(("%s: write at 0x%x: 0x%x\n", sc->sc_dev.dv_xname, offset,
101	    val));
102
103	bus_space_write_4(sc->sc_iot, sc->sc_ioh, offset, val);
104}
105
106int
107dwiic_i2c_acquire_bus(void *cookie, int flags)
108{
109	struct dwiic_softc *sc = cookie;
110
111	if (cold || sc->sc_poll || (flags & I2C_F_POLL))
112		return (0);
113
114	return rw_enter(&sc->sc_i2c_lock, RW_WRITE | RW_INTR);
115}
116
117void
118dwiic_i2c_release_bus(void *cookie, int flags)
119{
120	struct dwiic_softc *sc = cookie;
121
122	if (cold || sc->sc_poll || (flags & I2C_F_POLL))
123		return;
124
125	rw_exit(&sc->sc_i2c_lock);
126}
127
128int
129dwiic_init(struct dwiic_softc *sc)
130{
131	uint32_t reg;
132	uint8_t tx_fifo_depth;
133	uint8_t rx_fifo_depth;
134
135	/* make sure we're talking to a device we know */
136	reg = dwiic_read(sc, DW_IC_COMP_TYPE);
137	if (reg != DW_IC_COMP_TYPE_VALUE) {
138		DPRINTF(("%s: invalid component type 0x%x\n",
139		    sc->sc_dev.dv_xname, reg));
140		return 1;
141	}
142
143	/* fetch default timing parameters if not already specified */
144	if (!sc->ss_hcnt)
145		sc->ss_hcnt = dwiic_read(sc, DW_IC_SS_SCL_HCNT);
146	if (!sc->ss_lcnt)
147		sc->ss_lcnt = dwiic_read(sc, DW_IC_SS_SCL_LCNT);
148	if (!sc->fs_hcnt)
149		sc->fs_hcnt = dwiic_read(sc, DW_IC_FS_SCL_HCNT);
150	if (!sc->fs_lcnt)
151		sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT);
152	if (!sc->sda_hold_time)
153		sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD);
154
155	/* disable the adapter */
156	dwiic_enable(sc, 0);
157
158	/* write standard-mode SCL timing parameters */
159	dwiic_write(sc, DW_IC_SS_SCL_HCNT, sc->ss_hcnt);
160	dwiic_write(sc, DW_IC_SS_SCL_LCNT, sc->ss_lcnt);
161
162	/* and fast-mode SCL timing parameters */
163	dwiic_write(sc, DW_IC_FS_SCL_HCNT, sc->fs_hcnt);
164	dwiic_write(sc, DW_IC_FS_SCL_LCNT, sc->fs_lcnt);
165
166	/* SDA hold time */
167	reg = dwiic_read(sc, DW_IC_COMP_VERSION);
168	if (reg >= DW_IC_SDA_HOLD_MIN_VERS)
169		dwiic_write(sc, DW_IC_SDA_HOLD, sc->sda_hold_time);
170
171	/* FIFO threshold levels */
172	sc->tx_fifo_depth = 32;
173	sc->rx_fifo_depth = 32;
174	reg = dwiic_read(sc, DW_IC_COMP_PARAM_1);
175	tx_fifo_depth = DW_IC_TX_FIFO_DEPTH(reg);
176	rx_fifo_depth = DW_IC_RX_FIFO_DEPTH(reg);
177	if (tx_fifo_depth > 1 && tx_fifo_depth < sc->tx_fifo_depth)
178		sc->tx_fifo_depth = tx_fifo_depth;
179	if (rx_fifo_depth > 1 && rx_fifo_depth < sc->rx_fifo_depth)
180		sc->rx_fifo_depth = rx_fifo_depth;
181
182	dwiic_write(sc, DW_IC_TX_TL, sc->tx_fifo_depth / 2);
183	dwiic_write(sc, DW_IC_RX_TL, 0);
184
185	/* configure as i2c master with fast speed */
186	sc->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
187	    DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
188	dwiic_write(sc, DW_IC_CON, sc->master_cfg);
189
190	return 0;
191}
192
193void
194dwiic_enable(struct dwiic_softc *sc, int enable)
195{
196	int retries;
197
198	for (retries = 100; retries > 0; retries--) {
199		dwiic_write(sc, DW_IC_ENABLE, enable);
200		if ((dwiic_read(sc, DW_IC_ENABLE_STATUS) & 1) == enable)
201			return;
202
203		DELAY(25);
204	}
205
206	printf("%s: failed to %sable\n", sc->sc_dev.dv_xname,
207	    (enable ? "en" : "dis"));
208}
209
210int
211dwiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
212    size_t cmdlen, void *buf, size_t len, int flags)
213{
214	struct dwiic_softc *sc = cookie;
215	u_int32_t ic_con, st, cmd, resp;
216	int retries, tx_limit, rx_avail, x, readpos;
217	uint8_t *b;
218	int s;
219
220	if (sc->sc_busy)
221		return 1;
222
223	sc->sc_busy++;
224
225	DPRINTF(("%s: %s: op %d, addr 0x%02x, cmdlen %zu, len %zu, "
226	    "flags 0x%02x\n", sc->sc_dev.dv_xname, __func__, op, addr, cmdlen,
227	    len, flags));
228
229	/* setup transfer */
230	sc->sc_i2c_xfer.op = op;
231	sc->sc_i2c_xfer.buf = buf;
232	sc->sc_i2c_xfer.len = len;
233	sc->sc_i2c_xfer.flags = flags;
234	sc->sc_i2c_xfer.error = 0;
235
236	/* wait for bus to be idle */
237	for (retries = 100; retries > 0; retries--) {
238		st = dwiic_read(sc, DW_IC_STATUS);
239		if (!(st & DW_IC_STATUS_ACTIVITY))
240			break;
241		DELAY(1000);
242	}
243	DPRINTF(("%s: %s: status 0x%x\n", sc->sc_dev.dv_xname, __func__, st));
244	if (st & DW_IC_STATUS_ACTIVITY) {
245		sc->sc_busy = 0;
246		return (1);
247	}
248
249	if (cold || sc->sc_poll)
250		flags |= I2C_F_POLL;
251
252	/* disable controller */
253	dwiic_enable(sc, 0);
254
255	/* set slave address */
256	ic_con = dwiic_read(sc, DW_IC_CON);
257	ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
258	dwiic_write(sc, DW_IC_CON, ic_con);
259	dwiic_write(sc, DW_IC_TAR, addr);
260
261	/* disable interrupts */
262	dwiic_write(sc, DW_IC_INTR_MASK, 0);
263	dwiic_read(sc, DW_IC_CLR_INTR);
264
265	/* enable controller */
266	dwiic_enable(sc, 1);
267
268	/* wait until the controller is ready for commands */
269	if (flags & I2C_F_POLL)
270		DELAY(200);
271	else {
272		s = splbio();
273		dwiic_read(sc, DW_IC_CLR_INTR);
274		dwiic_write(sc, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY);
275
276		if (tsleep_nsec(&sc->sc_writewait, PRIBIO, "dwiic",
277		    MSEC_TO_NSEC(500)) != 0)
278			printf("%s: timed out waiting for tx_empty intr\n",
279			    sc->sc_dev.dv_xname);
280		splx(s);
281	}
282
283	/* send our command, one byte at a time */
284	if (cmdlen > 0) {
285		b = (void *)cmdbuf;
286
287		DPRINTF(("%s: %s: sending cmd (len %zu):", sc->sc_dev.dv_xname,
288		    __func__, cmdlen));
289		for (x = 0; x < cmdlen; x++)
290			DPRINTF((" %02x", b[x]));
291		DPRINTF(("\n"));
292
293		tx_limit = sc->tx_fifo_depth - dwiic_read(sc, DW_IC_TXFLR);
294		if (cmdlen > tx_limit) {
295			/* TODO */
296			printf("%s: can't write %zu (> %d)\n",
297			    sc->sc_dev.dv_xname, cmdlen, tx_limit);
298			sc->sc_i2c_xfer.error = 1;
299			sc->sc_busy = 0;
300			return (1);
301		}
302
303		for (x = 0; x < cmdlen; x++) {
304			cmd = b[x];
305			/*
306			 * Generate STOP condition if this is the last
307			 * byte of the transfer.
308			 */
309			if (x == (cmdlen - 1) && len == 0 && I2C_OP_STOP_P(op))
310				cmd |= DW_IC_DATA_CMD_STOP;
311			dwiic_write(sc, DW_IC_DATA_CMD, cmd);
312		}
313	}
314
315	b = (void *)buf;
316	x = readpos = 0;
317	tx_limit = sc->tx_fifo_depth - dwiic_read(sc, DW_IC_TXFLR);
318
319	DPRINTF(("%s: %s: need to read %zu bytes, can send %d read reqs\n",
320		sc->sc_dev.dv_xname, __func__, len, tx_limit));
321
322	while (x < len) {
323		if (I2C_OP_WRITE_P(op))
324			cmd = b[x];
325		else
326			cmd = DW_IC_DATA_CMD_READ;
327
328		/*
329		 * Generate RESTART condition if we're reversing
330		 * direction.
331		 */
332		if (x == 0 && cmdlen > 0 && I2C_OP_READ_P(op))
333			cmd |= DW_IC_DATA_CMD_RESTART;
334		/*
335		 * Generate STOP condition on the last byte of the
336		 * transfer.
337		 */
338		if (x == (len - 1) && I2C_OP_STOP_P(op))
339			cmd |= DW_IC_DATA_CMD_STOP;
340
341		dwiic_write(sc, DW_IC_DATA_CMD, cmd);
342
343		/*
344		 * For a block read, get the byte count before
345		 * continuing to read the data bytes.
346		 */
347		if (I2C_OP_READ_P(op) && I2C_OP_BLKMODE_P(op) && readpos == 0)
348			tx_limit = 1;
349
350		tx_limit--;
351		x++;
352
353		/*
354		 * As TXFLR fills up, we need to clear it out by reading all
355		 * available data.
356		 */
357		while (I2C_OP_READ_P(op) && (tx_limit == 0 || x == len)) {
358			DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
359			    sc->sc_dev.dv_xname, __func__, tx_limit, x));
360
361			if (flags & I2C_F_POLL) {
362				for (retries = 1000; retries > 0; retries--) {
363					rx_avail = dwiic_read(sc, DW_IC_RXFLR);
364					if (rx_avail > 0)
365						break;
366					DELAY(50);
367				}
368			} else {
369				s = splbio();
370				dwiic_read(sc, DW_IC_CLR_INTR);
371				dwiic_write(sc, DW_IC_INTR_MASK,
372				    DW_IC_INTR_RX_FULL);
373
374				if (tsleep_nsec(&sc->sc_readwait, PRIBIO,
375				    "dwiic", MSEC_TO_NSEC(500)) != 0)
376					printf("%s: timed out waiting for "
377					    "rx_full intr\n",
378					    sc->sc_dev.dv_xname);
379				splx(s);
380
381				rx_avail = dwiic_read(sc, DW_IC_RXFLR);
382			}
383
384			if (rx_avail == 0) {
385				printf("%s: timed out reading remaining %d\n",
386				    sc->sc_dev.dv_xname, (int)(len - readpos));
387				sc->sc_i2c_xfer.error = 1;
388				sc->sc_busy = 0;
389
390				return (1);
391			}
392
393			DPRINTF(("%s: %s: %d avail to read (%zu remaining)\n",
394			    sc->sc_dev.dv_xname, __func__, rx_avail,
395			    len - readpos));
396
397			while (rx_avail > 0) {
398				resp = dwiic_read(sc, DW_IC_DATA_CMD);
399				if (readpos < len) {
400					b[readpos] = resp;
401					readpos++;
402				}
403				rx_avail--;
404			}
405
406			/*
407			 * Update the transfer length when doing a
408			 * block read.
409			 */
410			if (I2C_OP_BLKMODE_P(op) && readpos > 0 && len > b[0])
411				len = b[0] + 1;
412
413			if (readpos >= len)
414				break;
415
416			DPRINTF(("%s: still need to read %d bytes\n",
417			    sc->sc_dev.dv_xname, (int)(len - readpos)));
418			tx_limit = sc->tx_fifo_depth -
419			    dwiic_read(sc, DW_IC_TXFLR);
420		}
421
422		if (I2C_OP_WRITE_P(op) && tx_limit == 0 && x < len) {
423			if (flags & I2C_F_POLL) {
424				for (retries = 1000; retries > 0; retries--) {
425					tx_limit = sc->tx_fifo_depth -
426					    dwiic_read(sc, DW_IC_TXFLR);
427					if (tx_limit > 0)
428						break;
429					DELAY(50);
430				}
431			} else {
432				s = splbio();
433				dwiic_read(sc, DW_IC_CLR_INTR);
434				dwiic_write(sc, DW_IC_INTR_MASK,
435				    DW_IC_INTR_TX_EMPTY);
436
437				if (tsleep_nsec(&sc->sc_writewait, PRIBIO,
438				    "dwiic", MSEC_TO_NSEC(500)) != 0)
439					printf("%s: timed out waiting for "
440					    "tx_empty intr\n",
441					    sc->sc_dev.dv_xname);
442				splx(s);
443
444				tx_limit = sc->tx_fifo_depth -
445				    dwiic_read(sc, DW_IC_TXFLR);
446			}
447
448			if (tx_limit == 0) {
449				printf("%s: timed out writing remaining %d\n",
450				    sc->sc_dev.dv_xname, (int)(len - x));
451				sc->sc_i2c_xfer.error = 1;
452				sc->sc_busy = 0;
453
454				return (1);
455			}
456		}
457	}
458
459	if (I2C_OP_STOP_P(op) && I2C_OP_WRITE_P(op)) {
460		if (flags & I2C_F_POLL) {
461			for (retries = 100; retries > 0; retries--) {
462				st = dwiic_read(sc, DW_IC_RAW_INTR_STAT);
463				if (st & DW_IC_INTR_STOP_DET)
464					break;
465				DELAY(1000);
466			}
467			if (!(st & DW_IC_INTR_STOP_DET))
468				printf("%s: timed out waiting for bus idle\n",
469				    sc->sc_dev.dv_xname);
470		} else {
471			s = splbio();
472			while (sc->sc_busy) {
473				dwiic_write(sc, DW_IC_INTR_MASK,
474				    DW_IC_INTR_STOP_DET);
475				if (tsleep_nsec(&sc->sc_busy, PRIBIO, "dwiic",
476				    MSEC_TO_NSEC(500)) != 0)
477					printf("%s: timed out waiting for "
478					    "stop intr\n",
479					    sc->sc_dev.dv_xname);
480			}
481			splx(s);
482		}
483	}
484	sc->sc_busy = 0;
485
486	return 0;
487}
488
489uint32_t
490dwiic_read_clear_intrbits(struct dwiic_softc *sc)
491{
492       uint32_t stat;
493
494       stat = dwiic_read(sc, DW_IC_INTR_STAT);
495
496       if (stat & DW_IC_INTR_RX_UNDER)
497	       dwiic_read(sc, DW_IC_CLR_RX_UNDER);
498       if (stat & DW_IC_INTR_RX_OVER)
499	       dwiic_read(sc, DW_IC_CLR_RX_OVER);
500       if (stat & DW_IC_INTR_TX_OVER)
501	       dwiic_read(sc, DW_IC_CLR_TX_OVER);
502       if (stat & DW_IC_INTR_RD_REQ)
503	       dwiic_read(sc, DW_IC_CLR_RD_REQ);
504       if (stat & DW_IC_INTR_TX_ABRT)
505	       dwiic_read(sc, DW_IC_CLR_TX_ABRT);
506       if (stat & DW_IC_INTR_RX_DONE)
507	       dwiic_read(sc, DW_IC_CLR_RX_DONE);
508       if (stat & DW_IC_INTR_ACTIVITY)
509	       dwiic_read(sc, DW_IC_CLR_ACTIVITY);
510       if (stat & DW_IC_INTR_STOP_DET)
511	       dwiic_read(sc, DW_IC_CLR_STOP_DET);
512       if (stat & DW_IC_INTR_START_DET)
513	       dwiic_read(sc, DW_IC_CLR_START_DET);
514       if (stat & DW_IC_INTR_GEN_CALL)
515	       dwiic_read(sc, DW_IC_CLR_GEN_CALL);
516
517       return stat;
518}
519
520int
521dwiic_intr(void *arg)
522{
523	struct dwiic_softc *sc = arg;
524	uint32_t en, stat;
525
526	en = dwiic_read(sc, DW_IC_ENABLE);
527	/* probably for the other controller */
528	if (!en)
529		return 0;
530
531	stat = dwiic_read_clear_intrbits(sc);
532	DPRINTF(("%s: %s: enabled=0x%x stat=0x%x\n", sc->sc_dev.dv_xname,
533	    __func__, en, stat));
534	if (!(stat & ~DW_IC_INTR_ACTIVITY))
535		return 0;
536
537	if (stat & DW_IC_INTR_TX_ABRT)
538		sc->sc_i2c_xfer.error = 1;
539
540	if (sc->sc_i2c_xfer.flags & I2C_F_POLL)
541		DPRINTF(("%s: %s: intr in poll mode?\n", sc->sc_dev.dv_xname,
542		    __func__));
543	else {
544		if (stat & DW_IC_INTR_RX_FULL) {
545			dwiic_write(sc, DW_IC_INTR_MASK, 0);
546			DPRINTF(("%s: %s: waking up reader\n",
547			    sc->sc_dev.dv_xname, __func__));
548			wakeup(&sc->sc_readwait);
549		}
550		if (stat & DW_IC_INTR_TX_EMPTY) {
551			dwiic_write(sc, DW_IC_INTR_MASK, 0);
552			DPRINTF(("%s: %s: waking up writer\n",
553			    sc->sc_dev.dv_xname, __func__));
554			wakeup(&sc->sc_writewait);
555		}
556		if (stat & DW_IC_INTR_STOP_DET) {
557			dwiic_write(sc, DW_IC_INTR_MASK, 0);
558			sc->sc_busy = 0;
559			wakeup(&sc->sc_busy);
560		}
561	}
562
563	return 1;
564}
565