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.14 2006/11/16 01:32:51 christos 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.14 2006/11/16 01:32:51 christos 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(void *addr, int flags, void (*iintr)(void *, int),
  166     void (*ointr)(void *), void *arg)
  167 {
  168         struct mpu_softc *sc = addr;
  169 
  170         DPRINTF(("mpu_open: sc=%p\n", sc));
  171 
  172         if (sc->open)
  173                 return EBUSY;
  174 #ifndef AUDIO_NO_POWER_CTL
  175         if (sc->powerctl)
  176                 sc->powerctl(sc->powerarg, 1);
  177 #endif
  178         if (mpu_reset(sc) != 0) {
  179 #ifndef AUDIO_NO_POWER_CTL
  180                 if (sc->powerctl)
  181                         sc->powerctl(sc->powerarg, 0);
  182 #endif
  183                 return EIO;
  184         }
  185 
  186         bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE);
  187         sc->open = 1;
  188         sc->intr = iintr;
  189         sc->arg = arg;
  190         return 0;
  191 }
  192 
  193 void
  194 mpu_close(addr)
  195         void *addr;
  196 {
  197         struct mpu_softc *sc = addr;
  198 
  199         DPRINTF(("mpu_close: sc=%p\n", sc));
  200 
  201         sc->open = 0;
  202         sc->intr = 0;
  203         mpu_reset(sc); /* exit UART mode */
  204 
  205 #ifndef AUDIO_NO_POWER_CTL
  206         if (sc->powerctl)
  207                 sc->powerctl(sc->powerarg, 0);
  208 #endif
  209 }
  210 
  211 void
  212 mpu_readinput(sc)
  213         struct mpu_softc *sc;
  214 {
  215         bus_space_tag_t iot = sc->iot;
  216         bus_space_handle_t ioh = sc->ioh;
  217         int data;
  218 
  219         while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) {
  220                 data = bus_space_read_1(iot, ioh, MPU_DATA);
  221                 DPRINTFN(3, ("mpu_rea: sc=%p 0x%02x\n", sc, data));
  222                 if (sc->intr)
  223                         sc->intr(sc->arg, data);
  224         }
  225 }
  226 
  227 int
  228 mpu_output(addr, d)
  229         void *addr;
  230         int d;
  231 {
  232         struct mpu_softc *sc = addr;
  233         int s;
  234 
  235         DPRINTFN(3, ("mpu_output: sc=%p 0x%02x\n", sc, d));
  236         if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) {
  237                 s = splaudio();
  238                 mpu_readinput(sc);
  239                 splx(s);
  240         }
  241         if (mpu_waitready(sc)) {
  242                 DPRINTF(("mpu_output: not ready\n"));
  243                 return EIO;
  244         }
  245         bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d);
  246         return 0;
  247 }
  248 
  249 void
  250 mpu_getinfo(addr, mi)
  251         void *addr;
  252         struct midi_info *mi;
  253 {
  254         struct mpu_softc *sc = addr;
  255 
  256         mi->name = sc->model;
  257         mi->props = 0;
  258 }
  259 
  260 int
  261 mpu_intr(addr)
  262         void *addr;
  263 {
  264         struct mpu_softc *sc = addr;
  265 
  266         if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) {
  267                 DPRINTF(("mpu_intr: no data\n"));
  268                 return (0);
  269         } else {
  270                 mpu_readinput(sc);
  271                 return (1);
  272         }
  273 }

Cache object: a0c65bbbcc80b6f6f090f4afe4dab37e


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