uart_dev_sab82532.c revision 120143
1/*
2 * Copyright (c) 2003 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_sab82532.c 120143 2003-09-17 01:41:21Z marcel $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/conf.h>
34#include <machine/bus.h>
35
36#include <dev/uart/uart.h>
37#include <dev/uart/uart_cpu.h>
38#include <dev/uart/uart_bus.h>
39#include <dev/uart/uart_dev_sab82532.h>
40
41#include "uart_if.h"
42
43#define	DEFAULT_RCLK	29491200
44
45#define	IS_CHANNEL_A(bas)	((uart_cpu_busaddr(bas) & 0x40) == 0x00)
46#define	IS_CHANNEL_B(bas)	((uart_cpu_busaddr(bas) & 0x40) == 0x40)
47
48/*
49 * NOTE: To allow us to read the baudrate divisor from the chip, we
50 * copy the value written to the write-only BGR register to an unused
51 * read-write register. We use TCR for that.
52 */
53
54static int
55sab82532_delay(struct uart_bas *bas)
56{
57	int divisor, m, n;
58	uint8_t bgr, ccr2;
59
60	bgr = uart_getreg(bas, SAB_TCR);
61	ccr2 = uart_getreg(bas, SAB_CCR2);
62	n = (bgr & 0x3f) + 1;
63	m = (bgr >> 6) | ((ccr2 >> 4) & 0xC);
64	divisor = n * (1<<m);
65
66	/* 1/10th the time to transmit 1 character (estimate). */
67	return (16000000 * divisor / bas->rclk);
68}
69
70static int
71sab82532_divisor(int rclk, int baudrate)
72{
73	int act_baud, act_div, divisor;
74	int error, m, n;
75
76	if (baudrate == 0)
77		return (0);
78
79	divisor = (rclk / (baudrate << 3) + 1) >> 1;
80	if (divisor < 2 || divisor >= 1048576)
81		return (0);
82
83	/* Find the best (N+1,M) pair. */
84	for (m = 1; m < 15; m++) {
85		n = divisor / (1<<m);
86		if (n < 1 || n > 63)
87			continue;
88		act_div = n * (1<<m);
89		act_baud = rclk / (act_div << 4);
90
91		/* 10 times error in percent: */
92		error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1;
93
94		/* 3.0% maximum error tolerance: */
95		if (error < -30 || error > 30)
96			continue;
97
98		/* Got it. */
99		return ((n - 1) | (m << 6));
100	}
101
102	return (0);
103}
104
105static void
106sab82532_flush(struct uart_bas *bas, int what)
107{
108
109	if (what & UART_FLUSH_TRANSMITTER) {
110		while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
111			;
112		uart_setreg(bas, SAB_CMDR, SAB_CMDR_XRES);
113		uart_barrier(bas);
114	}
115	if (what & UART_FLUSH_RECEIVER) {
116		while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
117			;
118		uart_setreg(bas, SAB_CMDR, SAB_CMDR_RRES);
119		uart_barrier(bas);
120	}
121}
122
123static int
124sab82532_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
125    int parity)
126{
127	int divisor;
128	uint8_t ccr2, dafo;
129
130	if (databits >= 8)
131		dafo = SAB_DAFO_CHL_CS8;
132	else if (databits == 7)
133		dafo = SAB_DAFO_CHL_CS7;
134	else if (databits == 6)
135		dafo = SAB_DAFO_CHL_CS6;
136	else
137		dafo = SAB_DAFO_CHL_CS5;
138	if (stopbits > 1)
139		dafo |= SAB_DAFO_STOP;
140	switch (parity) {
141	case UART_PARITY_EVEN:	dafo |= SAB_DAFO_PAR_EVEN; break;
142	case UART_PARITY_MARK:	dafo |= SAB_DAFO_PAR_MARK; break;
143	case UART_PARITY_NONE:	dafo |= SAB_DAFO_PAR_NONE; break;
144	case UART_PARITY_ODD:	dafo |= SAB_DAFO_PAR_ODD; break;
145	case UART_PARITY_SPACE:	dafo |= SAB_DAFO_PAR_SPACE; break;
146	default:		return (EINVAL);
147	}
148
149	/* Set baudrate. */
150	if (baudrate > 0) {
151		divisor = sab82532_divisor(bas->rclk, baudrate);
152		if (divisor == 0)
153			return (EINVAL);
154		uart_setreg(bas, SAB_BGR, divisor & 0xff);
155		uart_barrier(bas);
156		/* Allow reading the (n-1,m) tuple from the chip. */
157		uart_setreg(bas, SAB_TCR, divisor & 0xff);
158		uart_barrier(bas);
159		ccr2 = uart_getreg(bas, SAB_CCR2);
160		ccr2 &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8);
161		ccr2 |= (divisor >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8);
162		uart_setreg(bas, SAB_CCR2, ccr2);
163		uart_barrier(bas);
164	}
165
166	uart_setreg(bas, SAB_DAFO, dafo);
167	uart_barrier(bas);
168	return (0);
169}
170
171/*
172 * Low-level UART interface.
173 */
174static int sab82532_probe(struct uart_bas *bas);
175static void sab82532_init(struct uart_bas *bas, int, int, int, int);
176static void sab82532_term(struct uart_bas *bas);
177static void sab82532_putc(struct uart_bas *bas, int);
178static int sab82532_poll(struct uart_bas *bas);
179static int sab82532_getc(struct uart_bas *bas);
180
181struct uart_ops uart_sab82532_ops = {
182	.probe = sab82532_probe,
183	.init = sab82532_init,
184	.term = sab82532_term,
185	.putc = sab82532_putc,
186	.poll = sab82532_poll,
187	.getc = sab82532_getc,
188};
189
190static int
191sab82532_probe(struct uart_bas *bas)
192{
193
194	return (0);
195}
196
197static void
198sab82532_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
199    int parity)
200{
201	uint8_t ccr0, pvr;
202
203	if (bas->rclk == 0)
204		bas->rclk = DEFAULT_RCLK;
205
206	/*
207	 * Set all pins, except the DTR pins (pin 1 and 2) to be inputs.
208	 * Pin 4 is magical, meaning that I don't know what it does, but
209	 * it too has to be set to output.
210	 */
211	uart_setreg(bas, SAB_PCR,
212	    ~(SAB_PVR_DTR_A|SAB_PVR_DTR_B|SAB_PVR_MAGIC));
213	uart_barrier(bas);
214	/* Disable port interrupts. */
215	uart_setreg(bas, SAB_PIM, 0xff);
216	uart_barrier(bas);
217	/* Interrupts are active low. */
218	uart_setreg(bas, SAB_IPC, SAB_IPC_ICPL);
219	uart_barrier(bas);
220	/* Set DTR. */
221	pvr = uart_getreg(bas, SAB_PVR);
222	pvr &= IS_CHANNEL_A(bas) ? ~SAB_PVR_DTR_A : ~SAB_PVR_DTR_B;
223	uart_setreg(bas, SAB_PVR, pvr | SAB_PVR_MAGIC);
224	uart_barrier(bas);
225
226	/* power down */
227	uart_setreg(bas, SAB_CCR0, 0);
228	uart_barrier(bas);
229
230	/* set basic configuration */
231	ccr0 = SAB_CCR0_MCE|SAB_CCR0_SC_NRZ|SAB_CCR0_SM_ASYNC;
232	uart_setreg(bas, SAB_CCR0, ccr0);
233	uart_barrier(bas);
234	uart_setreg(bas, SAB_CCR1, SAB_CCR1_ODS|SAB_CCR1_BCR|SAB_CCR1_CM_7);
235	uart_barrier(bas);
236	uart_setreg(bas, SAB_CCR2, SAB_CCR2_BDF|SAB_CCR2_SSEL|SAB_CCR2_TOE);
237	uart_barrier(bas);
238	uart_setreg(bas, SAB_CCR3, 0);
239	uart_barrier(bas);
240	uart_setreg(bas, SAB_CCR4, SAB_CCR4_MCK4|SAB_CCR4_EBRG|SAB_CCR4_ICD);
241	uart_barrier(bas);
242	uart_setreg(bas, SAB_MODE, SAB_MODE_FCTS|SAB_MODE_RTS|SAB_MODE_RAC);
243	uart_barrier(bas);
244	uart_setreg(bas, SAB_RFC, SAB_RFC_DPS|SAB_RFC_RFDF|
245	    SAB_RFC_RFTH_32CHAR);
246	uart_barrier(bas);
247
248	sab82532_param(bas, baudrate, databits, stopbits, parity);
249
250	/* Clear interrupts. */
251	uart_setreg(bas, SAB_IMR0, 0xff);
252	uart_setreg(bas, SAB_IMR1, 0xff);
253	uart_barrier(bas);
254	uart_getreg(bas, SAB_ISR0);
255	uart_getreg(bas, SAB_ISR1);
256	uart_barrier(bas);
257
258	sab82532_flush(bas, UART_FLUSH_TRANSMITTER|UART_FLUSH_RECEIVER);
259
260	/* Power up. */
261	uart_setreg(bas, SAB_CCR0, ccr0|SAB_CCR0_PU);
262	uart_barrier(bas);
263}
264
265static void
266sab82532_term(struct uart_bas *bas)
267{
268	uint8_t pvr;
269
270	pvr = uart_getreg(bas, SAB_PVR);
271	pvr |= IS_CHANNEL_A(bas) ? SAB_PVR_DTR_A : SAB_PVR_DTR_B;
272	uart_setreg(bas, SAB_PVR, pvr);
273	uart_barrier(bas);
274}
275
276static void
277sab82532_putc(struct uart_bas *bas, int c)
278{
279	int delay, limit;
280
281	/* 1/10th the time to transmit 1 character (estimate). */
282	delay = sab82532_delay(bas);
283
284	limit = 20;
285	while ((uart_getreg(bas, SAB_STAR) & SAB_STAR_TEC) && --limit)
286		DELAY(delay);
287	uart_setreg(bas, SAB_TIC, c);
288	limit = 20;
289	while ((uart_getreg(bas, SAB_STAR) & SAB_STAR_TEC) && --limit)
290		DELAY(delay);
291}
292
293static int
294sab82532_poll(struct uart_bas *bas)
295{
296
297	if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE)
298		return (sab82532_getc(bas));
299	return (-1);
300}
301
302static int
303sab82532_getc(struct uart_bas *bas)
304{
305	int c, delay;
306
307	/* 1/10th the time to transmit 1 character (estimate). */
308	delay = sab82532_delay(bas);
309
310	while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE))
311		DELAY(delay);
312
313	while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
314		;
315	uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD);
316	uart_barrier(bas);
317
318	while (!(uart_getreg(bas, SAB_ISR0) & SAB_ISR0_TCD))
319		DELAY(delay);
320
321	c = uart_getreg(bas, SAB_RFIFO);
322	uart_barrier(bas);
323
324	/* Blow away everything left in the FIFO... */
325	while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
326		;
327	uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC);
328	uart_barrier(bas);
329	return (c);
330}
331
332/*
333 * High-level UART interface.
334 */
335struct sab82532_softc {
336	struct uart_softc base;
337};
338
339static int sab82532_bus_attach(struct uart_softc *);
340static int sab82532_bus_detach(struct uart_softc *);
341static int sab82532_bus_flush(struct uart_softc *, int);
342static int sab82532_bus_getsig(struct uart_softc *);
343static int sab82532_bus_ioctl(struct uart_softc *, int, intptr_t);
344static int sab82532_bus_ipend(struct uart_softc *);
345static int sab82532_bus_param(struct uart_softc *, int, int, int, int);
346static int sab82532_bus_probe(struct uart_softc *);
347static int sab82532_bus_receive(struct uart_softc *);
348static int sab82532_bus_setsig(struct uart_softc *, int);
349static int sab82532_bus_transmit(struct uart_softc *);
350
351static kobj_method_t sab82532_methods[] = {
352	KOBJMETHOD(uart_attach,		sab82532_bus_attach),
353	KOBJMETHOD(uart_detach,		sab82532_bus_detach),
354	KOBJMETHOD(uart_flush,		sab82532_bus_flush),
355	KOBJMETHOD(uart_getsig,		sab82532_bus_getsig),
356	KOBJMETHOD(uart_ioctl,		sab82532_bus_ioctl),
357	KOBJMETHOD(uart_ipend,		sab82532_bus_ipend),
358	KOBJMETHOD(uart_param,		sab82532_bus_param),
359	KOBJMETHOD(uart_probe,		sab82532_bus_probe),
360	KOBJMETHOD(uart_receive,	sab82532_bus_receive),
361	KOBJMETHOD(uart_setsig,		sab82532_bus_setsig),
362	KOBJMETHOD(uart_transmit,	sab82532_bus_transmit),
363	{ 0, 0 }
364};
365
366struct uart_class uart_sab82532_class = {
367	"sab82532 class",
368	sab82532_methods,
369	sizeof(struct sab82532_softc),
370	.uc_range = 64,
371	.uc_rclk = DEFAULT_RCLK
372};
373
374#define	SIGCHG(c, i, s, d)				\
375	if (c) {					\
376		i |= (i & s) ? s : s | d;		\
377	} else {					\
378		i = (i & s) ? (i & ~s) | d : i;		\
379	}
380
381static int
382sab82532_bus_attach(struct uart_softc *sc)
383{
384	struct uart_bas *bas;
385	uint8_t imr0, imr1;
386
387	bas = &sc->sc_bas;
388	if (sc->sc_sysdev == NULL)
389		sab82532_init(bas, 9600, 8, 1, UART_PARITY_NONE);
390
391	sc->sc_rxfifosz = 32;
392	sc->sc_txfifosz = 32;
393
394	imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO|
395	    SAB_IMR0_RPF;
396	uart_setreg(bas, SAB_IMR0, 0xff & ~imr0);
397	imr1 = SAB_IMR1_BRKT|SAB_IMR1_ALLS|SAB_IMR1_CSC;
398	uart_setreg(bas, SAB_IMR1, 0xff & ~imr1);
399	uart_barrier(bas);
400
401	if (sc->sc_sysdev == NULL)
402		sab82532_bus_setsig(sc, UART_SIG_DDTR|UART_SIG_DRTS);
403	(void)sab82532_bus_getsig(sc);
404	return (0);
405}
406
407static int
408sab82532_bus_detach(struct uart_softc *sc)
409{
410	struct uart_bas *bas;
411
412	bas = &sc->sc_bas;
413	uart_setreg(bas, SAB_IMR0, 0xff);
414	uart_setreg(bas, SAB_IMR1, 0xff);
415	uart_barrier(bas);
416	uart_getreg(bas, SAB_ISR0);
417	uart_getreg(bas, SAB_ISR1);
418	uart_barrier(bas);
419	uart_setreg(bas, SAB_CCR0, 0);
420	uart_barrier(bas);
421	return (0);
422}
423
424static int
425sab82532_bus_flush(struct uart_softc *sc, int what)
426{
427
428	mtx_lock_spin(&sc->sc_hwmtx);
429	sab82532_flush(&sc->sc_bas, what);
430	mtx_unlock_spin(&sc->sc_hwmtx);
431	return (0);
432}
433
434static int
435sab82532_bus_getsig(struct uart_softc *sc)
436{
437	struct uart_bas *bas;
438	uint32_t new, old, sig;
439	uint8_t pvr, star, vstr;
440
441	bas = &sc->sc_bas;
442	do {
443		old = sc->sc_hwsig;
444		sig = old;
445		mtx_lock_spin(&sc->sc_hwmtx);
446		star = uart_getreg(bas, SAB_STAR);
447		SIGCHG(star & SAB_STAR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS);
448		vstr = uart_getreg(bas, SAB_VSTR);
449		SIGCHG(vstr & SAB_VSTR_CD, sig, UART_SIG_DCD, UART_SIG_DDCD);
450		pvr = uart_getreg(bas, SAB_PVR);
451		pvr &= (IS_CHANNEL_A(bas)) ? SAB_PVR_DSR_A : SAB_PVR_DSR_B;
452		SIGCHG(~pvr, sig, UART_SIG_DSR, UART_SIG_DDSR);
453		mtx_unlock_spin(&sc->sc_hwmtx);
454		new = sig & ~UART_SIGMASK_DELTA;
455	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
456	return (sig);
457}
458
459static int
460sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
461{
462	struct uart_bas *bas;
463	uint8_t dafo, mode;
464	int error;
465
466	bas = &sc->sc_bas;
467	error = 0;
468	mtx_lock_spin(&sc->sc_hwmtx);
469	switch (request) {
470	case UART_IOCTL_BREAK:
471		dafo = uart_getreg(bas, SAB_DAFO);
472		if (data)
473			dafo |= SAB_DAFO_XBRK;
474		else
475			dafo &= ~SAB_DAFO_XBRK;
476		uart_setreg(bas, SAB_DAFO, dafo);
477		uart_barrier(bas);
478		break;
479	case UART_IOCTL_IFLOW:
480		mode = uart_getreg(bas, SAB_MODE);
481		if (data) {
482			mode &= ~SAB_MODE_RTS;
483			mode |= SAB_MODE_FRTS;
484		} else {
485			mode |= SAB_MODE_RTS;
486			mode &= ~SAB_MODE_FRTS;
487		}
488		uart_setreg(bas, SAB_MODE, mode);
489		uart_barrier(bas);
490		break;
491	case UART_IOCTL_OFLOW:
492		mode = uart_getreg(bas, SAB_MODE);
493		if (data)
494			mode &= ~SAB_MODE_FCTS;
495		else
496			mode |= SAB_MODE_FCTS;
497		uart_setreg(bas, SAB_MODE, mode);
498		uart_barrier(bas);
499		break;
500	default:
501		error = EINVAL;
502		break;
503	}
504	mtx_unlock_spin(&sc->sc_hwmtx);
505	return (error);
506}
507
508static int
509sab82532_bus_ipend(struct uart_softc *sc)
510{
511	struct uart_bas *bas;
512	int ipend;
513	uint8_t isr0, isr1;
514
515	bas = &sc->sc_bas;
516	mtx_lock_spin(&sc->sc_hwmtx);
517	isr0 = uart_getreg(bas, SAB_ISR0);
518	isr1 = uart_getreg(bas, SAB_ISR1);
519	uart_barrier(bas);
520	if (isr0 & SAB_ISR0_TIME) {
521		while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
522			;
523		uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD);
524		uart_barrier(bas);
525	}
526	mtx_unlock_spin(&sc->sc_hwmtx);
527
528	ipend = 0;
529	if (isr1 & SAB_ISR1_BRKT)
530		ipend |= UART_IPEND_BREAK;
531	if (isr0 & SAB_ISR0_RFO)
532		ipend |= UART_IPEND_OVERRUN;
533	if (isr0 & (SAB_ISR0_TCD|SAB_ISR0_RPF))
534		ipend |= UART_IPEND_RXREADY;
535	if ((isr0 & SAB_ISR0_CDSC) || (isr1 & SAB_ISR1_CSC))
536		ipend |= UART_IPEND_SIGCHG;
537	if (isr1 & SAB_ISR1_ALLS)
538		ipend |= UART_IPEND_TXIDLE;
539
540	return (ipend);
541}
542
543static int
544sab82532_bus_param(struct uart_softc *sc, int baudrate, int databits,
545    int stopbits, int parity)
546{
547	struct uart_bas *bas;
548	int error;
549
550	bas = &sc->sc_bas;
551	mtx_lock_spin(&sc->sc_hwmtx);
552	error = sab82532_param(bas, baudrate, databits, stopbits, parity);
553	mtx_unlock_spin(&sc->sc_hwmtx);
554	return (error);
555}
556
557static int
558sab82532_bus_probe(struct uart_softc *sc)
559{
560	char buf[80];
561	const char *ch, *vstr;
562	int error;
563
564	error = sab82532_probe(&sc->sc_bas);
565	if (error)
566		return (error);
567
568	/* Assume the address range is naturally aligned. */
569	ch = IS_CHANNEL_A(&sc->sc_bas) ? "A" : "B";
570
571	switch (uart_getreg(&sc->sc_bas, SAB_VSTR) & SAB_VSTR_VMASK) {
572	case SAB_VSTR_V_1:
573		vstr = "v1";
574		break;
575	case SAB_VSTR_V_2:
576		vstr = "v2";
577		break;
578	case SAB_VSTR_V_32:
579		vstr = "v3.2";
580		sc->sc_hwiflow = 0;	/* CTS doesn't work with RFC:RFDF. */
581		sc->sc_hwoflow = 1;
582		break;
583	default:
584		vstr = "v4?";
585		break;
586	}
587
588	snprintf(buf, sizeof(buf), "SAB 82532 %s, channel %s", vstr, ch);
589	device_set_desc_copy(sc->sc_dev, buf);
590	return (0);
591}
592
593static int
594sab82532_bus_receive(struct uart_softc *sc)
595{
596	struct uart_bas *bas;
597	int i, rbcl, xc;
598	uint8_t s;
599
600	bas = &sc->sc_bas;
601	mtx_lock_spin(&sc->sc_hwmtx);
602	if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) {
603		rbcl = uart_getreg(bas, SAB_RBCL) & 31;
604		if (rbcl == 0)
605			rbcl = 32;
606		for (i = 0; i < rbcl; i += 2) {
607			if (uart_rx_full(sc)) {
608				sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
609				break;
610			}
611			xc = uart_getreg(bas, SAB_RFIFO);
612			s = uart_getreg(bas, SAB_RFIFO + 1);
613			if (s & SAB_RSTAT_FE)
614				xc |= UART_STAT_FRAMERR;
615			if (s & SAB_RSTAT_PE)
616				xc |= UART_STAT_PARERR;
617			uart_rx_put(sc, xc);
618		}
619	}
620
621	while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
622		;
623	uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC);
624	uart_barrier(bas);
625	mtx_unlock_spin(&sc->sc_hwmtx);
626	return (0);
627}
628
629static int
630sab82532_bus_setsig(struct uart_softc *sc, int sig)
631{
632	struct uart_bas *bas;
633	uint32_t new, old;
634	uint8_t mode, pvr;
635
636	bas = &sc->sc_bas;
637	do {
638		old = sc->sc_hwsig;
639		new = old;
640		if (sig & UART_SIG_DDTR) {
641			SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR,
642			    UART_SIG_DDTR);
643		}
644		if (sig & UART_SIG_DRTS) {
645			SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS,
646			    UART_SIG_DRTS);
647		}
648	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
649
650	mtx_lock_spin(&sc->sc_hwmtx);
651	/* Set DTR pin. */
652	pvr = uart_getreg(bas, SAB_PVR);
653	if (new & UART_SIG_DTR)
654		pvr &= (IS_CHANNEL_A(bas)) ? ~SAB_PVR_DTR_A : ~SAB_PVR_DTR_B;
655	else
656		pvr |= (IS_CHANNEL_A(bas)) ? SAB_PVR_DTR_A : SAB_PVR_DTR_B;
657	uart_setreg(bas, SAB_PVR, pvr);
658
659	/* Set RTS pin. */
660	mode = uart_getreg(bas, SAB_MODE);
661	if (new & UART_SIG_RTS)
662		mode &= ~SAB_MODE_FRTS;
663	else
664		mode |= SAB_MODE_FRTS;
665	uart_setreg(bas, SAB_MODE, mode);
666	uart_barrier(bas);
667	mtx_unlock_spin(&sc->sc_hwmtx);
668	return (0);
669}
670
671static int
672sab82532_bus_transmit(struct uart_softc *sc)
673{
674	struct uart_bas *bas;
675	int i;
676
677	bas = &sc->sc_bas;
678	mtx_lock_spin(&sc->sc_hwmtx);
679	while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_XFW))
680		;
681	for (i = 0; i < sc->sc_txdatasz; i++)
682		uart_setreg(bas, SAB_XFIFO + i, sc->sc_txbuf[i]);
683	uart_barrier(bas);
684	while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
685		;
686	uart_setreg(bas, SAB_CMDR, SAB_CMDR_XF);
687	sc->sc_txbusy = 1;
688	mtx_unlock_spin(&sc->sc_hwmtx);
689	return (0);
690}
691