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

Annotation of sys/arch/sparc64/dev/beep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: beep.c,v 1.3 2006/05/29 03:26:54 jason Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2006 Jason L. Wright (jason@thought.net)
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     26:  * POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29: /*
                     30:  * Driver for beeper device on BBC machines (Blade 1k, 2k, etc)
                     31:  */
                     32:
                     33: #include <sys/types.h>
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/device.h>
                     38: #include <sys/conf.h>
                     39: #include <sys/timeout.h>
                     40:
                     41: #include <machine/bus.h>
                     42: #include <machine/autoconf.h>
                     43: #include <machine/openfirm.h>
                     44:
                     45: #include <sparc64/dev/ebusreg.h>
                     46: #include <sparc64/dev/ebusvar.h>
                     47:
                     48: #define        BEEP_CTRL               0
                     49: #define        BEEP_CNT_0              2
                     50: #define        BEEP_CNT_1              3
                     51: #define        BEEP_CNT_2              4
                     52: #define        BEEP_CNT_3              5
                     53:
                     54: #define        BEEP_CTRL_ON            0x01
                     55: #define        BEEP_CTRL_OFF           0x00
                     56:
                     57: struct beep_freq {
                     58:        int freq;
                     59:        u_int32_t reg;
                     60: };
                     61:
                     62: struct beep_softc {
                     63:        struct device           sc_dev;
                     64:        bus_space_tag_t         sc_iot;
                     65:        bus_space_handle_t      sc_ioh;
                     66:        int                     sc_clk;
                     67:        struct beep_freq        sc_freqs[9];
                     68: };
                     69:
                     70: int beep_match(struct device *, void *, void *);
                     71: void beep_attach(struct device *, struct device *, void *);
                     72: void beep_setfreq(struct beep_softc *, int);
                     73:
                     74: struct cfattach beep_ca = {
                     75:        sizeof(struct beep_softc), beep_match, beep_attach
                     76: };
                     77:
                     78: struct cfdriver beep_cd = {
                     79:        NULL, "beep", DV_DULL
                     80: };
                     81:
                     82: int
                     83: beep_match(struct device *parent, void *match, void *aux)
                     84: {
                     85:        struct ebus_attach_args *ea = aux;
                     86:
                     87:        if (strcmp(ea->ea_name, "beep") == 0)
                     88:                return (1);
                     89:        return (0);
                     90: }
                     91:
                     92: void
                     93: beep_attach(parent, self, aux)
                     94:        struct device *parent, *self;
                     95:        void *aux;
                     96: {
                     97:        struct beep_softc *sc = (void *)self;
                     98:        struct ebus_attach_args *ea = aux;
                     99:        int i;
                    100:
                    101:        sc->sc_iot = ea->ea_memtag;
                    102:
                    103:        /* Use prom address if available, otherwise map it. */
                    104:        if (ea->ea_nvaddrs) {
                    105:                if (bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0,
                    106:                    BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) {
                    107:                        printf(": can't map PROM register space\n");
                    108:                        return;
                    109:                }
                    110:        } else if (ebus_bus_map(sc->sc_iot, 0,
                    111:            EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0,
                    112:            &sc->sc_ioh) != 0) {
                    113:                printf(": can't map register space\n");
                    114:                 return;
                    115:        }
                    116:
                    117:        /* The bbc,beep is clocked at half the BBC frequency */
                    118:        sc->sc_clk = getpropint(findroot(), "clock-frequency", 0);
                    119:        sc->sc_clk /= 2;
                    120:
                    121:        /*
                    122:         * Compute the frequence table based on the scalar and base
                    123:         * board clock speed.
                    124:         */
                    125:        for (i = 0; i < 9; i++) {
                    126:                sc->sc_freqs[i].reg = 1 << (18 - i);
                    127:                sc->sc_freqs[i].freq = sc->sc_clk / sc->sc_freqs[i].reg;
                    128:        }
                    129:
                    130:        /* set beep at around 1200hz */
                    131:        beep_setfreq(sc, 1200);
                    132:
                    133:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, BEEP_CTRL,
                    134:            BEEP_CTRL_ON);
                    135:        for (i = 0; i < 1000; i++)
                    136:                DELAY(1000);
                    137:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, BEEP_CTRL,
                    138:            BEEP_CTRL_OFF);
                    139:
                    140:        printf(": clock %sMHz\n", clockfreq(sc->sc_clk));
                    141: }
                    142:
                    143: void
                    144: beep_setfreq(struct beep_softc *sc, int freq)
                    145: {
                    146:        int i, n, selected = -1;
                    147:
                    148:        n = sizeof(sc->sc_freqs)/sizeof(sc->sc_freqs[0]);
                    149:
                    150:        if (freq < sc->sc_freqs[0].freq)
                    151:                selected = 0;
                    152:        if (freq > sc->sc_freqs[n - 1].freq)
                    153:                selected = n - 1;
                    154:
                    155:        for (i = 1; selected == -1 && i < n; i++) {
                    156:                if (sc->sc_freqs[i].freq == freq)
                    157:                        selected = i;
                    158:                else if (sc->sc_freqs[i].freq > freq) {
                    159:                        int diff1, diff2;
                    160:
                    161:                        diff1 = freq - sc->sc_freqs[i - 1].freq;
                    162:                        diff2 = sc->sc_freqs[i].freq - freq;
                    163:                        if (diff1 < diff2)
                    164:                                selected = i - 1;
                    165:                        else
                    166:                                selected = i;
                    167:                }
                    168:        }
                    169:
                    170:        if (selected == -1)
                    171:                selected = 0;
                    172:
                    173:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, BEEP_CNT_0,
                    174:            (sc->sc_freqs[i].reg >> 24) & 0xff);
                    175:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, BEEP_CNT_1,
                    176:            (sc->sc_freqs[i].reg >> 16) & 0xff);
                    177:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, BEEP_CNT_2,
                    178:            (sc->sc_freqs[i].reg >>  8) & 0xff);
                    179:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, BEEP_CNT_3,
                    180:            (sc->sc_freqs[i].reg >>  0) & 0xff);
                    181: }

CVSweb