diff -Nru oss4-4.2-build2002/debian/30oss4-pm oss4-4.2-build2003/debian/30oss4-pm --- oss4-4.2-build2002/debian/30oss4-pm 1970-01-01 01:00:00.000000000 +0100 +++ oss4-4.2-build2003/debian/30oss4-pm 2010-07-18 10:49:10.000000000 +0200 @@ -0,0 +1,26 @@ +#!/bin/sh +# +# 99oss4-pm: Restart sound on suspend/resumt + +case "$1" in + hibernate|suspend) + # We need to force unload in order + # to quit applications that are using oss4.. + if which invoke-rc.d >/dev/null 2>&1; then + invoke-rc.d oss4-base force-unload + else + /etc/init.d/oss4-base force-unload + fi + ;; + thaw|resume) + if which invoke-rc.d >/dev/null 2>&1; then + invoke-rc.d oss4-base start + else + /etc/init.d/oss4-base start + fi + ;; + *) exit $NA + ;; +esac + + diff -Nru oss4-4.2-build2002/debian/changelog oss4-4.2-build2003/debian/changelog --- oss4-4.2-build2002/debian/changelog 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/changelog 2010-07-18 10:49:10.000000000 +0200 @@ -1,3 +1,30 @@ +oss4 (4.2-build2003-1ubuntu1) maverick; urgency=low + + * Merge from debian unstable (LP: #606833). Remaining changes: + - debian/{dkms/dkms.conf.template,m-a/rules}: + s/source/build/ in Kernel headers paths. + Thanks to Jason Scurfu and Niall Creech + + -- Angel Abad Sun, 18 Jul 2010 08:19:30 +0100 + +oss4 (4.2-build2003-1) unstable; urgency=high + + * New upstream release. + * Removed oss4-source, set oss4-dmks as the + only way to compile the drivers. + * Reload modules in oss4-dmks' postinst when + called with action "configure". + Closes: #558034 + * Added soundon and soundoff script to survive + a suspend/resume cycle. Added Recommends: pm-utils. + Closes: #565709 + * Added explicit dependency on linux-headers to make sure + the modules' build symklink is present. + Closes: #587191 + * Bumped standards-version. + + -- Romain Beauxis Wed, 14 Jul 2010 21:16:03 -0500 + oss4 (4.2-build2002-3ubuntu1) maverick; urgency=low * debian/{dkms/dkms.conf.template,m-a/rules}: diff -Nru oss4-4.2-build2002/debian/control oss4-4.2-build2003/debian/control --- oss4-4.2-build2002/debian/control 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/control 2010-07-18 10:49:10.000000000 +0200 @@ -5,11 +5,12 @@ XSBC-Original-Maintainer: Debian OSS4 Maintainers Uploaders: Sebastien NOEL , Romain Beauxis Build-Depends: debhelper (>= 7), cdbs, gawk, libgtk2.0-dev, txt2man, quilt, patchutils, dkms -Standards-Version: 3.8.4 +Standards-Version: 3.9.0 Package: oss4-base Architecture: alpha amd64 arm armeb armel avr32 hppa i386 ia64 lpia m32r m68k mips mipsel powerpc ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc Depends: linux-sound-base, ${shlibs:Depends}, ${misc:Depends} +Recommends: pm-utils Suggests: oss4-modules Description: Open Sound System - base package Open Sound System (OSS) is an attempt in unifying @@ -33,17 +34,10 @@ . This package contains a GTK2-based mixer control program. -Package: oss4-source -Architecture: all -Depends: make, debhelper, module-assistant, ${misc:Depends} -Description: Open Sound System - drivers sources - This package provides the source code for the OSS4 kernel modules. - These kernel drivers can be built from it using module-assistant. - Package: oss4-dkms Section: kernel Architecture: all -Depends: ${misc:Depends}, oss4-base, dkms +Depends: ${misc:Depends}, oss4-base, dkms, linux-headers-2.6-686 | linux-headers-2.6-amd64 | linux-headers-generic | linux-headers Provides: oss4-modules Description: Open Sound System - DKMS module sources This package contains the source for the OSS4 kernel modules, diff -Nru oss4-4.2-build2002/debian/m-a/compat oss4-4.2-build2003/debian/m-a/compat --- oss4-4.2-build2002/debian/m-a/compat 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/m-a/compat 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -5 diff -Nru oss4-4.2-build2002/debian/m-a/control.modules.in oss4-4.2-build2003/debian/m-a/control.modules.in --- oss4-4.2-build2002/debian/m-a/control.modules.in 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/m-a/control.modules.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,21 +0,0 @@ -Source: oss4 -Section: sound -Priority: optional -Maintainer: Debian OSS4 Maintainers -Build-Depends: debhelper (>> 5.0.0) -Standards-Version: 3.8.0 - -Package: oss4-modules-_KVERS_ -Architecture: alpha amd64 arm armeb armel avr32 hppa i386 ia64 lpia m32r m68k mips mipsel powerpc ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc -Provides: oss4-modules -Description: OSS4 modules for Linux (kernel _KVERS_). - This package contains the set of loadable kernel modules for the - Open Sound System v4. - . - This package contains the compiled kernel modules for _KVERS_ - . - If you have compiled your own kernel, you will most likely need to build - your own oss4-modules. The oss4-source package has been provided for use - with the Debian's module-assistant or kernel-package utilities - to produce a version of oss4-module for your kernel. - diff -Nru oss4-4.2-build2002/debian/oss4-base.dirs oss4-4.2-build2003/debian/oss4-base.dirs --- oss4-4.2-build2002/debian/oss4-base.dirs 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/oss4-base.dirs 2010-07-18 10:49:10.000000000 +0200 @@ -1,2 +1,2 @@ var/lib/oss4 - +etc/pm/sleep.d diff -Nru oss4-4.2-build2002/debian/oss4-base.init oss4-4.2-build2003/debian/oss4-base.init --- oss4-4.2-build2002/debian/oss4-base.init 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/oss4-base.init 2010-07-18 10:49:10.000000000 +0200 @@ -7,7 +7,7 @@ # Required-Start: $remote_fs $local_fs # Required-Stop: $remote_fs $local_fs # Default-Start: S -# Default-Stop: 0 6 +# Default-Stop: 0 1 6 # Short-Description: Start and Stop the OSS4 subsystem ### END INIT INFO diff -Nru oss4-4.2-build2002/debian/oss4-base.install oss4-4.2-build2003/debian/oss4-base.install --- oss4-4.2-build2002/debian/oss4-base.install 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/oss4-base.install 2010-07-18 10:49:10.000000000 +0200 @@ -8,4 +8,4 @@ debian/tmp/usr/lib/oss/etc/devices.list etc/oss4/ debian/tmp/usr/lib/oss/version.dat etc/oss4/ debian/tmp/usr/lib/oss/conf.tmpl/* etc/oss4/conf/ - +debian/30oss4-pm etc/pm/sleep.d diff -Nru oss4-4.2-build2002/debian/oss4-dkms.postinst oss4-4.2-build2003/debian/oss4-dkms.postinst --- oss4-4.2-build2002/debian/oss4-dkms.postinst 1970-01-01 01:00:00.000000000 +0100 +++ oss4-4.2-build2003/debian/oss4-dkms.postinst 2010-07-18 10:49:10.000000000 +0200 @@ -0,0 +1,28 @@ +#! /bin/sh +# postinst script for liquidsoap +set -e + +#DEBHELPER# + +case "$1" in + configure) + # Restart oss4-base + if which invoke-rc.d >/dev/null 2>&1; then + invoke-rc.d oss4-base force-reload + else + /etc/init.d/oss4-base force-reload + fi + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + exit 0 + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +exit 0 + diff -Nru oss4-4.2-build2002/debian/oss4-source.install oss4-4.2-build2003/debian/oss4-source.install --- oss4-4.2-build2002/debian/oss4-source.install 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/oss4-source.install 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -build-tree/oss4.tar.bz2 usr/src/ diff -Nru oss4-4.2-build2002/debian/oss.conf oss4-4.2-build2003/debian/oss.conf --- oss4-4.2-build2002/debian/oss.conf 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/oss.conf 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -OSSETCDIR=/etc/oss4 -OSSVARDIR=/var/lib/oss4 - diff -Nru oss4-4.2-build2002/debian/oss.conf.in oss4-4.2-build2003/debian/oss.conf.in --- oss4-4.2-build2002/debian/oss.conf.in 1970-01-01 01:00:00.000000000 +0100 +++ oss4-4.2-build2003/debian/oss.conf.in 2010-07-18 10:49:10.000000000 +0200 @@ -0,0 +1,3 @@ +OSSETCDIR=/etc/oss4 +OSSVARDIR=/var/lib/oss4 +OSSDKMSDIR=/var/lib/dkms/oss4/_VERSION_ diff -Nru oss4-4.2-build2002/debian/rules oss4-4.2-build2003/debian/rules --- oss4-4.2-build2002/debian/rules 2010-07-18 10:49:08.000000000 +0200 +++ oss4-4.2-build2003/debian/rules 2010-07-18 10:49:10.000000000 +0200 @@ -1,8 +1,8 @@ #!/usr/bin/make -f -DEB_TAR_SRCDIR := ./oss-v4.2-build2002-src-gpl -DEB_DH_INSTALLINIT_ARGS := --no-start -- start 50 S . stop 50 0 6 . +DEB_DH_INSTALLINIT_ARGS := --no-start -- start 50 S . stop 50 0 1 6 . UPSTREAM_VERSION := $(shell dpkg-parsechangelog|grep "^Version:"|cut -d" " -f2|rev|cut -d- -f2-|rev|cut -d':' -f2) +DEB_TAR_SRCDIR := ./oss-v$(UPSTREAM_VERSION)-src-gpl include /usr/share/cdbs/1/rules/tarball.mk include /usr/share/cdbs/1/rules/debhelper.mk @@ -32,8 +32,6 @@ build/oss4-base:: stamp-build-oss4 -build/oss4-source:: stamp-build-oss4 stamp-source-oss4 - build/oss4-dkms:: stamp-source-oss4 sed -e 's#_VERSION_#$(UPSTREAM_VERSION)#' < debian/oss4-dkms.install.in > debian/oss4-dkms.install sed -e 's#_VERSION_#$(UPSTREAM_VERSION)#' < debian/oss4-dkms.dkms.in > debian/oss4-dkms.dkms @@ -42,20 +40,18 @@ dh_dkms stamp-source-oss4: - mkdir -p build-tree/modules/oss4/debian - cp -r debian/m-a/* build-tree/modules/oss4/debian/ - cp debian/copyright build-tree/modules/oss4/debian/ - cp debian/changelog build-tree/modules/oss4/debian/ bash ./create-ma-tree.sh build-tree/modules/oss4 build-tree/oss-build find build-tree/modules/oss4 -type f -exec chmod -x {} \; - chmod 755 build-tree/modules/oss4/debian/rules - cd build-tree/ && tar cjf oss4.tar.bz2 modules/ touch stamp-source-oss4 $(CURDIR)/debian/tmp: cp -a $(CURDIR)/build-tree/oss-build/prototype $(CURDIR)/debian/tmp install/oss4-base:: $(CURDIR)/debian/tmp + sed -e 's#_VERSION_#$(UPSTREAM_VERSION)#' < debian/oss.conf.in > debian/oss.conf + +binary-install/oss4-base:: + chmod +x $(CURDIR)/debian/oss4-base/etc/pm/sleep.d/30oss4-pm install/oss4-dev:: $(CURDIR)/debian/tmp @@ -66,5 +62,6 @@ clean:: rm -rf stamp-build-oss4 stamp-prepare-oss4 stamp-source-oss4 \ debian/oss4-dkms.install debian/dkms/dkms.conf \ - oss-v4.2-build2002-src-gpl.tar.bz2.cdbs-config_list + oss-v4.2-build2002-src-gpl.tar.bz2.cdbs-config_list \ + debian/oss.conf Los archivos binarios /tmp/TOgfCHU0OD/oss4-4.2-build2002/oss-v4.2-build2002-src-gpl.tar.bz2 y /tmp/fXBqChI6fF/oss4-4.2-build2003/oss-v4.2-build2002-src-gpl.tar.bz2 son distintos Los archivos binarios /tmp/TOgfCHU0OD/oss4-4.2-build2002/oss-v4.2-build2003-src-gpl.tar.bz2 y /tmp/fXBqChI6fF/oss4-4.2-build2003/oss-v4.2-build2003-src-gpl.tar.bz2 son distintos diff -Nru oss4-4.2-build2002/=unpacked-tar1=/buildid.dat oss4-4.2-build2003/=unpacked-tar1=/buildid.dat --- oss4-4.2-build2002/=unpacked-tar1=/buildid.dat 2009-11-07 09:17:03.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/buildid.dat 2010-05-27 13:35:39.000000000 +0200 @@ -1 +1 @@ -2002 +2003 diff -Nru oss4-4.2-build2002/=unpacked-tar1=/cmd/osspartysh/osspartysh.c oss4-4.2-build2003/=unpacked-tar1=/cmd/osspartysh/osspartysh.c --- oss4-4.2-build2002/=unpacked-tar1=/cmd/osspartysh/osspartysh.c 2009-11-13 16:23:24.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/cmd/osspartysh/osspartysh.c 2010-05-27 13:38:38.000000000 +0200 @@ -46,8 +46,8 @@ #include #else #include -#endif #include +#endif #include #define PARTYSH_MAGIC "ParTySH" diff -Nru oss4-4.2-build2002/=unpacked-tar1=/cmd/ossplay/ossplay.c oss4-4.2-build2003/=unpacked-tar1=/cmd/ossplay/ossplay.c --- oss4-4.2-build2002/=unpacked-tar1=/cmd/ossplay/ossplay.c 2009-11-13 16:23:24.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/cmd/ossplay/ossplay.c 2010-05-27 13:38:38.000000000 +0200 @@ -37,7 +37,7 @@ unsigned int amplification = 100; int eflag = 0, force_speed = 0, force_fmt = 0, force_channels = 0, verbose = 0, quiet = 0; -flag from_stdin = 0, int_conv = 0, level_meters = 0, loop = 0, overwrite = 0, +flag from_stdin = 0, int_conv = 0, level_meters = 0, loop = 0, raw_file = 0, raw_mode = 0; double seek_time = 0; long seek_byte = 0; @@ -364,7 +364,6 @@ " single recording.\n"); print_msg (HELPM, " -R Open sound device in raw mode.\n"); - print_msg (HELPM, " -O Allow overwrite.\n"); exit (E_USAGE); } @@ -639,7 +638,7 @@ tmp, speed); } - dsp->speed = speed; + dsp->speed = tmp; dsp->channels = channels; dsp->format = format; @@ -892,10 +891,6 @@ verbose = 1; break; - case 'O': - overwrite = 1; - break; - case 'h': default: ossrecord_usage (argv[0]); diff -Nru oss4-4.2-build2002/=unpacked-tar1=/cmd/ossplay/ossplay_decode.c oss4-4.2-build2003/=unpacked-tar1=/cmd/ossplay/ossplay_decode.c --- oss4-4.2-build2002/=unpacked-tar1=/cmd/ossplay/ossplay_decode.c 2009-11-13 16:23:24.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/cmd/ossplay/ossplay_decode.c 2010-05-27 13:38:38.000000000 +0200 @@ -42,7 +42,7 @@ ima_values_t; extern int amplification, force_speed, force_fmt, force_channels; -extern flag int_conv, overwrite, verbose; +extern flag int_conv, verbose; extern char audio_devname[32]; extern off_t (*ossplay_lseek) (int, off_t, int); extern double seek_time; @@ -430,7 +430,7 @@ wave_fp = fdopen (1, "wb"); else { - fd = open (fname, O_WRONLY | O_CREAT | (overwrite?0:O_EXCL), 0644); + fd = open (fname, O_WRONLY | O_CREAT, 0644); if (fd == -1) { perror (fname); diff -Nru oss4-4.2-build2002/=unpacked-tar1=/.date oss4-4.2-build2003/=unpacked-tar1=/.date --- oss4-4.2-build2002/=unpacked-tar1=/.date 2009-11-13 16:23:22.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/.date 2010-05-27 13:38:37.000000000 +0200 @@ -1 +1 @@ -091113 +100527 diff -Nru oss4-4.2-build2002/=unpacked-tar1=/.hgtags oss4-4.2-build2003/=unpacked-tar1=/.hgtags --- oss4-4.2-build2002/=unpacked-tar1=/.hgtags 2009-11-07 09:17:22.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/.hgtags 2010-05-27 13:35:58.000000000 +0200 @@ -20,3 +20,4 @@ 80cfc369d9256107108d19f6f46a42b37b00b18e v4-2-build2000 f794ffc6c18524a62f4e3b81011e590b30bc5183 v4.2-build2001 21b607a0014a5135cde83d02f3048a616295048e v4.2-build2002 +372b5c3940ab0478aadc4c45fbf79af9ce9195a3 v4.2-2003 diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_ali5455/oss_ali5455.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_ali5455/oss_ali5455.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_ali5455/oss_ali5455.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_ali5455/oss_ali5455.c 2010-05-27 13:38:38.000000000 +0200 @@ -966,7 +966,7 @@ if (devc->bdlBuffer) { - CONTIG_FREE (devc->osdev, devc->bdlBuffer, 4 * 32 * 32, devc->bld_dma_handle); + CONTIG_FREE (devc->osdev, devc->bdlBuffer, 4 * 32 * 32, devc->bdl_dma_handle); devc->bdlBuffer = NULL; } diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_cmi878x/.devices oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_cmi878x/.devices --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_cmi878x/.devices 2008-12-16 10:32:44.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_cmi878x/.devices 2010-05-11 13:26:05.000000000 +0200 @@ -1,5 +1,5 @@ oss_cmi878x pci13f6,8788 CMedia CMI8788 -#oss_cmi878x pci1043,8269 Asus Xonar D2 (AV200) +oss_cmi878x pci1043,8269 Asus Xonar D2 (AV200) oss_cmi878x pci1043,834f Asus Xonar D1 (AV100) oss_cmi878x pci1043,8275 Asus Xonar DX (AV100) -#oss_cmi878x pci1043,82b7 Asus Xonar D2X (AV200) +oss_cmi878x pci1043,82b7 Asus Xonar D2X (AV200) diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_cmi878x/oss_cmi878x.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_cmi878x/oss_cmi878x.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_cmi878x/oss_cmi878x.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_cmi878x/oss_cmi878x.c 2010-05-27 13:38:38.000000000 +0200 @@ -113,6 +113,12 @@ #define XONAR_DX_OUTPUT 0x01 #define XONAR_DX_MCLOCK_256 0x10 +/* Xonar D2 spi specific */ +#define XONAR_D2_FRONTDAC 0x98 +#define XONAR_D2_SURRDAC 0x9a +#define XONAR_D2_LFEDAC 0x9c +#define XONAR_D2_REARDAC 0x9e + /* defs for AKM 4396 DAC */ #define AK4396_CTL1 0x00 #define AK4396_CTL2 0x01 @@ -209,11 +215,6 @@ /* Volume registers */ #define CS4362A_VOL_MUTE 0x80 -/* Alias only for now. */ -#define CS4398_WRITE(devc, codec, reg, val) \ - two_wire_write(devc, codec, reg, val) -#define CS4362A_WRITE(devc, codec, reg, val) \ - two_wire_write(devc, codec, reg, val) /* 0-100. Start at -96dB. */ #define CS4398_VOL(x) \ @@ -243,10 +244,14 @@ int trigger_bits; int audio_enabled; int audiodev; - int port_type; + int dac_type; #define ADEV_MULTICH 0 #define ADEV_FRONTPANEL 2 #define ADEV_SPDIF 3 + int adc_type; +#define ADEV_I2SADC1 0 +#define ADEV_I2SADC2 1 +#define ADEV_I2SADC3 2 int play_dma_start, rec_dma_start; int play_irq_mask, rec_irq_mask; int play_chan_reset, rec_chan_reset; @@ -277,7 +282,7 @@ /* Mixer */ ac97_devc ac97devc, fp_ac97devc; - int ac97_mixer_dev, fp_mixer_dev, spi_mixer_dev; + int ac97_mixer_dev, fp_mixer_dev, cmi_mixer_dev; int playvol[4]; /* uart401 */ oss_midi_inputbyte_t midi_input_intr; @@ -301,11 +306,11 @@ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); val = 0L; - val |= 0 << 24; /*codec 0 */ - val |= 1 << 23; /*ac97 read the reg address */ val |= reg << 16; + val |= 1 << 23; /*ac97 read the reg address */ + val |= 0 << 24; /*codec 0 */ OUTL (devc->osdev, val, AC97_CMD_DATA); - oss_udelay (100); + oss_udelay (200); data = INL (devc->osdev, AC97_CMD_DATA) & 0xFFFF; MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return data; @@ -321,12 +326,12 @@ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); val = 0L; - val |= 0 << 24; /*on board codec */ - val |= 0 << 23; /*ac97 write operation */ - val |= reg << 16; val |= data & 0xFFFF; + val |= reg << 16; + val |= 0 << 23; /*ac97 write operation */ + val |= 0 << 24; /*on board codec */ OUTL (devc->osdev, val, AC97_CMD_DATA); - oss_udelay (100); + oss_udelay (200); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return 1; } @@ -339,11 +344,11 @@ int data, val; MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); val = 0L; - val |= 1 << 24; /*fp codec1 */ - val |= 1 << 23; /*ac97 read the reg address */ val |= reg << 16; + val |= 1 << 23; /*ac97 read the reg address */ + val |= 1 << 24; /*fp codec1 */ OUTL (devc->osdev, val, AC97_CMD_DATA); - oss_udelay (100); + oss_udelay (200); data = INL (devc->osdev, AC97_CMD_DATA) & 0xFFFF; MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return data; @@ -359,12 +364,12 @@ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); val = 0L; - val |= 1 << 24; /*fp codec1 */ - val |= 0 << 23; /*ac97 write operation */ - val |= reg << 16; val |= data & 0xFFFF; + val |= reg << 16; + val |= 0 << 23; /*ac97 write operation */ + val |= 1 << 24; /*fp codec1 */ OUTL (devc->osdev, val, AC97_CMD_DATA); - oss_udelay (100); + oss_udelay (200); MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); return 1; } @@ -435,6 +440,19 @@ } +static void +pcm1796_write(cmi8788_devc *devc, int codec_id, unsigned char reg, unsigned char val) +{ +static const char codec_map[4] = { + 0, 1, 2, 4 + }; +unsigned char data[2]; + + data[0] = val; + data[1] = reg; + spi_write (devc, codec_map[codec_id], data); +} + static int cs4398_init (void *devc_, int codec_) { @@ -444,22 +462,22 @@ OUTW(devc->osdev, 0x0100, TWO_WIRE_CTRL); // Power down, enable control mode. - CS4398_WRITE(devc_, codec_, CS4398_MISC_CTRL, + two_wire_write(devc_, codec_, CS4398_MISC_CTRL, CS4398_CPEN | CS4398_POWER_DOWN); // Left justified PCM (DAC and 8788 support I2S, but doesn't work. // Setting it introduces clipping like hell). - CS4398_WRITE(devc_, codec_, CS4398_MODE_CTRL, 0); + two_wire_write(devc_, codec_, CS4398_MODE_CTRL, 0); // That's the DAC default, set anyway. - CS4398_WRITE(devc_, codec_, 3, 0x09); + two_wire_write(devc_, codec_, 3, 0x09); // PCM auto-mute. - CS4398_WRITE(devc_, codec_, 4, 0x82); + two_wire_write(devc_, codec_, 4, 0x82); // Vol A+B to -64dB. - CS4398_WRITE(devc_, codec_, 5, 0x80); - CS4398_WRITE(devc_, codec_, 6, 0x80); + two_wire_write(devc_, codec_, 5, 0x80); + two_wire_write(devc_, codec_, 6, 0x80); // Soft-ramping. - CS4398_WRITE(devc_, codec_, 7, 0xF0); + two_wire_write(devc_, codec_, 7, 0xF0); // Remove power down flag. - CS4398_WRITE(devc_, codec_, CS4398_MISC_CTRL, CS4398_CPEN); + two_wire_write(devc_, codec_, CS4398_MISC_CTRL, CS4398_CPEN); return 1; } @@ -473,45 +491,44 @@ OUTW(devc->osdev, 0x0100, TWO_WIRE_CTRL); /* Power down and enable control port. */ - CS4362A_WRITE(devc_, codec_, CS4362A_MODE1_CTRL, CS4362A_CPEN | CS4362A_POWER_DOWN); + two_wire_write(devc_, codec_, CS4362A_MODE1_CTRL, CS4362A_CPEN | CS4362A_POWER_DOWN); /* Left-justified PCM */ - CS4362A_WRITE(devc_, codec_, CS4362A_MODE2_CTRL, CS4362A_DIF_LJUST); + two_wire_write(devc_, codec_, CS4362A_MODE2_CTRL, CS4362A_DIF_LJUST); /* Ramp & Automute, re-set DAC defaults. */ - CS4362A_WRITE(devc_, codec_, CS4362A_MODE3_CTRL, 0x84); + two_wire_write(devc_, codec_, CS4362A_MODE3_CTRL, 0x84); /* Filter control, DAC defs. */ - CS4362A_WRITE(devc_, codec_, CS4362A_FILTER_CTRL, 0); + two_wire_write(devc_, codec_, CS4362A_FILTER_CTRL, 0); /* Invert control, DAC defs. */ - CS4362A_WRITE(devc_, codec_, CS4362A_INVERT_CTRL, 0); + two_wire_write(devc_, codec_, CS4362A_INVERT_CTRL, 0); /* Mixing control, DAC defs. */ - CS4362A_WRITE(devc_, codec_, CS4362A_MIX1_CTRL, 0x24); - CS4362A_WRITE(devc_, codec_, CS4362A_MIX2_CTRL, 0x24); - CS4362A_WRITE(devc_, codec_, CS4362A_MIX3_CTRL, 0x24); + two_wire_write(devc_, codec_, CS4362A_MIX1_CTRL, 0x24); + two_wire_write(devc_, codec_, CS4362A_MIX2_CTRL, 0x24); + two_wire_write(devc_, codec_, CS4362A_MIX3_CTRL, 0x24); /* Volume to -64dB. */ - CS4362A_WRITE(devc_, codec_, CS4362A_VOLA_1, 0x40); - CS4362A_WRITE(devc_, codec_, CS4362A_VOLB_1, 0x40); - CS4362A_WRITE(devc_, codec_, CS4362A_VOLA_2, 0x40); - CS4362A_WRITE(devc_, codec_, CS4362A_VOLB_2, 0x40); - CS4362A_WRITE(devc_, codec_, CS4362A_VOLA_3, 0x40); - CS4362A_WRITE(devc_, codec_, CS4362A_VOLB_3, 0x40); + two_wire_write(devc_, codec_, CS4362A_VOLA_1, 0x40); + two_wire_write(devc_, codec_, CS4362A_VOLB_1, 0x40); + two_wire_write(devc_, codec_, CS4362A_VOLA_2, 0x40); + two_wire_write(devc_, codec_, CS4362A_VOLB_2, 0x40); + two_wire_write(devc_, codec_, CS4362A_VOLA_3, 0x40); + two_wire_write(devc_, codec_, CS4362A_VOLB_3, 0x40); /* Power up. */ - CS4362A_WRITE(devc_, codec_, CS4362A_MODE1_CTRL, CS4362A_CPEN); + two_wire_write(devc_, codec_, CS4362A_MODE1_CTRL, CS4362A_CPEN); return 1; } -#if 0 static unsigned int mix_scale (int vol, int bits) { vol = mix_cvt[vol]; return (vol * ((1 << bits) - 1) / 100); } - +#if 0 static int cs4398_cleanup(void * devc_, int codec_) { /* Simply power down. Keep control port mode up. */ - CS4398_WRITE(devc_, codec_, CS4398_MISC_CTRL, + two_wire_write(devc_, codec_, CS4398_MISC_CTRL, CS4398_POWER_DOWN | CS4398_CPEN); return 1; @@ -520,7 +537,7 @@ static int cs4362a_cleanup(void *devc_, int codec_) { /* Simply power down. Keep control port mode up. */ - CS4362A_WRITE(devc_, codec_, CS4362A_MODE1_CTRL, + two_wire_write(devc_, codec_, CS4362A_MODE1_CTRL, CS4362A_CPEN | CS4362A_POWER_DOWN); return 1; @@ -538,28 +555,29 @@ switch(codec_id) { case 0: - CS4398_WRITE(devc, XONAR_DX_FRONTDAC, CS4398_VOLA, CS4398_VOL(left)); - CS4398_WRITE(devc, XONAR_DX_FRONTDAC, CS4398_VOLB, CS4398_VOL(right)); + two_wire_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLA, CS4398_VOL(left)); + two_wire_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLB, CS4398_VOL(right)); break; case 1: - CS4362A_WRITE(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_1, CS4362A_VOL(left)); - CS4362A_WRITE(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_1, CS4362A_VOL(right)); + two_wire_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_1, CS4362A_VOL(left)); + two_wire_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_1, CS4362A_VOL(right)); break; case 2: - CS4362A_WRITE(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_2, CS4362A_VOL(left)); - CS4362A_WRITE(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_2, CS4362A_VOL(right)); + two_wire_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_2, CS4362A_VOL(left)); + two_wire_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_2, CS4362A_VOL(right)); break; case 3: - CS4362A_WRITE(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_3, CS4362A_VOL(left)); - CS4362A_WRITE(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_3, CS4362A_VOL(right)); + two_wire_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_3, CS4362A_VOL(left)); + two_wire_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_3, CS4362A_VOL(right)); break; } } + static int cmi8788_set_play_volume (cmi8788_devc * devc, int codec_id, int value) { - int left, right; + unsigned char left, right; unsigned char data[2]; left = value & 0xff; @@ -573,6 +591,11 @@ case SUBID_XONAR_DX: xonar_dx_set_play_volume(devc, codec_id, value); break; + case SUBID_XONAR_D2: + case SUBID_XONAR_D2X: + pcm1796_write (devc, codec_id, 16, mix_scale(left,8)); + pcm1796_write (devc, codec_id, 17, mix_scale(right,8)); + break; default: /* Assume default AKM DACs */ data[0] = left; @@ -983,10 +1006,9 @@ int channels, bits, i2s_bits, i2s_rate; MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - - switch (portc->port_type) + switch (portc->adc_type) { - case ADEV_MULTICH: + case ADEV_I2SADC1: { portc->rec_dma_start = 0x1; portc->rec_irq_mask = 0x1; @@ -1049,7 +1071,7 @@ break; } - case ADEV_FRONTPANEL: + case ADEV_I2SADC2: { portc->rec_dma_start = 0x2; portc->rec_irq_mask = 0x2; @@ -1059,12 +1081,41 @@ OUTL (devc->osdev, dmap->dmabuf_phys, RECB_ADDR); OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, RECB_SIZE); OUTW (devc->osdev, dmap->fragment_size / 4 - 1, RECB_FRAG); - ac97_recrate (&devc->fp_ac97devc, portc->speed); + + switch (portc->bits) + { +#if 0 + case AFMT_S24_LE: + bits = 0x04; + break; +#endif + case AFMT_S32_LE: + bits = 0x08; + break; + default: /* AFMT_S16_LE */ + bits = 0x0; + break; + } + + OUTB (devc->osdev, (INB (devc->osdev, REC_FORMAT) & ~0x0C) | bits, + REC_FORMAT); + + /* setup i2s bits */ + i2s_bits = i2s_calc_bits (portc->bits); + OUTB (devc->osdev, + (INB (devc->osdev, I2S_ADC2_FORMAT) & ~0xC0) | i2s_bits, + I2S_ADC2_FORMAT); + + /* setup speed */ + i2s_rate = i2s_calc_rate (portc->speed); + OUTB (devc->osdev, + (INB (devc->osdev, I2S_ADC2_FORMAT) & ~0x7) | i2s_rate, + I2S_ADC2_FORMAT); break; } - case ADEV_SPDIF: + case ADEV_I2SADC3: { portc->rec_dma_start = 0x4; portc->rec_irq_mask = 0x4; @@ -1126,7 +1177,7 @@ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - switch (portc->port_type) + switch (portc->dac_type) { case ADEV_MULTICH: { @@ -1335,15 +1386,15 @@ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); if (direction == PCM_ENABLE_INPUT) { - switch (portc->port_type) + switch (portc->adc_type) { - case ADEV_MULTICH: + case ADEV_I2SADC1: ptr = INL (devc->osdev, RECA_ADDR); break; - case ADEV_FRONTPANEL: + case ADEV_I2SADC2: ptr = INL (devc->osdev, RECB_ADDR); break; - case ADEV_SPDIF: + case ADEV_I2SADC3: ptr = INL (devc->osdev, RECC_ADDR); break; } @@ -1351,7 +1402,7 @@ if (direction == PCM_ENABLE_OUTPUT) { - switch (portc->port_type) + switch (portc->dac_type) { case ADEV_MULTICH: ptr = INL (devc->osdev, MULTICH_ADDR); @@ -1368,7 +1419,6 @@ ptr -= dmap->dmabuf_phys; ptr %= dmap->bytes_in_use; MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); - // cmn_err (CE_CONT, "ptr=%x\n", ptr); return ptr; } @@ -1705,7 +1755,7 @@ default: val = *arg; - return *arg = cmi8788_set_play_volume (devc, 0, val); + return *arg = 0; break; } else @@ -1748,7 +1798,7 @@ break; default: - return *arg = devc->playvol[0]; + return *arg = 0; break; } } @@ -1779,21 +1829,24 @@ case 0: /* Record Monitor */ value = (INB (devc->osdev, REC_MONITOR) & 0x1) ? 1 : 0; break; - case 1: /* Front Panel Monitor */ - value = (INB (devc->osdev, REC_MONITOR) & 0x4) ? 1 : 0; - break; - case 2: /* SPDIFIN Monitor */ + case 1: /* SPDIFIN Monitor */ value = (INB (devc->osdev, REC_MONITOR) & 0x10) ? 1 : 0; break; - case 3: /* Speaker Spread - just check bit15 to see if it's set */ + case 2: /* Record source select */ + value = (ac97_read (devc, 0x72) & 0x1) ? 1 : 0; + break; + case 3: /* Speaker Spread - check bit15 to see if it's set */ value = (INW (devc->osdev, PLAY_ROUTING) & 0x8000) ? 0 : 1; break; case 4: /* SPDIF IN->OUT Loopback */ value = (INW (devc->osdev, SPDIF_FUNC) & 0x4) ? 1 : 0; break; - + case 5: + value = (INW (devc->osdev, GPIO_DATA) & 0x80) ? 1 : 0; + break; default: return OSS_EINVAL; + break; } return value; @@ -1806,29 +1859,35 @@ { case 0: /* Record Monitor */ if (value) - OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x1, + OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0xF, REC_MONITOR); else - OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x1, + OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0xF, REC_MONITOR); break; - case 1: /* Front Panel Record Monitor */ + case 1: /* SPDIFIN Monitor */ if (value) - OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x4, + OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x10, REC_MONITOR); else - OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x4, + OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x10, REC_MONITOR); break; - case 2: /* SPDIFIN Monitor */ + case 2: if (value) - OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x10, - REC_MONITOR); + { + if (devc->model == SUBID_XONAR_D1 || devc->model == SUBID_XONAR_DX) + OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x100, GPIO_DATA); + ac97_write(devc, 0x72, ac97_read(devc, 0x72) | 0x1); + } else - OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x10, - REC_MONITOR); + { + if (devc->model == SUBID_XONAR_D1 || devc->model == SUBID_XONAR_DX) + OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) & ~0x100, GPIO_DATA); + ac97_write(devc, 0x72, ac97_read(devc, 0x72) & ~0x1); + } break; case 3: /* Speaker Spread (clone front to all channels) */ @@ -1850,8 +1909,16 @@ SPDIF_FUNC); break; + case 5: + if (value) + OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x80, GPIO_DATA) ; + else + OUTW(devc->osdev, (INW(devc->osdev, GPIO_DATA) & ~0x80), GPIO_DATA); + break; + default: return OSS_EINVAL; + break; } return (value); } @@ -2072,6 +2139,7 @@ cmi8788_mix_init (int dev) { int group, parent, ctl; + cmi8788_devc *devc = mixer_devs[dev]->hw_devc; if ((parent = mixer_ext_create_group (dev, 0, "EXT")) < 0) return parent; @@ -2082,22 +2150,23 @@ if ((ctl = mixer_ext_create_control (dev, group, 0, cmi8788_ext, - MIXT_ONOFF, "MULTICHANNEL", 1, + MIXT_ONOFF, "ANALOG", 1, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, 1, cmi8788_ext, - MIXT_ONOFF, "FRONTPANEL", 1, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return ctl; - - if ((ctl = - mixer_ext_create_control (dev, group, 2, cmi8788_ext, MIXT_ONOFF, "SPDIF", 1, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; + if ((ctl = + mixer_ext_create_control (dev, group, 2, cmi8788_ext, MIXT_ENUM, + "inputsrc", 2, + MIXF_READABLE | MIXF_WRITEABLE)) < 0) + return ctl; + mixer_ext_set_strings (dev, ctl, "Line Mic", 0); + /* Create PLAYBACK ROUTING */ if ((group = mixer_ext_create_group (dev, parent, "OUTPUT_ROUTING")) < 0) return group; @@ -2114,6 +2183,13 @@ MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; + if (devc->model == SUBID_XONAR_D2 || devc->model == SUBID_XONAR_D2X) + if ((ctl = mixer_ext_create_control (dev, group, 5, cmi8788_ext, + MIXT_ONOFF, "PCM-LOOPBACK", 1, + MIXF_READABLE | MIXF_WRITEABLE)) < 0) + return ctl; + + /* Create SPDIF OUTPUT */ if ((group = mixer_ext_create_group (dev, 0, "SPDIF-OUT")) < 0) return group; @@ -2184,6 +2260,46 @@ } +void ac97_hwinit(cmi8788_devc *devc) +{ + + /* Gpio #0 programmed as output, set CMI9780 Reg0x70 */ + ac97_write(devc, 0x70, 0x100); + + /* LI2LI,MIC2MIC; let them always on, FOE on, ROE/BKOE/CBOE off */ + ac97_write(devc, 0x62, 0x180F); + + /* change PCBeep path, set Mix2FR on, option for quality issue */ + ac97_write(devc, 0x64, 0x8043); +#if 0 + /* unmute Master Volume */ + ac97_write(devc, 0x02, 0x0); + + + /* mute PCBeep, option for quality issues */ + ac97_write(devc, 0x0A, 0x8000); + + /* Record Select Control Register (Index 1Ah) */ + ac97_write(devc, 0x1A, 0x0000); + + /* set Mic Volume Register 0x0Eh umute and enable micboost */ + ac97_write(devc, 0x0E, 0x0848); + + /* set Line in Volume Register 0x10h mute */ + ac97_write(devc, 0x10, 0x8808); + + /* set CD Volume Register 0x12h mute */ + ac97_write(devc, 0x12, 0x8808); + + /* set AUX Volume Register 0x16h max */ + ac97_write(devc, 0x16, 0x0808); + + /* set record gain Register 0x1Ch to max */ + ac97_write(devc, 0x1C, 0x0F0F); +#endif + ac97_write(devc, 0x71, 0x0001); +} + static int init_cmi8788 (cmi8788_devc * devc) { @@ -2205,24 +2321,8 @@ bVal = INB (devc->osdev, FUNCTION); bVal |= 0x02; /* Reset codec*/ + OUTB(devc->osdev, bVal, FUNCTION); - switch(devc->model) - { - case SUBID_XONAR_D1: - case SUBID_XONAR_DX: - /* Two-Wire communication for Xonar DX DACs. */ - bVal |= 0x40; - break; - default: - /* SPI default for anything else, including the */ - /* Xonar D2 and D2X. */ - bVal &= ~0x40; - /* Enable SPI outputs 4 and 5 */ - bVal |= 0x80; - break; - } - - OUTB (devc->osdev, bVal, FUNCTION); /* I2S to 16bit, see below. */ sDac = 0x010A; @@ -2232,10 +2332,8 @@ { case SUBID_XONAR_D1: case SUBID_XONAR_DX: - /* Front DAC. */ - cs4398_init(devc, XONAR_DX_FRONTDAC); - /* Surround DAC. */ - cs4362a_init(devc, XONAR_DX_SURRDAC); + case SUBID_XONAR_D2: + case SUBID_XONAR_D2X: /* Must set master clock. */ sDac |= XONAR_DX_MCLOCK_256; break; @@ -2243,9 +2341,9 @@ /* Setup I2S to use 16bit instead of 24Bit */ OUTW (devc->osdev, sDac, I2S_MULTICH_FORMAT); - OUTW (devc->osdev, 0x010A, I2S_ADC1_FORMAT); - OUTW (devc->osdev, 0x010A, I2S_ADC2_FORMAT); - OUTW (devc->osdev, 0x010A, I2S_ADC3_FORMAT); + OUTW (devc->osdev, sDac, I2S_ADC1_FORMAT); + OUTW (devc->osdev, sDac, I2S_ADC2_FORMAT); + OUTW (devc->osdev, sDac, I2S_ADC3_FORMAT); /* setup Routing regs (default vals) */ OUTW (devc->osdev, 0xE400, PLAY_ROUTING); @@ -2253,8 +2351,9 @@ OUTB (devc->osdev, 0x00, REC_MONITOR); OUTB (devc->osdev, 0xE4, MONITOR_ROUTING); + /* install the CMI8788 mixer */ - if ((devc->spi_mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION, + if ((devc->cmi_mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION, devc->osdev, devc->osdev, "CMedia CMI8788", @@ -2265,9 +2364,9 @@ return 0; } - mixer_devs[devc->spi_mixer_dev]->hw_devc = devc; - mixer_devs[devc->spi_mixer_dev]->priority = 10; /* Possible default mixer candidate */ - mixer_ext_set_init_fn (devc->spi_mixer_dev, cmi8788_mix_init, 25); + mixer_devs[devc->cmi_mixer_dev]->hw_devc = devc; + mixer_devs[devc->cmi_mixer_dev]->priority = 10; /* Possible default mixer candidate */ + mixer_ext_set_init_fn (devc->cmi_mixer_dev, cmi8788_mix_init, 25); /* Cold reset onboard AC97 */ OUTW (devc->osdev, 0x1, AC97_CTRL); @@ -2290,32 +2389,16 @@ if (sVal & 0x10) { /* disable CODEC0 OUTPUT */ - OUTW (devc->osdev, INW (devc->osdev, AC97_OUT_CHAN_CONFIG) & ~0xFF00, + OUTW (devc->osdev, 0, /* INW (devc->osdev, AC97_OUT_CHAN_CONFIG) & ~0xFF00,*/ AC97_OUT_CHAN_CONFIG); /* enable CODEC0 INPUT */ - OUTW (devc->osdev, INW (devc->osdev, AC97_IN_CHAN_CONFIG) | 0x0300, + OUTW (devc->osdev, 0, /* INW (devc->osdev, AC97_IN_CHAN_CONFIG) | 0x0300,*/ AC97_IN_CHAN_CONFIG); - /* set Playback routing to I2S mode */ - OUTW (devc->osdev, INW (devc->osdev, PLAY_ROUTING) & ~0x10, - PLAY_ROUTING); - - /* setup record channel A (MULTICH) and B (Front Panel) in AC97 mode */ - OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING); - devc->ac97_mixer_dev = ac97_install (&devc->ac97devc, "AC97 Input Mixer", ac97_read, ac97_write, devc, devc->osdev); - - if (devc->ac97_mixer_dev >= 0) - { - /* setup the Codec0 as the input mux */ - ac97_write (devc, 0x70, 0x0300); - ac97_write (devc, 0x64, 0x8041); - ac97_write (devc, 0x62, 0x180F); - ac97_remove_control (&devc->ac97devc, UNUSED_CMI9780_CONTROLS, 0); - } } /* check if there's an front panel AC97 codec (CODEC1) and install the mixer */ @@ -2342,6 +2425,58 @@ } + + switch(devc->model) { + case SUBID_XONAR_D1: + case SUBID_XONAR_DX: + /*GPIO8 = 0x100 controls mic/line-in */ + /*GPIO0 = 0x001controls output */ + /*GPIO2/3 = 0x00C codec output control*/ + + /* setup for 2wire communication mode */ + OUTB(devc->osdev, INB (devc, FUNCTION) | 0x40, FUNCTION); + /* setup GPIO direction */ + OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x010D, GPIO_CONTROL); + /* setup GPIO pins */ + OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x0101, GPIO_DATA); + + /* init the front and rear dacs */ + cs4398_init(devc, XONAR_DX_FRONTDAC); + cs4362a_init(devc, XONAR_DX_SURRDAC); + /* initialize the codec 0 */ + ac97_hwinit(devc); + break; + + + case SUBID_XONAR_D2: + case SUBID_XONAR_D2X: + /*GPIO7 = 0x0080 controls mic/line-in */ + /*GPIO8 = 0x0100 controls output */ + /*GPIO2/3 = 0x000C codec output control*/ + + /* setup for spi communication mode */ + OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40) | 0x80, FUNCTION); + /* setup the GPIO direction */ + OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x018C, GPIO_CONTROL); + /* setup GPIO Pins */ + OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x0100, GPIO_DATA); + + /* for all 4 codecs: unmute, set to 24Bit SPI */ + for (i = 0; i < 4; ++i) { + pcm1796_write(devc, i, 16, mix_scale(75,8)); /* left vol*/ + pcm1796_write(devc, i, 17, mix_scale(75,8)); /* right vol */ + pcm1796_write(devc, i, 18, 0x30 | 0x80); /* unmute/24LSB/ATLD */ + } + /* initialize the codec 0 */ + ac97_hwinit(devc); + break; + + default: + /* SPI default for anything else, including the */ + OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40) | 0x80, FUNCTION); + break; + } + /* check if MPU401 is enabled in MISC register */ if (INB (devc->osdev, MISC_REG) & 0x40) attach_mpu (devc); @@ -2359,7 +2494,21 @@ sprintf (tmp_name, "%s (MultiChannel)", devc->chip_name); caps |= ADEV_DUPLEX; fmt |= AFMT_S32_LE; - portc->port_type = ADEV_MULTICH; + portc->dac_type = ADEV_MULTICH; + switch(devc->model) + { + case SUBID_XONAR_D1: + case SUBID_XONAR_DX: + case SUBID_XONAR_D2: + case SUBID_XONAR_D2X: + portc->adc_type = ADEV_I2SADC2; + break; + default: + portc->adc_type = ADEV_I2SADC1; + OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING); + break; + } + portc->min_rate = 32000; portc->max_rate = 192000; portc->min_chan = 2; @@ -2370,7 +2519,21 @@ sprintf (tmp_name, "%s (Multichannel)", devc->chip_name); caps |= ADEV_DUPLEX | ADEV_SHADOW; fmt |= AFMT_S32_LE; - portc->port_type = ADEV_MULTICH; + portc->dac_type = ADEV_MULTICH; + switch(devc->model) + { + case SUBID_XONAR_D1: + case SUBID_XONAR_DX: + case SUBID_XONAR_D2: + case SUBID_XONAR_D2X: + portc->adc_type = ADEV_I2SADC2; + break; + default: + portc->adc_type = ADEV_I2SADC1; + OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING); + break; + } + portc->min_rate = 32000; portc->max_rate = 192000; portc->min_chan = 2; @@ -2386,7 +2549,9 @@ caps |= ADEV_DUPLEX | ADEV_16BITONLY | ADEV_STEREOONLY | ADEV_SPECIAL; fmt |= AFMT_AC3; - portc->port_type = ADEV_FRONTPANEL; + portc->dac_type = ADEV_FRONTPANEL; + portc->adc_type = ADEV_I2SADC2; + OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING); portc->min_rate = 8000; portc->max_rate = 48000; portc->min_chan = 2; @@ -2397,7 +2562,8 @@ sprintf (tmp_name, "%s (SPDIF)", devc->chip_name); caps |= ADEV_DUPLEX | ADEV_STEREOONLY | ADEV_SPECIAL; fmt |= AFMT_AC3 | AFMT_S32_LE; - portc->port_type = ADEV_SPDIF; + portc->dac_type = ADEV_SPDIF; + portc->adc_type = ADEV_I2SADC3; portc->min_rate = 32000; portc->max_rate = 192000; portc->min_chan = 2; @@ -2446,28 +2612,18 @@ */ default_vol = 0x4b4b; devc->playvol[0] = - cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev, + cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev, MIXER_WRITE (SOUND_MIXER_PCM), &default_vol); devc->playvol[1] = - cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev, + cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev, MIXER_WRITE (SOUND_MIXER_REARVOL), &default_vol); devc->playvol[2] = - cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev, + cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev, MIXER_WRITE (SOUND_MIXER_CENTERVOL), &default_vol); devc->playvol[3] = - cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev, + cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev, MIXER_WRITE (SOUND_MIXER_SIDEVOL), &default_vol); - /* Enable Xonar output */ - switch(devc->model) - { - case SUBID_XONAR_D1: - case SUBID_XONAR_DX: - OUTW(devc->osdev, XONAR_DX_OUTPUT, GPIO_CONTROL); - OUTW(devc->osdev, XONAR_DX_OUTPUT, GPIO_DATA); - break; - } - return 1; } diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24/envy24_1010lt.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24/envy24_1010lt.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24/envy24_1010lt.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24/envy24_1010lt.c 2010-05-27 13:38:37.000000000 +0200 @@ -548,6 +548,15 @@ WriteGPIObit (devc, WCLOCK_ENABLE, 1); write_d1010lt_spdif_reg (devc, 4, read_d1010lt_spdif_reg (devc, 4) & (~BIT0)); + if (devc->model_data->svid == 0xd63014ff) + { + /* + * 1010 rev E only + * don't aks me why, but it seems to work + */ + WriteGPIObit (devc, 6, 0); + WriteGPIObit (devc, WCLOCK_ENABLE, 1); + } break; } } diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c 2010-05-27 13:38:38.000000000 +0200 @@ -3947,7 +3947,7 @@ #endif if (subvendor == 0xd6301412) /* Delta 1010 */ - if (devc->eeprom[0xc] == 0x7b) /* Looks like Delta 101 rev E */ + if (devc->eeprom[0xc] == 0x7b) /* Looks like Delta 1010 rev E */ subvendor = 0xd63014ff; /* Delta 1010E */ diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c.orig oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c.orig --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c.orig 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24/oss_envy24.c.orig 1970-01-01 01:00:00.000000000 +0100 @@ -1,4043 +0,0 @@ -/* - * Purpose: Driver for IC Ensemble ENVY24 based audio cards. - * - * The audio input and output devices implemented by this driver use additional - * layer of buffering for channel re-interleaving. The device itself uses - * 10/12 channel interleaved 32 bit format in hardware level. The - * re-interleaving engine splits these multi channel devices to several - * "stereo" devices. - */ -/* - * - * This file is part of Open Sound System. - * - * Copyright (C) 4Front Technologies 1996-2008. - * - * This this source file is released under GPL v2 license (no other versions). - * See the COPYING file included in the main directory of this source - * distribution for the license terms and conditions. - * - */ - -#include "oss_envy24_cfg.h" -#include -#include - -#include "envy24.h" - -extern int envy24_skipdevs; -extern int envy24_force_mono; -extern int envy24_gain_sliders; -int envy24_virtualout = 0; /* This used to be an config option */ - -extern int envy24_devmask; -#define DMASK_ANALOGOUT 1 -#define DMASK_ANALOGIN 2 -#define DMASK_SPDIFOUT 4 -#define DMASK_SPDIFIN 8 -#define DMASK_MONITORIN 16 -#define DMASK_RAWDEVS 32 - -extern envy24_auxdrv_t default_auxdrv; -extern envy24_auxdrv_t ap2496_auxdrv; -extern envy24_auxdrv_t d410_auxdrv; -extern envy24_auxdrv_t d1010lt_auxdrv; -extern envy24_auxdrv_t tdif_auxdrv; -extern envy24_auxdrv_t ewx2496_auxdrv; -extern envy24_auxdrv_t ews88d_auxdrv; -extern envy24_auxdrv_t dmx6fire_auxdrv; - -static card_spec models[] = { - {0xd6301412, "M Audio Delta 1010", 8, 8, - MF_MAUDIO | MF_MIDI1 | MF_SPDIF | MF_WCLOCK | MF_MEEPROM}, - {0xd6311412, "M Audio Delta DiO 2496", 2, 0, - MF_MAUDIO | MF_SPDIF | MF_SPDSELECT | MF_MEEPROM}, - {0xd6321412, "M Audio Delta 66", 4, 4, - MF_MAUDIO | MF_SPDIF | MF_AKMCODEC | MF_MEEPROM}, - {0xd6331412, "M Audio Delta 44", 4, 4, - MF_MAUDIO | MF_AKMCODEC | MF_MEEPROM}, - {0xd6341412, "M Audio Audiophile 2496", 2, 2, - MF_AP | MF_SPDIF | MF_MIDI1 | MF_MEEPROM, &ap2496_auxdrv}, - {0xd6381412, "M Audio Delta 410", 8, 2, MF_D410 | MF_SPDIF | MF_MEEPROM, - &d410_auxdrv}, - - /* Delta 1010 rev E is based on 1010LT instead of the original 1010 design */ - {0xd63014ff, "M Audio Delta 1010 rev E", 8, 8, - MF_MIDI1 | MF_SPDIF | MF_MEEPROM | MF_WCLOCK, &d1010lt_auxdrv}, - - {0xd63b1412, "M Audio Delta 1010LT", 8, 8, - MF_MIDI1 | MF_SPDIF | MF_MEEPROM | MF_WCLOCK, &d1010lt_auxdrv}, - {0xd6351412, "M Audio Delta TDIF", 8, 8, MF_SPDIF | MF_MEEPROM | MF_WCLOCK, - &tdif_auxdrv}, - {0x1115153b, "Terratec EWS88MT", 8, 8, - MF_MIDI1 | MF_SPDIF | MF_EWS88 | MF_AC97}, - {0x112b153b, "Terratec EWS88D", 8, 8, - MF_MIDI1 | MF_MIDI2 | MF_SPDIF | MF_AC97 | MF_WCLOCK, &ews88d_auxdrv}, - {0x1130153b, "Terratec EWX 24/96", 2, 2, MF_SPDIF | MF_EWX2496, - &ewx2496_auxdrv}, - {0x1138153b, "Terratec DMX6fire 24/96", 6, 6, - MF_MIDI1 | MF_MIDI2 | MF_SPDIF, &dmx6fire_auxdrv}, - {0x17121412, "Generic Envy24 based card", 8, 8, - MF_SPDIF | MF_MIDI1 | MF_CONSUMER | MF_HOONTECH}, - {0} -}; - -static struct speed_sel speed_tab[] = { - { - 8000, 0x06} - , - { - 9600, 0x03} - , - { - 11025, 0x0a} - , - { - 12000, 0x02} - , - { - 16000, 0x05} - , - { - 22050, 0x09} - , - { - 24000, 0x01} - , - { - 32000, 0x04} - , - { - 44100, 0x08} - , - { - 48000, 0x00} - , - /* {64000, 0x0f}, doesn't work */ - { - 88200, 0x0b} - , - { - 96000, 0x07} - , - { - -1, 0x10} - , -}; - -int -envy24_read_cci (envy24_devc * devc, int pos) -{ - OUTB (devc->osdev, pos, devc->ccs_base + 0x03); - return INB (devc->osdev, devc->ccs_base + 0x04); -} - -void -envy24_write_cci (envy24_devc * devc, int pos, int data) -{ - OUTB (devc->osdev, pos, devc->ccs_base + 0x03); - OUTB (devc->osdev, data, devc->ccs_base + 0x04); -} - -static int -eeprom_read (envy24_devc * devc, int pos) -{ - int i, status; - - for (i = 0; i < 0x10000; i++) - { - status = INB (devc->osdev, devc->ccs_base + 0x13); - if (!(status & 1)) - break; - - } - - OUTB (devc->osdev, 0xa0, devc->ccs_base + 0x10); /* EEPROM read */ - OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */ - - for (i = 0; i < 2000; i++) - { - status = INB (devc->osdev, devc->ccs_base + 0x13); - if (!(status & 1)) - break; - - } - - oss_udelay (1); - return INB (devc->osdev, devc->ccs_base + 0x12); -} - -static int -load_eeprom (envy24_devc * devc, int subid) -{ - int status, i, check; - - status = INB (devc->osdev, devc->ccs_base + 0x13); - - if (!(status & 0x80)) - return 0; /* No EEPROM */ - - for (i = 0; i < 32; i++) - { - devc->eeprom[i] = eeprom_read (devc, i); - devc->eeprom[i] = eeprom_read (devc, i); - } - DDB (cmn_err (CE_CONT, "EEPROM=")); - for (i = 0; i < 10; i++) - DDB (cmn_err (CE_CONT, "0x%02x, ", devc->eeprom[i])); - DDB (cmn_err (CE_CONT, "\n")); - - check = 0; - for (i = 0; i < 4; i++) - { - check <<= 8; - check |= devc->eeprom[i]; - } - - if (check != subid) - cmn_err (CE_CONT, - "Envy24 WARNING: Possible EEPROM read error %08x != %08x\n", - check, subid); - - return 1; -} - -static void -handle_playdev (envy24_devc * devc, envy24_portc * portc, int this_frag) -{ - int sample, nsamples, nbytes, ch; - dmap_t *dmap = audio_engines[portc->dev]->dmap_out; - - if (!(portc->trigger_bits & PCM_ENABLE_OUTPUT) && devc->playback_started) - return; - - nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */ - - nbytes = nsamples * portc->channels; - - if (audio_engines[portc->dev]->dmap_out->flags & DMAP_POST) - { - if (portc->pcm_qlen > 0) - portc->pcm_qlen--; - } - else - { - if (portc->pcm_qlen < devc->writeahead) - portc->pcm_qlen++; - } - - if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3)) - nbytes *= 2; - else if (portc-> - bits & (AFMT_S32_LE | AFMT_S32_BE | AFMT_S24_LE | AFMT_S24_BE)) - nbytes *= 4; - - if (nbytes != dmap->fragment_size) - return; /* Fragment size mismatch */ - - switch (portc->bits) - { - case AFMT_U8: - { - unsigned char *ip; - int *op; - - ip = audio_engines[portc->dev]->dmap_out->dmabuf; - ip += (dmap_get_qhead (dmap) * dmap->fragment_size); - op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag); - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 10 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *p++ = (*ip++ ^ 0x80) << 24; - } - } - } - break; - - case AFMT_AC3: - case AFMT_S16_LE: - { - short *ip; - int *op; -#ifdef DO_TIMINGS - oss_timing_printf ("Envy24: Copy out %d, %d", - dmap_get_qhead (dmap) * dmap->fragment_size, nbytes); -#endif - - ip = (short *) (dmap->dmabuf + - (dmap_get_qhead (dmap) * dmap->fragment_size)); - op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag); - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 10 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *p++ = *ip++ << 16; - } - } - } - break; - - case AFMT_S16_BE: - { - short *ip; - int *op; - - ip = (short *) (audio_engines[portc->dev]->dmap_out->dmabuf + - (dmap_get_qhead (dmap) * dmap->fragment_size)); - op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag); - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 10 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - short s = (short) (((*(unsigned short *) ip & 0xff) << 8) | - ((*(unsigned short *) ip & 0xff00) >> - 8)); - ip++; - *p++ = s << 16; - } - } - } - break; - - case AFMT_S24_LE: - { - int *ip; - int *op; - - ip = (int *) (audio_engines[portc->dev]->dmap_out->dmabuf + - (dmap_get_qhead (dmap) * dmap->fragment_size)); - op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag); - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 10 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *p++ = *ip++ << 8; - } - } - } - break; - - case AFMT_S32_LE: - { - int *ip; - int *op; - - ip = (int *) (audio_engines[portc->dev]->dmap_out->dmabuf + - (dmap_get_qhead (dmap) * dmap->fragment_size)); - op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag); - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 10 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *p++ = *ip++; - } - } - } - break; - } - - oss_audio_outputintr (portc->dev, 1); -} - -#ifdef DO_RIAA -static __inline__ int32_t -_riaa_sat31 (register int32_t a, register int32_t b) -{ - register int64_t v = (((int64_t) a) * b) + (1 << 30); - return (int32_t) (v >> 31); -} -#endif - -static void -handle_recdev (envy24_devc * devc, envy24_portc * portc) -{ - int sample, nsamples, nbytes, ch; - dmap_t *dmap = audio_engines[portc->dev]->dmap_in; - - if (portc->trigger_bits == 0 && devc->recording_started) - return; - - nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */ - - nbytes = nsamples * portc->channels; - - if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3)) - nbytes *= 2; - else if (portc->bits & (AFMT_S32_LE | AFMT_S24_LE)) - nbytes *= 4; - - if (nbytes != dmap->fragment_size) - { - return; /* Fragment size mismatch */ - } - - switch (portc->bits) - { - case AFMT_U8: - { - unsigned char *ip; - int *op; - - ip = audio_engines[portc->dev]->dmap_in->dmabuf; - ip += (dmap_get_qtail (dmap) * dmap->fragment_size); - op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag); - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 12 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *ip++ = ((*p++) >> 24) ^ 0x80; - } - } - } - break; - - case AFMT_S16_LE: -#ifdef DO_RIAA - if (portc->riaa_filter) - { - /* RIAA filtered version */ - short *ip; - int *op; - - ip = (short *) (audio_engines[portc->dev]->dmap_in->dmabuf + - (dmap_get_qtail (dmap) * dmap->fragment_size)); - op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag); - - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - - for (ch = 0; ch < portc->channels; ch++) - { - int *p = &op[portc->chnum + ch]; - short *p2 = &ip[ch]; - riaa_t *ff = &portc->riaa_parms[ch]; - - int32_t x1 = ff->x1, x2 = ff->x2, x3 = ff->x3, - y1 = ff->y1, y2 = ff->y2, y3 = ff->y3, x0, y0; - - for (sample = 0; sample < nsamples; sample++) - { - int tmp = *p; - p += 12; - - x0 = _riaa_sat31 (tmp, 0x4C30C30C); - - y0 = _riaa_sat31 (x0, 0xF38FB92F) + - _riaa_sat31 (x1, 0xF2492994) + - _riaa_sat31 (x2, 0x1AB82385) + - _riaa_sat31 (x3, 0x023FB0F8) + - (_riaa_sat31 (y1, 0x574DB88C) << 1) + - _riaa_sat31 (y2, 0xF650F27D) + - _riaa_sat31 (y3, 0xDACB84B9); - - x3 = x2; - x2 = x1; - x1 = x0; - y3 = y2; - y2 = y1; - y1 = y0; - - tmp = -y0; - - *p2 = tmp >> 16; - p2 += portc->channels; - } - - ff->x1 = x1; - ff->x2 = x2; - ff->x3 = x3; - ff->y1 = y1; - ff->y2 = y2; - ff->y3 = y3; - } - /* RIAA filtered version */ - } - else -#endif - { - short *ip; - int *op; - - ip = (short *) (audio_engines[portc->dev]->dmap_in->dmabuf + - (dmap_get_qtail (dmap) * dmap->fragment_size)); - op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag); - - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 12 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *ip++ = (*p++) >> 16; - } - } - } - break; - - case AFMT_S32_LE: - { - int *ip; - int *op; - - ip = (int *) (audio_engines[portc->dev]->dmap_in->dmabuf + - (dmap_get_qtail (dmap) * dmap->fragment_size)); - op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag); - - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 12 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *ip++ = *p++; - } - } - } - break; - - case AFMT_S24_LE: - { - int *ip; - int *op; - - ip = (int *) (audio_engines[portc->dev]->dmap_in->dmabuf + - (dmap_get_qtail (dmap) * dmap->fragment_size)); - op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag); - - VMEM_CHECK (ip, nsamples * sizeof (*ip)); - VMEM_CHECK (op, nsamples * sizeof (*op)); - for (sample = 0; sample < nsamples; sample++) - { - int *p = &op[sample * 12 + portc->chnum]; - - for (ch = 0; ch < portc->channels; ch++) - { - *ip++ = *p++ >> 8; - } - } - } - break; - } - - oss_audio_inputintr (portc->dev, 0); -} - -static void -tank_playback_data (envy24_devc * devc) -{ - int i, nc = devc->nr_outdevs; - envy24_portc *portc; - unsigned char *p; - - p = devc->playbuf + devc->hw_playfrag * devc->hw_pfragsize; - VMEM_CHECK (p, devc->hw_pfragsize); - memset (p, 0, devc->hw_pfragsize); /* Cleanup the fragment */ - - for (i = 0; i < nc; i++) - { - portc = &devc->play_portc[i]; - - if (!portc->open_mode) /* Not opened */ - continue; - handle_playdev (devc, portc, devc->hw_playfrag); - } - - devc->hw_playfrag = (devc->hw_playfrag + 1) % devc->hw_nfrags; -} - -static void -handle_recording (envy24_devc * devc) -{ - int i; - envy24_portc *portc; - /* oss_native_word flags; */ - - /* - * TODO: Fix mutexes and move the inputintr/outputintr calls outside the - * mutex block. - */ - /* MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); */ - for (i = 0; i < devc->nr_indevs; i++) - { - portc = &devc->rec_portc[i]; - - if (!portc->open_mode) /* Not opened */ - continue; - handle_recdev (devc, portc); - } - - devc->hw_recfrag = (devc->hw_recfrag + 1) % devc->hw_nfrags; - /* MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); */ -} - -extern int envy24d_get_buffer_pointer (int dev, dmap_t * dmap, int direction); - -static void -mt_audio_intr (envy24_devc * devc) -{ - int status; - -#ifdef DO_TIMINGS - oss_timing_enter (DF_INTERRUPT); - oss_do_timing2 (DFLAG_PROFILE, "Envy24_audio_intr"); -#endif - status = INB (devc->osdev, devc->mt_base + 0x00); - if (devc->playback_started && (status & 0x01)) /* Playback interrupt */ - { -/* cmn_err(CE_CONT, "%d\n", GET_JIFFIES()); */ - if (devc->direct_audio_opened & OPEN_WRITE) - { - envy24d_playintr (devc); - } - else - { - int ptr, qlen, i; - - ptr = INW (devc->osdev, devc->mt_base + 0x14); - ptr = (devc->playbuffsize - ((ptr + 1) * 4)) / devc->hw_pfragsize; - - /* Find the number of current fragments in the hardware level buffer */ - qlen = 0; - i = devc->hw_playfrag; - - while (qlen < 15 && i != ptr) - { - qlen++; - i = (i + 1) % devc->hw_nfrags; - } - - if (qlen != devc->writeahead) - { - tank_playback_data (devc); - } - - if (devc->hw_playfrag == ptr) /* Out of sync */ - { - tank_playback_data (devc); /* Try to catch the hardware pointer */ - } - - - tank_playback_data (devc); - } - } - - if (devc->recording_started && (status & 0x02)) /* Record interrupt */ - { - if (devc->direct_audio_opened & OPEN_READ) - envy24d_recintr (devc); - else - handle_recording (devc); - } - - OUTB (devc->osdev, status, devc->mt_base + 0x00); -#ifdef DO_TIMINGS - oss_timing_leave (DF_INTERRUPT); - oss_do_timing2 (DFLAG_PROFILE, "Envy24_audio_intr done"); -#endif -} - -static int -envy24intr (oss_device_t * osdev) -{ - int status; - envy24_devc *devc; - - devc = osdev->devc; - - status = INB (devc->osdev, devc->ccs_base + 0x02); - if (status == 0) - return 0; - - if (status & 0x80) /* MIDI UART 1 */ - if (devc->model_data->flags & MF_MIDI1) - uart401_irq (&devc->uart401devc1); - - if (status & 0x20) /* MIDI UART 2 */ - if (devc->model_data->flags & MF_MIDI2) - uart401_irq (&devc->uart401devc2); - - if (status & 0x10) - { -/*cmn_err(CE_CONT, "%d/%d.", GET_JIFFIES(), envy24d_get_buffer_pointer(11, audio_engines[11]->dmap_out, DMODE_OUTPUT)); */ - mt_audio_intr (devc); - } - - OUTB (devc->osdev, status, devc->ccs_base + 0x02); /* ACK */ - - return 1; -} - -static void envy24_setup_pro_speed (envy24_devc * devc); -static void envy24_setup_consumer_speed (envy24_devc * devc); - -void -envy24_prepare_play_engine (envy24_devc * devc) -{ - int tmp, fragsize, buffsize; - - if (devc->playback_prepared) - return; - - /* Set S/PDIF sample rate indication */ - - if (devc->spdif_cbits[0] & 0x01) - envy24_setup_pro_speed (devc); - else - envy24_setup_consumer_speed (devc); - - if (devc->model_data->flags & MF_SPDIF) - { - tmp = 0x80; - - if (devc->ac3_mode) - tmp |= 0x40; /* Audio mode off */ - - switch (devc->speed) - { - case 48000: - tmp |= 0x01; - break; - case 44100: - tmp |= 0x02; - break; - case 32000: - tmp |= 0x03; - break; - } - - if (devc->model_data->auxdrv->spdif_set) - devc->model_data->auxdrv->spdif_set (devc, tmp); - - } - - if (devc->model_data->auxdrv->set_rate) - devc->model_data->auxdrv->set_rate (devc); - else - { - tmp = devc->speedbits; - if (devc->syncsource != SYNC_INTERNAL) - { - tmp |= 0x10; /* S/PDIF input clock select */ - if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */ - { - int cmd = envy24_read_cci (devc, 0x20); - cmd |= 0x10; /* S/PDIF */ - if (devc->syncsource == SYNC_WCLOCK) - cmd &= ~0x10; /* World clock */ - envy24_write_cci (devc, 0x20, cmd); - } - } - OUTB (devc->osdev, tmp, devc->mt_base + 0x01); - } - - fragsize = devc->hw_pfragsize; - buffsize = devc->playbuffsize / 4 - 1; - - PMEM_CHECK (devc->playbuf_phys, devc->playbuffsize); - - OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */ - OUTW (devc->osdev, buffsize, devc->mt_base + 0x14); /* Count */ - OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */ - OUTW (devc->osdev, buffsize, devc->mt_base + 0x14); /* Count */ - OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */ - OUTW (devc->osdev, fragsize / 4 - 1, devc->mt_base + 0x16); /* Interrupt rate */ - OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */ - - devc->playback_prepared = 1; - mixer_devs[devc->mixer_dev]->modify_counter++; -} - -void -envy24_launch_play_engine (envy24_devc * devc) -{ - /* Unmask playback interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->mt_base + 0x00) & ~0x40, - devc->mt_base + 0x00); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x00) & ~0x40, - devc->mt_base + 0x00); - /* Kick it */ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) | 0x01, - devc->mt_base + 0x18); - devc->playback_started = 1; - - if (devc->model_data->auxdrv->set_rate) - devc->model_data->auxdrv->set_rate (devc); -} - -static void -start_playback (envy24_devc * devc) -{ - devc->hw_playfrag = 0; - -#ifdef DO_TIMINGS - oss_do_timing ("Envy24: Start playback"); -#endif - tank_playback_data (devc); - tank_playback_data (devc); - if (devc->writeahead == 2) - tank_playback_data (devc); - - envy24_prepare_play_engine (devc); - envy24_launch_play_engine (devc); -} - -void -envy24_stop_playback (envy24_devc * devc) -{ -#ifdef DO_TIMINGS - oss_do_timing ("Envy24: Stop playback"); -#endif - memset (devc->playbuf, 0, devc->playbuffsize); - /* - * Give the engine time to eat some silent samples - * This makes the corresponding digital mixer inputs to drop to 0 - * which decreases noise in the monitor outputs. - */ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01, - devc->mt_base + 0x18); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01, - devc->mt_base + 0x18); - - /* Mask playback interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->mt_base + 0x00) | 0x40, devc->mt_base + 0x00); - devc->playback_started = 0; - devc->playback_prepared = 0; -} - -void -envy24_start_recording (envy24_devc * devc) -{ - int tmp; - - devc->hw_recfrag = 0; - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04, - devc->mt_base + 0x18); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04, - devc->mt_base + 0x18); - oss_udelay (20); - - if (devc->model_data->flags & MF_SPDIF) - { - tmp = 0x80; - - switch (devc->speed) - { - case 48000: - tmp |= 0x01; - break; - case 44100: - tmp |= 0x02; - break; - case 32000: - tmp |= 0x03; - break; - } - - if (devc->model_data->auxdrv->spdif_set) - devc->model_data->auxdrv->spdif_set (devc, tmp); - - } - - tmp = devc->speedbits; - if (devc->syncsource != SYNC_INTERNAL) - { - tmp |= 0x10; /* S/PDIF input clock select */ - if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */ - { - int cmd = envy24_read_cci (devc, 0x20); - cmd |= 0x10; /* S/PDIF */ - if (devc->syncsource == SYNC_WCLOCK) - cmd &= ~0x10; /* World clock */ - envy24_write_cci (devc, 0x20, cmd); - } - } - - OUTB (devc->osdev, tmp, devc->mt_base + 0x01); - - if (devc->model_data->auxdrv->set_rate) - devc->model_data->auxdrv->set_rate (devc); - - PMEM_CHECK (devc->recbuf_phys, devc->recbuffsize); - - OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Base */ - oss_udelay (20); - OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Base */ - oss_udelay (20); - OUTW (devc->osdev, devc->recbuffsize / 4 - 1, devc->mt_base + 0x24); /* Count */ - OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Base */ - oss_udelay (60); - OUTW (devc->osdev, devc->hw_rfragsize / 4 - 1, devc->mt_base + 0x26); /* Interrupt rate */ - - oss_udelay (60); -} - -void -envy24_launch_recording (envy24_devc * devc) -{ - -#if 1 - /* Unmask recording interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->mt_base + 0x00) & ~0x80, - devc->mt_base + 0x00); - -#endif - /* Kick it */ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) | 0x04, - devc->mt_base + 0x18); - devc->recording_started = 1; - mixer_devs[devc->mixer_dev]->modify_counter++; - -} - -void -envy24_stop_recording (envy24_devc * devc) -{ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04, - devc->mt_base + 0x18); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04, - devc->mt_base + 0x18); - - /* Mask recording interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->mt_base + 0x00) | 0x80, devc->mt_base + 0x00); - devc->recording_started = 0; - memset (devc->recbuf, 0, devc->recbuffsize); -} - -/* - * Audio entrypoint routines - */ - -int -envy24_audio_set_rate (int dev, int arg) -{ - envy24_devc *devc = audio_engines[dev]->devc; -#if 1 - int i = 0, ix = -1, df, best = 0x7fffffff; - oss_native_word flags; - - if (arg <= 0) - return devc->speed; - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - if (devc->recording_started || devc->playback_started) - { - DDB (cmn_err (CE_CONT, - "Requested sampling rate(1) on device %d was %d, got %d\n", - dev, arg, devc->speed)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return devc->speed; - } - - if ((devc->open_inputs + devc->open_outputs) > 1) - { - DDB (cmn_err (CE_CONT, - "Requested sampling rate(2) on device %d was %d, got %d\n", - dev, arg, devc->speed)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return devc->speed; - } - - if (devc->ratelock) - { - DDB (cmn_err (CE_CONT, - "Requested sampling rate(3) on device %d was %d, got %d\n", - dev, arg, devc->speed)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return devc->speed; - } - -/* This is the only open device file so change the speed */ - - i = 0; - - while (speed_tab[i].speed != -1) - { - df = arg - speed_tab[i].speed; - if (df < 0) - df = -df; - - if (df < best) - { - best = df; - ix = i; - if (df == 0) - break; - } - - i++; - } - - if (ix == -1) /* No matching rate */ - { - DDB (cmn_err (CE_CONT, - "Requested sampling rate(4) on device %d was %d, got %d\n", - dev, arg, devc->speed)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return devc->speed; - } - - devc->speed = speed_tab[ix].speed; - devc->speedbits = speed_tab[ix].speedbits; -#endif - if (devc->speed != arg) - { - DDB (cmn_err (CE_CONT, - "Requested sampling rate(5) on device %d was %d, got %d\n", - dev, arg, devc->speed)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return devc->speed; - } - DDB (cmn_err (CE_CONT, "Sampling rate set to %d\n", devc->speed)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return devc->speed; -} - -static void -update_fragments (envy24_portc * portc) -{ - int nsamples, nbytes, dev = portc->dev; - envy24_devc *devc = audio_engines[dev]->devc; - - nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */ - - nbytes = nsamples * portc->channels; - - if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3)) - { - nbytes *= 2; - } - else if (portc->bits & (AFMT_S32_LE | AFMT_S24_LE)) - nbytes *= 4; - - audio_engines[dev]->min_block = nbytes; - audio_engines[dev]->max_block = nbytes; -} - -static short -envy24_audio_set_channels (int dev, short arg) -{ - envy24_portc *portc = audio_engines[dev]->portc; - envy24_devc *devc = audio_engines[dev]->devc; - int i, nc = devc->nr_play_channels; - oss_native_word flags; - - if (envy24_virtualout) - nc = 10; - - if (arg <= portc->channels) - return portc->channels; - - /* Force mono->stereo conversion if in skip=2 mode */ - if (devc->skipdevs == 2 && arg < 2) - arg = 2; - - if (envy24_force_mono) - arg = 1; - - if (portc->direction == DIR_INPUT) - { - if ((portc->chnum + arg) > devc->nr_rec_channels) - return portc->channels; - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - for (i = portc->channels; i < arg; i++) - if (devc->rec_channel_mask & (1 << (portc->chnum + i))) - { - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return portc->channels; - } - for (i = portc->channels; i < arg; i++) - devc->rec_channel_mask |= (1 << (portc->chnum + i)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - } - else - { - if ((portc->chnum + arg) > nc) - return portc->channels; - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - for (i = portc->channels; i < arg; i++) - if (devc->play_channel_mask & (1 << (portc->chnum + i))) - { - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return portc->channels; - } - for (i = portc->channels; i < arg; i++) - devc->play_channel_mask |= (1 << (portc->chnum + i)); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - } - - portc->channels = arg; - update_fragments (portc); - - return portc->channels; -} - -static unsigned int -envy24_audio_set_format (int dev, unsigned int arg) -{ - envy24_portc *portc = audio_engines[dev]->portc; - - if (arg == 0) - return portc->bits; - - if (!(arg & audio_engines[dev]->oformat_mask)) - return portc->bits = AFMT_S16_LE; - - portc->bits = arg; - - if (arg == AFMT_AC3) - { - envy24_audio_set_channels (dev, 2); - } - - update_fragments (portc); - - return portc->bits; -} - -static int -envy24_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg) -{ - envy24_devc *devc = audio_engines[dev]->devc; - envy24_portc *portc = audio_engines[dev]->portc; - oss_native_word flags; - int rt; - - if (arg == NULL) - return OSS_EINVAL; - - switch (cmd) - { - case SNDCTL_DSP_GET_RECSRC: - case SNDCTL_DSP_SET_RECSRC: - case SNDCTL_DSP_GET_PLAYTGT: - case SNDCTL_DSP_SET_PLAYTGT: - return *arg = 0; - break; - - case SNDCTL_DSP_GET_RECSRC_NAMES: - return oss_encode_enum ((oss_mixer_enuminfo *) arg, portc->name, 0); - break; - - case SNDCTL_DSP_GET_PLAYTGT_NAMES: - return oss_encode_enum ((oss_mixer_enuminfo *) arg, portc->name, 0); - break; - - case SNDCTL_DSP_GET_CHNORDER: - *(oss_uint64_t *) arg = CHNORDER_UNDEF; - return 0; - } - - if (devc->model_data->auxdrv->spdif_ioctl == NULL) - return OSS_EINVAL; - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - rt = devc->model_data->auxdrv->spdif_ioctl (devc, dev, cmd, arg); - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return rt; -} - -static void envy24_audio_trigger (int dev, int state); - -static void -envy24_audio_reset (int dev) -{ -#ifdef DO_TIMINGS - oss_do_timing ("Envy24: Reset audio"); -#endif - envy24_audio_trigger (dev, 0); -} - -#define WriteCsByte(devc, b, v) (devc)->spdif_cbits[b]=(v) -#define ReadCsByte(devc, b) (devc)->spdif_cbits[b] - -static __inline__ void -WriteCsField (envy24_devc * devc, unsigned char bByteNum, - unsigned short bMask, unsigned short bBits) -{ - /* Get current reg value. */ - unsigned char bTemp = ReadCsByte (devc, bByteNum); - - /* Clear field to be written. */ - bTemp &= ~(bMask); - - /* Set new values. */ - WriteCsByte (devc, bByteNum, (unsigned char) (bTemp | (bBits & bMask))); -} - -static void -envy24_setup_pro_speed (envy24_devc * devc) -{ - - switch (devc->speed) - { - case 32000: - WriteCsField (devc, 0, 0xc0, 0xc0); - break; - - case 44100: - WriteCsField (devc, 0, 0xc0, 0x40); - break; - - case 48000: - WriteCsField (devc, 0, 0xc0, 0x80); - break; - - default: - WriteCsField (devc, 0, 0xc0, 0x00); - break; - } -} - -static void -setup_pro_mode (envy24_devc * devc) -{ - devc->spdif_cbits[0] |= 0x01; /* Pro mode */ - devc->spdif_cbits[2] |= 0x2c; /* 24-bit data word */ - - envy24_setup_pro_speed (devc); -} - -static void -envy24_setup_consumer_speed (envy24_devc * devc) -{ - - /* - * Set the sampling rate indication - */ - if (devc->ac3_mode) - WriteCsField (devc, 0, 0x02, 0x02); /* 1:1 = 1 */ - else - WriteCsField (devc, 0, 0x02, 0x00); /* 1:1 = 0 */ - - switch (devc->speed) - { - case 22050L: - WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */ - WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */ - WriteCsField (devc, 4, 0x0F, 0x09); /* 3:0 = 1001 */ - break; - case 32000L: - WriteCsField (devc, 0, 0xC0, 0xC0); /* 7:6 = 11 */ - WriteCsField (devc, 3, 0x0F, 0x03); /* 3:0 = 0011 */ - WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */ - break; - case 44100L: - WriteCsField (devc, 0, 0xC0, 0x40); /* 7:6 = 01 */ - WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */ - WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */ - break; - case 48000L: - WriteCsField (devc, 0, 0xC0, 0x80); /* 7:6 = 10 */ - WriteCsField (devc, 3, 0x0F, 0x02); /* 3:0 = 0010 */ - WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */ - break; - case 88200L: - WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */ - WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */ - WriteCsField (devc, 4, 0x0F, 0x05); /* 3:0 = 0101 */ - break; - case 96000L: - WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */ - WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */ - WriteCsField (devc, 4, 0x0F, 0x04); /* 3:0 = 0100 */ - break; - default: - WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */ - WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */ - WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */ - break; - } -} - -static void -setup_consumer_mode (envy24_devc * devc) -{ - WriteCsByte (devc, 0, ReadCsByte (devc, 0) & ~(0x02)); /* Set audio mode */ - WriteCsByte (devc, 0, ReadCsByte (devc, 0) & ~(0x38)); /* Set no emphasis */ - - WriteCsByte (devc, 0, ReadCsByte (devc, 0) & ~(0x04)); /* Set "original" */ - WriteCsByte (devc, 1, ReadCsByte (devc, 1) | (0x80)); /* Set "original" */ - - envy24_setup_consumer_speed (devc); -} - -static void -setup_spdif_control (envy24_devc * devc) -{ -/* unsigned char *cbits; */ - - memset (devc->spdif_cbits, 0, sizeof (devc->spdif_cbits)); - -/* cbits = devc->spdif_cbits; */ - - if (devc->spdif_pro_mode) - { - setup_pro_mode (devc); - } - else - { - setup_consumer_mode (devc); - } -} - -/*ARGSUSED*/ -static int -envy24_audio_open (int dev, int mode, int open_flags) -{ - envy24_portc *portc = audio_engines[dev]->portc; - envy24_devc *devc = audio_engines[dev]->devc; - oss_native_word flags; - - mode |= ADEV_NOVIRTUAL; - - if (devc->playbuf == NULL || devc->recbuf == NULL) - { - cmn_err (CE_WARN, "No DMA buffer\n"); - return OSS_ENOSPC; - } - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - if (portc->open_mode != 0 || devc->direct_audio_opened != 0) - { - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return OSS_EBUSY; - } - - if (portc->direction == DIR_INPUT) - { - if (devc->rec_channel_mask & (1 << portc->chnum)) - { - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return OSS_EBUSY; - } - devc->rec_channel_mask |= (1 << portc->chnum); - } - else - { - if (devc->play_channel_mask & (1 << portc->chnum)) - { - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return OSS_EBUSY; - } - devc->play_channel_mask |= (1 << portc->chnum); - } - - portc->open_mode = mode; - portc->channels = 1; - if (devc->skipdevs == 2) - portc->channels = 2; - portc->pcm_qlen = 0; - if (portc->direction == DIR_INPUT) - { - if (devc->open_inputs++ == 0 && devc->open_outputs == 0) - { - devc->speed = speed_tab[devc->pending_speed_sel].speed; - devc->speedbits = speed_tab[devc->pending_speed_sel].speedbits; - } - } - else - { - if (devc->open_inputs == 0 && devc->open_outputs++ == 0) - { - if (portc->flags & PORTC_SPDOUT) - { - setup_spdif_control (devc); - } - - devc->speed = speed_tab[devc->pending_speed_sel].speed; - devc->speedbits = speed_tab[devc->pending_speed_sel].speedbits; - } - } -#if 1 - if (devc->use_src) - { - /* SRC stuff */ - audio_engines[dev]->flags |= ADEV_FIXEDRATE; - audio_engines[dev]->fixed_rate = devc->speed; - audio_engines[dev]->min_rate = devc->speed; - audio_engines[dev]->max_rate = devc->speed; - } - else - { - audio_engines[dev]->flags &= ~ADEV_FIXEDRATE; - audio_engines[dev]->fixed_rate = 0; - audio_engines[dev]->min_rate = 8000; - audio_engines[dev]->max_rate = 96000; - } -#endif - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - - return 0; -} - -/*ARGSUSED*/ -static void -envy24_audio_close (int dev, int mode) -{ - envy24_devc *devc = audio_engines[dev]->devc; - envy24_portc *portc = audio_engines[dev]->portc; - oss_native_word flags; - - int i; - - envy24_audio_reset (dev); - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - portc->open_mode = 0; - if (portc->flags & PORTC_SPDOUT) - devc->ac3_mode = 0; - if (portc->direction == DIR_INPUT) - { - devc->open_inputs--; - for (i = 0; i < portc->channels; i++) - devc->rec_channel_mask &= ~(1 << (portc->chnum + i)); - } - else - { - devc->open_outputs--; - for (i = 0; i < portc->channels; i++) - devc->play_channel_mask &= ~(1 << (portc->chnum + i)); - } - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); -} - -/*ARGSUSED*/ -static void -envy24_audio_output_block (int dev, oss_native_word buf, int count, - int fragsize, int intrflag) -{ -} - -/*ARGSUSED*/ -static void -envy24_audio_start_input (int dev, oss_native_word buf, int count, - int fragsize, int intrflag) -{ -} - -static int -envy24_sync_control (int dev, int event, int mode) -{ - envy24_devc *devc = audio_engines[dev]->devc; - envy24_portc *portc = audio_engines[dev]->portc; - - if (event == SYNC_PREPARE) - { - if (mode & PCM_ENABLE_OUTPUT) - { - if (!devc->playback_prepared) - devc->hw_playfrag = 0; - handle_playdev (devc, portc, devc->hw_playfrag); - handle_playdev (devc, portc, devc->hw_playfrag + 1); - if (devc->writeahead == 2) - handle_playdev (devc, portc, devc->hw_playfrag + 2); - envy24_prepare_play_engine (devc); - portc->trigger_bits |= PCM_ENABLE_OUTPUT; - } - - if (mode & PCM_ENABLE_INPUT) - { - if (devc->active_inputs == 0) - { - envy24_start_recording (devc); - } - portc->trigger_bits |= PCM_ENABLE_INPUT; - } - return 0; - } - - if (event == SYNC_TRIGGER) - { - if (mode & PCM_ENABLE_OUTPUT) - { - envy24_prepare_play_engine (devc); /* Just to make sure */ - devc->hw_playfrag = 1 + devc->writeahead; - if (devc->active_outputs++ == 0) - envy24_launch_play_engine (devc); - } - - if (mode & PCM_ENABLE_INPUT) - { - if (devc->active_inputs++ == 0) - { - devc->hw_recfrag = 0; - envy24_launch_recording (devc); - } - } - return 0; - } - - return OSS_EIO; -} - -static void -envy24_audio_trigger (int dev, int state) -{ - int changed; - oss_native_word flags; - - envy24_portc *portc = audio_engines[dev]->portc; - envy24_devc *devc = audio_engines[dev]->devc; - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - changed = state ^ portc->trigger_bits; - - if (portc->direction == DIR_OUTPUT && (changed & PCM_ENABLE_OUTPUT)) - { - if (state & PCM_ENABLE_OUTPUT) - { -#ifdef DO_TIMINGS - oss_do_timing ("Envy24: Trigger start output"); -#endif - portc->trigger_bits = state; - if (devc->active_outputs++ == 0) - start_playback (devc); - } - else - { -#ifdef DO_TIMINGS - oss_do_timing ("Envy24: Trigger stop output"); -#endif - portc->trigger_bits = state; - if (--devc->active_outputs == 0) - envy24_stop_playback (devc); - } - } - - if (portc->direction == DIR_INPUT && (changed & PCM_ENABLE_INPUT)) - { - if (state & PCM_ENABLE_INPUT) - { - portc->trigger_bits = state; - if (devc->active_inputs++ == 0) - { - envy24_start_recording (devc); - envy24_launch_recording (devc); - } - } - else - { - if (--devc->active_inputs == 0) - envy24_stop_recording (devc); - portc->trigger_bits = state; - } - } - - portc->trigger_bits = state; - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); -} - -/*ARGSUSED*/ -static int -envy24_audio_prepare_for_input (int dev, int bsize, int bcount) -{ - int nsamples, nbytes; - - envy24_portc *portc = audio_engines[dev]->portc; - envy24_devc *devc = audio_engines[dev]->devc; - oss_native_word flags; - - if (audio_engines[dev]->flags & ADEV_NOINPUT) - return OSS_EACCES; - - nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */ - - nbytes = nsamples * portc->channels; - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); -#ifdef DO_RIAA - memset (portc->riaa_parms, 0, sizeof (portc->riaa_parms)); - if (portc->riaa_filter) - cmn_err (CE_CONT, "oss: RIAA filter activated for /dev/dsp%d\n", dev); -#endif - - if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3)) - { - nbytes *= 2; - } - else if (portc->bits & (AFMT_S32_LE | AFMT_S24_LE)) - nbytes *= 4; - - if (nbytes != bsize) - { - dmap_p dmap = audio_engines[dev]->dmap_in; - dmap->fragment_size = bsize = nbytes; - dmap->bytes_in_use = dmap->fragment_size * dmap->nfrags; - if (dmap->bytes_in_use > dmap->buffsize) - { - dmap->nfrags = dmap->buffsize / dmap->fragment_size; - dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size; - } - } - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return 0; -} - -/*ARGSUSED*/ -static int -envy24_audio_prepare_for_output (int dev, int bsize, int bcount) -{ - int nsamples, nbytes; - oss_native_word flags; - - envy24_portc *portc = audio_engines[dev]->portc; - envy24_devc *devc = audio_engines[dev]->devc; - - if (audio_engines[dev]->flags & ADEV_NOOUTPUT) - return OSS_EACCES; - - nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */ - - nbytes = nsamples * portc->channels; - - if (portc->flags & PORTC_SPDOUT) - if (portc->bits == AFMT_AC3) - devc->ac3_mode = 1; - - if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3)) - { - nbytes *= 2; - } - else if (portc->bits & (AFMT_S32_LE | AFMT_S32_BE)) - nbytes *= 4; - - MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); - if (nbytes != bsize) - { - dmap_p dmap = audio_engines[dev]->dmap_out; - cmn_err (CE_CONT, "Fragment size mismatch: hw=%d, sw=%d\n", - nbytes, bsize); - cmn_err (CE_NOTE, - "Application bug detected. Fix ioctl() calling order\n"); - - oss_audio_set_error (dev, E_PLAY, - OSSERR (1012, "Wrong ioctl call order"), 0); - /* - * Errordesc: The envy24 driver requires that number of channels, sample format and - * sampling rate are set before calling any ioctl call that may lock - * the fragment size prematurely. In such case the driver cannot change the - * fragment size to value that is suitable for the device. - * - * Please use the recommended ioctl call order defined in - * http://manuals.opensound.com/developer/callorder.html. - */ - dmap->fragment_size = bsize = nbytes; - dmap->bytes_in_use = dmap->fragment_size * dmap->nfrags; - if (dmap->bytes_in_use > dmap->buffsize) - { - dmap->nfrags = dmap->buffsize / dmap->fragment_size; - dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size; - } - - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return OSS_EIO; - } - MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); - return 0; -} - -/*ARGSUSED*/ -static int -envy24_alloc_buffer (int dev, dmap_t * dmap, int direction) -{ - envy24_devc *devc = audio_engines[dev]->devc; - - if (dmap->dmabuf != NULL) - return 0; - -#if 0 -/* - * Ignore the direction parameter since it's missleading. Instead use the - * ADEV_NOINPUT/ADEV_NOOUTPUT flag. - */ - - if (audio_engines[dev]->flags & ADEV_NOINPUT) - direction = OPEN_WRITE; - else - direction = OPEN_READ; -#endif - - dmap->buffsize = devc->skipdevs * DEV_BUFSIZE; - dmap->dmabuf_phys = 0; - dmap->dmabuf = KERNEL_MALLOC (dmap->buffsize); - - if (dmap->dmabuf == NULL) - { - cmn_err (CE_WARN, "Failed to allocate a DMA buffer\n"); - return OSS_ENOSPC; - } - memset (dmap->dmabuf, 0, dmap->buffsize); - return 0; -} - -/*ARGSUSED*/ -static int -envy24_free_buffer (int dev, dmap_t * dmap, int direction) -{ - if (dmap->dmabuf == NULL) - return 0; -#if 1 - KERNEL_FREE (dmap->dmabuf); -#endif - dmap->dmabuf = NULL; - return 0; -} - -static int -envy24_check_input (int dev) -{ - envy24_devc *devc = audio_engines[dev]->devc; - - if (!devc->recording_started) - return 0; - - cmn_err (CE_NOTE, "Input timed out.\n"); - return OSS_EIO; -} - -static int -envy24_check_output (int dev) -{ - envy24_devc *devc = audio_engines[dev]->devc; - - if (!devc->playback_started) - return 0; - - cmn_err (CE_NOTE, "Output timed out\n"); - return OSS_EIO; -} - -static int -envy24_local_qlen (int dev) -{ - envy24_portc *portc = audio_engines[dev]->portc; - - return portc->pcm_qlen * audio_engines[dev]->dmap_out->fragment_size; -} - -static const audiodrv_t envy24_audio_driver = { - envy24_audio_open, - envy24_audio_close, - envy24_audio_output_block, - envy24_audio_start_input, - envy24_audio_ioctl, - envy24_audio_prepare_for_input, - envy24_audio_prepare_for_output, - envy24_audio_reset, - envy24_local_qlen, - NULL, - NULL, - NULL, - envy24_audio_trigger, - envy24_audio_set_rate, - envy24_audio_set_format, - envy24_audio_set_channels, - NULL, - NULL, - envy24_check_input, - envy24_check_output, - envy24_alloc_buffer, - envy24_free_buffer, - NULL, - NULL, - NULL, /* envy24_get_buffer_pointer */ - NULL, /* calibrate_speed */ - envy24_sync_control -}; - -/*ARGSUSED*/ -static int -envy24_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg) -{ - extern int envy24_realencoder_hack; - - if (!envy24_realencoder_hack) - { - if (cmd == SOUND_MIXER_READ_DEVMASK || - cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC || - cmd == SOUND_MIXER_READ_STEREODEVS) - return *arg = 0; - } - - if (cmd == SOUND_MIXER_READ_DEVMASK || - cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC || - cmd == SOUND_MIXER_READ_STEREODEVS) - return *arg = - SOUND_MASK_LINE | SOUND_MASK_PCM | SOUND_MASK_MIC | - SOUND_MASK_VOLUME | SOUND_MASK_CD; - - if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM || - cmd == SOUND_MIXER_READ_LINE || cmd == SOUND_MIXER_READ_MIC || - cmd == SOUND_MIXER_READ_CD || cmd == MIXER_READ (SOUND_MIXER_DIGITAL1)) - return *arg = 100 | (100 << 8); - if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM || - cmd == SOUND_MIXER_WRITE_LINE || cmd == SOUND_MIXER_READ_MIC || - cmd == SOUND_MIXER_WRITE_CD || - cmd == MIXER_WRITE (SOUND_MIXER_DIGITAL1)) - return *arg = 100 | (100 << 8); - if (cmd == SOUND_MIXER_READ_CAPS) - return *arg = SOUND_CAP_EXCL_INPUT; - if (cmd == SOUND_MIXER_PRIVATE1) - return *arg = 0; - return OSS_EINVAL; -} - -static int -envy24_set_control (int dev, int ctrl, unsigned int cmd, int value) -{ - envy24_devc *devc = mixer_devs[dev]->devc; - - if (cmd == SNDCTL_MIX_READ) - switch (ctrl) - { - case 1: - return devc->pending_speed_sel; - break; - - case 2: - return devc->syncsource; - break; - - case 3: - return devc->use_src; - break; - - case 4: - { - int tmp = envy24_read_cci (devc, 0x20); - return !!(tmp & 0x10); - } - break; - - case 5: - return devc->ratelock; - break; - - case 6: - return devc->speed; - break; - - case 7: - return devc->sync_locked = - devc->model_data->auxdrv->get_locked_status (devc); - - default: - return OSS_EIO; - } - - if (cmd == SNDCTL_MIX_WRITE) - switch (ctrl) - { - case 1: - if (value < 0 || value > 12) - return OSS_EIO; - - if (value != devc->pending_speed_sel) - { - if (devc->open_inputs == 0 && devc->open_outputs == 0) /* IDDLE */ - OUTB (devc->osdev, value, devc->mt_base + 0x01); /* Make the change now */ - } - - return devc->pending_speed_sel = value; - break; - - case 2: - if (value < 0 || value > 2) - return OSS_EIO; - return devc->syncsource = value; - break; - - case 3: - return devc->use_src = value; - break; - - case 4: - { - int tmp = envy24_read_cci (devc, 0x20) & ~0x10; - if (value) - tmp |= 0x10; /* Optical */ - envy24_write_cci (devc, 0x20, tmp); - return !!(tmp & 0x10); - } - break; - - case 5: - return devc->ratelock = value; - break; - - case 6: - return devc->speed; - break; - - case 7: - return devc->sync_locked = - devc->model_data->auxdrv->get_locked_status (devc); - break; - - default: - return OSS_EIO; - } - - return OSS_EINVAL; -} - -static int -read_mon (envy24_devc * devc, int ch, int is_right) -{ - int tmp; - - if (ch >= 20) - return 0; - - OUTB (devc->osdev, ch, devc->mt_base + 0x3a); - tmp = INW (devc->osdev, devc->mt_base + 0x38); - - if (is_right) - tmp >>= 8; - tmp &= 0x7f; - if (tmp > 0x60) /* Mute? */ - return 0; - - tmp = (tmp * 15) / 10; - return 144 - tmp; -} - -static int -mon_scale (int v) -{ - if (v == 0) - return 0x7f; /* Mute */ - - v = 144 - v; - - v = (10 * v) / 15; - if (v > 0x60) - v = 0x7f; - return v; -} - -static void -mon_set (envy24_devc * devc, int ch, int left, int right) -{ - - left = mon_scale (left); - right = mon_scale (right); - - OUTB (devc->osdev, 1, devc->mt_base + 0x3b); /* Volume change rate */ - OUTB (devc->osdev, ch, devc->mt_base + 0x3a); - OUTW (devc->osdev, left | (right << 8), devc->mt_base + 0x38); -} - -static int -read_peak (envy24_devc * devc, int ch) -{ - int tmp; - - if (ch >= 22) - return 0; - - OUTB (devc->osdev, ch, devc->mt_base + 0x3e); - tmp = INB (devc->osdev, devc->mt_base + 0x3f); - - return tmp; -} - -/*ARGSUSED*/ -static int -envy24_get_peak (int dev, int ctrl, unsigned int cmd, int value) -{ - static const unsigned char peak_cnv[256] = { - 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72, - 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90, - 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101, - 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, - 108, - 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114, - 114, - 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119, - 119, - 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123, - 123, - 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126, - 126, - 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129, - 130, - 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132, - 132, - 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135, - 135, - 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137, - 137, - 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, - 139, - 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, - 141, - 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, - 143, - 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, - }; - - envy24_devc *devc = mixer_devs[dev]->devc; - - int i, orign, n = -1, left = 0, right = 0; - - for (i = 0; i < 12 && n == -1; i++) - if (ctrl & (1 << i)) - n = i; - - if (n == -1) - return OSS_EINVAL; - - orign = n; - if (ctrl & 0x80000000) - n += 10; /* Recording stream */ - - if (cmd == SNDCTL_MIX_READ) - { - left = read_peak (devc, n); - if (ctrl & (1 << (orign + 1))) /* Stereo mode? */ - right = read_peak (devc, n + 1); - else - right = left; - - left = peak_cnv[left]; - right = peak_cnv[right]; - return left | (right << 8); - } - - return OSS_EINVAL; -} - -static int -envy24_set_mon (int dev, int ctrl, unsigned int cmd, int value) -{ - envy24_devc *devc = mixer_devs[dev]->devc; - - int i, orign, n = -1, left = 0, right = 0; - - for (i = 0; i < 10 && n == -1; i++) - if (ctrl & (1 << i)) - n = i; - - if (n == -1) - return OSS_EINVAL; - - orign = n; - if (ctrl & 0x80000000) - n += 10; /* Recording stream */ - - if (cmd == SNDCTL_MIX_READ) - { - left = read_mon (devc, n, 0) * 10; - if (ctrl & (1 << (orign + 1))) /* Stereo mode? */ - right = read_mon (devc, n + 1, 1) * 10; - else - right = read_mon (devc, n, 1) * 10; - - return left | (right << 16); - } - else if (cmd == SNDCTL_MIX_WRITE) - { - left = value & 0xffff; - right = (value >> 16) & 0xffff; - - if (right > 1440) - right = 1440; - if (left > 1440) - left = 1440; - - if (ctrl & (1 << (orign + 1))) /* Stereo mode? */ - { - mon_set (devc, n, left / 10, 0); - mon_set (devc, n + 1, 0, right / 10); - } - else - { - mon_set (devc, n, left / 10, right / 10); - } - return left | (right << 16); - } - return OSS_EINVAL; -} - -static int -get_loopback (envy24_devc * devc, int ch) -{ - int tmp; - - tmp = INL (devc->osdev, devc->mt_base + 0x34); - return (tmp >> (4 * ch)) & 0x07; -} - -static int -get_spdif_loopback (envy24_devc * devc, int ch) -{ - int tmp; - - tmp = INL (devc->osdev, devc->mt_base + 0x34); - return (tmp >> ((4 * ch) + 3)) & 0x01; -} - -static void -set_loopback (envy24_devc * devc, int ch, int val) -{ - int tmp = INL (devc->osdev, devc->mt_base + 0x34); - tmp &= ~(0x07 << (4 * ch)); - tmp |= (val & 0x07) << (4 * ch); - OUTL (devc->osdev, tmp, devc->mt_base + 0x34); -} - -static void -set_spdif_loopback (envy24_devc * devc, int ch, int val) -{ - int tmp = INL (devc->osdev, devc->mt_base + 0x34); - tmp &= ~(0x08 << (4 * ch)); - tmp |= (val & 0x01) << ((4 * ch) + 3); - OUTL (devc->osdev, tmp, devc->mt_base + 0x34); -} - -static int -envy24_set_outrout (int dev, int ctrl, unsigned int cmd, int value) -{ - envy24_devc *devc = mixer_devs[dev]->devc; - int tmp, i; - - if (cmd == SNDCTL_MIX_READ) - { - tmp = INW (devc->osdev, devc->mt_base + 0x30); - - for (i = 0; i < 8; i++) - if (ctrl & (1 << i)) - { - tmp = (tmp >> (2 * i)) & 0x03; - switch (tmp) - { - case 0: /* DMA */ - return 0; - break; - - case 1: /* Monitor */ - return 1; - break; - - case 2: /* Analog input loopback */ - return 2 + get_loopback (devc, i); - break; - - case 3: /* S/PDIF input loopback */ - return 10 + get_spdif_loopback (devc, i); - break; - } - } - - return OSS_EINVAL; - } - else if (cmd == SNDCTL_MIX_WRITE) - { - tmp = INW (devc->osdev, devc->mt_base + 0x30); - for (i = 0; i < 8; i++) - if (ctrl & (1 << i)) - { - int ch; - ch = i / 2; - if (i & 1) - ch += 4; - - tmp &= ~(0x03 << (ch * 2)); /* Cleanup */ - - if (value == 0) /* DMA */ - continue; - - if (value == 1) /* Monitor */ - { - tmp |= 1 << (ch * 2); - continue; - } - - if (value < 10) /* Analog inputs */ - { - tmp |= 2 << (ch * 2); - set_loopback (devc, i, value - 2); - continue; - } - - tmp |= 3 << (ch * 2); - set_spdif_loopback (devc, i, value - 10); - } - - OUTW (devc->osdev, tmp, devc->mt_base + 0x30); - return value; - } - return OSS_EINVAL; -} - -static int -envy24_set_stereo_outrout (int dev, int ctrl, unsigned int cmd, int value) -{ - envy24_devc *devc = mixer_devs[dev]->devc; - int tmp, i; - - if (cmd == SNDCTL_MIX_READ) - { - tmp = INW (devc->osdev, devc->mt_base + 0x30); - - for (i = 0; i < 8; i++) - if (ctrl & (1 << i)) - { - int ch; - ch = i / 2; - if (i & 1) - ch += 4; - tmp = (tmp >> (2 * ch)) & 0x03; - switch (tmp) - { - case 0: /* DMA */ - return 0; - break; - - case 1: /* Monitor */ - return 1; - break; - - case 2: /* Analog input loopback */ - return 2 + get_loopback (devc, i) / 2; - break; - - case 3: /* S/PDIF input loopback */ - return 6; - break; - } - } - - return OSS_EINVAL; - } - else if (cmd == SNDCTL_MIX_WRITE) - { - tmp = INW (devc->osdev, devc->mt_base + 0x30); - for (i = 0; i < 8; i++) - if (ctrl & (1 << i)) - { - int ch; - ch = i / 2; - if (i & 1) - ch += 4; - - tmp &= ~(0x03 << (ch * 2)); /* Cleanup */ - - if (value == 0) /* DMA */ - { - continue; - } - - if (value == 1) /* Monitor */ - { - tmp |= 1 << (ch * 2); - continue; - } - - if (value < 6) /* Analog inputs */ - { - tmp |= 2 << (ch * 2); - set_loopback (devc, i, (value - 2) * 2 + (i & 1)); - continue; - } - - tmp |= 3 << (ch * 2); /* S/PDIF */ - set_spdif_loopback (devc, i, (value - 10) + (i & 1)); - continue; - } - - OUTW (devc->osdev, tmp, devc->mt_base + 0x30); - return value; - } - return OSS_EINVAL; -} - -static int -read_spdif_stereo (envy24_devc * devc) -{ - int tmp; - tmp = INL (devc->osdev, devc->mt_base + 0x32); - -/* - * Look only at the left channel. Assume the same settings on right. - */ - - switch (tmp & 0x03) - { - case 0: /* From DMA */ - return 0; - break; - - case 1: /* From digital mixer */ - return 1; - break; - - case 2: /* Analog input # loopback */ - return 2 + ((tmp >> 9) & 0x03); - break; - - case 3: /* S/PDIF input loopback */ - return 6; - break; - } - - return 0; -} - -static int -read_spdif_mono (envy24_devc * devc, int ch) -{ - int tmp, v; - tmp = INL (devc->osdev, devc->mt_base + 0x32); - - if (ch == 0) /* Left channel ? */ - v = (tmp) & 0x03; - else - v = (tmp >> 2) & 0x03; - - switch (v) - { - case 0: /* DMA */ - return 0; - break; - - case 1: /* Monitor */ - return 1; - break; - - case 2: /* Analog input */ - if (ch == 0) /* Left or right */ - v = (tmp >> 8) & 0x07; - else - v = (tmp >> 12) & 0x07; - - return 2 + v; - break; - - case 3: - if (ch == 0) /* Left or right */ - v = (tmp >> 11) & 0x01; - else - v = (tmp >> 15) & 0x01; - return 10 + v; - break; - - } - - return 0; -} - -static int -write_spdif_mono (envy24_devc * devc, int ch, int val) -{ - int tmp = 0, v; - tmp = INW (devc->osdev, devc->mt_base + 0x32); - - if (val == 0) /* DMA */ - { - if (ch == 0) /* Left */ - tmp &= ~0x0003; - else - tmp &= ~0x000c; - goto do_ne; - } - - if (val == 1) /* Monitor */ - { - if (ch == 0) /* Left */ - { - tmp &= ~0x0003; - tmp |= 0x0001; - } - else - { - tmp &= ~0x000c; - tmp |= 0x0004; - } - goto do_ne; - } - - if (val < 10) /* Analog inputs */ - { - v = (val - 2) & 0x07; - - if (ch == 0) /* Left */ - { - tmp &= ~(0x0003 | (0x07 << 8)); - tmp |= 0x02 | (v << 8); - } - else - { - tmp &= ~(0x000c | (0x07 << 12)); - tmp |= 0x08 | (v << 12); - } - goto do_ne; - } - - /* Else S/PDIF */ - - if (ch == 0) /* Left */ - { - tmp &= ~(1 << 11); - tmp |= 0x0003; - - if (val == 11) - tmp |= 1 << 11; - } - else - { - tmp &= ~(1 << 15); - tmp |= 0x000c; - - if (val == 11) - tmp |= 1 << 15; - } - -do_ne: - OUTW (devc->osdev, tmp, devc->mt_base + 0x32); - return val; -} - -static int -write_spdif_stereo (envy24_devc * devc, int val) -{ - int tmp = 0, v; - - if (val == 0) /* DMA */ - { - tmp = 0x0000; - goto do_ne; - } - - if (val == 1) /* Monitor */ - { - tmp = 0x0005; - goto do_ne; - } - - if (val < 6) /* Analog inputs */ - { - tmp = 0x000a; - - v = (val - 2) * 2; - tmp |= (v << 8); - tmp |= ((v + 1) << 12); - goto do_ne; - } - - /* Else S/PDIF */ - - tmp = 0x800f; - -do_ne: - OUTW (devc->osdev, tmp, devc->mt_base + 0x32); - return val; -} - -static int -envy24_set_spdifrout (int dev, int ctrl, unsigned int cmd, int value) -{ - envy24_devc *devc = mixer_devs[dev]->devc; - - if (cmd == SNDCTL_MIX_READ) - { - if (ctrl == 3) - return read_spdif_stereo (devc); - else - return read_spdif_mono (devc, ctrl - 1); - } - else if (cmd == SNDCTL_MIX_WRITE) - { - if (ctrl == 3) - return write_spdif_stereo (devc, value); - else - return write_spdif_mono (devc, ctrl - 1, value); - } - return OSS_EINVAL; -} - -/*ARGSUSED*/ -static int -create_output_mixer (int dev, envy24_devc * devc, int root) -{ - int i, mask = devc->outportmask, group, err, num, skip; - char tmp[64]; - - int nc = devc->nr_play_channels; - - if (envy24_virtualout) - { - mask = 0; - nc = 10; - for (i = 0; i < nc; i++) - mask |= (1 << i); - } - - if ((group = mixer_ext_create_group (dev, 0, "ENVY24_OUTPUT")) < 0) - return group; - - skip = devc->skipdevs; - if (skip != 2) - skip = 1; - - for (i = 0; i < nc; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - sprintf (tmp, "@pcm%d", devc->play_portc[i / 2].dev); - - num |= 1 << (i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_MONVOL | - MIXF_READABLE | - MIXF_WRITEABLE | MIXF_CENTIBEL)) < - 0) - return err; - if ((err = mixer_ext_create_control (dev, group, - num, envy24_get_peak, - MIXT_STEREOPEAK, - "-", 144, - MIXF_READABLE | MIXF_DECIBEL)) < 0) - return err; - } - - return 0; -} - -/*ARGSUSED*/ -static int -create_input_mixer (int dev, envy24_devc * devc, int root) -{ - int i, mask = devc->inportmask, group, err, num, skip; - char tmp[64]; - - if ((group = mixer_ext_create_group (dev, 0, "ENVY24_INPUT")) < 0) - return group; - - skip = devc->skipdevs; - if (skip != 2) - skip = 1; - - for (i = 0; i < devc->nr_rec_channels && i < 10; i += skip) - { - - num = (1 << i); - if (!(mask & num)) - continue; /* Not present */ - - num |= 0x80000000; /* Input flag */ - - if (i == 8) - strcpy (tmp, "ENVY24_SPDIN"); - else - sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2); - - num |= (1 << (i + 1)); - - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_MONVOL | - MIXF_READABLE | - MIXF_WRITEABLE | MIXF_CENTIBEL)) < - 0) - return err; - - if ((err = mixer_ext_create_control (dev, group, - num, envy24_get_peak, - MIXT_STEREOPEAK, - "-", 144, - MIXF_READABLE | MIXF_DECIBEL)) < 0) - return err; - } - - num = (1 << 11); - - if ((err = mixer_ext_create_control (dev, group, - num, envy24_get_peak, - MIXT_STEREOPEAK, - "MONITOR", 144, - MIXF_READABLE | MIXF_DECIBEL)) < 0) - return err; - return 0; -} - -/*ARGSUSED*/ -static int -create_mon_mixer (int dev, envy24_devc * devc, int root) -{ - int i, mask = devc->outportmask, group, err, num, skip; - char tmp[64]; - - int nc = devc->nr_play_channels; - - if (envy24_virtualout) - { - mask = 0; - nc = 10; - for (i = 0; i < nc; i++) - mask |= (1 << i); - } - - if ((group = mixer_ext_create_group (dev, 0, "ENVY24_MON")) < 0) - return group; - - skip = devc->skipdevs; - if (skip != 2) - skip = 1; - - for (i = 0; i < nc; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - if (devc->skipdevs == 2) - { - if (i == 8) - strcpy (tmp, "ENVY24_SPDOUT"); - else - sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2); - - num |= 1 << (i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_MONVOL | - MIXF_READABLE | - MIXF_WRITEABLE | - MIXF_CENTIBEL)) < 0) - return err; - } - else - { - if (i == 8) - strcpy (tmp, "ENVY24_SPDOUTL"); - else if (i == 9) - strcpy (tmp, "ENVY24_SPDOUTR"); - else - sprintf (tmp, "ENVY24_OUT%d", i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_MONVOL | - MIXF_READABLE | - MIXF_WRITEABLE | - MIXF_CENTIBEL)) < 0) - return err; - } - } - - mask = devc->inportmask; - for (i = 0; i < devc->nr_rec_channels && i < 10; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - num |= 0x80000000; /* Input flag */ - - if (devc->skipdevs == 2) - { - if (i == 8) - strcpy (tmp, "ENVY24_SPDIN"); - else - sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2); - - num |= 1 << (i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_MONVOL | - MIXF_READABLE | - MIXF_WRITEABLE | - MIXF_CENTIBEL)) < 0) - return err; - } - else - { - if (i == 8) - strcpy (tmp, "ENVY24_SPDINL"); - else if (i == 9) - strcpy (tmp, "ENVY24_SPDINR"); - else - sprintf (tmp, "ENVY24_IN%d", i + 1); - - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_MONVOL | - MIXF_READABLE | - MIXF_WRITEABLE | - MIXF_CENTIBEL)) < 0) - return err; - } - } - - return 0; -} - -/*ARGSUSED*/ -static int -create_peak_mixer (int dev, envy24_devc * devc, int root) -{ - int i, mask = devc->outportmask, group, err, num, skip; - int nc = devc->nr_play_channels; - char tmp[64]; - - if ((group = mixer_ext_create_group (dev, 0, "ENVY24_PEAK")) < 0) - return group; - - skip = 2; - - for (i = 0; i < nc; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - { - if (i == 8) - strcpy (tmp, "ENVY24_SPDOUT"); - else - sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2); - - num |= 1 << (i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_get_peak, - MIXT_STEREOPEAK, - tmp, 144, - MIXF_READABLE | MIXF_DECIBEL)) < - 0) - return err; - } - } - - mask = devc->inportmask; - for (i = 0; i < devc->nr_rec_channels; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - num |= 0x80000000; /* Input flag */ - - { - if (i == 8) - strcpy (tmp, "ENVY24_SPDIN"); - else if (i == 10) - strcpy (tmp, "ENVY24_MAIN"); - else - sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2); - - num |= 1 << (i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_get_peak, - MIXT_STEREOPEAK, - tmp, 144, - MIXF_READABLE | MIXF_DECIBEL)) < - 0) - return err; - } - } - - return 0; -} - -void -envy24_set_enum_mask (int dev, int ctl, oss_native_word mask) -{ - oss_mixext *ext; - int i; - - ext = mixer_find_ext (dev, ctl); - - if (ext == NULL) - { - cmn_err (CE_WARN, "Cannot locate the mixer extension\n"); - return; - } - - memset (ext->enum_present, 0, sizeof (ext->enum_present)); - - for (i = 0; i < 32; i++) - if (mask & (1 << i)) - ext->enum_present[i / 8] |= (1 << (i % 8)); -} - -/*ARGSUSED*/ -static int -create_rout_mixer (int dev, envy24_devc * devc, int root) -{ - int i, mask = devc->outportmask, group, err, skip, num, chnum; - char tmp[64]; - - if ((group = - mixer_ext_create_group_flags (dev, 0, "ENVY24_ROUTE", MIXF_FLAT)) < 0) - return group; - - skip = devc->skipdevs; - if (skip != 2) - skip = 1; - - for (i = 0; i < 8; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - if (devc->skipdevs == 2) - { - oss_native_word tmpmask = 0x00000001; - int j; - - if (i < 2) - tmpmask |= 0x00000002; - for (j = 0; j < 8; j++) - if (mask & (1 << j)) - tmpmask |= 1 << ((j / 2) + 2); - if (devc->model_data->flags & MF_SPDIF) - tmpmask |= 0x00000040; - - sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2); - chnum = i; - num = (1 << chnum) | (1 << (chnum + 1)); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_stereo_outrout, - MIXT_ENUM, - tmp, 7, - MIXF_READABLE | - MIXF_WRITEABLE)) < 0) - return err; - envy24_set_enum_mask (dev, err, tmpmask); - } - else - { - oss_native_word tmpmask = 0x00000001; - int j; - - sprintf (tmp, "ENVY24_OUT%d", i + 1); - chnum = i; - num = 1 << chnum; - - if (i < 2) - tmpmask |= (1 << 1); - for (j = 0; j < 8; j++) - if (mask & (1 << j)) - tmpmask |= 1 << (j + 2); - if (devc->model_data->flags & MF_SPDIF) - tmpmask |= (3 << 10); - - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_outrout, - MIXT_ENUM, - tmp, 12, - MIXF_READABLE | - MIXF_WRITEABLE)) < 0) - return err; - envy24_set_enum_mask (dev, err, tmpmask); - } - } - - mask = devc->inportmask; - - if (devc->model_data->flags & MF_SPDIF) - { - if (devc->skipdevs == 2) - { - oss_native_word tmpmask = 0x00000043; - int j; - for (j = 0; j < 8; j++) - if (mask & (1 << j)) - tmpmask |= (1 << ((j / 2) + 2)); - - if ((err = mixer_ext_create_control (dev, group, - 3, envy24_set_spdifrout, - MIXT_ENUM, - "ENVY24_SPDIF", 7, - MIXF_READABLE | - MIXF_WRITEABLE)) < 0) - return err; - envy24_set_enum_mask (dev, err, tmpmask); - } - else - { - oss_native_word tmpmask = 0x00000c03; - int j; - for (j = 0; j < 8; j++) - if (mask & (1 << j)) - tmpmask |= (1 << (j + 2)); - - if ((err = mixer_ext_create_control (dev, group, - 1, envy24_set_spdifrout, - MIXT_ENUM, - "ENVY24_SPDIFL", 12, - MIXF_READABLE | - MIXF_WRITEABLE)) < 0) - return err; - envy24_set_enum_mask (dev, err, tmpmask); - - if ((err = mixer_ext_create_control (dev, group, - 2, envy24_set_spdifrout, - MIXT_ENUM, - "ENVY24_SPDIFR", 12, - MIXF_READABLE | - MIXF_WRITEABLE)) < 0) - return err; - envy24_set_enum_mask (dev, err, tmpmask); - } - } - -#if 0 - for (i = 0; i < devc->nr_rec_channels && i < 10; i += skip) - { - - num = 1 << i; - if (!(mask & num)) - continue; /* Not present */ - - num |= 0x80000000; /* Input flag */ - - if (devc->skipdevs == 2) - { - sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2); - num |= 1 << (i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_READABLE | - MIXF_WRITEABLE | - MIXF_CENTIBEL)) < 0) - return err; - } - else - { - sprintf (tmp, "ENVY24_IN%d", i + 1); - if ((err = mixer_ext_create_control (dev, group, - num, envy24_set_mon, - MIXT_STEREOSLIDER16, - tmp, 1440, - MIXF_READABLE | - MIXF_WRITEABLE | - MIXF_CENTIBEL)) < 0) - return err; - } - } -#endif - - return 0; -} - -static int -envy24_mix_init (int dev) -{ - envy24_devc *devc = mixer_devs[dev]->devc; - int group, err, ctl; - int n; - - extern int envy24_mixerstyle; - - if ((group = mixer_ext_create_group (dev, 0, "ENVY24")) < 0) - return group; - - if (envy24_skipdevs == 2) - switch (envy24_mixerstyle) - { - case 2: - /* New style input and output mixer sections */ - if ((err = create_output_mixer (dev, devc, group)) < 0) - return err; - if ((err = create_input_mixer (dev, devc, group)) < 0) - return err; - break; - - default: - /* Traditional mixer (peak meters and montor gains separated) */ - if ((err = create_peak_mixer (dev, devc, group)) < 0) - return err; - if ((err = create_mon_mixer (dev, devc, group)) < 0) - return err; - break; - } - - if ((err = create_rout_mixer (dev, devc, group)) < 0) - return err; - - if (devc->model_data->auxdrv->mixer_init) - if ((err = devc->model_data->auxdrv->mixer_init (devc, dev, group)) < 0) - return err; - - if ((err = mixer_ext_create_control (dev, group, - 1, envy24_set_control, - MIXT_ENUM, - "ENVY24_RATE", 12, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - mixer_ext_set_strings (dev, err, - "8000 9600 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000", 0); - - if (devc->model_data->flags & (MF_SPDIF | MF_WCLOCK)) - { - n = 2; - if (devc->model_data->flags & MF_WCLOCK) - n = 3; - if ((err = mixer_ext_create_control (dev, group, - 2, envy24_set_control, - MIXT_ENUM, - "ENVY24_SYNC", n, - MIXF_READABLE | MIXF_WRITEABLE)) < - 0) - return err; - } - - if (devc->model_data->flags & MF_SPDSELECT) - { - if ((err = mixer_ext_create_control (dev, group, - 4, envy24_set_control, - MIXT_ENUM, - "ENVY24_SPDIN", 2, - MIXF_READABLE | MIXF_WRITEABLE)) < - 0) - return err; - } - -#if 0 -/* Always on */ - if ((err = mixer_ext_create_control (dev, group, - 3, envy24_set_control, - MIXT_ONOFF, - "ENVY24_SRC", 2, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; -#endif - - if ((err = mixer_ext_create_control (dev, group, - 5, envy24_set_control, - MIXT_ONOFF, - "ENVY24_RATELOCK", 2, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - - if ((ctl = mixer_ext_create_control (dev, group, - 6, envy24_set_control, - MIXT_VALUE, - "ENVY24_ACTRATE", 96000, - MIXF_READABLE)) < 0) - return ctl; - mixer_ext_set_description(dev, ctl, "Sample rate currently used by the device"); - -#if 1 - if (devc->model_data->auxdrv->get_locked_status) - { - devc->sync_locked = devc->model_data->auxdrv->get_locked_status (devc); - - if ((err = mixer_ext_create_control (dev, group, - 7, envy24_set_control, - MIXT_ONOFF, - "ENVY24_LOCKED", 1, - MIXF_READABLE)) < 0) - return err; - } -#endif - - if (devc->model_data->auxdrv->spdif_mixer_init) - if ((err = - devc->model_data->auxdrv->spdif_mixer_init (devc, dev, group)) < 0) - return err; - return 0; -} - -static mixer_driver_t envy24_mixer_driver = { - envy24_mixer_ioctl -}; - -static int -install_adev (envy24_devc * devc, char *name, int flags, int skip, - int portc_flags, char *port_id, char *devfile_name) -{ - int dev, i; - adev_p adev; - int fmts = 0, last; - extern int envy24_realencoder_hack; - - if (portc_flags & PORTC_SPDOUT) - fmts |= AFMT_AC3; - - if ((dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION, - devc->osdev, - devc->osdev, - name, - &envy24_audio_driver, - sizeof (audiodrv_t), - ADEV_AUTOMODE | ADEV_NOMMAP | - flags | ADEV_NOVIRTUAL, - fmts | AFMT_S16_LE | AFMT_S32_LE | - AFMT_S24_LE, devc, -1, - devfile_name)) < 0) - { - dev = -1; - return 0; - } - else - { - envy24_portc *portc; - adev = audio_engines[dev]; - - if (devc->first_dev == -1) - devc->first_dev = dev; - for (i = 0; speed_tab[i].speed != -1; i++) - adev->rates[adev->nrates++] = speed_tab[i].speed; - - adev->vmix_flags = 0; - - if (flags == DIR_OUTPUT) - { - last = 10; - audio_engines[dev]->port_number = devc->curr_outch; - audio_engines[dev]->min_rate = 8000; - audio_engines[dev]->max_rate = 96000; - portc = &devc->play_portc[devc->nr_outdevs++]; - portc->chnum = devc->curr_outch; - strncpy (portc->name, port_id, sizeof (portc->name) - 1); - portc->name[sizeof (portc->name) - 1] = 0; - devc->curr_outch += skip; - if (portc_flags & PORTC_SPDOUT) - audio_engines[dev]->caps |= PCM_CAP_DIGITALOUT; - if (portc_flags & PORTC_SPDIN) - audio_engines[dev]->caps |= PCM_CAP_DIGITALIN; - - } - else - { - last = 12; - portc = &devc->rec_portc[devc->nr_indevs++]; - audio_engines[dev]->port_number = devc->curr_inch + 10; - portc->chnum = devc->curr_inch; - strncpy (portc->name, port_id, sizeof (portc->name) - 1); - portc->name[sizeof (portc->name) - 1] = 0; - devc->curr_inch += skip; -#ifdef DO_RIAA - portc->riaa_filter = 0; -#endif - } - - portc->flags = portc_flags; - audio_engines[dev]->devc = devc; - audio_engines[dev]->portc = portc; - audio_engines[dev]->rate_source = devc->first_dev; - - switch (skip) - { - case 1: - audio_engines[dev]->caps |= DSP_CH_MONO; - audio_engines[dev]->min_channels = 1; - audio_engines[dev]->max_channels = - (envy24_force_mono) ? 1 : last - portc->chnum; - break; - - case 2: - audio_engines[dev]->caps |= DSP_CH_STEREO; - audio_engines[dev]->min_channels = 1; - audio_engines[dev]->max_channels = last - portc->chnum; - break; - - default: - audio_engines[dev]->caps |= DSP_CH_MULTI; - audio_engines[dev]->min_channels = 1; - audio_engines[dev]->max_channels = last - portc->chnum; - } - - audio_engines[dev]->mixer_dev = devc->mixer_dev; - portc->dev = dev; - portc->open_mode = 0; - portc->is_active = 0; - portc->direction = flags; - portc->trigger_bits = 0; - - if (envy24_realencoder_hack && flags == DIR_INPUT - && devc->nr_indevs > 1) - if (oss_install_mixer (OSS_MIXER_DRIVER_VERSION, - devc->osdev, - devc->osdev, - "Dummy mixer", - &envy24_mixer_driver, - sizeof (mixer_driver_t), devc) >= 0) - { - mixer_devs[devc->mixer_dev]->priority = -1; /* Don't use as the default mixer */ - } - } - - return 1; -} - -static int -install_output_devices (envy24_devc * devc, int mask) -{ - char tmp[512], id[32]; - int i, nc, portc_flags = 0; - - char *lr = "", *kind; - - nc = devc->nr_play_channels = MAX_ODEV; - devc->nr_rec_channels = MAX_IDEV; - - if (devc->skipdevs < 1) - devc->skipdevs = 1; - - for (i = 0; i < nc; i += devc->skipdevs) - { - char *devfile_name = ""; - - if (devc->skipdevs != 2) - lr = (i & 1) ? "R" : "L"; - kind = ""; - - if (!(mask & (1 << devc->curr_outch))) - kind = "(virtual) "; - - switch (devc->curr_outch) - { - case 8: - case 9: - portc_flags = PORTC_SPDOUT; - sprintf (tmp, "%s %sS/PDIF out %s", devc->model_data->product, kind, - lr); - sprintf (id, "SPDIF%s", lr); - devfile_name = "spdout"; - break; - - default: - if (devc->skipdevs > 1) - { - sprintf (tmp, "%s %sout%d/%d", devc->model_data->product, kind, - i + 1, i + devc->skipdevs); - sprintf (id, "OUT%d/%d", i + 1, i + devc->skipdevs); - } - else - { - sprintf (tmp, "%s %sout%d", devc->model_data->product, kind, - i + 1); - sprintf (id, "OUT%d", i + 1); - } - } - - if (mask & (1 << devc->curr_outch)) - install_adev (devc, tmp, ADEV_NOINPUT, devc->skipdevs, portc_flags, - id, devfile_name); - else - devc->curr_outch += devc->skipdevs; - } - - return 1; -} - -/*ARGSUSED*/ -static int -install_virtual_output_devices (envy24_devc * devc, int mask) -{ -#if 0 - char tmp[512]; - int i, nc; - - char *lr = ""; - nc = devc->nr_play_channels = MAX_ODEV; - devc->nr_rec_channels = MAX_IDEV; - - if (envy24_virtualout) - { - nc = 10; - } - - if (devc->skipdevs < 1) - devc->skipdevs = 1; - - for (i = 0; i < nc; i += devc->skipdevs) - { - - if (devc->skipdevs != 2) - lr = (i & 1) ? "R" : "L"; - - switch (devc->curr_outch) - { - case 8: - case 9: - sprintf (tmp, "%s virtual out %s", devc->model_data->product, lr); - break; - - default: - if (devc->skipdevs > 1) - sprintf (tmp, "%s virtual out%d/%d", devc->model_data->product, - i + 1, i + devc->skipdevs); - else - sprintf (tmp, "%s virtual out%d", devc->model_data->product, - i + 1); - } - - if (!(mask & (1 << devc->curr_outch))) /* Not done yet */ - install_adev (devc, tmp, ADEV_NOINPUT, devc->skipdevs, 0, "virtual", ""); // TODO: Find better device file name - else - devc->curr_outch += devc->skipdevs; - } -#endif - return 1; -} - -static int -install_input_devices (envy24_devc * devc, int mask) -{ - char tmp[512], id[32]; - int i, portc_flags = 0; - - char *lr = ""; - - devc->nr_play_channels = MAX_ODEV; - devc->nr_rec_channels = MAX_IDEV; - - if (devc->skipdevs < 1) - devc->skipdevs = 1; - - for (i = 0; i < devc->nr_rec_channels; i += devc->skipdevs) - { - char *devfile_name = ""; - - if (devc->skipdevs != 2) - lr = (i & 1) ? "R" : "L"; - - switch (devc->curr_inch) - { - case 8: - case 9: - portc_flags = PORTC_SPDIN; - sprintf (tmp, "%s S/PDIF in %s", devc->model_data->product, lr); - sprintf (id, "SPDIF%s", lr); - devfile_name = "spdin"; - break; - - case 10: - case 11: - sprintf (tmp, "%s input from mon. mixer %s", - devc->model_data->product, lr); - sprintf (id, "MON%s", lr); - devfile_name = "mon"; - break; - - default: - if (devc->skipdevs > 1) - { - sprintf (tmp, "%s in%d/%d", devc->model_data->product, i + 1, - i + devc->skipdevs); - sprintf (id, "IN%d/%d", i + 1, i + devc->skipdevs); - } - else - { - sprintf (tmp, "%s in%d", devc->model_data->product, i + 1); - sprintf (id, "IN%d", i + 1); - } - } - - if (mask & (1 << devc->curr_inch)) - install_adev (devc, tmp, ADEV_NOOUTPUT, devc->skipdevs, portc_flags, - id, devfile_name); - else - devc->curr_inch += devc->skipdevs; - } - - OUTL (devc->osdev, 0x00224466, devc->mt_base + 0x34); /* 1 to 1 input routing */ - - return 1; -} - -static int -install_audio_devices (envy24_devc * devc) -{ - extern int envy24_swapdevs; - int maskout, maskin, i; -#define setmask(m, b) m|=(1<<(b)) - - maskout = maskin = 0; - - if (envy24_devmask == 0) - envy24_devmask = 65535; - - if (envy24_devmask & DMASK_MONITORIN) - { - setmask (maskin, 10); /* Monitor input left */ - setmask (maskin, 11); /* Monitor input right */ - } - - if (devc->model_data->flags & MF_SPDIF) - { - if (envy24_devmask & DMASK_SPDIFIN) - { - setmask (maskin, 8); /* S/PDIF left */ - setmask (maskin, 9); /* S/PDIF right */ - } - - if (envy24_devmask & DMASK_SPDIFOUT) - { - setmask (maskout, 8); /* S/PDIF left */ - setmask (maskout, 9); /* S/PDIF right */ - } - if (devc->model_data->auxdrv->spdif_set) - devc->model_data->auxdrv->spdif_set (devc, 0x20); - } - - if (envy24_devmask & DMASK_ANALOGOUT) - for (i = 0; i < devc->model_data->nr_outs; i++) - setmask (maskout, i); - - if (envy24_devmask & DMASK_ANALOGIN) - for (i = 0; i < devc->model_data->nr_ins; i++) - setmask (maskin, i); - - devc->inportmask = maskin; - devc->outportmask = maskout; - - if (envy24_swapdevs) - { - install_input_devices (devc, maskin); - install_output_devices (devc, maskout); - install_virtual_output_devices (devc, maskout); - } - else - { - install_output_devices (devc, maskout); - install_input_devices (devc, maskin); - install_virtual_output_devices (devc, maskout); - } - - for (i = 0; i < 10; i += devc->skipdevs) - { - int num = 1 << i; - if (devc->skipdevs == 2) - num |= 1 << (i + 1); - - if (maskout & num) - envy24_set_mon (devc->mixer_dev, num, SNDCTL_MIX_WRITE, - 1340 | (1340 << 16)); - if (maskin & num) - envy24_set_mon (devc->mixer_dev, 0x80000000 | num, SNDCTL_MIX_WRITE, - 1340 | (1340 << 16)); - } - - if (envy24_devmask & DMASK_RAWDEVS) - envy24d_install (devc); - return 1; -} - -static int -ac97_read (void *devc_, int reg) -{ - envy24_devc *devc = devc_; - int i, status; - - OUTB (devc->osdev, reg, devc->ccs_base + 0x08); - OUTB (devc->osdev, reg, devc->ccs_base + 0x08); - OUTB (devc->osdev, reg, devc->ccs_base + 0x08); - OUTB (devc->osdev, 0x10, devc->ccs_base + 0x09); - - for (i = 0; i < 1000; i++) - { - status = INB (devc->osdev, devc->ccs_base + 0x09); - if (!(status & 0x10)) - { - status = INW (devc->osdev, devc->ccs_base + 0x0a); - return status; - } - } - - return 0xffff; -} - -static int -ac97_writereg (void *devc_, int reg, int data) -{ - envy24_devc *devc = devc_; - int i, status; - - OUTB (devc->osdev, reg, devc->ccs_base + 0x08); - OUTB (devc->osdev, reg, devc->ccs_base + 0x08); - OUTB (devc->osdev, reg, devc->ccs_base + 0x08); - OUTB (devc->osdev, 0x20, devc->ccs_base + 0x09); - - for (i = 0; i < 1000; i++) - { - status = INB (devc->osdev, devc->ccs_base + 0x09); - if (!(status & 0x20)) - { - OUTW (devc->osdev, data & 0xffff, devc->ccs_base + 0x0a); - return 1; - } - } - - return 0; -} - -static int -ac97_write (void *devc, int reg, int data) -{ - int ret; - - ac97_writereg (devc, reg, data); - ac97_writereg (devc, reg, data); - ret = ac97_writereg (devc, reg, data); - return ret; -} - -static void -install_consumer_devices (envy24_devc * devc) -{ -#if 1 - int i, status; - - OUTB (devc->osdev, 0x80, devc->ccs_base + 0x09); /* Cold reset mixer */ - oss_udelay (200); - OUTB (devc->osdev, 0x00, devc->ccs_base + 0x09); /* Release reset */ - oss_udelay (200); - - for (i = 0; i < 1000; i++) - { - status = INB (devc->osdev, devc->ccs_base + 0x09); - - if (status & 0x80) - break; - - oss_udelay (1000); - } - - if (i >= 1000) - { - } -#endif - - devc->consumer_mixer_dev = - ac97_install (&devc->ac97devc, "Envy24 consumer mixer", ac97_read, - ac97_write, devc, devc->osdev); - - /* Route monitor output to consumer AC97 */ - OUTB (devc->osdev, 0x01, devc->mt_base + 0x3c); - - /* Set consumer volumes to full */ - envy24_write_cci (devc, 3, 0); - envy24_write_cci (devc, 4, 0); -} - -static int -maudio_load_eeprom (envy24_devc * devc) -{ - int status; - - status = INB (devc->osdev, devc->ccs_base + 0x13); - - if (!(status & 0x80)) - return 0; /* No EEPROM */ - - envy24_write_cci (devc, 0x22, devc->eeprom[0xc]); /* GPIO direction */ - envy24_write_cci (devc, 0x21, devc->eeprom[0xa]); /* GPIO write mask */ - envy24_write_cci (devc, 0x20, devc->eeprom[0xb]); /* GPIO data */ - - return 1; -} - - -static int -envy24_init (envy24_devc * devc) -{ - extern int envy24_nfrags; - oss_native_word phaddr; - int err; - - /* Disable all interrupts */ - OUTB (devc->osdev, 0xff, devc->ccs_base + 0x01); - OUTB (devc->osdev, 0xff, devc->mt_base + 0x00); - - if ((err = oss_register_interrupts (devc->osdev, 0, envy24intr, NULL)) < 0) - { - cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err); - return 0; - } - - if (envy24_skipdevs < 1) - envy24_skipdevs = 1; - if (envy24_skipdevs > 2) - envy24_skipdevs = 2; - - devc->skipdevs = envy24_skipdevs; - - if (envy24_skipdevs != 1) - envy24_force_mono = 0; - - if (devc->model_data->flags & MF_MIDI1) - { - char name[128]; - oss_native_word flags; - sprintf (name, "%s #1", devc->model_data->product); - - MUTEX_ENTER (devc->mutex, flags); - uart401_init (&devc->uart401devc1, devc->osdev, devc->ccs_base + 0x0c, - name); - MUTEX_EXIT (devc->mutex, flags); - - /* Enable UART1 interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->ccs_base + 0x01) & ~0x80, - devc->ccs_base + 0x01); - } - - if (devc->model_data->flags & MF_MIDI2) - { - char name[128]; - oss_native_word flags; - sprintf (name, "%s #2", devc->model_data->product); - - MUTEX_ENTER (devc->mutex, flags); - uart401_init (&devc->uart401devc2, devc->osdev, devc->ccs_base + 0x1c, - name); - MUTEX_EXIT (devc->mutex, flags); - /* Enable UART2 interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->ccs_base + 0x01) & ~0x20, - devc->ccs_base + 0x01); - } - - devc->speedbits = 0; - devc->speed = 48000; - devc->pending_speed_sel = 9; - - if (devc->model_data->flags & (MF_MEEPROM)) - maudio_load_eeprom (devc); - - if (devc->model_data->auxdrv->card_init) - devc->model_data->auxdrv->card_init (devc); - if (devc->model_data->auxdrv->spdif_init) - devc->model_data->auxdrv->spdif_init (devc); - - if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION, - devc->osdev, - devc->osdev, - devc->model_data->product, - &envy24_mixer_driver, - sizeof (mixer_driver_t), - devc)) >= 0) - { - int n = 50; - - if (devc->skipdevs == 1) - n += 30; - mixer_ext_set_init_fn (devc->mixer_dev, envy24_mix_init, n); - } - - if (envy24_nfrags != 2 && envy24_nfrags != 4 && envy24_nfrags != 8 && - envy24_nfrags != 16 && envy24_nfrags != 32 && envy24_nfrags != 64) - envy24_nfrags = 16; - - devc->playbuffsize = HW_PLAYBUFFSIZE; - devc->recbuffsize = HW_RECBUFFSIZE; - - devc->hw_nfrags = envy24_nfrags; - devc->hw_pfragsize = devc->playbuffsize / devc->hw_nfrags; - devc->hw_rfragsize = devc->recbuffsize / devc->hw_nfrags; - devc->hw_fragsamples = devc->hw_pfragsize / 40; /* # of 32 bit samples/fragment/channel */ - - if (devc->hw_pfragsize % 40) - cmn_err (CE_WARN, "Error! Bad per channel fragment size\n"); - devc->hw_playfrag = 0; - devc->hw_recfrag = 0; - - devc->playbuf = - CONTIG_MALLOC (devc->osdev, HW_ALLOCSIZE, MEMLIMIT_28BITS, &phaddr, devc->playbuf_dma_handle); - if (devc->playbuf == NULL) - { - cmn_err (CE_WARN, "Failed to allocate %d bytes of DMA buffer\n", - HW_ALLOCSIZE); - return 0; - } - - devc->playbuf_phys = phaddr; - if ((devc->playbuf_phys + HW_ALLOCSIZE) >= (256 * 1024 * 1024)) - { - cmn_err (CE_WARN, "Got DMA buffer beyond address 256M.\n"); - cmn_err (CE_CONT, "Reboot and try again\n"); - return 1; - } - - OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Play base */ - - devc->recbuf = - CONTIG_MALLOC (devc->osdev, HW_ALLOCSIZE, MEMLIMIT_28BITS, &phaddr, devc->recbuf_dma_handle); - if (devc->recbuf == NULL) - { - cmn_err (CE_WARN, "Failed to allocate %d bytes of DMA buffer\n", - HW_ALLOCSIZE); - return 0; - } - - devc->recbuf_phys = phaddr; - if ((devc->recbuf_phys + HW_ALLOCSIZE) >= (256 * 1024 * 1024)) - { - cmn_err (CE_WARN, "Got DMA buffer beyond address 256M.\n"); - cmn_err (CE_CONT, "Reboot and try again\n"); - return 1; - } - - OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Rec base */ - - devc->playback_started = 0; - devc->recording_started = 0; - devc->playback_prepared = 0; - devc->recording_prepared = 0; - devc->writeahead = 1; -#ifdef __VXWORKS__ - devc->ratelock = 0; -#else - devc->ratelock = 1; -#endif - memset (devc->playbuf, 0, HW_ALLOCSIZE); - memset (devc->recbuf, 0, HW_ALLOCSIZE); - - install_audio_devices (devc); - - if (devc->consumer_ac97_present || (devc->model_data->flags & MF_CONSUMER)) - install_consumer_devices (devc); - /* Enable professional rec/play interrupts */ - OUTB (devc->osdev, - INB (devc->osdev, devc->ccs_base + 0x01) & ~0x10, - devc->ccs_base + 0x01); - - setup_spdif_control (devc); - - if (devc->model_data->auxdrv->spdif_set) - devc->model_data->auxdrv->spdif_set (devc, 0x20); - -#if 1 - /* Make sure everything is initialized */ - envy24_prepare_play_engine (devc); - envy24_launch_play_engine (devc); - oss_udelay (10000); - envy24_stop_playback (devc); -#endif - -#if 0 - { - char line[200], *s = line; - *line = 0; - - for (i = 0; i < 0x20; i++) - { - if (!(i % 16)) - { - if (*line != 0) - cmn_err (CE_CONT, "%s\n", line); - - s = line; - sprintf (s, "CCS%02x: ", i); - s = line + strlen (line); - } - sprintf (s, "%02x ", INB (devc->osdev, devc->ccs_base + i)); - s = line + strlen (line); - } - *line = 0; - - for (i = 0; i < 0x40; i++) - { - if (!(i % 16)) - { - if (*line != 0) - cmn_err (CE_CONT, "%s\n", line); - - s = line; - sprintf (s, "MT%02x: ", i); - s = line + strlen (line); - } - sprintf (s, "%02x ", INB (devc->osdev, devc->mt_base + i)); - s = line + strlen (line); - } - - cmn_err (CE_CONT, "%s\n", line); - } -#endif - - return 1; -} - -int -oss_envy24_attach (oss_device_t * osdev) -{ - envy24_devc *devc; - static int status; - unsigned char pci_irq_line; - unsigned short pci_command, vendor, device; - unsigned int subvendor; - unsigned int pci_ioaddr, pci_ioaddr3; - int i; - - char *name = "Generic ENVY24"; - - DDB (cmn_err (CE_CONT, "Entered Envy24 probe routine\n")); - - if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL) - { - cmn_err (CE_WARN, "Out of memory\n"); - return 0; - } - - devc->osdev = osdev; - osdev->devc = devc; - - pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor); - pci_read_config_word (osdev, PCI_DEVICE_ID, &device); - - if (vendor != ICENSEMBLE_VENDOR_ID || device != ICENSEMBLE_ENVY24_ID) - return 0; - - pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr); - DDB (cmn_err (CE_CONT, "Device found at I/O %x\n", pci_ioaddr)); - pci_read_config_dword (osdev, PCI_BASE_ADDRESS_3, &pci_ioaddr3); - - devc->active_inputs = 0; - devc->active_outputs = 0; - devc->sync_locked = 1; - devc->first_dev = -1; - - pci_read_config_word (osdev, PCI_COMMAND, &pci_command); - pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line); - pci_read_config_dword (osdev, 0x2c, &subvendor); - devc->ccs_base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr) & ~0x3; - DDB (cmn_err (CE_CONT, "CCS base %x/%lx\n", pci_ioaddr, devc->ccs_base)); - - devc->mt_base = MAP_PCI_IOADDR (devc->osdev, 3, pci_ioaddr3) & ~0x3; - DDB (cmn_err (CE_CONT, "MT base %x/%lx\n", pci_ioaddr3, devc->mt_base)); - - pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; - pci_write_config_word (osdev, PCI_COMMAND, pci_command); - - - /* Reset the chip */ - OUTB (devc->osdev, 0x81, devc->ccs_base + 0x00); - oss_udelay (200); - /* Release reset */ - OUTB (devc->osdev, 0x01, devc->ccs_base + 0x00); - oss_udelay (200); - - devc->nr_outdevs = devc->nr_indevs = 0; - devc->curr_outch = devc->curr_inch = 0; - devc->playbuffsize = 0; - devc->recbuffsize = 0; - devc->playbuf = devc->recbuf = NULL; - - status = INB (devc->osdev, devc->ccs_base + 0x13); - if (status & 0x80) /* EEPROM present */ - { - static char resol_tab[] = { 16, 18, 20, 24 }; - unsigned char tmpbyte; - - load_eeprom (devc, subvendor); - - /* Fix bit 0x80 of EEPROM location 0x07. */ - pci_read_config_byte (osdev, 0x61, &tmpbyte); - tmpbyte &= 0x80; - devc->eeprom[0x07] &= ~0x80; - devc->eeprom[0x07] |= tmpbyte; - -#if 1 - devc->eeprom[0x07] |= 0x80; -#endif - - pci_write_config_byte (osdev, 0x60, devc->eeprom[0x06]); - pci_write_config_byte (osdev, 0x61, devc->eeprom[0x07]); - pci_write_config_byte (osdev, 0x62, devc->eeprom[0x08]); - pci_write_config_byte (osdev, 0x63, devc->eeprom[0x09]); - - if (devc->model_data->flags & MF_AC97) - devc->consumer_ac97_present = 1; - -#if 1 - if (devc->eeprom[0x06] & 0x20) - DDB (cmn_err (CE_CONT, "Two MPU401 UARTs present.\n")); - if (devc->eeprom[0x06] & 0x10) - { - DDB (cmn_err (CE_CONT, "Consumer AC97 not present.\n")); - } - else - { - DDB (cmn_err (CE_CONT, "Consumer AC97 present.\n")); - } - DDB (cmn_err (CE_CONT, "%d stereo ADC(s) available\n", - ((devc->eeprom[0x06] >> 2) & 0x03) + 1)); - DDB (cmn_err (CE_CONT, "%d stereo DAC(s) available\n", - ((devc->eeprom[0x06] >> 0) & 0x03) + 1)); - - DDB (cmn_err (CE_CONT, "MT converter type %s\n", - (devc->eeprom[0x07] & 0x80) ? "I2S" : "AC97")); - - if (devc->eeprom[0x08] & 0x80) - { - DDB (cmn_err (CE_CONT, "Has I2S volume control and mute\n")); - } - else - { - DDB (cmn_err (CE_CONT, "No I2S volume control and mute\n")); - } - if (devc->eeprom[0x08] & 0x20) - DDB (cmn_err (CE_CONT, "Has 96kHz support\n")); - - DDB (cmn_err (CE_CONT, "Converter resolution %d bits\n", - resol_tab[(devc->eeprom[0x08] >> 4) & 0x03])); - - if (devc->eeprom[0x09] & 0x02) - DDB (cmn_err (CE_CONT, "Has S/PDIF in support\n")); - if (devc->eeprom[0x09] & 0x01) - DDB (cmn_err (CE_CONT, "Has S/PDIF out support\n")); - -#endif - - if (subvendor == 0xd6301412) /* Delta 1010 */ - if (devc->eeprom[0xc] == 0x7b) /* Looks like Delta 101 rev E */ - subvendor = 0xd63014ff; /* Delta 1010E */ - - -#if 1 - if (!(devc->eeprom[0x07] & 0x80)) - { - cmn_err (CE_WARN, "Cards with AC97 codecs are not supported\n"); - return 0; - } -#endif - } - - i = 0; - while (models[i].svid != 0) - { - if (models[i].svid == subvendor) - { - name = models[i].product; - devc->model_data = &models[i]; - if (devc->model_data->auxdrv == NULL) - devc->model_data->auxdrv = &default_auxdrv; - DDB (cmn_err (CE_CONT, "Card id '%s'\n", name)); - - break; - } - - i++; - } - - if (models[i].svid == 0) - { - cmn_err (CE_NOTE, "Unknown device ID (%08x).\n", subvendor); - cmn_err (CE_NOTE, "This card is not supported (yet).\n"); - return 0; - } - - MUTEX_INIT (osdev, devc->mutex, MH_DRV); - oss_register_device (osdev, name); - devc->irq = pci_irq_line; - return envy24_init (devc); /* Detected */ -} - - -int -oss_envy24_detach (oss_device_t * osdev) -{ - envy24_devc *devc; - - devc = osdev->devc; - - if (oss_disable_device (osdev) < 0) - return 0; - - /* Disable all interrupts */ - OUTB (devc->osdev, 0xff, devc->ccs_base + 0x01); - - /* Stop playback */ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01, - devc->mt_base + 0x18); - oss_udelay (100); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01, - devc->mt_base + 0x18); - - /* Stop recording */ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04, - devc->mt_base + 0x18); - oss_udelay (100); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04, - devc->mt_base + 0x18); - - if (devc->model_data->flags & MF_MIDI1) - uart401_disable (&devc->uart401devc1); - if (devc->model_data->flags & MF_MIDI2) - uart401_disable (&devc->uart401devc2); - - oss_unregister_interrupts (osdev); - MUTEX_CLEANUP (devc->mutex); - UNMAP_PCI_IOADDR (devc->osdev, 0); - UNMAP_PCI_IOADDR (devc->osdev, 3); - - if (devc->playbuf != NULL) - CONTIG_FREE (devc->osdev, devc->playbuf, HW_ALLOCSIZE, devc->playbuf_dma_handle); - - if (devc->recbuf != NULL) - CONTIG_FREE (devc->osdev, devc->recbuf, HW_ALLOCSIZE, devc->recbuf_dma_handle); - devc->playbuf = devc->recbuf = NULL; - - oss_unregister_device (osdev); - return 1; -} diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24ht/envy24ht_revo71.c.orig oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24ht/envy24ht_revo71.c.orig --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_envy24ht/envy24ht_revo71.c.orig 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_envy24ht/envy24ht_revo71.c.orig 1970-01-01 01:00:00.000000000 +0100 @@ -1,336 +0,0 @@ -/* - * Purpose: Low level routines for M Audio Revolution 7.1 - */ -/* - * - * This file is part of Open Sound System. - * - * Copyright (C) 4Front Technologies 1996-2008. - * - * This this source file is released under GPL v2 license (no other versions). - * See the COPYING file included in the main directory of this source - * distribution for the license terms and conditions. - * - */ - -#include "oss_envy24ht_cfg.h" - -#include "spdif.h" -#include "envy24ht.h" - -#define BIT(x) (1<<(x)) - -#define CCLK (1<<1) -#define CDIN (1<<2) /* Currently not connected */ -#define CDTI (1<<3) -#define CSDIG (1<<4) -#define CSN1 (1<<5) -#define CSN2 (1<<6) - -#define WRITEMASK (CSN1|CSN2|CDTI|CCLK) - -#define DAC1 0x01 /* 2ch Front DAC (AK4381) */ -#define DAC2 0x03 /* 6ch Surround DAC (AK4355) */ - - -static void -writereg (envy24ht_devc * devc, int csn, int chip, unsigned char reg, - unsigned char val) -{ - int i; - unsigned short v, tmp; - - tmp = INW (devc->osdev, devc->ccs_base + 0x14) & ~(csn | CCLK | CDTI); - OUTW (devc->osdev, tmp, devc->ccs_base + 0x14); - - reg = (reg & 0x1f) | 0x20 | (chip << 6); /* Chip address (variable), write */ - /* Address bits */ - - for (i = 7; i >= 0; i--) - { - v = (reg & (1 << i)) ? CDTI : 0; - OUTW (devc->osdev, v | tmp, devc->ccs_base + 0x14); /* Tack */ - OUTW (devc->osdev, v | CCLK | tmp, devc->ccs_base + 0x14); /* Tick */ - } - - /* Data bits */ - - for (i = 7; i >= 0; i--) - { - v = (val & (1 << i)) ? CDTI : 0; - OUTW (devc->osdev, v | tmp, devc->ccs_base + 0x14); /* Tack */ - OUTW (devc->osdev, v | CCLK | tmp, devc->ccs_base + 0x14); /* Tick */ - } - - OUTW (devc->osdev, v | tmp, devc->ccs_base + 0x14); /* Tack */ - OUTW (devc->osdev, tmp | csn | CDTI | CCLK, devc->ccs_base + 0x14); /* Release */ - -} - -static void -writedac1 (envy24ht_devc * devc, unsigned char reg, unsigned char data) -{ - writereg (devc, CSN1, DAC1, reg, data); - devc->dac1val[reg] = data; -} - -static void -writedac2 (envy24ht_devc * devc, unsigned char reg, unsigned char data) -{ - writereg (devc, CSN2, DAC2, reg, data); - devc->dac2val[reg] = data; -} - -static void -revo71_mute (envy24ht_devc * devc, int mute) -{ - if (mute) - { - writedac1 (devc, 1, devc->dac1val[1] | BIT (0)); - writedac2 (devc, 1, devc->dac2val[1] | BIT (1)); - oss_udelay (1000); -/* OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x1e) & ~BIT(22-16), */ -/* devc->ccs_base + 0x1e); */ - } - else - { -/* OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x1e) | ~BIT(22-16), */ -/* devc->ccs_base + 0x1e); */ - oss_udelay (1000); - writedac1 (devc, 1, devc->dac1val[1] & ~BIT (0)); - writedac2 (devc, 1, devc->dac2val[1] & ~BIT (1)); - } -} - -static void -revo71_card_init (envy24ht_devc * devc) -{ - int i; - - OUTL (devc->osdev, WRITEMASK | 0x400000, devc->ccs_base + 0x18); /* GPIO direction */ - OUTW (devc->osdev, ~WRITEMASK, devc->ccs_base + 0x16); /* GPIO write mask */ - OUTB (devc->osdev, 0x40, devc->ccs_base + 0x1f); - OUTW (devc->osdev, WRITEMASK, devc->ccs_base + 0x14); /* Initial bit state */ - - OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1a); /* GPIO direction for bits 16:22 */ - OUTB (devc->osdev, 0x00, devc->ccs_base + 0x1f); /* GPIO mask for bits 16:22 */ - OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1e); /* GPIO data for bits 16:22 */ - -#if 0 - for (i = 0; i < 7; i++) - { - OUTW (devc->osdev, 1 << i, devc->ccs_base + 0x14); /* Test bit */ - OUTW (devc->osdev, 0, devc->ccs_base + 0x14); /* Test bit */ - } -#endif - - OUTW (devc->osdev, WRITEMASK, devc->ccs_base + 0x14); /* Initial bit state */ - oss_udelay (10); - - revo71_mute (devc, 1); -/* - * Init front DAC (AK4381) - */ - writedac1 (devc, 0x00, 0x0c); - writedac1 (devc, 0x01, 0x03); - writedac1 (devc, 0x02, 0x00); - - writedac1 (devc, 0x03, 0xff); /* Initial volume */ - writedac1 (devc, 0x04, 0xff); /* Initial volume */ - - writedac1 (devc, 0x00, 0x0f); -/* - * Init surround DAC (AK4355) - */ - writedac2 (devc, 0x01, 0x02); - writedac2 (devc, 0x00, 0x06); - oss_udelay (10); - writedac2 (devc, 0x02, 0x0e); - writedac2 (devc, 0x03, 0x01); - - for (i = 4; i < 10; i++) - writedac2 (devc, i, 0xff); /* Initial volumes */ - writedac2 (devc, 0x0a, 0x00); - - writedac2 (devc, 0x01, 0x01); - revo71_mute (devc, 0); -} - -static void -revo71_set_rate (envy24ht_devc * devc) -{ - int rate = devc->speed, i; - unsigned char tmp; - - if (devc->speed == devc->prev_speed) - return; - devc->prev_speed = devc->speed; - - revo71_mute (devc, 1); - - /* Pulse the PRST# signal to reset converters */ - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x05) | 0x80, - devc->mt_base + 0x05); - oss_udelay (5000); - OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x05) & ~0x80, - devc->mt_base + 0x05); - oss_udelay (5000); - - tmp = 0x03; - if (rate <= 48000) - tmp |= 0x00; - else - { - if (rate <= 96000) - tmp |= 0x04; - else - tmp |= 0x08; - } - - /* Front DAC */ - - writedac1 (devc, 0, 0x0c); - writedac1 (devc, 1, tmp); - writedac1 (devc, 2, 0x00); - writedac1 (devc, 3, devc->dac1val[3]); - writedac1 (devc, 4, devc->dac1val[4]); - writedac1 (devc, 0, 0x0f); - - /* Surround DAC */ - writedac2 (devc, 1, 0x02); - writedac2 (devc, 0, 0x06); - - tmp = 0x0e; - - if (devc->speed > 60000) - { - if (devc->speed > 120000) - tmp |= 0x20; - else - tmp |= 0x10; - } - writedac2 (devc, 2, tmp); - writedac2 (devc, 3, 0x01); - - for (i = 4; i < 10; i++) - writedac2 (devc, i, devc->dac2val[i]); - - writedac2 (devc, 0xa, 0x00); - writedac2 (devc, 1, 0x03); - - revo71_mute (devc, 0); -} - -static int -revo71_set_akm (int dev, int ctrl, unsigned int cmd, int value) -{ - envy24ht_devc *devc = mixer_devs[dev]->hw_devc; - - if (cmd == SNDCTL_MIX_READ) - { - if (ctrl < 0 || ctrl > 4) - return OSS_EIO; - - return devc->gains[ctrl]; - } - - if (cmd == SNDCTL_MIX_WRITE) - { - int left, right; - - left = value & 0xff; - right = (value >> 8) & 0xff; - - switch (ctrl) - { - case 0: /* Front */ - writedac1 (devc, 0x03, left); - writedac1 (devc, 0x04, right); - break; - - case 1: /* Rear */ - writedac2 (devc, 0x06, left); - writedac2 (devc, 0x07, right); - break; - - case 2: /* Center */ - writedac2 (devc, 0x04, left); - right = left; - break; - - case 3: /* LFE */ - writedac2 (devc, 0x05, left); - right = left; - break; - - case 4: /* Surround */ - writedac2 (devc, 0x08, left); - writedac2 (devc, 0x09, right); - break; - - default: - return OSS_EINVAL; - } - - value = left | (right << 8); - return devc->gains[ctrl] = value; - } - - return OSS_EINVAL; -} - -static int -revo71_mixer_init (envy24ht_devc * devc, int dev, int group) -{ - int i, err; - - for (i = 0; i < 6; i++) - devc->gains[i] = 0xffff; - - if ((group = mixer_ext_create_group (dev, 0, "ENVY24HT_GAIN")) < 0) - return group; - - if ((err = mixer_ext_create_control (dev, group, - 0, revo71_set_akm, - MIXT_STEREOSLIDER, - "GAIN_FRONT", 255, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - - if ((err = mixer_ext_create_control (dev, group, - 1, revo71_set_akm, - MIXT_STEREOSLIDER, - "GAIN_REAR", 255, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - - if ((err = mixer_ext_create_control (dev, group, - 2, revo71_set_akm, - MIXT_MONOSLIDER, - "GAIN_CENTER", 255, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - - if ((err = mixer_ext_create_control (dev, group, - 3, revo71_set_akm, - MIXT_MONOSLIDER, - "GAIN_LFE", 255, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - - if ((err = mixer_ext_create_control (dev, group, - 4, revo71_set_akm, - MIXT_STEREOSLIDER, - "GAIN_surround", 255, - MIXF_READABLE | MIXF_WRITEABLE)) < 0) - return err; - - return 0; -} - -envy24ht_auxdrv_t envy24ht_revo71_auxdrv = { - revo71_card_init, - revo71_mixer_init, - revo71_set_rate, - revo71_mixer_refresh -}; diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c 1970-01-01 01:00:00.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c 2010-05-27 13:38:38.000000000 +0200 @@ -0,0 +1,36 @@ +/* + * Purpose: init handler for Asus m9. + */ + +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +/* Codec index is 0 */ +/* Codec vendor 10ec:0260 */ +/* HD codec revision 1.0 (4.0) (0x00100400) */ +/* Subsystem ID 1025160d */ +#include "oss_hdaudio_cfg.h" +#include "hdaudio.h" +#include "hdaudio_codec.h" +#include "hdaudio_dedicated.h" +#include "hdaudio_mixers.h" + +int +hdaudio_asus_m9_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) +{ + DDB(cmn_err(CE_CONT, "hdaudio_asus_m9_mixer_init got called.\n")); + + corb_write (mixer, cad, 0x1b, 0, SET_EAPD, 0); + + return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); +} + diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_codecids.h oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_codecids.h --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_codecids.h 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_codecids.h 2010-05-27 13:38:38.000000000 +0200 @@ -827,6 +827,8 @@ NULL }; +extern int hdaudio_GPIO_init_1 (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); + static const codec_desc_t codecs[] = { /* Realtek HDA codecs */ {0x10ec0260, "ALC260", VF_NONE, (char **) &alc260remap}, @@ -840,11 +842,23 @@ {0x10ec0883, "ALC883", VF_ALC88X_HACK, (char **) &alc883remap}, {0x10ec0885, "ALC885", VF_ALC88X_HACK, (char **) &alc883remap}, {0x10ec0888, "ALC888", VF_ALC88X_HACK, (char **) &alc883remap}, + {0x10ec0889, "ALC889", VF_ALC88X_HACK, (char **) &alc883remap}, /* CMedia HDA codecs */ {0x13f69880, "CMI9880", VF_NONE, (char **) &cmi9880remap}, {0x434d4980, "CMI9880", VF_NONE, (char **) &cmi9880remap}, + {0x111d7603, "92HD75B3X5", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d7608, "92HD75B2X5", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b0, "92HD71B8X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b1, "92HD71B8X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b2, "92HD71B7X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b3, "92HD71B7X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b4, "92HD71B6X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b5, "92HD71B6X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b6, "92HD71B5X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + {0x111d76b7, "92HD71B5X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1}, + /* Analog Devices HDA codecs */ {0x11d41981, "AD1981", VF_NONE, (char **) &ad1981remap, 0x76543021}, {0x11d41983, "AD1983", VF_NONE, (char **) &ad1983remap, 0x76543021}, @@ -920,6 +934,8 @@ /* Creative Labs */ {0x1102000a, "Createive XFi XTreme", VF_NONE, NULL, 0x76543210}, + {0x11c11040, "Agere HDA Modem", VF_NONE, NULL, 0, NULL_mixer_init}, + /* Unknown */ {0, "Unknown"} }; @@ -1041,13 +1057,13 @@ extern int hdaudio_scaleoP_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_abit_AA8_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_ferrari5k_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); -extern int hdaudio_travelmate4060_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_vaio_vgn_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_thinkpad_r61_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_mac_sigmatel_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_mac_realtek_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_eeepc_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); extern int hdaudio_asus_a7k_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); +extern int hdaudio_asus_m9_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group); static const codec_desc_t subdevices[] = { {0x98801019, "ECS 915P-A", VF_NONE, NULL, 0x76541320}, @@ -1064,7 +1080,8 @@ {0x10250000, "Ferrari5k/ALC883", VF_ALC88X_HACK, (char **) &alc883remap, 0, hdaudio_ferrari5k_mixer_init, 0x10ec0883, 0x1025010a}, {0x10250000, "Acer_aspire5052/ALC883", VF_ALC88X_HACK, (char **) &alc883remap, 0, hdaudio_ferrari5k_mixer_init, 0x10ec0883, 0x1025010f}, - {0x1025160d, "Acer_travelmate4060/ALC260", VF_NONE, (char **) &alc260remap, 0, hdaudio_travelmate4060_mixer_init, 0x10ec0260, 0x1025008f}, + {0x1025160d, "Acer_travelmate4060/ALC260", VF_NONE, (char **) &alc260remap, 0, hdaudio_GPIO_init_1, 0x10ec0260, 0x1025008f}, + {0x10431153, "Asus M9", VF_NONE, (char **) &ad1986remap, 0x76540321, hdaudio_asus_m9_mixer_init}, /* **** Sony Vaio VGN-AR51 *** diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c 2010-05-27 13:38:38.000000000 +0200 @@ -112,3 +112,17 @@ return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); } + +int +hdaudio_GPIO_init_1 (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) +{ + DDB(cmn_err(CE_CONT, "hdaudio_GPIO_init_1 got called.\n")); + + /* Acer TravelMate 4060 and similar Aspire series, with ALC260 codec, need + * that we init GPIO to get internal speaker and headphone jack working. */ + corb_write(mixer, cad, 0x01, 0, SET_GPIO_ENABLE, 1); + corb_write(mixer, cad, 0x01, 0, SET_GPIO_DIR, 1); + corb_write(mixer, cad, 0x01, 0, SET_GPIO_DATA, 1); + + return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); +} diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_travelmate4060.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_travelmate4060.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_travelmate4060.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/hdaudio_travelmate4060.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,39 +0,0 @@ -/* - * Purpose: Hook to enable internal speaker on Acer TravelMate 4060. - */ - -/* - * - * This file is part of Open Sound System. - * - * Copyright (C) 4Front Technologies 1996-2008. - * - * This this source file is released under GPL v2 license (no other versions). - * See the COPYING file included in the main directory of this source - * distribution for the license terms and conditions. - * - */ - -/* Codec index is 0 */ -/* Codec vendor 10ec:0260 */ -/* HD codec revision 1.0 (4.0) (0x00100400) */ -/* Subsystem ID 1025160d */ -#include "oss_hdaudio_cfg.h" -#include "hdaudio.h" -#include "hdaudio_codec.h" -#include "hdaudio_dedicated.h" -#include "hdaudio_mixers.h" - -int -hdaudio_travelmate4060_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) -{ - DDB(cmn_err(CE_CONT, "hdaudio_travelmate4060_mixer_init got called.\n")); - - /* Acer TravelMate 4060 and similar Aspire series, with ALC260 codec, need - * that we init GPIO to get internal speaker and headphone jack working. */ - corb_write(mixer, cad, 0x01, 0, SET_GPIO_ENABLE, 1); - corb_write(mixer, cad, 0x01, 0, SET_GPIO_DIR, 1); - corb_write(mixer, cad, 0x01, 0, SET_GPIO_DATA, 1); - - return hdaudio_generic_mixer_init(dev, mixer, cad, top_group); -} diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/oss_hdaudio.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/oss_hdaudio.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_hdaudio/oss_hdaudio.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_hdaudio/oss_hdaudio.c 2010-05-27 13:38:38.000000000 +0200 @@ -1091,7 +1091,7 @@ if (!devc->codecmask) { - devc->codecmask = PCI_READL (devc->osdev, devc->azbar + HDA_STATESTS); + devc->codecmask = PCI_READW (devc->osdev, devc->azbar + HDA_STATESTS); DDB (cmn_err (CE_CONT, "Codec mask %x\n", devc->codecmask)); } diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_madi/oss_madi.c oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_madi/oss_madi.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/drv/oss_madi/oss_madi.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/drv/oss_madi/oss_madi.c 2010-05-27 13:38:38.000000000 +0200 @@ -660,7 +660,7 @@ adev_t *adev; int n; - if ((portc = PMALLOC (devc->osedv, sizeof (*portc))) == NULL) + if ((portc = PMALLOC (devc->osdev, sizeof (*portc))) == NULL) { cmn_err (CE_WARN, "Cannot allocate portc structure\n"); return OSS_ENOMEM; @@ -715,7 +715,7 @@ adev_t *adev; int n; - if ((portc = PMALLOC (devc->osedv, sizeof (*portc))) == NULL) + if ((portc = PMALLOC (devc->osdev, sizeof (*portc))) == NULL) { cmn_err (CE_WARN, "Cannot allocate portc structure\n"); return OSS_ENOMEM; diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/audio/oss_audio_core.c oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/audio/oss_audio_core.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/audio/oss_audio_core.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/audio/oss_audio_core.c 2010-05-27 13:38:37.000000000 +0200 @@ -413,7 +413,7 @@ adev->dmap_out->flags |= DMAP_COOKED; } - if (adev->dmask & DMASK_OUT) + if (adev->dmask & DMASK_IN) { adev->dmap_in->flags |= DMAP_COOKED; } @@ -495,7 +495,7 @@ if (adev->dmask & DMASK_OUT) adev->dmap_out->flags |= DMAP_COOKED; - if (adev->dmask & DMASK_OUT) + if (adev->dmask & DMASK_IN) adev->dmap_in->flags |= DMAP_COOKED; } @@ -525,7 +525,7 @@ adev->dmap_out->flags |= DMAP_COOKED; } - if (adev->dmask & DMASK_OUT) + if (adev->dmask & DMASK_IN) { adev->dmap_in->flags |= DMAP_COOKED; } @@ -585,7 +585,7 @@ adev->dmap_out->flags |= DMAP_COOKED; } - if (adev->dmask & DMASK_OUT) + if (adev->dmask & DMASK_IN) { adev->dmap_in->flags |= DMAP_COOKED; } @@ -3244,6 +3244,11 @@ break; case SNDCTL_DSP_SETDUPLEX: + /* + * Note! SNDCTL_DSP_SETDUPLEX has not been implemented by any driver for years. + * The call is still implemented in audio core but it may get removed in the + * future. + */ if (adev->open_mode != OPEN_READWRITE) { oss_audio_set_error (adev->engine_num, E_PLAY, diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/mixer/oss_mixer_core.c oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/mixer/oss_mixer_core.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/mixer/oss_mixer_core.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/mixer/oss_mixer_core.c 2010-05-27 13:38:37.000000000 +0200 @@ -1674,7 +1674,7 @@ info->numaudioengines = num_audio_engines; for (i = 0; i < 8; i++) info->openedaudio[i] = 0; - for (i = 0; i < num_audio_devfiles; i++) + for (i = 0; i < num_audio_engines; i++) if (audio_engines[i] != NULL) { if (audio_engines[i]->flags & ADEV_OPENED) diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/vmix_core/vmix_core.c oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/vmix_core/vmix_core.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/vmix_core/vmix_core.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/vmix_core/vmix_core.c 2010-05-27 13:38:37.000000000 +0200 @@ -1649,7 +1649,7 @@ if (mixer->instance_num > 0) opts |= ADEV_SPECIAL; - if ((portc = PMALLOC (mixer->osedv, sizeof (*portc))) == NULL) + if ((portc = PMALLOC (mixer->osdev, sizeof (*portc))) == NULL) { cmn_err (CE_WARN, "Cannot allocate portc structure\n"); return OSS_ENOMEM; @@ -1750,7 +1750,7 @@ if (mixer->masterdev == -1) return; - if ((portc = PMALLOC (mixer->osedv, sizeof (*portc))) == NULL) + if ((portc = PMALLOC (mixer->osdev, sizeof (*portc))) == NULL) { cmn_err (CE_WARN, "Cannot allocate portc structure\n"); return; diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/vmix_core/vmix_input.c oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/vmix_core/vmix_input.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/vmix_core/vmix_input.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/vmix_core/vmix_input.c 2010-05-27 13:38:37.000000000 +0200 @@ -369,7 +369,7 @@ if (mixer->record_engine.chbufs[i] == NULL) /* Not allocated yet */ { mixer->record_engine.chbufs[i] = - PMALLOC (mixer->master_portc, + PMALLOC (mixer->master_osdev, CHBUF_SAMPLES * sizeof (vmix_sample_t)); if (mixer->record_engine.chbufs[i] == NULL) { diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/vmix_core/vmix_output.c oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/vmix_core/vmix_output.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/framework/vmix_core/vmix_output.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/framework/vmix_core/vmix_output.c 2010-05-27 13:38:37.000000000 +0200 @@ -489,14 +489,14 @@ /* Find out the "best" sample format supported by the device */ - if (adev->oformat_mask & AFMT_S16_NE) + if (adev->oformat_mask & AFMT_S16_OE) fmt = AFMT_S16_OE; if (adev->oformat_mask & AFMT_S16_NE) fmt = AFMT_S16_NE; if (mixer->multich_enable) /* Better quality enabled */ { - if (adev->oformat_mask & AFMT_S32_NE) + if (adev->oformat_mask & AFMT_S32_OE) fmt = AFMT_S32_OE; if (adev->oformat_mask & AFMT_S32_NE) fmt = AFMT_S32_NE; diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/OS/BeOS/os_beos.c oss4-4.2-build2003/=unpacked-tar1=/kernel/OS/BeOS/os_beos.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/OS/BeOS/os_beos.c 2009-04-20 07:55:17.000000000 +0200 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/OS/BeOS/os_beos.c 2010-05-11 13:26:05.000000000 +0200 @@ -1070,6 +1070,16 @@ { case DRV_PCI: /* NOP */ +#ifdef __HAIKU__ + if (gPCI->reserve_device(osdev->dip->pciinfo.bus, + osdev->dip->pciinfo.device, + osdev->dip->pciinfo.function, + "oss", osdev) != B_OK) { + cmn_err (CE_WARN, "Could not reserve PCI device\n"); + /* XXX: CLEANUP! */ + return NULL; + } +#endif break; case DRV_VIRTUAL: @@ -1152,6 +1162,12 @@ /* NOP */ //pci_config_teardown (&osdev->pci_config_handle); //osdev->pci_config_handle = NULL; +#ifdef __HAIKU__ + gPCI->unreserve_device(osdev->dip->pciinfo.bus, + osdev->dip->pciinfo.device, + osdev->dip->pciinfo.function, + "oss", osdev); +#endif break; } diff -Nru oss4-4.2-build2002/=unpacked-tar1=/kernel/OS/FreeBSD/os_freebsd.c oss4-4.2-build2003/=unpacked-tar1=/kernel/OS/FreeBSD/os_freebsd.c --- oss4-4.2-build2002/=unpacked-tar1=/kernel/OS/FreeBSD/os_freebsd.c 2009-11-13 16:23:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/kernel/OS/FreeBSD/os_freebsd.c 2010-05-27 13:38:38.000000000 +0200 @@ -903,9 +903,15 @@ return ev.revents; } +#if defined(D_VERSION_03) && (D_VERSION == D_VERSION_03) +static int +oss_mmap (struct cdev *bsd_dev, vm_ooffset_t offset, vm_paddr_t * paddr, + int nprot, vm_memattr_t *memattr) +#else static int oss_mmap (struct cdev *bsd_dev, vm_offset_t offset, vm_paddr_t * paddr, int nprot) +#endif { int retval; int dev; diff -Nru oss4-4.2-build2002/=unpacked-tar1=/pull.sh oss4-4.2-build2003/=unpacked-tar1=/pull.sh --- oss4-4.2-build2002/=unpacked-tar1=/pull.sh 2009-02-07 10:12:52.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/pull.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -#!/bin/sh - -hg pull ../oss-4.1 -hg merge -hg commit -m "v4.1 pull `date +%y%m%d`" -sh push.sh diff -Nru oss4-4.2-build2002/=unpacked-tar1=/push.sh oss4-4.2-build2003/=unpacked-tar1=/push.sh --- oss4-4.2-build2002/=unpacked-tar1=/push.sh 2008-06-23 21:28:27.000000000 +0200 +++ oss4-4.2-build2003/=unpacked-tar1=/push.sh 2010-05-11 18:59:59.000000000 +0200 @@ -1,3 +1,3 @@ #!/bin/sh -hg push ssh://hg@voimakentta/oss -ssh hg@voimakentta "cd oss;hg update" + +hg push ssh://compusonic@opensound.hg.sourceforge.net/hgroot/opensound/opensound diff -Nru oss4-4.2-build2002/=unpacked-tar1=/RELNOTES.txt oss4-4.2-build2003/=unpacked-tar1=/RELNOTES.txt --- oss4-4.2-build2002/=unpacked-tar1=/RELNOTES.txt 2009-11-13 16:23:24.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/RELNOTES.txt 2010-05-27 13:38:38.000000000 +0200 @@ -1,4 +1,4 @@ -Release notes for Open Source OSS version v4.2-build2002 +Release notes for Open Source OSS version v4.2-build2003 ================================================== @@ -106,7 +106,7 @@ read-only media. There is nothing special in the source directory. Its contents are distributed -in the source tarball (oss-v4.2-build2002-src-gpl.tar.bz2). +in the source tarball (oss-v4.2-build2003-src-gpl.tar.bz2). The build directory is a special directory that contains symbolic links to the corresponding files in the source directory. Files in the build directory @@ -130,7 +130,7 @@ Save the tarball containing the source files in /tmp (or some other directory in the development system). In this document we will assume -that you have stored the sources in /tmp/oss-v4.2-build2002-src-gpl.tar.bz2. +that you have stored the sources in /tmp/oss-v4.2-build2003-src-gpl.tar.bz2. Go to the directory where you would like to create the source directory. For example: @@ -139,12 +139,12 @@ Next restore the files in the tarball by executing the following command: - bunzip2 -c /tmp/oss-v4.2-build2002-src-gpl.tar.bz2 | tar xvf - + bunzip2 -c /tmp/oss-v4.2-build2003-src-gpl.tar.bz2 | tar xvf - (Or if you have GNU make (Linux, FreeBSD) you simply use -tar xvfj /tmp/oss-v4.2-build2002-src-gpl.tar.bz2). +tar xvfj /tmp/oss-v4.2-build2003-src-gpl.tar.bz2). -After restoring the files they will appear in the oss-v4.2-build2002-src-gpl +After restoring the files they will appear in the oss-v4.2-build2003-src-gpl subdirectory under the current directory. Note! bunzip2 command is part of the bzip2 package. @@ -178,7 +178,7 @@ ------------------------------ If you have an earlier OSS build directory in the system it's recommended that -you remove it before creating the build directory for v4.2-build2002 +you remove it before creating the build directory for v4.2-build2003 alternatively you may create separate build directories for different OSS versions. @@ -301,7 +301,7 @@ Summary: (This is how we build OSS at 4front) --------------------------------------------- -1) cd /usr/src; tar -jxvf oss-v4.2-build2002-src-gpl.tar.bz2 +1) cd /usr/src; tar -jxvf oss-v4.2-build2003-src-gpl.tar.bz2 2) mkdir /usr/src/oss; cd /usr/src/oss 3) /usr/src/$TARGETDIR/configure 4) make install diff -Nru oss4-4.2-build2002/=unpacked-tar1=/setup/Linux/spec.tmpl oss4-4.2-build2003/=unpacked-tar1=/setup/Linux/spec.tmpl --- oss4-4.2-build2002/=unpacked-tar1=/setup/Linux/spec.tmpl 2009-08-10 19:20:24.000000000 +0200 +++ oss4-4.2-build2003/=unpacked-tar1=/setup/Linux/spec.tmpl 2010-05-11 13:26:05.000000000 +0200 @@ -7,7 +7,12 @@ Vendor: 4Front Technologies Packager: 4Front Technologies BuildRoot: /tmp/prototype -Requires: gcc, kernel-devel +Requires: gcc, make +%if 0%{?suse_version} +Requires: kernel-default-devel +%else +Requires: kernel-devel +%endif %description Open Sound System for Linux (OSS/Linux) is a commercial quality sound driver diff -Nru oss4-4.2-build2002/=unpacked-tar1=/setup/srcconf.c oss4-4.2-build2003/=unpacked-tar1=/setup/srcconf.c --- oss4-4.2-build2002/=unpacked-tar1=/setup/srcconf.c 2009-11-13 16:23:24.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/setup/srcconf.c 2010-05-27 13:38:38.000000000 +0200 @@ -1321,7 +1321,7 @@ grc_max = q; } - if (grc_max > grc_min) + if (grc_max < grc_min) grc_max = grc_min = 3; fprintf (f, "#define CONFIG_OSS_GRC_MIN_QUALITY %d\n", grc_min); diff -Nru oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/dsp/help.c oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/dsp/help.c --- oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/dsp/help.c 2009-05-29 10:06:06.000000000 +0200 +++ oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/dsp/help.c 2010-05-11 13:26:05.000000000 +0200 @@ -46,7 +46,7 @@ "is malfunctioning or it's not supported by OSS.\n" "\n" - "NOTE! It may be necessary to reboot the system after installing OSS\n + "NOTE! It may be necessary to reboot the system after installing OSS\n" #ifdef LICENSED_VERSION "\n" "If you are a licensed customer then please fill the problem report at\n" Los archivos binarios /tmp/TOgfCHU0OD/oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/libossmix_demo/ossmixlib_demo y /tmp/fXBqChI6fF/oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/libossmix_demo/ossmixlib_demo son distintos diff -Nru oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/samples/fulldup.c oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/samples/fulldup.c --- oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/samples/fulldup.c 2008-12-13 16:18:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/samples/fulldup.c 2010-05-11 13:26:05.000000000 +0200 @@ -96,14 +96,17 @@ exit (-1); } -/* - * Turn on the full duplex mode. - */ +#if 0 + /* + * There is no point in calling SNDCTL_DSP_SETDUPLEX any more. This call has not had any + * effect since SB16. + */ if (ioctl (fd, SNDCTL_DSP_SETDUPLEX, NULL) == -1) { perror ("SNDCTL_DSP_SETDUPLEX"); exit (-1); } +#endif /* * Try to set the fragment size to suitable level. diff -Nru oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/softsynth/Makefile oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/softsynth/Makefile --- oss4-4.2-build2002/=unpacked-tar1=/tutorials/sndkit/softsynth/Makefile 2008-12-13 16:18:23.000000000 +0100 +++ oss4-4.2-build2003/=unpacked-tar1=/tutorials/sndkit/softsynth/Makefile 2010-05-11 13:26:05.000000000 +0200 @@ -10,9 +10,12 @@ softsynth: softsynth.c $(CC) $(CFLAGS) $(OSSINCLUDES) softsynth.c -o softsynth -lOSSlib -softsynth_gtk: softsynth_gtk.c +softsynth_gtk1: softsynth_gtk.c -$(CC) $(CFLAGS) `gtk-config --cflags --libs` $(OSSINCLUDES) softsynth_gtk.c -o softsynth_gtk -lOSSlib +softsynth_gtk: softsynth_gtk.c + -$(CC) $(CFLAGS) `pkg-config gtk+-2.0 --cflags --libs` $(OSSINCLUDES) softsynth_gtk.c -o softsynth_gtk -lOSSlib + install: all -cp softsynth softsynth_gtk $(BINDIR)