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.10 2005/02/27 00:27:02 perry 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.10 2005/02/27 00:27:02 perry 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(void *, int,
   86                          void (*iintr)(void *, int),
   87                          void (*ointr)(void *), void *arg);
   88 void    mpu_close(void *);
   89 int     mpu_output(void *, int);
   90 void    mpu_getinfo(void *, struct midi_info *);
   91 
   92 const 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         midi_attach_mi(&mpu_midi_hw_if, sc, &sc->sc_dev);
  121 }
  122 
  123 static __inline int
  124 mpu_waitready(sc)
  125         struct mpu_softc *sc;
  126 {
  127         int i;
  128 
  129         for(i = 0; i < MPU_MAXWAIT; i++) {
  130                 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY))
  131                         return 0;
  132                 delay(10);
  133         }
  134         return 1;
  135 }
  136 
  137 int
  138 mpu_reset(sc)
  139         struct mpu_softc *sc;
  140 {
  141         bus_space_tag_t iot = sc->iot;
  142         bus_space_handle_t ioh = sc->ioh;
  143         int i;
  144         int s;
  145 
  146         if (mpu_waitready(sc)) {
  147                 DPRINTF(("mpu_reset: not ready\n"));
  148                 return EIO;
  149         }
  150         s = splaudio();         /* Don't let the interrupt get our ACK. */
  151         bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET);
  152         for(i = 0; i < 2*MPU_MAXWAIT; i++) {
  153                 if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) &&
  154                     bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) {
  155                         splx(s);
  156                         return 0;
  157                 }
  158         }
  159         splx(s);
  160         DPRINTF(("mpu_reset: No ACK\n"));
  161         return EIO;
  162 }
  163 
  164 int
  165 mpu_open(addr, flags, iintr, ointr, arg)
  166         void *addr;
  167         int flags;
  168         void (*iintr)(void *, int);
  169         void (*ointr)(void *);
  170         void *arg;
  171 {
  172         struct mpu_softc *sc = addr;
  173 
  174         DPRINTF(("mpu_open: sc=%p\n", sc));
  175 
  176         if (sc->open)
  177                 return EBUSY;
  178 #ifndef AUDIO_NO_POWER_CTL
  179         if (sc->powerctl)
  180                 sc->powerctl(sc->powerarg, 1);
  181 #endif
  182         if (mpu_reset(sc) != 0) {
  183 #ifndef AUDIO_NO_POWER_CTL
  184                 if (sc->powerctl)
  185                         sc->powerctl(sc->powerarg, 0);
  186 #endif
  187                 return EIO;
  188         }
  189 
  190         bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE);
  191         sc->open = 1;
  192         sc->intr = iintr;
  193         sc->arg = arg;
  194         return 0;
  195 }
  196 
  197 void
  198 mpu_close(addr)
  199         void *addr;
  200 {
  201         struct mpu_softc *sc = addr;
  202 
  203         DPRINTF(("mpu_close: sc=%p\n", sc));
  204 
  205         sc->open = 0;
  206         sc->intr = 0;
  207         mpu_reset(sc); /* exit UART mode */
  208 
  209 #ifndef AUDIO_NO_POWER_CTL
  210         if (sc->powerctl)
  211                 sc->powerctl(sc->powerarg, 0);
  212 #endif
  213 }
  214 
  215 void
  216 mpu_readinput(sc)
  217         struct mpu_softc *sc;
  218 {
  219         bus_space_tag_t iot = sc->iot;
  220         bus_space_handle_t ioh = sc->ioh;
  221         int data;
  222 
  223         while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) {
  224                 data = bus_space_read_1(iot, ioh, MPU_DATA);
  225                 DPRINTFN(3, ("mpu_rea: sc=%p 0x%02x\n", sc, data));
  226                 if (sc->intr)
  227                         sc->intr(sc->arg, data);
  228         }
  229 }
  230 
  231 int
  232 mpu_output(addr, d)
  233         void *addr;
  234         int d;
  235 {
  236         struct mpu_softc *sc = addr;
  237         int s;
  238 
  239         DPRINTFN(3, ("mpu_output: sc=%p 0x%02x\n", sc, d));
  240         if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) {
  241                 s = splaudio();
  242                 mpu_readinput(sc);
  243                 splx(s);
  244         }
  245         if (mpu_waitready(sc)) {
  246                 DPRINTF(("mpu_output: not ready\n"));
  247                 return EIO;
  248         }
  249         bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d);
  250         return 0;
  251 }
  252 
  253 void
  254 mpu_getinfo(addr, mi)
  255         void *addr;
  256         struct midi_info *mi;
  257 {
  258         struct mpu_softc *sc = addr;
  259 
  260         mi->name = sc->model;
  261         mi->props = 0;
  262 }
  263 
  264 int
  265 mpu_intr(addr)
  266         void *addr;
  267 {
  268         struct mpu_softc *sc = addr;
  269 
  270         if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) {
  271                 DPRINTF(("mpu_intr: no data\n"));
  272                 return (0);
  273         } else {
  274                 mpu_readinput(sc);
  275                 return (1);
  276         }
  277 }

Cache object: 57630a9113572f9d7d9fc96509c85af8


[ 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.