]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 LT |
2 | /****************************************************************************** |
3 | * | |
4 | * (C)Copyright 1998,1999 SysKonnect, | |
5 | * a business unit of Schneider & Koch & Co. Datensysteme GmbH. | |
6 | * | |
7 | * See the file "skfddi.c" for further information. | |
8 | * | |
1da177e4 LT |
9 | * The information in this file is provided "AS IS" without warranty. |
10 | * | |
11 | ******************************************************************************/ | |
12 | ||
13 | /* | |
14 | * Timer Driver for FBI board (timer chip 82C54) | |
15 | */ | |
16 | ||
17 | /* | |
18 | * Modifications: | |
19 | * | |
20 | * 28-Jun-1994 sw Edit v1.6. | |
21 | * MCA: Added support for the SK-NET FDDI-FM2 adapter. The | |
22 | * following functions have been added(+) or modified(*): | |
23 | * hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*) | |
24 | */ | |
25 | ||
26 | #include "h/types.h" | |
27 | #include "h/fddi.h" | |
28 | #include "h/smc.h" | |
29 | ||
30 | #ifndef lint | |
31 | static const char ID_sccs[] = "@(#)hwt.c 1.13 97/04/23 (C) SK " ; | |
32 | #endif | |
33 | ||
34 | /* | |
35 | * Prototypes of local functions. | |
36 | */ | |
37 | /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */ | |
38 | /*static void hwt_restart() ; */ | |
39 | ||
40 | /************************ | |
41 | * | |
42 | * hwt_start | |
43 | * | |
44 | * Start hardware timer (clock ticks are 16us). | |
45 | * | |
46 | * void hwt_start( | |
47 | * struct s_smc *smc, | |
48 | * u_long time) ; | |
49 | * In | |
50 | * smc - A pointer to the SMT Context structure. | |
51 | * | |
52 | * time - The time in units of 16us to load the timer with. | |
53 | * Out | |
54 | * Nothing. | |
55 | * | |
56 | ************************/ | |
57 | #define HWT_MAX (65000) | |
58 | ||
59 | void hwt_start(struct s_smc *smc, u_long time) | |
60 | { | |
61 | u_short cnt ; | |
62 | ||
63 | if (time > HWT_MAX) | |
64 | time = HWT_MAX ; | |
65 | ||
66 | smc->hw.t_start = time ; | |
67 | smc->hw.t_stop = 0L ; | |
68 | ||
69 | cnt = (u_short)time ; | |
70 | /* | |
71 | * if time < 16 us | |
72 | * time = 16 us | |
73 | */ | |
74 | if (!cnt) | |
75 | cnt++ ; | |
af096046 | 76 | |
1da177e4 LT |
77 | outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ; /* Load timer value. */ |
78 | outpw(ADDR(B2_TI_CRTL), TIM_START) ; /* Start timer. */ | |
af096046 | 79 | |
1da177e4 LT |
80 | smc->hw.timer_activ = TRUE ; |
81 | } | |
82 | ||
83 | /************************ | |
84 | * | |
85 | * hwt_stop | |
86 | * | |
87 | * Stop hardware timer. | |
88 | * | |
89 | * void hwt_stop( | |
90 | * struct s_smc *smc) ; | |
91 | * In | |
92 | * smc - A pointer to the SMT Context structure. | |
93 | * Out | |
94 | * Nothing. | |
95 | * | |
96 | ************************/ | |
97 | void hwt_stop(struct s_smc *smc) | |
98 | { | |
1da177e4 LT |
99 | outpw(ADDR(B2_TI_CRTL), TIM_STOP) ; |
100 | outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ; | |
1da177e4 LT |
101 | |
102 | smc->hw.timer_activ = FALSE ; | |
103 | } | |
104 | ||
105 | /************************ | |
106 | * | |
107 | * hwt_init | |
108 | * | |
109 | * Initialize hardware timer. | |
110 | * | |
111 | * void hwt_init( | |
112 | * struct s_smc *smc) ; | |
113 | * In | |
114 | * smc - A pointer to the SMT Context structure. | |
115 | * Out | |
116 | * Nothing. | |
117 | * | |
118 | ************************/ | |
119 | void hwt_init(struct s_smc *smc) | |
120 | { | |
121 | smc->hw.t_start = 0 ; | |
122 | smc->hw.t_stop = 0 ; | |
123 | smc->hw.timer_activ = FALSE ; | |
124 | ||
125 | hwt_restart(smc) ; | |
126 | } | |
127 | ||
128 | /************************ | |
129 | * | |
130 | * hwt_restart | |
131 | * | |
132 | * Clear timer interrupt. | |
133 | * | |
134 | * void hwt_restart( | |
135 | * struct s_smc *smc) ; | |
136 | * In | |
137 | * smc - A pointer to the SMT Context structure. | |
138 | * Out | |
139 | * Nothing. | |
140 | * | |
141 | ************************/ | |
142 | void hwt_restart(struct s_smc *smc) | |
143 | { | |
144 | hwt_stop(smc) ; | |
1da177e4 LT |
145 | } |
146 | ||
147 | /************************ | |
148 | * | |
149 | * hwt_read | |
150 | * | |
151 | * Stop hardware timer and read time elapsed since last start. | |
152 | * | |
153 | * u_long hwt_read(smc) ; | |
154 | * In | |
155 | * smc - A pointer to the SMT Context structure. | |
156 | * Out | |
157 | * The elapsed time since last start in units of 16us. | |
158 | * | |
159 | ************************/ | |
160 | u_long hwt_read(struct s_smc *smc) | |
161 | { | |
162 | u_short tr ; | |
1da177e4 | 163 | u_long is ; |
1da177e4 LT |
164 | |
165 | if (smc->hw.timer_activ) { | |
166 | hwt_stop(smc) ; | |
1da177e4 | 167 | tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ; |
af096046 | 168 | |
1da177e4 LT |
169 | is = GET_ISR() ; |
170 | /* Check if timer expired (or wraparound). */ | |
171 | if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) { | |
172 | hwt_restart(smc) ; | |
173 | smc->hw.t_stop = smc->hw.t_start ; | |
174 | } | |
175 | else | |
176 | smc->hw.t_stop = smc->hw.t_start - tr ; | |
177 | } | |
807540ba | 178 | return smc->hw.t_stop; |
1da177e4 LT |
179 | } |
180 | ||
181 | #ifdef PCI | |
182 | /************************ | |
183 | * | |
184 | * hwt_quick_read | |
185 | * | |
186 | * Stop hardware timer and read timer value and start the timer again. | |
187 | * | |
188 | * u_long hwt_read(smc) ; | |
189 | * In | |
190 | * smc - A pointer to the SMT Context structure. | |
191 | * Out | |
192 | * current timer value in units of 80ns. | |
193 | * | |
194 | ************************/ | |
195 | u_long hwt_quick_read(struct s_smc *smc) | |
196 | { | |
197 | u_long interval ; | |
198 | u_long time ; | |
199 | ||
200 | interval = inpd(ADDR(B2_TI_INI)) ; | |
201 | outpw(ADDR(B2_TI_CRTL), TIM_STOP) ; | |
202 | time = inpd(ADDR(B2_TI_VAL)) ; | |
203 | outpd(ADDR(B2_TI_INI),time) ; | |
204 | outpw(ADDR(B2_TI_CRTL), TIM_START) ; | |
205 | outpd(ADDR(B2_TI_INI),interval) ; | |
206 | ||
807540ba | 207 | return time; |
1da177e4 LT |
208 | } |
209 | ||
210 | /************************ | |
211 | * | |
212 | * hwt_wait_time(smc,start,duration) | |
213 | * | |
214 | * This function returnes after the amount of time is elapsed | |
215 | * since the start time. | |
216 | * | |
217 | * para start start time | |
218 | * duration time to wait | |
219 | * | |
eef35c2d | 220 | * NOTE: The function will return immediately, if the timer is not |
1da177e4 LT |
221 | * started |
222 | ************************/ | |
223 | void hwt_wait_time(struct s_smc *smc, u_long start, long int duration) | |
224 | { | |
225 | long diff ; | |
226 | long interval ; | |
227 | int wrapped ; | |
228 | ||
229 | /* | |
230 | * check if timer is running | |
231 | */ | |
232 | if (smc->hw.timer_activ == FALSE || | |
233 | hwt_quick_read(smc) == hwt_quick_read(smc)) { | |
234 | return ; | |
235 | } | |
236 | ||
237 | interval = inpd(ADDR(B2_TI_INI)) ; | |
238 | if (interval > duration) { | |
239 | do { | |
240 | diff = (long)(start - hwt_quick_read(smc)) ; | |
241 | if (diff < 0) { | |
242 | diff += interval ; | |
243 | } | |
244 | } while (diff <= duration) ; | |
245 | } | |
246 | else { | |
247 | diff = interval ; | |
248 | wrapped = 0 ; | |
249 | do { | |
250 | if (!wrapped) { | |
251 | if (hwt_quick_read(smc) >= start) { | |
252 | diff += interval ; | |
253 | wrapped = 1 ; | |
254 | } | |
255 | } | |
256 | else { | |
257 | if (hwt_quick_read(smc) < start) { | |
258 | wrapped = 0 ; | |
259 | } | |
260 | } | |
261 | } while (diff <= duration) ; | |
262 | } | |
263 | } | |
264 | #endif | |
265 |