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# 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 1140