The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/mpu.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: mpu.c,v 1.6 2003/12/04 13:57:30 keihan Exp $   */
    2 
    3 /*
    4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Lennart Augustsson (augustss@NetBSD.org).
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: mpu.c,v 1.6 2003/12/04 13:57:30 keihan Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/errno.h>
   45 #include <sys/ioctl.h>
   46 #include <sys/syslog.h>
   47 #include <sys/device.h>
   48 #include <sys/proc.h>
   49 #include <sys/buf.h>
   50 
   51 #include <machine/cpu.h>
   52 #include <machine/intr.h>
   53 #include <machine/bus.h>
   54 
   55 #include <dev/midi_if.h>
   56 
   57 #include <dev/ic/mpuvar.h>
   58 
   59 #ifdef AUDIO_DEBUG
   60 #define DPRINTF(x)      if (mpudebug) printf x
   61 #define DPRINTFN(n,x)   if (mpudebug >= (n)) printf x
   62 int     mpudebug = 0;
   63 #else
   64 #define DPRINTF(x)
   65 #define DPRINTFN(n,x)
   66 #endif
   67 
   68 #define MPU_DATA                0
   69 #define MPU_COMMAND     1
   70 #define  MPU_RESET      0xff
   71 #define  MPU_UART_MODE  0x3f
   72 #define  MPU_ACK                0xfe
   73 #define MPU_STATUS      1
   74 #define  MPU_OUTPUT_BUSY        0x40
   75 #define  MPU_INPUT_EMPTY        0x80
   76 
   77 #define MPU_MAXWAIT     10000   /* usec/10 to wait */
   78 
   79 #define MPU_GETSTATUS(iot, ioh) (bus_space_read_1(iot, ioh, MPU_STATUS))
   80 
   81 int     mpu_reset(struct mpu_softc *);
   82 static  __inline int mpu_waitready(struct mpu_softc *);
   83 void    mpu_readinput(struct mpu_softc *);
   84 
   85 int     mpu_open __P((void *, int, 
   86                          void (*iintr)__P((void *, int)),
   87                          void (*ointr)__P((void *)), void *arg));
   88 void    mpu_close __P((void *));
   89 int     mpu_output __P((void *, int));
   90 void    mpu_getinfo __P((void *, struct midi_info *));
   91 
   92 struct midi_hw_if mpu_midi_hw_if = {
   93         mpu_open,
   94         mpu_close,
   95         mpu_output,
   96         mpu_getinfo,
   97         0,                      /* ioctl */
   98 };
   99 
  100 int
  101 mpu_find(sc)
  102         struct mpu_softc *sc;
  103 {
  104         if (MPU_GETSTATUS(sc->iot, sc->ioh) == 0xff) {
  105                 DPRINTF(("mpu_find: No status\n"));
  106                 goto bad;
  107         }
  108         sc->open = 0;
  109         sc->intr = 0;
  110         if (mpu_reset(sc) == 0)
  111                 return 1;
  112 bad:
  113         return 0;
  114 }
  115 
  116 void
  117 mpu_attach(sc)
  118         struct mpu_softc *sc;
  119 {
  120         printf("\n");
  121 
  122         midi_attach_mi(&mpu_midi_hw_if, sc, &sc->sc_dev);
  123 }
  124 
  125 static __inline int
  126 mpu_waitready(sc)
  127         struct mpu_softc *sc;
  128 {
  129         int i;
  130 
  131         for(i = 0; i < MPU_MAXWAIT; i++) {
  132                 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY))
  133                         return 0;
  134                 delay(10);
  135         }
  136         return 1;
  137 }
  138 
  139 int
  140 mpu_reset(sc)
  141         struct mpu_softc *sc;
  142 {
  143         bus_space_tag_t iot = sc->iot;
  144         bus_space_handle_t ioh = sc->ioh;
  145         int i;
  146         int s;
  147 
  148         if (mpu_waitready(sc)) {
  149                 DPRINTF(("mpu_reset: not ready\n"));
  150                 return EIO;
  151         }
  152         s = splaudio();         /* Don't let the interrupt get our ACK. */
  153         bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET);
  154         for(i = 0; i < 2*MPU_MAXWAIT; i++) {
  155                 if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) &&
  156                     bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) {
  157                         splx(s);
  158                         return 0;
  159                 }
  160         }
  161         splx(s);
  162         DPRINTF(("mpu_reset: No ACK\n"));
  163         return EIO;
  164 }
  165 
  166 int
  167 mpu_open(addr, flags, iintr, ointr, arg)
  168         void *addr;
  169         int flags;
  170         void (*iintr)__P((void *, int));
  171         void (*ointr)__P((void *));
  172         void *arg;
  173 {
  174         struct mpu_softc *sc = addr;
  175 
  176         DPRINTF(("mpu_open: sc=%p\n", sc));
  177 
  178         if (sc->open)
  179                 return EBUSY;
  180 #ifndef AUDIO_NO_POWER_CTL
  181         if (sc->powerctl)
  182                 sc->powerctl(sc->powerarg, 1);
  183 #endif
  184         if (mpu_reset(sc) != 0) {
  185 #ifndef AUDIO_NO_POWER_CTL
  186                 if (sc->powerctl)
  187                         sc->powerctl(sc->powerarg, 0);
  188 #endif
  189                 return EIO;
  190         }
  191 
  192         bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE);
  193         sc->open = 1;
  194         sc->intr = iintr;
  195         sc->arg = arg;
  196         return 0;
  197 }
  198 
  199 void
  200 mpu_close(addr)
  201         void *addr;
  202 {
  203         struct mpu_softc *sc = addr;
  204 
  205         DPRINTF(("mpu_close: sc=%p\n", sc));
  206 
  207         sc->open = 0;
  208         sc->intr = 0;
  209         mpu_reset(sc); /* exit UART mode */
  210 
  211 #ifndef AUDIO_NO_POWER_CTL
  212         if (sc->powerctl)
  213                 sc->powerctl(sc->powerarg, 0);
  214 #endif
  215 }
  216 
  217 void
  218 mpu_readinput(sc)
  219         struct mpu_softc *sc;
  220 {
  221         bus_space_tag_t iot = sc->iot;
  222         bus_space_handle_t ioh = sc->ioh;
  223         int data;
  224 
  225         while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) {
  226                 data = bus_space_read_1(iot, ioh, MPU_DATA);
  227                 DPRINTFN(3, ("mpu_rea: sc=%p 0x%02x\n", sc, data));
  228                 if (sc->intr)
  229                         sc->intr(sc->arg, data);
  230         }
  231 }
  232 
  233 int
  234 mpu_output(addr, d)
  235         void *addr;
  236         int d;
  237 {
  238         struct mpu_softc *sc = addr;
  239         int s;
  240 
  241         DPRINTFN(3, ("mpu_output: sc=%p 0x%02x\n", sc, d));
  242         if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) {
  243                 s = splaudio();
  244                 mpu_readinput(sc);
  245                 splx(s);
  246         }
  247         if (mpu_waitready(sc)) {
  248                 DPRINTF(("mpu_output: not ready\n"));
  249                 return EIO;
  250         }
  251         bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d);
  252         return 0;
  253 }
  254 
  255 void
  256 mpu_getinfo(addr, mi)
  257         void *addr;
  258         struct midi_info *mi;
  259 {
  260         struct mpu_softc *sc = addr;
  261 
  262         mi->name = sc->model;
  263         mi->props = 0;
  264 }
  265 
  266 int
  267 mpu_intr(addr)
  268         void *addr;
  269 {
  270         struct mpu_softc *sc = addr;
  271 
  272         if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) {
  273                 DPRINTF(("mpu_intr: no data\n"));
  274                 return (0);
  275         } else {
  276                 mpu_readinput(sc);
  277                 return (1);
  278         }
  279 }

Cache object: 75fbf48435446d80267e383d05617655


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.