[BACK]Return to onyx.c CVS log [TXT][DIR] Up to [local] / sys / arch / macppc / dev

Annotation of sys/arch/macppc/dev/onyx.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: onyx.c,v 1.7 2007/04/23 16:27:20 deraadt Exp $        */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 2005 Tsubai Masanari.  All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. The name of the author may not be used to endorse or promote products
        !            15:  *    derived from this software without specific prior written permission.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            26:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: /*
        !            30:  * http://focus.ti.com/docs/prod/folders/print/pcm3052.html
        !            31:  *
        !            32:  * Datasheet is available from
        !            33:  * http://focus.ti.com/docs/prod/folders/print/pcm3052a.html
        !            34:  */
        !            35:
        !            36: #include <sys/param.h>
        !            37: #include <sys/audioio.h>
        !            38: #include <sys/device.h>
        !            39: #include <sys/systm.h>
        !            40:
        !            41: #include <dev/audio_if.h>
        !            42: #include <dev/ofw/openfirm.h>
        !            43: #include <macppc/dev/dbdma.h>
        !            44:
        !            45: #include <machine/autoconf.h>
        !            46:
        !            47: #include <macppc/dev/i2svar.h>
        !            48: #include <macppc/dev/kiicvar.h>
        !            49:
        !            50: #ifdef ONYX_DEBUG
        !            51: # define DPRINTF printf
        !            52: #else
        !            53: # define DPRINTF while (0) printf
        !            54: #endif
        !            55:
        !            56: /* XXX */
        !            57: #define PCM3052_I2C_ADDR       0x8c
        !            58:
        !            59: /* PCM3052 registers */
        !            60: #define PCM3052_REG_LEFT_VOLUME                0x41
        !            61: #define PCM3052_REG_RIGHT_VOLUME       0x42
        !            62:
        !            63: /* XXX */
        !            64: #define onyx_softc i2s_softc
        !            65:
        !            66: /* XXX */
        !            67: void kiic_setmode(struct kiic_softc *, u_int, u_int);
        !            68: int kiic_write(struct device *, int, int, const void *, int);
        !            69:
        !            70: int onyx_getdev(void *, struct audio_device *);
        !            71: int onyx_match(struct device *, void *, void *);
        !            72: void onyx_attach(struct device *, struct device *, void *);
        !            73: void onyx_defer(struct device *);
        !            74: void onyx_set_volume(struct onyx_softc *, int, int);
        !            75:
        !            76: struct cfattach onyx_ca = {
        !            77:        sizeof(struct onyx_softc), onyx_match, onyx_attach
        !            78: };
        !            79:
        !            80: struct cfdriver onyx_cd = {
        !            81:        NULL, "onyx", DV_DULL
        !            82: };
        !            83:
        !            84: struct audio_hw_if onyx_hw_if = {
        !            85:        i2s_open,
        !            86:        i2s_close,
        !            87:        NULL,
        !            88:        i2s_query_encoding,
        !            89:        i2s_set_params,
        !            90:        i2s_round_blocksize,
        !            91:        NULL,
        !            92:        NULL,
        !            93:        NULL,
        !            94:        NULL,
        !            95:        NULL,
        !            96:        i2s_halt_output,
        !            97:        i2s_halt_input,
        !            98:        NULL,
        !            99:        onyx_getdev,
        !           100:        NULL,
        !           101:        i2s_set_port,
        !           102:        i2s_get_port,
        !           103:        i2s_query_devinfo,
        !           104:        i2s_allocm,
        !           105:        NULL,
        !           106:        i2s_round_buffersize,
        !           107:        i2s_mappage,
        !           108:        i2s_get_props,
        !           109:        i2s_trigger_output,
        !           110:        i2s_trigger_input,
        !           111: };
        !           112:
        !           113: struct audio_device onyx_device = {
        !           114:        "ONYX",
        !           115:        "",
        !           116:        "onyx"
        !           117: };
        !           118:
        !           119: int
        !           120: onyx_match(struct device *parent, void *match, void *aux)
        !           121: {
        !           122:        struct confargs *ca = aux;
        !           123:        int soundbus, soundchip, soundcodec;
        !           124:        int32_t layout = 0;
        !           125:
        !           126:        if (strcmp(ca->ca_name, "i2s") != 0)
        !           127:                return (0);
        !           128:
        !           129:        if ((soundbus = OF_child(ca->ca_node)) == 0 ||
        !           130:            (soundchip = OF_child(soundbus)) == 0)
        !           131:                return (0);
        !           132:
        !           133:        if (OF_getprop(soundchip, "platform-onyx-codec-ref",
        !           134:            &soundcodec, sizeof soundcodec) == sizeof soundcodec)
        !           135:                return (1);
        !           136:
        !           137:        /*
        !           138:         * Apple really messed up.  First and second generation iMac
        !           139:         * G5 (PowerMac8,1 and PowerMac8,2) have a "deq" i2c device
        !           140:         * listed in the OF device tree, which is a telltale sign of
        !           141:         * snapper(4).  But in reality that chip isn't there.  So we
        !           142:         * match on "layout-id" instead.
        !           143:         */
        !           144:        if (OF_getprop(soundchip, "layout-id", &layout, sizeof layout) &&
        !           145:            (layout == 0x2d || layout == 0x56))
        !           146:                return (1);
        !           147:
        !           148:        return (0);
        !           149: }
        !           150:
        !           151: void
        !           152: onyx_attach(struct device *parent, struct device *self, void *aux)
        !           153: {
        !           154:        struct onyx_softc *sc = (struct onyx_softc *)self;
        !           155:
        !           156:        sc->sc_setvolume = onyx_set_volume;
        !           157:
        !           158:        i2s_attach(parent, sc, aux);
        !           159:        config_defer(self, onyx_defer);
        !           160: }
        !           161:
        !           162: void
        !           163: onyx_defer(struct device *dev)
        !           164: {
        !           165:        struct onyx_softc *sc = (struct onyx_softc *)dev;
        !           166:        struct device *dv;
        !           167:
        !           168:        TAILQ_FOREACH(dv, &alldevs, dv_list)
        !           169:                if (strncmp(dv->dv_xname, "kiic", 4) == 0 &&
        !           170:                    strncmp(dv->dv_parent->dv_xname, "macobio", 7) == 0)
        !           171:                        sc->sc_i2c = dv;
        !           172:        if (sc->sc_i2c == NULL) {
        !           173:                printf("%s: unable to find i2c\n", sc->sc_dev.dv_xname);
        !           174:                return;
        !           175:        }
        !           176:
        !           177:        /* XXX If i2c has failed to attach, what should we do? */
        !           178:
        !           179:        audio_attach_mi(&onyx_hw_if, sc, &sc->sc_dev);
        !           180:
        !           181:        deq_reset(sc);
        !           182:        onyx_set_volume(sc, 192, 192);
        !           183: }
        !           184:
        !           185: int
        !           186: onyx_getdev(void *h, struct audio_device *retp)
        !           187: {
        !           188:        *retp = onyx_device;
        !           189:        return (0);
        !           190: }
        !           191:
        !           192: void
        !           193: onyx_set_volume(struct onyx_softc *sc, int left, int right)
        !           194: {
        !           195:        u_int8_t data;
        !           196:
        !           197:        sc->sc_vol_l = left;
        !           198:        sc->sc_vol_r = right;
        !           199:
        !           200:        kiic_setmode(sc->sc_i2c, I2C_STDSUBMODE, 0);
        !           201:        data = 128 + (left >> 1);
        !           202:        kiic_write(sc->sc_i2c, PCM3052_I2C_ADDR,
        !           203:            PCM3052_REG_LEFT_VOLUME, &data, 1);
        !           204:        data = 128 + (right >> 1);
        !           205:        kiic_write(sc->sc_i2c, PCM3052_I2C_ADDR,
        !           206:            PCM3052_REG_RIGHT_VOLUME, &data, 1);
        !           207: }

CVSweb