#!/bin/bash## ALSA Configurator## Copyright (c) 1999-2002 SuSE GmbH# Jan ONDREJ## written by Takashi Iwai <tiwai@suse.de># Bernd Kaindl <bk@suse.de># Jan ONDREJ (SAL) <ondrejj@salstar.sk>## based on the original version of Jan ONDREJ's alsaconf for ALSA 0.4.## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.#export TEXTDOMAIN=alsaconfprefix=/usrexec_prefix=${prefix}bindir=${exec_prefix}/binsbindir=${exec_prefix}/sbinversion=1.0.16USE_NLS=yes# Useful for debuggingPROCFS="/proc"SYSFS="/sys"# i18n stuffif test "$USE_NLS" = "yes" && which gettext > /dev/null; then xecho() { gettext -s "$*" }else xecho() { echo "$*" } gettext() { echo -n "$*" }fixmsg() { msg=$(gettext "$1") shift printf "$msg" $*}# Check for GNU/Linux distributionsif [ -f /etc/SuSE-release ]; then distribution="suse" suse_version=$(grep 'VERSION = ' /etc/SuSE-release | sed -e s/'VERSION = '//)elif [ -f /etc/UnitedLinux-release ]; then distribution="suse"elif [ -f /etc/gentoo-release ]; then distribution="gentoo"elif [ -f /etc/debian_version ]; then distribution="debian"elif [ -f /etc/mandrake-release ]; then distribution="mandrake"elif test -f /etc/redhat-release && grep -q "Red Hat" /etc/redhat-release; then distribution="redhat"elif test -f /etc/fedora-release && grep -q "Fedora" /etc/fedora-release; then distribution="fedora"elif test -f /etc/arch-release && grep -q "Arch" /etc/arch-release; then distribution="arch"else distribution="unknown"fifor prog in lspci lsmod; do for path in /sbin /usr/sbin /bin /usr/bin;do test -x $path/$prog && eval $prog=$path/$prog donedoneunset prog pathusage() { xecho "ALSA configurator" echo " version $version" xecho "usage: alsaconf [options] -l|--legacy check only legacy non-isapnp cards -m|--modinfo read module descriptions instead of reading card db -s|--sound wav-file use the specified wav file as a test sound -u|--uid uid set the uid for the ALSA devices (default = 0) [obsoleted] -g|--gid gid set the gid for the ALSA devices (default = 0) [obsoleted] -d|--devmode mode set the permission for ALSA devices (default = 0666) [obs.] -r|--strict set strict device mode (equiv. with -g 17 -d 0660) [obsoleted] -L|--log file logging on the specified file (for debugging purpose only) -p|--probe card-name probe a legacy non-isapnp card and print module options -P|--listprobe list the supported legacy card modules -c|--config file specify the module config file -R|--resources list available DMA and IRQ resources with debug for legacy -h|--help what you're reading"}OPTS=`getopt -o lmL:hp:Pu:g:d:rs:c:R --long legacy,modinfo,log:,help,probe:,listprobe,uid:,gid:,devmode:,strict,sound:,config:,resources -n alsaconf -- "$@"` || exit 1eval set -- "$OPTS"do_legacy_only=0use_modinfo_db=0alsa_uid=0alsa_gid=0alsa_mode=0666legacy_probe_card=""LOGFILE=""TESTSOUND="/usr/share/sounds/alsa/test.wav"try_all_combination=0resources="false"# legacy supportLEGACY_CARDS="opl3sa2 cs4236 cs4232 cs4231 es18xx es1688 sb16 sb8"while true ; do case "$1" in -l|--legacy) do_legacy_only=1; shift ;; -m|--modinfo) use_modinfo_db=1; shift ;; -s|--sound) TESTSOUND=$2; shift 2;; -h|--help) usage; exit 0 ;; -L|--log) LOGFILE="$2"; shift 2;; -p|--probe) legacy_probe_card="$2"; shift 2;; -P|--listprobe) echo "$LEGACY_CARDS"; exit 0;; -u|--uid) alsa_uid="$2"; shift 2;; -g|--gid) alsa_gid="$2"; shift 2;; -d|--devmode) alsa_mode="$2"; shift 2;; -r|--strict) alsa_uid=0; alsa_gid=17; alsa_mode=0660; shift;; -c|--config) cfgfile="$2"; shift 2;; -R|--resources) resources="true"; shift;; --) shift ; break ;; *) usage ; exit 1 ;; esacdone## probe legacy ISA cards#check_dma_avail () { list="" if [ -d $SYSFS/bus/pnp/devices ]; then for dma in $*; do ok="true" for i in $SYSFS/bus/pnp/devices/??:* ; do if grep -q "state = active" $i/resources ; then if grep -q '^dma '$dma'$' $i/resources; then ok="false" fi fi done if [ -r $PROCFS/dma ]; then if grep -q '^ *'$dma': ' $PROCFS/dma ; then ok="false" fi fi if [ "$ok" = "true" ]; then list="$list $dma" fi done else if [ -r $PROCFS/dma ]; then for dma in $*; do grep -q '^ *'$dma': ' $PROCFS/dma || list="$list $dma" done fi fi if [ ! -z "$list" ]; then echo $list fi}check_irq_avail () { list="" if [ -d $SYSFS/bus/pnp/devices ]; then for irq in $*; do ok="true" for i in $SYSFS/bus/pnp/devices/??:* ; do if grep -q "state = active" $i/resources ; then if grep -q '^irq '$irq'$' $i/resources; then ok="false" fi fi done if [ -r $PROCFS/interrupts ]; then if grep -q '^ *'$irq': ' $PROCFS/interrupts ; then ok="false" fi fi if [ "$ok" = "true" ]; then list="$list $irq" fi done else if [ -r $PROCFS/interrupts ]; then for irq in $*; do grep -q '^ *'$irq': ' $PROCFS/interrupts || list="$list $irq" done fi fi if [ ! -z "$list" ]; then echo $list fi}###if [ "$resources" = "true" ]; then if [ -d $SYSFS/bus/pnp/devices ]; then for i in $SYSFS/bus/pnp/devices/??:* ; do if [ "$resources" = "true" ]; then echo ">>>>> PnP file: $i/resources" cat $i/resources fi done fi if [ -r $PROCFS/dma ]; then echo ">>>>> Allocated dma channels:" cat $PROCFS/dma fi if [ -r $PROCFS/interrupts ]; then echo ">>>>> Allocated interrupt channels:" cat $PROCFS/interrupts fi echo -n "Valid DMA channels: " check_dma_avail 0 1 2 3 4 5 6 7 echo -n "Valid IRQ channels: " check_irq_avail 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 exit 0fi# Check for root privilegesif [ `id -u` -ne 0 ]; then xecho "You must be root to use this script." exit 1fi## check the snd_ prefix for ALSA module options# snd_ prefix is obsoleted since 0.9.0rc4.#if /sbin/modinfo -p snd | grep -q snd_ ; then mpfx="snd_"else mpfx=""fialsa_device_opts=""if /sbin/modinfo -p snd | grep -q uid ; then if [ x"$alsa_uid" != x0 ]; then alsa_device_opts="$alsa_device_opts ${mpfx}device_uid=$alsa_uid" fi if [ x"$alsa_gid" != x0 ]; then alsa_device_opts="$alsa_device_opts ${mpfx}device_gid=$alsa_gid" fifiif /sbin/modinfo -p snd | grep -q device_mode ; then if [ x"$alsa_mode" != x0 ]; then alsa_device_opts="$alsa_device_opts ${mpfx}device_mode=$alsa_mode" fificase `uname -r` in2.6.*) kernel="new" ;;*) kernel="old" ;;esac# cfgfile = base config file to remove/update the sound setting# cfgout = new config file to write the sound setting (if different from $cfgfile)if [ -n "$cfgfile" ]; then if [ ! -r "$cfgfile" ]; then xecho "ERROR: The config file doesn't exist: " echo $cfgfile exit 1 fielseif [ "$distribution" = "gentoo" ]; then cfgfile="/etc/modules.d/alsa"elif [ "$kernel" = "new" ]; then if [ -d /etc/modprobe.d ]; then cfgout="/etc/modprobe.d/sound" fi cfgfile="/etc/modprobe.conf"elif [ "$distribution" = "debian" ]; then cfgfile="/etc/modutils/sound"elif [ -e /etc/modules.conf ]; then cfgfile="/etc/modules.conf"elif [ -e /etc/conf.modules ]; then cfgfile="/etc/conf.modules"else cfgfile="/etc/modules.conf" touch /etc/modules.conffifi# Check for dialog, whiptail, gdialog, awk, ... ?if which dialog > /dev/null; then DIALOG=dialogelse if which whiptail > /dev/null; then whiptail_wrapper() { X1="$1" X2="$2" if [ $1 = --yesno ]; then X3=`expr $3 + 2` else X3=$3 fi shift 3 whiptail "$X1" "$X2" $X3 "$@" } DIALOG=whiptail_wrapper else xecho "Error, dialog or whiptail not found." exit 1 fifiif which awk > /dev/null; then :else xecho "Error, awk not found. Can't continue." exit 1fi## remove entries by yast2 sound configurator#remove_y2_block() { awk ' /^alias sound-slot-[0-9]/ { next } /^alias char-major-116 / { next } /^alias char-major-14 / { next } /^alias snd-card-[0-9] / { next } /^options snd / { next } /^options snd-/ { next } /^options off / { next } /^alias sound-service-[0-9]/ { next } /^# YaST2: sound / { next } { print }'}## remove entries by sndconfig sound configurator## found strings to search for in WriteConfModules, # from sndconfig 0.68-4 (rawhide version)remove_sndconfig_block() { awk ' /^alias sound-slot-0/ { modulename = $3 ; next } /^alias sound-slot-[0-9]/ { next } /^post-install sound-slot-[0-9] / { next } /^pre-remove sound-slot-[0-9] / { next } /^options sound / { next } /^alias synth0 opl3/ { next } /^options opl3 / { next } /^alias midi / { mididev = $3 ; next } /^options / { if ($2 == mididev) next } /^pre-install / { if ($2 == mididev) next } /^alias synth0 / { synth = $3 ; next } /^post-install / { if ($2 == synth) next } /^options sb / { next } /^post-install .+ \/bin\/modprobe "aci"/ { if ($2 == modulename) next } /^options adlib_card / { next } /^options .+ isapnp=1/ { if ($2 == modulename) next } /^options i810_audio / { next } /^options / {if ($2 == modulename) next } { print }'}## remove the previous configuration by alsaconf#remove_ac_block() { awk '/^'"$ACB"'$/,/^'"$ACE"'$/ { next } { print }'}## set default mixer volumes#set_mixers() { amixer -s -q <<EOFset Master 75% unmuteset Master -12dBset 'Master Mono' 75% unmuteset 'Master Mono' -12dBset Front 75% unmuteset Front -12dBset PCM 90% unmuteset PCM 0dBmixer Synth 90% unmutemixer Synth 0dBmixer CD 90% unmutemixer CD 0dB# mute micset Mic 0% mute# ESS 1969 chipset has 2 PCM channelsset PCM,1 90% unmuteset PCM,1 0dB# Trident/YMFPCI/emu10k1set Wave 100% unmuteset Music 100% unmuteset AC97 100% unmute# CS4237B chipset:set 'Master Digital' 75% unmute# Envy24 chips with analog outsset DAC 90% unmuteset DAC -12dBset DAC,0 90% unmuteset DAC,0 -12dBset DAC,1 90% unmuteset DAC,1 -12dB# some notebooks use headphone instead of masterset Headphone 75% unmuteset Headphone -12dBset Playback 100% unmute# turn off digital switchesset "SB Live Analog/Digital Output Jack" offset "Audigy Analog/Digital Output Jack" offEOF}# INTROintro() { local msg=$(xmsg " ALSA CONFIGURATOR version %s This script is a configurator for Advanced Linux Sound Architecture (ALSA) driver. If ALSA is already running, you should close all sound apps now and stop the sound driver. alsaconf will try to do this, but it's not 100%% sure." $version) $DIALOG --msgbox "$msg" 20 63 || acex 0}# FAREWELLfarewell() { local msg=$(gettext " OK, sound driver is configured. ALSA CONFIGURATOR will prepare the card for playing now. Now I'll run alsasound init script, then I'll use amixer to raise the default volumes. You can change the volume later via a mixer program such as alsamixer or gamix. ") $DIALOG --msgbox "$msg" 17 60 || acex 0}# Exit functionacex() { cleanup clear exit $1}## search for alsasound init script#if [ "$distribution" = "debian" ]; then rcalsasound=/etc/init.d/alsaelif [ -x /etc/init.d/alsasound ]; then rcalsasound=/etc/init.d/alsasoundelif [ -x /usr/sbin/rcalsasound ]; then rcalsasound=/usr/sbin/rcalsasoundelif [ -x /sbin/rcalsasound ]; then rcalsasound=/sbin/rcalsasoundelif [ -x /etc/rc.d/init.d/alsasound ]; then rcalsasound=/etc/rc.d/init.d/alsasoundelif [ -x /etc/init.d/alsa ]; then rcalsasound=/etc/init.d/alsaelif [ -x /etc/rc.d/alsa ]; then rcalsasound=/etc/rc.d/alsaelse rcalsasound=rcalsasoundfi# MAINif [ -d $PROCFS/asound ]; then $rcalsasound stop >/dev/null 2>&1 $rcalsasound unload >/dev/null 2>&1 /sbin/rmmod dmasound dmasound_awacs 2>/dev/nullficleanup () { killall -9 aplay arecord >/dev/null 2>&1 /sbin/modprobe -r isapnp >/dev/null 2>&1 /sbin/modprobe -r isa-pnp >/dev/null 2>&1 rm -f "$TMP" "$addcfg" "$FOUND" "$DUMP"}trap cleanup 0TMP=`mktemp -q /tmp/alsaconf.XXXXXX`if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1fiaddcfg=`mktemp -q /tmp/alsaconf.XXXXXX`if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1fiFOUND=`mktemp -q /tmp/alsaconf.XXXXXX`if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1fiDUMP=`mktemp -q /tmp/alsaconf.XXXXXX`if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1fi# convert ISA PnP id number to string 'ABC'convert_isapnp_id () { if [ -z "$1" ]; then echo "XXXX" return fi let a='('$1'>>2) & 0x3f' let b='(('$1' & 0x03) << 3) | (('$1' >> 13) & 0x07)' let c='('$1'>> 8) & 0x1f' strs='@ABCDEFGHIJKLMNOPQRSTUVWXYZ' echo ${strs:$a:1}${strs:$b:1}${strs:$c:1}}# swap high & low bytesswap_number () { if [ -z "$1" ]; then echo "0000" return fi let v='(('$1'>>8)&0xff)|(('$1'&0xff)<<8)' printf "%04x" $v}# build card database# build_card_db filenamebuild_card_db () { MODDIR=/lib/modules/`uname -r` last_driver="" echo -n > $1 # list pci cards while read driver vendor device dummy; do if expr $driver : 'snd-.*' >/dev/null ; then if [ "$last_driver" != "$driver" ]; then echo $driver.o last_driver=$driver fi id1=`printf '0x%04x' $vendor` id2=`printf '0x%04x' $device` echo "PCI: $id1=$id2" fi done < $MODDIR/modules.pcimap >> $1 # list isapnp cards while read driver cardvendor carddevice data vendor func; do if expr $driver : 'snd-.*' >/dev/null ; then if [ "$last_driver" != "$driver" ]; then echo $driver.o last_driver=$driver fi id1=`convert_isapnp_id $cardvendor` dev1=`swap_number $carddevice` id2=`convert_isapnp_id $vendor` dev2=`swap_number $func` echo "ISAPNP: $id1$dev1=$id2$dev2" fi done < $MODDIR/modules.isapnpmap >> $1}## probe cards#probe_cards () { found="0" test -r $PROCFS/isapnp || /sbin/modprobe isapnp >/dev/null 2>&1 test -r $PROCFS/isapnp || /sbin/modprobe isa-pnp >/dev/null 2>&1 if [ -r $PROCFS/isapnp ]; then cat $PROCFS/isapnp >"$DUMP" found="1" elif [ -d $SYSFS/bus/pnp/devices ]; then # use 2.6 kernel's sysfs output # fake the isapnp dump index=0 bindex=0 for d1 in $SYSFS/devices/pnp* ; do for d2 in $d1/*:* ; do if [ -r $d2/card_id ]; then id=`cat $d2/card_id` name=`cat $d2/name` echo "Card $index '$id:$name' " >> "$DUMP" index=$[$index+1] found="1" else if [ -r $d2/id ]; then # FIXME: multiple id might be present (separated with new-line) id=`head -n 1 $d2/id` echo "BIOS $bindex '$id' " >> "$DUMP" bindex=$[$bindex+1] found="1" fi fi done done fi if [ "$found" = "0" ]; then echo -n >"$DUMP" fi CARDID_DB=/var/tmp/alsaconf.cards if [ ! -r $CARDID_DB ]; then use_modinfo_db=1 fi if [ $use_modinfo_db != 1 ]; then if [ $CARDID_DB -ot /lib/modules/`uname -r`/modules.dep ]; then use_modinfo_db=1 fi fi if [ $use_modinfo_db = 1 ]; then xecho "Building card database.." build_card_db $CARDID_DB fi if [ ! -r $CARDID_DB ]; then xecho "No card database is found.." exit 1 fi ncards=`grep '^snd-.*\.o$' $CARDID_DB | wc -w` msg=$(gettext "Searching sound cards") awk 'BEGIN { format="%-40s %s\n"; ncards='"$ncards"'; idx=0;}/^snd-.*\.o$/{ sub(/.o$/, ""); driver=$0; perc=(idx * 100) / (ncards + 1); print int(perc); idx++;}/^[<literal space><literal tab>]*PCI: /{ gsub(/0x/, ""); gsub(/=/, ":"); x = sprintf ("'$lspci' -n 2>/dev/null| grep '"' 04..: '"' | grep %s", $2); if (system (x) == 0) printf "%s %s\n", $2, driver >>"'"$FOUND"'"}/^[<literal space><literal tab>]*ISAPNP: /{ id2 = substr($0, index($0, "=")+1); gsub(/=.*/, ""); x = sprintf ("grep '\''^Card [0-9] .%s:'\'' '"$DUMP"'", $2); if (system (x) == 0) printf "%s %s\n", $2, driver >>"'"$FOUND"'" else if (index($2, "ffff") > 0) { x = sprintf ("grep '\''^BIOS [0-9]* .%s.'\'' '"$DUMP"'", id2); if (system (x) == 0) printf "%s %s\n", id2, driver >>"'"$FOUND"'" }}' < $CARDID_DB |\ $DIALOG --gauge "$msg" 6 40 0 # # PowerMac # if grep -q MacRISC $PROCFS/cpuinfo; then MODDIR=/lib/modules/`uname -r` find $MODDIR -name 'snd-powermac*' -print | \ while read i; do i=${i##*/} i=${i%%.o} i=${i%%.ko} echo "PowerMac $i" >> $FOUND done fi # # Sparc # if grep -q Sparc $PROCFS/cpuinfo; then test -r $PROCFS/openprom/name || /bin/mount -t openpromfs none $PROCFS/openprom >/dev/null 2>&1 # Check for an "audio" device audio= compat= if test -r $PROCFS/openprom; then audio=`find $PROCFS/openprom -follow -type d -name "audio*" -print` fi if test -n "$audio"; then compat=`cat $audio/compatible` compat=${compat#\'} compat=${compat%\'} compat=${compat#SUNW,} fi # Go through all cards we have MODDIR=/lib/modules/`uname -r` find $MODDIR -name 'snd-sun-*' -print | \ while read i; do i=${i##*/} i=${i%%.o} i=${i%%.ko} sdev=`echo ${i#snd-sun-} | tr "[a-z]" "[A-Z]"` if test "$sdev" = "$compat"; then echo "$sdev $i" >> $FOUND elif test -r $PROCFS/openprom; then find $PROCFS/openprom -follow -type d -name "SUNW,${sdev}*" \ -exec echo "$sdev $i" \; 2>/dev/null >> $FOUND else echo "$sdev $i" >> $FOUND fi done fi}## look for a descriptive device name from the given device id#find_device_name () { if expr "$1" : '[0-9a-f][0-9a-f][0-9a-f][0-9a-f]:[0-9a-f][0-9a-f][0-9a-f][0-9a-f]' >/dev/null; then $lspci -d $1 2>/dev/null| sed -e 's/^.*:..\.. [^:]*: //g' return elif expr "$1" : '[A-Z@][A-Z@][A-Z@][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' >/dev/null; then cardname=`grep '^Card [0-9]\+ .'$1':' $DUMP | head -n 1 | sed -e 's/^Card [0-9]\+ '\''.*:\(.*\)'\'' .*$/\1/'` echo $cardname else echo $1 fi}# get hwcfg file type from the given driver nameget_hwcfg_type () { while read dev driver; do if [ "$driver" = "$1" ]; then case "$dev" in *:*) # FIXME: need to look around /sys/bus/pci/* (or use vpid-* ?) devid=`$lspci -d "$dev" | head -n 1 | sed -e 's/ .*$//'` case "$devid" in *:*:*.*) ;; *) devid="0000:$devid" ;; esac echo bus-pci-$devid ;; *) echo $driver ;; esac break fi done}# clean up all hwcfg-* files containing ALSA modules# alsaconf sets up exclusivelycleanup_hwcfg () { for i in /etc/sysconfig/hardware/hwcfg-*; do grep -q "MODULE='snd-" $i && rm -f $i done}## set up /etc/sysconfig/hardware/hwcfg-* stuff#setup_hwcfg () { card=$1 cleanup_hwcfg cfg=`echo "$devs_olist" | get_hwcfg_type $card` echo "MODULE='$card'" > /etc/sysconfig/hardware/hwcfg-$cfg echo "STARTMODE='auto'" >> /etc/sysconfig/hardware/hwcfg-$cfg}## configure and try test sound#ac_config_card () { CARD_DRIVER=snd-$1 CARD_OPTS="${*:2}" if [ -n "$cfgout" ]; then msg=$(xmsg "Configuring %sDo you want to modify %s (and %s if present)?" $CARD_DRIVER $cfgout $cfgfile) $DIALOG --yesno "$msg" 8 50 || acex 0 else msg=$(xmsg "Configuring %sDo you want to modify %s?" $CARD_DRIVER $cfgfile) $DIALOG --yesno "$msg" 8 50 || acex 0 fi clear # Copy conf.modules and make changes. ACB="# --- BEGIN: Generated by ALSACONF, do not edit. ---" ACE="# --- END: Generated by ALSACONF, do not edit. ---" # Detect 2.2.X kernel KVER=`uname -r | tr ".-" " "` KVER1=`echo $KVER | cut -d" " -f1` KVER2=`echo $KVER | cut -d" " -f2` if [ $KVER1 -ge 2 ] && [ $KVER2 -ge 2 ]; then SOUND_CORE="soundcore" else SOUND_CORE="snd" fi if [ -r $cfgfile ] ; then if [ "$distribution" = "redhat" -o "$distribution" = "fedora" ] ; then remove_ac_block < $cfgfile | remove_sndconfig_block | uniq > $TMP else remove_ac_block < $cfgfile | remove_y2_block | uniq > $TMP fi fi if [ -z "$have_alias" -a "$kernel" = "new" ]; then if grep -q char-major-116 /lib/modules/`uname -r`/modules.alias; then have_alias="yes" fi fi if [ -z "$have_alias" ]; thenecho "alias char-major-116 sndalias char-major-14 $SOUND_COREalias sound-service-0-0 snd-mixer-ossalias sound-service-0-1 snd-seq-ossalias sound-service-0-3 snd-pcm-ossalias sound-service-0-8 snd-seq-ossalias sound-service-0-12 snd-pcm-oss" >> $addcfg fi if [ -n "$alsa_device_opts" ]; then echo "options snd $alsa_device_opts" >> $addcfg fiecho "alias snd-card-0 $CARD_DRIVERalias sound-slot-0 $CARD_DRIVER" >> $addcfg if [ -n "$CARD_OPTS" ]; then echo "options $CARD_DRIVER $CARD_OPTS" >> $addcfg fi if [ -n "$cfgout" ]; then [ ! -r "$cfgfile" ] || cmp -s "$TMP" "$cfgfile" || cat "$TMP" > "$cfgfile" cmp -s "$addcfg" "$cfgout" || cat "$addcfg" > "$cfgout" else echo "$ACB# --- ALSACONF version $version ---" >> $TMP cat "$addcfg" >> "$TMP" echo "$ACE" >> $TMP cmp -s "$TMP" "$cfgfile" || cat "$TMP" > "$cfgfile" fi /sbin/depmod -a 2>/dev/null # remove yast2 entries (- only for suse distro) if [ -f /var/lib/YaST/unique.inf ]; then awk 'BEGIN { in_sound=0; }/^\[sound\]$/ { print; in_sound=1; next; }/^\[.+\]$/ { print; in_sound=0; next; }{ if (in_sound == 0) { print; } }' < /var/lib/YaST/unique.inf > $TMP cp -f $TMP /var/lib/YaST/unique.inf fi # set up /etc/sysconfig/hardware/* if [ "$distribution" = "suse" ]; then case "$suse_version" in 10.[012]*|10) setup_hwcfg $CARD_DRIVER ;; esac fi farewell clear if [ "$distribution" = "gentoo" ]; then xecho "Running modules-update..." modules-update elif [ "$distribution" = "debian" ]; then xecho "Running update-modules..." update-modules fi if [ -x $rcalsasound ] ; then echo Loading driver... $rcalsasound restart fi echo Setting default volumes... if [ -x $bindir/set_default_volume ]; then $bindir/set_default_volume -f else set_mixers fi if [ -f $TESTSOUND ]; then msg=$(gettext " The mixer is set up now for for playing. Shall I try to play a sound sample now? NOTE:If you have a big amplifier, lower your volumes or say no. Otherwise check that your speaker volume is open, and look if you can hear test sound.") if $DIALOG --yesno "$msg" 13 65 then clear echo aplay -N $TESTSOUND fi fi if [ ! -r /etc/asound.state ]; then xecho "Saving the mixer setup used for this in /etc/asound.state." $sbindir/alsactl store fi clear xecho "=============================================================================== Now ALSA is ready to use. For adjustment of volumes, use your favorite mixer. Have a lot of fun!"}# check playback# return 0 - OK, 1 - NG, 2 - not working (irq/dma problem)ac_try_load () { test -n "$LOGFILE" && echo "$1 ${*:2}" >> "$LOGFILE" /sbin/modprobe snd-$1 ${*:2} >/dev/null 2>&1 if $lsmod | grep -q -E '^(snd-|snd_)'$1' '; then : ; else /sbin/modprobe -r snd-$1 >/dev/null 2>&1 return 1 fi # mute mixers amixer set Master 0% mute >/dev/null 2>&1 amixer set PCM 0% mute >/dev/null 2>&1 # output 0.5 sec head -c 4000 < /dev/zero | aplay -N -r8000 -fS16_LE -traw -c1 > /dev/null 2>&1 & # remember pid pp=$! # sleep for 2 seconds (to be sure -- 1 sec would be enough) sleep 2 # kill the child process if still exists. kill -9 $pp > /dev/null 2>&1 st=$? ac_cardname=`head -n 1 $PROCFS/asound/cards | sed -e 's/^[0-9].* - \(.*\)$/\1/'` /sbin/modprobe -r snd-$1 >/dev/null 2>&1 if [ $st = 0 ]; then # irq problem? test -n "$LOGFILE" && echo "no playback return" >> "$LOGFILE" return 2 else # seems ok! test -n "$LOGFILE" && echo "playback OK" >> "$LOGFILE" return 0 fi}# check capture# return 0 - OK, 1 - NG, 2 - not working (irq/dma problem)# ac_try_capture card duplex optsac_try_capture () { test -n "$LOGFILE" && echo "$1 ${*:2}" >> "$LOGFILE" /sbin/modprobe snd-$1 ${*:3} >/dev/null 2>&1 if $lsmod | grep -q -E '^(snd-|snd_)'$1' '; then : ; else /sbin/modprobe -r snd-$1 >/dev/null 2>&1 return 1 fi # mute mixers amixer set Master 0% mute >/dev/null 2>&1 amixer set PCM 0% mute >/dev/null 2>&1 play_pid=0 if [ $2 = yes ]; then # try duplex - start dummy playing aplay -N -r8000 -fS16_LE -traw -c1 < /dev/zero > /dev/null 2>&1 & play_pid=$! fi # record 1sec arecord -N -d1 > /dev/null 2>&1 & # remember pid pp=$! # sleep for 2 seconds sleep 2 # kill the child process if still exists. kill -9 $pp > /dev/null 2>&1 st=$? # kill playback process if any test $play_pid != 0 && kill -9 $play_pid /sbin/modprobe -r snd-$1 >/dev/null 2>&1 if [ $st = 0 ]; then test -n "$LOGFILE" && echo "capture no return" >> "$LOGFILE" return 2 else test -n "$LOGFILE" && echo "capture OK" >> "$LOGFILE" return 0 fi}get_dma_pair () { case $1 in 0) echo 1 3 5;; 1) echo 0 3 5;; 3) echo 1 0 5;; 5) echo 3 1 0;; esac}## check playback on specified irqs## ac_try_irq card opts irqs...# return 0 - OK, 1 - NG, 2 - not working (dma problem?)#ac_try_irq () { card=$1 opts="$2 ${mpfx}irq=$3" ac_try_load $card $opts >/dev/null 2>&1 result=$? case $result in 0) ac_opts="$opts" return 0 ;; 2) for irq in ${*:4}; do opts="$2 ${mpfx}irq=$irq" ac_try_load $card $opts >/dev/null 2>&1 if [ $? = 0 ]; then ac_opts="$opts" return 0 fi done return 2 ;; esac return 1}## check playback/capture on dma1 & dma2 & specified irqs## ac_try_dmas card opts irqs...# return 0 - OK, 1 - NG#ac_try_dmas () { dma_list=`check_dma_avail 1 0 3 5` for irq in ${*:3}; do for dma1 in $dma_list; do for dma2 in `get_dma_pair $dma1`; do opts="$2 ${mpfx}dma1=$dma1 ${mpfx}dma2=$dma2 ${mpfx}irq=$irq" ac_try_load $1 $opts >/dev/null 2>&1 result=$? if [ $result = 1 ]; then if [ $try_all_combination = 1 ]; then continue else return 1 fi elif [ $result = 0 ]; then test -n "$LOGFILE" && echo "Now checking capture..." >> "$LOGFILE" ac_opts="$opts" ac_try_capture $1 yes $opts >/dev/null 2>&1 && return 0 for d in yes no; do for dma2 in $dma_list; do if [ $dma1 != $dma2 ]; then opts="$2 ${mpfx}dma1=$dma1 ${mpfx}dma2=$dma2 ${mpfx}irq=$irq" ac_opts="$opts" ac_try_capture $1 $d $opts >/dev/null 2>&1 && return 0 fi done done return 0 fi done done done return 1}# check if the option $2 exists in card $1: set value $3ac_check_option () { if /sbin/modinfo -p snd-$1 | grep -q $2; then echo "$2=$3" fi}ac_try_card_sb8 () { card=sb8 irq_list=`check_irq_avail 5 3 9 10 7` for dma8 in `check_dma_avail 1 3`; do opts="${mpfx}dma8=$dma8" ac_try_irq $card "$opts" $irq_list && return 0 done return 1}ac_try_card_sb16 () { card=sb16 isapnp=`ac_check_option $card ${mpfx}isapnp 0` opts="$isapnp" irq_list=`check_irq_avail 5 9 10 7 3` dma_list=`check_dma_avail 0 1 3` dma16_list=`check_dma_avail 5 6 7` # at first try auto-probing by driver itself ac_try_load $card $opts >/dev/null 2>&1 result=$? case $result in 0) ac_opts="$opts" ac_try_capture $card yes $opts >/dev/null 2>&1 && return 0 for d in yes no; do for dma8 in $dma_list; do for irq in $irq_list; do opts="${mpfx}dma8=$dma8 ${mpfx}irq=$irq $isapnp" ac_try_capture $card $d $opts >/dev/null 2>&1 && return 0 done done done return 0 ;; 2) for dma16 in $dma16_list; do opts="${mpfx}dma16=$dma16 $isapnp" if ac_try_irq $card "$opts" $irq_list ; then ac_try_capture $card yes $ac_opts >/dev/null 2>&1 && return 0 ac_opts_saved="$ac_opts" for d in yes no; do for dma8 in $dma_list; do ac_opts="$ac_opts_saved ${mpfx}dma8=$dma8" ac_try_capture $card $d $ac_opts >/dev/null 2>&1 && return 0 done done # return anyway here.. return 0 fi done ;; esac return 1}ac_try_card_es1688 () { card=es1688 opts="" irq_list=`check_irq_avail 5 9 10 7` for dma8 in `check_dma_avail 1 3 0`; do opts="${mpfx}dma8=$dma8 ${mpfx}mpu_irq=-1" ac_try_irq $card "$opts" $irq_list && return 0 done return 1}ac_try_card_es18xx () { card=es18xx opts=`ac_check_option $card ${mpfx}isapnp 0` ac_try_dmas $card "$opts" `check_irq_avail 5 9 10 7` && return 0 return 1}ac_try_card_cs4236 () { card=cs4236 irq_list=`check_irq_avail 5 7 9 11 12 15` isapnp=`ac_check_option $card ${mpfx}isapnp 0` for cport in 0x538 0x210 0xf00; do for port in 0x530 0x534; do opts="${mpfx}port=$port ${mpfx}cport=$cport $isapnp" ac_try_dmas $card "$opts" $irq_list && return 0 done done return 1}ac_try_card_cs4232 () { card=cs4232 irq_list=`check_irq_avail 5 7 9 11 12 15` isapnp=`ac_check_option $card ${mpfx}isapnp 0` for cport in 0x538 0x210 0xf00; do for port in 0x530 0x534; do opts="${mpfx}port=$port ${mpfx}cport=$cport $isapnp" ac_try_dmas $card "$opts" $irq_list && return 0 done done return 1}ac_try_card_cs4231 () { card=cs4231 irq_list=`check_irq_avail 5 7 9 11 12 15` for port in 0x530 0x534; do opts="${mpfx}port=$port" ac_try_dmas $card "$opts" $irq_list && return 0 done return 1}ac_try_card_opl3sa2 () { card=opl3sa2 irq_list=`check_irq_avail 5 9 3 1 11 12 15 0` isapnp=`ac_check_option $card ${mpfx}isapnp 0` for port in 0x370 0x538 0xf86 0x100; do for wss_port in 0x530 0xe80 0xf40 0x604; do opts="${mpfx}fm_port=-1 ${mpfx}midi_port=-1 ${mpfx}port=$port ${mpfx}wss_port=$wss_port $isapnp" ac_try_dmas $card "$opts" $irq_list && return 0 done done return 1}ac_config_legacy () { title=$(gettext "WARNING") msg=$(gettext " Probing legacy ISA cards might make your system unstable. Do you want to proceed?") $DIALOG --title "$title" --yesno "$msg" 10 50 || acex 0 if [ x"$1" = x ]; then probe_list="$LEGACY_CARDS" else probe_list=$* fi menu_args=() for card in $probe_list; do cardname=`/sbin/modinfo -d snd-$card | sed -e 's/^\"\(.*\)\"$/\1/g'` if [ x"$cardname" != x ]; then menu_args=("${menu_args[@]}" "$card" "$cardname" "on") fi done if [ x$menu_args = x ]; then msg=$(gettext "No legacy drivers are available for your machine") $DIALOG --msgbox "$msg" 5 50 return 1 fi title=$(gettext "Driver Selection") msg=$(gettext " Probing legacy ISA cards Please select the drivers to probe:") $DIALOG --title "$title" --checklist "$msg" \ 17 64 8 "${menu_args[@]}" 2> $FOUND || acex 0 if [ $try_all_combination != 1 ]; then msg=$(gettext " Shall I try all possible DMA and IRQ combinations? With this option, some unconventional configuration might be found, but it will take much longer time.") if $DIALOG --yesno "$msg" 10 60 then try_all_combination=1 fi fi xecho "Probing legacy cards.. This may take a few minutes.." echo -n $(gettext "Probing: ") cards=`cat $FOUND | tr -d \"` for card in $cards; do echo -n " $card" ac_opts="" if eval ac_try_card_$card ; then xecho " : FOUND!!" ac_config_card $card $ac_opts return 0 fi done echo title=$(gettext "Result") msg=$(gettext "No legacy cards found") $DIALOG --title "$title" --msgbox "$msg" 5 50 return 1}## main part continued..#if test -n "$LOGFILE" ; then touch "$LOGFILE" echo -n "Starting alsaconf: " >> "$LOGFILE" date >> "$LOGFILE"fiif [ x"$legacy_probe_card" != x ]; then ac_opts="" if eval ac_try_card_$legacy_probe_card >/dev/null 2>&1; then echo "$ac_opts" echo "$ac_cardname" exit 0 else echo "FAILED" exit 1 fifiintroif [ $do_legacy_only = 1 ]; then ac_config_legacy exit 0fiprobe_cardsdevs_found=()devs_olist=""if [ -s "$FOUND" ]; then while read dev card ; do MODDIR=/lib/modules/`uname -r` find $MODDIR -type f | grep -q -E $card'\.(o|ko)' || continue cardname=`find_device_name $dev | cut -c 1-64` if [ -z "$cardname" ]; then cardname="$card" fi card=${card##snd-} devs_found=("${devs_found[@]}" "$card" "$cardname") devs_devs=("${devs_devs[@]}" "$card" "$dev") done <"$FOUND" devs_olist=`cat $FOUND`fiif [ x$devs_found != x ]; then # # check for TP600E # if [ ${devs_found[0]} = cs46xx ]; then if $lspci -nv 2>/dev/null| grep -q "Subsystem: 1014:1010"; then msg=$(gettext " Looks like you having a Thinkpad 600E or 770 notebook. On this notebook, CS4236 driver should be used although CS46xx chip is detected. Shall I try to snd-cs4236 driver and probe the legacy ISA configuration?") if $DIALOG --yesno "$msg" 13 60 then try_all_combination=1 ac_config_legacy cs4236 exit 0 fi elif $lspci -nv 2>/dev/null| grep -q "Subsystem: 8086:8080"; then msg=$(gettext " Looks like you having a Dell Dimension machine. On this machine, CS4232 driver should be used although CS46xx chip is detected. Shall I try to snd-cs4232 driver and probe the legacy ISA configuration?") if $DIALOG --yesno "$msg" 13 60 then try_all_combination=1 ac_config_legacy cs4232 exit 0 fi fi fi devs_found=("${devs_found[@]}" "legacy" "Probe legacy ISA (non-PnP) chips") title=$(gettext "Soundcard Selection") msg=$(gettext " Following card(s) are found on your system. Choose a soundcard to configure:") $DIALOG --title "$title" --menu "$msg" 17 76 8 "${devs_found[@]}" 2> $FOUND || acex 0 card=`head -n 1 $FOUND` if [ "$card" = "legacy" ]; then ac_config_legacy else ac_config_card "$card" fi exit 0else msg=$(gettext " No supported PnP or PCI card found. Would you like to probe legacy ISA sound cards/chips?") if $DIALOG --yesno "$msg" 9 60 ; then ac_config_legacy exit 0 fifirm -f "$FOUND" "$DUMP"exit 0