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/isa/cec.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: cec.c,v 1.1 2003/06/02 03:57:15 gmcgarry Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2003 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Gregory McGarry.
    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: cec.c,v 1.1 2003/06/02 03:57:15 gmcgarry Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/callout.h>
   45 #include <sys/conf.h>
   46 #include <sys/device.h>
   47 #include <sys/kernel.h>
   48 
   49 #include <machine/bus.h>
   50 
   51 #include <dev/isa/isavar.h>
   52 #include <dev/isa/isadmavar.h>
   53 
   54 #include <dev/gpib/gpibvar.h>
   55 
   56 #include <dev/ic/nec7210reg.h>
   57 
   58 #define DEBUG
   59 
   60 #ifdef DEBUG
   61 int cecdebug = 0x1f;
   62 #define DPRINTF(flag, str)      if (cecdebug & (flag)) printf str
   63 #define DBG_FOLLOW      0x01
   64 #define DBG_CONFIG      0x02
   65 #define DBG_INTR        0x04
   66 #define DBG_REPORTTIME  0x08
   67 #define DBG_FAIL        0x10
   68 #define DBG_WAIT        0x20
   69 #else
   70 #define DPRINTF(flag, str)      /* nothing */
   71 #endif
   72 
   73 #define CEC_IOSIZE      8
   74 
   75 struct cec_softc {
   76         struct device sc_dev;           /* generic device glue */
   77 
   78         bus_space_tag_t sc_iot;
   79         bus_space_handle_t sc_ioh;
   80         isa_chipset_tag_t sc_ic;
   81         int sc_drq;
   82         void *sc_ih;
   83 
   84         int sc_myaddr;                  /* my address */
   85         struct gpib_softc *sc_gpib;
   86 
   87         volatile int sc_flags;
   88 #define CECF_IO         0x1
   89 #define CECF_PPOLL      0x4
   90 #define CECF_READ       0x8
   91 #define CECF_TIMO       0x10
   92 #define CECF_USEDMA     0x20
   93         int sc_ppoll_slave;             /* XXX stash our ppoll address */
   94         struct callout sc_timeout_ch;
   95 };
   96 
   97 int     cecprobe(struct device *, struct cfdata *, void *);
   98 void    cecattach(struct device *, struct device *, void *);
   99 
  100 CFATTACH_DECL(cec, sizeof(struct cec_softc),
  101         cecprobe, cecattach, NULL, NULL);
  102 
  103 void    cecreset(void *); 
  104 int     cecpptest(void *, int);
  105 void    cecppwatch(void *, int);
  106 void    cecppclear(void *);
  107 void    cecxfer(void *, int, int, void *, int, int, int);
  108 void    cecgo(void *v);
  109 int     cecintr(void *);
  110 int     cecsendcmds(void *, void *, int);
  111 int     cecsenddata(void *, void *, int);
  112 int     cecrecvdata(void *, void *, int);
  113 int     cecgts(void *);
  114 int     cectc(void *, int);
  115 void    cecifc(void *);
  116 
  117 static int      cecwait(struct cec_softc *, int, int);
  118 static void     cectimeout(void *v);
  119 static int      nec7210_setaddress(struct cec_softc *, int, int);
  120 static void     nec7210_init(struct cec_softc *);
  121 static void     nec7210_ifc(struct cec_softc *);
  122 
  123 /*
  124  * Our chipset structure.
  125  */
  126 struct gpib_chipset_tag cec_ic = {
  127         cecreset,
  128         NULL,
  129         NULL,
  130         cecpptest,
  131         cecppwatch,
  132         cecppclear,
  133         cecxfer,
  134         cectc,
  135         cecgts,
  136         cecifc,
  137         cecsendcmds,
  138         cecsenddata,
  139         cecrecvdata
  140 };
  141 
  142 int cecwtimeout = 0x10000;
  143 int cecdmathresh = 3;
  144 
  145 int
  146 cecprobe(struct device *parent, struct cfdata *match, void *aux)
  147 {
  148         struct isa_attach_args *ia = aux;
  149         bus_space_tag_t iot = ia->ia_iot;
  150         bus_space_handle_t ioh;
  151 
  152         DPRINTF(DBG_CONFIG, ("cecprobe: called\n"));
  153 
  154         if (ia->ia_nio < 1)
  155                 return (0);
  156         if (ia->ia_nirq < 1)
  157                 return (0);
  158         if (ia->ia_ndrq < 1)
  159                 return (0);
  160 
  161         if (ISA_DIRECT_CONFIG(ia))
  162                 return (0);
  163 
  164         if (ia->ia_io[0].ir_addr == ISACF_PORT_DEFAULT)
  165                 return (0);
  166 
  167         if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq == ISACF_DRQ_DEFAULT)
  168                 ia->ia_ndrq = 0;
  169 
  170         if (bus_space_map(iot, ia->ia_io[0].ir_addr, CEC_IOSIZE, 0, &ioh))
  171                 return (0);
  172 
  173         /* XXX insert probe here */
  174 
  175         ia->ia_io[0].ir_size = CEC_IOSIZE;
  176         ia->ia_niomem = 0;
  177 
  178         bus_space_unmap(iot, ioh, CEC_IOSIZE);
  179 
  180         return (1);
  181 }
  182 
  183 void
  184 cecattach(struct device *parent, struct device *self, void *aux)
  185 {
  186         struct cec_softc *sc = (struct cec_softc *)self;
  187         struct isa_attach_args *ia = aux;
  188         struct gpibdev_attach_args ga;
  189         bus_size_t maxsize;
  190 
  191         printf("\n");
  192 
  193         DPRINTF(DBG_CONFIG, ("cecattach: called\n"));
  194 
  195         sc->sc_iot = ia->ia_iot;
  196         sc->sc_ic = ia->ia_ic;
  197 
  198         if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CEC_IOSIZE,
  199             0, &sc->sc_ioh) != 0) {
  200                 printf("%s: unable to map I/O space\n", sc->sc_dev.dv_xname);
  201                 return;
  202         }
  203 
  204         if (ia->ia_ndrq > 0) {
  205                 sc->sc_flags |= CECF_USEDMA;
  206                 sc->sc_drq = ia->ia_drq[0].ir_drq;
  207 
  208                 (void) isa_drq_alloc(sc->sc_ic, sc->sc_drq);
  209                 maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
  210                 if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
  211                     maxsize, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW)) {
  212                         printf("%s: unable to create map for drq %d\n",
  213                             sc->sc_dev.dv_xname, sc->sc_drq);
  214                         sc->sc_flags &= ~CECF_USEDMA;
  215                 }
  216         }
  217 
  218         sc->sc_myaddr = 15;             /* XXX */
  219 
  220         cecreset(sc);
  221         (void) nec7210_setaddress(sc, sc->sc_myaddr, -1);
  222 
  223         sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  224             IST_EDGE, IPL_BIO, cecintr, sc);
  225         if (sc->sc_ih == NULL) {
  226                 printf("%s: couldn't establish interrupt\n",
  227                     sc->sc_dev.dv_xname);
  228                 return;
  229         }
  230 
  231         callout_init(&sc->sc_timeout_ch);
  232 
  233         /* attach MI GPIB bus */
  234         cec_ic.cookie = (void *)sc;
  235         ga.ga_ic = &cec_ic;
  236         ga.ga_address = sc->sc_myaddr;
  237         sc->sc_gpib =
  238             (struct gpib_softc *)config_found(self, &ga, gpibdevprint);
  239 }
  240 
  241 int
  242 cecintr(void *v)
  243 {
  244         struct cec_softc *sc = v;
  245         bus_space_tag_t iot = sc->sc_iot;
  246         bus_space_handle_t ioh = sc->sc_ioh;
  247         u_int8_t stat1, stat2;
  248 
  249         stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
  250         stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
  251 
  252         DPRINTF(DBG_INTR, ("cecintr: sc=%p stat1=0x%x stat2=0x%x\n",
  253             sc, stat1, stat2));
  254 
  255         if (sc->sc_flags & CECF_IO) {
  256 
  257                 if (sc->sc_flags & CECF_TIMO)
  258                         callout_stop(&sc->sc_timeout_ch);
  259 
  260                 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
  261                 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
  262                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
  263                 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
  264                 if (sc->sc_flags & CECF_USEDMA)
  265                         isa_dmadone(sc->sc_ic, sc->sc_drq);
  266                 gpibintr(sc->sc_gpib);
  267 
  268         } else if (sc->sc_flags & CECF_PPOLL) {
  269 
  270                 if (cecpptest(sc, sc->sc_ppoll_slave)) {
  271                         sc->sc_flags &= ~CECF_PPOLL;
  272                         bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
  273                         gpibintr(sc->sc_gpib);
  274                 }
  275 
  276         }
  277         return (1);
  278 }
  279 
  280 void
  281 cecreset(void *v)
  282 {
  283         struct cec_softc *sc = v;
  284         u_int8_t cmd;
  285 
  286         DPRINTF(DBG_FOLLOW, ("cecreset: sc=%p\n", sc));
  287 
  288         nec7210_init(sc);
  289         nec7210_ifc(sc);
  290         /* we're now the system controller */
  291 
  292         /* XXX should be pushed higher */
  293 
  294         /* universal device clear */
  295         cmd = GPIBCMD_DCL;
  296         (void) cecsendcmds(sc, &cmd, 1);
  297         /* delay for devices to clear */
  298         DELAY(100000);
  299 }
  300 
  301 int
  302 cecsendcmds(void *v, void *ptr, int origcnt)
  303 {
  304         struct cec_softc *sc = v;
  305         bus_space_tag_t iot = sc->sc_iot;
  306         bus_space_handle_t ioh = sc->sc_ioh;
  307         int cnt = origcnt;
  308         u_int8_t *addr = ptr;
  309 
  310         DPRINTF(DBG_FOLLOW, ("cecsendcmds: sc=%p, ptr=%p cnt=%d\n",
  311             sc, ptr, origcnt));
  312 
  313         while (--cnt >= 0) {
  314                 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
  315                 if (cecwait(sc, 0, ISR2_CO))
  316                         return (origcnt - cnt - 1);
  317         }
  318         return (origcnt);
  319 }
  320 
  321 
  322 int
  323 cecrecvdata(void *v, void *ptr, int origcnt)
  324 {
  325         struct cec_softc *sc = v;
  326         bus_space_tag_t iot = sc->sc_iot;
  327         bus_space_handle_t ioh = sc->sc_ioh;
  328         int cnt = origcnt;
  329         u_int8_t *addr = ptr;
  330 
  331         DPRINTF(DBG_FOLLOW, ("cecrecvdata: sc=%p, ptr=%p cnt=%d\n",
  332             sc, ptr, origcnt));
  333 
  334         /* XXX holdoff on end */
  335         bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_AUXMR, AUXCMD_RHDF);
  336 
  337         if (cnt) {
  338                 while (--cnt >= 0) {
  339                         if (cecwait(sc, ISR1_DI, 0))
  340                                 return (origcnt - cnt - 1);
  341                         *addr++ = bus_space_read_1(iot, ioh, NEC7210_DIR);
  342                 }
  343         }
  344         return (origcnt);
  345 }
  346 
  347 int
  348 cecsenddata(void *v, void *ptr, int origcnt)
  349 {
  350         struct cec_softc *sc = v;
  351         bus_space_tag_t iot = sc->sc_iot;
  352         bus_space_handle_t ioh = sc->sc_ioh;
  353         int cnt = origcnt;
  354         u_int8_t *addr = ptr;
  355 
  356         DPRINTF(DBG_FOLLOW, ("cecdsenddata: sc=%p, ptr=%p cnt=%d\n",
  357             sc, ptr, origcnt));
  358 
  359         if (cnt) {
  360                 while (--cnt > 0) {
  361                         bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
  362                         if (cecwait(sc, ISR1_DO, 0))
  363                                 return (origcnt - cnt - 1);
  364                 }
  365                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
  366                 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr);       
  367                 (void) cecwait(sc, ISR1_DO, 0);
  368         }
  369         return (origcnt);
  370 }
  371 
  372 int
  373 cectc(void *v, int sync)
  374 {
  375         struct cec_softc *sc = v;
  376         bus_space_tag_t iot = sc->sc_iot;
  377         bus_space_handle_t ioh = sc->sc_ioh;
  378         u_int8_t adsr;
  379         int timo = cecwtimeout;
  380 
  381         DPRINTF(DBG_FOLLOW, ("cectc: sc=%p, sync=%d\n", sc, sync));
  382 
  383         adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
  384 #if 0
  385         if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_CIC) {
  386                 DPRINTF(0xff, ("cectc: already CIC\n"));
  387                 return (0);
  388         }
  389 #endif
  390 
  391         if (sync) {
  392                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_RHDF);
  393                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCS);
  394         } else {
  395                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
  396         }
  397 
  398         /* wait until ATN is asserted */
  399         for (;;) {
  400                 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
  401                 if (--timo == 0) {
  402                         DPRINTF(DBG_REPORTTIME, ("cectc: timeout\n"));
  403                         return (1);
  404                 }
  405                 if ((adsr & ADSR_NATN) == 0)
  406                         break;
  407                 DELAY(1);
  408         }
  409 
  410         return (0);
  411 }
  412 
  413 int
  414 cecgts(void *v)
  415 {
  416         struct cec_softc *sc = v;
  417         bus_space_tag_t iot = sc->sc_iot;
  418         bus_space_handle_t ioh = sc->sc_ioh;
  419         u_int8_t adsr;
  420         int timo = cecwtimeout;
  421 
  422         DPRINTF(DBG_FOLLOW, ("cecgts: sc=%p\n", sc));
  423 
  424         adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
  425 #if 0
  426         if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_NATN) {
  427                 DPRINTF(0xff, ("cecgts: already standby\n"));
  428                 return (0);
  429         }
  430 #endif
  431 
  432         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_GTS);
  433 
  434         /* wait unit ATN is released */
  435         for (;;) {
  436                 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
  437                 if (--timo == 0) {
  438                         DPRINTF(DBG_REPORTTIME, ("cecgts: timeout\n"));
  439                         return (1);
  440                 }
  441                 if ((adsr & ADSR_NATN) == ADSR_NATN)
  442                         break;
  443                 DELAY(1);
  444         }
  445 
  446         return (0);
  447 }
  448 
  449 int
  450 cecpptest(void *v, int slave)
  451 {
  452         struct cec_softc *sc = v;
  453         bus_space_tag_t iot = sc->sc_iot;
  454         bus_space_handle_t ioh = sc->sc_ioh;
  455         int ppoll;
  456 
  457         DPRINTF(DBG_FOLLOW, ("cecpptest: sc=%p slave=%d\n", sc, slave));
  458 
  459         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
  460         DELAY(25);
  461         ppoll = bus_space_read_1(iot, ioh, NEC7210_CPTR);
  462         DPRINTF(0xff, ("cecpptest: ppoll=%x\n", ppoll));
  463         return ((ppoll & (0x80 >> slave)) != 0);
  464 }
  465 
  466 void
  467 cecppwatch(void *v, int slave)
  468 {
  469         struct cec_softc *sc = v;
  470         bus_space_tag_t iot = sc->sc_iot;
  471         bus_space_handle_t ioh = sc->sc_ioh;
  472 
  473         DPRINTF(DBG_FOLLOW, ("cecppwatch: sc=%p\n", sc));
  474 
  475         sc->sc_flags |= CECF_PPOLL;
  476         sc->sc_ppoll_slave = slave;
  477         bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
  478         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
  479 }
  480 
  481 void
  482 cecppclear(void *v)
  483 {
  484         struct cec_softc *sc = v;
  485 
  486         DPRINTF(DBG_FOLLOW, ("cecppclear: sc=%p\n", sc));
  487 
  488         sc->sc_flags &= ~CECF_PPOLL;
  489         bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_IMR2, 0);
  490 }
  491 
  492 void
  493 cecxfer(void *v, int slave, int sec, void *buf, int count, int dir, int timo)
  494 {
  495         struct cec_softc *sc = v;
  496         bus_space_tag_t iot = sc->sc_iot;
  497         bus_space_handle_t ioh = sc->sc_ioh;
  498 
  499         DPRINTF(DBG_FOLLOW,
  500             ("cecxfer: slave=%d sec=%d buf=%p count=%d dir=%x timo=%d\n",
  501             slave, sec, buf, count, dir, timo));
  502 
  503         sc->sc_flags |= CECF_IO;
  504         if (dir == GPIB_READ)
  505                 sc->sc_flags |= CECF_READ;
  506         if (timo) {
  507                 sc->sc_flags |= CECF_TIMO;
  508                 callout_reset(&sc->sc_timeout_ch, 5*hz, cectimeout, sc);
  509         }
  510 
  511         if (sc->sc_flags & CECF_READ) {
  512                 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA read request\n"));
  513                 if ((sc->sc_flags & CECF_USEDMA) != 0) {
  514                         isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count, NULL,
  515                             DMAMODE_READ | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
  516                         bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAI);
  517                         bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
  518                         // XXX (void) cecrecv(sc, slave, sec, NULL, 0);
  519                         (void) gpibrecv(&cec_ic, slave, sec, NULL, 0);
  520                 } else {
  521                         /* XXX this doesn't work */
  522                         DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
  523                         bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
  524                         // XXX (void) cecrecv(sc, slave, sec, buf, count);
  525                         (void) gpibrecv(&cec_ic, slave, sec, buf, count);
  526                         bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
  527                 }
  528         } else {
  529                 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA write request\n"));
  530                 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
  531                 if (count < cecdmathresh ||
  532                     (sc->sc_flags & CECF_USEDMA) == 0) {
  533                         DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
  534                         // XXX (void) cecsend(sc, slave, sec, buf, count);
  535                         (void) gpibsend(&cec_ic, slave, sec, buf, count);
  536                         bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
  537                         return;
  538                 }
  539                 /* we send the last byte with EOI set */
  540                 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count-1, NULL,
  541                     DMAMODE_WRITE | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
  542                 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAO);
  543                 // XXX (void) cecsend(sc, slave, sec, NULL, 0);
  544                 (void) gpibsend(&cec_ic, slave, sec, NULL, 0);
  545                 while (!isa_dmafinished(sc->sc_ic, sc->sc_drq))
  546                         DELAY(1);
  547                 (void) cecwait(sc, ISR1_DO, 0);
  548                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
  549                 bus_space_write_1(iot, ioh, NEC7210_CDOR, *(char *)buf+count);
  550                 /* generate interrupt */
  551                 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_DO);
  552         }
  553 }
  554 
  555 void
  556 cecifc(void *v)
  557 {
  558         struct cec_softc *sc = v;
  559 
  560         nec7210_ifc(sc);
  561 }
  562 
  563 static int
  564 nec7210_setaddress(struct cec_softc *sc, int pri, int sec)
  565 {
  566         bus_space_tag_t iot = sc->sc_iot;
  567         bus_space_handle_t ioh = sc->sc_ioh;
  568         u_int8_t admr;
  569 
  570         /* assign our primary address */
  571         bus_space_write_1(iot, ioh, NEC7210_ADDR, (pri & ADDR_MASK));
  572 
  573         admr = ADMR_TRM0 | ADMR_TRM1;
  574 
  575         /* assign our secondary address */
  576         if (sec != -1) {
  577                 bus_space_write_1(iot, ioh, NEC7210_ADDR,
  578                     (ADDR_ARS | (sec & ADDR_MASK)));
  579                 admr |= ADMR_ADM1;
  580         } else {
  581                 /* disable secondary address */
  582                 bus_space_write_1(iot, ioh, NEC7210_ADDR,
  583                     (ADDR_ARS | ADDR_DT | ADDR_DL));
  584                 admr |= ADMR_ADM0;
  585         }
  586         bus_space_write_1(iot, ioh, NEC7210_ADMR, admr);
  587 
  588         return (0);
  589 }
  590 
  591 static void
  592 nec7210_init(struct cec_softc *sc)
  593 {
  594         bus_space_tag_t iot = sc->sc_iot;
  595         bus_space_handle_t ioh = sc->sc_ioh;
  596 
  597         /* reset chip */
  598         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CRST);
  599 
  600         /* clear interrupts */
  601         bus_space_read_1(iot, ioh, NEC7210_CPTR);
  602         bus_space_read_1(iot, ioh, NEC7210_ISR1);
  603         bus_space_read_1(iot, ioh, NEC7210_ISR2);
  604 
  605         /* initialise interrupts */
  606         bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
  607         bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
  608         bus_space_write_1(iot, ioh, NEC7210_SPMR, 0);
  609         bus_space_write_1(iot, ioh, NEC7210_EOSR, 0);
  610 
  611         /* set internal clock to 8MHz */
  612         bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_ICR | 0x8));
  613         /* parallel poll unconfigure */
  614         bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_PPOLL | PPOLL_PPU));
  615 
  616         /* assign our address */
  617         bus_space_write_1(iot, ioh, NEC7210_ADDR, 0);
  618         /* disable secondary address */
  619         bus_space_write_1(iot, ioh, NEC7210_ADDR,
  620             (ADDR_ARS | ADDR_DT | ADDR_DL));
  621 
  622         /* setup transceivers */
  623         bus_space_write_1(iot, ioh, NEC7210_ADMR,
  624             (ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1));
  625         bus_space_write_1(iot, ioh, NEC7210_AUXMR,
  626             (AUXMR_REGA | AUX_A_HSNORM));
  627 
  628         /* set INT pin to active high */
  629         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGB);
  630         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGE);
  631 
  632         /* holdoff on end condition */
  633         bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_REGA | AUX_A_HLDE));
  634 
  635         /* reconnect to bus */
  636         bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_CMD | AUXCMD_IEPON));
  637 }
  638 
  639 /*
  640  * Place all devices on the bus into quiescient state ready for
  641  * remote programming.
  642  * Obviously, we're the system controller upon exit.
  643  */
  644 void
  645 nec7210_ifc(struct cec_softc *sc)
  646 {
  647         bus_space_tag_t iot = sc->sc_iot;
  648         bus_space_handle_t ioh = sc->sc_ioh;
  649 
  650 /*XXX*/ bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
  651         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CREN);
  652         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SIFC);
  653         /* wait for devices to enter quiescient state */
  654         DELAY(100);
  655         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CIFC);
  656         bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SREN);
  657 }
  658 
  659 static int
  660 cecwait(struct cec_softc *sc, int x1, int x2)
  661 {
  662         int timo = cecwtimeout;
  663         bus_space_tag_t iot = sc->sc_iot;
  664         bus_space_handle_t ioh = sc->sc_ioh;
  665         u_int8_t stat1, stat2;
  666 
  667         DPRINTF(DBG_WAIT, ("cecwait: sc=%p, x1=0x%x x2=0x%x\n", sc, x1, x2));
  668 
  669         for (;;) {
  670                 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
  671                 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
  672 #if 0
  673                 if ((stat1 & ISR1_ERR)) {
  674                         DPRINTF(DBG_WAIT, ("cecwait: got ERR\n"));
  675                         return (1);
  676                 }
  677 #endif
  678                 if (--timo == 0) {
  679                         DPRINTF(DBG_REPORTTIME,
  680                             ("cecwait: timeout x1=0x%x x2=0x%x\n", x1, x2));
  681                         return (1);
  682                 }
  683                 if ((stat1 & x1) || (stat2 & x2))
  684                         break;
  685                 DELAY(1);
  686         }
  687         return (0);
  688 }
  689 
  690 static void
  691 cectimeout(void *v)
  692 {
  693         struct cec_softc *sc = v;
  694         bus_space_tag_t iot = sc->sc_iot;
  695         bus_space_handle_t ioh = sc->sc_ioh;
  696         int s;
  697 
  698         DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc));
  699 
  700         s = splbio();
  701         if (sc->sc_flags & CECF_IO) {
  702                 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
  703                 bus_space_write_2(iot, ioh, NEC7210_IMR2, 0);
  704                 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
  705                 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
  706                 isa_dmaabort(sc->sc_ic, sc->sc_drq);
  707                 printf("%s: %s timeout\n", sc->sc_dev.dv_xname,
  708                     sc->sc_flags & CECF_READ ? "read" : "write");
  709                 gpibintr(sc->sc_gpib);
  710         }
  711         splx(s);
  712 }

Cache object: 8a3203f2051aec7f4c43f35ae2e314d9


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