LCOV - code coverage report
Current view: top level - dev/isa - pcppi.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 97 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: pcppi.c,v 1.13 2016/01/08 15:54:13 jcs Exp $ */
       2             : /* $NetBSD: pcppi.c,v 1.1 1998/04/15 20:26:18 drochner Exp $ */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1996 Carnegie-Mellon University.
       6             :  * All rights reserved.
       7             :  *
       8             :  * Author: Chris G. Demetriou
       9             :  * 
      10             :  * Permission to use, copy, modify and distribute this software and
      11             :  * its documentation is hereby granted, provided that both the copyright
      12             :  * notice and this permission notice appear in all copies of the
      13             :  * software, derivative works or modified versions, and any portions
      14             :  * thereof, and that both notices appear in supporting documentation.
      15             :  * 
      16             :  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
      17             :  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
      18             :  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
      19             :  * 
      20             :  * Carnegie Mellon requests users of this software to return to
      21             :  *
      22             :  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
      23             :  *  School of Computer Science
      24             :  *  Carnegie Mellon University
      25             :  *  Pittsburgh PA 15213-3890
      26             :  *
      27             :  * any improvements or extensions that they make and grant Carnegie the
      28             :  * rights to redistribute these changes.
      29             :  */
      30             : 
      31             : #include <sys/param.h>
      32             : #include <sys/systm.h>
      33             : #include <sys/kernel.h>
      34             : #include <sys/device.h>
      35             : #include <sys/errno.h>
      36             : #include <sys/timeout.h>
      37             : 
      38             : #include <machine/bus.h>
      39             : 
      40             : #include <dev/isa/isareg.h>
      41             : #include <dev/isa/isavar.h>
      42             : #include <dev/isa/pcppireg.h>
      43             : #include <dev/isa/pcppivar.h>
      44             : 
      45             : #include <dev/ic/i8253reg.h>
      46             : 
      47             : #include "pckbd.h"
      48             : #include "hidkbd.h"
      49             : #if NPCKBD > 0 || NHIDKBD > 0
      50             : #include <dev/ic/pckbcvar.h>
      51             : #include <dev/pckbc/pckbdvar.h>
      52             : #include <dev/hid/hidkbdvar.h>
      53             : void    pcppi_kbd_bell(void *, u_int, u_int, u_int, int);
      54             : #endif
      55             : 
      56             : struct pcppi_softc {
      57             :         struct device sc_dv;
      58             : 
      59             :         bus_space_tag_t sc_iot;
      60             :         bus_space_handle_t sc_ppi_ioh, sc_pit1_ioh;
      61             : 
      62             :         struct timeout sc_bell_timeout;
      63             : 
      64             :         int sc_bellactive, sc_bellpitch;
      65             :         int sc_slp;
      66             :         int sc_timeout;
      67             : };
      68             : 
      69             : int     pcppi_match(struct device *, void *, void *);
      70             : void    pcppi_attach(struct device *, struct device *, void *);
      71             : 
      72             : struct cfattach pcppi_ca = {
      73             :         sizeof(struct pcppi_softc), pcppi_match, pcppi_attach,
      74             : };
      75             : 
      76             : struct cfdriver pcppi_cd = {
      77             :         NULL, "pcppi", DV_DULL
      78             : };
      79             : 
      80             : static void pcppi_bell_stop(void *);
      81             : 
      82             : #define PCPPIPRI (PZERO - 1)
      83             : 
      84             : int
      85           0 : pcppi_match(parent, match, aux)
      86             :         struct device *parent;
      87             :         void *match;
      88             :         void *aux;
      89             : {
      90           0 :         struct isa_attach_args *ia = aux;
      91           0 :         bus_space_handle_t ppi_ioh, pit1_ioh;
      92             :         int have_pit1, have_ppi, rv;
      93             :         u_int8_t v, nv;
      94             : 
      95             :         /* If values are hardwired to something that they can't be, punt. */
      96           0 :         if ((ia->ia_iobase != IOBASEUNK && ia->ia_iobase != IO_PPI) ||
      97           0 :             ia->ia_maddr != MADDRUNK || ia->ia_msize != 0 ||
      98           0 :             ia->ia_irq != IRQUNK || ia->ia_drq != DRQUNK)
      99           0 :                 return (0);
     100             : 
     101             :         rv = 0;
     102             :         have_pit1 = have_ppi = 0;
     103             : 
     104           0 :         if (bus_space_map(ia->ia_iot, IO_TIMER1, 4, 0, &pit1_ioh))
     105             :                 goto lose;
     106             :         have_pit1 = 1;
     107           0 :         if (bus_space_map(ia->ia_iot, IO_PPI, 1, 0, &ppi_ioh))
     108             :                 goto lose;
     109             :         have_ppi = 1;
     110             : 
     111             :         /*
     112             :          * Check for existence of PPI.  Realistically, this is either going to
     113             :          * be here or nothing is going to be here.
     114             :          *
     115             :          * We don't want to have any chance of changing speaker output (which
     116             :          * this test might, if it crashes in the middle, or something;
     117             :          * normally it's be to quick to produce anthing audible), but
     118             :          * many "combo chip" mock-PPI's don't seem to support the top bit
     119             :          * of Port B as a settable bit.  The bottom bit has to be settable,
     120             :          * since the speaker driver hardware still uses it.
     121             :          */
     122           0 :         v = bus_space_read_1(ia->ia_iot, ppi_ioh, 0);                /* XXX */
     123           0 :         bus_space_write_1(ia->ia_iot, ppi_ioh, 0, v ^ 0x01); /* XXX */
     124           0 :         nv = bus_space_read_1(ia->ia_iot, ppi_ioh, 0);               /* XXX */
     125           0 :         if (((nv ^ v) & 0x01) == 0x01)
     126           0 :                 rv = 1;
     127           0 :         bus_space_write_1(ia->ia_iot, ppi_ioh, 0, v);                /* XXX */
     128           0 :         nv = bus_space_read_1(ia->ia_iot, ppi_ioh, 0);               /* XXX */
     129           0 :         if (((nv ^ v) & 0x01) != 0x00) {
     130             :                 rv = 0;
     131           0 :                 goto lose;
     132             :         }
     133             : 
     134             :         /*
     135             :          * We assume that the programmable interval timer is there.
     136             :          */
     137             : 
     138             : lose:
     139           0 :         if (have_pit1)
     140           0 :                 bus_space_unmap(ia->ia_iot, pit1_ioh, 4);
     141           0 :         if (have_ppi)
     142           0 :                 bus_space_unmap(ia->ia_iot, ppi_ioh, 1);
     143           0 :         if (rv) {
     144           0 :                 ia->ia_iobase = IO_PPI;
     145           0 :                 ia->ia_iosize = 0x1;
     146           0 :                 ia->ia_msize = 0x0;
     147           0 :         }
     148           0 :         return (rv);
     149           0 : }
     150             : 
     151             : void
     152           0 : pcppi_attach(parent, self, aux)
     153             :         struct device *parent, *self;
     154             :         void *aux;
     155             : {
     156           0 :         struct pcppi_softc *sc = (struct pcppi_softc *)self;
     157           0 :         struct isa_attach_args *ia = aux;
     158             :         bus_space_tag_t iot;
     159           0 :         struct pcppi_attach_args pa;
     160             : 
     161           0 :         timeout_set(&sc->sc_bell_timeout, pcppi_bell_stop, sc);
     162             : 
     163           0 :         sc->sc_iot = iot = ia->ia_iot;
     164             : 
     165           0 :         if (bus_space_map(iot, IO_TIMER1, 4, 0, &sc->sc_pit1_ioh) ||
     166           0 :             bus_space_map(iot, IO_PPI, 1, 0, &sc->sc_ppi_ioh))
     167           0 :                 panic("pcppi_attach: couldn't map");
     168             : 
     169           0 :         printf("\n");
     170             : 
     171           0 :         sc->sc_bellactive = sc->sc_bellpitch = sc->sc_slp = 0;
     172             : 
     173             :         /* Provide a beeper for the keyboard, if there isn't one already. */
     174             : #if NPCKBD > 0
     175           0 :         pckbd_hookup_bell(pcppi_kbd_bell, sc);
     176             : #endif
     177             : #if NHIDKBD > 0
     178           0 :         hidkbd_hookup_bell(pcppi_kbd_bell, sc);
     179             : #endif
     180             : 
     181           0 :         pa.pa_cookie = sc;
     182           0 :         while (config_found(self, &pa, 0))
     183             :                 ;
     184           0 : }
     185             : 
     186             : void
     187           0 : pcppi_bell(self, pitch, period, slp)
     188             :         pcppi_tag_t self;
     189             :         int pitch, period;
     190             :         int slp;
     191             : {
     192           0 :         struct pcppi_softc *sc = self;
     193             :         int s1, s2;
     194             : 
     195           0 :         s1 = spltty(); /* ??? */
     196           0 :         if (sc->sc_bellactive) {
     197           0 :                 if (sc->sc_timeout) {
     198           0 :                         sc->sc_timeout = 0;
     199           0 :                         timeout_del(&sc->sc_bell_timeout);
     200           0 :                 }
     201           0 :                 if (sc->sc_slp)
     202           0 :                         wakeup(pcppi_bell_stop);
     203             :         }
     204           0 :         if (pitch == 0 || period == 0) {
     205           0 :                 pcppi_bell_stop(sc);
     206           0 :                 sc->sc_bellpitch = 0;
     207           0 :                 splx(s1);
     208           0 :                 return;
     209             :         }
     210           0 :         if (!sc->sc_bellactive || sc->sc_bellpitch != pitch) {
     211           0 :                 s2 = splhigh();
     212           0 :                 bus_space_write_1(sc->sc_iot, sc->sc_pit1_ioh, TIMER_MODE,
     213             :                     TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
     214           0 :                 bus_space_write_1(sc->sc_iot, sc->sc_pit1_ioh, TIMER_CNTR2,
     215             :                     TIMER_DIV(pitch) % 256);
     216           0 :                 bus_space_write_1(sc->sc_iot, sc->sc_pit1_ioh, TIMER_CNTR2,
     217             :                     TIMER_DIV(pitch) / 256);
     218           0 :                 splx(s2);
     219             :                 /* enable speaker */
     220           0 :                 bus_space_write_1(sc->sc_iot, sc->sc_ppi_ioh, 0,
     221             :                         bus_space_read_1(sc->sc_iot, sc->sc_ppi_ioh, 0)
     222             :                         | PIT_SPKR);
     223           0 :         }
     224           0 :         sc->sc_bellpitch = pitch;
     225             : 
     226           0 :         sc->sc_bellactive = 1;
     227             : 
     228           0 :         if (slp & PCPPI_BELL_POLL) {
     229           0 :                 delay((period * 1000000) / hz);
     230           0 :                 pcppi_bell_stop(sc);
     231           0 :         } else {
     232           0 :                 sc->sc_timeout = 1;
     233           0 :                 timeout_add(&sc->sc_bell_timeout, period);
     234           0 :                 if (slp & PCPPI_BELL_SLEEP) {
     235           0 :                         sc->sc_slp = 1;
     236           0 :                         tsleep(pcppi_bell_stop, PCPPIPRI | PCATCH, "bell", 0);
     237           0 :                         sc->sc_slp = 0;
     238           0 :                 }
     239             :         }
     240           0 :         splx(s1);
     241           0 : }
     242             : 
     243             : static void
     244           0 : pcppi_bell_stop(arg)
     245             :         void *arg;
     246             : {
     247           0 :         struct pcppi_softc *sc = arg;
     248             :         int s;
     249             : 
     250           0 :         s = spltty(); /* ??? */
     251           0 :         sc->sc_timeout = 0;
     252             : 
     253             :         /* disable bell */
     254           0 :         bus_space_write_1(sc->sc_iot, sc->sc_ppi_ioh, 0,
     255             :                           bus_space_read_1(sc->sc_iot, sc->sc_ppi_ioh, 0)
     256             :                           & ~PIT_SPKR);
     257           0 :         sc->sc_bellactive = 0;
     258           0 :         if (sc->sc_slp)
     259           0 :                 wakeup(pcppi_bell_stop);
     260           0 :         splx(s);
     261           0 : }
     262             : 
     263             : #if NPCKBD > 0 || NHIDKBD > 0
     264             : void
     265           0 : pcppi_kbd_bell(arg, pitch, period, volume, poll)
     266             :         void *arg;
     267             :         u_int pitch, period, volume;
     268             :         int poll;
     269             : {
     270             :         /*
     271             :          * Comes in as ms, goes out as ticks; volume ignored.
     272             :          */
     273           0 :         pcppi_bell(arg, volume ? pitch : 0, (period * hz) / 1000,
     274           0 :             poll ? PCPPI_BELL_POLL : 0);
     275           0 : }
     276             : #endif /* NPCKBD > 0 || NHIDKBD > 0 */

Generated by: LCOV version 1.13