blob: a915a1affcde029637e10da78ab967e2661e6554 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001#! /bin/sh
2#
3# Turtle Beach MultiSound Driver Notes
4# -- Andrew Veliath <andrewtv@usa.net>
5#
6# Last update: September 10, 1998
7# Corresponding msnd driver: 0.8.3
8#
9# ** This file is a README (top part) and shell archive (bottom part).
10# The corresponding archived utility sources can be unpacked by
11# running `sh MultiSound' (the utilities are only needed for the
12# Pinnacle and Fiji cards). **
13#
14#
15# -=-=- Getting Firmware -=-=-
16# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17#
18# See the section `Obtaining and Creating Firmware Files' in this
19# document for instructions on obtaining the necessary firmware
20# files.
21#
22#
23# Supported Features
24# ~~~~~~~~~~~~~~~~~~
25#
26# Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is
27# not currently available) and mixer functionality (/dev/mixer) are
28# supported (memory mapped digital audio is not yet supported).
29# Digital transfers and monitoring can be done as well if you have
30# the digital daughterboard (see the section on using the S/PDIF port
31# for more information).
32#
33# Support for the Turtle Beach MultiSound Hurricane architecture is
34# composed of the following modules (these can also operate compiled
35# into the kernel):
36#
37# snd-msnd-lib - MultiSound base (requires snd)
38#
39# snd-msnd-classic - Base audio/mixer support for Classic, Monetery and
40# Tahiti cards
41#
42# snd-msnd-pinnacle - Base audio/mixer support for Pinnacle and Fiji cards
43#
44#
45# Important Notes - Read Before Using
46# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47#
48# The firmware files are not included (may change in future). You
49# must obtain these images from Turtle Beach (they are included in
50# the MultiSound Development Kits), and place them in /etc/sound for
51# example, and give the full paths in the Linux configuration. If
52# you are compiling in support for the MultiSound driver rather than
53# using it as a module, these firmware files must be accessible
54# during kernel compilation.
55#
56# Please note these files must be binary files, not assembler. See
57# the section later in this document for instructions to obtain these
58# files.
59#
60#
61# Configuring Card Resources
62# ~~~~~~~~~~~~~~~~~~~~~~~~~~
63#
64# ** This section is very important, as your card may not work at all
65# or your machine may crash if you do not do this correctly. **
66#
67# * Classic/Monterey/Tahiti
68#
69# These cards are configured through the driver snd-msnd-classic. You must
70# know the io port, then the driver will select the irq and memory resources
71# on the card. It is up to you to know if these are free locations or now,
72# a conflict can lock the machine up.
73#
74# * Pinnacle/Fiji
75#
76# The Pinnacle and Fiji cards have an extra config port, either
77# 0x250, 0x260 or 0x270. This port can be disabled to have the card
78# configured strictly through PnP, however you lose the ability to
79# access the IDE controller and joystick devices on this card when
80# using PnP. The included pinnaclecfg program in this shell archive
81# can be used to configure the card in non-PnP mode, and in PnP mode
82# you can use isapnptools. These are described briefly here.
83#
84# pinnaclecfg is not required; you can use the snd-msnd-pinnacle module
85# to fully configure the card as well. However, pinnaclecfg can be
86# used to change the resource values of a particular device after the
87# snd-msnd-pinnacle module has been loaded. If you are compiling the
88# driver into the kernel, you must set these values during compile
89# time, however other peripheral resource values can be changed with
90# the pinnaclecfg program after the kernel is loaded.
91#
92#
93# *** PnP mode
94#
95# Use pnpdump to obtain a sample configuration if you can; I was able
96# to obtain one with the command `pnpdump 1 0x203' -- this may vary
97# for you (running pnpdump by itself did not work for me). Then,
98# edit this file and use isapnp to uncomment and set the card values.
99# Use these values when inserting the snd-msnd-pinnacle module. Using
100# this method, you can set the resources for the DSP and the Kurzweil
101# synth (Pinnacle). Since Linux does not directly support PnP
102# devices, you may have difficulty when using the card in PnP mode
103# when it the driver is compiled into the kernel. Using non-PnP mode
104# is preferable in this case.
105#
106# Here is an example mypinnacle.conf for isapnp that sets the card to
107# io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil
108# synth to 0x330 and irq 9 (may need editing for your system):
109#
110# (READPORT 0x0203)
111# (CSN 2)
112# (IDENTIFY *)
113#
114# # DSP
115# (CONFIGURE BVJ0440/-1 (LD 0
116# (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000))
117# (ACT Y)))
118#
119# # Kurzweil Synth (Pinnacle Only)
120# (CONFIGURE BVJ0440/-1 (LD 1
121# (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E)))
122# (ACT Y)))
123#
124# (WAITFORKEY)
125#
126#
127# *** Non-PnP mode
128#
129# The second way is by running the card in non-PnP mode. This
130# actually has some advantages in that you can access some other
131# devices on the card, such as the joystick and IDE controller. To
132# configure the card, unpack this shell archive and build the
133# pinnaclecfg program. Using this program, you can assign the
134# resource values to the card's devices, or disable the devices. As
135# an alternative to using pinnaclecfg, you can specify many of the
136# configuration values when loading the snd-msnd-pinnacle module (or
137# during kernel configuration when compiling the driver into the
138# kernel).
139#
140# If you specify cfg=0x250 for the snd-msnd-pinnacle module, it
141# automatically configure the card to the given io, irq and memory
142# values using that config port (the config port is jumper selectable
143# on the card to 0x250, 0x260 or 0x270).
144#
145# See the `snd-msnd-pinnacle Additional Options' section below for more
146# information on these parameters (also, if you compile the driver
147# directly into the kernel, these extra parameters can be useful
148# here).
149#
150#
151# ** It is very easy to cause problems in your machine if you choose a
152# resource value which is incorrect. **
153#
154#
155# Examples
156# ~~~~~~~~
157#
158# * MultiSound Classic/Monterey/Tahiti:
159#
160# modprobe snd
161# insmod snd-msnd-lib
162# insmod snd-msnd-classic io=0x290 irq=7 mem=0xd0000
163#
164# * MultiSound Pinnacle in PnP mode:
165#
166# modprobe snd
167# insmod snd-msnd-lib
168# isapnp mypinnacle.conf
169# insmod snd-msnd-pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values
170#
171# * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port,
172# one of 0x250, 0x260 or 0x270):
173#
174# modprobe snd
175# insmod snd-msnd-lib
176# insmod snd-msnd-pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000
177#
178# * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP
179# mode, add the following (assumes you did `isapnp mypinnacle.conf'):
180#
181# insmod snd
182# insmod mpu401 io=0x330 irq=9 <-- match mypinnacle.conf values
183#
184# * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP
185# mode, add the following. Note how we first configure the peripheral's
186# resources, _then_ install a Linux driver for it:
187#
188# insmod snd
189# pinnaclecfg 0x250 mpu 0x330 9
190# insmod mpu401 io=0x330 irq=9
191#
192# -- OR you can use the following sequence without pinnaclecfg in non-PnP mode:
193#
194# modprobe snd
195# insmod snd-msnd-lib
196# insmod snd-msnd-pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9
197# insmod snd
198# insmod mpu401 io=0x330 irq=9
199#
200# * To setup the joystick port on the Pinnacle in non-PnP mode (though
201# you have to find the actual Linux joystick driver elsewhere), you
202# can use pinnaclecfg:
203#
204# pinnaclecfg 0x250 joystick 0x200
205#
206# -- OR you can configure this using snd-msnd-pinnacle with the following:
207#
208# modprobe snd
209# insmod snd-msnd-lib
210# insmod snd-msnd-pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200
211#
212#
213# snd-msnd-classic, snd-msnd-pinnacle Required Options
214# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215#
216# If the following options are not given, the module will not load.
217# Examine the kernel message log for informative error messages.
218# WARNING--probing isn't supported so try to make sure you have the
219# correct shared memory area, otherwise you may experience problems.
220#
221# io I/O base of DSP, e.g. io=0x210
222# irq IRQ number, e.g. irq=5
223# mem Shared memory area, e.g. mem=0xd8000
224#
225#
226# snd-msnd-classic, snd-msnd-pinnacle Additional Options
227# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
228#
229# fifosize The digital audio FIFOs, in kilobytes. If not
230# specified, the default will be used. Increasing
231# this value will reduce the chance of a FIFO
232# underflow at the expense of increasing overall
233# latency. For example, fifosize=512 will
234# allocate 512kB read and write FIFOs (1MB total).
235# While this may reduce dropouts, a heavy machine
236# load will undoubtedly starve the FIFO of data
237# and you will eventually get dropouts. One
238# option is to alter the scheduling priority of
239# the playback process, using `nice' or some form
240# of POSIX soft real-time scheduling.
241#
242# calibrate_signal Setting this to one calibrates the ADCs to the
243# signal, zero calibrates to the card (defaults
244# to zero).
245#
246#
247# snd-msnd-pinnacle Additional Options
248# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
249#
250# digital Specify digital=1 to enable the S/PDIF input
251# if you have the digital daughterboard
252# adapter. This will enable access to the
253# DIGITAL1 input for the soundcard in the mixer.
254# Some mixer programs might have trouble setting
255# the DIGITAL1 source as an input. If you have
256# trouble, you can try the setdigital.c program
257# at the bottom of this document.
258#
259# cfg Non-PnP configuration port for the Pinnacle
260# and Fiji (typically 0x250, 0x260 or 0x270,
261# depending on the jumper configuration). If
262# this option is omitted, then it is assumed
263# that the card is in PnP mode, and that the
264# specified DSP resource values are already
265# configured with PnP (i.e. it won't attempt to
266# do any sort of configuration).
267#
268# When the Pinnacle is in non-PnP mode, you can use the following
269# options to configure particular devices. If a full specification
270# for a device is not given, then the device is not configured. Note
271# that you still must use a Linux driver for any of these devices
272# once their resources are setup (such as the Linux joystick driver,
273# or the MPU401 driver from OSS for the Kurzweil synth).
274#
275# mpu_io I/O port of MPU (on-board Kurzweil synth)
276# mpu_irq IRQ of MPU (on-board Kurzweil synth)
277# ide_io0 First I/O port of IDE controller
278# ide_io1 Second I/O port of IDE controller
279# ide_irq IRQ IDE controller
280# joystick_io I/O port of joystick
281#
282#
283# Obtaining and Creating Firmware Files
284# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
285#
286# For the Classic/Tahiti/Monterey
287# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288#
289# Download to /tmp and unzip the following file from Turtle Beach:
290#
291# ftp://ftp.voyetra.com/pub/tbs/msndcl/msndvkit.zip
292#
293# When unzipped, unzip the file named MsndFiles.zip. Then copy the
294# following firmware files to /etc/sound (note the file renaming):
295#
296# cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin
297# cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin
298#
299# When configuring the Linux kernel, specify /etc/sound/msndinit.bin and
300# /etc/sound/msndperm.bin for the two firmware files (Linux kernel
301# versions older than 2.2 do not ask for firmware paths, and are
302# hardcoded to /etc/sound).
303#
304# If you are compiling the driver into the kernel, these files must
305# be accessible during compilation, but will not be needed later.
306# The files must remain, however, if the driver is used as a module.
307#
308#
309# For the Pinnacle/Fiji
310# ~~~~~~~~~~~~~~~~~~~~~
311#
312# Download to /tmp and unzip the following file from Turtle Beach (be
313# sure to use the entire URL; some have had trouble navigating to the
314# URL):
315#
316# ftp://ftp.voyetra.com/pub/tbs/pinn/pnddk100.zip
317#
318# Unpack this shell archive, and run make in the created directory
319# (you need a C compiler and flex to build the utilities). This
320# should give you the executables conv, pinnaclecfg and setdigital.
321# conv is only used temporarily here to create the firmware files,
322# while pinnaclecfg is used to configure the Pinnacle or Fiji card in
323# non-PnP mode, and setdigital can be used to set the S/PDIF input on
324# the mixer (pinnaclecfg and setdigital should be copied to a
325# convenient place, possibly run during system initialization).
326#
327# To generating the firmware files with the `conv' program, we create
328# the binary firmware files by doing the following conversion
329# (assuming the archive unpacked into a directory named PINNDDK):
330#
331# ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin
332# ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin
333#
334# The conv (and conv.l) program is not needed after conversion and can
335# be safely deleted. Then, when configuring the Linux kernel, specify
336# /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two
337# firmware files (Linux kernel versions older than 2.2 do not ask for
338# firmware paths, and are hardcoded to /etc/sound).
339#
340# If you are compiling the driver into the kernel, these files must
341# be accessible during compilation, but will not be needed later.
342# The files must remain, however, if the driver is used as a module.
343#
344#
345# Using Digital I/O with the S/PDIF Port
346# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
347#
348# If you have a Pinnacle or Fiji with the digital daughterboard and
349# want to set it as the input source, you can use this program if you
350# have trouble trying to do it with a mixer program (be sure to
351# insert the module with the digital=1 option, or say Y to the option
352# during compiled-in kernel operation). Upon selection of the S/PDIF
353# port, you should be able monitor and record from it.
354#
355# There is something to note about using the S/PDIF port. Digital
356# timing is taken from the digital signal, so if a signal is not
357# connected to the port and it is selected as recording input, you
358# will find PCM playback to be distorted in playback rate. Also,
359# attempting to record at a sampling rate other than the DAT rate may
360# be problematic (i.e. trying to record at 8000Hz when the DAT signal
361# is 44100Hz). If you have a problem with this, set the recording
362# input to analog if you need to record at a rate other than that of
363# the DAT rate.
364#
365#
366# -- Shell archive attached below, just run `sh MultiSound' to extract.
367# Contains Pinnacle/Fiji utilities to convert firmware, configure
368# in non-PnP mode, and select the DIGITAL1 input for the mixer.
369#
370#
371#!/bin/sh
372# This is a shell archive (produced by GNU sharutils 4.2).
373# To extract the files from this archive, save it to some FILE, remove
374# everything before the `!/bin/sh' line above, then type `sh FILE'.
375#
376# Made on 1998-12-04 10:07 EST by <andrewtv@ztransform.velsoft.com>.
377# Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'.
378#
379# Existing files will *not* be overwritten unless `-c' is specified.
380#
381# This shar contains:
382# length mode name
383# ------ ---------- ------------------------------------------
384# 2064 -rw-rw-r-- MultiSound.d/setdigital.c
385# 10224 -rw-rw-r-- MultiSound.d/pinnaclecfg.c
386# 106 -rw-rw-r-- MultiSound.d/Makefile
387# 146 -rw-rw-r-- MultiSound.d/conv.l
388# 1491 -rw-rw-r-- MultiSound.d/msndreset.c
389#
390save_IFS="${IFS}"
391IFS="${IFS}:"
392gettext_dir=FAILED
393locale_dir=FAILED
394first_param="$1"
395for dir in $PATH
396do
397 if test "$gettext_dir" = FAILED && test -f $dir/gettext \
398 && ($dir/gettext --version >/dev/null 2>&1)
399 then
400 set `$dir/gettext --version 2>&1`
401 if test "$3" = GNU
402 then
403 gettext_dir=$dir
404 fi
405 fi
406 if test "$locale_dir" = FAILED && test -f $dir/shar \
407 && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
408 then
409 locale_dir=`$dir/shar --print-text-domain-dir`
410 fi
411done
412IFS="$save_IFS"
413if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
414then
415 echo=echo
416else
417 TEXTDOMAINDIR=$locale_dir
418 export TEXTDOMAINDIR
419 TEXTDOMAIN=sharutils
420 export TEXTDOMAIN
421 echo="$gettext_dir/gettext -s"
422fi
423touch -am 1231235999 $$.touch >/dev/null 2>&1
424if test ! -f 1231235999 && test -f $$.touch; then
425 shar_touch=touch
426else
427 shar_touch=:
428 echo
429 $echo 'WARNING: not restoring timestamps. Consider getting and'
430 $echo "installing GNU \`touch', distributed in GNU File Utilities..."
431 echo
432fi
433rm -f 1231235999 $$.touch
434#
435if mkdir _sh01426; then
436 $echo 'x -' 'creating lock directory'
437else
438 $echo 'failed to create lock directory'
439 exit 1
440fi
441# ============= MultiSound.d/setdigital.c ==============
442if test ! -d 'MultiSound.d'; then
443 $echo 'x -' 'creating directory' 'MultiSound.d'
444 mkdir 'MultiSound.d'
445fi
446if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then
447 $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)'
448else
449 $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)'
450 sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' &&
451/*********************************************************************
452X *
453X * setdigital.c - sets the DIGITAL1 input for a mixer
454X *
455X * Copyright (C) 1998 Andrew Veliath
456X *
457X * This program is free software; you can redistribute it and/or modify
458X * it under the terms of the GNU General Public License as published by
459X * the Free Software Foundation; either version 2 of the License, or
460X * (at your option) any later version.
461X *
462X * This program is distributed in the hope that it will be useful,
463X * but WITHOUT ANY WARRANTY; without even the implied warranty of
464X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
465X * GNU General Public License for more details.
466X *
467X * You should have received a copy of the GNU General Public License
468X * along with this program; if not, write to the Free Software
469X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
470X *
471X ********************************************************************/
472X
473#include <stdio.h>
474#include <stdlib.h>
475#include <unistd.h>
476#include <fcntl.h>
477#include <sys/types.h>
478#include <sys/stat.h>
479#include <sys/ioctl.h>
480#include <sys/soundcard.h>
481X
482int main(int argc, char *argv[])
483{
484X int fd;
485X unsigned long recmask, recsrc;
486X
487X if (argc != 2) {
488X fprintf(stderr, "usage: setdigital <mixer device>\n");
489X exit(1);
490X }
491X
492X if ((fd = open(argv[1], O_RDWR)) < 0) {
493X perror(argv[1]);
494X exit(1);
495X }
496X
497X if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) {
498X fprintf(stderr, "error: ioctl read recording mask failed\n");
499X perror("ioctl");
500X close(fd);
501X exit(1);
502X }
503X
504X if (!(recmask & SOUND_MASK_DIGITAL1)) {
505X fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n");
506X close(fd);
507X exit(1);
508X }
509X
510X if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) {
511X fprintf(stderr, "error: ioctl read recording source failed\n");
512X perror("ioctl");
513X close(fd);
514X exit(1);
515X }
516X
517X recsrc |= SOUND_MASK_DIGITAL1;
518X
519X if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) {
520X fprintf(stderr, "error: ioctl write recording source failed\n");
521X perror("ioctl");
522X close(fd);
523X exit(1);
524X }
525X
526X close(fd);
527X
528X return 0;
529}
530SHAR_EOF
531 $shar_touch -am 1204092598 'MultiSound.d/setdigital.c' &&
532 chmod 0664 'MultiSound.d/setdigital.c' ||
533 $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed'
534 if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
535 && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
536 md5sum -c << SHAR_EOF >/dev/null 2>&1 \
537 || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed'
538e87217fc3e71288102ba41fd81f71ec4 MultiSound.d/setdigital.c
539SHAR_EOF
540 else
541 shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`"
542 test 2064 -eq "$shar_count" ||
543 $echo 'MultiSound.d/setdigital.c:' 'original size' '2064,' 'current size' "$shar_count!"
544 fi
545fi
546# ============= MultiSound.d/pinnaclecfg.c ==============
547if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then
548 $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)'
549else
550 $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)'
551 sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' &&
552/*********************************************************************
553X *
554X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program
555X *
556X * This is for NON-PnP mode only. For PnP mode, use isapnptools.
557X *
558X * This is Linux-specific, and must be run with root permissions.
559X *
560X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux
561X *
562X * Copyright (C) 1998 Andrew Veliath
563X *
564X * This program is free software; you can redistribute it and/or modify
565X * it under the terms of the GNU General Public License as published by
566X * the Free Software Foundation; either version 2 of the License, or
567X * (at your option) any later version.
568X *
569X * This program is distributed in the hope that it will be useful,
570X * but WITHOUT ANY WARRANTY; without even the implied warranty of
571X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
572X * GNU General Public License for more details.
573X *
574X * You should have received a copy of the GNU General Public License
575X * along with this program; if not, write to the Free Software
576X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
577X *
578X ********************************************************************/
579X
580#include <stdio.h>
581#include <stdlib.h>
582#include <string.h>
583#include <errno.h>
584#include <unistd.h>
585#include <asm/types.h>
586#include <sys/io.h>
587X
588#define IREG_LOGDEVICE 0x07
589#define IREG_ACTIVATE 0x30
590#define LD_ACTIVATE 0x01
591#define LD_DISACTIVATE 0x00
592#define IREG_EECONTROL 0x3F
593#define IREG_MEMBASEHI 0x40
594#define IREG_MEMBASELO 0x41
595#define IREG_MEMCONTROL 0x42
596#define IREG_MEMRANGEHI 0x43
597#define IREG_MEMRANGELO 0x44
598#define MEMTYPE_8BIT 0x00
599#define MEMTYPE_16BIT 0x02
600#define MEMTYPE_RANGE 0x00
601#define MEMTYPE_HIADDR 0x01
602#define IREG_IO0_BASEHI 0x60
603#define IREG_IO0_BASELO 0x61
604#define IREG_IO1_BASEHI 0x62
605#define IREG_IO1_BASELO 0x63
606#define IREG_IRQ_NUMBER 0x70
607#define IREG_IRQ_TYPE 0x71
608#define IRQTYPE_HIGH 0x02
609#define IRQTYPE_LOW 0x00
610#define IRQTYPE_LEVEL 0x01
611#define IRQTYPE_EDGE 0x00
612X
613#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
614#define LOBYTE(w) ((BYTE)(w))
615#define MAKEWORD(low,hi) ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8)))
616X
617typedef __u8 BYTE;
618typedef __u16 USHORT;
619typedef __u16 WORD;
620X
621static int config_port = -1;
622X
623static int msnd_write_cfg(int cfg, int reg, int value)
624{
625X outb(reg, cfg);
626X outb(value, cfg + 1);
627X if (value != inb(cfg + 1)) {
628X fprintf(stderr, "error: msnd_write_cfg: I/O error\n");
629X return -EIO;
630X }
631X return 0;
632}
633X
634static int msnd_read_cfg(int cfg, int reg)
635{
636X outb(reg, cfg);
637X return inb(cfg + 1);
638}
639X
640static int msnd_write_cfg_io0(int cfg, int num, WORD io)
641{
642X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
643X return -EIO;
644X if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
645X return -EIO;
646X if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
647X return -EIO;
648X return 0;
649}
650X
651static int msnd_read_cfg_io0(int cfg, int num, WORD *io)
652{
653X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
654X return -EIO;
655X
656X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO),
657X msnd_read_cfg(cfg, IREG_IO0_BASEHI));
658X
659X return 0;
660}
661X
662static int msnd_write_cfg_io1(int cfg, int num, WORD io)
663{
664X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
665X return -EIO;
666X if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
667X return -EIO;
668X if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
669X return -EIO;
670X return 0;
671}
672X
673static int msnd_read_cfg_io1(int cfg, int num, WORD *io)
674{
675X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
676X return -EIO;
677X
678X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO),
679X msnd_read_cfg(cfg, IREG_IO1_BASEHI));
680X
681X return 0;
682}
683X
684static int msnd_write_cfg_irq(int cfg, int num, WORD irq)
685{
686X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
687X return -EIO;
688X if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
689X return -EIO;
690X if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
691X return -EIO;
692X return 0;
693}
694X
695static int msnd_read_cfg_irq(int cfg, int num, WORD *irq)
696{
697X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
698X return -EIO;
699X
700X *irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER);
701X
702X return 0;
703}
704X
705static int msnd_write_cfg_mem(int cfg, int num, int mem)
706{
707X WORD wmem;
708X
709X mem >>= 8;
710X mem &= 0xfff;
711X wmem = (WORD)mem;
712X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
713X return -EIO;
714X if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
715X return -EIO;
716X if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
717X return -EIO;
718X if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
719X return -EIO;
720X return 0;
721}
722X
723static int msnd_read_cfg_mem(int cfg, int num, int *mem)
724{
725X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
726X return -EIO;
727X
728X *mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO),
729X msnd_read_cfg(cfg, IREG_MEMBASEHI));
730X *mem <<= 8;
731X
732X return 0;
733}
734X
735static int msnd_activate_logical(int cfg, int num)
736{
737X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
738X return -EIO;
739X if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
740X return -EIO;
741X return 0;
742}
743X
744static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
745{
746X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
747X return -EIO;
748X if (msnd_write_cfg_io0(cfg, num, io0))
749X return -EIO;
750X if (msnd_write_cfg_io1(cfg, num, io1))
751X return -EIO;
752X if (msnd_write_cfg_irq(cfg, num, irq))
753X return -EIO;
754X if (msnd_write_cfg_mem(cfg, num, mem))
755X return -EIO;
756X if (msnd_activate_logical(cfg, num))
757X return -EIO;
758X return 0;
759}
760X
761static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem)
762{
763X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
764X return -EIO;
765X if (msnd_read_cfg_io0(cfg, num, io0))
766X return -EIO;
767X if (msnd_read_cfg_io1(cfg, num, io1))
768X return -EIO;
769X if (msnd_read_cfg_irq(cfg, num, irq))
770X return -EIO;
771X if (msnd_read_cfg_mem(cfg, num, mem))
772X return -EIO;
773X return 0;
774}
775X
776static void usage(void)
777{
778X fprintf(stderr,
779X "\n"
780X "pinnaclecfg 1.0\n"
781X "\n"
782X "usage: pinnaclecfg <config port> [device config]\n"
783X "\n"
784X "This is for use with the card in NON-PnP mode only.\n"
785X "\n"
786X "Available devices (not all available for Fiji):\n"
787X "\n"
788X " Device Description\n"
789X " -------------------------------------------------------------------\n"
790X " reset Reset all devices (i.e. disable)\n"
791X " show Display current device configurations\n"
792X "\n"
793X " dsp <io> <irq> <mem> Audio device\n"
794X " mpu <io> <irq> Internal Kurzweil synth\n"
795X " ide <io0> <io1> <irq> On-board IDE controller\n"
796X " joystick <io> Joystick port\n"
797X "\n");
798X exit(1);
799}
800X
801static int cfg_reset(void)
802{
803X int i;
804X
805X for (i = 0; i < 4; ++i)
806X msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0);
807X
808X return 0;
809}
810X
811static int cfg_show(void)
812{
813X int i;
814X int count = 0;
815X
816X for (i = 0; i < 4; ++i) {
817X WORD io0, io1, irq;
818X int mem;
819X msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem);
820X switch (i) {
821X case 0:
822X if (io0 || irq || mem) {
823X printf("dsp 0x%x %d 0x%x\n", io0, irq, mem);
824X ++count;
825X }
826X break;
827X case 1:
828X if (io0 || irq) {
829X printf("mpu 0x%x %d\n", io0, irq);
830X ++count;
831X }
832X break;
833X case 2:
834X if (io0 || io1 || irq) {
835X printf("ide 0x%x 0x%x %d\n", io0, io1, irq);
836X ++count;
837X }
838X break;
839X case 3:
840X if (io0) {
841X printf("joystick 0x%x\n", io0);
842X ++count;
843X }
844X break;
845X }
846X }
847X
848X if (count == 0)
849X fprintf(stderr, "no devices configured\n");
850X
851X return 0;
852}
853X
854static int cfg_dsp(int argc, char *argv[])
855{
856X int io, irq, mem;
857X
858X if (argc < 3 ||
859X sscanf(argv[0], "0x%x", &io) != 1 ||
860X sscanf(argv[1], "%d", &irq) != 1 ||
861X sscanf(argv[2], "0x%x", &mem) != 1)
862X usage();
863X
864X if (!(io == 0x290 ||
865X io == 0x260 ||
866X io == 0x250 ||
867X io == 0x240 ||
868X io == 0x230 ||
869X io == 0x220 ||
870X io == 0x210 ||
871X io == 0x3e0)) {
872X fprintf(stderr, "error: io must be one of "
873X "210, 220, 230, 240, 250, 260, 290, or 3E0\n");
874X usage();
875X }
876X
877X if (!(irq == 5 ||
878X irq == 7 ||
879X irq == 9 ||
880X irq == 10 ||
881X irq == 11 ||
882X irq == 12)) {
883X fprintf(stderr, "error: irq must be one of "
884X "5, 7, 9, 10, 11 or 12\n");
885X usage();
886X }
887X
888X if (!(mem == 0xb0000 ||
889X mem == 0xc8000 ||
890X mem == 0xd0000 ||
891X mem == 0xd8000 ||
892X mem == 0xe0000 ||
893X mem == 0xe8000)) {
894X fprintf(stderr, "error: mem must be one of "
895X "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
896X usage();
897X }
898X
899X return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem);
900}
901X
902static int cfg_mpu(int argc, char *argv[])
903{
904X int io, irq;
905X
906X if (argc < 2 ||
907X sscanf(argv[0], "0x%x", &io) != 1 ||
908X sscanf(argv[1], "%d", &irq) != 1)
909X usage();
910X
911X return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0);
912}
913X
914static int cfg_ide(int argc, char *argv[])
915{
916X int io0, io1, irq;
917X
918X if (argc < 3 ||
919X sscanf(argv[0], "0x%x", &io0) != 1 ||
920X sscanf(argv[0], "0x%x", &io1) != 1 ||
921X sscanf(argv[1], "%d", &irq) != 1)
922X usage();
923X
924X return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0);
925}
926X
927static int cfg_joystick(int argc, char *argv[])
928{
929X int io;
930X
931X if (argc < 1 ||
932X sscanf(argv[0], "0x%x", &io) != 1)
933X usage();
934X
935X return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0);
936}
937X
938int main(int argc, char *argv[])
939{
940X char *device;
941X int rv = 0;
942X
943X --argc; ++argv;
944X
945X if (argc < 2)
946X usage();
947X
948X sscanf(argv[0], "0x%x", &config_port);
949X if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) {
950X fprintf(stderr, "error: <config port> must be 0x250, 0x260 or 0x270\n");
951X exit(1);
952X }
953X if (ioperm(config_port, 2, 1)) {
954X perror("ioperm");
955X fprintf(stderr, "note: pinnaclecfg must be run as root\n");
956X exit(1);
957X }
958X device = argv[1];
959X
960X argc -= 2; argv += 2;
961X
962X if (strcmp(device, "reset") == 0)
963X rv = cfg_reset();
964X else if (strcmp(device, "show") == 0)
965X rv = cfg_show();
966X else if (strcmp(device, "dsp") == 0)
967X rv = cfg_dsp(argc, argv);
968X else if (strcmp(device, "mpu") == 0)
969X rv = cfg_mpu(argc, argv);
970X else if (strcmp(device, "ide") == 0)
971X rv = cfg_ide(argc, argv);
972X else if (strcmp(device, "joystick") == 0)
973X rv = cfg_joystick(argc, argv);
974X else {
975X fprintf(stderr, "error: unknown device %s\n", device);
976X usage();
977X }
978X
979X if (rv)
980X fprintf(stderr, "error: device configuration failed\n");
981X
982X return 0;
983}
984SHAR_EOF
985 $shar_touch -am 1204092598 'MultiSound.d/pinnaclecfg.c' &&
986 chmod 0664 'MultiSound.d/pinnaclecfg.c' ||
987 $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed'
988 if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
989 && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
990 md5sum -c << SHAR_EOF >/dev/null 2>&1 \
991 || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed'
992366bdf27f0db767a3c7921d0a6db20fe MultiSound.d/pinnaclecfg.c
993SHAR_EOF
994 else
995 shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`"
996 test 10224 -eq "$shar_count" ||
997 $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10224,' 'current size' "$shar_count!"
998 fi
999fi
1000# ============= MultiSound.d/Makefile ==============
1001if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then
1002 $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)'
1003else
1004 $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)'
1005 sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' &&
1006CC = gcc
1007CFLAGS = -O
1008PROGS = setdigital msndreset pinnaclecfg conv
1009X
1010all: $(PROGS)
1011X
1012clean:
1013X rm -f $(PROGS)
1014SHAR_EOF
1015 $shar_touch -am 1204092398 'MultiSound.d/Makefile' &&
1016 chmod 0664 'MultiSound.d/Makefile' ||
1017 $echo 'restore of' 'MultiSound.d/Makefile' 'failed'
1018 if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1019 && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1020 md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1021 || $echo 'MultiSound.d/Makefile:' 'MD5 check failed'
102276ca8bb44e3882edcf79c97df6c81845 MultiSound.d/Makefile
1023SHAR_EOF
1024 else
1025 shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`"
1026 test 106 -eq "$shar_count" ||
1027 $echo 'MultiSound.d/Makefile:' 'original size' '106,' 'current size' "$shar_count!"
1028 fi
1029fi
1030# ============= MultiSound.d/conv.l ==============
1031if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then
1032 $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)'
1033else
1034 $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)'
1035 sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' &&
1036%%
1037[ \n\t,\r]
1038\;.*
1039DB
1040[0-9A-Fa-f]+H { int n; sscanf(yytext, "%xH", &n); printf("%c", n); }
1041%%
1042int yywrap() { return 1; }
1043void main() { yylex(); }
1044SHAR_EOF
1045 $shar_touch -am 0828231798 'MultiSound.d/conv.l' &&
1046 chmod 0664 'MultiSound.d/conv.l' ||
1047 $echo 'restore of' 'MultiSound.d/conv.l' 'failed'
1048 if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1049 && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1050 md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1051 || $echo 'MultiSound.d/conv.l:' 'MD5 check failed'
1052d2411fc32cd71a00dcdc1f009e858dd2 MultiSound.d/conv.l
1053SHAR_EOF
1054 else
1055 shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`"
1056 test 146 -eq "$shar_count" ||
1057 $echo 'MultiSound.d/conv.l:' 'original size' '146,' 'current size' "$shar_count!"
1058 fi
1059fi
1060# ============= MultiSound.d/msndreset.c ==============
1061if test -f 'MultiSound.d/msndreset.c' && test "$first_param" != -c; then
1062 $echo 'x -' SKIPPING 'MultiSound.d/msndreset.c' '(file already exists)'
1063else
1064 $echo 'x -' extracting 'MultiSound.d/msndreset.c' '(text)'
1065 sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/msndreset.c' &&
1066/*********************************************************************
1067X *
1068X * msndreset.c - resets the MultiSound card
1069X *
1070X * Copyright (C) 1998 Andrew Veliath
1071X *
1072X * This program is free software; you can redistribute it and/or modify
1073X * it under the terms of the GNU General Public License as published by
1074X * the Free Software Foundation; either version 2 of the License, or
1075X * (at your option) any later version.
1076X *
1077X * This program is distributed in the hope that it will be useful,
1078X * but WITHOUT ANY WARRANTY; without even the implied warranty of
1079X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1080X * GNU General Public License for more details.
1081X *
1082X * You should have received a copy of the GNU General Public License
1083X * along with this program; if not, write to the Free Software
1084X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1085X *
1086X ********************************************************************/
1087X
1088#include <stdio.h>
1089#include <stdlib.h>
1090#include <unistd.h>
1091#include <fcntl.h>
1092#include <sys/types.h>
1093#include <sys/stat.h>
1094#include <sys/ioctl.h>
1095#include <sys/soundcard.h>
1096X
1097int main(int argc, char *argv[])
1098{
1099X int fd;
1100X
1101X if (argc != 2) {
1102X fprintf(stderr, "usage: msndreset <mixer device>\n");
1103X exit(1);
1104X }
1105X
1106X if ((fd = open(argv[1], O_RDWR)) < 0) {
1107X perror(argv[1]);
1108X exit(1);
1109X }
1110X
1111X if (ioctl(fd, SOUND_MIXER_PRIVATE1, 0) < 0) {
1112X fprintf(stderr, "error: msnd ioctl reset failed\n");
1113X perror("ioctl");
1114X close(fd);
1115X exit(1);
1116X }
1117X
1118X close(fd);
1119X
1120X return 0;
1121}
1122SHAR_EOF
1123 $shar_touch -am 1204100698 'MultiSound.d/msndreset.c' &&
1124 chmod 0664 'MultiSound.d/msndreset.c' ||
1125 $echo 'restore of' 'MultiSound.d/msndreset.c' 'failed'
1126 if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1127 && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1128 md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1129 || $echo 'MultiSound.d/msndreset.c:' 'MD5 check failed'
1130c52f876521084e8eb25e12e01dcccb8a MultiSound.d/msndreset.c
1131SHAR_EOF
1132 else
1133 shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/msndreset.c'`"
1134 test 1491 -eq "$shar_count" ||
1135 $echo 'MultiSound.d/msndreset.c:' 'original size' '1491,' 'current size' "$shar_count!"
1136 fi
1137fi
1138rm -fr _sh01426
1139exit 0