35#ifdef HAVE_KERNEL_OPTION_HEADERS
52#define SV_PCI_ID 0xca005333
53#define SV_DEFAULT_BUFSZ 16384
54#define SV_MIN_BLKSZ 128
55#define SV_INTR_PER_BUFFER 2
120#define sv_direct_set(x, y, z) _sv_direct_set(x, y, z, __LINE__)
136 device_printf(sc->
dev,
"sv_direct_set register 0x%02x %d != %d from line %d\n",
reg,
n,
val, line);
150#define sv_indirect_set(x, y, z) _sv_indirect_set(x, y, z, __LINE__)
161 reg &= ~SV_CM_INDEX_MCE;
166 device_printf(sc->
dev,
"sv_indirect_set register 0x%02x %d != %d line %d\n",
reg,
n,
val, line);
173 u_int32_t
base, u_int32_t
count, u_int8_t mode)
179 DEB(printf(
"base 0x%08x count %5d mode 0x%02x\n",
186 return bus_space_read_4(st, sh,
SV_DMA_COUNT) & 0xffffff;
204 DEB(printf(
"svchan_init failed\n"));
260 u_int32_t f_out, f_actual;
261 u_int32_t rs, re,
r, best_r = 0,
r2, t,
n, best_n = 0;
262 int32_t
m, best_m = 0, ms, me, err, min_err;
269 min_err = 0x7fffffff;
272 t = 80000000 / f_out;
273 for (rs = 1; (1 << rs) < t; rs++);
275 t = 150000000 / f_out;
276 for (re = 1; (2 << re) < t; re++);
280 for (
r = rs;
r <= re;
r++) {
282 for (
n = 3;
n < 34;
n++) {
284 ms = (
m > 3) ? (
m - 1) : 3;
285 me = (
m < 129) ? (
m + 1) : 129;
286 for (
m = ms;
m <= me;
m++) {
288 if (f_actual > f_out) {
289 err = f_actual - f_out;
291 err = f_out - f_actual;
307 DEB(printf(
"svrchan_setspeed: %d -> PLLM 0x%02x PLLNR 0x%08x\n",
363 u_int32_t sz, remain;
440 u_int32_t sz, remain;
445 return (sz - remain);
470}
static const mt [SOUND_MIXER_NRDEVICES] = {
517 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
527 for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
528 if (
mt[i].
max) v |= (1 << i);
532 for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
533 if (
mt[i].iselect) v |= (1 << i);
554 for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
555 if ((1 << i) &
mask) {
559 DEB(printf(
"sv_mix_setrecsrc: mask 0x%08x adc_input 0x%02x\n",
mask, v));
598 DEB(printf(
"Power state %d\n",
state));
669 device_printf(
dev,
"unable to reinitialize the card\n");
674 device_printf(
dev,
"unable to reinitialize the mixer\n");
714 switch(pci_get_devid(
dev)) {
716 device_set_desc(
dev,
"S3 Sonicvibes");
717 return BUS_PROBE_DEFAULT;
726 rman_res_t
count, midi_start, games_start;
729 u_long sdmaa, sdmac, ml, mu;
731 sc = malloc(
sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
734 pci_enable_busmaster(
dev);
736 if (pci_get_powerstate(
dev) != PCI_POWERSTATE_D0) {
737 device_printf(
dev,
"chip is in D%d power mode "
738 "-- setting to D0\n", pci_get_powerstate(
dev));
739 pci_set_powerstate(
dev, PCI_POWERSTATE_D0);
746 device_printf(
dev,
"sv_attach: cannot allocate enh\n");
753 DEB(printf(
"sv_attach: initial dmaa 0x%08x\n",
data));
755 DEB(printf(
"sv_attach: initial dmac 0x%08x\n",
data));
763 sc->
irq = bus_alloc_resource_any(
dev, SYS_RES_IRQ, &sc->
irqid,
764 RF_ACTIVE | RF_SHAREABLE);
767 device_printf(
dev,
"sv_attach: Unable to map interrupt\n");
772 if (bus_dma_tag_create(bus_get_dma_tag(
dev), 2,
774 BUS_SPACE_MAXADDR_24BIT,
781 device_printf(
dev,
"sv_attach: Unable to create dma tag\n");
791 device_printf(
dev,
"sv_attach: Mixer failed to initialize\n");
806 if (games_start < midi_start) {
816 if ((mu - ml >= 0x800) ||
817 ((mu - ml) % 0x200)) {
818 device_printf(
dev,
"sv_attach: resource assumptions not met "
819 "(midi 0x%08lx, games 0x%08lx)\n",
820 (u_long)midi_start, (u_long)games_start);
825 sdmac = sdmaa + 0x40;
838 device_printf(
dev,
"sv_attach: cannot allocate dmaa\n");
846 data = ((u_int32_t)sdmaa & 0xfffffff0) | (
data & 0x0f);
856 device_printf(
dev,
"sv_attach: cannot allocate dmac\n");
864 data = ((u_int32_t)sdmac & 0xfffffff0) | (
data & 0x0f);
869 printf(
"Sonicvibes: revision %d.\n", sc->
rev);
872 device_printf(
dev,
"sv_attach: pcm_register fail\n");
883 DEB(printf(
"sv_attach: succeeded\n"));
891 bus_teardown_intr(
dev, sc->
irq, sc->
ih);
893 bus_release_resource(
dev, SYS_RES_IRQ, sc->
irqid, sc->
irq);
916 bus_teardown_intr(
dev, sc->
irq, sc->
ih);
917 bus_release_resource(
dev, SYS_RES_IRQ, sc->
irqid, sc->
irq);
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size)
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf)
unsigned int sndbuf_getsize(struct snd_dbuf *b)
int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
void chn_intr(struct pcm_channel *c)
struct pcmchan_matrix * m
static int mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src)
int mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
static int mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev)
void mix_setdevs(struct snd_mixer *m, u_int32_t v)
int mixer_reinit(device_t dev)
void * mix_getdevinfo(struct snd_mixer *m)
void mix_setrecdevs(struct snd_mixer *m, u_int32_t v)
Record mask of available recording devices.
#define RANGE(var, low, high)
void * pcm_getdevinfo(device_t dev)
int pcm_setstatus(device_t dev, char *str)
int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
int pcm_unregister(device_t dev)
int pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep)
unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz)
#define SND_FORMAT(f, c, e)
#define DSP_DEFAULT_SPEED
struct pcm_channel * channel
struct resource * dmaa_reg
struct resource * dmac_reg
bus_space_handle_t dmaa_sh
bus_space_handle_t dmac_sh
bus_space_handle_t enh_sh
bus_dma_tag_t parent_dmat
struct resource * enh_reg
static struct pcmchan_caps * svchan_getcaps(kobj_t obj, void *data)
static int sv_detach(device_t dev)
static u_int32_t sc_fmt[]
static int svpchan_trigger(kobj_t obj, void *data, int go)
static int sv_attach(device_t dev)
static int svrchan_trigger(kobj_t obj, void *data, int go)
static void sv_mix_mute_all(struct sc_info *sc)
static void sv_intr(void *data)
DRIVER_MODULE(snd_vibes, pci, sonicvibes_driver, pcm_devclass, 0, 0)
static int svchan_setformat(kobj_t obj, void *data, u_int32_t format)
static int sv_init(struct sc_info *sc)
static void _sv_indirect_set(struct sc_info *sc, u_int8_t reg, u_int8_t val, int line)
static int sv_mix_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right)
static int sv_probe(device_t dev)
SND_DECLARE_FILE("$FreeBSD$")
static int sv_set_recspeed(struct sc_info *sc, u_int32_t speed)
static kobj_method_t svrchan_methods[]
static void _sv_direct_set(struct sc_info *sc, u_int8_t reg, u_int8_t val, int line)
static u_int32_t svpchan_getptr(kobj_t obj, void *data)
struct sv_mix_props mt[SOUND_MIXER_NRDEVICES]
static int sv_gain(struct sc_info *sc, u_int32_t dev, u_int32_t left, u_int32_t right)
static int sv_resume(device_t dev)
#define sv_direct_set(x, y, z)
#define sv_indirect_set(x, y, z)
static u_int8_t sv_direct_get(struct sc_info *sc, u_int8_t reg)
static u_int32_t svchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
static driver_t sonicvibes_driver
MODULE_DEPEND(snd_vibes, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER)
static int sv_mix_init(struct snd_mixer *m)
MODULE_VERSION(snd_vibes, 1)
static int sv_suspend(device_t dev)
#define SV_INTR_PER_BUFFER
static u_int32_t sv_dma_get_count(bus_space_tag_t st, bus_space_handle_t sh)
static device_method_t sc_methods[]
static struct pcmchan_caps sc_caps
static void * svchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
static void sv_dma_set_config(bus_space_tag_t st, bus_space_handle_t sh, u_int32_t base, u_int32_t count, u_int8_t mode)
static u_int32_t svrchan_getptr(kobj_t obj, void *data)
static u_int8_t sv_indirect_get(struct sc_info *sc, u_int8_t reg)
static void sv_power(struct sc_info *sc, int state)
static kobj_method_t sv_mixer_methods[]
static void sv_channel_gain(struct sc_info *sc, u_int32_t dev, u_int32_t gain, u_int32_t channel)
static u_int32_t svchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
static kobj_method_t svpchan_methods[]
static u_int32_t sv_mix_setrecsrc(struct snd_mixer *m, u_int32_t mask)
#define SV_DIGITAL_OFF_GP
#define SV_REG_PCM_SAMPLING_HI
#define SV_ANALOG_OFF_SPLL
#define SV_CM_STATUS_AINT
#define SV_REG_DIGITAL_PWR
#define SV_INPUT_GAIN_MASK
#define SV_ANALOG_OFF_SRS
#define SV_REG_CLOCK_SOURCE
#define SV_DIGITAL_OFF_SYN
#define SV_REG_DMAA_COUNT_LO
#define SV_PCI_DMA_ENABLE
#define SV_CM_CONTROL_ENHANCED
#define SV_PLAYBACK_PAUSE
#define SV_CM_STATUS_CINT
#define SV_REG_DMAA_COUNT_HI
#define SV_CM_CONTROL_RESET
#define SV_REG_ANALOG_PWR
#define SV_DIGITAL_OFF_MU
#define SV_REG_PCM_SAMPLING_LO
#define SV_PCI_DMA_EXTENDED
#define SV_REG_DMAC_COUNT_LO
#define SV_REG_DMAC_COUNT_HI