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/tms320av110.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: tms320av110.c,v 1.12 2003/01/06 13:05:11 wiz Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Ignatios Souvatzis.
    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 /*
   40  * Machine independent part of TMS320AV110 driver.
   41  *
   42  * Currently, only minimum support for audio output. For audio/video
   43  * synchronization, more is needed.
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __KERNEL_RCSID(0, "$NetBSD: tms320av110.c,v 1.12 2003/01/06 13:05:11 wiz Exp $");
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/kernel.h>
   52 #include <sys/device.h>
   53 #include <sys/proc.h>
   54 
   55 #include <sys/audioio.h>
   56 #include <dev/audio_if.h>
   57 
   58 #include <dev/ic/tms320av110reg.h>
   59 #include <dev/ic/tms320av110var.h>
   60 
   61 #include <machine/bus.h>
   62 
   63 int tav_open __P((void*, int));
   64 void tav_close __P((void *));
   65 int tav_drain __P((void *));
   66 int tav_query_encoding __P((void *, struct audio_encoding *));
   67 int tav_set_params __P((void *, int, int, struct audio_params *, 
   68     struct audio_params *));
   69 int tav_round_blocksize __P((void *, int));
   70 int tav_init_output __P((void *, void *, int));
   71 int tav_start_output __P((void *, void *, int, void (*)(void *), void *));
   72 int tav_start_input __P((void *, void *, int, void (*)(void *), void *));
   73 int tav_halt_output __P((void *));
   74 int tav_halt_input __P((void *));
   75 int tav_speaker_ctl __P((void *, int));
   76 int tav_getdev __P((void *, struct audio_device *));
   77 int tav_setfd __P((void *, int));
   78 int tav_set_port __P((void *, mixer_ctrl_t *));
   79 int tav_get_port __P((void *, mixer_ctrl_t *));
   80 int tav_query_devinfo __P((void *, mixer_devinfo_t *));
   81 int tav_get_props __P((void *));
   82 
   83 struct audio_hw_if tav_audio_if = {
   84         tav_open,
   85         tav_close,
   86         0 /* tav_drain*/,               /* optional */
   87         tav_query_encoding,
   88         tav_set_params,
   89         tav_round_blocksize,
   90         0 /* commit_settings */,        /* optional */
   91         tav_init_output,                /* optional */
   92         0 /* tav_init_input */,         /* optional */
   93         tav_start_output,
   94         tav_start_input,
   95         tav_halt_output,
   96         tav_halt_input,
   97         tav_speaker_ctl,                /* optional */
   98         tav_getdev,
   99         0 /* setfd */,                  /* optional */
  100         tav_set_port,
  101         tav_get_port,
  102         tav_query_devinfo,
  103         0 /* alloc */,                  /* optional */
  104         0 /* free */,                   /* optional */
  105         0 /* round_buffersize */,       /* optional */
  106         0 /* mappage */,                /* optional */
  107         tav_get_props,
  108         0 /* dev_ioctl */               /* optional */
  109 };
  110 
  111 void
  112 tms320av110_attach_mi(sc)
  113         struct tav_softc *sc;
  114 {
  115         bus_space_tag_t iot = sc->sc_iot;
  116         bus_space_handle_t ioh = sc->sc_ioh;
  117 
  118         tav_write_byte(iot, ioh, TAV_RESET, 1);
  119         while (tav_read_byte(iot, ioh, TAV_RESET))
  120                 delay(250);
  121 
  122         tav_write_byte(iot, ioh, TAV_PCM_ORD, sc->sc_pcm_ord);
  123         tav_write_byte(iot, ioh, TAV_PCM_18, sc->sc_pcm_18);
  124         tav_write_byte(iot, ioh, TAV_DIF, sc->sc_dif);
  125         tav_write_byte(iot, ioh, TAV_PCM_DIV, sc->sc_pcm_div);
  126 
  127         printf(": chip rev. %d, %d bytes buffer\n",
  128             tav_read_byte(iot, ioh, TAV_VERSION),
  129             TAV_DRAM_SIZE(tav_read_byte(iot, ioh, TAV_DRAM_EXT)));
  130 
  131         tav_write_byte(iot, ioh, TAV_AUD_ID_EN, 0);
  132         tav_write_byte(iot, ioh, TAV_SKIP, 0);
  133         tav_write_byte(iot, ioh, TAV_REPEAT, 0);
  134         tav_write_byte(iot, ioh, TAV_MUTE, 0);
  135         tav_write_byte(iot, ioh, TAV_PLAY, 1);
  136         tav_write_byte(iot, ioh, TAV_SYNC_ECM, 0);
  137         tav_write_byte(iot, ioh, TAV_CRC_ECM, 0);
  138         tav_write_byte(iot, ioh, TAV_ATTEN_L, 0);
  139         tav_write_byte(iot, ioh, TAV_ATTEN_R, 0);
  140         tav_write_short(iot, ioh, TAV_FREE_FORM, 0);
  141         tav_write_byte(iot, ioh, TAV_SIN_EN, 0);
  142         tav_write_byte(iot, ioh, TAV_SYNC_ECM, TAV_ECM_REPEAT);
  143         tav_write_byte(iot, ioh, TAV_CRC_ECM, TAV_ECM_REPEAT);
  144 
  145         audio_attach_mi(&tav_audio_if, sc, &sc->sc_dev);
  146 }
  147 
  148 int
  149 tms320av110_intr(p)
  150         void *p;
  151 {
  152         struct tav_softc *sc = p;
  153         u_int16_t intlist;
  154 
  155         intlist = tav_read_short(sc->sc_iot, sc->sc_ioh, TAV_INTR)
  156             /* & tav_read_short(sc->sc_iot, sc->sc_ioh, TAV_INTR_EN)*/;
  157 
  158         if (!intlist)
  159                 return 0;
  160 
  161         /* ack now, so that we don't miss later interrupts */
  162         if (sc->sc_intack)
  163                 (sc->sc_intack)(sc);
  164 
  165         if (intlist & TAV_INTR_LOWWATER) {
  166                 (*sc->sc_intr)(sc->sc_intrarg);
  167         }
  168 
  169         if (intlist & TAV_INTR_PCM_OUTPUT_UNDERFLOW) {
  170                  wakeup(sc);
  171         }
  172 
  173         return 1;
  174 }
  175 
  176 struct audio_encoding tav_encodings[] = {
  177         {0, AudioEmpeg_l2_stream, AUDIO_ENCODING_MPEG_L2_STREAM, 1, 0,},
  178         {1, AudioEmpeg_l2_packets, AUDIO_ENCODING_MPEG_L2_PACKETS, 1, 0,},
  179         {2, AudioEmpeg_l2_system, AUDIO_ENCODING_MPEG_L2_SYSTEM, 1, 0,},
  180         {3, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0,},
  181 };
  182 
  183 int
  184 tav_open(hdl, flags)
  185         void *hdl;
  186         int flags;
  187 {
  188         struct tav_softc *sc;
  189 
  190         sc = hdl;
  191 
  192         /* dummy */
  193         return 0;
  194 }
  195 
  196 void
  197 tav_close(hdl)
  198         void *hdl;
  199 {
  200         struct tav_softc *sc;
  201         bus_space_tag_t iot;
  202         bus_space_handle_t ioh;
  203 
  204         sc = hdl;
  205         iot = sc->sc_iot;
  206         ioh = sc->sc_ioh;
  207 
  208         /* re"start" chip, also clears interrupts and interrupt enable */
  209         tav_write_short(iot, ioh, TAV_INTR_EN, 0);
  210         if (sc->sc_intack)
  211                 (*sc->sc_intack)(sc);
  212 }
  213 
  214 int
  215 tav_drain(hdl)
  216         void *hdl;
  217 {
  218         struct tav_softc *sc;
  219         bus_space_tag_t iot;
  220         bus_space_handle_t ioh;
  221         u_int16_t mask;
  222 
  223         sc = hdl;
  224         iot = sc->sc_iot;
  225         ioh = sc->sc_ioh;
  226 
  227         /*
  228          * tsleep waiting for underflow interrupt.
  229          */
  230         if (tav_read_short(iot, ioh, TAV_BUFF)) {
  231                 mask = tav_read_short(iot, ioh, TAV_INTR_EN);
  232                 tav_write_short(iot, ioh, TAV_INTR_EN,
  233                     mask|TAV_INTR_PCM_OUTPUT_UNDERFLOW);
  234 
  235                 /* still more than zero? */
  236                 if (tav_read_short(iot, ioh, TAV_BUFF))
  237                         (void)tsleep(sc, PCATCH, "tavdrain", 32*hz);
  238 
  239                 /* can be really that long for mpeg */
  240 
  241                 mask = tav_read_short(iot, ioh, TAV_INTR_EN);
  242                 tav_write_short(iot, ioh, TAV_INTR_EN,
  243                     mask & ~TAV_INTR_PCM_OUTPUT_UNDERFLOW);
  244         }
  245         
  246         return 0;
  247 }
  248 
  249 int
  250 tav_query_encoding(hdl, ae)
  251         void *hdl;
  252         struct audio_encoding *ae;
  253 {
  254         struct tav_softc *sc;
  255 
  256         sc = hdl;
  257         if (ae->index >= sizeof(tav_encodings)/sizeof(*ae))
  258                 return EINVAL;
  259 
  260         *ae = tav_encodings[ae->index];
  261 
  262         return 0;
  263 }
  264 
  265 int
  266 tav_start_input(hdl, block, bsize, intr, intrarg)
  267         void *hdl;
  268         void *block;
  269         int bsize;
  270         void (*intr) __P((void *));
  271         void *intrarg;
  272 {
  273         return ENOTTY;
  274 }
  275 
  276 int
  277 tav_halt_input(hdl)
  278         void *hdl;
  279 {
  280         return ENOTTY;
  281 }
  282 
  283 int
  284 tav_start_output(hdl, block, bsize, intr, intrarg)
  285         void *hdl;
  286         void *block;
  287         int bsize;
  288         void (*intr) __P((void *));
  289         void *intrarg;
  290 {
  291         struct tav_softc *sc;
  292         bus_space_tag_t iot;
  293         bus_space_handle_t ioh;
  294         u_int8_t *ptr;
  295         int count;
  296 
  297 
  298         sc = hdl;
  299         iot = sc->sc_iot;
  300         ioh = sc->sc_ioh;
  301         ptr = block;
  302         count = bsize;
  303         
  304         sc->sc_intr = intr;
  305         sc->sc_intrarg = intrarg;
  306 
  307         bus_space_write_multi_1(iot, ioh, TAV_DATAIN, ptr, count);
  308         tav_write_short(iot, ioh, TAV_INTR_EN, TAV_INTR_LOWWATER);
  309 
  310         return 0;
  311 }
  312 
  313 int
  314 tav_init_output(hdl, buffer, size)
  315         void *hdl;
  316         void *buffer;
  317         int size;
  318 {
  319         struct tav_softc *sc;
  320         bus_space_tag_t iot;
  321         bus_space_handle_t ioh;
  322 
  323         sc = hdl;
  324         iot = sc->sc_iot;
  325         ioh = sc->sc_ioh;
  326 
  327         tav_write_byte(iot, ioh, TAV_PLAY, 1);
  328         tav_write_byte(iot, ioh, TAV_MUTE, 0);
  329 
  330         return 0;
  331 }
  332 
  333 int
  334 tav_halt_output(hdl)
  335         void *hdl;
  336 {
  337         struct tav_softc *sc;
  338         bus_space_tag_t iot;
  339         bus_space_handle_t ioh;
  340 
  341         sc = hdl;
  342         iot = sc->sc_iot;
  343         ioh = sc->sc_ioh;
  344 
  345         tav_write_byte(iot, ioh, TAV_PLAY, 0);
  346 
  347         return 0;
  348 }
  349 
  350 int
  351 tav_getdev(hdl, ret)
  352         void *hdl;
  353         struct audio_device *ret;
  354 {
  355         struct tav_softc *sc;
  356         bus_space_tag_t iot;
  357         bus_space_handle_t ioh;
  358 
  359         sc = hdl;
  360         iot = sc->sc_iot;
  361         ioh = sc->sc_ioh;
  362 
  363         strncpy(ret->name, "tms320av110", MAX_AUDIO_DEV_LEN);
  364         sprintf(ret->version, "%u", /* guaranteed to be <= 4 in length */
  365             tav_read_byte(iot, ioh, TAV_VERSION));
  366         strncpy(ret->config, sc->sc_dev.dv_xname, MAX_AUDIO_DEV_LEN);
  367 
  368         return 0;
  369 }
  370 
  371 int
  372 tav_round_blocksize(hdl, size)
  373         void *hdl;
  374         int size;
  375 {
  376         struct tav_softc *sc;
  377         bus_space_tag_t iot;
  378         bus_space_handle_t ioh;
  379         int maxhalf;
  380 
  381         sc = hdl;
  382         iot = sc->sc_iot;
  383         ioh = sc->sc_ioh;
  384 
  385         maxhalf = TAV_DRAM_HSIZE(tav_read_byte(iot, ioh, TAV_DRAM_EXT));
  386         if (size > maxhalf)
  387                 size = maxhalf;
  388 
  389         /* XXX should round to 128 bytes limits for audio bypass */
  390         size &= ~3;
  391 
  392         tav_write_short(iot, ioh, TAV_BALE_LIM, size/8);
  393 
  394         /* the buffer limits are in units of 4 bytes */
  395         return (size);
  396 }
  397 
  398 int
  399 tav_get_props(hdl)
  400         void *hdl;
  401 {
  402         return 0;
  403 }
  404 
  405 int
  406 tav_set_params(hdl, setmode, usemode, p, r)
  407         void *hdl;
  408         int setmode, usemode;
  409         struct  audio_params *p, *r;
  410 {
  411         struct tav_softc *sc;
  412         bus_space_tag_t iot;
  413         bus_space_handle_t ioh;
  414 
  415         sc = hdl;
  416         iot = sc->sc_iot;
  417         ioh = sc->sc_ioh;
  418 
  419         if (!(setmode & AUMODE_PLAY))
  420                 return 0;
  421 
  422         if (p->encoding == AUDIO_ENCODING_ULAW)
  423                 p->encoding = AUDIO_ENCODING_MPEG_L2_STREAM;
  424 
  425         switch(p->encoding) {
  426         default:
  427                 return EINVAL;
  428 
  429         case AUDIO_ENCODING_SLINEAR_BE:
  430 
  431                 /* XXX: todo: add 8bit and mono using software */ 
  432                 p->precision = 16;
  433                 p->channels = 2;
  434 
  435                 /* XXX: this might depend on the specific board. 
  436                    should be handled by the backend */
  437 
  438                 p->sample_rate = 44100;
  439 
  440                 bus_space_write_1(iot, ioh, TAV_STR_SEL, 
  441                     TAV_STR_SEL_AUDIO_BYPASS);
  442                 break;
  443 
  444         /* XXX: later: add ULINEAR, and LE using software encoding */
  445 
  446         case AUDIO_ENCODING_MPEG_L1_STREAM:
  447                 /* FALLTHROUGH */
  448         case AUDIO_ENCODING_MPEG_L2_STREAM:
  449                 bus_space_write_1(iot, ioh, TAV_STR_SEL,
  450                     TAV_STR_SEL_MPEG_AUDIO_STREAM);
  451                 p->sample_rate = 44100;
  452                 p->precision = 1;
  453                 break;
  454 
  455         case AUDIO_ENCODING_MPEG_L1_PACKETS:
  456                 /* FALLTHROUGH */
  457         case AUDIO_ENCODING_MPEG_L2_PACKETS:
  458                 bus_space_write_1(iot, ioh, TAV_STR_SEL,
  459                     TAV_STR_SEL_MPEG_AUDIO_PACKETS);
  460                 p->sample_rate = 44100;
  461                 p->precision = 1;
  462                 break;
  463 
  464         case AUDIO_ENCODING_MPEG_L1_SYSTEM:
  465                 /* FALLTHROUGH */
  466         case AUDIO_ENCODING_MPEG_L2_SYSTEM:
  467                 bus_space_write_1(iot, ioh, TAV_STR_SEL,
  468                     TAV_STR_SEL_MPEG_SYSTEM_STREAM);
  469                 p->sample_rate = 44100;
  470                 p->precision = 1;
  471                 break;
  472         }
  473         tav_write_byte(iot, ioh, TAV_RESTART, 1);
  474         do {
  475                 delay(10);
  476         } while (tav_read_byte(iot, ioh, TAV_RESTART));
  477 
  478         return 0;
  479 }
  480 
  481 int
  482 tav_set_port(hdl, mc)
  483         void *hdl;
  484         mixer_ctrl_t *mc;
  485 {
  486         struct tav_softc *sc;
  487 
  488         sc = hdl;
  489         /* dummy */
  490         return 0;
  491 }
  492 
  493 int
  494 tav_get_port(hdl, mc)
  495         void *hdl;
  496         mixer_ctrl_t *mc;
  497 {
  498         struct tav_softc *sc;
  499 
  500         sc = hdl;
  501         /* dummy */
  502         return 0;
  503 }
  504 
  505 int
  506 tav_query_devinfo(hdl, di)
  507         void *hdl;
  508         mixer_devinfo_t *di;
  509 {
  510         return ENXIO;
  511 }
  512 
  513 int
  514 tav_speaker_ctl(hdl, value)
  515         void *hdl;
  516         int value;
  517 {
  518         struct tav_softc *sc;
  519         bus_space_tag_t iot;
  520         bus_space_handle_t ioh;
  521 
  522         sc = hdl;
  523         iot = sc->sc_iot;
  524         ioh = sc->sc_ioh;
  525 
  526         tav_write_byte(iot, ioh, TAV_MUTE, !value);
  527 
  528         return 0;
  529 }

Cache object: fd0e6badf0f891857b6893a1f0f330ad


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