xref: /netbsd-src/sys/arch/evbsh3/nextvod/stasc.c (revision 3587d6f89c746bbb4f886219ddacd41ace480ecf)
1 /* $NetBSD: stasc.c,v 1.2 2020/07/20 01:06:33 uwe Exp $ */
2 /*
3  * Copyright (c) 2020 Valery Ushakov
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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 /*
28  * STMicroelectronics ST40 Asynchronous Serial Controller
29  */
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: stasc.c,v 1.2 2020/07/20 01:06:33 uwe Exp $");
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/conf.h>
36 #include <sys/device.h>
37 #include <sys/kernel.h>
38 
39 #include <dev/cons.h>
40 
41 
42 #define STM_ASC_BASE	0xfd032000
43 
44 #define ASC_BAUDRATE_OFFSET	0x00
45 #define ASC_TX_BUFF_OFFSET	0x04
46 #define ASC_RX_BUFF_OFFSET	0x08
47 #define ASC_CTRL_OFFSET		0x0C
48 #define ASC_INT_EN_OFFSET	0x10
49 #define ASC_INT_STA_OFFSET	0x14
50 #define ASC_GUARDTIME_OFFSET	0x18
51 #define ASC_TIMEOUT_OFFSET	0x1C
52 #define ASC_TX_RST_OFFSET	0x20
53 #define ASC_RX_RST_OFFSET	0x24
54 #define ASC_RETRIES_OFFSET	0x28
55 
56 #define ASC_TX_BUFF	(*(volatile uint32_t *)(STM_ASC_BASE + ASC_TX_BUFF_OFFSET))
57 #define ASC_RX_BUFF	(*(volatile uint32_t *)(STM_ASC_BASE + ASC_RX_BUFF_OFFSET))
58 #define ASC_INT_EN	(*(volatile uint32_t *)(STM_ASC_BASE + ASC_INT_EN_OFFSET))
59 #define ASC_INT_STA	(*(volatile uint32_t *)(STM_ASC_BASE + ASC_INT_STA_OFFSET))
60 
61 
62 #define ASC_CTRL_NACK_DISABLE	0x2000
63 #define ASC_CTRL_BAUDMODE	0x1000
64 #define ASC_CTRL_CTS_EN		0x0800
65 #define ASC_CTRL_FIFO_EN	0x0400
66 #define ASC_CTRL_SC_EN		0x0200
67 #define ASC_CTRL_RX_EN		0x0100
68 #define ASC_CTRL_RUN		0x0080
69 #define ASC_CTRL_LOOPBACK	0x0040
70 #define ASC_CTRL_PARITYODD	0x0020
71 #define ASC_CTRL_STOPBITS_MASK	0x0018
72 #define     ASC_CTRL_STOPBITS_0_5	0x0000
73 #define     ASC_CTRL_STOPBITS_1_0	0x0008
74 #define     ASC_CTRL_STOPBITS_1_5	0x0010
75 #define     ASC_CTRL_STOPBITS_2_0	0x0018
76 #define ASC_CTRL_MODE_MASK	0x0007
77 #define     ASC_CTRL_MODE_8N		0x0001 /* 8 bit */
78 #define     ASC_CTRL_MODE_7P		0x0003 /* 7 bit + parity  */
79 #define     ASC_CTRL_MODE_9N		0x0004 /* 9 bit */
80 #define     ASC_CTRL_MODE_8W		0x0005 /* 8 bit + wakeup */
81 #define     ASC_CTRL_MODE_8P		0x0007 /* 8 bit + parity */
82 
83 
84 #define ASC_INT_EN_RHF		0x0100 /* ASC_INT_STA_RHF */
85 #define ASC_INT_EN_TOE		0x0080 /* ASC_INT_STA_TOE */
86 #define ASC_INT_EN_TNE		0x0040 /* ASC_INT_STA_TNE */
87 #define ASC_INT_EN_OE		0x0020 /* ASC_INT_STA_OE */
88 #define ASC_INT_EN_FE		0x0010 /* ASC_INT_STA_FE */
89 #define ASC_INT_EN_PE		0x0008 /* ASC_INT_STA_PE */
90 #define	ASC_INT_EN_THE		0x0004 /* ASC_INT_STA_THE */
91 #define ASC_INT_EN_TE		0x0002 /* ASC_INT_STA_TE */
92 #define ASC_INT_EN_RBF		0x0001 /* ASC_INT_STA_RBF */
93 
94 #define ASC_INT_STA_NKD		0x0400 /* Tx: NACK Data */
95 #define ASC_INT_STA_TF		0x0200 /* Tx: Transmitter Full */
96 #define ASC_INT_STA_RHF		0x0100 /* Rx: Receiver FIFO Half Full */
97 #define ASC_INT_STA_TOE		0x0080 /* Rx: Timeout Or Empty */
98 #define ASC_INT_STA_TNE		0x0040 /* Rx: Timeout Or Not Empty */
99 #define ASC_INT_STA_OE		0x0020 /* Rx: Overrun Error */
100 #define ASC_INT_STA_FE		0x0010 /* Rx: Frame Error */
101 #define ASC_INT_STA_PE		0x0008 /* Rx: Parity Error */
102 #define	ASC_INT_STA_THE		0x0004 /* Tx: Transmitter FIFO Half Empty */
103 #define ASC_INT_STA_TE		0x0002 /* Tx: Transmitter Empty */
104 #define ASC_INT_STA_RBF		0x0001 /* Rx: Reciever Buffer Full */
105 
106 
107 
108 struct stasc_softc {
109 	device_t sc_dev;
110 };
111 
112 
113 static int stasc_match(device_t, cfdata_t, void *);
114 static void stasc_attach(device_t, device_t, void *);
115 
116 CFATTACH_DECL_NEW(stasc, sizeof(struct stasc_softc),
117     stasc_match, stasc_attach, NULL, NULL);
118 
119 
120 /* console */
121 cons_decl(stasc_)
122 
123 /* assign to cn_tab after cleaning bss to get printf early for the cpu setup */
124 struct consdev stasc_earlycons = cons_init(stasc_);
125 
126 extern struct cfdriver stasc_cd;
127 
128 const struct cdevsw stasc_cdevsw = {
129 	.d_open = noopen,
130 	.d_close = noclose,
131 	.d_read = noread,
132 	.d_write = nowrite,
133 	.d_ioctl = noioctl,
134 	.d_stop = nostop,
135 	.d_tty = notty,
136 	.d_poll = nopoll,
137 	.d_mmap = nommap,
138 	.d_kqfilter = nokqfilter,
139 	.d_discard = nodiscard,
140 	.d_flag = D_TTY
141 };
142 
143 
144 
145 static int
146 stasc_match(device_t parent, cfdata_t cfp, void *aux)
147 {
148 
149 	if (strcmp(cfp->cf_name, "stasc") != 0)
150 		return 0;
151 
152 	return 0;		/* just stub it out for now */
153 }
154 
155 
156 static void
157 stasc_attach(device_t parent, device_t self, void *aux)
158 {
159 	struct stasc_softc *sc;
160 
161 	sc = device_private(self);
162 	sc->sc_dev = self;
163 
164 	aprint_normal("\n");
165 }
166 
167 
168 void
169 stasc_cnprobe(struct consdev *cp)
170 {
171 
172 	cp->cn_pri = CN_NORMAL;
173 }
174 
175 
176 void
177 stasc_cninit(struct consdev *cp)
178 {
179 
180 	return;
181 }
182 
183 
184 int
185 stasc_cngetc(dev_t dev)
186 {
187 	int s = splserial();
188 	uint32_t status;
189 	int c;
190 
191 	/* don't block if Rx buffer is empty */
192 	status = ASC_INT_STA;
193 	if (!ISSET(status, ASC_INT_STA_RBF)) {
194 		splx(s);
195 		return -1;
196 	}
197 
198 	/* can read the character now */
199 	c = ASC_RX_BUFF;
200 	splx(s);
201 	return (unsigned char)c;
202 }
203 
204 
205 void
206 stasc_cnputc(dev_t dev, int c)
207 {
208 	int s = splserial();
209 	uint32_t timo, status;
210 
211 	/* wait for Tx Full to become clear */
212 	timo = 150000;
213 	do {
214 		status = ASC_INT_STA;
215 	} while (ISSET(status, ASC_INT_STA_TF) && --timo);
216 
217 	/* can write the character now */
218 	ASC_TX_BUFF = c;
219 	splx(s);
220 }
221 
222 
223 void
224 stasc_cnpollc(dev_t dev, int on)
225 {
226 
227 	return;
228 }
229