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/ad1848_isa.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: ad1848_isa.c,v 1.23 2003/05/09 23:51:28 fvdl Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Ken Hornstein and John Kohl.
    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  * Copyright (c) 1994 John Brezak
   40  * Copyright (c) 1991-1993 Regents of the University of California.
   41  * All rights reserved.
   42  *
   43  * Redistribution and use in source and binary forms, with or without
   44  * modification, are permitted provided that the following conditions
   45  * are met:
   46  * 1. Redistributions of source code must retain the above copyright
   47  *    notice, this list of conditions and the following disclaimer.
   48  * 2. Redistributions in binary form must reproduce the above copyright
   49  *    notice, this list of conditions and the following disclaimer in the
   50  *    documentation and/or other materials provided with the distribution.
   51  * 3. All advertising materials mentioning features or use of this software
   52  *    must display the following acknowledgement:
   53  *      This product includes software developed by the Computer Systems
   54  *      Engineering Group at Lawrence Berkeley Laboratory.
   55  * 4. Neither the name of the University nor of the Laboratory may be used
   56  *    to endorse or promote products derived from this software without
   57  *    specific prior written permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   69  * SUCH DAMAGE.
   70  *
   71  */
   72 
   73 /*
   74  * Copyright by Hannu Savolainen 1994
   75  *
   76  * Redistribution and use in source and binary forms, with or without
   77  * modification, are permitted provided that the following conditions are
   78  * met: 1. Redistributions of source code must retain the above copyright
   79  * notice, this list of conditions and the following disclaimer. 2.
   80  * Redistributions in binary form must reproduce the above copyright notice,
   81  * this list of conditions and the following disclaimer in the documentation
   82  * and/or other materials provided with the distribution.
   83  *
   84  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
   85  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   86  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   87  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   88  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   89  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   90  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   91  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   92  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   93  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   94  * SUCH DAMAGE.
   95  *
   96  */
   97 /*
   98  * Portions of this code are from the VOXware support for the ad1848
   99  * by Hannu Savolainen <hannu@voxware.pp.fi>
  100  *
  101  * Portions also supplied from the SoundBlaster driver for NetBSD.
  102  */
  103 
  104 #include <sys/cdefs.h>
  105 __KERNEL_RCSID(0, "$NetBSD: ad1848_isa.c,v 1.23 2003/05/09 23:51:28 fvdl Exp $");
  106 
  107 #include <sys/param.h>
  108 #include <sys/systm.h>
  109 #include <sys/errno.h>
  110 #include <sys/ioctl.h>
  111 #include <sys/syslog.h>
  112 #include <sys/device.h>
  113 #include <sys/proc.h>
  114 #include <sys/buf.h>
  115 
  116 #include <machine/cpu.h>
  117 #include <machine/bus.h>
  118 
  119 #include <sys/audioio.h>
  120 
  121 #include <dev/audio_if.h>
  122 #include <dev/auconv.h>
  123 
  124 #include <dev/isa/isavar.h>
  125 #include <dev/isa/isadmavar.h>
  126 
  127 #include <dev/ic/ad1848reg.h>
  128 #include <dev/ic/cs4231reg.h>
  129 #include <dev/ic/cs4237reg.h>
  130 #include <dev/isa/ad1848var.h>
  131 #include <dev/isa/cs4231var.h>
  132 
  133 #ifdef AUDIO_DEBUG
  134 #define DPRINTF(x)      if (ad1848debug) printf x
  135 extern int      ad1848debug;
  136 #else
  137 #define DPRINTF(x)
  138 #endif
  139 
  140 static int ad1848_isa_read __P(( struct ad1848_softc *, int));
  141 static void ad1848_isa_write __P(( struct ad1848_softc *, int, int));
  142 
  143 int
  144 ad1848_isa_read(sc, index)
  145         struct ad1848_softc *sc;
  146         int index;
  147 {
  148         return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, index));
  149 }
  150 
  151 void
  152 ad1848_isa_write(sc, index, value)
  153         struct ad1848_softc *sc;
  154         int index;
  155         int value;
  156 {
  157         bus_space_write_1(sc->sc_iot, sc->sc_ioh, index, value);
  158 }
  159 
  160 /*
  161  * Map and probe for the ad1848 chip
  162  */
  163 int
  164 ad1848_isa_mapprobe(isc, iobase)
  165         struct ad1848_isa_softc *isc;
  166         int iobase;
  167 {
  168         struct ad1848_softc *sc = &isc->sc_ad1848;
  169 
  170         if (!AD1848_BASE_VALID(iobase)) {
  171 #ifdef AUDIO_DEBUG
  172                 printf("ad1848: configured iobase %04x invalid\n", iobase);
  173 #endif
  174                 return 0;
  175         }
  176 
  177         /* Map the AD1848 ports */
  178         if (bus_space_map(sc->sc_iot, iobase, AD1848_NPORT, 0, &sc->sc_ioh))
  179                 return 0;
  180 
  181         if (!ad1848_isa_probe(isc)) {
  182                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
  183                 return 0;
  184         } else
  185                 return 1;
  186 }
  187 
  188 /*
  189  * Probe for the ad1848 chip
  190  */
  191 int
  192 ad1848_isa_probe(isc)
  193         struct ad1848_isa_softc *isc;
  194 {
  195         struct ad1848_softc *sc = &isc->sc_ad1848;
  196         u_char tmp, tmp1 = 0xff, tmp2 = 0xff;
  197         int i, t;
  198 
  199         sc->sc_readreg = ad1848_isa_read;
  200         sc->sc_writereg = ad1848_isa_write;
  201 
  202         /* Is there an ad1848 chip ? */
  203         sc->MCE_bit = MODE_CHANGE_ENABLE;
  204         sc->mode = 1;   /* MODE 1 = original ad1848/ad1846/cs4248 */
  205 
  206         /*
  207          * Check that the I/O address is in use.
  208          *
  209          * The SP_IN_INIT bit of the base I/O port is known to be 0 after the
  210          * chip has performed its power-on initialization. Just assume
  211          * this has happened before the OS is starting.
  212          *
  213          * If the I/O address is unused, inb() typically returns 0xff.
  214          */
  215         tmp = ADREAD(sc, AD1848_IADDR);
  216         if (tmp & SP_IN_INIT) { /* Not a AD1848 */
  217                 DPRINTF(("ad_detect_A %x\n", tmp));
  218                 goto bad;
  219         }
  220 
  221         /*
  222          * Test if it's possible to change contents of the indirect registers.
  223          * Registers 0 and 1 are ADC volume registers.  The bit 0x10 is read
  224          * only so try to avoid using it.  The bit 0x20 is the mic preamp
  225          * enable; on some chips it is always the same in both registers, so
  226          * we avoid tests where they are different.
  227          */
  228         ad_write(sc, 0, 0x8a);
  229         ad_write(sc, 1, 0x45);  /* 0x55 with bit 0x10 clear */
  230         tmp1 = ad_read(sc, 0);
  231         tmp2 = ad_read(sc, 1);
  232 
  233         if (tmp1 != 0x8a || tmp2 != 0x45) {
  234                 DPRINTF(("ad_detect_B (%x/%x)\n", tmp1, tmp2));
  235                 goto bad;
  236         }
  237 
  238         ad_write(sc, 0, 0x65);
  239         ad_write(sc, 1, 0xaa);
  240         tmp1 = ad_read(sc, 0);
  241         tmp2 = ad_read(sc, 1);
  242 
  243         if (tmp1 != 0x65 || tmp2 != 0xaa) {
  244                 DPRINTF(("ad_detect_C (%x/%x)\n", tmp1, tmp2));
  245                 goto bad;
  246         }
  247 
  248         /*
  249          * The indirect register I12 has some read only bits. Lets
  250          * try to change them.
  251          */
  252         tmp = ad_read(sc, SP_MISC_INFO);
  253         ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f);
  254 
  255         /* Here, AD1845 may sometimes be busy.  Wait til it becomes ready. */
  256         for (t = 0; t < 100000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; t++)
  257                 ;
  258 #ifdef AUDIO_DEBUG
  259         if (t)
  260                 DPRINTF(("ad1848_isa_probe: t %d\n", t));
  261 #endif
  262 
  263         if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) {
  264                 DPRINTF(("ad_detect_D (%x)\n", tmp1));
  265                 goto bad;
  266         }
  267 
  268         /*
  269          * MSB and 4 LSBs of the reg I12 tell the chip revision.
  270          *
  271          * A preliminary version of the AD1846 data sheet stated that it
  272          * used an ID field of 0x0B.  The current version, however,
  273          * states that the AD1846 uses ID 0x0A, just like the AD1848K.
  274          *
  275          * this switch statement will need updating as newer clones arrive....
  276          */
  277         switch (tmp1 & 0x8f) {
  278         case 0x09:
  279                 sc->chip_name = "AD1848J";
  280                 break;
  281         case 0x0A:
  282                 sc->chip_name = "AD1848K";
  283                 break;
  284 #if 0   /* See above */
  285         case 0x0B:
  286                 sc->chip_name = "AD1846";
  287                 break;
  288 #endif
  289         case 0x81:
  290                 sc->chip_name = "CS4248revB"; /* or CS4231 rev B; see below */
  291                 break;
  292         case 0x89:
  293                 sc->chip_name = "CS4248";
  294                 break;
  295         case 0x8A:
  296                 sc->chip_name = "broken"; /* CS4231/AD1845; see below */
  297                 break;
  298         default:
  299                 sc->chip_name = "unknown";
  300                 DPRINTF(("ad1848: unknown codec version 0x%02x\n",
  301                          tmp1 & 0x8f));
  302                 break;
  303         }
  304 
  305         /*
  306          * The original AD1848/CS4248 has just 16 indirect registers. This
  307          * means that I0 and I16 should return the same value (etc.).
  308          * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test
  309          * fails with CS4231, AD1845, etc.
  310          */
  311         ad_write(sc, SP_MISC_INFO, 0);  /* Mode2 = disabled */
  312 
  313         for (i = 0; i < 16; i++)
  314                 if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) {
  315                         if (i != SP_TEST_AND_INIT) {
  316                                 DPRINTF(("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2));
  317                                 goto bad;
  318                         }
  319                 }
  320 
  321         /*
  322          * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
  323          * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845.
  324          */
  325         ad_write(sc, SP_MISC_INFO, MODE2);      /* Set mode2, clear 0x80 */
  326 
  327         tmp1 = ad_read(sc, SP_MISC_INFO);
  328         if ((tmp1 & 0xc0) == (0x80 | MODE2)) {
  329                 /*
  330                  *      CS4231 or AD1845 detected - is it?
  331                  *
  332                  *      Verify that setting I2 doesn't change I18.
  333                  */
  334                 ad_write(sc, 18, 0x88); /* Set I18 to known value */
  335 
  336                 ad_write(sc, 2, 0x45);
  337                 if ((tmp2 = ad_read(sc, 18)) != 0x45) { /* No change -> CS4231? */
  338                         ad_write(sc, 2, 0xaa);
  339                         if ((tmp2 = ad_read(sc, 18)) == 0xaa) {     /* Rotten bits? */
  340                                 DPRINTF(("ad_detect_H(%x)\n", tmp2));
  341                                 goto bad;
  342                         }
  343 
  344                         sc->mode = 2;
  345 
  346                         /*
  347                          *  It's a CS4231, or another clone with 32 registers.
  348                          *  Let's find out which by checking I25.
  349                          */
  350                         if ((tmp1 & 0x8f) == 0x8a) {
  351                                 tmp1 = ad_read(sc, CS_VERSION_ID);
  352                                 switch (tmp1 & 0xe7) {
  353                                 case 0xA0:
  354                                         sc->chip_name = "CS4231A";
  355                                         break;
  356                                 case 0x80:
  357                                         /*  XXX I25 no good, AD1845 same as CS4231 */
  358                                         /*
  359                                          * XXX
  360                                          * This test is correct only after reset
  361                                          */
  362                                         if (ad_read(sc, 17) & 0xf0) {
  363                                                 sc->chip_name = "AD1845";
  364                                                 sc->is_ad1845 = 1;
  365                                         } else
  366                                                 sc->chip_name = "CS4231";
  367                                         break;
  368                                 case 0x82:
  369                                         sc->chip_name = "CS4232";
  370                                         break;
  371                                 case 0x03:
  372                                 case 0x83:
  373                                         sc->chip_name = "CS4236";
  374 
  375                                         /*
  376                                          * Try to switch to mode3 (CS4236B or
  377                                          * CS4237B) by setting CMS to 3.  A
  378                                          * plain CS4236 will not react to
  379                                          * LLBM settings.
  380                                          */
  381                                         ad_write(sc, SP_MISC_INFO, MODE3);
  382 
  383                                         tmp1 = ad_read(sc, CS_LEFT_LINE_CONTROL);
  384                                         ad_write(sc, CS_LEFT_LINE_CONTROL, 0xe0);
  385                                         tmp2 = ad_read(sc, CS_LEFT_LINE_CONTROL);
  386                                         if (tmp2 == 0xe0) {
  387                                                 /*
  388                                                  * it's a CS4237B or another
  389                                                  * clone supporting mode 3.
  390                                                  * Let's determine which by
  391                                                  * enabling extended registers
  392                                                  * and checking X25.
  393                                                  */
  394                                                 tmp2 = ad_xread(sc, CS_X_CHIP_VERSION);
  395                                                 switch (tmp2 & X_CHIP_VERSIONF_CID) {
  396                                                 case X_CHIP_CID_CS4236BB:
  397                                                         sc->chip_name = "CS4236BrevB";
  398                                                         break;
  399                                                 case X_CHIP_CID_CS4236B:
  400                                                         sc->chip_name = "CS4236B";
  401                                                         break;
  402                                                 case X_CHIP_CID_CS4237B:
  403                                                         sc->chip_name = "CS4237B";
  404                                                         break;
  405                                                 default:
  406                                                         sc->chip_name = "CS4236B compatible";
  407                                                         DPRINTF(("cs4236: unknown mode 3 compatible codec, version 0x%02x\n", tmp2));
  408                                                         break;
  409                                                 }
  410                                                 sc->mode = 3;
  411                                         }
  412 
  413                                         /* restore volume control information */
  414                                         ad_write(sc, CS_LEFT_LINE_CONTROL, tmp1);
  415                                         break;
  416                                 }
  417                         }
  418                 }
  419         }
  420 
  421         /* Wait for 1848 to init */
  422         while(ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  423                 ;
  424 
  425         /* Wait for 1848 to autocal */
  426         ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
  427         while(ADREAD(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG)
  428                 ;
  429 
  430         return 1;
  431 bad:
  432         return 0;
  433 }
  434 
  435 /* Unmap the I/O ports */
  436 void
  437 ad1848_isa_unmap(isc)
  438         struct ad1848_isa_softc *isc;
  439 {
  440         struct ad1848_softc *sc = &isc->sc_ad1848;
  441         bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
  442 }
  443 
  444 /*
  445  * Attach hardware to driver, attach hardware driver to audio
  446  * pseudo-device driver .
  447  */
  448 void
  449 ad1848_isa_attach(isc)
  450         struct ad1848_isa_softc *isc;
  451 {
  452         struct ad1848_softc *sc = &isc->sc_ad1848;
  453         int error;
  454 
  455         sc->sc_readreg = ad1848_isa_read;
  456         sc->sc_writereg = ad1848_isa_write;
  457 
  458         if (isc->sc_playdrq != -1) {
  459                 isc->sc_play_maxsize = isa_dmamaxsize(isc->sc_ic,
  460                     isc->sc_playdrq);
  461                 error = isa_dmamap_create(isc->sc_ic, isc->sc_playdrq,
  462                     isc->sc_play_maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW);
  463                 if (error) {
  464                         printf("%s: can't create map for drq %d\n",
  465                             sc->sc_dev.dv_xname, isc->sc_playdrq);
  466                         return;
  467                 }
  468         }
  469         if (isc->sc_recdrq != -1 && isc->sc_recdrq != isc->sc_playdrq) {
  470                 isc->sc_rec_maxsize = isa_dmamaxsize(isc->sc_ic,
  471                     isc->sc_recdrq);
  472                 error = isa_dmamap_create(isc->sc_ic, isc->sc_recdrq,
  473                     isc->sc_rec_maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW);
  474                 if (error) {
  475                         printf("%s: can't create map for drq %d\n",
  476                             sc->sc_dev.dv_xname, isc->sc_recdrq);
  477                         isa_dmamap_destroy(isc->sc_ic, isc->sc_playdrq);
  478                         return;
  479                 }
  480         }
  481 
  482         ad1848_attach(sc);
  483 }
  484 
  485 int
  486 ad1848_isa_open(addr, flags)
  487         void *addr;
  488         int flags;
  489 {
  490         struct ad1848_isa_softc *isc = addr;
  491         struct ad1848_softc *sc = &isc->sc_ad1848;
  492         int error, state;
  493 
  494         DPRINTF(("ad1848_isa_open: sc=%p\n", isc));
  495         state = 0;
  496 
  497         if (isc->sc_playdrq != -1) {
  498                 error = isa_drq_alloc(isc->sc_ic, isc->sc_playdrq);
  499                 if (error != 0)
  500                         return EBUSY;
  501                 state |= 1;
  502         }
  503         if (isc->sc_recdrq != -1 && isc->sc_recdrq != isc->sc_playdrq) {
  504                 error = isa_drq_alloc(isc->sc_ic, isc->sc_recdrq);
  505                 if (error != 0)
  506                         goto bad;
  507                 state |= 2;
  508         }
  509 
  510 #ifndef AUDIO_NO_POWER_CTL
  511         /* Power-up chip */
  512         if (isc->powerctl)
  513                 isc->powerctl(isc->powerarg, flags);
  514 #endif
  515 
  516         /* Init and mute wave output */
  517         ad1848_mute_wave_output(sc, WAVE_MUTE2_INIT, 1);
  518 
  519         error = ad1848_open(sc, flags);
  520         if (error) {
  521 #ifndef AUDIO_NO_POWER_CTL
  522                 if (isc->powerctl)
  523                         isc->powerctl(isc->powerarg, 0);
  524 #endif
  525                 goto bad;
  526         }
  527 
  528         DPRINTF(("ad1848_isa_open: opened\n"));
  529         return (0);
  530 
  531 bad:
  532         if (state & 1)
  533                 isa_drq_free(isc->sc_ic, isc->sc_playdrq);
  534         if (state & 2)
  535                 isa_drq_free(isc->sc_ic, isc->sc_recdrq);
  536 
  537         return (error);
  538 }
  539 
  540 /*
  541  * Close function is called at splaudio().
  542  */
  543 void
  544 ad1848_isa_close(addr)
  545         void *addr;
  546 {
  547         struct ad1848_isa_softc *isc = addr;
  548         struct ad1848_softc *sc = &isc->sc_ad1848;
  549 
  550         ad1848_isa_halt_output(isc);
  551         ad1848_isa_halt_input(isc);
  552 
  553         isc->sc_pintr = isc->sc_rintr = NULL;
  554 
  555         if (isc->sc_playdrq != -1)
  556                 isa_drq_free(isc->sc_ic, isc->sc_playdrq);
  557         if (isc->sc_recdrq != -1 && isc->sc_recdrq != isc->sc_playdrq)
  558                 isa_drq_free(isc->sc_ic, isc->sc_recdrq);
  559 
  560         DPRINTF(("ad1848_isa_close: stop DMA\n"));
  561         ad1848_close(sc);
  562 
  563 #ifndef AUDIO_NO_POWER_CTL
  564         /* Power-down chip */
  565         if (isc->powerctl)
  566                 isc->powerctl(isc->powerarg, 0);
  567 #endif
  568 }
  569 
  570 int
  571 ad1848_isa_trigger_input(addr, start, end, blksize, intr, arg, param)
  572         void *addr;
  573         void *start, *end;
  574         int blksize;
  575         void (*intr) __P((void *));
  576         void *arg;
  577         struct audio_params *param;
  578 {
  579         struct ad1848_isa_softc *isc = addr;
  580         struct ad1848_softc *sc = &isc->sc_ad1848;
  581         u_int8_t reg;
  582 
  583         isa_dmastart(isc->sc_ic, isc->sc_recdrq, start,
  584             (char *)end - (char *)start, NULL,
  585             DMAMODE_READ | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
  586 
  587         isc->sc_recrun = 1;
  588         if (sc->mode == 2 && isc->sc_playdrq != isc->sc_recdrq) {
  589                 isc->sc_rintr = intr;
  590                 isc->sc_rarg = arg;
  591         } else {
  592                 isc->sc_pintr = intr;
  593                 isc->sc_parg = arg;
  594         }
  595 
  596         
  597         /* 
  598          * Calculate number of transfers.
  599          * Note that ADPCM is always transferred 4 bytes at at a time.
  600          */
  601         blksize = (param->encoding == AUDIO_ENCODING_ADPCM) ? blksize / 4 - 1 :
  602             (blksize * 8) / (param->precision * param->factor * param->channels) - 1;
  603 
  604         if (sc->mode >= 2) {
  605                 ad_write(sc, CS_LOWER_REC_CNT, blksize & 0xff);
  606                 ad_write(sc, CS_UPPER_REC_CNT, blksize >> 8);
  607         } else {
  608                 ad_write(sc, SP_LOWER_BASE_COUNT, blksize & 0xff);
  609                 ad_write(sc, SP_UPPER_BASE_COUNT, blksize >> 8);
  610         }
  611 
  612         reg = ad_read(sc, SP_INTERFACE_CONFIG);
  613         ad_write(sc, SP_INTERFACE_CONFIG, CAPTURE_ENABLE|reg);
  614 
  615         return (0);
  616 }
  617 
  618 int
  619 ad1848_isa_trigger_output(addr, start, end, blksize, intr, arg, param)
  620         void *addr;
  621         void *start, *end;
  622         int blksize;
  623         void (*intr) __P((void *));
  624         void *arg;
  625         struct audio_params *param;
  626 {
  627         struct ad1848_isa_softc *isc = addr;
  628         struct ad1848_softc *sc = &isc->sc_ad1848;
  629         u_int8_t reg;
  630 
  631         isa_dmastart(isc->sc_ic, isc->sc_playdrq, start,
  632             (char *)end - (char *)start, NULL,
  633             DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
  634 
  635         isc->sc_playrun = 1;
  636         isc->sc_pintr = intr;
  637         isc->sc_parg = arg;
  638 
  639         /* 
  640          * Calculate number of transfers.
  641          * Note that ADPCM is always transferred 4 bytes at at a time.
  642          */
  643         blksize = (param->encoding == AUDIO_ENCODING_ADPCM) ? blksize / 4 - 1 :
  644             (blksize * 8) / (param->precision * param->factor * param->channels) - 1;
  645 
  646         ad_write(sc, SP_LOWER_BASE_COUNT, blksize & 0xff);
  647         ad_write(sc, SP_UPPER_BASE_COUNT, blksize >> 8);
  648 
  649         /* Unmute wave output */
  650         ad1848_mute_wave_output(sc, WAVE_MUTE2, 0);
  651 
  652         reg = ad_read(sc, SP_INTERFACE_CONFIG);
  653         ad_write(sc, SP_INTERFACE_CONFIG, PLAYBACK_ENABLE|reg);
  654 
  655         return (0);
  656 }
  657 
  658 int
  659 ad1848_isa_halt_input(addr)
  660         void *addr;
  661 {
  662         struct ad1848_isa_softc *isc = addr;
  663         struct ad1848_softc *sc = &isc->sc_ad1848;
  664 
  665         if (isc->sc_recrun) {
  666                 ad1848_halt_input(sc);
  667                 isa_dmaabort(isc->sc_ic, isc->sc_recdrq);
  668                 isc->sc_recrun = 0;
  669         }
  670 
  671         return (0);
  672 }
  673 
  674 int
  675 ad1848_isa_halt_output(addr)
  676         void *addr;
  677 {
  678         struct ad1848_isa_softc *isc = addr;
  679         struct ad1848_softc *sc = &isc->sc_ad1848;
  680 
  681         if (isc->sc_playrun) {
  682                 /* Mute wave output */
  683                 ad1848_mute_wave_output(sc, WAVE_MUTE2, 1);
  684 
  685                 ad1848_halt_output(sc);
  686                 isa_dmaabort(isc->sc_ic, isc->sc_playdrq);
  687                 isc->sc_playrun = 0;
  688         }
  689 
  690         return (0);
  691 }
  692 
  693 int
  694 ad1848_isa_intr(arg)
  695         void *arg;
  696 {
  697         struct ad1848_isa_softc *isc = arg;
  698         struct ad1848_softc *sc = &isc->sc_ad1848;
  699         int retval = 0;
  700         u_char status;
  701 
  702         /* Get intr status */
  703         status = ADREAD(sc, AD1848_STATUS);
  704 
  705 #ifdef AUDIO_DEBUG
  706         if (ad1848debug > 1)
  707                 printf("ad1848_isa_intr: pintr=%p rintr=%p status=%x\n",
  708                     isc->sc_pintr, isc->sc_rintr, status);
  709 #endif
  710         isc->sc_interrupts++;
  711 
  712         /* Handle interrupt */
  713         if ((status & INTERRUPT_STATUS) != 0) {
  714                 if (sc->mode == 2 && isc->sc_playdrq != isc->sc_recdrq) {
  715                         status = ad_read(sc, CS_IRQ_STATUS);
  716                         if ((status & CS_IRQ_PI) && isc->sc_pintr != NULL) {
  717                                 (*isc->sc_pintr)(isc->sc_parg);
  718                                 retval = 1;
  719                         }
  720                         if ((status & CS_IRQ_CI) && isc->sc_rintr != NULL) {
  721                                 (*isc->sc_rintr)(isc->sc_rarg);
  722                                 retval = 1;
  723                         }
  724                 } else {
  725                         if (isc->sc_pintr != NULL) {
  726                                 (*isc->sc_pintr)(isc->sc_parg);
  727                                 retval = 1;
  728                         }
  729                 }
  730 
  731                 /* Clear interrupt */
  732                 ADWRITE(sc, AD1848_STATUS, 0);
  733         }
  734         return(retval);
  735 }
  736 
  737 void *
  738 ad1848_isa_malloc(addr, direction, size, pool, flags)
  739         void *addr;
  740         int direction;
  741         size_t size;
  742         struct malloc_type *pool;
  743         int flags;
  744 {
  745         struct ad1848_isa_softc *isc = addr;
  746         int drq;
  747 
  748         if (direction == AUMODE_PLAY)
  749                 drq = isc->sc_playdrq;
  750         else
  751                 drq = isc->sc_recdrq;
  752         return (isa_malloc(isc->sc_ic, drq, size, pool, flags));
  753 }
  754 
  755 void
  756 ad1848_isa_free(addr, ptr, pool)
  757         void *addr;
  758         void *ptr;
  759         struct malloc_type *pool;
  760 {
  761         isa_free(ptr, pool);
  762 }
  763 
  764 size_t
  765 ad1848_isa_round_buffersize(addr, direction, size)
  766         void *addr;
  767         int direction;
  768         size_t size;
  769 {
  770         struct ad1848_isa_softc *isc = addr;
  771         bus_size_t maxsize;
  772 
  773         if (direction == AUMODE_PLAY)
  774                 maxsize = isc->sc_play_maxsize;
  775         else if (isc->sc_recdrq == isc->sc_playdrq)
  776                 maxsize = isc->sc_play_maxsize;
  777         else
  778                 maxsize = isc->sc_rec_maxsize;
  779 
  780         if (size > maxsize)
  781                 size = maxsize;
  782         return (size);
  783 }
  784 
  785 paddr_t
  786 ad1848_isa_mappage(addr, mem, off, prot)
  787         void *addr;
  788         void *mem;
  789         off_t off;
  790         int prot;
  791 {
  792         return isa_mappage(mem, off, prot);
  793 }
  794 
  795 int
  796 ad1848_isa_get_props(addr)
  797         void *addr;
  798 {
  799         struct ad1848_isa_softc *isc = addr;
  800 
  801         return (AUDIO_PROP_MMAP |
  802                 (isc->sc_playdrq != isc->sc_recdrq ? AUDIO_PROP_FULLDUPLEX : 0));
  803 }

Cache object: bd89b94850c04f3759f57c8c9c4ff016


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