[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

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