1 /******************************************************************************
2 * *
3 * License Agreement *
4 * *
5 * Copyright (c) 2006 Altera Corporation, San Jose, California, USA. *
6 * All rights reserved. *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining a *
9 * copy of this software and associated documentation files (the "Software"), *
10 * to deal in the Software without restriction, including without limitation *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
12 * and/or sell copies of the Software, and to permit persons to whom the *
13 * Software is furnished to do so, subject to the following conditions: *
14 * *
15 * The above copyright notice and this permission notice shall be included in *
16 * all copies or substantial portions of the Software. *
17 * *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
24 * DEALINGS IN THE SOFTWARE. *
25 * *
26 * *
27 ******************************************************************************/
28
29 #include <fcntl.h>
30 #include <string.h>
31
32 #include "sys/alt_irq.h"
33 #include "sys/ioctl.h"
34 #include "sys/alt_errno.h"
35
36 #include "altera_avalon_uart_regs.h"
37 #include "altera_avalon_uart.h"
38
39
40 #if !defined(ALT_USE_SMALL_DRIVERS) && !defined(ALTERA_AVALON_UART_SMALL)
41
42 /* ----------------------------------------------------------- */
43 /* ------------------------- FAST DRIVER --------------------- */
44 /* ----------------------------------------------------------- */
45
46 /*
47 * To reduce the code footprint of this driver, the ioctl() function is not
48 * included by default. If you wish to use the ioctl features provided
49 * below, you can do so by adding the option : -DALTERA_AVALON_UART_USE_IOCTL
50 * to CPPFLAGS in the Makefile (or through the Eclipse IDE).
51 */
52
53 #ifdef ALTERA_AVALON_UART_USE_IOCTL
54
55 /*
56 * altera_avalon_uart_ioctl() is called by the system ioctl() function to handle
57 * ioctl requests for the UART. The only ioctl requests supported are TIOCMGET
58 * and TIOCMSET.
59 *
60 * TIOCMGET returns a termios structure that describes the current device
61 * configuration.
62 *
63 * TIOCMSET sets the device (if possible) to match the requested configuration.
64 * The requested configuration is described using a termios structure passed
65 * through the input argument "arg".
66 */
67
68 static int altera_avalon_uart_tiocmget(altera_avalon_uart_state* sp,
69 struct termios* term);
70 static int altera_avalon_uart_tiocmset(altera_avalon_uart_state* sp,
71 struct termios* term);
72
73 int
altera_avalon_uart_ioctl(altera_avalon_uart_state * sp,int req,void * arg)74 altera_avalon_uart_ioctl(altera_avalon_uart_state* sp, int req, void* arg)
75 {
76 int rc = -ENOTTY;
77
78 switch (req)
79 {
80 case TIOCMGET:
81 rc = altera_avalon_uart_tiocmget(sp, (struct termios*) arg);
82 break;
83 case TIOCMSET:
84 rc = altera_avalon_uart_tiocmset(sp, (struct termios*) arg);
85 break;
86 default:
87 break;
88 }
89 return rc;
90 }
91
92 /*
93 * altera_avalon_uart_tiocmget() is used by altera_avalon_uart_ioctl() to fill
94 * in the input termios structure with the current device configuration.
95 *
96 * See termios.h for further details on the contents of the termios structure.
97 */
98
99 static int
altera_avalon_uart_tiocmget(altera_avalon_uart_state * sp,struct termios * term)100 altera_avalon_uart_tiocmget(altera_avalon_uart_state* sp,
101 struct termios* term)
102 {
103 memcpy (term, &sp->termios, sizeof (struct termios));
104 return 0;
105 }
106
107 /*
108 * altera_avalon_uart_tiocmset() is used by altera_avalon_uart_ioctl() to
109 * configure the device according to the settings in the input termios
110 * structure. In practice the only configuration that can be changed is the
111 * baud rate, and then only if the hardware is configured to have a writable
112 * baud register.
113 */
114
115 static int
altera_avalon_uart_tiocmset(altera_avalon_uart_state * sp,struct termios * term)116 altera_avalon_uart_tiocmset(altera_avalon_uart_state* sp,
117 struct termios* term)
118 {
119 speed_t speed;
120
121 speed = sp->termios.c_ispeed;
122
123 /* Update the settings if the hardware supports it */
124
125 if (!(sp->flags & ALT_AVALON_UART_FB))
126 {
127 sp->termios.c_ispeed = sp->termios.c_ospeed = term->c_ispeed;
128 }
129 /*
130 * If the request was for an unsupported setting, return an error.
131 */
132
133 if (memcmp(term, &sp->termios, sizeof (struct termios)))
134 {
135 sp->termios.c_ispeed = sp->termios.c_ospeed = speed;
136 return -EIO;
137 }
138
139 /*
140 * Otherwise, update the hardware.
141 */
142
143 IOWR_ALTERA_AVALON_UART_DIVISOR(sp->base,
144 ((sp->freq/sp->termios.c_ispeed) - 1));
145
146 return 0;
147 }
148
149 #endif /* ALTERA_AVALON_UART_USE_IOCTL */
150
151 #endif /* fast driver */
152