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