1 /******************************************************************************
 
   3  *      (C)Copyright 1998,1999 SysKonnect,
 
   4  *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
 
   6  *      See the file "skfddi.c" for further information.
 
   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.
 
  13  *      The information in this file is provided "AS IS" without warranty.
 
  15  ******************************************************************************/
 
  18  * Timer Driver for FBI board (timer chip 82C54)
 
  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(*)
 
  35 static const char ID_sccs[] = "@(#)hwt.c        1.13 97/04/23 (C) SK " ;
 
  39  * Prototypes of local functions.
 
  41 /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
 
  42 /*static void hwt_restart() ; */
 
  44 /************************
 
  48  *      Start hardware timer (clock ticks are 16us).
 
  54  *      smc - A pointer to the SMT Context structure.
 
  56  *      time - The time in units of 16us to load the timer with.
 
  60  ************************/
 
  61 #define HWT_MAX (65000)
 
  63 void hwt_start(struct s_smc *smc, u_long time)
 
  70         smc->hw.t_start = time ;
 
  81         outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;    /* Load timer value. */
 
  82         outpw(ADDR(B2_TI_CRTL), TIM_START) ;            /* Start timer. */
 
  84         smc->hw.timer_activ = TRUE ;
 
  87 /************************
 
  91  *      Stop hardware timer.
 
  94  *              struct s_smc *smc) ;
 
  96  *      smc - A pointer to the SMT Context structure.
 
 100  ************************/
 
 101 void hwt_stop(struct s_smc *smc)
 
 103         outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
 
 104         outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
 
 106         smc->hw.timer_activ = FALSE ;
 
 109 /************************
 
 113  *      Initialize hardware timer.
 
 116  *              struct s_smc *smc) ;
 
 118  *      smc - A pointer to the SMT Context structure.
 
 122  ************************/
 
 123 void hwt_init(struct s_smc *smc)
 
 125         smc->hw.t_start = 0 ;
 
 127         smc->hw.timer_activ = FALSE ;
 
 132 /************************
 
 136  *      Clear timer interrupt.
 
 139  *              struct s_smc *smc) ;
 
 141  *      smc - A pointer to the SMT Context structure.
 
 145  ************************/
 
 146 void hwt_restart(struct s_smc *smc)
 
 151 /************************
 
 155  *      Stop hardware timer and read time elapsed since last start.
 
 157  *      u_long hwt_read(smc) ;
 
 159  *      smc - A pointer to the SMT Context structure.
 
 161  *      The elapsed time since last start in units of 16us.
 
 163  ************************/
 
 164 u_long hwt_read(struct s_smc *smc)
 
 169         if (smc->hw.timer_activ) {
 
 171                 tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
 
 174                 /* Check if timer expired (or wraparound). */
 
 175                 if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
 
 177                         smc->hw.t_stop = smc->hw.t_start ;
 
 180                         smc->hw.t_stop = smc->hw.t_start - tr ;
 
 182         return (smc->hw.t_stop) ;
 
 186 /************************
 
 190  *      Stop hardware timer and read timer value and start the timer again.
 
 192  *      u_long hwt_read(smc) ;
 
 194  *      smc - A pointer to the SMT Context structure.
 
 196  *      current timer value in units of 80ns.
 
 198  ************************/
 
 199 u_long hwt_quick_read(struct s_smc *smc)
 
 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) ;
 
 214 /************************
 
 216  *      hwt_wait_time(smc,start,duration)
 
 218  *      This function returnes after the amount of time is elapsed
 
 219  *      since the start time.
 
 221  * para start           start time
 
 222  *      duration        time to wait
 
 224  * NOTE: The fuction will return immediately, if the timer is not 
 
 226  ************************/
 
 227 void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
 
 234          * check if timer is running
 
 236         if (smc->hw.timer_activ == FALSE ||
 
 237                 hwt_quick_read(smc) == hwt_quick_read(smc)) {
 
 241         interval = inpd(ADDR(B2_TI_INI)) ;
 
 242         if (interval > duration) {
 
 244                         diff = (long)(start - hwt_quick_read(smc)) ;
 
 248                 } while (diff <= duration) ;
 
 255                                 if (hwt_quick_read(smc) >= start) {
 
 261                                 if (hwt_quick_read(smc) < start) {
 
 265                 } while (diff <= duration) ;