Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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