4 * Pantelis Antoniou <panto@intracom.gr>
7 * SPDX-License-Identifier: GPL-2.0+
13 #include <linux/compiler.h>
15 DECLARE_GLOBAL_DATA_PTR;
17 /**************************************************************/
19 /* convienient macros */
20 #define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT)
22 #define MAX3100_SPI_TXD(x) \
25 MAX3100_SPI_TXD_PORT |= MAX3100_SPI_TXD_BIT; \
27 MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \
30 #define MAX3100_SPI_CLK(x) \
33 MAX3100_SPI_CLK_PORT |= MAX3100_SPI_CLK_BIT; \
35 MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \
38 #define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT)
40 #define MAX3100_CS(x) \
43 MAX3100_CS_PORT |= MAX3100_CS_BIT; \
45 MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \
48 /**************************************************************/
50 /* MAX3100 definitions */
52 #define MAX3100_WC (3 << 14) /* write configuration */
53 #define MAX3100_RC (1 << 14) /* read configuration */
54 #define MAX3100_WD (2 << 14) /* write data */
55 #define MAX3100_RD (0 << 14) /* read data */
57 /* configuration register bits */
58 #define MAX3100_FEN (1 << 13) /* FIFO enable */
59 #define MAX3100_SHDN (1 << 12) /* shutdown bit */
60 #define MAX3100_TM (1 << 11) /* T bit irq mask */
61 #define MAX3100_RM (1 << 10) /* R bit irq mask */
62 #define MAX3100_PM (1 << 9) /* P bit irq mask */
63 #define MAX3100_RAM (1 << 8) /* mask for RA/FE bit */
64 #define MAX3100_IR (1 << 7) /* IRDA timing mode */
65 #define MAX3100_ST (1 << 6) /* transmit stop bit */
66 #define MAX3100_PE (1 << 5) /* parity enable bit */
67 #define MAX3100_L (1 << 4) /* Length bit */
68 #define MAX3100_B_MASK (0x000F) /* baud rate bits mask */
69 #define MAX3100_B(x) ((x) & 0x000F) /* baud rate select bits */
71 /* data register bits (write) */
72 #define MAX3100_TE (1 << 10) /* transmit enable bit (active low) */
73 #define MAX3100_RTS (1 << 9) /* request-to-send bit (inverted ~RTS pin) */
75 /* data register bits (read) */
76 #define MAX3100_RA (1 << 10) /* receiver activity when in shutdown mode */
77 #define MAX3100_FE (1 << 10) /* framing error when in normal mode */
78 #define MAX3100_CTS (1 << 9) /* clear-to-send bit (inverted ~CTS pin) */
80 /* data register bits (both directions) */
81 #define MAX3100_R (1 << 15) /* receive bit */
82 #define MAX3100_T (1 << 14) /* transmit bit */
83 #define MAX3100_P (1 << 8) /* parity bit */
84 #define MAX3100_D_MASK 0x00FF /* data bits mask */
85 #define MAX3100_D(x) ((x) & 0x00FF) /* data bits */
87 /* these definitions are valid only for fOSC = 3.6864MHz */
88 #define MAX3100_B_230400 MAX3100_B(0)
89 #define MAX3100_B_115200 MAX3100_B(1)
90 #define MAX3100_B_57600 MAX3100_B(2)
91 #define MAX3100_B_38400 MAX3100_B(9)
92 #define MAX3100_B_19200 MAX3100_B(10)
93 #define MAX3100_B_9600 MAX3100_B(11)
94 #define MAX3100_B_4800 MAX3100_B(12)
95 #define MAX3100_B_2400 MAX3100_B(13)
96 #define MAX3100_B_1200 MAX3100_B(14)
97 #define MAX3100_B_600 MAX3100_B(15)
99 /**************************************************************/
101 static inline unsigned int max3100_transfer(unsigned int val)
111 MAX3100_SPI_TXD(val & 0x8000);
113 MAX3100_SPI_CLK_TOGGLE();
116 if (MAX3100_SPI_RXD())
118 MAX3100_SPI_CLK_TOGGLE();
128 /**************************************************************/
130 /* must be power of 2 */
133 static int rxfifo_cnt;
134 static int rxfifo_in;
135 static int rxfifo_out;
136 static unsigned char rxfifo_buf[16];
138 static void max3100_serial_putc_raw(int c)
142 while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0)
145 rx = max3100_transfer(MAX3100_WD | (c & 0xff));
146 if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) {
148 rxfifo_buf[rxfifo_in++] = rx & 0xff;
149 rxfifo_in &= RXFIFO_SZ - 1;
153 static int max3100_serial_getc(void)
158 while (rxfifo_cnt == 0) {
159 rx = max3100_transfer(MAX3100_RD);
160 if ((rx & MAX3100_R) != 0) {
163 rxfifo_buf[rxfifo_in++] = rx & 0xff;
164 rxfifo_in &= RXFIFO_SZ - 1;
166 if (rxfifo_cnt >= RXFIFO_SZ)
168 } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
174 c = rxfifo_buf[rxfifo_out++];
175 rxfifo_out &= RXFIFO_SZ - 1;
179 static int max3100_serial_tstc(void)
186 rx = max3100_transfer(MAX3100_RD);
187 if ((rx & MAX3100_R) == 0)
192 rxfifo_buf[rxfifo_in++] = rx & 0xff;
193 rxfifo_in &= RXFIFO_SZ - 1;
195 if (rxfifo_cnt >= RXFIFO_SZ)
197 } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
202 static int max3100_serial_init(void)
204 unsigned int wconf, rconf;
210 switch (gd->baudrate) {
212 wconf = MAX3100_B_1200;
215 wconf = MAX3100_B_2400;
218 wconf = MAX3100_B_4800;
221 wconf = MAX3100_B_9600;
224 wconf = MAX3100_B_19200;
227 wconf = MAX3100_B_38400;
230 wconf = MAX3100_B_57600;
234 wconf = MAX3100_B_115200;
237 wconf = MAX3100_B_230400;
241 /* try for 10ms, with a 100us gap */
242 for (i = 0; i < 10000; i += 100) {
244 max3100_transfer(MAX3100_WC | wconf);
245 rconf = max3100_transfer(MAX3100_RC) & 0x3fff;
252 rxfifo_in = rxfifo_out = rxfifo_cnt = 0;
257 static void max3100_serial_putc(const char c)
260 max3100_serial_putc_raw('\r');
262 max3100_serial_putc_raw(c);
265 static void max3100_serial_puts(const char *s)
268 max3100_serial_putc_raw(*s++);
271 static void max3100_serial_setbrg(void)
275 static struct serial_device max3100_serial_drv = {
276 .name = "max3100_serial",
277 .start = max3100_serial_init,
279 .setbrg = max3100_serial_setbrg,
280 .putc = max3100_serial_putc,
281 .puts = max3100_serial_puts,
282 .getc = max3100_serial_getc,
283 .tstc = max3100_serial_tstc,
286 void max3100_serial_initialize(void)
288 serial_register(&max3100_serial_drv);
291 __weak struct serial_device *default_serial_console(void)
293 return &max3100_serial_drv;