summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/isa/files.isa12
-rw-r--r--sys/dev/pci/files.pci14
-rw-r--r--sys/dev/pci/fms.c95
-rw-r--r--sys/dev/pci/fmsradio.c420
-rw-r--r--sys/dev/pci/fmsradio.h59
-rw-r--r--sys/dev/pci/fmsreg.h115
-rw-r--r--sys/dev/pci/fmsvar.h6
-rw-r--r--sys/dev/pci/sf64pcr.c349
8 files changed, 641 insertions, 429 deletions
diff --git a/sys/dev/isa/files.isa b/sys/dev/isa/files.isa
index 9def8d83545..b5ea67c6b7b 100644
--- a/sys/dev/isa/files.isa
+++ b/sys/dev/isa/files.isa
@@ -1,4 +1,4 @@
-# $OpenBSD: files.isa,v 1.76 2002/04/25 04:56:59 mickey Exp $
+# $OpenBSD: files.isa,v 1.77 2002/05/06 16:37:43 mickey Exp $
# $NetBSD: files.isa,v 1.21 1996/05/16 03:45:55 mycroft Exp $
#
# Config file and device description for machine-independent ISA code.
@@ -339,27 +339,27 @@ attach opl at isa with opl_isa
file dev/isa/opl_isa.c opl_isa
# Sound Forte RadioLink SF16-FMR FM Radio Card
-device sfr: radio, tc921x, pt2254a
+device sfr: radiobus, tc921x, pt2254a
attach sfr at isa
file dev/isa/sf16fmr.c sfr
# Sound Forte RadioLink SF16-FMR2 FM Radio Card
-device sf2r: radio, tea5757
+device sf2r: radiobus, tea5757
attach sf2r at isa
file dev/isa/sf16fmr2.c sf2r
# Aztech/PackardBell FM Radio Card
-device az: radio, lm700x
+device az: radiobus, lm700x
attach az at isa
file dev/isa/aztech.c az
# AIMS Lab Radiotrack & compatible
-device rt: radio, lm700x
+device rt: radiobus, lm700x
attach rt at isa
file dev/isa/radiotrack.c rt
# AIMS Lab Radiotrack II FM Radio Card
-device rtii: radio, tea5757
+device rtii: radiobus, tea5757
attach rtii at isa
file dev/isa/radiotrack2.c rtii
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index bdec482014c..c91efd1e8dd 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.132 2002/04/15 06:23:07 deraadt Exp $
+# $OpenBSD: files.pci,v 1.133 2002/05/06 16:37:43 mickey Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -131,9 +131,10 @@ attach opl at yds with opl_yds
file dev/pci/opl_yds.c opl_yds
# Forte Media FM801
-device fms: audio, auconv, mulaw, ac97, midibus
+device fms: audio, auconv, mulaw, ac97, midibus, tea5757, radiobus
attach fms at pci
file dev/pci/fms.c fms
+file dev/pci/fmsradio.c fms & radio
# VIA VT82C686A AC'97 Audio
device auvia: audio, auconv, mulaw, ac97
@@ -257,7 +258,7 @@ attach sv at pci
file dev/pci/sv.c sv
# Brooktree Bt848 video capture
-device bktr: pcibus, radio
+device bktr: pcibus, radiobus
attach bktr at pci
file dev/pci/bktr/bktr_audio.c bktr needs-count
file dev/pci/bktr/bktr_card.c bktr
@@ -397,15 +398,10 @@ attach pcscp at pci
file dev/pci/pcscp.c pcscp
# Guillemot Maxi Radio FM 2000 Radio Card
-device mr: radio
+device mr: radiobus
attach mr at pci
file dev/pci/maxiradio.c mr
-# MediaForte SoundForte SF64-PCR Radio card
-device sf4r: radio, tea5757
-attach sf4r at pci
-file dev/pci/sf64pcr.c sf4r
-
# National Semiconductor DP83820/DP83821 based GigE
device nge: ether, ifnet, mii, ifmedia, mii_phy
attach nge at pci
diff --git a/sys/dev/pci/fms.c b/sys/dev/pci/fms.c
index ee56e5227da..ad3af60b850 100644
--- a/sys/dev/pci/fms.c
+++ b/sys/dev/pci/fms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fms.c,v 1.8 2002/03/14 03:16:06 millert Exp $ */
+/* $OpenBSD: fms.c,v 1.9 2002/05/06 16:37:43 mickey Exp $ */
/* $NetBSD: fms.c,v 1.5.4.1 2000/06/30 16:27:50 simonb Exp $ */
/*-
@@ -41,6 +41,8 @@
* Forte Media FM801 Audio Device Driver
*/
+#include "radio.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -59,10 +61,16 @@
#include <dev/auconv.h>
#include <dev/ic/ac97.h>
+#if NRADIO > 0
+#include <sys/radioio.h>
+#include <dev/radio_if.h>
+#include <dev/pci/fmsradio.h>
+#endif /* NRADIO > 0 */
#if 0
#include <dev/ic/mpuvar.h>
#endif
+#include <dev/pci/fmsreg.h>
#include <dev/pci/fmsvar.h>
@@ -146,6 +154,17 @@ struct audio_hw_if fms_hw_if = {
fms_trigger_input
};
+#if NRADIO > 0
+struct radio_hw_if fmsradio_hw_if = {
+ NULL, /* open */
+ NULL, /* close */
+ fmsradio_get_info,
+ fmsradio_set_info,
+ fmsradio_search
+};
+#endif /* NRADIO > 0 */
+
+
int fms_attach_codec(void *, struct ac97_codec_if *);
int fms_read_codec(void *, u_int8_t, u_int16_t *);
int fms_write_codec(void *, u_int8_t, u_int16_t);
@@ -155,69 +174,6 @@ int fms_allocmem(struct fms_softc *, size_t, size_t,
struct fms_dma *);
int fms_freemem(struct fms_softc *, struct fms_dma *);
-#define FM_PCM_VOLUME 0x00
-#define FM_FM_VOLUME 0x02
-#define FM_I2S_VOLUME 0x04
-#define FM_RECORD_SOURCE 0x06
-
-#define FM_PLAY_CTL 0x08
-#define FM_PLAY_RATE_MASK 0x0f00
-#define FM_PLAY_BUF1_LAST 0x0001
-#define FM_PLAY_BUF2_LAST 0x0002
-#define FM_PLAY_START 0x0020
-#define FM_PLAY_PAUSE 0x0040
-#define FM_PLAY_STOPNOW 0x0080
-#define FM_PLAY_16BIT 0x4000
-#define FM_PLAY_STEREO 0x8000
-
-#define FM_PLAY_DMALEN 0x0a
-#define FM_PLAY_DMABUF1 0x0c
-#define FM_PLAY_DMABUF2 0x10
-
-
-#define FM_REC_CTL 0x14
-#define FM_REC_RATE_MASK 0x0f00
-#define FM_REC_BUF1_LAST 0x0001
-#define FM_REC_BUF2_LAST 0x0002
-#define FM_REC_START 0x0020
-#define FM_REC_PAUSE 0x0040
-#define FM_REC_STOPNOW 0x0080
-#define FM_REC_16BIT 0x4000
-#define FM_REC_STEREO 0x8000
-
-
-#define FM_REC_DMALEN 0x16
-#define FM_REC_DMABUF1 0x18
-#define FM_REC_DMABUF2 0x1c
-
-#define FM_CODEC_CTL 0x22
-#define FM_VOLUME 0x26
-#define FM_VOLUME_MUTE 0x8000
-
-#define FM_CODEC_CMD 0x2a
-#define FM_CODEC_CMD_READ 0x0080
-#define FM_CODEC_CMD_VALID 0x0100
-#define FM_CODEC_CMD_BUSY 0x0200
-
-#define FM_CODEC_DATA 0x2c
-
-#define FM_IO_CTL 0x52
-#define FM_CARD_CTL 0x54
-
-#define FM_INTMASK 0x56
-#define FM_INTMASK_PLAY 0x0001
-#define FM_INTMASK_REC 0x0002
-#define FM_INTMASK_VOL 0x0040
-#define FM_INTMASK_MPU 0x0080
-
-#define FM_INTSTATUS 0x5a
-#define FM_INTSTATUS_PLAY 0x0100
-#define FM_INTSTATUS_REC 0x0200
-#define FM_INTSTATUS_VOL 0x4000
-#define FM_INTSTATUS_MPU 0x8000
-
-
-
int
fms_match(parent, match, aux)
struct device *parent;
@@ -311,6 +267,17 @@ fms_attach(parent, self, aux)
bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_INTSTATUS,
FM_INTSTATUS_PLAY | FM_INTSTATUS_REC | FM_INTSTATUS_MPU |
FM_INTSTATUS_VOL);
+
+#if NRADIO > 0
+ sc->radio.tea.iot = sc->sc_iot;
+ sc->radio.tea.ioh = sc->sc_ioh;
+ sc->radio.tea.offset = FM_IO_CTL;
+ sc->radio.tea.flags = sc->sc_dev.dv_cfdata->cf_flags;
+
+ fmsradio_attach(&sc->radio, sc->sc_dev.dv_xname);
+ /* /dev/radio will attach anyway */
+ radio_attach_mi(&fmsradio_hw_if, sc, &sc->sc_dev);
+#endif /* NRADIO > 0 */
sc->host_if.arg = sc;
sc->host_if.attach = fms_attach_codec;
diff --git a/sys/dev/pci/fmsradio.c b/sys/dev/pci/fmsradio.c
new file mode 100644
index 00000000000..84b433328b4
--- /dev/null
+++ b/sys/dev/pci/fmsradio.c
@@ -0,0 +1,420 @@
+/* $OpenBSD: fmsradio.c,v 1.1 2002/05/06 16:37:43 mickey Exp $ */
+
+/*
+ * Copyright (c) 2002 Vladimir Popov <jumbo@narod.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Device Driver for FM Tuners attached to FM801 */
+
+/* Currently supported tuners:
+ * o MediaForte SoundForte SF64-PCR PCI Radio Card
+ * o MediaForte SoundForte SF256-PCP-R PCI Sound Card with FM Radio
+ */
+
+#include "radio.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/audioio.h>
+#include <sys/radioio.h>
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/audio_if.h>
+#include <dev/radio_if.h>
+
+#include <dev/ic/ac97.h>
+#include <dev/pci/fmsradio.h>
+#include <dev/pci/fmsreg.h>
+#include <dev/pci/fmsvar.h>
+
+#include <dev/ic/tea5757.h>
+
+#define TUNER_UNKNOWN 0
+#define TUNER_SF256PCPR 1
+#define TUNER_SF64PCR 2
+#define TUNER_NOT_ATTACHED 0xFFFF
+
+#define SF64PCR_CAPS RADIO_CAPS_DETECT_STEREO | \
+ RADIO_CAPS_DETECT_SIGNAL | \
+ RADIO_CAPS_SET_MONO | \
+ RADIO_CAPS_HW_SEARCH | \
+ RADIO_CAPS_HW_AFC | \
+ RADIO_CAPS_LOCK_SENSITIVITY
+
+#define SF256PCPR_CAPS RADIO_CAPS_SET_MONO | \
+ RADIO_CAPS_HW_SEARCH | \
+ RADIO_CAPS_HW_AFC | \
+ RADIO_CAPS_LOCK_SENSITIVITY
+
+#define PCR_WREN_ON (0 << 1)
+#define PCR_WREN_OFF (1 << 1)
+#define PCR_CLOCK_ON (1 << 0)
+#define PCR_CLOCK_OFF (0 << 0)
+#define PCR_DATA_ON (1 << 2)
+#define PCR_DATA_OFF (0 << 2)
+
+#define PCR_SIGNAL 0x80
+#define PCR_STEREO 0x80
+#define PCR_INFO_SIGNAL (1 << 24)
+#define PCR_INFO_STEREO (1 << 25)
+
+#define PCPR_WREN_ON (0 << 2)
+#define PCPR_WREN_OFF (1 << 2)
+#define PCPR_CLOCK_ON (1 << 0)
+#define PCPR_CLOCK_OFF (0 << 0)
+#define PCPR_DATA_ON (1 << 1)
+#define PCPR_DATA_OFF (0 << 1)
+
+/*
+ * Function prototypes
+ */
+void fmsradio_set_mute(struct fmsradio_if *);
+
+void sf64pcr_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
+void sf64pcr_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
+void sf64pcr_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
+u_int32_t sf64pcr_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+int sf64pcr_probe(struct fmsradio_if *);
+
+void sf256pcpr_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
+void sf256pcpr_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
+void sf256pcpr_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
+u_int32_t sf256pcpr_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+int sf256pcpr_probe(struct fmsradio_if *);
+
+int
+fmsradio_attach(struct fmsradio_if *sc, char *devname)
+{
+ sc->vol = 0;
+ sc->mute = 0;
+ sc->freq = MIN_FM_FREQ;
+ sc->stereo = TEA5757_STEREO;
+ sc->lock = TEA5757_S030;
+
+ sc->card = TUNER_UNKNOWN;
+ if ((sc->card = sf64pcr_probe(sc)) == TUNER_SF64PCR)
+ printf("%s: SoundForte SF64-PCR FM Radio\n", devname);
+ else if ((sc->card = sf256pcpr_probe(sc)) == TUNER_SF256PCPR)
+ printf("%s: SoundForte SF256-PCP-R FM Radio\n", devname);
+ else {
+ sc->card = TUNER_NOT_ATTACHED;
+ return 0;
+ }
+
+ fmsradio_set_mute(sc);
+
+ return sc->card;
+}
+
+/* SF256-PCP-R specific routines */
+int
+sf256pcpr_probe(struct fmsradio_if *sc)
+{
+ u_int32_t freq;
+
+ sc->tea.init = sf256pcpr_init;
+ sc->tea.rset = sf256pcpr_rset;
+ sc->tea.write_bit = sf256pcpr_write_bit;
+ sc->tea.read = sf256pcpr_hw_read;
+
+ tea5757_set_freq(&sc->tea, sc->stereo, sc->lock, sc->freq);
+ freq = sf256pcpr_hw_read(sc->tea.iot, sc->tea.ioh, sc->tea.offset);
+ if (tea5757_decode_freq(freq, sc->tea.flags & TEA5757_TEA5759)
+ != sc->freq)
+ return TUNER_UNKNOWN;
+
+ return TUNER_SF256PCPR;
+}
+
+u_int32_t
+sf256pcpr_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
+{
+ u_int32_t res = 0ul;
+ u_int16_t i, d;
+
+ d = FM_IO_GPIO;
+ d |= FM_IO_GPIO3_IN | PCPR_WREN_OFF;
+
+ /* Now read data in */
+ d |= FM_IO_GPIO1_IN | PCPR_DATA_ON;
+
+ bus_space_write_2(iot, ioh, offset, d | PCPR_CLOCK_OFF);
+
+ /* Read the register */
+ i = 24;
+ while (i--) {
+ res <<= 1;
+ bus_space_write_2(iot, ioh, offset, d | PCPR_CLOCK_ON);
+ bus_space_write_2(iot, ioh, offset, d | PCPR_CLOCK_OFF);
+ res |= bus_space_read_2(iot, ioh, offset) & PCPR_DATA_ON ? 1 : 0;
+ }
+
+ return (res & (TEA5757_DATA | TEA5757_FREQ));
+}
+
+void
+sf256pcpr_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
+ int bit)
+{
+ u_int16_t data, wren;
+
+ wren = FM_IO_GPIO | FM_IO_GPIO3_IN | PCPR_WREN_ON;
+ data = bit ? PCPR_DATA_ON : PCPR_DATA_OFF;
+
+ bus_space_write_2(iot, ioh, off, PCPR_CLOCK_OFF | wren | data);
+ bus_space_write_2(iot, ioh, off, PCPR_CLOCK_ON | wren | data);
+ bus_space_write_2(iot, ioh, off, PCPR_CLOCK_OFF | wren | data);
+}
+
+void
+sf256pcpr_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset,
+ u_int32_t d)
+{
+ d = FM_IO_GPIO | FM_IO_GPIO3_IN;
+ d |= PCPR_WREN_ON | PCPR_DATA_OFF | PCPR_CLOCK_OFF;
+
+ bus_space_write_2(iot, ioh, offset, d);
+ bus_space_write_2(iot, ioh, offset, d);
+}
+
+void
+sf256pcpr_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset,
+ u_int32_t d)
+{
+ d = FM_IO_GPIO | FM_IO_GPIO3_IN;
+ d |= PCPR_WREN_OFF | PCPR_DATA_OFF | PCPR_CLOCK_OFF;
+
+ bus_space_write_2(iot, ioh, offset, d);
+ bus_space_write_2(iot, ioh, offset, d);
+}
+
+/* SF64-PCR specific routines */
+int
+sf64pcr_probe(struct fmsradio_if *sc)
+{
+ u_int32_t freq;
+
+ sc->tea.init = sf64pcr_init;
+ sc->tea.rset = sf64pcr_rset;
+ sc->tea.write_bit = sf64pcr_write_bit;
+ sc->tea.read = sf64pcr_hw_read;
+
+ tea5757_set_freq(&sc->tea, sc->stereo, sc->lock, sc->freq);
+ freq = sf64pcr_hw_read(sc->tea.iot, sc->tea.ioh, sc->tea.offset);
+ if (tea5757_decode_freq(freq, sc->tea.flags & TEA5757_TEA5759)
+ != sc->freq)
+ return TUNER_UNKNOWN;
+
+ return TUNER_SF64PCR;
+}
+
+u_int32_t
+sf64pcr_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
+{
+ u_int32_t res = 0ul;
+ u_int16_t d, i, ind = 0;
+
+ d = FM_IO_GPIO;
+ d |= FM_IO_GPIO3_IN | PCR_WREN_OFF;
+
+ /* Now read data in */
+ d |= FM_IO_GPIO2_IN | PCR_DATA_ON;
+
+ bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_OFF);
+ DELAY(4);
+
+ /* Read the register */
+ i = 23;
+ while (i--) {
+ bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_ON);
+ DELAY(4);
+
+ bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_OFF);
+ DELAY(4);
+
+ res |= bus_space_read_2(iot, ioh, offset) & PCR_DATA_ON ? 1 : 0;
+ res <<= 1;
+ }
+
+ bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_ON);
+ DELAY(4);
+
+ i = bus_space_read_1(iot, ioh, offset);
+ ind = i & PCR_SIGNAL ? (1 << 1) : (0 << 1); /* Tuning */
+
+ bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_OFF);
+
+ i = bus_space_read_2(iot, ioh, offset);
+ ind |= i & PCR_STEREO ? (1 << 0) : (0 << 0); /* Mono */
+ res |= i & PCR_DATA_ON ? (1 << 0) : (0 << 0);
+
+ return (res & (TEA5757_DATA | TEA5757_FREQ)) | (ind << 24);
+}
+
+void
+sf64pcr_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
+ int bit)
+{
+ u_int16_t data, wren;
+
+ wren = FM_IO_GPIO | FM_IO_GPIO3_IN | PCR_WREN_ON;
+ data = bit ? PCR_DATA_ON : PCR_DATA_OFF;
+
+ bus_space_write_2(iot, ioh, off, PCR_CLOCK_OFF | wren | data);
+ DELAY(4);
+ bus_space_write_2(iot, ioh, off, PCR_CLOCK_ON | wren | data);
+ DELAY(4);
+ bus_space_write_2(iot, ioh, off, PCR_CLOCK_OFF | wren | data);
+ DELAY(4);
+}
+
+void
+sf64pcr_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset,
+ u_int32_t d)
+{
+ d = FM_IO_GPIO | FM_IO_GPIO3_IN;
+ d |= PCR_WREN_ON | PCR_DATA_ON | PCR_CLOCK_OFF;
+
+ bus_space_write_2(iot, ioh, offset, d);
+ DELAY(4);
+}
+
+void
+sf64pcr_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset,
+ u_int32_t d)
+{
+ /* Do nothing */
+ return;
+}
+
+
+/* Common tuner routines */
+/*
+ * Mute/unmute
+ */
+void
+fmsradio_set_mute(struct fmsradio_if *sc)
+{
+ u_int16_t v, mute, unmute;
+
+ mute = FM_IO_GPIO | FM_IO_GPIO3_IN;
+ switch (sc->card) {
+ case TUNER_SF256PCPR:
+ unmute = FM_IO_GPIO | FM_IO_GPIO3_IN | FM_IO_GPIO2;
+ break;
+ case TUNER_SF64PCR:
+ unmute = FM_IO_GPIO | FM_IO_GPIO3_IN | FM_IO_GPIO1;
+ break;
+ default:
+ return;
+ }
+ v = (sc->mute || !sc->vol) ? mute : unmute;
+ bus_space_write_2(sc->tea.iot, sc->tea.ioh, sc->tea.offset, v);
+}
+
+int
+fmsradio_get_info(void *v, struct radio_info *ri)
+{
+ struct fms_softc *fms_sc = v;
+ struct fmsradio_if *sc = &fms_sc->radio;
+ u_int32_t buf;
+
+ if (sc->card == TUNER_NOT_ATTACHED)
+ return (ENXIO);
+
+ ri->mute = sc->mute;
+ ri->volume = sc->vol ? 255 : 0;
+ ri->stereo = sc->stereo == TEA5757_STEREO ? 1 : 0;
+ ri->lock = tea5757_decode_lock(sc->lock);
+
+ switch (sc->card) {
+ case TUNER_SF256PCPR:
+ ri->caps = SF256PCPR_CAPS;
+ buf = sf256pcpr_hw_read(sc->tea.iot, sc->tea.ioh, sc->tea.offset);
+ ri->info = 0; /* UNSUPPORTED */
+ break;
+ case TUNER_SF64PCR:
+ ri->caps = SF64PCR_CAPS;
+ buf = sf64pcr_hw_read(sc->tea.iot, sc->tea.ioh, sc->tea.offset);
+ ri->info = buf & PCR_INFO_SIGNAL ? 0 : RADIO_INFO_SIGNAL;
+ ri->info |= buf & PCR_INFO_STEREO ? 0 : RADIO_INFO_STEREO;
+ break;
+ default:
+ break;
+ }
+
+ ri->freq = sc->freq = tea5757_decode_freq(buf,
+ sc->tea.flags & TEA5757_TEA5759);
+
+ fmsradio_set_mute(sc);
+
+ /* UNSUPPORTED */
+ ri->rfreq = 0;
+
+ return (0);
+}
+
+int
+fmsradio_set_info(void *v, struct radio_info *ri)
+{
+ struct fms_softc *fms_sc = v;
+ struct fmsradio_if *sc = &fms_sc->radio;
+
+ if (sc->card == TUNER_NOT_ATTACHED)
+ return (ENXIO);
+
+ sc->mute = ri->mute ? 1 : 0;
+ sc->vol = ri->volume ? 255 : 0;
+ sc->stereo = ri->stereo ? TEA5757_STEREO: TEA5757_MONO;
+ sc->lock = tea5757_encode_lock(ri->lock);
+ ri->freq = sc->freq = tea5757_set_freq(&sc->tea,
+ sc->lock, sc->stereo, ri->freq);
+ fmsradio_set_mute(sc);
+
+ return (0);
+}
+
+int
+fmsradio_search(void *v, int f)
+{
+ struct fms_softc *fms_sc = v;
+ struct fmsradio_if *sc = &fms_sc->radio;
+
+ if (sc->card == TUNER_NOT_ATTACHED)
+ return (ENXIO);
+
+ tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
+ fmsradio_set_mute(sc);
+
+ return (0);
+}
diff --git a/sys/dev/pci/fmsradio.h b/sys/dev/pci/fmsradio.h
new file mode 100644
index 00000000000..dc09c5d976d
--- /dev/null
+++ b/sys/dev/pci/fmsradio.h
@@ -0,0 +1,59 @@
+/* $OpenBSD: fmsradio.h,v 1.1 2002/05/06 16:37:43 mickey Exp $ */
+
+/*
+ * Copyright (c) 2002 Vladimir Popov <jumbo@narod.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Device Driver for FM801-based FM Tuners */
+
+/* Currently supported tuners:
+ * o MediaForte SoundForte SF64-PCR PCI Radio Card
+ * o MediaForte SoundForte SF256-PCP-R PCI Sound Card with FM tuner
+ */
+
+#ifndef _FMS_RADIO_H_
+#define _FMS_RADIO_H_
+
+#include <dev/ic/tea5757.h>
+
+struct fmsradio_if {
+ int card; /* Card type */
+
+ int mute;
+ u_int8_t vol;
+ u_int32_t freq;
+ u_int32_t stereo;
+ u_int32_t lock;
+
+ struct tea5757_t tea;
+};
+
+int fmsradio_attach(struct fmsradio_if *, char *);
+
+int fmsradio_get_info(void *, struct radio_info *);
+int fmsradio_set_info(void *, struct radio_info *);
+int fmsradio_search(void *, int);
+
+#endif /* _FMS_RADIO_H_ */
diff --git a/sys/dev/pci/fmsreg.h b/sys/dev/pci/fmsreg.h
new file mode 100644
index 00000000000..6e56e6ac247
--- /dev/null
+++ b/sys/dev/pci/fmsreg.h
@@ -0,0 +1,115 @@
+/* $OpenBSD: fmsreg.h,v 1.1 2002/05/06 16:37:43 mickey Exp $ */
+/* $NetBSD: fms.c,v 1.5.4.1 2000/06/30 16:27:50 simonb Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Witold J. Wnuk.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _DEV_PCI_FMSREG_H_
+#define _DEV_PCI_FMSREG_H_
+
+#define FM_PCM_VOLUME 0x00
+#define FM_FM_VOLUME 0x02
+#define FM_I2S_VOLUME 0x04
+#define FM_RECORD_SOURCE 0x06
+
+#define FM_PLAY_CTL 0x08
+#define FM_PLAY_RATE_MASK 0x0f00
+#define FM_PLAY_BUF1_LAST 0x0001
+#define FM_PLAY_BUF2_LAST 0x0002
+#define FM_PLAY_START 0x0020
+#define FM_PLAY_PAUSE 0x0040
+#define FM_PLAY_STOPNOW 0x0080
+#define FM_PLAY_16BIT 0x4000
+#define FM_PLAY_STEREO 0x8000
+
+#define FM_PLAY_DMALEN 0x0a
+#define FM_PLAY_DMABUF1 0x0c
+#define FM_PLAY_DMABUF2 0x10
+
+
+#define FM_REC_CTL 0x14
+#define FM_REC_RATE_MASK 0x0f00
+#define FM_REC_BUF1_LAST 0x0001
+#define FM_REC_BUF2_LAST 0x0002
+#define FM_REC_START 0x0020
+#define FM_REC_PAUSE 0x0040
+#define FM_REC_STOPNOW 0x0080
+#define FM_REC_16BIT 0x4000
+#define FM_REC_STEREO 0x8000
+
+
+#define FM_REC_DMALEN 0x16
+#define FM_REC_DMABUF1 0x18
+#define FM_REC_DMABUF2 0x1c
+
+#define FM_CODEC_CTL 0x22
+#define FM_VOLUME 0x26
+#define FM_VOLUME_MUTE 0x8000
+
+#define FM_CODEC_CMD 0x2a
+#define FM_CODEC_CMD_READ 0x0080
+#define FM_CODEC_CMD_VALID 0x0100
+#define FM_CODEC_CMD_BUSY 0x0200
+
+#define FM_CODEC_DATA 0x2c
+
+#define FM_IO_CTL 0x52
+#define FM_IO_GPIO 0xf000
+#define FM_IO_GPIO0 0x0001
+#define FM_IO_GPIO1 0x0002
+#define FM_IO_GPIO2 0x0004
+#define FM_IO_GPIO3 0x0008
+#define FM_IO_GPIO0_IN 0x0100 /* 1 - input; 0 - output */
+#define FM_IO_GPIO1_IN 0x0200
+#define FM_IO_GPIO2_IN 0x0400
+#define FM_IO_GPIO3_IN 0x0800
+
+#define FM_CARD_CTL 0x54
+
+#define FM_INTMASK 0x56
+#define FM_INTMASK_PLAY 0x0001
+#define FM_INTMASK_REC 0x0002
+#define FM_INTMASK_VOL 0x0040
+#define FM_INTMASK_MPU 0x0080
+
+#define FM_INTSTATUS 0x5a
+#define FM_INTSTATUS_PLAY 0x0100
+#define FM_INTSTATUS_REC 0x0200
+#define FM_INTSTATUS_VOL 0x4000
+#define FM_INTSTATUS_MPU 0x8000
+
+#endif /* _DEV_PCI_FMSREG_H_ */
diff --git a/sys/dev/pci/fmsvar.h b/sys/dev/pci/fmsvar.h
index 355281e4d77..5bdd53c0eeb 100644
--- a/sys/dev/pci/fmsvar.h
+++ b/sys/dev/pci/fmsvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fmsvar.h,v 1.2 2000/10/14 18:04:07 aaron Exp $ */
+/* $OpenBSD: fmsvar.h,v 1.3 2002/05/06 16:37:43 mickey Exp $ */
/* $NetBSD: fmsvar.h,v 1.1 1999/11/01 21:54:12 augustss Exp $ */
/*-
@@ -59,6 +59,10 @@ struct fms_softc {
struct ac97_codec_if *codec_if;
struct ac97_host_if host_if;
+#if NRADIO > 0
+ struct fmsradio_if radio;
+#endif
+
struct fms_dma *sc_dmas;
void (*sc_pintr)(void *);
diff --git a/sys/dev/pci/sf64pcr.c b/sys/dev/pci/sf64pcr.c
deleted file mode 100644
index 1f2d841b0f1..00000000000
--- a/sys/dev/pci/sf64pcr.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/* $OpenBSD: sf64pcr.c,v 1.4 2002/01/07 18:32:19 mickey Exp $ */
-/* $RuOBSD: sf64pcr.c,v 1.11 2001/12/05 10:19:40 mickey Exp $ */
-
-/*
- * Copyright (c) 2001 Vladimir Popov <jumbo@narod.ru>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* MediaForte SoundForte SF64-PCR PCI Radio Card Device Driver */
-
-/*
- * Philips TEA5757H AM/FM Self Tuned Radio:
- * http://www.semiconductors.philips.com/pip/TEA5757H
- *
- * ForteMedia FM801:
- * ???
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/radioio.h>
-
-#include <machine/bus.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcidevs.h>
-
-#include <dev/radio_if.h>
-#include <dev/ic/tea5757.h>
-
-/* config base I/O address ? */
-#define PCI_CBIO 0x6400
-#define SF64PCR_PCI_OFFSET 0x52
-
-#define CARD_RADIO_CAPS RADIO_CAPS_DETECT_STEREO | \
- RADIO_CAPS_DETECT_SIGNAL | \
- RADIO_CAPS_SET_MONO | \
- RADIO_CAPS_HW_SEARCH | \
- RADIO_CAPS_HW_AFC | \
- RADIO_CAPS_LOCK_SENSITIVITY
-
-#define SF64PCR_MUTE 0xF800
-#define SF64PCR_UNMUTE 0xF802
-
-#define SF64PCR_SIGNAL 0x80
-#define SF64PCR_STEREO 0x80
-
-#define SF64PCR_INFO_STEREO (1 << 24)
-#define SF64PCR_INFO_SIGNAL (1 << 25)
-
-#define SF64PCR_CLCK_ON (1 << 0)
-#define SF64PCR_CLCK_OFF (0 << 0)
-
-#define SF64PCR_WREN1_ON (0 << 1)
-#define SF64PCR_WREN1_OFF (1 << 1)
-
-#define SF64PCR_DATA_ON (1 << 2)
-#define SF64PCR_DATA_OFF (0 << 2)
-
-#define SF64PCR_WREN2_ON (0 << 10)
-#define SF64PCR_WREN2_OFF (1 << 10)
-
-#define SF64PCR_0xF800 0xF800
-
-#define SF64PCR_WRITE_ONE_CLOCK_LOW \
- SF64PCR_0xF800 | \
- SF64PCR_WREN1_ON | \
- SF64PCR_WREN2_ON | \
- SF64PCR_DATA_ON | \
- SF64PCR_CLCK_OFF
-
-/* 0xFC02 */
-#define SF64PCR_READ_CLOCK_LOW \
- SF64PCR_0xF800 | \
- SF64PCR_CLCK_OFF | \
- SF64PCR_WREN1_OFF | \
- SF64PCR_DATA_OFF | \
- SF64PCR_WREN2_OFF
-
-/* 0xFC03 */
-#define SF64PCR_READ_CLOCK_HIGH \
- SF64PCR_0xF800 | \
- SF64PCR_CLCK_ON | \
- SF64PCR_WREN1_OFF | \
- SF64PCR_DATA_OFF | \
- SF64PCR_WREN2_OFF
-
-int sf64pcr_match(struct device *, void *, void *);
-void sf64pcr_attach(struct device *, struct device * self, void *);
-
-int sf64pcr_get_info(void *, struct radio_info *);
-int sf64pcr_set_info(void *, struct radio_info *);
-int sf64pcr_search(void *, int);
-
-/* define our interface to the high-level radio driver */
-struct radio_hw_if sf4r_hw_if = {
- NULL, /* open */
- NULL, /* close */
- sf64pcr_get_info,
- sf64pcr_set_info,
- sf64pcr_search
-};
-
-struct sf64pcr_softc {
- struct device dev;
-
- int mute;
- u_int8_t vol;
- u_int32_t freq;
- u_int32_t stereo;
- u_int32_t lock;
-
- struct tea5757_t tea;
-};
-
-struct cfattach sf4r_ca = {
- sizeof(struct sf64pcr_softc), sf64pcr_match, sf64pcr_attach
-};
-
-struct cfdriver sf4r_cd = {
- NULL, "sf4r", DV_DULL
-};
-
-/*
- * Function prototypes
- */
-void sf64pcr_set_mute(struct sf64pcr_softc *);
-
-void sf64pcr_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
-void sf64pcr_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
-void sf64pcr_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
-u_int32_t sf64pcr_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-
-/*
- * PCI initialization stuff
- */
-int
-sf64pcr_match(struct device *parent, void *match, void *aux)
-{
- struct pci_attach_args *pa = aux;
- /* FIXME: more thorough testing */
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_FORTEMEDIA &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_FORTEMEDIA_FM801)
- return (1);
- return (0);
-}
-
-void
-sf64pcr_attach(struct device *parent, struct device *self, void *aux)
-{
- struct sf64pcr_softc *sc = (struct sf64pcr_softc *) self;
- struct pci_attach_args *pa = aux;
- struct cfdata *cf = sc->dev.dv_cfdata;
- pci_chipset_tag_t pc = pa->pa_pc;
- pcireg_t csr;
-
- if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
- &sc->tea.iot, &sc->tea.ioh, NULL, NULL, 0)) {
- printf(": can't map i/o space\n");
- return;
- }
-
- /* Enable the card */
- csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
- pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
- csr | PCI_COMMAND_MASTER_ENABLE);
-
- sc->vol = 0;
- sc->mute = 0;
- sc->freq = MIN_FM_FREQ;
- sc->stereo = TEA5757_STEREO;
- sc->lock = TEA5757_S030;
- sc->tea.offset = SF64PCR_PCI_OFFSET;
- sc->tea.flags = cf->cf_flags;
- sc->tea.init = sf64pcr_init;
- sc->tea.rset = sf64pcr_rset;
- sc->tea.write_bit = sf64pcr_write_bit;
- sc->tea.read = sf64pcr_hw_read;
-
- printf(": SoundForte RadioLink SF64-PCR PCI\n");
-
- tea5757_set_freq(&sc->tea, sc->lock, sc->stereo, sc->freq);
- sf64pcr_set_mute(sc);
-
- radio_attach_mi(&sf4r_hw_if, sc, &sc->dev);
-}
-
-/*
- * Mute/unmute
- */
-void
-sf64pcr_set_mute(struct sf64pcr_softc *sc)
-{
- u_int16_t mute;
-
- mute = (sc->mute || !sc->vol) ? SF64PCR_MUTE : SF64PCR_UNMUTE;
- bus_space_write_2(sc->tea.iot, sc->tea.ioh, sc->tea.offset, mute);
-}
-
-void
-sf64pcr_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh,
- bus_size_t off, int bit)
-{
- u_int16_t data, wren;
-
- wren = SF64PCR_0xF800 | SF64PCR_WREN1_ON | SF64PCR_WREN2_ON;
- data = bit ? SF64PCR_DATA_ON : SF64PCR_DATA_OFF;
-
- bus_space_write_2(iot, ioh, off, SF64PCR_CLCK_OFF | wren | data);
- DELAY(4);
- bus_space_write_2(iot, ioh, off, SF64PCR_CLCK_ON | wren | data);
- DELAY(4);
- bus_space_write_2(iot, ioh, off, SF64PCR_CLCK_OFF | wren | data);
- DELAY(4);
-}
-
-void
-sf64pcr_init(bus_space_tag_t iot, bus_space_handle_t ioh,
- bus_size_t offset, u_int32_t d)
-{
- d = SF64PCR_WRITE_ONE_CLOCK_LOW;
-
- bus_space_write_2(iot, ioh, offset, d);
- DELAY(4);
-}
-
-void
-sf64pcr_rset(bus_space_tag_t iot, bus_space_handle_t ioh,
- bus_size_t offset, u_int32_t d)
-{
- /* Do nothing */
- return;
-}
-
-/*
- * Read TEA5757 shift register
- */
-u_int32_t
-sf64pcr_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
-{
- u_int32_t res = 0ul;
- int rb, ind = 0;
-
- bus_space_write_2(iot, ioh, offset, SF64PCR_READ_CLOCK_LOW);
- DELAY(4);
-
- /* Read the register */
- rb = 23;
- while (rb--) {
- bus_space_write_2(iot, ioh, offset, SF64PCR_READ_CLOCK_HIGH);
- DELAY(4);
-
- bus_space_write_2(iot, ioh, offset, SF64PCR_READ_CLOCK_LOW);
- DELAY(4);
-
- res |= bus_space_read_2(iot, ioh, offset) & SF64PCR_DATA_ON ?
- 1 : 0;
- res <<= 1;
- }
-
- bus_space_write_2(iot, ioh, offset, SF64PCR_READ_CLOCK_HIGH);
- DELAY(4);
-
- rb = bus_space_read_1(iot, ioh, offset);
- ind = rb & SF64PCR_SIGNAL ? (1 << 1) : (0 << 1); /* Tuning */
-
- bus_space_write_2(iot, ioh, offset, SF64PCR_READ_CLOCK_LOW);
-
- rb = bus_space_read_2(iot, ioh, offset);
- ind |= rb & SF64PCR_STEREO ? (1 << 0) : (0 << 0); /* Mono */
- res |= rb & SF64PCR_DATA_ON ? 1 : 0;
-
- return (res & (TEA5757_DATA | TEA5757_FREQ)) | (ind << 24);
-}
-
-int
-sf64pcr_get_info(void *v, struct radio_info *ri)
-{
- struct sf64pcr_softc *sc = v;
- u_int32_t buf;
-
- ri->mute = sc->mute;
- ri->volume = sc->vol ? 255 : 0;
- ri->stereo = sc->stereo == TEA5757_STEREO ? 1 : 0;
- ri->caps = CARD_RADIO_CAPS;
- ri->rfreq = 0;
- ri->lock = tea5757_decode_lock(sc->lock);
-
- buf = sf64pcr_hw_read(sc->tea.iot, sc->tea.ioh, sc->tea.offset);
- ri->freq = sc->freq = tea5757_decode_freq(buf,
- sc->tea.flags & TEA5757_TEA5759);
- ri->info = buf & SF64PCR_INFO_SIGNAL ? 0 : RADIO_INFO_SIGNAL;
- ri->info |= buf & SF64PCR_INFO_STEREO ? 0 : RADIO_INFO_STEREO;
-
- return (0);
-}
-
-int
-sf64pcr_set_info(void *v, struct radio_info *ri)
-{
-
- struct sf64pcr_softc *sc = v;
-
- sc->mute = ri->mute ? 1 : 0;
- sc->vol = ri->volume ? 255 : 0;
- sc->stereo = ri->stereo ? TEA5757_STEREO: TEA5757_MONO;
- sc->lock = tea5757_encode_lock(ri->lock);
- ri->freq = sc->freq = tea5757_set_freq(&sc->tea,
- sc->lock, sc->stereo, ri->freq);
- sf64pcr_set_mute(sc);
-
- return (0);
-}
-
-int
-sf64pcr_search(void *v, int f)
-{
- struct sf64pcr_softc *sc = v;
-
- tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
- sf64pcr_set_mute(sc);
-
- return (0);
-}