Add support for radio cards. Written by Maxim Tsyplakov and Vladimir Popov
for OpenBSD, from where it was imported.
This commit is contained in:
parent
cdf2a29382
commit
1c06f6a40f
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files,v 1.486 2001/12/17 15:40:43 atatat Exp $
|
||||
# $NetBSD: files,v 1.487 2002/01/01 21:51:39 augustss Exp $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
@ -201,6 +201,7 @@ define ata {[channel = -1], [drive = -1]}
|
||||
define atapi {[channel = -1]}
|
||||
define mii {[phy = -1]}
|
||||
define irbus { }
|
||||
define radio { }
|
||||
|
||||
# audio device attributes
|
||||
#
|
||||
@ -738,7 +739,14 @@ file dev/ic/ate_subr.c ate
|
||||
# Crystal Semiconductor CS8900, CS8920, and CS8920M Ethernet
|
||||
#
|
||||
device cs: arp, ether, ifnet
|
||||
file dev/ic/cs89x0.c cs
|
||||
file dev/ic/cs89x0.c cs
|
||||
|
||||
# Radio device attributes
|
||||
#
|
||||
define tea5757
|
||||
file dev/ic/tea5757.c tea5757
|
||||
define lm700x
|
||||
file dev/ic/lm700x.c lm700x
|
||||
|
||||
# Definitions for wscons
|
||||
# device attributes: display, display with emulator, keyboard, and mouse
|
||||
@ -801,6 +809,10 @@ file dev/usb/ohci.c ohci needs-flag
|
||||
device ehci: usbus
|
||||
file dev/usb/ehci.c ehci needs-flag
|
||||
|
||||
# radio devices, attaches to radio hardware driver
|
||||
device radio
|
||||
attach radio at radio
|
||||
|
||||
# IEEE 1394 controllers
|
||||
# (These need to be here since it will have both PCI and CardBus attachments)
|
||||
#
|
||||
@ -946,6 +958,7 @@ file dev/md.c md needs-count
|
||||
file dev/midi.c midi | midibus needs-flag
|
||||
file dev/midisyn.c midisyn
|
||||
file dev/mulaw.c mulaw
|
||||
file dev/radio.c radio needs-flag
|
||||
file dev/raidframe/rf_acctrace.c raid needs-flag
|
||||
file dev/raidframe/rf_alloclist.c raid needs-flag
|
||||
file dev/raidframe/rf_aselect.c raid needs-flag
|
||||
|
131
sys/dev/ic/lm700x.c
Normal file
131
sys/dev/ic/lm700x.c
Normal file
@ -0,0 +1,131 @@
|
||||
/* $NetBSD: lm700x.c,v 1.1 2002/01/01 21:51:40 augustss Exp $ */
|
||||
/* $OpenBSD: lm700x.c,v 1.2 2001/12/06 16:28:18 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 ``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 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.
|
||||
*/
|
||||
|
||||
/* Implementation of most common lm700x routines */
|
||||
|
||||
/*
|
||||
* Sanyo LM7001 Direct PLL Frequency Synthesizer
|
||||
* ??? See http://www.redsword.com/tjacobs/geeb/fmcard.htm
|
||||
*
|
||||
* The LM7001J and LM7001JM (used in Aztech/PackardBell cards) are PLL
|
||||
* frequency synthesizer LSIs for tuners. These LSIs are software compatible
|
||||
* with LM7000 (used in Radiotrack, Radioreveal RA300, some Mediaforte cards),
|
||||
* but do not include an IF calculation circuit.
|
||||
*
|
||||
* The FM VCO circuit includes a high-speed programmable divider that can
|
||||
* divide directly.
|
||||
*
|
||||
* Features:
|
||||
* Seven reference frequencies: 1, 5, 9, 10, 25, 50, and 100 kHz;
|
||||
* Band-switching outputs (3 bits);
|
||||
* Controller clock output (400 kHz);
|
||||
* Serial input circuit for data input (using the CE, CL and DATA pins).
|
||||
*
|
||||
* The LM7001J and LM7001JM have a 24-bit shift register.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <dev/ic/lm700x.h>
|
||||
|
||||
u_int32_t
|
||||
lm700x_encode_freq(u_int32_t nfreq, u_int32_t rf)
|
||||
{
|
||||
nfreq += IF_FREQ;
|
||||
nfreq /= lm700x_decode_ref(rf);
|
||||
return nfreq;
|
||||
}
|
||||
|
||||
void
|
||||
lm700x_hardware_write(struct lm700x_t *lm, u_int32_t data, u_int32_t addon)
|
||||
{
|
||||
int i;
|
||||
|
||||
lm->init(lm->iot, lm->ioh, lm->offset, lm->rsetdata | addon);
|
||||
|
||||
for (i = 0; i < LM700X_REGISTER_LENGTH; i++)
|
||||
if (data & (1 << i)) {
|
||||
bus_space_write_1(lm->iot, lm->ioh, lm->offset,
|
||||
lm->wocl | addon);
|
||||
DELAY(LM700X_WRITE_DELAY);
|
||||
bus_space_write_1(lm->iot, lm->ioh, lm->offset,
|
||||
lm->woch | addon);
|
||||
DELAY(LM700X_WRITE_DELAY);
|
||||
bus_space_write_1(lm->iot, lm->ioh, lm->offset,
|
||||
lm->wocl | addon);
|
||||
} else {
|
||||
bus_space_write_1(lm->iot, lm->ioh, lm->offset,
|
||||
lm->wzcl | addon);
|
||||
DELAY(LM700X_WRITE_DELAY);
|
||||
bus_space_write_1(lm->iot, lm->ioh, lm->offset,
|
||||
lm->wzch | addon);
|
||||
DELAY(LM700X_WRITE_DELAY);
|
||||
bus_space_write_1(lm->iot, lm->ioh, lm->offset,
|
||||
lm->wzcl | addon);
|
||||
}
|
||||
|
||||
lm->rset(lm->iot, lm->ioh, lm->offset, lm->rsetdata | addon);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
lm700x_encode_ref(u_int8_t rf)
|
||||
{
|
||||
u_int32_t ret;
|
||||
|
||||
if (rf < 36)
|
||||
ret = LM700X_REF_025;
|
||||
else if (rf > 35 && rf < 75)
|
||||
ret = LM700X_REF_050;
|
||||
else
|
||||
ret = LM700X_REF_100;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u_int8_t
|
||||
lm700x_decode_ref(u_int32_t rf)
|
||||
{
|
||||
u_int8_t ret;
|
||||
|
||||
switch (rf) {
|
||||
case LM700X_REF_100:
|
||||
ret = 100;
|
||||
break;
|
||||
case LM700X_REF_025:
|
||||
ret = 25;
|
||||
break;
|
||||
case LM700X_REF_050:
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
ret = 50;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
80
sys/dev/ic/lm700x.h
Normal file
80
sys/dev/ic/lm700x.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* $NetBSD: lm700x.h,v 1.1 2002/01/01 21:51:40 augustss Exp $ */
|
||||
/* $OpenBSD: lm700x.h,v 1.2 2001/12/06 16:28:18 mickey Exp $ */
|
||||
/* $RuOBSD: lm700x.h,v 1.2 2001/10/18 16:51:36 pva 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 ``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 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 _LM700X_H_
|
||||
#define _LM700X_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#define LM700X_REGISTER_LENGTH 24
|
||||
|
||||
#define LM700X_DATA_MASK 0xFFC000
|
||||
#define LM700X_FREQ_MASK 0x003FFF
|
||||
|
||||
#define LM700X_FREQ(x) (x << 0) /* 0x003FFF */
|
||||
#define LM700X_LSI(x) (x << 14) /* 0x00C000 */ /* always zero */
|
||||
#define LM700X_BAND(x) (x << 16) /* 0x070000 */
|
||||
#define LM700X_STEREO LM700X_BAND(3)
|
||||
#define LM700X_MONO LM700X_BAND(1)
|
||||
#define LM700X_TIME_BASE(x) (x << 19) /* 0x080000 */ /* always zero */
|
||||
#define LM700X_REF_FREQ(x) (x << 20) /* 0x700000 */
|
||||
#define LM700X_REF_100 LM700X_REF_FREQ(0)
|
||||
#define LM700X_REF_025 LM700X_REF_FREQ(2)
|
||||
#define LM700X_REF_050 LM700X_REF_FREQ(4)
|
||||
/* The rest is for an AM band */
|
||||
|
||||
#define LM700X_DIVIDER_AM (0 << 23) /* 0x000000 */
|
||||
#define LM700X_DIVIDER_FM (1 << 23) /* 0x800000 */
|
||||
|
||||
#define LM700X_WRITE_DELAY 6 /* 6 microseconds */
|
||||
|
||||
struct lm700x_t {
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
bus_size_t offset;
|
||||
|
||||
u_int32_t wzcl; /* write zero clock low */
|
||||
u_int32_t wzch; /* write zero clock high */
|
||||
u_int32_t wocl; /* write one clock low */
|
||||
u_int32_t woch; /* write one clock high */
|
||||
u_int32_t initdata;
|
||||
u_int32_t rsetdata;
|
||||
|
||||
void (*init)(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void (*rset)(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
};
|
||||
|
||||
u_int32_t lm700x_encode_freq(u_int32_t, u_int32_t);
|
||||
u_int32_t lm700x_encode_ref(u_int8_t);
|
||||
u_int8_t lm700x_decode_ref(u_int32_t);
|
||||
void lm700x_hardware_write(struct lm700x_t *, u_int32_t, u_int32_t);
|
||||
|
||||
#endif /* _LM700X_H_ */
|
187
sys/dev/ic/tea5757.c
Normal file
187
sys/dev/ic/tea5757.c
Normal file
@ -0,0 +1,187 @@
|
||||
/* $NetBSD: tea5757.c,v 1.1 2002/01/01 21:51:40 augustss Exp $ */
|
||||
/* $OpenBSD: tea5757.c,v 1.2 2001/12/06 16:28:18 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 ``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 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.
|
||||
*/
|
||||
|
||||
/* Implementation of most common TEA5757 routines */
|
||||
|
||||
/*
|
||||
* Philips TEA5757H Self Tuned Radio
|
||||
* http://www.semiconductors.philips.com/pip/TEA5757H
|
||||
*
|
||||
* The TEA5757; TEA5759 is a 44-pin integrated AM/FM stereo radio circuit.
|
||||
* The radio part is based on the TEA5712.
|
||||
*
|
||||
* The TEA5757 is used in FM-standards in which the local oscillator
|
||||
* frequency is above the radio frequency (e.g. European and American
|
||||
* standards). The TEA5759 is the version in which the oscillator frequency
|
||||
* is below the radio frequency (e.g. Japanese standard).
|
||||
*
|
||||
* The TEA5757; TEA5759 radio has a bus which consists of three wires:
|
||||
* BUS-CLOCK: software driven clock input
|
||||
* DATA: data input/output
|
||||
* WRITE-ENABLE: write/read input
|
||||
*
|
||||
* The TEA5757; TEA5759 has a 25-bit shift register.
|
||||
*
|
||||
* The chips are used in Radiotrack II, Guillemot Maxi Radio FM 2000,
|
||||
* Gemtek PCI cards and most Mediaforte FM tuners and sound cards with
|
||||
* integrated FM tuners.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <dev/ic/tea5757.h>
|
||||
|
||||
/*
|
||||
* Convert frequency to hardware representation
|
||||
*/
|
||||
u_int32_t
|
||||
tea5757_encode_freq(u_int32_t freq)
|
||||
{
|
||||
#ifdef RADIO_TEA5759
|
||||
freq -= IF_FREQ;
|
||||
#else
|
||||
freq += IF_FREQ;
|
||||
#endif /* RADIO_TEA5759 */
|
||||
/*
|
||||
* NO FLOATING POINT!
|
||||
*/
|
||||
freq *= 10;
|
||||
freq /= 125;
|
||||
return freq & TEA5757_FREQ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert frequency from hardware representation
|
||||
*/
|
||||
u_int32_t
|
||||
tea5757_decode_freq(u_int32_t freq)
|
||||
{
|
||||
freq &= TEA5757_FREQ;
|
||||
freq *= 125; /* 12.5 kHz */
|
||||
freq /= 10;
|
||||
#ifdef RADIO_TEA5759
|
||||
freq += IF_FREQ;
|
||||
#else
|
||||
freq -= IF_FREQ;
|
||||
#endif /* RADIO_TEA5759 */
|
||||
return freq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware search
|
||||
*/
|
||||
void
|
||||
tea5757_search(struct tea5757_t *tea, u_int32_t stereo, u_int32_t lock, int dir)
|
||||
{
|
||||
u_int32_t reg;
|
||||
u_int co = 0;
|
||||
|
||||
reg = stereo | lock | TEA5757_SEARCH_START;
|
||||
reg |= dir ? TEA5757_SEARCH_UP : TEA5757_SEARCH_DOWN;
|
||||
tea5757_hardware_write(tea, reg);
|
||||
|
||||
DELAY(TEA5757_ACQUISITION_DELAY);
|
||||
|
||||
do {
|
||||
DELAY(TEA5757_WAIT_DELAY);
|
||||
reg = tea->read(tea->iot, tea->ioh, tea->offset);
|
||||
} while ((reg & TEA5757_FREQ) == 0 && ++co < 200);
|
||||
}
|
||||
|
||||
void
|
||||
tea5757_hardware_write(struct tea5757_t *tea, u_int32_t data)
|
||||
{
|
||||
int i = TEA5757_REGISTER_LENGTH;
|
||||
|
||||
tea->init(tea->iot, tea->ioh, tea->offset, 0);
|
||||
|
||||
while (i--)
|
||||
if (data & (1 << i))
|
||||
tea->write_bit(tea->iot, tea->ioh, tea->offset, 1);
|
||||
else
|
||||
tea->write_bit(tea->iot, tea->ioh, tea->offset, 0);
|
||||
|
||||
tea->rset(tea->iot, tea->ioh, tea->offset, 0);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
tea5757_set_freq(struct tea5757_t *tea, u_int32_t stereo, u_int32_t lock, u_int32_t freq)
|
||||
{
|
||||
u_int32_t data = 0ul;
|
||||
|
||||
if (freq < MIN_FM_FREQ)
|
||||
freq = MIN_FM_FREQ;
|
||||
if (freq > MAX_FM_FREQ)
|
||||
freq = MAX_FM_FREQ;
|
||||
|
||||
data = tea5757_encode_freq(freq) | stereo | lock | TEA5757_SEARCH_END;
|
||||
tea5757_hardware_write(tea, data);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
tea5757_encode_lock(u_int8_t lock)
|
||||
{
|
||||
u_int32_t ret;
|
||||
|
||||
if (lock < 8)
|
||||
ret = TEA5757_S005;
|
||||
else if (lock > 7 && lock < 15)
|
||||
ret = TEA5757_S010;
|
||||
else if (lock > 14 && lock < 51)
|
||||
ret = TEA5757_S030;
|
||||
else if (lock > 50)
|
||||
ret = TEA5757_S150;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u_int8_t
|
||||
tea5757_decode_lock(u_int32_t lock)
|
||||
{
|
||||
u_int8_t ret = 150;
|
||||
|
||||
switch (lock) {
|
||||
case TEA5757_S005:
|
||||
ret = 5;
|
||||
break;
|
||||
case TEA5757_S010:
|
||||
ret = 10;
|
||||
break;
|
||||
case TEA5757_S030:
|
||||
ret = 30;
|
||||
break;
|
||||
case TEA5757_S150:
|
||||
ret = 150;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
89
sys/dev/ic/tea5757.h
Normal file
89
sys/dev/ic/tea5757.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* $NetBSD: tea5757.h,v 1.1 2002/01/01 21:51:40 augustss Exp $ */
|
||||
/* $OpenBSD: tea5757.h,v 1.2 2001/12/06 16:28:18 mickey Exp $ */
|
||||
/* $RuOBSD: tea5757.h,v 1.2 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Vladimir Popov <jumbo@narod.ru>
|
||||
*
|
||||
* 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 ``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 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 _TEA5757_H_
|
||||
#define _TEA5757_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#define TEA5757_REGISTER_LENGTH 25
|
||||
#define TEA5757_FREQ 0x0007FFF
|
||||
#define TEA5757_DATA 0x1FF8000
|
||||
|
||||
#define TEA5757_SEARCH_START (1 << 24) /* 0x1000000 */
|
||||
#define TEA5757_SEARCH_END (0 << 24) /* 0x0000000 */
|
||||
|
||||
#define TEA5757_SEARCH_UP (1 << 23) /* 0x0800000 */
|
||||
#define TEA5757_SEARCH_DOWN (0 << 23) /* 0x0000000 */
|
||||
#define TEA5757_ACQUISITION_DELAY 100000
|
||||
#define TEA5757_WAIT_DELAY 1000
|
||||
#define TEA5757_SEARCH_DELAY 14 /* 14 microseconds */
|
||||
|
||||
#define TEA5757_STEREO (0 << 22) /* 0x0000000 */
|
||||
#define TEA5757_MONO (1 << 22) /* 0x0400000 */
|
||||
|
||||
#define TEA5757_BAND_FM (0 << 20)
|
||||
#define TEA5757_BAND_MW (1 << 20)
|
||||
#define TEA5757_BAND_LW (2 << 20)
|
||||
#define TEA5757_BAND_SW (3 << 20)
|
||||
|
||||
#define TEA5757_USER_PORT (0 << 18)
|
||||
#define TEA5757_DUMMY (0 << 15)
|
||||
|
||||
#define TEA5757_S005 (0 << 16) /* 0x0000000 * > 5 mkV */
|
||||
#define TEA5757_S010 (2 << 16) /* 0x0020000 * > 10 mkV */
|
||||
#define TEA5757_S030 (1 << 16) /* 0x0010000 * > 30 mkV */
|
||||
#define TEA5757_S150 (3 << 16) /* 0x0030000 * > 150 mkV */
|
||||
|
||||
struct tea5757_t {
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
bus_size_t offset;
|
||||
|
||||
void (*init)(bus_space_tag_t, bus_space_handle_t, bus_size_t,
|
||||
u_int32_t); /* init value */
|
||||
void (*rset)(bus_space_tag_t, bus_space_handle_t, bus_size_t,
|
||||
u_int32_t); /* reset value */
|
||||
void (*write_bit)(bus_space_tag_t, bus_space_handle_t, bus_size_t,
|
||||
int); /* the bit */
|
||||
u_int32_t (*read)(bus_space_tag_t, bus_space_handle_t, bus_size_t);
|
||||
};
|
||||
|
||||
u_int32_t tea5757_encode_freq(u_int32_t);
|
||||
u_int32_t tea5757_decode_freq(u_int32_t);
|
||||
u_int32_t tea5757_encode_lock(u_int8_t);
|
||||
u_int8_t tea5757_decode_lock(u_int32_t);
|
||||
|
||||
u_int32_t tea5757_set_freq(struct tea5757_t *, u_int32_t, u_int32_t, u_int32_t);
|
||||
void tea5757_search(struct tea5757_t *, u_int32_t, u_int32_t, int);
|
||||
|
||||
void tea5757_hardware_write(struct tea5757_t *, u_int32_t);
|
||||
|
||||
#endif /* _TEA5757_H_ */
|
341
sys/dev/isa/aztech.c
Normal file
341
sys/dev/isa/aztech.c
Normal file
@ -0,0 +1,341 @@
|
||||
/* $NetBSD: aztech.c,v 1.1 2002/01/01 21:51:41 augustss Exp $ */
|
||||
/* $OpenBSD: aztech.c,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: aztech.c,v 1.11 2001/10/20 13:23:47 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>,
|
||||
* 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 AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
/* Aztech/PackardBell FM Radio Card device driver */
|
||||
|
||||
/*
|
||||
* Sanyo LM7001J Direct PLL Frequency Synthesizer:
|
||||
* ??? See http://www.redsword.com/tjacobs/geeb/fmcard.htm
|
||||
*
|
||||
* Philips TEA5712T AM/FM Stereo DTS Radio:
|
||||
* http://www.semiconductors.philips.com/pip/TEA5712
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/ic/lm700x.h>
|
||||
#include <dev/radio_if.h>
|
||||
|
||||
#define RF_25K 25
|
||||
#define RF_50K 50
|
||||
#define RF_100K 100
|
||||
|
||||
#define MAX_VOL 3
|
||||
#define VOLUME_RATIO(x) (255 * x / MAX_VOL)
|
||||
|
||||
#define AZ_BASE_VALID(x) ((x == 0x350) || (x == 0x358))
|
||||
#define AZTECH_CAPABILITIES RADIO_CAPS_DETECT_STEREO | \
|
||||
RADIO_CAPS_DETECT_SIGNAL | \
|
||||
RADIO_CAPS_SET_MONO | \
|
||||
RADIO_CAPS_REFERENCE_FREQ
|
||||
|
||||
#define AZ_WREN_ON (1 << 1)
|
||||
#define AZ_WREN_OFF (0 << 1)
|
||||
|
||||
#define AZ_CLCK_ON (1 << 6)
|
||||
#define AZ_CLCK_OFF (0 << 6)
|
||||
|
||||
#define AZ_DATA_ON (1 << 7)
|
||||
#define AZ_DATA_OFF (0 << 7)
|
||||
|
||||
int az_probe(struct device *, struct cfdata *, void *);
|
||||
void az_attach(struct device *, struct device * self, void *);
|
||||
|
||||
int az_get_info(void *, struct radio_info *);
|
||||
int az_set_info(void *, struct radio_info *);
|
||||
|
||||
struct radio_hw_if az_hw_if = {
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
az_get_info,
|
||||
az_set_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct az_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
int mute;
|
||||
u_int8_t vol;
|
||||
u_int32_t freq;
|
||||
u_int32_t rf;
|
||||
u_int32_t stereo;
|
||||
|
||||
struct lm700x_t lm;
|
||||
};
|
||||
|
||||
struct cfattach az_ca = {
|
||||
sizeof(struct az_softc), az_probe, az_attach
|
||||
};
|
||||
|
||||
u_int az_find(bus_space_tag_t, bus_space_handle_t);
|
||||
void az_set_mute(struct az_softc *);
|
||||
void az_set_freq(struct az_softc *, u_int32_t);
|
||||
u_int8_t az_state(bus_space_tag_t, bus_space_handle_t);
|
||||
|
||||
void az_lm700x_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void az_lm700x_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
|
||||
u_int8_t az_conv_vol(u_int8_t);
|
||||
u_int8_t az_unconv_vol(u_int8_t);
|
||||
|
||||
int
|
||||
az_probe(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
bus_space_tag_t iot = ia->ia_iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
||||
int iosize = 1, iobase = ia->ia_iobase;
|
||||
|
||||
if (!AZ_BASE_VALID(iobase)) {
|
||||
printf("az: configured iobase 0x%x invalid", iobase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bus_space_map(iot, iobase, iosize, 0, &ioh))
|
||||
return 0;
|
||||
|
||||
bus_space_unmap(iot, ioh, iosize);
|
||||
|
||||
if (!az_find(iot, ioh))
|
||||
return 0;
|
||||
|
||||
ia->ia_iosize = iosize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
az_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct az_softc *sc = (void *)self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
sc->lm.iot = ia->ia_iot;
|
||||
sc->rf = LM700X_REF_050;
|
||||
sc->stereo = LM700X_STEREO;
|
||||
sc->mute = 0;
|
||||
sc->freq = MIN_FM_FREQ;
|
||||
sc->vol = 0;
|
||||
|
||||
/* remap I/O */
|
||||
if (bus_space_map(sc->lm.iot, ia->ia_iobase, ia->ia_iosize,
|
||||
0, &sc->lm.ioh))
|
||||
panic(": bus_space_map() of %s failed", sc->sc_dev.dv_xname);
|
||||
|
||||
printf(": Aztech/PackardBell");
|
||||
|
||||
/* Configure struct lm700x_t lm */
|
||||
sc->lm.offset = 0;
|
||||
sc->lm.wzcl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_OFF;
|
||||
sc->lm.wzch = AZ_WREN_ON | AZ_CLCK_ON | AZ_DATA_OFF;
|
||||
sc->lm.wocl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_ON;
|
||||
sc->lm.woch = AZ_WREN_ON | AZ_CLCK_ON | AZ_DATA_ON;
|
||||
sc->lm.initdata = 0;
|
||||
sc->lm.rsetdata = AZ_DATA_ON | AZ_CLCK_ON | AZ_WREN_OFF;
|
||||
sc->lm.init = az_lm700x_init;
|
||||
sc->lm.rset = az_lm700x_rset;
|
||||
|
||||
az_set_freq(sc, sc->freq);
|
||||
|
||||
radio_attach_mi(&az_hw_if, sc, &sc->sc_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mute the card
|
||||
*/
|
||||
void
|
||||
az_set_mute(struct az_softc *sc)
|
||||
{
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
sc->mute ? 0 : sc->vol);
|
||||
delay(6);
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
sc->mute ? 0 : sc->vol);
|
||||
}
|
||||
|
||||
void
|
||||
az_set_freq(struct az_softc *sc, u_int32_t nfreq)
|
||||
{
|
||||
u_int8_t vol;
|
||||
u_int32_t reg;
|
||||
|
||||
vol = sc->mute ? 0 : sc->vol;
|
||||
|
||||
if (nfreq > MAX_FM_FREQ)
|
||||
nfreq = MAX_FM_FREQ;
|
||||
if (nfreq < MIN_FM_FREQ)
|
||||
nfreq = MIN_FM_FREQ;
|
||||
|
||||
sc->freq = nfreq;
|
||||
|
||||
reg = lm700x_encode_freq(nfreq, sc->rf);
|
||||
reg |= sc->stereo | sc->rf | LM700X_DIVIDER_FM;
|
||||
|
||||
lm700x_hardware_write(&sc->lm, reg, vol);
|
||||
|
||||
az_set_mute(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return state of the card - tuned/not tuned, mono/stereo
|
||||
*/
|
||||
u_int8_t
|
||||
az_state(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
return (3 ^ bus_space_read_1(iot, ioh, 0)) & 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert volume to hardware representation.
|
||||
* The card uses bits 00000x0x to set volume.
|
||||
*/
|
||||
u_int8_t
|
||||
az_conv_vol(u_int8_t vol)
|
||||
{
|
||||
if (vol < VOLUME_RATIO(1))
|
||||
return 0;
|
||||
else if (vol >= VOLUME_RATIO(1) && vol < VOLUME_RATIO(2))
|
||||
return 1;
|
||||
else if (vol >= VOLUME_RATIO(2) && vol < VOLUME_RATIO(3))
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert volume from hardware representation
|
||||
*/
|
||||
u_int8_t
|
||||
az_unconv_vol(u_int8_t vol)
|
||||
{
|
||||
switch (vol) {
|
||||
case 0:
|
||||
return VOLUME_RATIO(0);
|
||||
case 1:
|
||||
return VOLUME_RATIO(1);
|
||||
case 4:
|
||||
return VOLUME_RATIO(2);
|
||||
}
|
||||
return VOLUME_RATIO(3);
|
||||
}
|
||||
|
||||
u_int
|
||||
az_find(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
struct az_softc sc;
|
||||
u_int i, scanres = 0;
|
||||
|
||||
sc.lm.iot = iot;
|
||||
sc.lm.ioh = ioh;
|
||||
sc.lm.offset = 0;
|
||||
sc.lm.wzcl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_OFF;
|
||||
sc.lm.wzch = AZ_WREN_ON | AZ_CLCK_ON | AZ_DATA_OFF;
|
||||
sc.lm.wocl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_ON;
|
||||
sc.lm.woch = AZ_WREN_ON | AZ_CLCK_ON | AZ_DATA_ON;
|
||||
sc.lm.initdata = 0;
|
||||
sc.lm.rsetdata = AZ_DATA_ON | AZ_CLCK_ON | AZ_WREN_OFF;
|
||||
sc.lm.init = az_lm700x_init;
|
||||
sc.lm.rset = az_lm700x_rset;
|
||||
sc.rf = LM700X_REF_050;
|
||||
sc.mute = 0;
|
||||
sc.stereo = LM700X_STEREO;
|
||||
sc.vol = 0;
|
||||
|
||||
/*
|
||||
* Scan whole FM range. If there is a card it'll
|
||||
* respond on some frequency.
|
||||
*/
|
||||
for (i = MIN_FM_FREQ; !scanres && i < MAX_FM_FREQ; i += 10) {
|
||||
az_set_freq(&sc, i);
|
||||
scanres += 3 - az_state(iot, ioh);
|
||||
}
|
||||
|
||||
return scanres;
|
||||
}
|
||||
|
||||
void
|
||||
az_lm700x_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
|
||||
u_int32_t data)
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
az_lm700x_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
|
||||
u_int32_t data)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, data);
|
||||
}
|
||||
|
||||
int
|
||||
az_get_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct az_softc *sc = v;
|
||||
|
||||
ri->mute = sc->mute;
|
||||
ri->volume = az_unconv_vol(sc->vol);
|
||||
ri->stereo = sc->stereo == LM700X_STEREO ? 1 : 0;
|
||||
ri->caps = AZTECH_CAPABILITIES;
|
||||
ri->rfreq = lm700x_decode_ref(sc->rf);
|
||||
ri->info = az_state(sc->lm.iot, sc->lm.ioh);
|
||||
ri->freq = sc->freq;
|
||||
|
||||
/* UNSUPPORTED */
|
||||
ri->lock = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
az_set_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct az_softc *sc = v;
|
||||
|
||||
sc->mute = ri->mute ? 1 : 0;
|
||||
sc->vol = az_conv_vol(ri->volume);
|
||||
sc->stereo = ri->stereo ? LM700X_STEREO : LM700X_MONO;
|
||||
sc->rf = lm700x_encode_ref(ri->rfreq);
|
||||
|
||||
az_set_freq(sc, ri->freq);
|
||||
az_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.isa,v 1.120 2001/12/16 22:35:31 thorpej Exp $
|
||||
# $NetBSD: files.isa,v 1.121 2002/01/01 21:51:41 augustss Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent ISA code.
|
||||
# Included by ports that need it. Requires that the SCSI files be
|
||||
@ -414,6 +414,26 @@ file dev/isa/pcdisplay.c pcdisplay needs-flag
|
||||
defpseudo pcweasel: sysmon_wdog
|
||||
file dev/isa/weasel_isa.c pcweasel needs-flag
|
||||
|
||||
# Sound Forte RadioLink SF16-FMR2 FM Radio Card
|
||||
device sf2r: radio, tea5757
|
||||
attach sf2r at isa
|
||||
file dev/isa/sf16fmr2.c sf2r
|
||||
|
||||
# Aztech/PackardBell FM Radio Card
|
||||
device az: radio, lm700x
|
||||
attach az at isa
|
||||
file dev/isa/aztech.c az
|
||||
|
||||
# AIMS Lab Radiotrack & compatible
|
||||
device rt: radio, lm700x
|
||||
attach rt at isa
|
||||
file dev/isa/radiotrack.c rt
|
||||
|
||||
# AIMS Lab Radiotrack II FM Radio Card
|
||||
device rtii: radio, tea5757
|
||||
attach rtii at isa
|
||||
file dev/isa/radiotrack2.c rtii
|
||||
|
||||
# PC PPI + TIMER 1 (speaker interface)
|
||||
device pcppi {}
|
||||
attach pcppi at isa
|
||||
|
407
sys/dev/isa/radiotrack.c
Normal file
407
sys/dev/isa/radiotrack.c
Normal file
@ -0,0 +1,407 @@
|
||||
/* $NetBSD: radiotrack.c,v 1.1 2002/01/01 21:51:41 augustss Exp $ */
|
||||
/* $OpenBSD: radiotrack.c,v 1.1 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: radiotrack.c,v 1.3 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>,
|
||||
* 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 AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
/* AIMS Lab Radiotrack FM Radio Card device driver */
|
||||
|
||||
/*
|
||||
* Sanyo LM7000 Direct PLL Frequency Synthesizer
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/ic/lm700x.h>
|
||||
#include <dev/radio_if.h>
|
||||
|
||||
#define RF_25K 25
|
||||
#define RF_50K 50
|
||||
#define RF_100K 100
|
||||
|
||||
#define MAX_VOL 5 /* XXX Find real value */
|
||||
#define VOLUME_RATIO(x) (255 * x / MAX_VOL)
|
||||
|
||||
#define RT_BASE_VALID(x) \
|
||||
((x == 0x30C) || (x == 0x20C) || (x == 0x284) || (x == 0x384))
|
||||
|
||||
#define CARD_RADIOTRACK 0x01
|
||||
#define CARD_SF16FMI 0x02
|
||||
#define CARD_UNKNOWN 0xFF
|
||||
|
||||
#define RTRACK_CAPABILITIES RADIO_CAPS_DETECT_STEREO | \
|
||||
RADIO_CAPS_DETECT_SIGNAL | \
|
||||
RADIO_CAPS_SET_MONO | \
|
||||
RADIO_CAPS_REFERENCE_FREQ
|
||||
|
||||
#define RT_WREN_ON (1 << 0)
|
||||
#define RT_WREN_OFF (0 << 0)
|
||||
|
||||
#define RT_CLCK_ON (1 << 1)
|
||||
#define RT_CLCK_OFF (0 << 1)
|
||||
|
||||
#define RT_DATA_ON (1 << 2)
|
||||
#define RT_DATA_OFF (0 << 2)
|
||||
|
||||
#define RT_CARD_ON (1 << 3)
|
||||
#define RT_CARD_OFF (0 << 3)
|
||||
|
||||
#define RT_SIGNAL_METER (1 << 4)
|
||||
#define RT_SIGNAL_METER_DELAY 150000
|
||||
|
||||
#define RT_VOLUME_DOWN (1 << 6)
|
||||
#define RT_VOLUME_UP (2 << 6)
|
||||
#define RT_VOLUME_STEADY (3 << 6)
|
||||
#define RT_VOLUME_DELAY 100000
|
||||
|
||||
int rt_probe(struct device *, struct cfdata *, void *);
|
||||
void rt_attach(struct device *, struct device * self, void *);
|
||||
int rt_get_info(void *, struct radio_info *);
|
||||
int rt_set_info(void *, struct radio_info *);
|
||||
|
||||
struct radio_hw_if rt_hw_if = {
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
rt_get_info,
|
||||
rt_set_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct rt_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
int mute;
|
||||
u_int8_t vol;
|
||||
u_int8_t cardtype;
|
||||
u_int32_t freq;
|
||||
u_int32_t rf;
|
||||
u_int32_t stereo;
|
||||
|
||||
struct lm700x_t lm;
|
||||
};
|
||||
|
||||
struct cfattach rt_ca = {
|
||||
sizeof(struct rt_softc), rt_probe, rt_attach
|
||||
};
|
||||
|
||||
int rt_find(bus_space_tag_t, bus_space_handle_t);
|
||||
void rt_set_mute(struct rt_softc *, int);
|
||||
void rt_set_freq(struct rt_softc *, u_int32_t);
|
||||
u_int8_t rt_state(bus_space_tag_t, bus_space_handle_t);
|
||||
|
||||
void rt_lm700x_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void rt_lm700x_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
|
||||
u_int8_t rt_conv_vol(u_int8_t);
|
||||
u_int8_t rt_unconv_vol(u_int8_t);
|
||||
|
||||
int
|
||||
rt_probe(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
bus_space_tag_t iot = ia->ia_iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
||||
int iosize = 1, iobase = ia->ia_iobase;
|
||||
|
||||
if (!RT_BASE_VALID(iobase)) {
|
||||
printf("rt: configured iobase 0x%x invalid", iobase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bus_space_map(iot, iobase, iosize, 0, &ioh))
|
||||
return 0;
|
||||
|
||||
bus_space_unmap(iot, ioh, iosize);
|
||||
|
||||
if (!rt_find(iot, ioh))
|
||||
return 0;
|
||||
|
||||
ia->ia_iosize = iosize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
rt_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct rt_softc *sc = (void *) self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
sc->lm.iot = ia->ia_iot;
|
||||
sc->rf = LM700X_REF_050;
|
||||
sc->stereo = LM700X_STEREO;
|
||||
sc->mute = 0;
|
||||
sc->freq = MIN_FM_FREQ;
|
||||
sc->vol = 0;
|
||||
|
||||
/* remap I/O */
|
||||
if (bus_space_map(sc->lm.iot, ia->ia_iobase, ia->ia_iosize,
|
||||
0, &sc->lm.ioh))
|
||||
panic(": bus_space_map() of %s failed", sc->sc_dev.dv_xname);
|
||||
|
||||
switch (sc->lm.iot) {
|
||||
case 0x20C:
|
||||
/* FALLTHROUGH */
|
||||
case 0x30C:
|
||||
sc->cardtype = CARD_RADIOTRACK;
|
||||
printf(": AIMS Lab Radiotrack or compatible");
|
||||
break;
|
||||
case 0x284:
|
||||
/* FALLTHROUGH */
|
||||
case 0x384:
|
||||
sc->cardtype = CARD_SF16FMI;
|
||||
printf(": SoundForte RadioX SF16-FMI");
|
||||
break;
|
||||
default:
|
||||
sc->cardtype = CARD_UNKNOWN;
|
||||
printf(": Unknown card");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Configure struct lm700x_t lm */
|
||||
sc->lm.offset = 0;
|
||||
sc->lm.wzcl = RT_WREN_ON | RT_CLCK_OFF | RT_DATA_OFF;
|
||||
sc->lm.wzch = RT_WREN_ON | RT_CLCK_ON | RT_DATA_OFF;
|
||||
sc->lm.wocl = RT_WREN_ON | RT_CLCK_OFF | RT_DATA_ON;
|
||||
sc->lm.woch = RT_WREN_ON | RT_CLCK_ON | RT_DATA_ON;
|
||||
sc->lm.initdata = 0;
|
||||
sc->lm.rsetdata = RT_DATA_ON | RT_CLCK_ON | RT_WREN_OFF;
|
||||
sc->lm.init = rt_lm700x_init;
|
||||
sc->lm.rset = rt_lm700x_rset;
|
||||
|
||||
rt_set_freq(sc, sc->freq);
|
||||
|
||||
radio_attach_mi(&rt_hw_if, sc, &sc->sc_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mute the card
|
||||
*/
|
||||
void
|
||||
rt_set_mute(struct rt_softc *sc, int vol)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (sc->mute) {
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
RT_VOLUME_DOWN | RT_CARD_ON);
|
||||
DELAY(MAX_VOL * RT_VOLUME_DELAY);
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
RT_VOLUME_STEADY | RT_CARD_ON);
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0, RT_CARD_OFF);
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0, RT_CARD_OFF);
|
||||
} else {
|
||||
val = sc->vol - vol;
|
||||
if (val < 0) {
|
||||
val *= -1;
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
RT_VOLUME_DOWN | RT_CARD_ON);
|
||||
} else {
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
RT_VOLUME_UP | RT_CARD_ON);
|
||||
}
|
||||
DELAY(val * RT_VOLUME_DELAY);
|
||||
bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
|
||||
RT_VOLUME_STEADY | RT_CARD_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rt_set_freq(struct rt_softc *sc, u_int32_t nfreq)
|
||||
{
|
||||
u_int32_t reg;
|
||||
|
||||
if (nfreq > MAX_FM_FREQ)
|
||||
nfreq = MAX_FM_FREQ;
|
||||
if (nfreq < MIN_FM_FREQ)
|
||||
nfreq = MIN_FM_FREQ;
|
||||
|
||||
sc->freq = nfreq;
|
||||
|
||||
reg = lm700x_encode_freq(nfreq, sc->rf);
|
||||
reg |= sc->stereo | sc->rf | LM700X_DIVIDER_FM;
|
||||
|
||||
lm700x_hardware_write(&sc->lm, reg, RT_VOLUME_STEADY);
|
||||
|
||||
rt_set_mute(sc, sc->vol);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return state of the card - tuned/not tuned, mono/stereo
|
||||
*/
|
||||
u_int8_t
|
||||
rt_state(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
u_int8_t ret;
|
||||
|
||||
bus_space_write_1(iot, ioh, 0,
|
||||
RT_VOLUME_STEADY | RT_SIGNAL_METER | RT_CARD_ON);
|
||||
DELAY(RT_SIGNAL_METER_DELAY);
|
||||
ret = bus_space_read_1(iot, ioh, 0);
|
||||
|
||||
switch (ret) {
|
||||
case 0xFD:
|
||||
ret = RADIO_INFO_SIGNAL | RADIO_INFO_STEREO;
|
||||
break;
|
||||
case 0xFF:
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = RADIO_INFO_SIGNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert volume to hardware representation.
|
||||
*/
|
||||
u_int8_t
|
||||
rt_conv_vol(u_int8_t vol)
|
||||
{
|
||||
if (vol < VOLUME_RATIO(1))
|
||||
return 0;
|
||||
else if (vol >= VOLUME_RATIO(1) && vol < VOLUME_RATIO(2))
|
||||
return 1;
|
||||
else if (vol >= VOLUME_RATIO(2) && vol < VOLUME_RATIO(3))
|
||||
return 2;
|
||||
else if (vol >= VOLUME_RATIO(3) && vol < VOLUME_RATIO(4))
|
||||
return 3;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert volume from hardware representation
|
||||
*/
|
||||
u_int8_t
|
||||
rt_unconv_vol(u_int8_t vol)
|
||||
{
|
||||
return VOLUME_RATIO(vol);
|
||||
}
|
||||
|
||||
int
|
||||
rt_find(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
struct rt_softc sc;
|
||||
#if 0
|
||||
u_int i, scanres = 0;
|
||||
#endif
|
||||
|
||||
sc.lm.iot = iot;
|
||||
sc.lm.ioh = ioh;
|
||||
sc.lm.offset = 0;
|
||||
sc.lm.wzcl = RT_WREN_ON | RT_CLCK_OFF | RT_DATA_OFF;
|
||||
sc.lm.wzch = RT_WREN_ON | RT_CLCK_ON | RT_DATA_OFF;
|
||||
sc.lm.wocl = RT_WREN_ON | RT_CLCK_OFF | RT_DATA_ON;
|
||||
sc.lm.woch = RT_WREN_ON | RT_CLCK_ON | RT_DATA_ON;
|
||||
sc.lm.initdata = 0;
|
||||
sc.lm.rsetdata = RT_SIGNAL_METER;
|
||||
sc.lm.init = rt_lm700x_init;
|
||||
sc.lm.rset = rt_lm700x_rset;
|
||||
sc.rf = LM700X_REF_050;
|
||||
sc.mute = 0;
|
||||
sc.stereo = LM700X_STEREO;
|
||||
sc.vol = 0;
|
||||
|
||||
/*
|
||||
* Scan whole FM range. If there is a card it'll
|
||||
* respond on some frequency.
|
||||
*/
|
||||
return 0;
|
||||
#if 0
|
||||
for (i = MIN_FM_FREQ; !scanres && i < MAX_FM_FREQ; i += 10) {
|
||||
rt_set_freq(&sc, i);
|
||||
scanres += rt_state(iot, ioh);
|
||||
}
|
||||
|
||||
return scanres;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
rt_lm700x_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
|
||||
u_int32_t data)
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
rt_lm700x_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
|
||||
u_int32_t data)
|
||||
{
|
||||
DELAY(1000);
|
||||
bus_space_write_1(iot, ioh, off, RT_CARD_OFF | data);
|
||||
DELAY(50000);
|
||||
bus_space_write_1(iot, ioh, off, RT_VOLUME_STEADY | RT_CARD_ON | data);
|
||||
}
|
||||
|
||||
int
|
||||
rt_set_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct rt_softc *sc = v;
|
||||
|
||||
sc->mute = ri->mute ? 1 : 0;
|
||||
sc->vol = rt_conv_vol(ri->volume);
|
||||
sc->stereo = ri->stereo ? LM700X_STEREO : LM700X_MONO;
|
||||
sc->rf = lm700x_encode_ref(ri->rfreq);
|
||||
|
||||
rt_set_freq(sc, ri->freq);
|
||||
rt_set_mute(sc, sc->vol);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rt_get_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct rt_softc *sc = v;
|
||||
|
||||
ri->mute = sc->mute;
|
||||
ri->volume = rt_unconv_vol(sc->vol);
|
||||
ri->stereo = sc->stereo == LM700X_STEREO ? 0 : 1;
|
||||
ri->caps = RTRACK_CAPABILITIES;
|
||||
ri->rfreq = lm700x_decode_ref(sc->rf);
|
||||
ri->info = 3 & rt_state(sc->lm.iot, sc->lm.ioh);
|
||||
ri->freq = sc->freq;
|
||||
|
||||
/* UNSUPPORTED */
|
||||
ri->lock = 0;
|
||||
|
||||
return (0);
|
||||
}
|
326
sys/dev/isa/radiotrack2.c
Normal file
326
sys/dev/isa/radiotrack2.c
Normal file
@ -0,0 +1,326 @@
|
||||
/* $NetBSD: radiotrack2.c,v 1.1 2002/01/01 21:51:41 augustss Exp $ */
|
||||
/* $OpenBSD: radiotrack2.c,v 1.1 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: radiotrack2.c,v 1.2 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>,
|
||||
* 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 AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
/* AIMS Lab Radiotrack II FM Radio Card device driver */
|
||||
|
||||
/*
|
||||
* Philips TEA5757H AM/FM Self Tuned Radio:
|
||||
* http://www.semiconductors.philips.com/pip/TEA5757H
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/radio_if.h>
|
||||
#include <dev/ic/tea5757.h>
|
||||
|
||||
#define RTII_BASE_VALID(x) ((x == 0x20C) || (x == 0x30C))
|
||||
#define RTII_CAPABILITIES RADIO_CAPS_DETECT_STEREO | \
|
||||
RADIO_CAPS_DETECT_SIGNAL | \
|
||||
RADIO_CAPS_SET_MONO | \
|
||||
RADIO_CAPS_LOCK_SENSITIVITY | \
|
||||
RADIO_CAPS_HW_AFC | \
|
||||
RADIO_CAPS_HW_SEARCH
|
||||
|
||||
#if 0
|
||||
#define RTII_SIGNAL (1 << 3)
|
||||
#define RTII_STEREO (1 << 3)
|
||||
#endif /* 0 */
|
||||
|
||||
#define RTII_MUTE 0x01
|
||||
#define RTII_UNMUTE 0x00
|
||||
|
||||
#define RTII_RESET 0xC8
|
||||
|
||||
#define RTII_DATA_ON (1 << 2)
|
||||
#define RTII_DATA_OFF (0 << 2)
|
||||
|
||||
#define RTII_CLCK_ON (1 << 1)
|
||||
#define RTII_CLCK_OFF (0 << 1)
|
||||
|
||||
#define RTII_WREN_ON (0 << 0)
|
||||
#define RTII_WREN_OFF (1 << 0)
|
||||
|
||||
#define RTII_READ_CLOCK_LOW (RTII_DATA_ON | RTII_CLCK_OFF | RTII_WREN_OFF)
|
||||
#define RTII_READ_CLOCK_HIGH (RTII_DATA_ON | RTII_CLCK_ON | RTII_WREN_OFF)
|
||||
|
||||
int rtii_probe(struct device *, struct cfdata *, void *);
|
||||
void rtii_attach(struct device *, struct device * self, void *);
|
||||
|
||||
int rtii_get_info(void *, struct radio_info *);
|
||||
int rtii_set_info(void *, struct radio_info *);
|
||||
int rtii_search(void *, int);
|
||||
|
||||
/* define our interface to the higher level radio driver */
|
||||
struct radio_hw_if rtii_hw_if = {
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
rtii_get_info,
|
||||
rtii_set_info,
|
||||
rtii_search
|
||||
};
|
||||
|
||||
struct rtii_softc {
|
||||
struct device dev;
|
||||
|
||||
u_int32_t freq;
|
||||
u_int32_t stereo;
|
||||
u_int32_t lock;
|
||||
u_int8_t vol;
|
||||
int mute;
|
||||
|
||||
struct tea5757_t tea;
|
||||
};
|
||||
|
||||
struct cfattach rtii_ca = {
|
||||
sizeof(struct rtii_softc), rtii_probe, rtii_attach
|
||||
};
|
||||
|
||||
void rtii_set_mute(struct rtii_softc *);
|
||||
int rtii_find(bus_space_tag_t, bus_space_handle_t);
|
||||
|
||||
u_int32_t rtii_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
|
||||
|
||||
void rtii_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void rtii_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void rtii_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
|
||||
|
||||
int
|
||||
rtii_probe(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
bus_space_tag_t iot = ia->ia_iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
||||
int iosize = 1, iobase = ia->ia_iobase;
|
||||
|
||||
if (!RTII_BASE_VALID(iobase)) {
|
||||
printf("rtii: configured iobase 0x%x invalid\n", iobase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bus_space_map(iot, iobase, iosize, 0, &ioh))
|
||||
return 0;
|
||||
|
||||
bus_space_unmap(iot, ioh, iosize);
|
||||
|
||||
if (!rtii_find(iot, ioh))
|
||||
return 0;
|
||||
|
||||
ia->ia_iosize = iosize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
rtii_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct rtii_softc *sc = (void *) self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
sc->tea.iot = ia->ia_iot;
|
||||
sc->mute = 0;
|
||||
sc->vol = 0;
|
||||
sc->freq = MIN_FM_FREQ;
|
||||
sc->stereo = TEA5757_STEREO;
|
||||
sc->lock = TEA5757_S030;
|
||||
|
||||
/* remap I/O */
|
||||
if (bus_space_map(sc->tea.iot, ia->ia_iobase, ia->ia_iosize,
|
||||
0, &sc->tea.ioh))
|
||||
panic("rtiiattach: bus_space_map() failed");
|
||||
|
||||
sc->tea.offset = 0;
|
||||
|
||||
sc->tea.init = rtii_init;
|
||||
sc->tea.rset = rtii_rset;
|
||||
sc->tea.write_bit = rtii_write_bit;
|
||||
sc->tea.read = rtii_hw_read;
|
||||
|
||||
printf(": AIMS Lab Radiotrack II");
|
||||
tea5757_set_freq(&sc->tea, sc->stereo, sc->lock, sc->freq);
|
||||
rtii_set_mute(sc);
|
||||
|
||||
radio_attach_mi(&rtii_hw_if, sc, &sc->dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mute/unmute the card
|
||||
*/
|
||||
void
|
||||
rtii_set_mute(struct rtii_softc *sc)
|
||||
{
|
||||
u_int8_t mute;
|
||||
|
||||
mute = (sc->mute || !sc->vol) ? RTII_MUTE : RTII_UNMUTE;
|
||||
bus_space_write_1(sc->tea.iot, sc->tea.ioh, 0, mute);
|
||||
DELAY(6);
|
||||
bus_space_write_1(sc->tea.iot, sc->tea.ioh, 0, mute);
|
||||
}
|
||||
|
||||
void
|
||||
rtii_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, RTII_RESET | RTII_WREN_OFF);
|
||||
bus_space_write_1(iot, ioh, off, RTII_RESET | RTII_WREN_ON);
|
||||
bus_space_write_1(iot, ioh, off, RTII_RESET | RTII_WREN_ON);
|
||||
}
|
||||
|
||||
void
|
||||
rtii_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, RTII_RESET | RTII_WREN_OFF);
|
||||
}
|
||||
|
||||
int
|
||||
rtii_find(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
struct rtii_softc sc;
|
||||
u_int32_t freq;
|
||||
|
||||
sc.tea.iot = iot;
|
||||
sc.tea.ioh = ioh;
|
||||
sc.tea.offset = 0;
|
||||
sc.tea.init = rtii_init;
|
||||
sc.tea.rset = rtii_rset;
|
||||
sc.tea.write_bit = rtii_write_bit;
|
||||
sc.tea.read = rtii_hw_read;
|
||||
sc.lock = TEA5757_S030;
|
||||
sc.stereo = TEA5757_STEREO;
|
||||
|
||||
/*
|
||||
* Let's try to write and read a frequency.
|
||||
* If the written and read frequencies are
|
||||
* the same then success.
|
||||
*/
|
||||
sc.freq = MIN_FM_FREQ;
|
||||
tea5757_set_freq(&sc.tea, sc.stereo, sc.lock, sc.freq);
|
||||
rtii_set_mute(&sc);
|
||||
freq = rtii_hw_read(iot, ioh, sc.tea.offset);
|
||||
if (tea5757_decode_freq(freq) == sc.freq)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rtii_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, int bit)
|
||||
{
|
||||
u_int8_t data;
|
||||
|
||||
data = bit ? RTII_DATA_ON : RTII_DATA_OFF;
|
||||
|
||||
bus_space_write_1(iot, ioh, off, RTII_WREN_ON | RTII_CLCK_OFF | data);
|
||||
bus_space_write_1(iot, ioh, off, RTII_WREN_ON | RTII_CLCK_ON | data);
|
||||
bus_space_write_1(iot, ioh, off, RTII_WREN_ON | RTII_CLCK_OFF | data);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
rtii_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off)
|
||||
{
|
||||
u_int8_t i;
|
||||
u_int32_t res = 0;
|
||||
|
||||
bus_space_write_1(iot, ioh, off, RTII_READ_CLOCK_LOW);
|
||||
DELAY(6);
|
||||
|
||||
i = 24;
|
||||
while ( i-- ) {
|
||||
bus_space_write_1(iot, ioh, off, RTII_READ_CLOCK_HIGH);
|
||||
DELAY(6);
|
||||
bus_space_write_1(iot, ioh, off, RTII_READ_CLOCK_LOW);
|
||||
res |= bus_space_read_1(iot, ioh, off) & RTII_DATA_ON ? 1 : 0;
|
||||
DELAY(6);
|
||||
res <<= 1;
|
||||
}
|
||||
|
||||
return (res & (TEA5757_DATA | TEA5757_FREQ)) >> 1;
|
||||
}
|
||||
|
||||
int
|
||||
rtii_get_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct rtii_softc *sc = v;
|
||||
|
||||
ri->mute = sc->mute;
|
||||
ri->volume = sc->vol ? 255 : 0;
|
||||
ri->stereo = sc->stereo == TEA5757_STEREO ? 1 : 0;
|
||||
ri->caps = RTII_CAPABILITIES;
|
||||
ri->rfreq = 0;
|
||||
ri->lock = tea5757_decode_lock(sc->lock);
|
||||
|
||||
ri->freq = sc->freq = tea5757_decode_freq(rtii_hw_read(sc->tea.iot,
|
||||
sc->tea.ioh, sc->tea.offset));
|
||||
|
||||
switch (bus_space_read_1(sc->tea.iot, sc->tea.ioh, 0)) {
|
||||
case 0xFD:
|
||||
ri->info = RADIO_INFO_SIGNAL | RADIO_INFO_STEREO;
|
||||
break;
|
||||
case 0xFF:
|
||||
ri->info = 0;
|
||||
break;
|
||||
default:
|
||||
ri->info = RADIO_INFO_SIGNAL;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rtii_set_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct rtii_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);
|
||||
rtii_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rtii_search(void *v, int f)
|
||||
{
|
||||
struct rtii_softc *sc = v;
|
||||
|
||||
tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
|
||||
rtii_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
335
sys/dev/isa/sf16fmr2.c
Normal file
335
sys/dev/isa/sf16fmr2.c
Normal file
@ -0,0 +1,335 @@
|
||||
/* $NetBSD: sf16fmr2.c,v 1.1 2002/01/01 21:51:41 augustss Exp $ */
|
||||
/* $OpenBSD: sf16fmr2.c,v 1.3 2001/12/18 18:48:08 mickey Exp $ */
|
||||
/* $RuOBSD: sf16fmr2.c,v 1.12 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>,
|
||||
* 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 AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
/* SoundForte RadioLink SF16-FMR2 FM Radio Card device driver */
|
||||
|
||||
/*
|
||||
* Philips TEA5757H AM/FM Self Tuned Radio:
|
||||
* http://www.semiconductors.philips.com/pip/TEA5757H
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/radio_if.h>
|
||||
#include <dev/ic/tea5757.h>
|
||||
|
||||
#define SF16FMR2_BASE_VALID(x) (x == 0x384)
|
||||
#define SF16FMR2_CAPABILITIES RADIO_CAPS_DETECT_STEREO | \
|
||||
RADIO_CAPS_DETECT_SIGNAL | \
|
||||
RADIO_CAPS_SET_MONO | \
|
||||
RADIO_CAPS_LOCK_SENSITIVITY | \
|
||||
RADIO_CAPS_HW_AFC | \
|
||||
RADIO_CAPS_HW_SEARCH
|
||||
|
||||
#define SF16FMR2_AMPLIFIER (1 << 7)
|
||||
#define SF16FMR2_SIGNAL (1 << 3)
|
||||
#define SF16FMR2_STEREO (1 << 3)
|
||||
|
||||
#define SF16FMR2_MUTE 0x00
|
||||
#define SF16FMR2_UNMUTE 0x04
|
||||
|
||||
#define SF16FMR2_DATA_ON (1 << 0)
|
||||
#define SF16FMR2_DATA_OFF (0 << 0)
|
||||
|
||||
#define SF16FMR2_CLCK_ON (1 << 1)
|
||||
#define SF16FMR2_CLCK_OFF (0 << 1)
|
||||
|
||||
#define SF16FMR2_WREN_ON (0 << 2) /* SF16-FMR2 has inverse WREN */
|
||||
#define SF16FMR2_WREN_OFF (1 << 2)
|
||||
|
||||
#define SF16FMR2_READ_CLOCK_LOW \
|
||||
SF16FMR2_DATA_ON | SF16FMR2_CLCK_OFF | SF16FMR2_WREN_OFF
|
||||
|
||||
#define SF16FMR2_READ_CLOCK_HIGH \
|
||||
SF16FMR2_DATA_ON | SF16FMR2_CLCK_ON | SF16FMR2_WREN_OFF
|
||||
|
||||
int sf2r_probe(struct device *, struct cfdata *, void *);
|
||||
void sf2r_attach(struct device *, struct device * self, void *);
|
||||
|
||||
int sf2r_get_info(void *, struct radio_info *);
|
||||
int sf2r_set_info(void *, struct radio_info *);
|
||||
int sf2r_search(void *, int);
|
||||
|
||||
/* define our interface to the higher level radio driver */
|
||||
struct radio_hw_if sf2r_hw_if = {
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
sf2r_get_info,
|
||||
sf2r_set_info,
|
||||
sf2r_search
|
||||
};
|
||||
|
||||
struct sf2r_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
u_int32_t freq;
|
||||
u_int32_t stereo;
|
||||
u_int32_t lock;
|
||||
u_int8_t vol;
|
||||
int mute;
|
||||
|
||||
struct tea5757_t tea;
|
||||
};
|
||||
|
||||
struct cfattach sf2r_ca = {
|
||||
sizeof(struct sf2r_softc), sf2r_probe, sf2r_attach
|
||||
};
|
||||
|
||||
void sf2r_set_mute(struct sf2r_softc *);
|
||||
int sf2r_find(bus_space_tag_t, bus_space_handle_t);
|
||||
|
||||
u_int32_t sf2r_read_register(bus_space_tag_t, bus_space_handle_t, bus_size_t);
|
||||
|
||||
void sf2r_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void sf2r_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void sf2r_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
|
||||
|
||||
int
|
||||
sf2r_probe(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct isa_attach_args *ia = aux;
|
||||
bus_space_tag_t iot = ia->ia_iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
||||
int iosize = 1, iobase = ia->ia_iobase;
|
||||
|
||||
if (!SF16FMR2_BASE_VALID(iobase)) {
|
||||
printf("sf2r: configured iobase 0x%x invalid\n", iobase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bus_space_map(iot, iobase, iosize, 0, &ioh))
|
||||
return 0;
|
||||
|
||||
bus_space_unmap(iot, ioh, iosize);
|
||||
|
||||
if (!sf2r_find(iot, ioh))
|
||||
return 0;
|
||||
|
||||
ia->ia_iosize = iosize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
sf2r_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct sf2r_softc *sc = (void *) self;
|
||||
struct isa_attach_args *ia = aux;
|
||||
|
||||
sc->tea.iot = ia->ia_iot;
|
||||
sc->mute = 0;
|
||||
sc->vol = 0;
|
||||
sc->freq = MIN_FM_FREQ;
|
||||
sc->stereo = TEA5757_STEREO;
|
||||
sc->lock = TEA5757_S030;
|
||||
|
||||
/* remap I/O */
|
||||
if (bus_space_map(sc->tea.iot, ia->ia_iobase, ia->ia_iosize,
|
||||
0, &sc->tea.ioh))
|
||||
panic("sf2rattach: bus_space_map() failed");
|
||||
|
||||
sc->tea.offset = 0;
|
||||
|
||||
sc->tea.init = sf2r_init;
|
||||
sc->tea.rset = sf2r_rset;
|
||||
sc->tea.write_bit = sf2r_write_bit;
|
||||
sc->tea.read = sf2r_read_register;
|
||||
|
||||
printf(": SoundForte RadioLink SF16-FMR2");
|
||||
tea5757_set_freq(&sc->tea, sc->stereo, sc->lock, sc->freq);
|
||||
sf2r_set_mute(sc);
|
||||
|
||||
radio_attach_mi(&sf2r_hw_if, sc, &sc->sc_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mute/unmute the card
|
||||
*/
|
||||
void
|
||||
sf2r_set_mute(struct sf2r_softc *sc)
|
||||
{
|
||||
u_int8_t mute;
|
||||
|
||||
mute = (sc->mute || !sc->vol) ? SF16FMR2_MUTE : SF16FMR2_UNMUTE;
|
||||
bus_space_write_1(sc->tea.iot, sc->tea.ioh, 0, mute);
|
||||
DELAY(64);
|
||||
bus_space_write_1(sc->tea.iot, sc->tea.ioh, 0, mute);
|
||||
}
|
||||
|
||||
void
|
||||
sf2r_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_MUTE);
|
||||
}
|
||||
|
||||
void
|
||||
sf2r_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_MUTE);
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_UNMUTE);
|
||||
}
|
||||
|
||||
int
|
||||
sf2r_find(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
struct sf2r_softc sc;
|
||||
u_int32_t freq;
|
||||
|
||||
sc.tea.iot = iot;
|
||||
sc.tea.ioh = ioh;
|
||||
sc.tea.offset = 0;
|
||||
sc.tea.init = sf2r_init;
|
||||
sc.tea.rset = sf2r_rset;
|
||||
sc.tea.write_bit = sf2r_write_bit;
|
||||
sc.tea.read = sf2r_read_register;
|
||||
sc.lock = TEA5757_S030;
|
||||
sc.stereo = TEA5757_STEREO;
|
||||
|
||||
if ((bus_space_read_1(iot, ioh, 0) & 0x70) == 0x30) {
|
||||
/*
|
||||
* Let's try to write and read a frequency.
|
||||
* If the written and read frequencies are
|
||||
* the same then success.
|
||||
*/
|
||||
sc.freq = MIN_FM_FREQ;
|
||||
tea5757_set_freq(&sc.tea, sc.stereo, sc.lock, sc.freq);
|
||||
sf2r_set_mute(&sc);
|
||||
freq = sf2r_read_register(iot, ioh, sc.tea.offset);
|
||||
if (tea5757_decode_freq(freq) == sc.freq)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sf2r_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, int bit)
|
||||
{
|
||||
u_int8_t data;
|
||||
|
||||
data = bit ? SF16FMR2_DATA_ON : SF16FMR2_DATA_OFF;
|
||||
|
||||
bus_space_write_1(iot, ioh, off,
|
||||
SF16FMR2_WREN_ON | SF16FMR2_CLCK_OFF | data);
|
||||
bus_space_write_1(iot, ioh, off,
|
||||
SF16FMR2_WREN_ON | SF16FMR2_CLCK_ON | data);
|
||||
bus_space_write_1(iot, ioh, off,
|
||||
SF16FMR2_WREN_ON | SF16FMR2_CLCK_OFF | data);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
sf2r_read_register(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off)
|
||||
{
|
||||
u_int32_t res = 0;
|
||||
u_int8_t i, state = 0;
|
||||
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_READ_CLOCK_LOW);
|
||||
DELAY(6);
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_READ_CLOCK_HIGH);
|
||||
|
||||
i = bus_space_read_1(iot, ioh, off);
|
||||
DELAY(6);
|
||||
/* Amplifier: 0 - not present, 1 - present */
|
||||
state = i & SF16FMR2_AMPLIFIER ? (1 << 2) : (0 << 2);
|
||||
/* Signal: 0 - not tuned, 1 - tuned */
|
||||
state |= i & SF16FMR2_SIGNAL ? (0 << 1) : (1 << 1);
|
||||
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_READ_CLOCK_LOW);
|
||||
i = bus_space_read_1(iot, ioh, off);
|
||||
/* Stereo: 0 - mono, 1 - stereo */
|
||||
state |= i & SF16FMR2_STEREO ? (0 << 0) : (1 << 0);
|
||||
res = i & SF16FMR2_DATA_ON;
|
||||
|
||||
i = 23;
|
||||
while ( i-- ) {
|
||||
DELAY(6);
|
||||
res <<= 1;
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_READ_CLOCK_HIGH);
|
||||
DELAY(6);
|
||||
bus_space_write_1(iot, ioh, off, SF16FMR2_READ_CLOCK_LOW);
|
||||
res |= bus_space_read_1(iot, ioh, off) & SF16FMR2_DATA_ON;
|
||||
}
|
||||
|
||||
return res | (state << 24);
|
||||
}
|
||||
|
||||
int
|
||||
sf2r_get_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct sf2r_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 = SF16FMR2_CAPABILITIES;
|
||||
ri->rfreq = 0;
|
||||
ri->lock = tea5757_decode_lock(sc->lock);
|
||||
|
||||
buf = sf2r_read_register(sc->tea.iot, sc->tea.ioh, sc->tea.offset);
|
||||
ri->freq = sc->freq = tea5757_decode_freq(buf);
|
||||
ri->info = 3 & (buf >> 24);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sf2r_set_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct sf2r_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);
|
||||
sf2r_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sf2r_search(void *v, int f)
|
||||
{
|
||||
struct sf2r_softc *sc = v;
|
||||
|
||||
tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
|
||||
sf2r_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.pci,v 1.152 2002/01/01 16:49:05 hpeyerl Exp $
|
||||
# $NetBSD: files.pci,v 1.153 2002/01/01 21:51:40 augustss Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent PCI code.
|
||||
# Included by ports that need it. Requires that the SCSI files be
|
||||
@ -150,6 +150,16 @@ device trm: scsi
|
||||
attach trm at pci
|
||||
file dev/pci/trm.c trm
|
||||
|
||||
# Guillemot Maxi Radio FM 2000 Radio Card
|
||||
device mr: radio
|
||||
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
|
||||
|
||||
# PCI IDE controllers
|
||||
device pciide {[channel = -1]}: cy82c693, wdc_base, ata, atapi
|
||||
attach pciide at pci
|
||||
|
298
sys/dev/pci/maxiradio.c
Normal file
298
sys/dev/pci/maxiradio.c
Normal file
@ -0,0 +1,298 @@
|
||||
/* $NetBSD: maxiradio.c,v 1.1 2002/01/01 21:51:40 augustss Exp $ */
|
||||
/* $OpenBSD: maxiradio.c,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: maxiradio.c,v 1.5 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>
|
||||
* 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 AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
/* Guillemot Maxi Radio FM2000 PCI Radio Card Device Driver */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/proc.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/ic/tea5757.h>
|
||||
#include <dev/radio_if.h>
|
||||
|
||||
int mr_match(struct device *, struct cfdata *, void *);
|
||||
void mr_attach(struct device *, struct device *, void *);
|
||||
|
||||
int mr_get_info(void *, struct radio_info *);
|
||||
int mr_set_info(void *, struct radio_info *);
|
||||
int mr_search(void *, int);
|
||||
|
||||
/* config base I/O address ? */
|
||||
#define PCI_CBIO 0x6400
|
||||
|
||||
#define MAXIRADIO_CAPS RADIO_CAPS_DETECT_SIGNAL | \
|
||||
RADIO_CAPS_SET_MONO | \
|
||||
RADIO_CAPS_HW_SEARCH | \
|
||||
RADIO_CAPS_HW_AFC | \
|
||||
RADIO_CAPS_LOCK_SENSITIVITY
|
||||
#if 0
|
||||
RADIO_CAPS_DETECT_STEREO |
|
||||
#endif /* 0 */
|
||||
|
||||
#define MAXIRADIO_MUTE 0x00
|
||||
#define MAXIRADIO_UNMUTE 0x10
|
||||
|
||||
#define MAXIRADIO_SIGNAL 0x08
|
||||
|
||||
#define MR_WREN_ON (1 << 2)
|
||||
#define MR_WREN_OFF (0 << 2)
|
||||
|
||||
#define MR_DATA_ON (1 << 1)
|
||||
#define MR_DATA_OFF (0 << 1)
|
||||
|
||||
#define MR_CLCK_ON (1 << 0)
|
||||
#define MR_CLCK_OFF (0 << 0)
|
||||
|
||||
#define MR_READ_CLOCK_LOW (MR_WREN_OFF | MR_DATA_ON | MR_CLCK_OFF)
|
||||
#define MR_READ_CLOCK_HIGH (MR_WREN_OFF | MR_DATA_ON | MR_CLCK_ON)
|
||||
|
||||
/* define our interface to the high-level radio driver */
|
||||
|
||||
struct radio_hw_if mr_hw_if = {
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
mr_get_info,
|
||||
mr_set_info,
|
||||
mr_search
|
||||
};
|
||||
|
||||
struct mr_softc {
|
||||
struct device sc_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 mr_ca = {
|
||||
sizeof(struct mr_softc), mr_match, mr_attach
|
||||
};
|
||||
|
||||
void mr_set_mute(struct mr_softc *);
|
||||
void mr_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
|
||||
void mr_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
void mr_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
|
||||
int mr_state(bus_space_tag_t, bus_space_handle_t);
|
||||
u_int32_t mr_hardware_read(bus_space_tag_t, bus_space_handle_t,
|
||||
bus_size_t);
|
||||
|
||||
int
|
||||
mr_match(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct pci_attach_args *pa = aux;
|
||||
|
||||
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_GUILLEMOT &&
|
||||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_GUILLEMOT_MAXIRADIO)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
mr_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct mr_softc *sc = (struct mr_softc *)self;
|
||||
struct pci_attach_args *pa = aux;
|
||||
pci_chipset_tag_t pc = pa->pa_pc;
|
||||
bus_size_t iosize;
|
||||
pcireg_t csr;
|
||||
char devinfo[256];
|
||||
|
||||
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
|
||||
printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
|
||||
|
||||
/* Map I/O registers */
|
||||
if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
|
||||
&sc->tea.iot, &sc->tea.ioh, NULL, &iosize)) {
|
||||
printf(": can't map i/o space\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
XXXX
|
||||
if (pci_io_find(pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize)) {
|
||||
printf (": can't find i/o base\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bus_space_map(sc->tea.iot = pa->pa_iot, iobase, iosize,
|
||||
0, &sc->tea.ioh)) {
|
||||
printf(": can't map i/o space\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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->freq = MIN_FM_FREQ;
|
||||
sc->vol = 0;
|
||||
sc->mute = 0;
|
||||
sc->stereo = TEA5757_STEREO;
|
||||
sc->lock = TEA5757_S030;
|
||||
sc->tea.offset = 0;
|
||||
sc->tea.init = mr_init;
|
||||
sc->tea.rset = mr_rset;
|
||||
sc->tea.write_bit = mr_write_bit;
|
||||
sc->tea.read = mr_hardware_read;
|
||||
|
||||
radio_attach_mi(&mr_hw_if, sc, &sc->sc_dev);
|
||||
}
|
||||
|
||||
int
|
||||
mr_get_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct mr_softc *sc = v;
|
||||
|
||||
ri->mute = sc->mute;
|
||||
ri->volume = sc->vol ? 255 : 0;
|
||||
ri->stereo = sc->stereo == TEA5757_STEREO ? 1 : 0;
|
||||
ri->caps = MAXIRADIO_CAPS;
|
||||
ri->rfreq = 0;
|
||||
ri->lock = tea5757_decode_lock(sc->lock);
|
||||
|
||||
ri->freq = sc->freq = tea5757_decode_freq(mr_hardware_read(sc->tea.iot,
|
||||
sc->tea.ioh, sc->tea.offset));
|
||||
|
||||
ri->info = mr_state(sc->tea.iot, sc->tea.ioh);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mr_set_info(void *v, struct radio_info *ri)
|
||||
{
|
||||
struct mr_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);
|
||||
mr_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mr_search(void *v, int f)
|
||||
{
|
||||
struct mr_softc *sc = v;
|
||||
|
||||
tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
|
||||
mr_set_mute(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
mr_set_mute(struct mr_softc *sc)
|
||||
{
|
||||
int mute;
|
||||
|
||||
mute = (sc->mute || !sc->vol) ? MAXIRADIO_MUTE : MAXIRADIO_UNMUTE;
|
||||
bus_space_write_1(sc->tea.iot, sc->tea.ioh, 0, mute);
|
||||
}
|
||||
|
||||
void
|
||||
mr_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
|
||||
int bit)
|
||||
{
|
||||
u_int8_t data;
|
||||
|
||||
data = bit ? MR_DATA_ON : MR_DATA_OFF;
|
||||
bus_space_write_1(iot, ioh, off, MR_WREN_ON | MR_CLCK_OFF | data);
|
||||
DELAY(5);
|
||||
bus_space_write_1(iot, ioh, off, MR_WREN_ON | MR_CLCK_ON | data);
|
||||
DELAY(5);
|
||||
bus_space_write_1(iot, ioh, off, MR_WREN_ON | MR_CLCK_OFF | data);
|
||||
DELAY(5);
|
||||
}
|
||||
|
||||
void
|
||||
mr_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, MR_WREN_ON | MR_DATA_ON | MR_CLCK_OFF);
|
||||
}
|
||||
|
||||
void
|
||||
mr_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
|
||||
{
|
||||
bus_space_write_1(iot, ioh, off, MAXIRADIO_UNMUTE);
|
||||
}
|
||||
|
||||
/* COMPLETELY UNTESTED */
|
||||
u_int32_t
|
||||
mr_hardware_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off)
|
||||
{
|
||||
u_int32_t reg = 0ul;
|
||||
int i;
|
||||
|
||||
bus_space_write_1(iot, ioh, off, MR_READ_CLOCK_LOW);
|
||||
DELAY(5);
|
||||
|
||||
i = 24;
|
||||
while (i--) {
|
||||
bus_space_write_1(iot, ioh, off, MR_READ_CLOCK_HIGH);
|
||||
DELAY(5);
|
||||
bus_space_write_1(iot, ioh, off, MR_READ_CLOCK_LOW);
|
||||
DELAY(5);
|
||||
reg |= bus_space_read_1(iot, ioh, off) & MR_DATA_ON ? 1 : 0;
|
||||
reg <<= 1;
|
||||
}
|
||||
|
||||
reg >>= 1;
|
||||
|
||||
return (reg & (TEA5757_DATA | TEA5757_FREQ));
|
||||
}
|
||||
|
||||
int
|
||||
mr_state(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
{
|
||||
/* XXX: where is a stereo bit ? */
|
||||
return bus_space_read_1(iot, ioh, 0) & MAXIRADIO_SIGNAL ?
|
||||
(0 << 1) : (1 << 1);
|
||||
}
|
161
sys/dev/radio.c
Normal file
161
sys/dev/radio.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* $NetBSD: radio.c,v 1.1 2002/01/01 21:51:38 augustss Exp $ */
|
||||
/* $OpenBSD: radio.c,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: radio.c,v 1.7 2001/12/04 06:03:05 tm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>
|
||||
* 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 ``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 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.
|
||||
*/
|
||||
|
||||
/* This is the /dev/radio driver from OpenBSD */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/radioio.h>
|
||||
|
||||
#include <dev/radio_if.h>
|
||||
#include <dev/radiovar.h>
|
||||
|
||||
int radioprobe(struct device *, struct cfdata *, void *);
|
||||
void radioattach(struct device *, struct device *, void *);
|
||||
int radioopen(dev_t, int, int, struct proc *);
|
||||
int radioclose(dev_t, int, int, struct proc *);
|
||||
int radioioctl(dev_t, u_long, caddr_t, int, struct proc *);
|
||||
int radioprint(void *, const char *);
|
||||
|
||||
struct cfattach radio_ca = {
|
||||
sizeof(struct radio_softc), radioprobe, radioattach,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
extern struct cfdriver radio_cd;
|
||||
|
||||
int
|
||||
radioprobe(struct device *parent, struct cfdata *match, void *aux)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
radioattach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct radio_softc *sc = (void *)self;
|
||||
struct radio_attach_args *sa = aux;
|
||||
struct radio_hw_if *hwp = sa->hwif;
|
||||
void *hdlp = sa->hdl;
|
||||
|
||||
printf("\n");
|
||||
sc->hw_if = hwp;
|
||||
sc->hw_hdl = hdlp;
|
||||
sc->sc_dev = parent;
|
||||
}
|
||||
|
||||
int
|
||||
radioopen(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
int unit;
|
||||
struct radio_softc *sc;
|
||||
|
||||
unit = RADIOUNIT(dev);
|
||||
if (unit >= radio_cd.cd_ndevs ||
|
||||
(sc = radio_cd.cd_devs[unit]) == NULL ||
|
||||
sc->hw_if == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
if (sc->hw_if->open != NULL)
|
||||
return (sc->hw_if->open(sc->hw_hdl, flags, fmt, p));
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
radioclose(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
struct radio_softc *sc;
|
||||
|
||||
sc = radio_cd.cd_devs[RADIOUNIT(dev)];
|
||||
|
||||
if (sc->hw_if->close != NULL)
|
||||
return (sc->hw_if->close(sc->hw_hdl, flags, fmt, p));
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
radioioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
|
||||
{
|
||||
struct radio_softc *sc;
|
||||
int unit, error;
|
||||
|
||||
unit = RADIOUNIT(dev);
|
||||
if (unit >= radio_cd.cd_ndevs ||
|
||||
(sc = radio_cd.cd_devs[unit]) == NULL || sc->hw_if == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
error = EOPNOTSUPP;
|
||||
switch (cmd) {
|
||||
case RIOCGINFO:
|
||||
if (sc->hw_if->get_info)
|
||||
error = (sc->hw_if->get_info)(sc->hw_hdl,
|
||||
(struct radio_info *)data);
|
||||
break;
|
||||
case RIOCSINFO:
|
||||
if (sc->hw_if->set_info)
|
||||
error = (sc->hw_if->set_info)(sc->hw_hdl,
|
||||
(struct radio_info *)data);
|
||||
break;
|
||||
case RIOCSSRCH:
|
||||
if (sc->hw_if->search)
|
||||
error = (sc->hw_if->search)(sc->hw_hdl,
|
||||
*(int *)data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from hardware driver. This is where the MI radio driver gets
|
||||
* probed/attached to the hardware driver
|
||||
*/
|
||||
struct device *
|
||||
radio_attach_mi(struct radio_hw_if *rhwp, void *hdlp, struct device *dev)
|
||||
{
|
||||
struct radio_attach_args arg;
|
||||
|
||||
arg.hwif = rhwp;
|
||||
arg.hdl = hdlp;
|
||||
return (config_found(dev, &arg, radioprint));
|
||||
}
|
||||
|
||||
int
|
||||
radioprint(void *aux, const char *pnp)
|
||||
{
|
||||
return UNCONF;
|
||||
}
|
58
sys/dev/radio_if.h
Normal file
58
sys/dev/radio_if.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* $NetBSD: radio_if.h,v 1.1 2002/01/01 21:51:38 augustss Exp $ */
|
||||
/* $OpenBSD: radio_if.h,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: radio_if.h,v 1.6 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>
|
||||
* 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 ``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 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 _SYS_DEV_RADIO_IF_H
|
||||
#define _SYS_DEV_RADIO_IF_H
|
||||
|
||||
/*
|
||||
* Generic interface to hardware driver
|
||||
*/
|
||||
|
||||
#define RADIOUNIT(x) (minor(x))
|
||||
|
||||
struct radio_hw_if {
|
||||
/* open hardware */
|
||||
int (*open)(void *, int, int, struct proc *);
|
||||
|
||||
/* close hardware */
|
||||
int (*close)(void *, int, int, struct proc *);
|
||||
|
||||
int (*get_info)(void *, struct radio_info *);
|
||||
int (*set_info)(void *, struct radio_info *);
|
||||
int (*search)(void *, int);
|
||||
};
|
||||
|
||||
struct radio_attach_args {
|
||||
struct radio_hw_if *hwif;
|
||||
void *hdl;
|
||||
};
|
||||
|
||||
struct device *radio_attach_mi(struct radio_hw_if *, void *, struct device *);
|
||||
|
||||
#endif /* _SYS_DEV_RADIO_IF_H */
|
40
sys/dev/radiovar.h
Normal file
40
sys/dev/radiovar.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* $NetBSD: radiovar.h,v 1.1 2002/01/01 21:51:39 augustss Exp $ */
|
||||
/* $OpenBSD: radiovar.h,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
|
||||
/* $RuOBSD: radiovar.h,v 1.3 2001/09/29 17:10:16 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>
|
||||
* 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 ``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 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 _SYS_DEV_RADIOVAR_H
|
||||
#define _SYS_DEV_RADIOVAR_H
|
||||
|
||||
struct radio_softc {
|
||||
struct device dev;
|
||||
void *hw_hdl; /* hardware driver handle */
|
||||
struct device *sc_dev; /* hardware device struct */
|
||||
struct radio_hw_if *hw_if; /* hardware interface */
|
||||
};
|
||||
|
||||
#endif /* _SYS_DEV_RADIOVAR_H */
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.37 2001/12/05 06:51:55 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.38 2002/01/01 21:51:39 augustss Exp $
|
||||
|
||||
KDIR= /sys/sys
|
||||
INCSDIR= /usr/include/sys
|
||||
@ -15,7 +15,7 @@ INCS= acct.h agpio.h ansi.h ataio.h audioio.h buf.h bswap.h \
|
||||
localedef.h lock.h lockf.h malloc.h map.h mbuf.h md4.h md5.h midiio.h \
|
||||
mman.h mount.h msg.h msgbuf.h mtio.h namei.h null.h param.h pipe.h \
|
||||
poll.h pool.h proc.h properties.h \
|
||||
protosw.h ptrace.h queue.h reboot.h resource.h \
|
||||
protosw.h ptrace.h queue.h reboot.h radioio.h resource.h \
|
||||
resourcevar.h rnd.h scanio.h sched.h scsiio.h select.h sem.h sha1.h \
|
||||
shm.h signal.h signalvar.h socket.h socketvar.h sockio.h stat.h \
|
||||
syscall.h syscallargs.h sysctl.h stdint.h swap.h syslimits.h syslog.h \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conf.h,v 1.94 2001/12/02 12:17:12 lukem Exp $ */
|
||||
/* $NetBSD: conf.h,v 1.95 2002/01/01 21:51:39 augustss Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
@ -369,6 +369,7 @@ extern struct cdevsw cdevsw[];
|
||||
#define cdev_openfirm_init(c,n) cdev__oci_init(c,n)
|
||||
#define cdev_openprom_init(c,n) cdev__oci_init(c,n)
|
||||
#define cdev_clockctl_init(c,n) cdev__oci_init(c,n)
|
||||
#define cdev_radio_init(c,n) cdev__oci_init(c,n)
|
||||
|
||||
/* open, close, read, ioctl, poll */
|
||||
#define cdev_usb_init(c,n) cdev__ocrip_init(c,n)
|
||||
|
69
sys/sys/radioio.h
Normal file
69
sys/sys/radioio.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* $NetBSD: radioio.h,v 1.1 2002/01/01 21:51:39 augustss Exp $ */
|
||||
/* $OpenBSD: radioio.h,v 1.2 2001/12/05 10:27:05 mickey Exp $ */
|
||||
/* $RuOBSD: radioio.h,v 1.4 2001/10/18 16:51:36 pva Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>,
|
||||
* 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 AUTHORS ``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 AUTHORS 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 _SYS_RADIOIO_H_
|
||||
#define _SYS_RADIOIO_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#define MIN_FM_FREQ 87500
|
||||
#define MAX_FM_FREQ 108000
|
||||
|
||||
#define IF_FREQ 10700
|
||||
|
||||
struct radio_info {
|
||||
int mute;
|
||||
int volume;
|
||||
int stereo;
|
||||
int rfreq; /* reference frequency */
|
||||
int lock; /* locking field strength during an automatic search */
|
||||
u_int32_t freq; /* in kHz */
|
||||
u_int32_t caps; /* card capabilities */
|
||||
#define RADIO_CAPS_DETECT_STEREO (1<<0)
|
||||
#define RADIO_CAPS_DETECT_SIGNAL (1<<1)
|
||||
#define RADIO_CAPS_SET_MONO (1<<2)
|
||||
#define RADIO_CAPS_HW_SEARCH (1<<3)
|
||||
#define RADIO_CAPS_HW_AFC (1<<4)
|
||||
#define RADIO_CAPS_REFERENCE_FREQ (1<<5)
|
||||
#define RADIO_CAPS_LOCK_SENSITIVITY (1<<6)
|
||||
#define RADIO_CAPS_RESERVED1 (1<<7)
|
||||
#define RADIO_CAPS_RESERVED2 (0xFF<<8)
|
||||
#define RADIO_CARD_TYPE (0xFF<<16)
|
||||
u_int32_t info;
|
||||
#define RADIO_INFO_STEREO (1<<0)
|
||||
#define RADIO_INFO_SIGNAL (1<<1)
|
||||
};
|
||||
|
||||
/* Radio device operations */
|
||||
#define RIOCGINFO _IOR('R', 21, struct radio_info) /* get info */
|
||||
#define RIOCSINFO _IOWR('R', 22, struct radio_info) /* set info */
|
||||
#define RIOCSSRCH _IOW('R', 23, int) /* search up/down */
|
||||
|
||||
#endif /* _SYS_RADIOIO_H_ */
|
Loading…
Reference in New Issue
Block a user