[BACK]Return to gtp.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/gtp.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: gtp.c,v 1.3 2006/04/20 20:30:29 miod Exp $    */
                      2:
                      3: /*
                      4:  * Copyright (c) 2002 Vladimir Popov <jumbo@narod.ru>
                      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 AUTHORS ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     19:  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
                     20:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     21:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     22:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     23:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     24:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     25:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     26:  */
                     27:
                     28: /* Gemtek PCI Radio Card Device Driver */
                     29:
                     30: #include <sys/param.h>
                     31: #include <sys/systm.h>
                     32: #include <sys/device.h>
                     33: #include <sys/errno.h>
                     34: #include <sys/ioctl.h>
                     35: #include <sys/proc.h>
                     36: #include <sys/radioio.h>
                     37:
                     38: #include <machine/bus.h>
                     39:
                     40: #include <dev/pci/pcireg.h>
                     41: #include <dev/pci/pcivar.h>
                     42: #include <dev/pci/pcidevs.h>
                     43:
                     44: #include <dev/ic/tea5757.h>
                     45: #include <dev/radio_if.h>
                     46:
                     47: int    gtp_match(struct device *, void *, void *);
                     48: void   gtp_attach(struct device *, struct device *, void *);
                     49:
                     50: int     gtp_get_info(void *, struct radio_info *);
                     51: int     gtp_set_info(void *, struct radio_info *);
                     52: int     gtp_search(void *, int);
                     53:
                     54: #define GEMTEK_PCI_CAPS        RADIO_CAPS_DETECT_SIGNAL |                      \
                     55:                        RADIO_CAPS_DETECT_STEREO |                      \
                     56:                        RADIO_CAPS_SET_MONO |                           \
                     57:                        RADIO_CAPS_HW_SEARCH |                          \
                     58:                        RADIO_CAPS_HW_AFC |                             \
                     59:                        RADIO_CAPS_LOCK_SENSITIVITY
                     60:
                     61: #define GEMTEK_PCI_MUTE                0x00
                     62: #define GEMTEK_PCI_RSET                0x10
                     63:
                     64: #define GEMTEK_PCI_SIGNAL      0x08
                     65: #define GEMTEK_PCI_STEREO      0x08
                     66:
                     67: #define GTP_WREN_ON            (1 << 2)
                     68: #define GTP_WREN_OFF           (0 << 2)
                     69:
                     70: #define GTP_DATA_ON            (1 << 1)
                     71: #define GTP_DATA_OFF           (0 << 1)
                     72:
                     73: #define GTP_CLCK_ON            (1 << 0)
                     74: #define GTP_CLCK_OFF           (0 << 0)
                     75:
                     76: #define GTP_READ_CLOCK_LOW     (GTP_WREN_OFF | GTP_DATA_ON | GTP_CLCK_OFF)
                     77: #define GTP_READ_CLOCK_HIGH    (GTP_WREN_OFF | GTP_DATA_ON | GTP_CLCK_ON)
                     78:
                     79: /* define our interface to the high-level radio driver */
                     80:
                     81: struct radio_hw_if gtp_hw_if = {
                     82:        NULL, /* open */
                     83:        NULL, /* close */
                     84:        gtp_get_info,
                     85:        gtp_set_info,
                     86:        gtp_search
                     87: };
                     88:
                     89: struct gtp_softc {
                     90:        struct device   sc_dev;
                     91:
                     92:        int     mute;
                     93:        u_int8_t        vol;
                     94:        u_int32_t       freq;
                     95:        u_int32_t       stereo;
                     96:        u_int32_t       lock;
                     97:
                     98:        struct tea5757_t        tea;
                     99: };
                    100:
                    101: struct cfattach gtp_ca = {
                    102:        sizeof(struct gtp_softc), gtp_match, gtp_attach
                    103: };
                    104:
                    105: struct cfdriver gtp_cd = {
                    106:        NULL, "gtp", DV_DULL
                    107: };
                    108:
                    109: void   gtp_set_mute(struct gtp_softc *);
                    110: void   gtp_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
                    111: void   gtp_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                    112: void   gtp_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                    113: int    gtp_state(bus_space_tag_t, bus_space_handle_t);
                    114: u_int32_t      gtp_hardware_read(bus_space_tag_t, bus_space_handle_t,
                    115:                bus_size_t);
                    116:
                    117: int
                    118: gtp_match(struct device *parent, void *match, void *aux)
                    119: {
                    120:        struct pci_attach_args *pa = aux;
                    121:        /* FIXME:
                    122:         * Guillemot produces the card that
                    123:         * was originally developed by Gemtek
                    124:         */
                    125:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_GEMTEK &&
                    126:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_GEMTEK_PR103)
                    127:                return (1);
                    128:        return (0);
                    129: }
                    130:
                    131: void
                    132: gtp_attach(struct device *parent, struct device *self, void *aux)
                    133: {
                    134:        struct gtp_softc *sc = (struct gtp_softc *) self;
                    135:        struct pci_attach_args *pa = aux;
                    136:        struct cfdata *cf = sc->sc_dev.dv_cfdata;
                    137:
                    138:        if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->tea.iot,
                    139:            &sc->tea.ioh, NULL, NULL, 0)) {
                    140:                printf(": can't map i/o space\n");
                    141:                return;
                    142:        }
                    143:
                    144:        sc->vol = 0;
                    145:        sc->mute = 0;
                    146:        sc->freq = MIN_FM_FREQ;
                    147:        sc->stereo = TEA5757_STEREO;
                    148:        sc->lock = TEA5757_S030;
                    149:        sc->tea.offset = 0;
                    150:        sc->tea.flags = cf->cf_flags;
                    151:        sc->tea.init = gtp_init;
                    152:        sc->tea.rset = gtp_rset;
                    153:        sc->tea.write_bit = gtp_write_bit;
                    154:        sc->tea.read = gtp_hardware_read;
                    155:
                    156:        printf(": Gemtek PR103\n");
                    157:
                    158:        radio_attach_mi(&gtp_hw_if, sc, &sc->sc_dev);
                    159: }
                    160:
                    161: int
                    162: gtp_get_info(void *v, struct radio_info *ri)
                    163: {
                    164:        struct gtp_softc *sc = v;
                    165:
                    166:        ri->mute = sc->mute;
                    167:        ri->volume = sc->vol ? 255 : 0;
                    168:        ri->stereo = sc->stereo == TEA5757_STEREO ? 1 : 0;
                    169:        ri->caps = GEMTEK_PCI_CAPS;
                    170:        ri->rfreq = 0;
                    171:        ri->lock = tea5757_decode_lock(sc->lock);
                    172:
                    173:        /* Frequency read unsupported */
                    174:        ri->freq = sc->freq;
                    175:
                    176:        ri->info = gtp_state(sc->tea.iot, sc->tea.ioh);
                    177:        gtp_set_mute(sc);
                    178:
                    179:        return (0);
                    180: }
                    181:
                    182: int
                    183: gtp_set_info(void *v, struct radio_info *ri)
                    184: {
                    185:        struct gtp_softc *sc = v;
                    186:
                    187:        sc->mute = ri->mute ? 1 : 0;
                    188:        sc->vol = ri->volume ? 255 : 0;
                    189:        sc->stereo = ri->stereo ? TEA5757_STEREO: TEA5757_MONO;
                    190:        sc->lock = tea5757_encode_lock(ri->lock);
                    191:        ri->freq = sc->freq = tea5757_set_freq(&sc->tea,
                    192:            sc->lock, sc->stereo, ri->freq);
                    193:        gtp_set_mute(sc);
                    194:
                    195:        return (0);
                    196: }
                    197:
                    198: int
                    199: gtp_search(void *v, int f)
                    200: {
                    201:        struct gtp_softc *sc = v;
                    202:
                    203:        tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
                    204:        gtp_set_mute(sc);
                    205:
                    206:        return (0);
                    207: }
                    208:
                    209: void
                    210: gtp_set_mute(struct gtp_softc *sc)
                    211: {
                    212:        if (sc->mute || !sc->vol)
                    213:                bus_space_write_2(sc->tea.iot, sc->tea.ioh, 0, GEMTEK_PCI_MUTE);
                    214:        else
                    215:                sc->freq = tea5757_set_freq(&sc->tea,
                    216:                    sc->lock, sc->stereo, sc->freq);
                    217: }
                    218:
                    219: void
                    220: gtp_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
                    221:                int bit)
                    222: {
                    223:        u_int8_t data;
                    224:
                    225:        data = bit ? GTP_DATA_ON : GTP_DATA_OFF;
                    226:        bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_CLCK_OFF | data);
                    227:        bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_CLCK_ON  | data);
                    228:        bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_CLCK_OFF | data);
                    229: }
                    230:
                    231: void
                    232: gtp_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
                    233: {
                    234:        bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_DATA_ON | GTP_CLCK_OFF);
                    235: }
                    236:
                    237: void
                    238: gtp_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
                    239: {
                    240:        bus_space_write_1(iot, ioh, off, GEMTEK_PCI_RSET);
                    241: }
                    242:
                    243: u_int32_t
                    244: gtp_hardware_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off)
                    245: {
                    246:        /* UNSUPPORTED */
                    247:        return 0;
                    248: }
                    249:
                    250: int
                    251: gtp_state(bus_space_tag_t iot, bus_space_handle_t ioh)
                    252: {
                    253:        int ret;
                    254:
                    255:        bus_space_write_2(iot, ioh, 0,
                    256:            GTP_DATA_ON | GTP_WREN_OFF | GTP_CLCK_OFF);
                    257:        ret  = bus_space_read_2(iot, ioh, 0) &
                    258:            GEMTEK_PCI_STEREO?  0 : RADIO_INFO_STEREO;
                    259:        bus_space_write_2(iot, ioh, 0,
                    260:            GTP_DATA_ON | GTP_WREN_OFF | GTP_CLCK_ON);
                    261:        ret |= bus_space_read_2(iot, ioh, 0) &
                    262:            GEMTEK_PCI_SIGNAL?  0 : RADIO_INFO_SIGNAL;
                    263:
                    264:        return ret;
                    265: }

CVSweb