root/dev/pci/gtp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gtp_match
  2. gtp_attach
  3. gtp_get_info
  4. gtp_set_info
  5. gtp_search
  6. gtp_set_mute
  7. gtp_write_bit
  8. gtp_init
  9. gtp_rset
  10. gtp_hardware_read
  11. gtp_state

    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 }

/* [<][>][^][v][top][bottom][index][help] */