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