From 9295aea1e8e00ea83965eb739b8d0bd2ea03c7cb Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:00:17 +0200 Subject: ALSA: wss_lib: move cs4231_lib into wss_lib Move the file sound/isa/cs423x/cs4231_lib.c into sound/isa/cs423x/wss_lib.c This is the first step toward merging all libraries for Windows Sound System compatible chips into a single library. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/Kconfig | 28 +- sound/isa/Makefile | 2 +- sound/isa/cs423x/Makefile | 2 - sound/isa/cs423x/cs4231_lib.c | 1945 ----------------------------------------- sound/isa/wss/Makefile | 10 + sound/isa/wss/wss_lib.c | 1945 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1970 insertions(+), 1962 deletions(-) delete mode 100644 sound/isa/cs423x/cs4231_lib.c create mode 100644 sound/isa/wss/Makefile create mode 100644 sound/isa/wss/wss_lib.c (limited to 'sound/isa') diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 5769a13c1d95..87055568ccd4 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -4,7 +4,7 @@ config SND_AD1848_LIB tristate select SND_PCM -config SND_CS4231_LIB +config SND_WSS_LIB tristate select SND_PCM @@ -86,7 +86,7 @@ config SND_AZT2320 select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for soundcards based on the Aztech Systems AZT2320 chip. @@ -108,7 +108,7 @@ config SND_CMI8330 config SND_CS4231 tristate "Generic Cirrus Logic CS4231 driver" select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for CS4231 chips from Cirrus Logic - Crystal Semiconductors. @@ -120,7 +120,7 @@ config SND_CS4232 tristate "Generic Cirrus Logic CS4232 driver" select SND_OPL3_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for CS4232 chips from Cirrus Logic - Crystal Semiconductors. @@ -132,7 +132,7 @@ config SND_CS4236 tristate "Generic Cirrus Logic CS4236+ driver" select SND_OPL3_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y to include support for CS4235,CS4236,CS4237B,CS4238B, CS4239 chips from Cirrus Logic - Crystal Semiconductors. @@ -228,7 +228,7 @@ config SND_GUSEXTREME config SND_GUSMAX tristate "Gravis UltraSound MAX" select SND_RAWMIDI - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for Gravis UltraSound MAX soundcards. @@ -240,7 +240,7 @@ config SND_INTERWAVE tristate "AMD InterWave, Gravis UltraSound PnP" depends on PNP select SND_RAWMIDI - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for AMD InterWave based soundcards (Gravis UltraSound Plug & Play, STB SoundRage32, @@ -253,7 +253,7 @@ config SND_INTERWAVE_STB tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)" depends on PNP select SND_RAWMIDI - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for AMD InterWave based soundcards with a TEA6330T bass and treble regulator @@ -266,7 +266,7 @@ config SND_OPL3SA2 tristate "Yamaha OPL3-SA2/SA3" select SND_OPL3_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3 chips. @@ -292,7 +292,7 @@ config SND_OPTI92X_CS4231 select SND_OPL3_LIB select SND_OPL4_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for soundcards based on Opti 82C92x chips and using a CS4231 codec. @@ -304,7 +304,7 @@ config SND_OPTI93X tristate "OPTi 82C93x" select SND_OPL3_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for soundcards based on Opti 82C93x chips. @@ -315,7 +315,7 @@ config SND_OPTI93X config SND_MIRO tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" select SND_OPL4_LIB - select SND_CS4231_LIB + select SND_WSS_LIB select SND_MPU401_UART select SND_PCM help @@ -384,7 +384,7 @@ config SND_SSCAPE tristate "Ensoniq SoundScape PnP driver" select SND_HWDEP select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for Ensoniq SoundScape PnP soundcards. @@ -397,7 +397,7 @@ config SND_WAVEFRONT select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART - select SND_CS4231_LIB + select SND_WSS_LIB help Say Y here to include support for Turtle Beach Maui, Tropez and Tropez+ soundcards based on the Wavefront chip. diff --git a/sound/isa/Makefile b/sound/isa/Makefile index c0ce7db2a1b5..63af13d901a5 100644 --- a/sound/isa/Makefile +++ b/sound/isa/Makefile @@ -27,4 +27,4 @@ obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ opti9xx/ \ - sb/ wavefront/ + sb/ wavefront/ wss/ diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile index 5067ee001933..5870ca21ab59 100644 --- a/sound/isa/cs423x/Makefile +++ b/sound/isa/cs423x/Makefile @@ -3,14 +3,12 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-cs4231-lib-objs := cs4231_lib.o snd-cs4236-lib-objs := cs4236_lib.o snd-cs4231-objs := cs4231.o snd-cs4232-objs := cs4232.o snd-cs4236-objs := cs4236.o # Toplevel Module Dependency -obj-$(CONFIG_SND_CS4231_LIB) += snd-cs4231-lib.o obj-$(CONFIG_SND_CS4231) += snd-cs4231.o obj-$(CONFIG_SND_CS4232) += snd-cs4232.o obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c deleted file mode 100644 index 521db705d179..000000000000 --- a/sound/isa/cs423x/cs4231_lib.c +++ /dev/null @@ -1,1945 +0,0 @@ -/* - * Copyright (c) by Jaroslav Kysela - * Routines for control of CS4231(A)/CS4232/InterWave & compatible chips - * - * Bugs: - * - sometimes record brokes playback with WSS portion of - * Yamaha OPL3-SA3 chip - * - CS4231 (GUS MAX) - still trouble with occasional noises - * - broken initialization? - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips"); -MODULE_LICENSE("GPL"); - -#if 0 -#define SNDRV_DEBUG_MCE -#endif - -/* - * Some variables - */ - -static unsigned char freq_bits[14] = { - /* 5510 */ 0x00 | CS4231_XTAL2, - /* 6620 */ 0x0E | CS4231_XTAL2, - /* 8000 */ 0x00 | CS4231_XTAL1, - /* 9600 */ 0x0E | CS4231_XTAL1, - /* 11025 */ 0x02 | CS4231_XTAL2, - /* 16000 */ 0x02 | CS4231_XTAL1, - /* 18900 */ 0x04 | CS4231_XTAL2, - /* 22050 */ 0x06 | CS4231_XTAL2, - /* 27042 */ 0x04 | CS4231_XTAL1, - /* 32000 */ 0x06 | CS4231_XTAL1, - /* 33075 */ 0x0C | CS4231_XTAL2, - /* 37800 */ 0x08 | CS4231_XTAL2, - /* 44100 */ 0x0A | CS4231_XTAL2, - /* 48000 */ 0x0C | CS4231_XTAL1 -}; - -static unsigned int rates[14] = { - 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, - 27042, 32000, 33075, 37800, 44100, 48000 -}; - -static struct snd_pcm_hw_constraint_list hw_constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime) -{ - return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); -} - -static unsigned char snd_cs4231_original_image[32] = -{ - 0x00, /* 00/00 - lic */ - 0x00, /* 01/01 - ric */ - 0x9f, /* 02/02 - la1ic */ - 0x9f, /* 03/03 - ra1ic */ - 0x9f, /* 04/04 - la2ic */ - 0x9f, /* 05/05 - ra2ic */ - 0xbf, /* 06/06 - loc */ - 0xbf, /* 07/07 - roc */ - 0x20, /* 08/08 - pdfr */ - CS4231_AUTOCALIB, /* 09/09 - ic */ - 0x00, /* 0a/10 - pc */ - 0x00, /* 0b/11 - ti */ - CS4231_MODE2, /* 0c/12 - mi */ - 0xfc, /* 0d/13 - lbc */ - 0x00, /* 0e/14 - pbru */ - 0x00, /* 0f/15 - pbrl */ - 0x80, /* 10/16 - afei */ - 0x01, /* 11/17 - afeii */ - 0x9f, /* 12/18 - llic */ - 0x9f, /* 13/19 - rlic */ - 0x00, /* 14/20 - tlb */ - 0x00, /* 15/21 - thb */ - 0x00, /* 16/22 - la3mic/reserved */ - 0x00, /* 17/23 - ra3mic/reserved */ - 0x00, /* 18/24 - afs */ - 0x00, /* 19/25 - lamoc/version */ - 0xcf, /* 1a/26 - mioc */ - 0x00, /* 1b/27 - ramoc/reserved */ - 0x20, /* 1c/28 - cdfr */ - 0x00, /* 1d/29 - res4 */ - 0x00, /* 1e/30 - cbru */ - 0x00, /* 1f/31 - cbrl */ -}; - -static unsigned char snd_opti93x_original_image[32] = -{ - 0x00, /* 00/00 - l_mixout_outctrl */ - 0x00, /* 01/01 - r_mixout_outctrl */ - 0x88, /* 02/02 - l_cd_inctrl */ - 0x88, /* 03/03 - r_cd_inctrl */ - 0x88, /* 04/04 - l_a1/fm_inctrl */ - 0x88, /* 05/05 - r_a1/fm_inctrl */ - 0x80, /* 06/06 - l_dac_inctrl */ - 0x80, /* 07/07 - r_dac_inctrl */ - 0x00, /* 08/08 - ply_dataform_reg */ - 0x00, /* 09/09 - if_conf */ - 0x00, /* 0a/10 - pin_ctrl */ - 0x00, /* 0b/11 - err_init_reg */ - 0x0a, /* 0c/12 - id_reg */ - 0x00, /* 0d/13 - reserved */ - 0x00, /* 0e/14 - ply_upcount_reg */ - 0x00, /* 0f/15 - ply_lowcount_reg */ - 0x88, /* 10/16 - reserved/l_a1_inctrl */ - 0x88, /* 11/17 - reserved/r_a1_inctrl */ - 0x88, /* 12/18 - l_line_inctrl */ - 0x88, /* 13/19 - r_line_inctrl */ - 0x88, /* 14/20 - l_mic_inctrl */ - 0x88, /* 15/21 - r_mic_inctrl */ - 0x80, /* 16/22 - l_out_outctrl */ - 0x80, /* 17/23 - r_out_outctrl */ - 0x00, /* 18/24 - reserved */ - 0x00, /* 19/25 - reserved */ - 0x00, /* 1a/26 - reserved */ - 0x00, /* 1b/27 - reserved */ - 0x00, /* 1c/28 - cap_dataform_reg */ - 0x00, /* 1d/29 - reserved */ - 0x00, /* 1e/30 - cap_upcount_reg */ - 0x00 /* 1f/31 - cap_lowcount_reg */ -}; - -/* - * Basic I/O functions - */ - -static inline void cs4231_outb(struct snd_cs4231 *chip, u8 offset, u8 val) -{ - outb(val, chip->port + offset); -} - -static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset) -{ - return inb(chip->port + offset); -} - -static void snd_cs4231_wait(struct snd_cs4231 *chip) -{ - int timeout; - - for (timeout = 250; - timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); - timeout--) - udelay(100); -} - -static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, - unsigned char mask, unsigned char value) -{ - unsigned char tmp = (chip->image[reg] & mask) | value; - - snd_cs4231_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); -#endif - chip->image[reg] = tmp; - if (!chip->calibrate_mute) { - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); - wmb(); - cs4231_outb(chip, CS4231P(REG), tmp); - mb(); - } -} - -static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) -{ - int timeout; - - for (timeout = 250; - timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); - timeout--) - udelay(10); - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); - cs4231_outb(chip, CS4231P(REG), value); - mb(); -} - -void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) -{ - snd_cs4231_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); -#endif - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); - cs4231_outb(chip, CS4231P(REG), value); - chip->image[reg] = value; - mb(); - snd_printdd("codec out - reg 0x%x = 0x%x\n", - chip->mce_bit | reg, value); -} - -unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) -{ - snd_cs4231_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); -#endif - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); - mb(); - return cs4231_inb(chip, CS4231P(REG)); -} - -void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val) -{ - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); - cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); - cs4231_outb(chip, CS4231P(REG), val); - chip->eimage[CS4236_REG(reg)] = val; -#if 0 - printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val); -#endif -} - -unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg) -{ - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); - cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); -#if 1 - return cs4231_inb(chip, CS4231P(REG)); -#else - { - unsigned char res; - res = cs4231_inb(chip, CS4231P(REG)); - printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res); - return res; - } -#endif -} - -#if 0 - -static void snd_cs4231_debug(struct snd_cs4231 *chip) -{ - printk("CS4231 REGS: INDEX = 0x%02x ", cs4231_inb(chip, CS4231P(REGSEL))); - printk(" STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS))); - printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00)); - printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10)); - printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01)); - printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11)); - printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02)); - printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12)); - printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03)); - printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13)); - printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04)); - printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14)); - printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05)); - printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15)); - printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06)); - printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16)); - printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07)); - printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17)); - printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08)); - printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18)); - printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09)); - printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19)); - printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a)); - printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a)); - printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b)); - printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b)); - printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c)); - printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c)); - printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d)); - printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d)); - printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e)); - printk(" 0x1e: ply lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e)); - printk(" 0x0f: rec upr count = 0x%02x ", snd_cs4231_in(chip, 0x0f)); - printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f)); -} - -#endif - -/* - * CS4231 detection / MCE routines - */ - -static void snd_cs4231_busy_wait(struct snd_cs4231 *chip) -{ - int timeout; - - /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */ - for (timeout = 5; timeout > 0; timeout--) - cs4231_inb(chip, CS4231P(REGSEL)); - /* end of cleanup sequence */ - for (timeout = 250; - timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); - timeout--) - udelay(10); -} - -void snd_cs4231_mce_up(struct snd_cs4231 *chip) -{ - unsigned long flags; - int timeout; - - snd_cs4231_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk("mce_up - auto calibration time out (0)\n"); -#endif - spin_lock_irqsave(&chip->reg_lock, flags); - chip->mce_bit |= CS4231_MCE; - timeout = cs4231_inb(chip, CS4231P(REGSEL)); - if (timeout == 0x80) - snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); - if (!(timeout & CS4231_MCE)) - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); - spin_unlock_irqrestore(&chip->reg_lock, flags); -} - -void snd_cs4231_mce_down(struct snd_cs4231 *chip) -{ - unsigned long flags; - unsigned long end_time; - int timeout; - - snd_cs4231_busy_wait(chip); - -#ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); -#endif - spin_lock_irqsave(&chip->reg_lock, flags); - chip->mce_bit &= ~CS4231_MCE; - timeout = cs4231_inb(chip, CS4231P(REGSEL)); - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (timeout == 0x80) - snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); - if ((timeout & CS4231_MCE) == 0 || - !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { - return; - } - - /* - * Wait for (possible -- during init auto-calibration may not be set) - * calibration process to start. Needs upto 5 sample periods on AD1848 - * which at the slowest possible rate of 5.5125 kHz means 907 us. - */ - msleep(1); - - snd_printdd("(1) jiffies = %lu\n", jiffies); - - /* check condition up to 250 ms */ - end_time = jiffies + msecs_to_jiffies(250); - while (snd_cs4231_in(chip, CS4231_TEST_INIT) & - CS4231_CALIB_IN_PROGRESS) { - - if (time_after(jiffies, end_time)) { - snd_printk(KERN_ERR "mce_down - " - "auto calibration time out (2)\n"); - return; - } - msleep(1); - } - - snd_printdd("(2) jiffies = %lu\n", jiffies); - - /* check condition up to 100 ms */ - end_time = jiffies + msecs_to_jiffies(100); - while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { - if (time_after(jiffies, end_time)) { - snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); - return; - } - msleep(1); - } - - snd_printdd("(3) jiffies = %lu\n", jiffies); - snd_printd("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL))); -} - -static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size) -{ - switch (format & 0xe0) { - case CS4231_LINEAR_16: - case CS4231_LINEAR_16_BIG: - size >>= 1; - break; - case CS4231_ADPCM_16: - return size >> 2; - } - if (format & CS4231_STEREO) - size >>= 1; - return size; -} - -static int snd_cs4231_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - int result = 0; - unsigned int what; - struct snd_pcm_substream *s; - int do_start; - -#if 0 - printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, cs4231_inb(chip, CS4231P(STATUS))); -#endif - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - do_start = 1; break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - do_start = 0; break; - default: - return -EINVAL; - } - - what = 0; - snd_pcm_group_for_each_entry(s, substream) { - if (s == chip->playback_substream) { - what |= CS4231_PLAYBACK_ENABLE; - snd_pcm_trigger_done(s, substream); - } else if (s == chip->capture_substream) { - what |= CS4231_RECORD_ENABLE; - snd_pcm_trigger_done(s, substream); - } - } - spin_lock(&chip->reg_lock); - if (do_start) { - chip->image[CS4231_IFACE_CTRL] |= what; - if (chip->trigger) - chip->trigger(chip, what, 1); - } else { - chip->image[CS4231_IFACE_CTRL] &= ~what; - if (chip->trigger) - chip->trigger(chip, what, 0); - } - snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); - spin_unlock(&chip->reg_lock); -#if 0 - snd_cs4231_debug(chip); -#endif - return result; -} - -/* - * CODEC I/O - */ - -static unsigned char snd_cs4231_get_rate(unsigned int rate) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(rates); i++) - if (rate == rates[i]) - return freq_bits[i]; - // snd_BUG(); - return freq_bits[ARRAY_SIZE(rates) - 1]; -} - -static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, - int format, - int channels) -{ - unsigned char rformat; - - rformat = CS4231_LINEAR_8; - switch (format) { - case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break; - case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break; - case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break; - case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break; - case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break; - } - if (channels > 1) - rformat |= CS4231_STEREO; -#if 0 - snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode); -#endif - return rformat; -} - -static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute) -{ - unsigned long flags; - - mute = mute ? 1 : 0; - spin_lock_irqsave(&chip->reg_lock, flags); - if (chip->calibrate_mute == mute) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - return; - } - if (!mute) { - snd_cs4231_dout(chip, CS4231_LEFT_INPUT, chip->image[CS4231_LEFT_INPUT]); - snd_cs4231_dout(chip, CS4231_RIGHT_INPUT, chip->image[CS4231_RIGHT_INPUT]); - snd_cs4231_dout(chip, CS4231_LOOPBACK, chip->image[CS4231_LOOPBACK]); - } - snd_cs4231_dout(chip, CS4231_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]); - snd_cs4231_dout(chip, CS4231_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]); - snd_cs4231_dout(chip, CS4231_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]); - snd_cs4231_dout(chip, CS4231_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]); - snd_cs4231_dout(chip, CS4231_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]); - snd_cs4231_dout(chip, CS4231_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]); - snd_cs4231_dout(chip, CS4231_LEFT_LINE_IN, mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); - snd_cs4231_dout(chip, CS4231_RIGHT_LINE_IN, mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); - snd_cs4231_dout(chip, CS4231_MONO_CTRL, mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); - if (chip->hardware == CS4231_HW_INTERWAVE) { - snd_cs4231_dout(chip, CS4231_LEFT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]); - snd_cs4231_dout(chip, CS4231_RIGHT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]); - snd_cs4231_dout(chip, CS4231_LINE_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]); - snd_cs4231_dout(chip, CS4231_LINE_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]); - } - chip->calibrate_mute = mute; - spin_unlock_irqrestore(&chip->reg_lock, flags); -} - -static void snd_cs4231_playback_format(struct snd_cs4231 *chip, - struct snd_pcm_hw_params *params, - unsigned char pdfr) -{ - unsigned long flags; - int full_calib = 1; - - mutex_lock(&chip->mce_mutex); - snd_cs4231_calibrate_mute(chip, 1); - if (chip->hardware == CS4231_HW_CS4231A || - (chip->hardware & CS4231_HW_CS4232_MASK)) { - spin_lock_irqsave(&chip->reg_lock, flags); - if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */ - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10); - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x10); - udelay(100); /* Fixes audible clicks at least on GUS MAX */ - full_calib = 0; - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - } - if (full_calib) { - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - if (chip->hardware != CS4231_HW_INTERWAVE && !chip->single_dma) { - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, - (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ? - (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) : - pdfr); - } else { - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr); - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (chip->hardware == CS4231_HW_OPL3SA2) - udelay(100); /* this seems to help */ - snd_cs4231_mce_down(chip); - } - snd_cs4231_calibrate_mute(chip, 0); - mutex_unlock(&chip->mce_mutex); -} - -static void snd_cs4231_capture_format(struct snd_cs4231 *chip, - struct snd_pcm_hw_params *params, - unsigned char cdfr) -{ - unsigned long flags; - int full_calib = 1; - - mutex_lock(&chip->mce_mutex); - snd_cs4231_calibrate_mute(chip, 1); - if (chip->hardware == CS4231_HW_CS4231A || - (chip->hardware & CS4231_HW_CS4232_MASK)) { - spin_lock_irqsave(&chip->reg_lock, flags); - if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */ - (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20); - snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT] = cdfr); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x20); - full_calib = 0; - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - } - if (full_calib) { - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - if (chip->hardware != CS4231_HW_INTERWAVE) { - if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, - ((chip->single_dma ? cdfr : chip->image[CS4231_PLAYBK_FORMAT]) & 0xf0) | - (cdfr & 0x0f)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - } - } - snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - } - snd_cs4231_calibrate_mute(chip, 0); - mutex_unlock(&chip->mce_mutex); -} - -/* - * Timer interface - */ - -static unsigned long snd_cs4231_timer_resolution(struct snd_timer * timer) -{ - struct snd_cs4231 *chip = snd_timer_chip(timer); - if (chip->hardware & CS4231_HW_CS4236B_MASK) - return 14467; - else - return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920; -} - -static int snd_cs4231_timer_start(struct snd_timer * timer) -{ - unsigned long flags; - unsigned int ticks; - struct snd_cs4231 *chip = snd_timer_chip(timer); - spin_lock_irqsave(&chip->reg_lock, flags); - ticks = timer->sticks; - if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 || - (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] || - (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) { - snd_cs4231_out(chip, CS4231_TIMER_HIGH, chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8)); - snd_cs4231_out(chip, CS4231_TIMER_LOW, chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE); - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -static int snd_cs4231_timer_stop(struct snd_timer * timer) -{ - unsigned long flags; - struct snd_cs4231 *chip = snd_timer_chip(timer); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -static void snd_cs4231_init(struct snd_cs4231 *chip) -{ - unsigned long flags; - - snd_cs4231_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("init: (1)\n"); -#endif - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | - CS4231_RECORD_ENABLE | CS4231_RECORD_PIO | - CS4231_CALIB_MODE); - chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB; - snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("init: (2)\n"); -#endif - - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]); -#endif - - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("init: (4)\n"); -#endif - - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("init: (5)\n"); -#endif -} - -static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) -{ - unsigned long flags; - - mutex_lock(&chip->open_mutex); - if ((chip->mode & mode) || - ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) { - mutex_unlock(&chip->open_mutex); - return -EAGAIN; - } - if (chip->mode & CS4231_MODE_OPEN) { - chip->mode |= mode; - mutex_unlock(&chip->open_mutex); - return 0; - } - /* ok. now enable and ack CODEC IRQ */ - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | - CS4231_RECORD_IRQ | - CS4231_TIMER_IRQ); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE; - snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | - CS4231_RECORD_IRQ | - CS4231_TIMER_IRQ); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - chip->mode = mode; - mutex_unlock(&chip->open_mutex); - return 0; -} - -static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) -{ - unsigned long flags; - - mutex_lock(&chip->open_mutex); - chip->mode &= ~mode; - if (chip->mode & CS4231_MODE_OPEN) { - mutex_unlock(&chip->open_mutex); - return; - } - snd_cs4231_calibrate_mute(chip, 1); - - /* disable IRQ */ - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE; - snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); - - /* now disable record & playback */ - - if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | - CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | - CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); - snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - } - - /* clear IRQ again */ - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - spin_unlock_irqrestore(&chip->reg_lock, flags); - - snd_cs4231_calibrate_mute(chip, 0); - - chip->mode = 0; - mutex_unlock(&chip->open_mutex); -} - -/* - * timer open/close - */ - -static int snd_cs4231_timer_open(struct snd_timer * timer) -{ - struct snd_cs4231 *chip = snd_timer_chip(timer); - snd_cs4231_open(chip, CS4231_MODE_TIMER); - return 0; -} - -static int snd_cs4231_timer_close(struct snd_timer * timer) -{ - struct snd_cs4231 *chip = snd_timer_chip(timer); - snd_cs4231_close(chip, CS4231_MODE_TIMER); - return 0; -} - -static struct snd_timer_hardware snd_cs4231_timer_table = -{ - .flags = SNDRV_TIMER_HW_AUTO, - .resolution = 9945, - .ticks = 65535, - .open = snd_cs4231_timer_open, - .close = snd_cs4231_timer_close, - .c_resolution = snd_cs4231_timer_resolution, - .start = snd_cs4231_timer_start, - .stop = snd_cs4231_timer_stop, -}; - -/* - * ok.. exported functions.. - */ - -static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - unsigned char new_pdfr; - int err; - - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) - return err; - new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) | - snd_cs4231_get_rate(params_rate(hw_params)); - chip->set_playback_format(chip, hw_params, new_pdfr); - return 0; -} - -static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long flags; - unsigned int size = snd_pcm_lib_buffer_bytes(substream); - unsigned int count = snd_pcm_lib_period_bytes(substream); - - spin_lock_irqsave(&chip->reg_lock, flags); - chip->p_dma_size = size; - chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO); - snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); - count = snd_cs4231_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1; - snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); - snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); - spin_unlock_irqrestore(&chip->reg_lock, flags); -#if 0 - snd_cs4231_debug(chip); -#endif - return 0; -} - -static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - unsigned char new_cdfr; - int err; - - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) - return err; - new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) | - snd_cs4231_get_rate(params_rate(hw_params)); - chip->set_capture_format(chip, hw_params, new_cdfr); - return 0; -} - -static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long flags; - unsigned int size = snd_pcm_lib_buffer_bytes(substream); - unsigned int count = snd_pcm_lib_period_bytes(substream); - - spin_lock_irqsave(&chip->reg_lock, flags); - chip->c_dma_size = size; - chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); - snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); - count = snd_cs4231_get_count(chip->image[CS4231_REC_FORMAT], count) - 1; - if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) { - snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); - snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); - } else { - snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count); - snd_cs4231_out(chip, CS4231_REC_UPR_CNT, (unsigned char) (count >> 8)); - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -void snd_cs4231_overrange(struct snd_cs4231 *chip) -{ - unsigned long flags; - unsigned char res; - - spin_lock_irqsave(&chip->reg_lock, flags); - res = snd_cs4231_in(chip, CS4231_TEST_INIT); - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */ - chip->capture_substream->runtime->overrange++; -} - -irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id) -{ - struct snd_cs4231 *chip = dev_id; - unsigned char status; - - status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); - if (status & CS4231_TIMER_IRQ) { - if (chip->timer) - snd_timer_interrupt(chip->timer, chip->timer->sticks); - } - if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) { - if (status & CS4231_PLAYBACK_IRQ) { - if (chip->mode & CS4231_MODE_PLAY) { - if (chip->playback_substream) - snd_pcm_period_elapsed(chip->playback_substream); - } - if (chip->mode & CS4231_MODE_RECORD) { - if (chip->capture_substream) { - snd_cs4231_overrange(chip); - snd_pcm_period_elapsed(chip->capture_substream); - } - } - } - } else { - if (status & CS4231_PLAYBACK_IRQ) { - if (chip->playback_substream) - snd_pcm_period_elapsed(chip->playback_substream); - } - if (status & CS4231_RECORD_IRQ) { - if (chip->capture_substream) { - snd_cs4231_overrange(chip); - snd_pcm_period_elapsed(chip->capture_substream); - } - } - } - - spin_lock(&chip->reg_lock); - snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); - spin_unlock(&chip->reg_lock); - return IRQ_HANDLED; -} - -static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) - return 0; - ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); - return bytes_to_frames(substream->runtime, ptr); -} - -static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) - return 0; - ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); - return bytes_to_frames(substream->runtime, ptr); -} - -/* - - */ - -static int snd_cs4231_probe(struct snd_cs4231 *chip) -{ - unsigned long flags; - int i, id, rev; - unsigned char *ptr; - unsigned int hw; - -#if 0 - snd_cs4231_debug(chip); -#endif - id = 0; - for (i = 0; i < 50; i++) { - mb(); - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - udelay(2000); - else { - spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2); - id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f; - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (id == 0x0a) - break; /* this is valid value */ - } - } - snd_printdd("cs4231: port = 0x%lx, id = 0x%x\n", chip->port, id); - if (id != 0x0a) - return -ENODEV; /* no valid device found */ - - if (((hw = chip->hardware) & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) { - rev = snd_cs4231_in(chip, CS4231_VERSION) & 0xe7; - snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev); - if (rev == 0x80) { - unsigned char tmp = snd_cs4231_in(chip, 23); - snd_cs4231_out(chip, 23, ~tmp); - if (snd_cs4231_in(chip, 23) != tmp) - chip->hardware = CS4231_HW_AD1845; - else - chip->hardware = CS4231_HW_CS4231; - } else if (rev == 0xa0) { - chip->hardware = CS4231_HW_CS4231A; - } else if (rev == 0xa2) { - chip->hardware = CS4231_HW_CS4232; - } else if (rev == 0xb2) { - chip->hardware = CS4231_HW_CS4232A; - } else if (rev == 0x83) { - chip->hardware = CS4231_HW_CS4236; - } else if (rev == 0x03) { - chip->hardware = CS4231_HW_CS4236B; - } else { - snd_printk("unknown CS chip with version 0x%x\n", rev); - return -ENODEV; /* unknown CS4231 chip? */ - } - } - spin_lock_irqsave(&chip->reg_lock, flags); - cs4231_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); - mb(); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - chip->image[CS4231_MISC_INFO] = CS4231_MODE2; - switch (chip->hardware) { - case CS4231_HW_INTERWAVE: - chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3; - break; - case CS4231_HW_CS4235: - case CS4231_HW_CS4236B: - case CS4231_HW_CS4237B: - case CS4231_HW_CS4238B: - case CS4231_HW_CS4239: - if (hw == CS4231_HW_DETECT3) - chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3; - else - chip->hardware = CS4231_HW_CS4236; - break; - } - - chip->image[CS4231_IFACE_CTRL] = - (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) | - (chip->single_dma ? CS4231_SINGLE_DMA : 0); - if (chip->hardware != CS4231_HW_OPTI93X) { - chip->image[CS4231_ALT_FEATURE_1] = 0x80; - chip->image[CS4231_ALT_FEATURE_2] = - chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01; - } - ptr = (unsigned char *) &chip->image; - snd_cs4231_mce_down(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */ - snd_cs4231_out(chip, i, *ptr++); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_up(chip); - snd_cs4231_mce_down(chip); - - mdelay(2); - - /* ok.. try check hardware version for CS4236+ chips */ - if ((hw & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) { - if (chip->hardware == CS4231_HW_CS4236B) { - rev = snd_cs4236_ext_in(chip, CS4236_VERSION); - snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff); - id = snd_cs4236_ext_in(chip, CS4236_VERSION); - snd_cs4236_ext_out(chip, CS4236_VERSION, rev); - snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id); - if ((id & 0x1f) == 0x1d) { /* CS4235 */ - chip->hardware = CS4231_HW_CS4235; - switch (id >> 5) { - case 4: - case 5: - case 6: - break; - default: - snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id); - } - } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */ - switch (id >> 5) { - case 4: - case 5: - case 6: - case 7: - chip->hardware = CS4231_HW_CS4236B; - break; - default: - snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id); - } - } else if ((id & 0x1f) == 0x08) { /* CS4237B */ - chip->hardware = CS4231_HW_CS4237B; - switch (id >> 5) { - case 4: - case 5: - case 6: - case 7: - break; - default: - snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id); - } - } else if ((id & 0x1f) == 0x09) { /* CS4238B */ - chip->hardware = CS4231_HW_CS4238B; - switch (id >> 5) { - case 5: - case 6: - case 7: - break; - default: - snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id); - } - } else if ((id & 0x1f) == 0x1e) { /* CS4239 */ - chip->hardware = CS4231_HW_CS4239; - switch (id >> 5) { - case 4: - case 5: - case 6: - break; - default: - snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id); - } - } else { - snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id); - } - } - } - return 0; /* all things are ok.. */ -} - -/* - - */ - -static struct snd_pcm_hardware snd_cs4231_playback = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | - SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - .rate_min = 5510, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = 64, - .period_bytes_max = (128*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static struct snd_pcm_hardware snd_cs4231_capture = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | - SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - .rate_min = 5510, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = 64, - .period_bytes_max = (128*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -/* - - */ - -static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - runtime->hw = snd_cs4231_playback; - - /* hardware bug in InterWave chipset */ - if (chip->hardware == CS4231_HW_INTERWAVE && chip->dma1 > 3) - runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW; - - /* hardware limitation of cheap chips */ - if (chip->hardware == CS4231_HW_CS4235 || - chip->hardware == CS4231_HW_CS4239) - runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; - - snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max); - - if (chip->claim_dma) { - if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0) - return err; - } - - if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) { - if (chip->release_dma) - chip->release_dma(chip, chip->dma_private_data, chip->dma1); - snd_free_pages(runtime->dma_area, runtime->dma_bytes); - return err; - } - chip->playback_substream = substream; - snd_pcm_set_sync(substream); - chip->rate_constraint(runtime); - return 0; -} - -static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - runtime->hw = snd_cs4231_capture; - - /* hardware limitation of cheap chips */ - if (chip->hardware == CS4231_HW_CS4235 || - chip->hardware == CS4231_HW_CS4239) - runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; - - snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); - - if (chip->claim_dma) { - if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0) - return err; - } - - if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) { - if (chip->release_dma) - chip->release_dma(chip, chip->dma_private_data, chip->dma2); - snd_free_pages(runtime->dma_area, runtime->dma_bytes); - return err; - } - chip->capture_substream = substream; - snd_pcm_set_sync(substream); - chip->rate_constraint(runtime); - return 0; -} - -static int snd_cs4231_playback_close(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - - chip->playback_substream = NULL; - snd_cs4231_close(chip, CS4231_MODE_PLAY); - return 0; -} - -static int snd_cs4231_capture_close(struct snd_pcm_substream *substream) -{ - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); - - chip->capture_substream = NULL; - snd_cs4231_close(chip, CS4231_MODE_RECORD); - return 0; -} - -#ifdef CONFIG_PM - -/* lowlevel suspend callback for CS4231 */ -static void snd_cs4231_suspend(struct snd_cs4231 *chip) -{ - int reg; - unsigned long flags; - - snd_pcm_suspend_all(chip->pcm); - spin_lock_irqsave(&chip->reg_lock, flags); - for (reg = 0; reg < 32; reg++) - chip->image[reg] = snd_cs4231_in(chip, reg); - spin_unlock_irqrestore(&chip->reg_lock, flags); -} - -/* lowlevel resume callback for CS4231 */ -static void snd_cs4231_resume(struct snd_cs4231 *chip) -{ - int reg; - unsigned long flags; - /* int timeout; */ - - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - for (reg = 0; reg < 32; reg++) { - switch (reg) { - case CS4231_VERSION: - break; - default: - snd_cs4231_out(chip, reg, chip->image[reg]); - break; - } - } - spin_unlock_irqrestore(&chip->reg_lock, flags); -#if 1 - snd_cs4231_mce_down(chip); -#else - /* The following is a workaround to avoid freeze after resume on TP600E. - This is the first half of copy of snd_cs4231_mce_down(), but doesn't - include rescheduling. -- iwai - */ - snd_cs4231_busy_wait(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - chip->mce_bit &= ~CS4231_MCE; - timeout = cs4231_inb(chip, CS4231P(REGSEL)); - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (timeout == 0x80) - snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); - if ((timeout & CS4231_MCE) == 0 || - !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { - return; - } - snd_cs4231_busy_wait(chip); -#endif -} -#endif /* CONFIG_PM */ - -static int snd_cs4231_free(struct snd_cs4231 *chip) -{ - release_and_free_resource(chip->res_port); - release_and_free_resource(chip->res_cport); - if (chip->irq >= 0) { - disable_irq(chip->irq); - if (!(chip->hwshare & CS4231_HWSHARE_IRQ)) - free_irq(chip->irq, (void *) chip); - } - if (!(chip->hwshare & CS4231_HWSHARE_DMA1) && chip->dma1 >= 0) { - snd_dma_disable(chip->dma1); - free_dma(chip->dma1); - } - if (!(chip->hwshare & CS4231_HWSHARE_DMA2) && chip->dma2 >= 0 && chip->dma2 != chip->dma1) { - snd_dma_disable(chip->dma2); - free_dma(chip->dma2); - } - if (chip->timer) - snd_device_free(chip->card, chip->timer); - kfree(chip); - return 0; -} - -static int snd_cs4231_dev_free(struct snd_device *device) -{ - struct snd_cs4231 *chip = device->device_data; - return snd_cs4231_free(chip); -} - -const char *snd_cs4231_chip_id(struct snd_cs4231 *chip) -{ - switch (chip->hardware) { - case CS4231_HW_CS4231: return "CS4231"; - case CS4231_HW_CS4231A: return "CS4231A"; - case CS4231_HW_CS4232: return "CS4232"; - case CS4231_HW_CS4232A: return "CS4232A"; - case CS4231_HW_CS4235: return "CS4235"; - case CS4231_HW_CS4236: return "CS4236"; - case CS4231_HW_CS4236B: return "CS4236B"; - case CS4231_HW_CS4237B: return "CS4237B"; - case CS4231_HW_CS4238B: return "CS4238B"; - case CS4231_HW_CS4239: return "CS4239"; - case CS4231_HW_INTERWAVE: return "AMD InterWave"; - case CS4231_HW_OPL3SA2: return chip->card->shortname; - case CS4231_HW_AD1845: return "AD1845"; - case CS4231_HW_OPTI93X: return "OPTi 93x"; - default: return "???"; - } -} - -static int snd_cs4231_new(struct snd_card *card, - unsigned short hardware, - unsigned short hwshare, - struct snd_cs4231 ** rchip) -{ - struct snd_cs4231 *chip; - - *rchip = NULL; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - chip->hardware = hardware; - chip->hwshare = hwshare; - - spin_lock_init(&chip->reg_lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); - chip->card = card; - chip->rate_constraint = snd_cs4231_xrate; - chip->set_playback_format = snd_cs4231_playback_format; - chip->set_capture_format = snd_cs4231_capture_format; - if (chip->hardware == CS4231_HW_OPTI93X) - memcpy(&chip->image, &snd_opti93x_original_image, - sizeof(snd_opti93x_original_image)); - else - memcpy(&chip->image, &snd_cs4231_original_image, - sizeof(snd_cs4231_original_image)); - - *rchip = chip; - return 0; -} - -int snd_cs4231_create(struct snd_card *card, - unsigned long port, - unsigned long cport, - int irq, int dma1, int dma2, - unsigned short hardware, - unsigned short hwshare, - struct snd_cs4231 ** rchip) -{ - static struct snd_device_ops ops = { - .dev_free = snd_cs4231_dev_free, - }; - struct snd_cs4231 *chip; - int err; - - err = snd_cs4231_new(card, hardware, hwshare, &chip); - if (err < 0) - return err; - - chip->irq = -1; - chip->dma1 = -1; - chip->dma2 = -1; - - if ((chip->res_port = request_region(port, 4, "CS4231")) == NULL) { - snd_printk(KERN_ERR "cs4231: can't grab port 0x%lx\n", port); - snd_cs4231_free(chip); - return -EBUSY; - } - chip->port = port; - if ((long)cport >= 0 && (chip->res_cport = request_region(cport, 8, "CS4232 Control")) == NULL) { - snd_printk(KERN_ERR "cs4231: can't grab control port 0x%lx\n", cport); - snd_cs4231_free(chip); - return -ENODEV; - } - chip->cport = cport; - if (!(hwshare & CS4231_HWSHARE_IRQ) && request_irq(irq, snd_cs4231_interrupt, IRQF_DISABLED, "CS4231", (void *) chip)) { - snd_printk(KERN_ERR "cs4231: can't grab IRQ %d\n", irq); - snd_cs4231_free(chip); - return -EBUSY; - } - chip->irq = irq; - if (!(hwshare & CS4231_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) { - snd_printk(KERN_ERR "cs4231: can't grab DMA1 %d\n", dma1); - snd_cs4231_free(chip); - return -EBUSY; - } - chip->dma1 = dma1; - if (!(hwshare & CS4231_HWSHARE_DMA2) && dma1 != dma2 && dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) { - snd_printk(KERN_ERR "cs4231: can't grab DMA2 %d\n", dma2); - snd_cs4231_free(chip); - return -EBUSY; - } - if (dma1 == dma2 || dma2 < 0) { - chip->single_dma = 1; - chip->dma2 = chip->dma1; - } else - chip->dma2 = dma2; - - /* global setup */ - if (snd_cs4231_probe(chip) < 0) { - snd_cs4231_free(chip); - return -ENODEV; - } - snd_cs4231_init(chip); - -#if 0 - if (chip->hardware & CS4231_HW_CS4232_MASK) { - if (chip->res_cport == NULL) - snd_printk("CS4232 control port features are not accessible\n"); - } -#endif - - /* Register device */ - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_cs4231_free(chip); - return err; - } - -#ifdef CONFIG_PM - /* Power Management */ - chip->suspend = snd_cs4231_suspend; - chip->resume = snd_cs4231_resume; -#endif - - *rchip = chip; - return 0; -} - -static struct snd_pcm_ops snd_cs4231_playback_ops = { - .open = snd_cs4231_playback_open, - .close = snd_cs4231_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cs4231_playback_hw_params, - .hw_free = snd_cs4231_playback_hw_free, - .prepare = snd_cs4231_playback_prepare, - .trigger = snd_cs4231_trigger, - .pointer = snd_cs4231_playback_pointer, -}; - -static struct snd_pcm_ops snd_cs4231_capture_ops = { - .open = snd_cs4231_capture_open, - .close = snd_cs4231_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cs4231_capture_hw_params, - .hw_free = snd_cs4231_capture_hw_free, - .prepare = snd_cs4231_capture_prepare, - .trigger = snd_cs4231_trigger, - .pointer = snd_cs4231_capture_pointer, -}; - -int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) -{ - struct snd_pcm *pcm; - int err; - - if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0) - return err; - - spin_lock_init(&chip->reg_lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); - - /* global setup */ - pcm->private_data = chip; - pcm->info_flags = 0; - if (chip->single_dma) - pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; - if (chip->hardware != CS4231_HW_INTERWAVE) - pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; - strcpy(pcm->name, snd_cs4231_chip_id(chip)); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_isa_data(), - 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); - - chip->pcm = pcm; - if (rpcm) - *rpcm = pcm; - return 0; -} - -static void snd_cs4231_timer_free(struct snd_timer *timer) -{ - struct snd_cs4231 *chip = timer->private_data; - chip->timer = NULL; -} - -int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rtimer) -{ - struct snd_timer *timer; - struct snd_timer_id tid; - int err; - - /* Timer initialization */ - tid.dev_class = SNDRV_TIMER_CLASS_CARD; - tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; - tid.card = chip->card->number; - tid.device = device; - tid.subdevice = 0; - if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0) - return err; - strcpy(timer->name, snd_cs4231_chip_id(chip)); - timer->private_data = chip; - timer->private_free = snd_cs4231_timer_free; - timer->hw = snd_cs4231_timer_table; - chip->timer = timer; - if (rtimer) - *rtimer = timer; - return 0; -} - -/* - * MIXER part - */ - -static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - static char *texts[4] = { - "Line", "Aux", "Mic", "Mix" - }; - static char *opl3sa_texts[4] = { - "Line", "CD", "Mic", "Mix" - }; - static char *gusmax_texts[4] = { - "Line", "Synth", "Mic", "Mix" - }; - char **ptexts = texts; - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - - snd_assert(chip->card != NULL, return -EINVAL); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - if (!strcmp(chip->card->driver, "GUS MAX")) - ptexts = gusmax_texts; - switch (chip->hardware) { - case CS4231_HW_INTERWAVE: ptexts = gusmax_texts; break; - case CS4231_HW_OPL3SA2: ptexts = opl3sa_texts; break; - } - strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - - spin_lock_irqsave(&chip->reg_lock, flags); - ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6; - ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6; - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - unsigned short left, right; - int change; - - if (ucontrol->value.enumerated.item[0] > 3 || - ucontrol->value.enumerated.item[1] > 3) - return -EINVAL; - left = ucontrol->value.enumerated.item[0] << 6; - right = ucontrol->value.enumerated.item[1] << 6; - spin_lock_irqsave(&chip->reg_lock, flags); - left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left; - right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right; - change = left != chip->image[CS4231_LEFT_INPUT] || - right != chip->image[CS4231_RIGHT_INPUT]; - snd_cs4231_out(chip, CS4231_LEFT_INPUT, left); - snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return change; -} - -int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 16) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0xff; - - spin_lock_irqsave(&chip->reg_lock, flags); - ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask; - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (invert) - ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; - return 0; -} - -int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0xff; - int change; - unsigned short val; - - val = (ucontrol->value.integer.value[0] & mask); - if (invert) - val = mask - val; - val <<= shift; - spin_lock_irqsave(&chip->reg_lock, flags); - val = (chip->image[reg] & ~(mask << shift)) | val; - change = val != chip->image[reg]; - snd_cs4231_out(chip, reg, val); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return change; -} - -int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 24) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int left_reg = kcontrol->private_value & 0xff; - int right_reg = (kcontrol->private_value >> 8) & 0xff; - int shift_left = (kcontrol->private_value >> 16) & 0x07; - int shift_right = (kcontrol->private_value >> 19) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - - spin_lock_irqsave(&chip->reg_lock, flags); - ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask; - ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask; - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (invert) { - ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; - ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; - } - return 0; -} - -int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int left_reg = kcontrol->private_value & 0xff; - int right_reg = (kcontrol->private_value >> 8) & 0xff; - int shift_left = (kcontrol->private_value >> 16) & 0x07; - int shift_right = (kcontrol->private_value >> 19) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - int change; - unsigned short val1, val2; - - val1 = ucontrol->value.integer.value[0] & mask; - val2 = ucontrol->value.integer.value[1] & mask; - if (invert) { - val1 = mask - val1; - val2 = mask - val2; - } - val1 <<= shift_left; - val2 <<= shift_right; - spin_lock_irqsave(&chip->reg_lock, flags); - val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; - val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; - change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; - snd_cs4231_out(chip, left_reg, val1); - snd_cs4231_out(chip, right_reg, val2); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return change; -} - -static struct snd_kcontrol_new snd_cs4231_controls[] = { -CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), -CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), -CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), -CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), -CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), -CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1), -CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), -CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1), -CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), -CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = snd_cs4231_info_mux, - .get = snd_cs4231_get_mux, - .put = snd_cs4231_put_mux, -}, -CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), -CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), -CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) -}; - -static struct snd_kcontrol_new snd_opti93x_controls[] = { -CS4231_DOUBLE("Master Playback Switch", 0, - OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), -CS4231_DOUBLE("Master Playback Volume", 0, - OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), -CS4231_DOUBLE("PCM Playback Switch", 0, - CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("PCM Playback Volume", 0, - CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1), -CS4231_DOUBLE("FM Playback Switch", 0, - CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("FM Playback Volume", 0, - CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Line Playback Switch", 0, - CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), -CS4231_DOUBLE("Line Playback Volume", 0, - CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1), -CS4231_DOUBLE("Mic Playback Switch", 0, - OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Mic Playback Volume", 0, - OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Mic Boost", 0, - CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), -CS4231_DOUBLE("CD Playback Switch", 0, - CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("CD Playback Volume", 0, - CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Aux Playback Switch", 0, - OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Playback Volume", 0, - OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Capture Volume", 0, - CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = snd_cs4231_info_mux, - .get = snd_cs4231_get_mux, - .put = snd_cs4231_put_mux, -} -}; - -int snd_cs4231_mixer(struct snd_cs4231 *chip) -{ - struct snd_card *card; - unsigned int idx; - int err; - - snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); - - card = chip->card; - - strcpy(card->mixername, chip->pcm->name); - - if (chip->hardware == CS4231_HW_OPTI93X) - for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_opti93x_controls[idx], - chip)); - if (err < 0) - return err; - } - else - for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_cs4231_controls[idx], - chip)); - if (err < 0) - return err; - } - return 0; -} - -EXPORT_SYMBOL(snd_cs4231_out); -EXPORT_SYMBOL(snd_cs4231_in); -EXPORT_SYMBOL(snd_cs4236_ext_out); -EXPORT_SYMBOL(snd_cs4236_ext_in); -EXPORT_SYMBOL(snd_cs4231_mce_up); -EXPORT_SYMBOL(snd_cs4231_mce_down); -EXPORT_SYMBOL(snd_cs4231_overrange); -EXPORT_SYMBOL(snd_cs4231_interrupt); -EXPORT_SYMBOL(snd_cs4231_chip_id); -EXPORT_SYMBOL(snd_cs4231_create); -EXPORT_SYMBOL(snd_cs4231_pcm); -EXPORT_SYMBOL(snd_cs4231_mixer); -EXPORT_SYMBOL(snd_cs4231_timer); -EXPORT_SYMBOL(snd_cs4231_info_single); -EXPORT_SYMBOL(snd_cs4231_get_single); -EXPORT_SYMBOL(snd_cs4231_put_single); -EXPORT_SYMBOL(snd_cs4231_info_double); -EXPORT_SYMBOL(snd_cs4231_get_double); -EXPORT_SYMBOL(snd_cs4231_put_double); - -/* - * INIT part - */ - -static int __init alsa_cs4231_init(void) -{ - return 0; -} - -static void __exit alsa_cs4231_exit(void) -{ -} - -module_init(alsa_cs4231_init) -module_exit(alsa_cs4231_exit) diff --git a/sound/isa/wss/Makefile b/sound/isa/wss/Makefile new file mode 100644 index 000000000000..454fee769a31 --- /dev/null +++ b/sound/isa/wss/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for ALSA +# Copyright (c) 2008 by Jaroslav Kysela +# + +snd-wss-lib-objs := wss_lib.o + +# Toplevel Module Dependency +obj-$(CONFIG_SND_WSS_LIB) += snd-wss-lib.o + diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c new file mode 100644 index 000000000000..c5795f32ed30 --- /dev/null +++ b/sound/isa/wss/wss_lib.c @@ -0,0 +1,1945 @@ +/* + * Copyright (c) by Jaroslav Kysela + * Routines for control of CS4231(A)/CS4232/InterWave & compatible chips + * + * Bugs: + * - sometimes record brokes playback with WSS portion of + * Yamaha OPL3-SA3 chip + * - CS4231 (GUS MAX) - still trouble with occasional noises + * - broken initialization? + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips"); +MODULE_LICENSE("GPL"); + +#if 0 +#define SNDRV_DEBUG_MCE +#endif + +/* + * Some variables + */ + +static unsigned char freq_bits[14] = { + /* 5510 */ 0x00 | CS4231_XTAL2, + /* 6620 */ 0x0E | CS4231_XTAL2, + /* 8000 */ 0x00 | CS4231_XTAL1, + /* 9600 */ 0x0E | CS4231_XTAL1, + /* 11025 */ 0x02 | CS4231_XTAL2, + /* 16000 */ 0x02 | CS4231_XTAL1, + /* 18900 */ 0x04 | CS4231_XTAL2, + /* 22050 */ 0x06 | CS4231_XTAL2, + /* 27042 */ 0x04 | CS4231_XTAL1, + /* 32000 */ 0x06 | CS4231_XTAL1, + /* 33075 */ 0x0C | CS4231_XTAL2, + /* 37800 */ 0x08 | CS4231_XTAL2, + /* 44100 */ 0x0A | CS4231_XTAL2, + /* 48000 */ 0x0C | CS4231_XTAL1 +}; + +static unsigned int rates[14] = { + 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, + 27042, 32000, 33075, 37800, 44100, 48000 +}; + +static struct snd_pcm_hw_constraint_list hw_constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, +}; + +static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime) +{ + return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); +} + +static unsigned char snd_cs4231_original_image[32] = +{ + 0x00, /* 00/00 - lic */ + 0x00, /* 01/01 - ric */ + 0x9f, /* 02/02 - la1ic */ + 0x9f, /* 03/03 - ra1ic */ + 0x9f, /* 04/04 - la2ic */ + 0x9f, /* 05/05 - ra2ic */ + 0xbf, /* 06/06 - loc */ + 0xbf, /* 07/07 - roc */ + 0x20, /* 08/08 - pdfr */ + CS4231_AUTOCALIB, /* 09/09 - ic */ + 0x00, /* 0a/10 - pc */ + 0x00, /* 0b/11 - ti */ + CS4231_MODE2, /* 0c/12 - mi */ + 0xfc, /* 0d/13 - lbc */ + 0x00, /* 0e/14 - pbru */ + 0x00, /* 0f/15 - pbrl */ + 0x80, /* 10/16 - afei */ + 0x01, /* 11/17 - afeii */ + 0x9f, /* 12/18 - llic */ + 0x9f, /* 13/19 - rlic */ + 0x00, /* 14/20 - tlb */ + 0x00, /* 15/21 - thb */ + 0x00, /* 16/22 - la3mic/reserved */ + 0x00, /* 17/23 - ra3mic/reserved */ + 0x00, /* 18/24 - afs */ + 0x00, /* 19/25 - lamoc/version */ + 0xcf, /* 1a/26 - mioc */ + 0x00, /* 1b/27 - ramoc/reserved */ + 0x20, /* 1c/28 - cdfr */ + 0x00, /* 1d/29 - res4 */ + 0x00, /* 1e/30 - cbru */ + 0x00, /* 1f/31 - cbrl */ +}; + +static unsigned char snd_opti93x_original_image[32] = +{ + 0x00, /* 00/00 - l_mixout_outctrl */ + 0x00, /* 01/01 - r_mixout_outctrl */ + 0x88, /* 02/02 - l_cd_inctrl */ + 0x88, /* 03/03 - r_cd_inctrl */ + 0x88, /* 04/04 - l_a1/fm_inctrl */ + 0x88, /* 05/05 - r_a1/fm_inctrl */ + 0x80, /* 06/06 - l_dac_inctrl */ + 0x80, /* 07/07 - r_dac_inctrl */ + 0x00, /* 08/08 - ply_dataform_reg */ + 0x00, /* 09/09 - if_conf */ + 0x00, /* 0a/10 - pin_ctrl */ + 0x00, /* 0b/11 - err_init_reg */ + 0x0a, /* 0c/12 - id_reg */ + 0x00, /* 0d/13 - reserved */ + 0x00, /* 0e/14 - ply_upcount_reg */ + 0x00, /* 0f/15 - ply_lowcount_reg */ + 0x88, /* 10/16 - reserved/l_a1_inctrl */ + 0x88, /* 11/17 - reserved/r_a1_inctrl */ + 0x88, /* 12/18 - l_line_inctrl */ + 0x88, /* 13/19 - r_line_inctrl */ + 0x88, /* 14/20 - l_mic_inctrl */ + 0x88, /* 15/21 - r_mic_inctrl */ + 0x80, /* 16/22 - l_out_outctrl */ + 0x80, /* 17/23 - r_out_outctrl */ + 0x00, /* 18/24 - reserved */ + 0x00, /* 19/25 - reserved */ + 0x00, /* 1a/26 - reserved */ + 0x00, /* 1b/27 - reserved */ + 0x00, /* 1c/28 - cap_dataform_reg */ + 0x00, /* 1d/29 - reserved */ + 0x00, /* 1e/30 - cap_upcount_reg */ + 0x00 /* 1f/31 - cap_lowcount_reg */ +}; + +/* + * Basic I/O functions + */ + +static inline void cs4231_outb(struct snd_cs4231 *chip, u8 offset, u8 val) +{ + outb(val, chip->port + offset); +} + +static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset) +{ + return inb(chip->port + offset); +} + +static void snd_cs4231_wait(struct snd_cs4231 *chip) +{ + int timeout; + + for (timeout = 250; + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); + timeout--) + udelay(100); +} + +static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, + unsigned char mask, unsigned char value) +{ + unsigned char tmp = (chip->image[reg] & mask) | value; + + snd_cs4231_wait(chip); +#ifdef CONFIG_SND_DEBUG + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); +#endif + chip->image[reg] = tmp; + if (!chip->calibrate_mute) { + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + wmb(); + cs4231_outb(chip, CS4231P(REG), tmp); + mb(); + } +} + +static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) +{ + int timeout; + + for (timeout = 250; + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); + timeout--) + udelay(10); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + cs4231_outb(chip, CS4231P(REG), value); + mb(); +} + +void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) +{ + snd_cs4231_wait(chip); +#ifdef CONFIG_SND_DEBUG + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); +#endif + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + cs4231_outb(chip, CS4231P(REG), value); + chip->image[reg] = value; + mb(); + snd_printdd("codec out - reg 0x%x = 0x%x\n", + chip->mce_bit | reg, value); +} + +unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) +{ + snd_cs4231_wait(chip); +#ifdef CONFIG_SND_DEBUG + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); +#endif + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + mb(); + return cs4231_inb(chip, CS4231P(REG)); +} + +void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val) +{ + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); + cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); + cs4231_outb(chip, CS4231P(REG), val); + chip->eimage[CS4236_REG(reg)] = val; +#if 0 + printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val); +#endif +} + +unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg) +{ + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); + cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); +#if 1 + return cs4231_inb(chip, CS4231P(REG)); +#else + { + unsigned char res; + res = cs4231_inb(chip, CS4231P(REG)); + printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res); + return res; + } +#endif +} + +#if 0 + +static void snd_cs4231_debug(struct snd_cs4231 *chip) +{ + printk("CS4231 REGS: INDEX = 0x%02x ", cs4231_inb(chip, CS4231P(REGSEL))); + printk(" STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS))); + printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00)); + printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10)); + printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01)); + printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11)); + printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02)); + printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12)); + printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03)); + printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13)); + printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04)); + printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14)); + printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05)); + printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15)); + printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06)); + printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16)); + printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07)); + printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17)); + printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08)); + printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18)); + printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09)); + printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19)); + printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a)); + printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a)); + printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b)); + printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b)); + printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c)); + printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c)); + printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d)); + printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d)); + printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e)); + printk(" 0x1e: ply lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e)); + printk(" 0x0f: rec upr count = 0x%02x ", snd_cs4231_in(chip, 0x0f)); + printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f)); +} + +#endif + +/* + * CS4231 detection / MCE routines + */ + +static void snd_cs4231_busy_wait(struct snd_cs4231 *chip) +{ + int timeout; + + /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */ + for (timeout = 5; timeout > 0; timeout--) + cs4231_inb(chip, CS4231P(REGSEL)); + /* end of cleanup sequence */ + for (timeout = 250; + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); + timeout--) + udelay(10); +} + +void snd_cs4231_mce_up(struct snd_cs4231 *chip) +{ + unsigned long flags; + int timeout; + + snd_cs4231_wait(chip); +#ifdef CONFIG_SND_DEBUG + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + snd_printk("mce_up - auto calibration time out (0)\n"); +#endif + spin_lock_irqsave(&chip->reg_lock, flags); + chip->mce_bit |= CS4231_MCE; + timeout = cs4231_inb(chip, CS4231P(REGSEL)); + if (timeout == 0x80) + snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); + if (!(timeout & CS4231_MCE)) + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); +} + +void snd_cs4231_mce_down(struct snd_cs4231 *chip) +{ + unsigned long flags; + unsigned long end_time; + int timeout; + + snd_cs4231_busy_wait(chip); + +#ifdef CONFIG_SND_DEBUG + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); +#endif + spin_lock_irqsave(&chip->reg_lock, flags); + chip->mce_bit &= ~CS4231_MCE; + timeout = cs4231_inb(chip, CS4231P(REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (timeout == 0x80) + snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); + if ((timeout & CS4231_MCE) == 0 || + !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { + return; + } + + /* + * Wait for (possible -- during init auto-calibration may not be set) + * calibration process to start. Needs upto 5 sample periods on AD1848 + * which at the slowest possible rate of 5.5125 kHz means 907 us. + */ + msleep(1); + + snd_printdd("(1) jiffies = %lu\n", jiffies); + + /* check condition up to 250 ms */ + end_time = jiffies + msecs_to_jiffies(250); + while (snd_cs4231_in(chip, CS4231_TEST_INIT) & + CS4231_CALIB_IN_PROGRESS) { + + if (time_after(jiffies, end_time)) { + snd_printk(KERN_ERR "mce_down - " + "auto calibration time out (2)\n"); + return; + } + msleep(1); + } + + snd_printdd("(2) jiffies = %lu\n", jiffies); + + /* check condition up to 100 ms */ + end_time = jiffies + msecs_to_jiffies(100); + while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { + if (time_after(jiffies, end_time)) { + snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); + return; + } + msleep(1); + } + + snd_printdd("(3) jiffies = %lu\n", jiffies); + snd_printd("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL))); +} + +static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size) +{ + switch (format & 0xe0) { + case CS4231_LINEAR_16: + case CS4231_LINEAR_16_BIG: + size >>= 1; + break; + case CS4231_ADPCM_16: + return size >> 2; + } + if (format & CS4231_STEREO) + size >>= 1; + return size; +} + +static int snd_cs4231_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + int result = 0; + unsigned int what; + struct snd_pcm_substream *s; + int do_start; + +#if 0 + printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, cs4231_inb(chip, CS4231P(STATUS))); +#endif + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + do_start = 1; break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + do_start = 0; break; + default: + return -EINVAL; + } + + what = 0; + snd_pcm_group_for_each_entry(s, substream) { + if (s == chip->playback_substream) { + what |= CS4231_PLAYBACK_ENABLE; + snd_pcm_trigger_done(s, substream); + } else if (s == chip->capture_substream) { + what |= CS4231_RECORD_ENABLE; + snd_pcm_trigger_done(s, substream); + } + } + spin_lock(&chip->reg_lock); + if (do_start) { + chip->image[CS4231_IFACE_CTRL] |= what; + if (chip->trigger) + chip->trigger(chip, what, 1); + } else { + chip->image[CS4231_IFACE_CTRL] &= ~what; + if (chip->trigger) + chip->trigger(chip, what, 0); + } + snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); + spin_unlock(&chip->reg_lock); +#if 0 + snd_cs4231_debug(chip); +#endif + return result; +} + +/* + * CODEC I/O + */ + +static unsigned char snd_cs4231_get_rate(unsigned int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(rates); i++) + if (rate == rates[i]) + return freq_bits[i]; + // snd_BUG(); + return freq_bits[ARRAY_SIZE(rates) - 1]; +} + +static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, + int format, + int channels) +{ + unsigned char rformat; + + rformat = CS4231_LINEAR_8; + switch (format) { + case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break; + case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break; + case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break; + case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break; + case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break; + } + if (channels > 1) + rformat |= CS4231_STEREO; +#if 0 + snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode); +#endif + return rformat; +} + +static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute) +{ + unsigned long flags; + + mute = mute ? 1 : 0; + spin_lock_irqsave(&chip->reg_lock, flags); + if (chip->calibrate_mute == mute) { + spin_unlock_irqrestore(&chip->reg_lock, flags); + return; + } + if (!mute) { + snd_cs4231_dout(chip, CS4231_LEFT_INPUT, chip->image[CS4231_LEFT_INPUT]); + snd_cs4231_dout(chip, CS4231_RIGHT_INPUT, chip->image[CS4231_RIGHT_INPUT]); + snd_cs4231_dout(chip, CS4231_LOOPBACK, chip->image[CS4231_LOOPBACK]); + } + snd_cs4231_dout(chip, CS4231_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]); + snd_cs4231_dout(chip, CS4231_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]); + snd_cs4231_dout(chip, CS4231_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]); + snd_cs4231_dout(chip, CS4231_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]); + snd_cs4231_dout(chip, CS4231_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]); + snd_cs4231_dout(chip, CS4231_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]); + snd_cs4231_dout(chip, CS4231_LEFT_LINE_IN, mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); + snd_cs4231_dout(chip, CS4231_RIGHT_LINE_IN, mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); + snd_cs4231_dout(chip, CS4231_MONO_CTRL, mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); + if (chip->hardware == CS4231_HW_INTERWAVE) { + snd_cs4231_dout(chip, CS4231_LEFT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]); + snd_cs4231_dout(chip, CS4231_RIGHT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]); + snd_cs4231_dout(chip, CS4231_LINE_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]); + snd_cs4231_dout(chip, CS4231_LINE_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]); + } + chip->calibrate_mute = mute; + spin_unlock_irqrestore(&chip->reg_lock, flags); +} + +static void snd_cs4231_playback_format(struct snd_cs4231 *chip, + struct snd_pcm_hw_params *params, + unsigned char pdfr) +{ + unsigned long flags; + int full_calib = 1; + + mutex_lock(&chip->mce_mutex); + snd_cs4231_calibrate_mute(chip, 1); + if (chip->hardware == CS4231_HW_CS4231A || + (chip->hardware & CS4231_HW_CS4232_MASK)) { + spin_lock_irqsave(&chip->reg_lock, flags); + if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */ + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10); + snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr); + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x10); + udelay(100); /* Fixes audible clicks at least on GUS MAX */ + full_calib = 0; + } + spin_unlock_irqrestore(&chip->reg_lock, flags); + } + if (full_calib) { + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + if (chip->hardware != CS4231_HW_INTERWAVE && !chip->single_dma) { + snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, + (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ? + (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) : + pdfr); + } else { + snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr); + } + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (chip->hardware == CS4231_HW_OPL3SA2) + udelay(100); /* this seems to help */ + snd_cs4231_mce_down(chip); + } + snd_cs4231_calibrate_mute(chip, 0); + mutex_unlock(&chip->mce_mutex); +} + +static void snd_cs4231_capture_format(struct snd_cs4231 *chip, + struct snd_pcm_hw_params *params, + unsigned char cdfr) +{ + unsigned long flags; + int full_calib = 1; + + mutex_lock(&chip->mce_mutex); + snd_cs4231_calibrate_mute(chip, 1); + if (chip->hardware == CS4231_HW_CS4231A || + (chip->hardware & CS4231_HW_CS4232_MASK)) { + spin_lock_irqsave(&chip->reg_lock, flags); + if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */ + (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20); + snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT] = cdfr); + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x20); + full_calib = 0; + } + spin_unlock_irqrestore(&chip->reg_lock, flags); + } + if (full_calib) { + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + if (chip->hardware != CS4231_HW_INTERWAVE) { + if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { + snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, + ((chip->single_dma ? cdfr : chip->image[CS4231_PLAYBK_FORMAT]) & 0xf0) | + (cdfr & 0x0f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + } + } + snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + } + snd_cs4231_calibrate_mute(chip, 0); + mutex_unlock(&chip->mce_mutex); +} + +/* + * Timer interface + */ + +static unsigned long snd_cs4231_timer_resolution(struct snd_timer * timer) +{ + struct snd_cs4231 *chip = snd_timer_chip(timer); + if (chip->hardware & CS4231_HW_CS4236B_MASK) + return 14467; + else + return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920; +} + +static int snd_cs4231_timer_start(struct snd_timer * timer) +{ + unsigned long flags; + unsigned int ticks; + struct snd_cs4231 *chip = snd_timer_chip(timer); + spin_lock_irqsave(&chip->reg_lock, flags); + ticks = timer->sticks; + if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 || + (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] || + (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) { + snd_cs4231_out(chip, CS4231_TIMER_HIGH, chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8)); + snd_cs4231_out(chip, CS4231_TIMER_LOW, chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks); + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE); + } + spin_unlock_irqrestore(&chip->reg_lock, flags); + return 0; +} + +static int snd_cs4231_timer_stop(struct snd_timer * timer) +{ + unsigned long flags; + struct snd_cs4231 *chip = snd_timer_chip(timer); + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE); + spin_unlock_irqrestore(&chip->reg_lock, flags); + return 0; +} + +static void snd_cs4231_init(struct snd_cs4231 *chip) +{ + unsigned long flags; + + snd_cs4231_mce_down(chip); + +#ifdef SNDRV_DEBUG_MCE + snd_printk("init: (1)\n"); +#endif + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | + CS4231_RECORD_ENABLE | CS4231_RECORD_PIO | + CS4231_CALIB_MODE); + chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB; + snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + +#ifdef SNDRV_DEBUG_MCE + snd_printk("init: (2)\n"); +#endif + + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + +#ifdef SNDRV_DEBUG_MCE + snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]); +#endif + + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]); + spin_unlock_irqrestore(&chip->reg_lock, flags); + + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + +#ifdef SNDRV_DEBUG_MCE + snd_printk("init: (4)\n"); +#endif + + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + +#ifdef SNDRV_DEBUG_MCE + snd_printk("init: (5)\n"); +#endif +} + +static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) +{ + unsigned long flags; + + mutex_lock(&chip->open_mutex); + if ((chip->mode & mode) || + ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) { + mutex_unlock(&chip->open_mutex); + return -EAGAIN; + } + if (chip->mode & CS4231_MODE_OPEN) { + chip->mode |= mode; + mutex_unlock(&chip->open_mutex); + return 0; + } + /* ok. now enable and ack CODEC IRQ */ + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | + CS4231_RECORD_IRQ | + CS4231_TIMER_IRQ); + snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE; + snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); + snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | + CS4231_RECORD_IRQ | + CS4231_TIMER_IRQ); + snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); + spin_unlock_irqrestore(&chip->reg_lock, flags); + + chip->mode = mode; + mutex_unlock(&chip->open_mutex); + return 0; +} + +static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) +{ + unsigned long flags; + + mutex_lock(&chip->open_mutex); + chip->mode &= ~mode; + if (chip->mode & CS4231_MODE_OPEN) { + mutex_unlock(&chip->open_mutex); + return; + } + snd_cs4231_calibrate_mute(chip, 1); + + /* disable IRQ */ + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE; + snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); + + /* now disable record & playback */ + + if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | + CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) { + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | + CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); + snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_down(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + } + + /* clear IRQ again */ + snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + spin_unlock_irqrestore(&chip->reg_lock, flags); + + snd_cs4231_calibrate_mute(chip, 0); + + chip->mode = 0; + mutex_unlock(&chip->open_mutex); +} + +/* + * timer open/close + */ + +static int snd_cs4231_timer_open(struct snd_timer * timer) +{ + struct snd_cs4231 *chip = snd_timer_chip(timer); + snd_cs4231_open(chip, CS4231_MODE_TIMER); + return 0; +} + +static int snd_cs4231_timer_close(struct snd_timer * timer) +{ + struct snd_cs4231 *chip = snd_timer_chip(timer); + snd_cs4231_close(chip, CS4231_MODE_TIMER); + return 0; +} + +static struct snd_timer_hardware snd_cs4231_timer_table = +{ + .flags = SNDRV_TIMER_HW_AUTO, + .resolution = 9945, + .ticks = 65535, + .open = snd_cs4231_timer_open, + .close = snd_cs4231_timer_close, + .c_resolution = snd_cs4231_timer_resolution, + .start = snd_cs4231_timer_start, + .stop = snd_cs4231_timer_stop, +}; + +/* + * ok.. exported functions.. + */ + +static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + unsigned char new_pdfr; + int err; + + if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) + return err; + new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) | + snd_cs4231_get_rate(params_rate(hw_params)); + chip->set_playback_format(chip, hw_params, new_pdfr); + return 0; +} + +static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + +static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned long flags; + unsigned int size = snd_pcm_lib_buffer_bytes(substream); + unsigned int count = snd_pcm_lib_period_bytes(substream); + + spin_lock_irqsave(&chip->reg_lock, flags); + chip->p_dma_size = size; + chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO); + snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); + count = snd_cs4231_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1; + snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); + snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); + spin_unlock_irqrestore(&chip->reg_lock, flags); +#if 0 + snd_cs4231_debug(chip); +#endif + return 0; +} + +static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + unsigned char new_cdfr; + int err; + + if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) + return err; + new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) | + snd_cs4231_get_rate(params_rate(hw_params)); + chip->set_capture_format(chip, hw_params, new_cdfr); + return 0; +} + +static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + +static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned long flags; + unsigned int size = snd_pcm_lib_buffer_bytes(substream); + unsigned int count = snd_pcm_lib_period_bytes(substream); + + spin_lock_irqsave(&chip->reg_lock, flags); + chip->c_dma_size = size; + chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); + snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); + count = snd_cs4231_get_count(chip->image[CS4231_REC_FORMAT], count) - 1; + if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) { + snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); + snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); + } else { + snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count); + snd_cs4231_out(chip, CS4231_REC_UPR_CNT, (unsigned char) (count >> 8)); + } + spin_unlock_irqrestore(&chip->reg_lock, flags); + return 0; +} + +void snd_cs4231_overrange(struct snd_cs4231 *chip) +{ + unsigned long flags; + unsigned char res; + + spin_lock_irqsave(&chip->reg_lock, flags); + res = snd_cs4231_in(chip, CS4231_TEST_INIT); + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */ + chip->capture_substream->runtime->overrange++; +} + +irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id) +{ + struct snd_cs4231 *chip = dev_id; + unsigned char status; + + status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); + if (status & CS4231_TIMER_IRQ) { + if (chip->timer) + snd_timer_interrupt(chip->timer, chip->timer->sticks); + } + if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) { + if (status & CS4231_PLAYBACK_IRQ) { + if (chip->mode & CS4231_MODE_PLAY) { + if (chip->playback_substream) + snd_pcm_period_elapsed(chip->playback_substream); + } + if (chip->mode & CS4231_MODE_RECORD) { + if (chip->capture_substream) { + snd_cs4231_overrange(chip); + snd_pcm_period_elapsed(chip->capture_substream); + } + } + } + } else { + if (status & CS4231_PLAYBACK_IRQ) { + if (chip->playback_substream) + snd_pcm_period_elapsed(chip->playback_substream); + } + if (status & CS4231_RECORD_IRQ) { + if (chip->capture_substream) { + snd_cs4231_overrange(chip); + snd_pcm_period_elapsed(chip->capture_substream); + } + } + } + + spin_lock(&chip->reg_lock); + snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); + spin_unlock(&chip->reg_lock); + return IRQ_HANDLED; +} + +static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + size_t ptr; + + if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) + return 0; + ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); + return bytes_to_frames(substream->runtime, ptr); +} + +static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + size_t ptr; + + if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) + return 0; + ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); + return bytes_to_frames(substream->runtime, ptr); +} + +/* + + */ + +static int snd_cs4231_probe(struct snd_cs4231 *chip) +{ + unsigned long flags; + int i, id, rev; + unsigned char *ptr; + unsigned int hw; + +#if 0 + snd_cs4231_debug(chip); +#endif + id = 0; + for (i = 0; i < 50; i++) { + mb(); + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + udelay(2000); + else { + spin_lock_irqsave(&chip->reg_lock, flags); + snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2); + id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f; + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (id == 0x0a) + break; /* this is valid value */ + } + } + snd_printdd("cs4231: port = 0x%lx, id = 0x%x\n", chip->port, id); + if (id != 0x0a) + return -ENODEV; /* no valid device found */ + + if (((hw = chip->hardware) & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) { + rev = snd_cs4231_in(chip, CS4231_VERSION) & 0xe7; + snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev); + if (rev == 0x80) { + unsigned char tmp = snd_cs4231_in(chip, 23); + snd_cs4231_out(chip, 23, ~tmp); + if (snd_cs4231_in(chip, 23) != tmp) + chip->hardware = CS4231_HW_AD1845; + else + chip->hardware = CS4231_HW_CS4231; + } else if (rev == 0xa0) { + chip->hardware = CS4231_HW_CS4231A; + } else if (rev == 0xa2) { + chip->hardware = CS4231_HW_CS4232; + } else if (rev == 0xb2) { + chip->hardware = CS4231_HW_CS4232A; + } else if (rev == 0x83) { + chip->hardware = CS4231_HW_CS4236; + } else if (rev == 0x03) { + chip->hardware = CS4231_HW_CS4236B; + } else { + snd_printk("unknown CS chip with version 0x%x\n", rev); + return -ENODEV; /* unknown CS4231 chip? */ + } + } + spin_lock_irqsave(&chip->reg_lock, flags); + cs4231_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); + mb(); + spin_unlock_irqrestore(&chip->reg_lock, flags); + + chip->image[CS4231_MISC_INFO] = CS4231_MODE2; + switch (chip->hardware) { + case CS4231_HW_INTERWAVE: + chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3; + break; + case CS4231_HW_CS4235: + case CS4231_HW_CS4236B: + case CS4231_HW_CS4237B: + case CS4231_HW_CS4238B: + case CS4231_HW_CS4239: + if (hw == CS4231_HW_DETECT3) + chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3; + else + chip->hardware = CS4231_HW_CS4236; + break; + } + + chip->image[CS4231_IFACE_CTRL] = + (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) | + (chip->single_dma ? CS4231_SINGLE_DMA : 0); + if (chip->hardware != CS4231_HW_OPTI93X) { + chip->image[CS4231_ALT_FEATURE_1] = 0x80; + chip->image[CS4231_ALT_FEATURE_2] = + chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01; + } + ptr = (unsigned char *) &chip->image; + snd_cs4231_mce_down(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */ + snd_cs4231_out(chip, i, *ptr++); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_cs4231_mce_up(chip); + snd_cs4231_mce_down(chip); + + mdelay(2); + + /* ok.. try check hardware version for CS4236+ chips */ + if ((hw & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) { + if (chip->hardware == CS4231_HW_CS4236B) { + rev = snd_cs4236_ext_in(chip, CS4236_VERSION); + snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff); + id = snd_cs4236_ext_in(chip, CS4236_VERSION); + snd_cs4236_ext_out(chip, CS4236_VERSION, rev); + snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id); + if ((id & 0x1f) == 0x1d) { /* CS4235 */ + chip->hardware = CS4231_HW_CS4235; + switch (id >> 5) { + case 4: + case 5: + case 6: + break; + default: + snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id); + } + } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */ + switch (id >> 5) { + case 4: + case 5: + case 6: + case 7: + chip->hardware = CS4231_HW_CS4236B; + break; + default: + snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id); + } + } else if ((id & 0x1f) == 0x08) { /* CS4237B */ + chip->hardware = CS4231_HW_CS4237B; + switch (id >> 5) { + case 4: + case 5: + case 6: + case 7: + break; + default: + snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id); + } + } else if ((id & 0x1f) == 0x09) { /* CS4238B */ + chip->hardware = CS4231_HW_CS4238B; + switch (id >> 5) { + case 5: + case 6: + case 7: + break; + default: + snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id); + } + } else if ((id & 0x1f) == 0x1e) { /* CS4239 */ + chip->hardware = CS4231_HW_CS4239; + switch (id >> 5) { + case 4: + case 5: + case 6: + break; + default: + snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id); + } + } else { + snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id); + } + } + } + return 0; /* all things are ok.. */ +} + +/* + + */ + +static struct snd_pcm_hardware snd_cs4231_playback = +{ + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, + .rate_min = 5510, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (128*1024), + .period_bytes_min = 64, + .period_bytes_max = (128*1024), + .periods_min = 1, + .periods_max = 1024, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware snd_cs4231_capture = +{ + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, + .rate_min = 5510, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (128*1024), + .period_bytes_min = 64, + .period_bytes_max = (128*1024), + .periods_min = 1, + .periods_max = 1024, + .fifo_size = 0, +}; + +/* + + */ + +static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int err; + + runtime->hw = snd_cs4231_playback; + + /* hardware bug in InterWave chipset */ + if (chip->hardware == CS4231_HW_INTERWAVE && chip->dma1 > 3) + runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW; + + /* hardware limitation of cheap chips */ + if (chip->hardware == CS4231_HW_CS4235 || + chip->hardware == CS4231_HW_CS4239) + runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; + + snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max); + + if (chip->claim_dma) { + if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0) + return err; + } + + if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) { + if (chip->release_dma) + chip->release_dma(chip, chip->dma_private_data, chip->dma1); + snd_free_pages(runtime->dma_area, runtime->dma_bytes); + return err; + } + chip->playback_substream = substream; + snd_pcm_set_sync(substream); + chip->rate_constraint(runtime); + return 0; +} + +static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int err; + + runtime->hw = snd_cs4231_capture; + + /* hardware limitation of cheap chips */ + if (chip->hardware == CS4231_HW_CS4235 || + chip->hardware == CS4231_HW_CS4239) + runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; + + snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); + + if (chip->claim_dma) { + if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0) + return err; + } + + if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) { + if (chip->release_dma) + chip->release_dma(chip, chip->dma_private_data, chip->dma2); + snd_free_pages(runtime->dma_area, runtime->dma_bytes); + return err; + } + chip->capture_substream = substream; + snd_pcm_set_sync(substream); + chip->rate_constraint(runtime); + return 0; +} + +static int snd_cs4231_playback_close(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + + chip->playback_substream = NULL; + snd_cs4231_close(chip, CS4231_MODE_PLAY); + return 0; +} + +static int snd_cs4231_capture_close(struct snd_pcm_substream *substream) +{ + struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + + chip->capture_substream = NULL; + snd_cs4231_close(chip, CS4231_MODE_RECORD); + return 0; +} + +#ifdef CONFIG_PM + +/* lowlevel suspend callback for CS4231 */ +static void snd_cs4231_suspend(struct snd_cs4231 *chip) +{ + int reg; + unsigned long flags; + + snd_pcm_suspend_all(chip->pcm); + spin_lock_irqsave(&chip->reg_lock, flags); + for (reg = 0; reg < 32; reg++) + chip->image[reg] = snd_cs4231_in(chip, reg); + spin_unlock_irqrestore(&chip->reg_lock, flags); +} + +/* lowlevel resume callback for CS4231 */ +static void snd_cs4231_resume(struct snd_cs4231 *chip) +{ + int reg; + unsigned long flags; + /* int timeout; */ + + snd_cs4231_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + for (reg = 0; reg < 32; reg++) { + switch (reg) { + case CS4231_VERSION: + break; + default: + snd_cs4231_out(chip, reg, chip->image[reg]); + break; + } + } + spin_unlock_irqrestore(&chip->reg_lock, flags); +#if 1 + snd_cs4231_mce_down(chip); +#else + /* The following is a workaround to avoid freeze after resume on TP600E. + This is the first half of copy of snd_cs4231_mce_down(), but doesn't + include rescheduling. -- iwai + */ + snd_cs4231_busy_wait(chip); + spin_lock_irqsave(&chip->reg_lock, flags); + chip->mce_bit &= ~CS4231_MCE; + timeout = cs4231_inb(chip, CS4231P(REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (timeout == 0x80) + snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); + if ((timeout & CS4231_MCE) == 0 || + !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { + return; + } + snd_cs4231_busy_wait(chip); +#endif +} +#endif /* CONFIG_PM */ + +static int snd_cs4231_free(struct snd_cs4231 *chip) +{ + release_and_free_resource(chip->res_port); + release_and_free_resource(chip->res_cport); + if (chip->irq >= 0) { + disable_irq(chip->irq); + if (!(chip->hwshare & CS4231_HWSHARE_IRQ)) + free_irq(chip->irq, (void *) chip); + } + if (!(chip->hwshare & CS4231_HWSHARE_DMA1) && chip->dma1 >= 0) { + snd_dma_disable(chip->dma1); + free_dma(chip->dma1); + } + if (!(chip->hwshare & CS4231_HWSHARE_DMA2) && chip->dma2 >= 0 && chip->dma2 != chip->dma1) { + snd_dma_disable(chip->dma2); + free_dma(chip->dma2); + } + if (chip->timer) + snd_device_free(chip->card, chip->timer); + kfree(chip); + return 0; +} + +static int snd_cs4231_dev_free(struct snd_device *device) +{ + struct snd_cs4231 *chip = device->device_data; + return snd_cs4231_free(chip); +} + +const char *snd_cs4231_chip_id(struct snd_cs4231 *chip) +{ + switch (chip->hardware) { + case CS4231_HW_CS4231: return "CS4231"; + case CS4231_HW_CS4231A: return "CS4231A"; + case CS4231_HW_CS4232: return "CS4232"; + case CS4231_HW_CS4232A: return "CS4232A"; + case CS4231_HW_CS4235: return "CS4235"; + case CS4231_HW_CS4236: return "CS4236"; + case CS4231_HW_CS4236B: return "CS4236B"; + case CS4231_HW_CS4237B: return "CS4237B"; + case CS4231_HW_CS4238B: return "CS4238B"; + case CS4231_HW_CS4239: return "CS4239"; + case CS4231_HW_INTERWAVE: return "AMD InterWave"; + case CS4231_HW_OPL3SA2: return chip->card->shortname; + case CS4231_HW_AD1845: return "AD1845"; + case CS4231_HW_OPTI93X: return "OPTi 93x"; + default: return "???"; + } +} + +static int snd_cs4231_new(struct snd_card *card, + unsigned short hardware, + unsigned short hwshare, + struct snd_cs4231 ** rchip) +{ + struct snd_cs4231 *chip; + + *rchip = NULL; + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + chip->hardware = hardware; + chip->hwshare = hwshare; + + spin_lock_init(&chip->reg_lock); + mutex_init(&chip->mce_mutex); + mutex_init(&chip->open_mutex); + chip->card = card; + chip->rate_constraint = snd_cs4231_xrate; + chip->set_playback_format = snd_cs4231_playback_format; + chip->set_capture_format = snd_cs4231_capture_format; + if (chip->hardware == CS4231_HW_OPTI93X) + memcpy(&chip->image, &snd_opti93x_original_image, + sizeof(snd_opti93x_original_image)); + else + memcpy(&chip->image, &snd_cs4231_original_image, + sizeof(snd_cs4231_original_image)); + + *rchip = chip; + return 0; +} + +int snd_cs4231_create(struct snd_card *card, + unsigned long port, + unsigned long cport, + int irq, int dma1, int dma2, + unsigned short hardware, + unsigned short hwshare, + struct snd_cs4231 ** rchip) +{ + static struct snd_device_ops ops = { + .dev_free = snd_cs4231_dev_free, + }; + struct snd_cs4231 *chip; + int err; + + err = snd_cs4231_new(card, hardware, hwshare, &chip); + if (err < 0) + return err; + + chip->irq = -1; + chip->dma1 = -1; + chip->dma2 = -1; + + if ((chip->res_port = request_region(port, 4, "CS4231")) == NULL) { + snd_printk(KERN_ERR "cs4231: can't grab port 0x%lx\n", port); + snd_cs4231_free(chip); + return -EBUSY; + } + chip->port = port; + if ((long)cport >= 0 && (chip->res_cport = request_region(cport, 8, "CS4232 Control")) == NULL) { + snd_printk(KERN_ERR "cs4231: can't grab control port 0x%lx\n", cport); + snd_cs4231_free(chip); + return -ENODEV; + } + chip->cport = cport; + if (!(hwshare & CS4231_HWSHARE_IRQ) && request_irq(irq, snd_cs4231_interrupt, IRQF_DISABLED, "CS4231", (void *) chip)) { + snd_printk(KERN_ERR "cs4231: can't grab IRQ %d\n", irq); + snd_cs4231_free(chip); + return -EBUSY; + } + chip->irq = irq; + if (!(hwshare & CS4231_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) { + snd_printk(KERN_ERR "cs4231: can't grab DMA1 %d\n", dma1); + snd_cs4231_free(chip); + return -EBUSY; + } + chip->dma1 = dma1; + if (!(hwshare & CS4231_HWSHARE_DMA2) && dma1 != dma2 && dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) { + snd_printk(KERN_ERR "cs4231: can't grab DMA2 %d\n", dma2); + snd_cs4231_free(chip); + return -EBUSY; + } + if (dma1 == dma2 || dma2 < 0) { + chip->single_dma = 1; + chip->dma2 = chip->dma1; + } else + chip->dma2 = dma2; + + /* global setup */ + if (snd_cs4231_probe(chip) < 0) { + snd_cs4231_free(chip); + return -ENODEV; + } + snd_cs4231_init(chip); + +#if 0 + if (chip->hardware & CS4231_HW_CS4232_MASK) { + if (chip->res_cport == NULL) + snd_printk("CS4232 control port features are not accessible\n"); + } +#endif + + /* Register device */ + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { + snd_cs4231_free(chip); + return err; + } + +#ifdef CONFIG_PM + /* Power Management */ + chip->suspend = snd_cs4231_suspend; + chip->resume = snd_cs4231_resume; +#endif + + *rchip = chip; + return 0; +} + +static struct snd_pcm_ops snd_cs4231_playback_ops = { + .open = snd_cs4231_playback_open, + .close = snd_cs4231_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cs4231_playback_hw_params, + .hw_free = snd_cs4231_playback_hw_free, + .prepare = snd_cs4231_playback_prepare, + .trigger = snd_cs4231_trigger, + .pointer = snd_cs4231_playback_pointer, +}; + +static struct snd_pcm_ops snd_cs4231_capture_ops = { + .open = snd_cs4231_capture_open, + .close = snd_cs4231_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cs4231_capture_hw_params, + .hw_free = snd_cs4231_capture_hw_free, + .prepare = snd_cs4231_capture_prepare, + .trigger = snd_cs4231_trigger, + .pointer = snd_cs4231_capture_pointer, +}; + +int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) +{ + struct snd_pcm *pcm; + int err; + + if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0) + return err; + + spin_lock_init(&chip->reg_lock); + mutex_init(&chip->mce_mutex); + mutex_init(&chip->open_mutex); + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); + + /* global setup */ + pcm->private_data = chip; + pcm->info_flags = 0; + if (chip->single_dma) + pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; + if (chip->hardware != CS4231_HW_INTERWAVE) + pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; + strcpy(pcm->name, snd_cs4231_chip_id(chip)); + + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_isa_data(), + 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); + + chip->pcm = pcm; + if (rpcm) + *rpcm = pcm; + return 0; +} + +static void snd_cs4231_timer_free(struct snd_timer *timer) +{ + struct snd_cs4231 *chip = timer->private_data; + chip->timer = NULL; +} + +int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rtimer) +{ + struct snd_timer *timer; + struct snd_timer_id tid; + int err; + + /* Timer initialization */ + tid.dev_class = SNDRV_TIMER_CLASS_CARD; + tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; + tid.card = chip->card->number; + tid.device = device; + tid.subdevice = 0; + if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0) + return err; + strcpy(timer->name, snd_cs4231_chip_id(chip)); + timer->private_data = chip; + timer->private_free = snd_cs4231_timer_free; + timer->hw = snd_cs4231_timer_table; + chip->timer = timer; + if (rtimer) + *rtimer = timer; + return 0; +} + +/* + * MIXER part + */ + +static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[4] = { + "Line", "Aux", "Mic", "Mix" + }; + static char *opl3sa_texts[4] = { + "Line", "CD", "Mic", "Mix" + }; + static char *gusmax_texts[4] = { + "Line", "Synth", "Mic", "Mix" + }; + char **ptexts = texts; + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + + snd_assert(chip->card != NULL, return -EINVAL); + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 2; + uinfo->value.enumerated.items = 4; + if (uinfo->value.enumerated.item > 3) + uinfo->value.enumerated.item = 3; + if (!strcmp(chip->card->driver, "GUS MAX")) + ptexts = gusmax_texts; + switch (chip->hardware) { + case CS4231_HW_INTERWAVE: ptexts = gusmax_texts; break; + case CS4231_HW_OPL3SA2: ptexts = opl3sa_texts; break; + } + strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]); + return 0; +} + +static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&chip->reg_lock, flags); + ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6; + ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6; + spin_unlock_irqrestore(&chip->reg_lock, flags); + return 0; +} + +static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + unsigned long flags; + unsigned short left, right; + int change; + + if (ucontrol->value.enumerated.item[0] > 3 || + ucontrol->value.enumerated.item[1] > 3) + return -EINVAL; + left = ucontrol->value.enumerated.item[0] << 6; + right = ucontrol->value.enumerated.item[1] << 6; + spin_lock_irqsave(&chip->reg_lock, flags); + left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left; + right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right; + change = left != chip->image[CS4231_LEFT_INPUT] || + right != chip->image[CS4231_RIGHT_INPUT]; + snd_cs4231_out(chip, CS4231_LEFT_INPUT, left); + snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right); + spin_unlock_irqrestore(&chip->reg_lock, flags); + return change; +} + +int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + int mask = (kcontrol->private_value >> 16) & 0xff; + + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mask; + return 0; +} + +int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 8) & 0xff; + int mask = (kcontrol->private_value >> 16) & 0xff; + int invert = (kcontrol->private_value >> 24) & 0xff; + + spin_lock_irqsave(&chip->reg_lock, flags); + ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask; + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (invert) + ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; + return 0; +} + +int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 8) & 0xff; + int mask = (kcontrol->private_value >> 16) & 0xff; + int invert = (kcontrol->private_value >> 24) & 0xff; + int change; + unsigned short val; + + val = (ucontrol->value.integer.value[0] & mask); + if (invert) + val = mask - val; + val <<= shift; + spin_lock_irqsave(&chip->reg_lock, flags); + val = (chip->image[reg] & ~(mask << shift)) | val; + change = val != chip->image[reg]; + snd_cs4231_out(chip, reg, val); + spin_unlock_irqrestore(&chip->reg_lock, flags); + return change; +} + +int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + int mask = (kcontrol->private_value >> 24) & 0xff; + + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mask; + return 0; +} + +int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int left_reg = kcontrol->private_value & 0xff; + int right_reg = (kcontrol->private_value >> 8) & 0xff; + int shift_left = (kcontrol->private_value >> 16) & 0x07; + int shift_right = (kcontrol->private_value >> 19) & 0x07; + int mask = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 22) & 1; + + spin_lock_irqsave(&chip->reg_lock, flags); + ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask; + ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask; + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (invert) { + ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; + ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; + } + return 0; +} + +int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int left_reg = kcontrol->private_value & 0xff; + int right_reg = (kcontrol->private_value >> 8) & 0xff; + int shift_left = (kcontrol->private_value >> 16) & 0x07; + int shift_right = (kcontrol->private_value >> 19) & 0x07; + int mask = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 22) & 1; + int change; + unsigned short val1, val2; + + val1 = ucontrol->value.integer.value[0] & mask; + val2 = ucontrol->value.integer.value[1] & mask; + if (invert) { + val1 = mask - val1; + val2 = mask - val2; + } + val1 <<= shift_left; + val2 <<= shift_right; + spin_lock_irqsave(&chip->reg_lock, flags); + val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; + val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; + change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; + snd_cs4231_out(chip, left_reg, val1); + snd_cs4231_out(chip, right_reg, val2); + spin_unlock_irqrestore(&chip->reg_lock, flags); + return change; +} + +static struct snd_kcontrol_new snd_cs4231_controls[] = { +CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), +CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), +CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), +CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), +CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), +CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), +CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1), +CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), +CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1), +CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), +CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = snd_cs4231_info_mux, + .get = snd_cs4231_get_mux, + .put = snd_cs4231_put_mux, +}, +CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), +CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), +CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) +}; + +static struct snd_kcontrol_new snd_opti93x_controls[] = { +CS4231_DOUBLE("Master Playback Switch", 0, + OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), +CS4231_DOUBLE("Master Playback Volume", 0, + OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), +CS4231_DOUBLE("PCM Playback Switch", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), +CS4231_DOUBLE("PCM Playback Volume", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1), +CS4231_DOUBLE("FM Playback Switch", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +CS4231_DOUBLE("FM Playback Volume", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1), +CS4231_DOUBLE("Line Playback Switch", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), +CS4231_DOUBLE("Line Playback Volume", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1), +CS4231_DOUBLE("Mic Playback Switch", 0, + OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), +CS4231_DOUBLE("Mic Playback Volume", 0, + OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1), +CS4231_DOUBLE("Mic Boost", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), +CS4231_DOUBLE("CD Playback Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +CS4231_DOUBLE("CD Playback Volume", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1), +CS4231_DOUBLE("Aux Playback Switch", 0, + OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1), +CS4231_DOUBLE("Aux Playback Volume", 0, + OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1), +CS4231_DOUBLE("Capture Volume", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = snd_cs4231_info_mux, + .get = snd_cs4231_get_mux, + .put = snd_cs4231_put_mux, +} +}; + +int snd_cs4231_mixer(struct snd_cs4231 *chip) +{ + struct snd_card *card; + unsigned int idx; + int err; + + snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); + + card = chip->card; + + strcpy(card->mixername, chip->pcm->name); + + if (chip->hardware == CS4231_HW_OPTI93X) + for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { + err = snd_ctl_add(card, + snd_ctl_new1(&snd_opti93x_controls[idx], + chip)); + if (err < 0) + return err; + } + else + for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { + err = snd_ctl_add(card, + snd_ctl_new1(&snd_cs4231_controls[idx], + chip)); + if (err < 0) + return err; + } + return 0; +} + +EXPORT_SYMBOL(snd_cs4231_out); +EXPORT_SYMBOL(snd_cs4231_in); +EXPORT_SYMBOL(snd_cs4236_ext_out); +EXPORT_SYMBOL(snd_cs4236_ext_in); +EXPORT_SYMBOL(snd_cs4231_mce_up); +EXPORT_SYMBOL(snd_cs4231_mce_down); +EXPORT_SYMBOL(snd_cs4231_overrange); +EXPORT_SYMBOL(snd_cs4231_interrupt); +EXPORT_SYMBOL(snd_cs4231_chip_id); +EXPORT_SYMBOL(snd_cs4231_create); +EXPORT_SYMBOL(snd_cs4231_pcm); +EXPORT_SYMBOL(snd_cs4231_mixer); +EXPORT_SYMBOL(snd_cs4231_timer); +EXPORT_SYMBOL(snd_cs4231_info_single); +EXPORT_SYMBOL(snd_cs4231_get_single); +EXPORT_SYMBOL(snd_cs4231_put_single); +EXPORT_SYMBOL(snd_cs4231_info_double); +EXPORT_SYMBOL(snd_cs4231_get_double); +EXPORT_SYMBOL(snd_cs4231_put_double); + +/* + * INIT part + */ + +static int __init alsa_cs4231_init(void) +{ + return 0; +} + +static void __exit alsa_cs4231_exit(void) +{ +} + +module_init(alsa_cs4231_init) +module_exit(alsa_cs4231_exit) -- cgit v1.2.3 From 61ef19d7e771ce021edb0dff0da134b6d688d4aa Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:02:42 +0200 Subject: ALSA: wss_lib: rename cs4231.h into wss.h Rename file include/sound/cs4231.h into include/sound/wss.h Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/azt2320.c | 2 +- sound/isa/cs423x/cs4231.c | 2 +- sound/isa/cs423x/cs4236.c | 2 +- sound/isa/cs423x/cs4236_lib.c | 2 +- sound/isa/gus/gusmax.c | 2 +- sound/isa/gus/interwave.c | 2 +- sound/isa/opl3sa2.c | 2 +- sound/isa/opti9xx/miro.c | 2 +- sound/isa/opti9xx/opti92x-ad1848.c | 2 +- sound/isa/sscape.c | 2 +- sound/isa/wavefront/wavefront.c | 1 + sound/isa/wss/wss_lib.c | 2 +- 12 files changed, 12 insertions(+), 11 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index 154e728f592d..a24db091d445 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index e9462b9944be..7da28e7c0322 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 4d4b8ddc26ba..246c221556e3 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index de71910401ea..eb227d856d1e 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c @@ -85,7 +85,7 @@ #include #include #include -#include +#include #include MODULE_AUTHOR("Jaroslav Kysela "); diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index f87c6236661c..cd82891db80a 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #define SNDRV_LEGACY_FIND_FREE_IRQ #define SNDRV_LEGACY_FIND_FREE_DMA #include diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index ca0d7ace0c75..eac8cc77e338 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #ifdef SNDRV_STB #include #endif diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 854a9f74b466..e81cbe86823a 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 2a1e2f5d12c2..59f7c55baf30 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 0797ca441a37..93a03d9c7a95 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -34,7 +34,7 @@ #include #include #if defined(CS4231) || defined(OPTi93X) -#include +#include #else #include #endif /* CS4231 */ diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 06ad7863dff5..1dc4224b3207 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 3a6c6fe1ec4d..2fb058b5a45f 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -29,6 +29,7 @@ #include #include #include +#include #include MODULE_AUTHOR("Paul Barton-Davis "); diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index c5795f32ed30..549e6ab34b03 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From 7779f75f072784d3fccf721b8ec43107f93619a0 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:03:41 +0200 Subject: ALSA: wss_lib: rename cs4321_foo to wss_foo Rename functions and structures from the former cs4321_lib to names more corresponding with the new name: wss_lib. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/azt2320.c | 27 +- sound/isa/cs423x/cs4231.c | 16 +- sound/isa/cs423x/cs4236.c | 47 +- sound/isa/cs423x/cs4236_lib.c | 344 ++++++---- sound/isa/gus/gusmax.c | 48 +- sound/isa/gus/interwave.c | 65 +- sound/isa/opl3sa2.c | 34 +- sound/isa/opti9xx/miro.c | 23 +- sound/isa/opti9xx/opti92x-ad1848.c | 36 +- sound/isa/sscape.c | 61 +- sound/isa/wavefront/wavefront.c | 61 +- sound/isa/wss/wss_lib.c | 1247 ++++++++++++++++++++---------------- 12 files changed, 1129 insertions(+), 880 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index a24db091d445..3e74d1a3928e 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -76,7 +76,7 @@ struct snd_card_azt2320 { int dev_no; struct pnp_dev *dev; struct pnp_dev *devmpu; - struct snd_cs4231 *chip; + struct snd_wss *chip; }; static struct pnp_card_device_id snd_azt2320_pnpids[] = { @@ -181,7 +181,7 @@ static int __devinit snd_card_azt2320_probe(int dev, int error; struct snd_card *card; struct snd_card_azt2320 *acard; - struct snd_cs4231 *chip; + struct snd_wss *chip; struct snd_opl3 *opl3; if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, @@ -200,11 +200,11 @@ static int __devinit snd_card_azt2320_probe(int dev, return error; } - if ((error = snd_cs4231_create(card, wss_port[dev], -1, - irq[dev], - dma1[dev], - dma2[dev], - CS4231_HW_DETECT, 0, &chip)) < 0) { + error = snd_wss_create(card, wss_port[dev], -1, + irq[dev], + dma1[dev], dma2[dev], + WSS_HW_DETECT, 0, &chip); + if (error < 0) { snd_card_free(card); return error; } @@ -214,15 +214,18 @@ static int __devinit snd_card_azt2320_probe(int dev, sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i", card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]); - if ((error = snd_cs4231_pcm(chip, 0, NULL)) < 0) { + error = snd_wss_pcm(chip, 0, NULL); + if (error < 0) { snd_card_free(card); return error; } - if ((error = snd_cs4231_mixer(chip)) < 0) { + error = snd_wss_mixer(chip); + if (error < 0) { snd_card_free(card); return error; } - if ((error = snd_cs4231_timer(chip, 0, NULL)) < 0) { + error = snd_wss_timer(chip, 0, NULL); + if (error < 0) { snd_card_free(card); return error; } @@ -293,7 +296,7 @@ static int snd_azt2320_pnp_suspend(struct pnp_card_link *pcard, pm_message_t sta { struct snd_card *card = pnp_get_card_drvdata(pcard); struct snd_card_azt2320 *acard = card->private_data; - struct snd_cs4231 *chip = acard->chip; + struct snd_wss *chip = acard->chip; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->suspend(chip); @@ -304,7 +307,7 @@ static int snd_azt2320_pnp_resume(struct pnp_card_link *pcard) { struct snd_card *card = pnp_get_card_drvdata(pcard); struct snd_card_azt2320 *acard = card->private_data; - struct snd_cs4231 *chip = acard->chip; + struct snd_wss *chip = acard->chip; chip->resume(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index 7da28e7c0322..ddd289120aa8 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -91,7 +91,7 @@ static int __devinit snd_cs4231_match(struct device *dev, unsigned int n) static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) { struct snd_card *card; - struct snd_cs4231 *chip; + struct snd_wss *chip; struct snd_pcm *pcm; int error; @@ -99,14 +99,14 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) if (!card) return -EINVAL; - error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n], - CS4231_HW_DETECT, 0, &chip); + error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n], + WSS_HW_DETECT, 0, &chip); if (error < 0) goto out; card->private_data = chip; - error = snd_cs4231_pcm(chip, 0, &pcm); + error = snd_wss_pcm(chip, 0, &pcm); if (error < 0) goto out; @@ -118,11 +118,11 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) if (dma2[n] >= 0) sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); - error = snd_cs4231_mixer(chip); + error = snd_wss_mixer(chip); if (error < 0) goto out; - error = snd_cs4231_timer(chip, 0, NULL); + error = snd_wss_timer(chip, 0, NULL); if (error < 0) goto out; @@ -160,7 +160,7 @@ static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n) static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state) { struct snd_card *card = dev_get_drvdata(dev); - struct snd_cs4231 *chip = card->private_data; + struct snd_wss *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->suspend(chip); @@ -170,7 +170,7 @@ static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t s static int snd_cs4231_resume(struct device *dev, unsigned int n) { struct snd_card *card = dev_get_drvdata(dev); - struct snd_cs4231 *chip = card->private_data; + struct snd_wss *chip = card->private_data; chip->resume(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 246c221556e3..3ff0f1229910 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -134,7 +134,7 @@ static int pnp_registered; #endif /* CONFIG_PNP */ struct snd_card_cs4236 { - struct snd_cs4231 *chip; + struct snd_wss *chip; struct resource *res_sb_port; #ifdef CONFIG_PNP struct pnp_dev *wss; @@ -396,7 +396,7 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) { struct snd_card_cs4236 *acard; struct snd_pcm *pcm; - struct snd_cs4231 *chip; + struct snd_wss *chip; struct snd_opl3 *opl3; int err; @@ -408,41 +408,37 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) } #ifdef CS4232 - if ((err = snd_cs4231_create(card, - port[dev], - cport[dev], - irq[dev], - dma1[dev], - dma2[dev], - CS4231_HW_DETECT, - 0, - &chip)) < 0) + err = snd_wss_create(card, port[dev], cport[dev], + irq[dev], + dma1[dev], dma2[dev], + WSS_HW_DETECT, 0, &chip); + if (err < 0) return err; acard->chip = chip; - if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) + err = snd_wss_pcm(chip, 0, &pcm); + if (err < 0) return err; - if ((err = snd_cs4231_mixer(chip)) < 0) + err = snd_wss_mixer(chip); + if (err < 0) return err; #else /* CS4236 */ - if ((err = snd_cs4236_create(card, - port[dev], - cport[dev], - irq[dev], - dma1[dev], - dma2[dev], - CS4231_HW_DETECT, - 0, - &chip)) < 0) + err = snd_cs4236_create(card, + port[dev], cport[dev], + irq[dev], dma1[dev], dma2[dev], + WSS_HW_DETECT, 0, &chip); + if (err < 0) return err; acard->chip = chip; - if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0) + err = snd_cs4236_pcm(chip, 0, &pcm); + if (err < 0) return err; - if ((err = snd_cs4236_mixer(chip)) < 0) + err = snd_cs4236_mixer(chip); + if (err < 0) return err; #endif strcpy(card->driver, pcm->name); @@ -455,7 +451,8 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) if (dma2[dev] >= 0) sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); - if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) + err = snd_wss_timer(chip, 0, NULL); + if (err < 0) return err; if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index eb227d856d1e..33e9cf178b8b 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c @@ -121,13 +121,14 @@ static unsigned char snd_cs4236_ext_map[18] = { * */ -static void snd_cs4236_ctrl_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val) +static void snd_cs4236_ctrl_out(struct snd_wss *chip, + unsigned char reg, unsigned char val) { outb(reg, chip->cport + 3); outb(chip->cimage[reg] = val, chip->cport + 4); } -static unsigned char snd_cs4236_ctrl_in(struct snd_cs4231 *chip, unsigned char reg) +static unsigned char snd_cs4236_ctrl_in(struct snd_wss *chip, unsigned char reg) { outb(reg, chip->cport + 3); return inb(chip->cport + 4); @@ -180,44 +181,52 @@ static unsigned char divisor_to_rate_register(unsigned int divisor) } } -static void snd_cs4236_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char pdfr) +static void snd_cs4236_playback_format(struct snd_wss *chip, + struct snd_pcm_hw_params *params, + unsigned char pdfr) { unsigned long flags; unsigned char rate = divisor_to_rate_register(params->rate_den); spin_lock_irqsave(&chip->reg_lock, flags); /* set fast playback format change and clean playback FIFO */ - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10); - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] & ~0x10); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] | 0x10); + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] & ~0x10); snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate); spin_unlock_irqrestore(&chip->reg_lock, flags); } -static void snd_cs4236_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char cdfr) +static void snd_cs4236_capture_format(struct snd_wss *chip, + struct snd_pcm_hw_params *params, + unsigned char cdfr) { unsigned long flags; unsigned char rate = divisor_to_rate_register(params->rate_den); spin_lock_irqsave(&chip->reg_lock, flags); /* set fast capture format change and clean capture FIFO */ - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20); - snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] & ~0x20); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] | 0x20); + snd_wss_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] & ~0x20); snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate); spin_unlock_irqrestore(&chip->reg_lock, flags); } #ifdef CONFIG_PM -static void snd_cs4236_suspend(struct snd_cs4231 *chip) +static void snd_cs4236_suspend(struct snd_wss *chip) { int reg; unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); for (reg = 0; reg < 32; reg++) - chip->image[reg] = snd_cs4231_in(chip, reg); + chip->image[reg] = snd_wss_in(chip, reg); for (reg = 0; reg < 18; reg++) chip->eimage[reg] = snd_cs4236_ext_in(chip, CS4236_I23VAL(reg)); for (reg = 2; reg < 9; reg++) @@ -225,12 +234,12 @@ static void snd_cs4236_suspend(struct snd_cs4231 *chip) spin_unlock_irqrestore(&chip->reg_lock, flags); } -static void snd_cs4236_resume(struct snd_cs4231 *chip) +static void snd_cs4236_resume(struct snd_wss *chip) { int reg; unsigned long flags; - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); for (reg = 0; reg < 32; reg++) { switch (reg) { @@ -240,7 +249,7 @@ static void snd_cs4236_resume(struct snd_cs4231 *chip) case 29: /* why? CS4235 - master right */ break; default: - snd_cs4231_out(chip, reg, chip->image[reg]); + snd_wss_out(chip, reg, chip->image[reg]); break; } } @@ -255,7 +264,7 @@ static void snd_cs4236_resume(struct snd_cs4231 *chip) } } spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); } #endif /* CONFIG_PM */ @@ -266,24 +275,26 @@ int snd_cs4236_create(struct snd_card *card, int irq, int dma1, int dma2, unsigned short hardware, unsigned short hwshare, - struct snd_cs4231 ** rchip) + struct snd_wss **rchip) { - struct snd_cs4231 *chip; + struct snd_wss *chip; unsigned char ver1, ver2; unsigned int reg; int err; *rchip = NULL; - if (hardware == CS4231_HW_DETECT) - hardware = CS4231_HW_DETECT3; + if (hardware == WSS_HW_DETECT) + hardware = WSS_HW_DETECT3; if (cport < 0x100) { snd_printk("please, specify control port for CS4236+ chips\n"); return -ENODEV; } - if ((err = snd_cs4231_create(card, port, cport, irq, dma1, dma2, hardware, hwshare, &chip)) < 0) + err = snd_wss_create(card, port, cport, + irq, dma1, dma2, hardware, hwshare, &chip); + if (err < 0) return err; - if (!(chip->hardware & CS4231_HW_CS4236B_MASK)) { + if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware); snd_device_free(card, chip); return -ENODEV; @@ -330,20 +341,20 @@ int snd_cs4236_create(struct snd_card *card, snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]); /* initialize compatible but more featured registers */ - snd_cs4231_out(chip, CS4231_LEFT_INPUT, 0x40); - snd_cs4231_out(chip, CS4231_RIGHT_INPUT, 0x40); - snd_cs4231_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff); - snd_cs4231_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff); - snd_cs4231_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf); - snd_cs4231_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf); - snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff); - snd_cs4231_out(chip, CS4231_LEFT_LINE_IN, 0xff); - snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff); + snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40); + snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40); + snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff); + snd_wss_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff); + snd_wss_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf); + snd_wss_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf); + snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff); + snd_wss_out(chip, CS4231_LEFT_LINE_IN, 0xff); + snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff); switch (chip->hardware) { - case CS4231_HW_CS4235: - case CS4231_HW_CS4239: - snd_cs4231_out(chip, CS4235_LEFT_MASTER, 0xff); - snd_cs4231_out(chip, CS4235_RIGHT_MASTER, 0xff); + case WSS_HW_CS4235: + case WSS_HW_CS4239: + snd_wss_out(chip, CS4235_LEFT_MASTER, 0xff); + snd_wss_out(chip, CS4235_RIGHT_MASTER, 0xff); break; } @@ -351,12 +362,13 @@ int snd_cs4236_create(struct snd_card *card, return 0; } -int snd_cs4236_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) +int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; - if ((err = snd_cs4231_pcm(chip, device, &pcm)) < 0) + err = snd_wss_pcm(chip, device, &pcm); + if (err < 0) return err; pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX; if (rpcm) @@ -387,7 +399,7 @@ static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -404,7 +416,7 @@ static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -433,7 +445,7 @@ static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -450,7 +462,7 @@ static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -490,7 +502,7 @@ static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -512,7 +524,7 @@ static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -555,7 +567,7 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -577,7 +589,7 @@ static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -600,7 +612,7 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_ val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2; change = val1 != chip->image[left_reg] || val2 != chip->eimage[CS4236_REG(right_reg)]; - snd_cs4231_out(chip, left_reg, val1); + snd_wss_out(chip, left_reg, val1); snd_cs4236_ext_out(chip, right_reg, val2); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; @@ -619,7 +631,7 @@ static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol) static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); @@ -631,7 +643,7 @@ static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct s static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short val1, val2; @@ -678,7 +690,7 @@ static inline int snd_cs4235_mixer_output_accu_set_volume(int vol) static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); @@ -690,7 +702,7 @@ static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short val1, val2; @@ -701,108 +713,160 @@ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ val1 = (chip->image[CS4235_LEFT_MASTER] & ~(3 << 5)) | val1; val2 = (chip->image[CS4235_RIGHT_MASTER] & ~(3 << 5)) | val2; change = val1 != chip->image[CS4235_LEFT_MASTER] || val2 != chip->image[CS4235_RIGHT_MASTER]; - snd_cs4231_out(chip, CS4235_LEFT_MASTER, val1); - snd_cs4231_out(chip, CS4235_RIGHT_MASTER, val2); + snd_wss_out(chip, CS4235_LEFT_MASTER, val1); + snd_wss_out(chip, CS4235_RIGHT_MASTER, val2); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } static struct snd_kcontrol_new snd_cs4236_controls[] = { -CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), -CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), +CS4236_DOUBLE("Master Digital Playback Switch", 0, + CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), +CS4236_DOUBLE("Master Digital Capture Switch", 0, + CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), CS4236_MASTER_DIGITAL("Master Digital Volume", 0), -CS4236_DOUBLE("Capture Boost Volume", 0, CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), - -CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), - -CS4236_DOUBLE("DSP Playback Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), -CS4236_DOUBLE("DSP Playback Volume", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1), - -CS4236_DOUBLE("FM Playback Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), -CS4236_DOUBLE("FM Playback Volume", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1), - -CS4236_DOUBLE("Wavetable Playback Switch", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), -CS4236_DOUBLE("Wavetable Playback Volume", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1), - -CS4231_DOUBLE("Synth Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), -CS4231_DOUBLE("Synth Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), -CS4231_DOUBLE("Synth Capture Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), -CS4231_DOUBLE("Synth Capture Bypass", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 5, 5, 1, 1), - -CS4236_DOUBLE("Mic Playback Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), -CS4236_DOUBLE("Mic Capture Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), +CS4236_DOUBLE("Capture Boost Volume", 0, + CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), + +WSS_DOUBLE("PCM Playback Switch", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("PCM Playback Volume", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), + +CS4236_DOUBLE("DSP Playback Switch", 0, + CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), +CS4236_DOUBLE("DSP Playback Volume", 0, + CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1), + +CS4236_DOUBLE("FM Playback Switch", 0, + CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), +CS4236_DOUBLE("FM Playback Volume", 0, + CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1), + +CS4236_DOUBLE("Wavetable Playback Switch", 0, + CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), +CS4236_DOUBLE("Wavetable Playback Volume", 0, + CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1), + +WSS_DOUBLE("Synth Playback Switch", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), +WSS_DOUBLE("Synth Volume", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), +WSS_DOUBLE("Synth Capture Switch", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), +WSS_DOUBLE("Synth Capture Bypass", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 5, 5, 1, 1), + +CS4236_DOUBLE("Mic Playback Switch", 0, + CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), +CS4236_DOUBLE("Mic Capture Switch", 0, + CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1), -CS4236_DOUBLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0), - -CS4231_DOUBLE("Line Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Line Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), -CS4231_DOUBLE("Line Capture Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), -CS4231_DOUBLE("Line Capture Bypass", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1), - -CS4231_DOUBLE("CD Playback Switch", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("CD Volume", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), -CS4231_DOUBLE("CD Capture Switch", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), - -CS4236_DOUBLE1("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), -CS4236_DOUBLE1("Mono Playback Switch", 0, CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), -CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), -CS4231_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), - -CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), -CS4231_DOUBLE("Analog Loopback Capture Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), - -CS4231_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0), -CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1) +CS4236_DOUBLE("Mic Playback Boost", 0, + CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0), + +WSS_DOUBLE("Line Playback Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Line Volume", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), +WSS_DOUBLE("Line Capture Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), +WSS_DOUBLE("Line Capture Bypass", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1), + +WSS_DOUBLE("CD Playback Switch", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("CD Volume", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), +WSS_DOUBLE("CD Capture Switch", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), + +CS4236_DOUBLE1("Mono Output Playback Switch", 0, + CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), +CS4236_DOUBLE1("Mono Playback Switch", 0, + CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), +WSS_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), +WSS_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), + +WSS_DOUBLE("Capture Volume", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), +WSS_DOUBLE("Analog Loopback Capture Switch", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), + +WSS_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0), +CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, + CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1) }; static struct snd_kcontrol_new snd_cs4235_controls[] = { -CS4231_DOUBLE("Master Switch", 0, CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1), -CS4231_DOUBLE("Master Volume", 0, CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1), +WSS_DOUBLE("Master Switch", 0, + CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1), +WSS_DOUBLE("Master Volume", 0, + CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1), CS4235_OUTPUT_ACCU("Playback Volume", 0), -CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), -CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), +CS4236_DOUBLE("Master Digital Playback Switch", 0, + CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), +CS4236_DOUBLE("Master Digital Capture Switch", 0, + CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), CS4236_MASTER_DIGITAL("Master Digital Volume", 0), -CS4231_DOUBLE("Master Digital Playback Switch", 1, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), -CS4231_DOUBLE("Master Digital Capture Switch", 1, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), -CS4231_DOUBLE("Master Digital Volume", 1, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), +WSS_DOUBLE("Master Digital Playback Switch", 1, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), +WSS_DOUBLE("Master Digital Capture Switch", 1, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), +WSS_DOUBLE("Master Digital Volume", 1, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), -CS4236_DOUBLE("Capture Volume", 0, CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), +CS4236_DOUBLE("Capture Volume", 0, + CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), -CS4231_DOUBLE("PCM Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("PCM Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), +WSS_DOUBLE("PCM Switch", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("PCM Volume", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), CS4236_DOUBLE("FM Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), -CS4236_DOUBLE("Wavetable Switch", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), +CS4236_DOUBLE("Wavetable Switch", 0, + CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), -CS4236_DOUBLE("Mic Capture Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), -CS4236_DOUBLE("Mic Playback Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), +CS4236_DOUBLE("Mic Capture Switch", 0, + CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), +CS4236_DOUBLE("Mic Playback Switch", 0, + CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1), CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0), -CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Capture Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), -CS4231_DOUBLE("Aux Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), - -CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Capture Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), -CS4231_DOUBLE("Aux Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), - -CS4236_DOUBLE1("Master Mono Switch", 0, CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), - -CS4236_DOUBLE1("Mono Switch", 0, CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), -CS4231_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), - -CS4231_DOUBLE("Analog Loopback Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), +WSS_DOUBLE("Aux Playback Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Aux Capture Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), +WSS_DOUBLE("Aux Volume", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), + +WSS_DOUBLE("Aux Playback Switch", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Aux Capture Switch", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), +WSS_DOUBLE("Aux Volume", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), + +CS4236_DOUBLE1("Master Mono Switch", 0, + CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), + +CS4236_DOUBLE1("Mono Switch", 0, + CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), +WSS_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), + +WSS_DOUBLE("Analog Loopback Switch", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), }; #define CS4236_IEC958_ENABLE(xname, xindex) \ @@ -813,14 +877,14 @@ CS4231_DOUBLE("Analog Loopback Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0; #if 0 printk("get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", - snd_cs4231_in(chip, CS4231_ALT_FEATURE_1), + snd_wss_in(chip, CS4231_ALT_FEATURE_1), snd_cs4236_ctrl_in(chip, 3), snd_cs4236_ctrl_in(chip, 4), snd_cs4236_ctrl_in(chip, 5), @@ -833,7 +897,7 @@ static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct sn static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short enable, val; @@ -841,23 +905,23 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn enable = ucontrol->value.integer.value[0] & 1; mutex_lock(&chip->mce_mutex); - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1); change = val != chip->image[CS4231_ALT_FEATURE_1]; - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, val); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, val); val = snd_cs4236_ctrl_in(chip, 4) | 0xc0; snd_cs4236_ctrl_out(chip, 4, val); udelay(100); val &= ~0x40; snd_cs4236_ctrl_out(chip, 4, val); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); mutex_unlock(&chip->mce_mutex); #if 0 printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", - snd_cs4231_in(chip, CS4231_ALT_FEATURE_1), + snd_wss_in(chip, CS4231_ALT_FEATURE_1), snd_cs4236_ctrl_in(chip, 3), snd_cs4236_ctrl_in(chip, 4), snd_cs4236_ctrl_in(chip, 5), @@ -896,7 +960,7 @@ CS4236_SINGLEC("3D Control - Volume", 0, 2, 0, 15, 1), CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0) }; -int snd_cs4236_mixer(struct snd_cs4231 *chip) +int snd_cs4236_mixer(struct snd_wss *chip) { struct snd_card *card; unsigned int idx, count; @@ -905,10 +969,10 @@ int snd_cs4236_mixer(struct snd_cs4231 *chip) snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); card = chip->card; - strcpy(card->mixername, snd_cs4231_chip_id(chip)); + strcpy(card->mixername, snd_wss_chip_id(chip)); - if (chip->hardware == CS4231_HW_CS4235 || - chip->hardware == CS4231_HW_CS4239) { + if (chip->hardware == WSS_HW_CS4235 || + chip->hardware == WSS_HW_CS4239) { for (idx = 0; idx < ARRAY_SIZE(snd_cs4235_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4235_controls[idx], chip))) < 0) return err; @@ -920,16 +984,16 @@ int snd_cs4236_mixer(struct snd_cs4231 *chip) } } switch (chip->hardware) { - case CS4231_HW_CS4235: - case CS4231_HW_CS4239: + case WSS_HW_CS4235: + case WSS_HW_CS4239: count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4235); kcontrol = snd_cs4236_3d_controls_cs4235; break; - case CS4231_HW_CS4237B: + case WSS_HW_CS4237B: count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4237); kcontrol = snd_cs4236_3d_controls_cs4237; break; - case CS4231_HW_CS4238B: + case WSS_HW_CS4238B: count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4238); kcontrol = snd_cs4236_3d_controls_cs4238; break; @@ -941,8 +1005,8 @@ int snd_cs4236_mixer(struct snd_cs4231 *chip) if ((err = snd_ctl_add(card, snd_ctl_new1(kcontrol, chip))) < 0) return err; } - if (chip->hardware == CS4231_HW_CS4237B || - chip->hardware == CS4231_HW_CS4238B) { + if (chip->hardware == WSS_HW_CS4237B || + chip->hardware == WSS_HW_CS4238B) { for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_iec958_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_iec958_controls[idx], chip))) < 0) return err; diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index cd82891db80a..f94c1976e632 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -75,7 +75,7 @@ struct snd_gusmax { int irq; struct snd_card *card; struct snd_gus_card *gus; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; unsigned short gus_status_reg; unsigned short pcm_status_reg; }; @@ -117,7 +117,7 @@ static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id) } if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ handled = 1; - snd_cs4231_interrupt(irq, maxcard->cs4231); + snd_wss_interrupt(irq, maxcard->wss); loop++; } } while (loop && --max > 0); @@ -140,10 +140,7 @@ static void __devinit snd_gusmax_init(int dev, struct snd_card *card, outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT)); } -#define CS4231_PRIVATE( left, right, shift, mute ) \ - ((left << 24)|(right << 16)|(shift<<8)|mute) - -static int __devinit snd_gusmax_mixer(struct snd_cs4231 *chip) +static int __devinit snd_gusmax_mixer(struct snd_wss *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -214,7 +211,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) int xirq, xdma1, xdma2, err; struct snd_card *card; struct snd_gus_card *gus = NULL; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; struct snd_gusmax *maxcard; card = snd_card_new(index[dev], id[dev], THIS_MODULE, @@ -301,33 +298,39 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) } maxcard->irq = xirq; - if ((err = snd_cs4231_create(card, - gus->gf1.port + 0x10c, -1, xirq, - xdma2 < 0 ? xdma1 : xdma2, xdma1, - CS4231_HW_DETECT, - CS4231_HWSHARE_IRQ | - CS4231_HWSHARE_DMA1 | - CS4231_HWSHARE_DMA2, - &cs4231)) < 0) + err = snd_wss_create(card, + gus->gf1.port + 0x10c, -1, xirq, + xdma2 < 0 ? xdma1 : xdma2, xdma1, + WSS_HW_DETECT, + WSS_HWSHARE_IRQ | + WSS_HWSHARE_DMA1 | + WSS_HWSHARE_DMA2, + &wss); + if (err < 0) goto _err; - if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) + err = snd_wss_pcm(wss, 0, NULL); + if (err < 0) goto _err; - if ((err = snd_cs4231_mixer(cs4231)) < 0) + err = snd_wss_mixer(wss); + if (err < 0) goto _err; - if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) + err = snd_wss_timer(wss, 2, NULL); + if (err < 0) goto _err; if (pcm_channels[dev] > 0) { if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) goto _err; } - if ((err = snd_gusmax_mixer(cs4231)) < 0) + err = snd_gusmax_mixer(wss); + if (err < 0) goto _err; - if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) + err = snd_gf1_rawmidi_new(gus, 0, NULL); + if (err < 0) goto _err; sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1); @@ -336,11 +339,12 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) snd_card_set_dev(card, pdev); - if ((err = snd_card_register(card)) < 0) + err = snd_card_register(card); + if (err < 0) goto _err; maxcard->gus = gus; - maxcard->cs4231 = cs4231; + maxcard->wss = wss; dev_set_drvdata(pdev, card); return 0; diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index eac8cc77e338..5faecfb602d3 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -118,7 +118,7 @@ struct snd_interwave { int irq; struct snd_card *card; struct snd_gus_card *gus; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; #ifdef SNDRV_STB struct resource *i2c_res; #endif @@ -312,7 +312,7 @@ static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id) } if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ handled = 1; - snd_cs4231_interrupt(irq, iwcard->cs4231); + snd_wss_interrupt(irq, iwcard->wss); loop++; } } while (loop && --max > 0); @@ -498,13 +498,17 @@ static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus) } static struct snd_kcontrol_new snd_interwave_controls[] = { -CS4231_DOUBLE("Master Playback Switch", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Master Playback Volume", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1), -CS4231_DOUBLE("Mic Playback Switch", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Mic Playback Volume", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1) +WSS_DOUBLE("Master Playback Switch", 0, + CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("Master Playback Volume", 0, + CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1), +WSS_DOUBLE("Mic Playback Switch", 0, + CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Mic Playback Volume", 0, + CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1) }; -static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip) +static int __devinit snd_interwave_mixer(struct snd_wss *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -527,10 +531,10 @@ static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip) for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0) return err; - snd_cs4231_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f); - snd_cs4231_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f); - snd_cs4231_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f); - snd_cs4231_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f); + snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f); + snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f); + snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f); + snd_wss_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f); /* reassign AUXA to SYNTHESIZER */ strcpy(id1.name, "Aux Playback Switch"); strcpy(id2.name, "Synth Playback Switch"); @@ -642,7 +646,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) { int xirq, xdma1, xdma2; struct snd_interwave *iwcard = card->private_data; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; struct snd_gus_card *gus; #ifdef SNDRV_STB struct snd_i2c_bus *i2c_bus; @@ -684,33 +688,39 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) } iwcard->irq = xirq; - if ((err = snd_cs4231_create(card, - gus->gf1.port + 0x10c, -1, xirq, - xdma2 < 0 ? xdma1 : xdma2, xdma1, - CS4231_HW_INTERWAVE, - CS4231_HWSHARE_IRQ | - CS4231_HWSHARE_DMA1 | - CS4231_HWSHARE_DMA2, - &cs4231)) < 0) + err = snd_wss_create(card, + gus->gf1.port + 0x10c, -1, xirq, + xdma2 < 0 ? xdma1 : xdma2, xdma1, + WSS_HW_INTERWAVE, + WSS_HWSHARE_IRQ | + WSS_HWSHARE_DMA1 | + WSS_HWSHARE_DMA2, + &wss); + if (err < 0) return err; - if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) + err = snd_wss_pcm(wss, 0, &pcm); + if (err < 0) return err; sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A'); strcat(pcm->name, " (codec)"); - if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) + err = snd_wss_timer(wss, 2, NULL); + if (err < 0) return err; - if ((err = snd_cs4231_mixer(cs4231)) < 0) + err = snd_wss_mixer(wss); + if (err < 0) return err; if (pcm_channels[dev] > 0) { - if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) + err = snd_gf1_pcm_new(gus, 1, 1, NULL); + if (err < 0) return err; } - if ((err = snd_interwave_mixer(cs4231)) < 0) + err = snd_interwave_mixer(wss); + if (err < 0) return err; #ifdef SNDRV_STB @@ -754,10 +764,11 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%d", xdma2); - if ((err = snd_card_register(card)) < 0) + err = snd_card_register(card); + if (err < 0) return err; - iwcard->cs4231 = cs4231; + iwcard->wss = wss; iwcard->gus = gus; return 0; } diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index e81cbe86823a..949fee5cd070 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -133,7 +133,7 @@ struct snd_opl3sa2 { spinlock_t reg_lock; struct snd_hwdep *synth; struct snd_rawmidi *rmidi; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; unsigned char ctlregs[0x20]; int ymode; /* SL added */ struct snd_kcontrol *master_switch; @@ -318,7 +318,7 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) if (status & 0x07) { /* TI,CI,PI */ handled = 1; - snd_cs4231_interrupt(irq, chip->cs4231); + snd_wss_interrupt(irq, chip->wss); } if (status & 0x40) { /* hardware volume change */ @@ -573,7 +573,7 @@ static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) struct snd_opl3sa2 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - chip->cs4231->suspend(chip->cs4231); + chip->wss->suspend(chip->wss); /* power down */ snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); @@ -597,8 +597,8 @@ static int snd_opl3sa2_resume(struct snd_card *card) for (i = 0x12; i <= 0x16; i++) snd_opl3sa2_write(chip, i, chip->ctlregs[i]); } - /* restore cs4231 */ - chip->cs4231->resume(chip->cs4231); + /* restore wss */ + chip->wss->resume(chip->wss); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; @@ -659,7 +659,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) { int xirq, xdma1, xdma2; struct snd_opl3sa2 *chip; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; struct snd_opl3 *opl3; int err; @@ -679,23 +679,25 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) return -ENODEV; } chip->irq = xirq; - if ((err = snd_cs4231_create(card, - wss_port[dev] + 4, -1, - xirq, xdma1, xdma2, - CS4231_HW_OPL3SA2, - CS4231_HWSHARE_IRQ, - &cs4231)) < 0) { + err = snd_wss_create(card, + wss_port[dev] + 4, -1, + xirq, xdma1, xdma2, + WSS_HW_OPL3SA2, WSS_HWSHARE_IRQ, &wss); + if (err < 0) { snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4); return err; } - chip->cs4231 = cs4231; - if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) + chip->wss = wss; + err = snd_wss_pcm(wss, 0, NULL); + if (err < 0) return err; - if ((err = snd_cs4231_mixer(cs4231)) < 0) + err = snd_wss_mixer(wss); + if (err < 0) return err; if ((err = snd_opl3sa2_mixer(chip)) < 0) return err; - if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0) + err = snd_wss_timer(wss, 0, NULL); + if (err < 0) return err; if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) { if ((err = snd_opl3_create(card, fm_port[dev], diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 59f7c55baf30..4641daa7844d 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -1221,7 +1221,7 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) int error; struct snd_miro *miro; - struct snd_cs4231 *codec; + struct snd_wss *codec; struct snd_timer *timer; struct snd_card *card; struct snd_pcm *pcm; @@ -1310,29 +1310,32 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) } } - if ((error = snd_miro_configure(miro))) { + error = snd_miro_configure(miro); + if (error) { snd_card_free(card); return error; } - if ((error = snd_cs4231_create(card, miro->wss_base + 4, -1, - miro->irq, miro->dma1, miro->dma2, - CS4231_HW_AD1845, - 0, - &codec)) < 0) { + error = snd_wss_create(card, miro->wss_base + 4, -1, + miro->irq, miro->dma1, miro->dma2, + WSS_HW_AD1845, 0, &codec); + if (error < 0) { snd_card_free(card); return error; } - if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) { + error = snd_wss_pcm(codec, 0, &pcm); + if (error < 0) { snd_card_free(card); return error; } - if ((error = snd_cs4231_mixer(codec)) < 0) { + error = snd_wss_mixer(codec); + if (error < 0) { snd_card_free(card); return error; } - if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) { + error = snd_wss_timer(codec, 0, &timer); + if (error < 0) { snd_card_free(card); return error; } diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 93a03d9c7a95..fefb8597717c 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -139,7 +139,7 @@ struct snd_opti9xx { unsigned long mc_base_size; #ifdef OPTi93X unsigned long mc_indir_index; - struct snd_cs4231 *codec; + struct snd_wss *codec; #endif /* OPTi93X */ unsigned long pwd_reg; @@ -562,7 +562,7 @@ __skip_mpu: static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) { - struct snd_cs4231 *codec = dev_id; + struct snd_wss *codec = dev_id; struct snd_opti9xx *chip = codec->card->private_data; unsigned char status; @@ -570,7 +570,7 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream) snd_pcm_period_elapsed(codec->playback_substream); if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) { - snd_cs4231_overrange(codec); + snd_wss_overrange(codec); snd_pcm_period_elapsed(codec->capture_substream); } outb(0x00, OPTi93X_PORT(codec, STATUS)); @@ -691,7 +691,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) if (chip) { #ifdef OPTi93X - struct snd_cs4231 *codec = chip->codec; + struct snd_wss *codec = chip->codec; if (codec && codec->irq > 0) { disable_irq(codec->irq); free_irq(codec->irq, codec); @@ -707,7 +707,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) int error; struct snd_opti9xx *chip = card->private_data; #if defined(CS4231) || defined(OPTi93X) - struct snd_cs4231 *codec; + struct snd_wss *codec; #ifdef CS4231 struct snd_timer *timer; #endif @@ -734,33 +734,39 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) #endif if (chip->wss_base == SNDRV_AUTO_PORT) { - if ((chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) { + chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); + if (chip->wss_base < 0) { snd_printk("unable to find a free WSS port\n"); return -EBUSY; } } - if ((error = snd_opti9xx_configure(chip))) + error = snd_opti9xx_configure(chip); + if (error) return error; #if defined(CS4231) || defined(OPTi93X) - if ((error = snd_cs4231_create(card, chip->wss_base + 4, -1, - chip->irq, chip->dma1, chip->dma2, + error = snd_wss_create(card, chip->wss_base + 4, -1, + chip->irq, chip->dma1, chip->dma2, #ifdef CS4231 - CS4231_HW_DETECT, 0, + WSS_HW_DETECT, 0, #else /* OPTi93x */ - CS4231_HW_OPTI93X, CS4231_HWSHARE_IRQ, + WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, #endif - &codec)) < 0) + &codec); + if (error < 0) return error; #ifdef OPTi93X chip->codec = codec; #endif - if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) + error = snd_wss_pcm(codec, 0, &pcm); + if (error < 0) return error; - if ((error = snd_cs4231_mixer(codec)) < 0) + error = snd_wss_mixer(codec); + if (error < 0) return error; #ifdef CS4231 - if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) + error = snd_wss_timer(codec, 0, &timer); + if (error < 0) return error; #else /* OPTI93X */ error = request_irq(chip->irq, snd_opti93x_interrupt, diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 1dc4224b3207..48a16d865834 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -147,7 +147,7 @@ struct soundscape { enum card_type type; struct resource *io_res; struct resource *wss_res; - struct snd_cs4231 *chip; + struct snd_wss *chip; struct snd_mpu401 *mpu; struct snd_hwdep *hw; @@ -726,7 +726,7 @@ static int sscape_midi_info(struct snd_kcontrol *ctl, static int sscape_midi_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kctl); + struct snd_wss *chip = snd_kcontrol_chip(kctl); struct snd_card *card = chip->card; register struct soundscape *s = get_card_soundscape(card); unsigned long flags; @@ -746,7 +746,7 @@ static int sscape_midi_get(struct snd_kcontrol *kctl, static int sscape_midi_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kctl); + struct snd_wss *chip = snd_kcontrol_chip(kctl); struct snd_card *card = chip->card; register struct soundscape *s = get_card_soundscape(card); unsigned long flags; @@ -958,7 +958,9 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l * Override for the CS4231 playback format function. * The AD1845 has much simpler format and rate selection. */ -static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *params, unsigned char format) +static void ad1845_playback_format(struct snd_wss *chip, + struct snd_pcm_hw_params *params, + unsigned char format) { unsigned long flags; unsigned rate = params_rate(params); @@ -983,9 +985,9 @@ static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_p * NOTE: We seem to need to write to the MSB before the LSB * to get the correct sample frequency. */ - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0)); - snd_cs4231_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); - snd_cs4231_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0)); + snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); + snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); spin_unlock_irqrestore(&chip->reg_lock, flags); } @@ -994,7 +996,9 @@ static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_p * Override for the CS4231 capture format function. * The AD1845 has much simpler format and rate selection. */ -static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *params, unsigned char format) +static void ad1845_capture_format(struct snd_wss *chip, + struct snd_pcm_hw_params *params, + unsigned char format) { unsigned long flags; unsigned rate = params_rate(params); @@ -1019,9 +1023,9 @@ static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_pa * NOTE: We seem to need to write to the MSB before the LSB * to get the correct sample frequency. */ - snd_cs4231_out(chip, CS4231_REC_FORMAT, (format & 0xf0)); - snd_cs4231_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); - snd_cs4231_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); + snd_wss_out(chip, CS4231_REC_FORMAT, (format & 0xf0)); + snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); + snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); spin_unlock_irqrestore(&chip->reg_lock, flags); } @@ -1036,7 +1040,7 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq, int dma1, int dma2) { register struct soundscape *sscape = get_card_soundscape(card); - struct snd_cs4231 *chip; + struct snd_wss *chip; int err; if (sscape->type == SSCAPE_VIVO) @@ -1045,9 +1049,8 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, if (dma1 == dma2) dma2 = -1; - err = snd_cs4231_create(card, - port, -1, irq, dma1, dma2, - CS4231_HW_DETECT, CS4231_HWSHARE_DMA1, &chip); + err = snd_wss_create(card, port, -1, irq, dma1, dma2, + WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip); if (!err) { unsigned long flags; struct snd_pcm *pcm; @@ -1063,11 +1066,11 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, * #define AD1845_IFACE_CONFIG \ (CS4231_AUTOCALIB | CS4231_RECORD_ENABLE | CS4231_PLAYBACK_ENABLE) - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG); + snd_wss_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); */ if (sscape->type != SSCAPE_VIVO) { @@ -1077,11 +1080,11 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, * be 14.31818 MHz, because we must set this register * to get the playback to sound correct ... */ - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20); + snd_wss_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); /* * More custom configuration: @@ -1089,28 +1092,28 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, * b) enable frequency selection (for capture/playback) */ spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_MISC_INFO, - CS4231_MODE2 | 0x10); - val = snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL); - snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, - val | AD1845_FREQ_SEL_ENABLE); + snd_wss_out(chip, CS4231_MISC_INFO, + CS4231_MODE2 | 0x10); + val = snd_wss_in(chip, AD1845_PWR_DOWN_CTRL); + snd_wss_out(chip, AD1845_PWR_DOWN_CTRL, + val | AD1845_FREQ_SEL_ENABLE); spin_unlock_irqrestore(&chip->reg_lock, flags); } - err = snd_cs4231_pcm(chip, 0, &pcm); + err = snd_wss_pcm(chip, 0, &pcm); if (err < 0) { snd_printk(KERN_ERR "sscape: No PCM device " "for AD1845 chip\n"); goto _error; } - err = snd_cs4231_mixer(chip); + err = snd_wss_mixer(chip); if (err < 0) { snd_printk(KERN_ERR "sscape: No mixer device " "for AD1845 chip\n"); goto _error; } - err = snd_cs4231_timer(chip, 0, NULL); + err = snd_wss_timer(chip, 0, NULL); if (err < 0) { snd_printk(KERN_ERR "sscape: No timer device " "for AD1845 chip\n"); diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 2fb058b5a45f..4c095bc7c729 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -1,6 +1,6 @@ /* * ALSA card-level driver for Turtle Beach Wavefront cards - * (Maui,Tropez,Tropez+) + * (Maui,Tropez,Tropez+) * * Copyright (c) 1997-1999 by Paul Barton-Davis * @@ -320,8 +320,8 @@ snd_wavefront_new_midi (struct snd_card *card, snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_wavefront_midi_input); rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | - SNDRV_RAWMIDI_INFO_INPUT | - SNDRV_RAWMIDI_INFO_DUPLEX; + SNDRV_RAWMIDI_INFO_INPUT | + SNDRV_RAWMIDI_INFO_DUPLEX; return rmidi; } @@ -364,7 +364,7 @@ static int __devinit snd_wavefront_probe (struct snd_card *card, int dev) { snd_wavefront_card_t *acard = card->private_data; - struct snd_cs4231 *chip; + struct snd_wss *chip; struct snd_hwdep *wavefront_synth; struct snd_rawmidi *ics2115_internal_rmidi = NULL; struct snd_rawmidi *ics2115_external_rmidi = NULL; @@ -373,21 +373,20 @@ snd_wavefront_probe (struct snd_card *card, int dev) /* --------- PCM --------------- */ - if ((err = snd_cs4231_create (card, - cs4232_pcm_port[dev], - -1, - cs4232_pcm_irq[dev], - dma1[dev], - dma2[dev], - CS4231_HW_DETECT, 0, &chip)) < 0) { - snd_printk (KERN_ERR "can't allocate CS4231 device\n"); + err = snd_wss_create(card, cs4232_pcm_port[dev], -1, + cs4232_pcm_irq[dev], dma1[dev], dma2[dev], + WSS_HW_DETECT, 0, &chip); + if (err < 0) { + snd_printk(KERN_ERR "can't allocate WSS device\n"); return err; } - if ((err = snd_cs4231_pcm (chip, 0, NULL)) < 0) + err = snd_wss_pcm(chip, 0, NULL); + if (err < 0) return err; - if ((err = snd_cs4231_timer (chip, 0, NULL)) < 0) + err = snd_wss_timer(chip, 0, NULL); + if (err < 0) return err; /* ---------- OPL3 synth --------- */ @@ -395,24 +394,24 @@ snd_wavefront_probe (struct snd_card *card, int dev) if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { struct snd_opl3 *opl3; - if ((err = snd_opl3_create(card, - fm_port[dev], - fm_port[dev] + 2, - OPL3_HW_OPL3_CS, - 0, &opl3)) < 0) { + err = snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2, + OPL3_HW_OPL3_CS, 0, &opl3); + if (err < 0) { snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n"); return err; } - if ((err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL)) < 0) + err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL); + if (err < 0) return err; hw_dev++; } /* ------- ICS2115 Wavetable synth ------- */ - if ((acard->wavefront.res_base = request_region(ics2115_port[dev], 16, - "ICS2115")) == NULL) { + acard->wavefront.res_base = request_region(ics2115_port[dev], 16, + "ICS2115"); + if (acard->wavefront.res_base == NULL) { snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n", ics2115_port[dev], ics2115_port[dev] + 16 - 1); return -EBUSY; @@ -426,7 +425,8 @@ snd_wavefront_probe (struct snd_card *card, int dev) acard->wavefront.irq = ics2115_irq[dev]; acard->wavefront.base = ics2115_port[dev]; - if ((wavefront_synth = snd_wavefront_new_synth (card, hw_dev, acard)) == NULL) { + wavefront_synth = snd_wavefront_new_synth(card, hw_dev, acard); + if (wavefront_synth == NULL) { snd_printk (KERN_ERR "can't create WaveFront synth device\n"); return -ENOMEM; } @@ -437,7 +437,8 @@ snd_wavefront_probe (struct snd_card *card, int dev) /* --------- Mixer ------------ */ - if ((err = snd_cs4231_mixer(chip)) < 0) { + err = snd_wss_mixer(chip); + if (err < 0) { snd_printk (KERN_ERR "can't allocate mixer device\n"); return err; } @@ -445,11 +446,11 @@ snd_wavefront_probe (struct snd_card *card, int dev) /* -------- CS4232 MPU-401 interface -------- */ if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) { - if ((err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232, - cs4232_mpu_port[dev], 0, - cs4232_mpu_irq[dev], - IRQF_DISABLED, - NULL)) < 0) { + err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232, + cs4232_mpu_port[dev], 0, + cs4232_mpu_irq[dev], IRQF_DISABLED, + NULL); + if (err < 0) { snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n"); return err; } @@ -602,7 +603,7 @@ static struct isa_driver snd_wavefront_driver = { #ifdef CONFIG_PNP static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) + const struct pnp_card_device_id *pid) { static int dev; struct snd_card *card; diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 549e6ab34b03..a982997805c4 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -6,7 +6,7 @@ * - sometimes record brokes playback with WSS portion of * Yamaha OPL3-SA3 chip * - CS4231 (GUS MAX) - still trouble with occasional noises - * - broken initialization? + * - broken initialization? * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -78,12 +78,13 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = { .mask = 0, }; -static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime) +static int snd_wss_xrate(struct snd_pcm_runtime *runtime) { - return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); + return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hw_constraints_rates); } -static unsigned char snd_cs4231_original_image[32] = +static unsigned char snd_wss_original_image[32] = { 0x00, /* 00/00 - lic */ 0x00, /* 01/01 - ric */ @@ -159,150 +160,209 @@ static unsigned char snd_opti93x_original_image[32] = * Basic I/O functions */ -static inline void cs4231_outb(struct snd_cs4231 *chip, u8 offset, u8 val) +static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val) { outb(val, chip->port + offset); } -static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset) +static inline u8 wss_inb(struct snd_wss *chip, u8 offset) { return inb(chip->port + offset); } -static void snd_cs4231_wait(struct snd_cs4231 *chip) +static void snd_wss_wait(struct snd_wss *chip) { int timeout; for (timeout = 250; - timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); + timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(100); } -static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, +static void snd_wss_outm(struct snd_wss *chip, unsigned char reg, unsigned char mask, unsigned char value) { unsigned char tmp = (chip->image[reg] & mask) | value; - snd_cs4231_wait(chip); + snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); #endif chip->image[reg] = tmp; if (!chip->calibrate_mute) { - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); wmb(); - cs4231_outb(chip, CS4231P(REG), tmp); + wss_outb(chip, CS4231P(REG), tmp); mb(); } } -static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) +static void snd_wss_dout(struct snd_wss *chip, unsigned char reg, + unsigned char value) { int timeout; for (timeout = 250; - timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); + timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(10); - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); - cs4231_outb(chip, CS4231P(REG), value); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + wss_outb(chip, CS4231P(REG), value); mb(); } -void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) +void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value) { - snd_cs4231_wait(chip); + snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); #endif - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); - cs4231_outb(chip, CS4231P(REG), value); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + wss_outb(chip, CS4231P(REG), value); chip->image[reg] = value; mb(); snd_printdd("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value); } +EXPORT_SYMBOL(snd_wss_out); -unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) +unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg) { - snd_cs4231_wait(chip); + snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); #endif - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); mb(); - return cs4231_inb(chip, CS4231P(REG)); + return wss_inb(chip, CS4231P(REG)); } +EXPORT_SYMBOL(snd_wss_in); -void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val) +void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg, + unsigned char val) { - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); - cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); - cs4231_outb(chip, CS4231P(REG), val); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); + wss_outb(chip, CS4231P(REG), + reg | (chip->image[CS4236_EXT_REG] & 0x01)); + wss_outb(chip, CS4231P(REG), val); chip->eimage[CS4236_REG(reg)] = val; #if 0 printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val); #endif } +EXPORT_SYMBOL(snd_cs4236_ext_out); -unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg) +unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg) { - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); - cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); + wss_outb(chip, CS4231P(REG), + reg | (chip->image[CS4236_EXT_REG] & 0x01)); #if 1 - return cs4231_inb(chip, CS4231P(REG)); + return wss_inb(chip, CS4231P(REG)); #else { unsigned char res; - res = cs4231_inb(chip, CS4231P(REG)); + res = wss_inb(chip, CS4231P(REG)); printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res); return res; } #endif } +EXPORT_SYMBOL(snd_cs4236_ext_in); #if 0 -static void snd_cs4231_debug(struct snd_cs4231 *chip) -{ - printk("CS4231 REGS: INDEX = 0x%02x ", cs4231_inb(chip, CS4231P(REGSEL))); - printk(" STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS))); - printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00)); - printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10)); - printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01)); - printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11)); - printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02)); - printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12)); - printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03)); - printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13)); - printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04)); - printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14)); - printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05)); - printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15)); - printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06)); - printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16)); - printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07)); - printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17)); - printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08)); - printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18)); - printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09)); - printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19)); - printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a)); - printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a)); - printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b)); - printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b)); - printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c)); - printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c)); - printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d)); - printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d)); - printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e)); - printk(" 0x1e: ply lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e)); - printk(" 0x0f: rec upr count = 0x%02x ", snd_cs4231_in(chip, 0x0f)); - printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f)); +static void snd_wss_debug(struct snd_wss *chip) +{ + printk(KERN_DEBUG + "CS4231 REGS: INDEX = 0x%02x " + " STATUS = 0x%02x\n", + wss_inb(chip, CS4231P(REGSEL), + wss_inb(chip, CS4231P(STATUS))); + printk(KERN_DEBUG + " 0x00: left input = 0x%02x " + " 0x10: alt 1 (CFIG 2) = 0x%02x\n", + snd_wss_in(chip, 0x00), + snd_wss_in(chip, 0x10)); + printk(KERN_DEBUG + " 0x01: right input = 0x%02x " + " 0x11: alt 2 (CFIG 3) = 0x%02x\n", + snd_wss_in(chip, 0x01), + snd_wss_in(chip, 0x11)); + printk(KERN_DEBUG + " 0x02: GF1 left input = 0x%02x " + " 0x12: left line in = 0x%02x\n", + snd_wss_in(chip, 0x02), + snd_wss_in(chip, 0x12)); + printk(KERN_DEBUG + " 0x03: GF1 right input = 0x%02x " + " 0x13: right line in = 0x%02x\n", + snd_wss_in(chip, 0x03), + snd_wss_in(chip, 0x13)); + printk(KERN_DEBUG + " 0x04: CD left input = 0x%02x " + " 0x14: timer low = 0x%02x\n", + snd_wss_in(chip, 0x04), + snd_wss_in(chip, 0x14)); + printk(KERN_DEBUG + " 0x05: CD right input = 0x%02x " + " 0x15: timer high = 0x%02x\n", + snd_wss_in(chip, 0x05), + snd_wss_in(chip, 0x15)); + printk(KERN_DEBUG + " 0x06: left output = 0x%02x " + " 0x16: left MIC (PnP) = 0x%02x\n", + snd_wss_in(chip, 0x06), + snd_wss_in(chip, 0x16)); + printk(KERN_DEBUG + " 0x07: right output = 0x%02x " + " 0x17: right MIC (PnP) = 0x%02x\n", + snd_wss_in(chip, 0x07), + snd_wss_in(chip, 0x17)); + printk(KERN_DEBUG + " 0x08: playback format = 0x%02x " + " 0x18: IRQ status = 0x%02x\n", + snd_wss_in(chip, 0x08), + snd_wss_in(chip, 0x18)); + printk(KERN_DEBUG + " 0x09: iface (CFIG 1) = 0x%02x " + " 0x19: left line out = 0x%02x\n", + snd_wss_in(chip, 0x09), + snd_wss_in(chip, 0x19)); + printk(KERN_DEBUG + " 0x0a: pin control = 0x%02x " + " 0x1a: mono control = 0x%02x\n", + snd_wss_in(chip, 0x0a), + snd_wss_in(chip, 0x1a)); + printk(KERN_DEBUG + " 0x0b: init & status = 0x%02x " + " 0x1b: right line out = 0x%02x\n", + snd_wss_in(chip, 0x0b), + snd_wss_in(chip, 0x1b)); + printk(KERN_DEBUG + " 0x0c: revision & mode = 0x%02x " + " 0x1c: record format = 0x%02x\n", + snd_wss_in(chip, 0x0c), + snd_wss_in(chip, 0x1c)); + printk(KERN_DEBUG + " 0x0d: loopback = 0x%02x " + " 0x1d: var freq (PnP) = 0x%02x\n", + snd_wss_in(chip, 0x0d), + snd_wss_in(chip, 0x1d)); + printk(KERN_DEBUG + " 0x0e: ply upr count = 0x%02x " + " 0x1e: ply lwr count = 0x%02x\n", + snd_wss_in(chip, 0x0e), + snd_wss_in(chip, 0x1e)); + printk(KERN_DEBUG + " 0x0f: rec upr count = 0x%02x " + " 0x1f: rec lwr count = 0x%02x\n", + snd_wss_in(chip, 0x0f), + snd_wss_in(chip, 0x1f)); } #endif @@ -311,61 +371,63 @@ static void snd_cs4231_debug(struct snd_cs4231 *chip) * CS4231 detection / MCE routines */ -static void snd_cs4231_busy_wait(struct snd_cs4231 *chip) +static void snd_wss_busy_wait(struct snd_wss *chip) { int timeout; /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */ for (timeout = 5; timeout > 0; timeout--) - cs4231_inb(chip, CS4231P(REGSEL)); + wss_inb(chip, CS4231P(REGSEL)); /* end of cleanup sequence */ for (timeout = 250; - timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); + timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(10); } -void snd_cs4231_mce_up(struct snd_cs4231 *chip) +void snd_wss_mce_up(struct snd_wss *chip) { unsigned long flags; int timeout; - snd_cs4231_wait(chip); + snd_wss_wait(chip); #ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("mce_up - auto calibration time out (0)\n"); #endif spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit |= CS4231_MCE; - timeout = cs4231_inb(chip, CS4231P(REGSEL)); + timeout = wss_inb(chip, CS4231P(REGSEL)); if (timeout == 0x80) snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); if (!(timeout & CS4231_MCE)) - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + wss_outb(chip, CS4231P(REGSEL), + chip->mce_bit | (timeout & 0x1f)); spin_unlock_irqrestore(&chip->reg_lock, flags); } +EXPORT_SYMBOL(snd_wss_mce_up); -void snd_cs4231_mce_down(struct snd_cs4231 *chip) +void snd_wss_mce_down(struct snd_wss *chip) { unsigned long flags; unsigned long end_time; int timeout; - snd_cs4231_busy_wait(chip); + snd_wss_busy_wait(chip); #ifdef CONFIG_SND_DEBUG - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); #endif spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit &= ~CS4231_MCE; - timeout = cs4231_inb(chip, CS4231P(REGSEL)); - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + timeout = wss_inb(chip, CS4231P(REGSEL)); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || - !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { + !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) { return; } @@ -380,7 +442,7 @@ void snd_cs4231_mce_down(struct snd_cs4231 *chip) /* check condition up to 250 ms */ end_time = jiffies + msecs_to_jiffies(250); - while (snd_cs4231_in(chip, CS4231_TEST_INIT) & + while (snd_wss_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) { if (time_after(jiffies, end_time)) { @@ -395,7 +457,7 @@ void snd_cs4231_mce_down(struct snd_cs4231 *chip) /* check condition up to 100 ms */ end_time = jiffies + msecs_to_jiffies(100); - while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { + while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { if (time_after(jiffies, end_time)) { snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); return; @@ -404,10 +466,11 @@ void snd_cs4231_mce_down(struct snd_cs4231 *chip) } snd_printdd("(3) jiffies = %lu\n", jiffies); - snd_printd("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL))); + snd_printd("mce_down - exit = 0x%x\n", wss_inb(chip, CS4231P(REGSEL))); } +EXPORT_SYMBOL(snd_wss_mce_down); -static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size) +static unsigned int snd_wss_get_count(unsigned char format, unsigned int size) { switch (format & 0xe0) { case CS4231_LINEAR_16: @@ -422,19 +485,15 @@ static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size return size; } -static int snd_cs4231_trigger(struct snd_pcm_substream *substream, - int cmd) +static int snd_wss_trigger(struct snd_pcm_substream *substream, + int cmd) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); int result = 0; unsigned int what; struct snd_pcm_substream *s; int do_start; -#if 0 - printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, cs4231_inb(chip, CS4231P(STATUS))); -#endif - switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -466,10 +525,10 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, if (chip->trigger) chip->trigger(chip, what, 0); } - snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); + snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); spin_unlock(&chip->reg_lock); #if 0 - snd_cs4231_debug(chip); + snd_wss_debug(chip); #endif return result; } @@ -478,7 +537,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, * CODEC I/O */ -static unsigned char snd_cs4231_get_rate(unsigned int rate) +static unsigned char snd_wss_get_rate(unsigned int rate) { int i; @@ -489,9 +548,9 @@ static unsigned char snd_cs4231_get_rate(unsigned int rate) return freq_bits[ARRAY_SIZE(rates) - 1]; } -static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, - int format, - int channels) +static unsigned char snd_wss_get_format(struct snd_wss *chip, + int format, + int channels) { unsigned char rformat; @@ -511,7 +570,7 @@ static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, return rformat; } -static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute) +static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute) { unsigned long flags; @@ -522,30 +581,46 @@ static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute) return; } if (!mute) { - snd_cs4231_dout(chip, CS4231_LEFT_INPUT, chip->image[CS4231_LEFT_INPUT]); - snd_cs4231_dout(chip, CS4231_RIGHT_INPUT, chip->image[CS4231_RIGHT_INPUT]); - snd_cs4231_dout(chip, CS4231_LOOPBACK, chip->image[CS4231_LOOPBACK]); + snd_wss_dout(chip, CS4231_LEFT_INPUT, + chip->image[CS4231_LEFT_INPUT]); + snd_wss_dout(chip, CS4231_RIGHT_INPUT, + chip->image[CS4231_RIGHT_INPUT]); + snd_wss_dout(chip, CS4231_LOOPBACK, + chip->image[CS4231_LOOPBACK]); } - snd_cs4231_dout(chip, CS4231_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]); - snd_cs4231_dout(chip, CS4231_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]); - snd_cs4231_dout(chip, CS4231_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]); - snd_cs4231_dout(chip, CS4231_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]); - snd_cs4231_dout(chip, CS4231_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]); - snd_cs4231_dout(chip, CS4231_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]); - snd_cs4231_dout(chip, CS4231_LEFT_LINE_IN, mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); - snd_cs4231_dout(chip, CS4231_RIGHT_LINE_IN, mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); - snd_cs4231_dout(chip, CS4231_MONO_CTRL, mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); - if (chip->hardware == CS4231_HW_INTERWAVE) { - snd_cs4231_dout(chip, CS4231_LEFT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]); - snd_cs4231_dout(chip, CS4231_RIGHT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]); - snd_cs4231_dout(chip, CS4231_LINE_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]); - snd_cs4231_dout(chip, CS4231_LINE_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]); + snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT, + mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]); + snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT, + mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]); + snd_wss_dout(chip, CS4231_AUX2_LEFT_INPUT, + mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]); + snd_wss_dout(chip, CS4231_AUX2_RIGHT_INPUT, + mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]); + snd_wss_dout(chip, CS4231_LEFT_OUTPUT, + mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]); + snd_wss_dout(chip, CS4231_RIGHT_OUTPUT, + mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]); + snd_wss_dout(chip, CS4231_LEFT_LINE_IN, + mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); + snd_wss_dout(chip, CS4231_RIGHT_LINE_IN, + mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); + snd_wss_dout(chip, CS4231_MONO_CTRL, + mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); + if (chip->hardware == WSS_HW_INTERWAVE) { + snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT, + mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]); + snd_wss_dout(chip, CS4231_RIGHT_MIC_INPUT, + mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]); + snd_wss_dout(chip, CS4231_LINE_LEFT_OUTPUT, + mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]); + snd_wss_dout(chip, CS4231_LINE_RIGHT_OUTPUT, + mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]); } chip->calibrate_mute = mute; spin_unlock_irqrestore(&chip->reg_lock, flags); } -static void snd_cs4231_playback_format(struct snd_cs4231 *chip, +static void snd_wss_playback_format(struct snd_wss *chip, struct snd_pcm_hw_params *params, unsigned char pdfr) { @@ -553,79 +628,88 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, int full_calib = 1; mutex_lock(&chip->mce_mutex); - snd_cs4231_calibrate_mute(chip, 1); - if (chip->hardware == CS4231_HW_CS4231A || - (chip->hardware & CS4231_HW_CS4232_MASK)) { + snd_wss_calibrate_mute(chip, 1); + if (chip->hardware == WSS_HW_CS4231A || + (chip->hardware & WSS_HW_CS4232_MASK)) { spin_lock_irqsave(&chip->reg_lock, flags); if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */ - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10); - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x10); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] | 0x10); + chip->image[CS4231_PLAYBK_FORMAT] = pdfr; + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, + chip->image[CS4231_PLAYBK_FORMAT]); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] &= ~0x10); udelay(100); /* Fixes audible clicks at least on GUS MAX */ full_calib = 0; } spin_unlock_irqrestore(&chip->reg_lock, flags); } if (full_calib) { - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - if (chip->hardware != CS4231_HW_INTERWAVE && !chip->single_dma) { - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, - (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ? - (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) : - pdfr); + if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) { + if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) + pdfr = (pdfr & 0xf0) | + (chip->image[CS4231_REC_FORMAT] & 0x0f); } else { - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr); + chip->image[CS4231_PLAYBK_FORMAT] = pdfr; } + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr); spin_unlock_irqrestore(&chip->reg_lock, flags); - if (chip->hardware == CS4231_HW_OPL3SA2) + if (chip->hardware == WSS_HW_OPL3SA2) udelay(100); /* this seems to help */ - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); } - snd_cs4231_calibrate_mute(chip, 0); + snd_wss_calibrate_mute(chip, 0); mutex_unlock(&chip->mce_mutex); } -static void snd_cs4231_capture_format(struct snd_cs4231 *chip, - struct snd_pcm_hw_params *params, - unsigned char cdfr) +static void snd_wss_capture_format(struct snd_wss *chip, + struct snd_pcm_hw_params *params, + unsigned char cdfr) { unsigned long flags; int full_calib = 1; mutex_lock(&chip->mce_mutex); - snd_cs4231_calibrate_mute(chip, 1); - if (chip->hardware == CS4231_HW_CS4231A || - (chip->hardware & CS4231_HW_CS4232_MASK)) { + snd_wss_calibrate_mute(chip, 1); + if (chip->hardware == WSS_HW_CS4231A || + (chip->hardware & WSS_HW_CS4232_MASK)) { spin_lock_irqsave(&chip->reg_lock, flags); if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */ (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20); - snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT] = cdfr); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x20); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] | 0x20); + snd_wss_out(chip, CS4231_REC_FORMAT, + chip->image[CS4231_REC_FORMAT] = cdfr); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] &= ~0x20); full_calib = 0; } spin_unlock_irqrestore(&chip->reg_lock, flags); } if (full_calib) { - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - if (chip->hardware != CS4231_HW_INTERWAVE) { - if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, - ((chip->single_dma ? cdfr : chip->image[CS4231_PLAYBK_FORMAT]) & 0xf0) | - (cdfr & 0x0f)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); - snd_cs4231_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - } + if (chip->hardware != WSS_HW_INTERWAVE && + !(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) { + if (chip->single_dma) + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr); + else + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, + (chip->image[CS4231_PLAYBK_FORMAT] & 0xf0) | + (cdfr & 0x0f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_wss_mce_down(chip); + snd_wss_mce_up(chip); + spin_lock_irqsave(&chip->reg_lock, flags); } - snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr); + snd_wss_out(chip, CS4231_REC_FORMAT, cdfr); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); } - snd_cs4231_calibrate_mute(chip, 0); + snd_wss_calibrate_mute(chip, 0); mutex_unlock(&chip->mce_mutex); } @@ -633,130 +717,146 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, * Timer interface */ -static unsigned long snd_cs4231_timer_resolution(struct snd_timer * timer) +static unsigned long snd_wss_timer_resolution(struct snd_timer *timer) { - struct snd_cs4231 *chip = snd_timer_chip(timer); - if (chip->hardware & CS4231_HW_CS4236B_MASK) + struct snd_wss *chip = snd_timer_chip(timer); + if (chip->hardware & WSS_HW_CS4236B_MASK) return 14467; else return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920; } -static int snd_cs4231_timer_start(struct snd_timer * timer) +static int snd_wss_timer_start(struct snd_timer *timer) { unsigned long flags; unsigned int ticks; - struct snd_cs4231 *chip = snd_timer_chip(timer); + struct snd_wss *chip = snd_timer_chip(timer); spin_lock_irqsave(&chip->reg_lock, flags); ticks = timer->sticks; if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 || (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] || (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) { - snd_cs4231_out(chip, CS4231_TIMER_HIGH, chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8)); - snd_cs4231_out(chip, CS4231_TIMER_LOW, chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE); + chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8); + snd_wss_out(chip, CS4231_TIMER_HIGH, + chip->image[CS4231_TIMER_HIGH]); + chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks; + snd_wss_out(chip, CS4231_TIMER_LOW, + chip->image[CS4231_TIMER_LOW]); + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1] | + CS4231_TIMER_ENABLE); } spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } -static int snd_cs4231_timer_stop(struct snd_timer * timer) +static int snd_wss_timer_stop(struct snd_timer *timer) { unsigned long flags; - struct snd_cs4231 *chip = snd_timer_chip(timer); + struct snd_wss *chip = snd_timer_chip(timer); spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE); + chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE; + snd_wss_out(chip, CS4231_ALT_FEATURE_1, + chip->image[CS4231_ALT_FEATURE_1]); spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } -static void snd_cs4231_init(struct snd_cs4231 *chip) +static void snd_wss_init(struct snd_wss *chip) { unsigned long flags; - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE snd_printk("init: (1)\n"); #endif - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | - CS4231_RECORD_ENABLE | CS4231_RECORD_PIO | - CS4231_CALIB_MODE); + chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | + CS4231_PLAYBACK_PIO | + CS4231_RECORD_ENABLE | + CS4231_RECORD_PIO | + CS4231_CALIB_MODE); chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB; - snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); + snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE snd_printk("init: (2)\n"); #endif - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]); + snd_wss_out(chip, + CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE - snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]); + snd_printk("init: (3) - afei = 0x%x\n", + chip->image[CS4231_ALT_FEATURE_1]); #endif spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]); + snd_wss_out(chip, CS4231_ALT_FEATURE_2, + chip->image[CS4231_ALT_FEATURE_2]); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]); + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, + chip->image[CS4231_PLAYBK_FORMAT]); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE snd_printk("init: (4)\n"); #endif - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]); + snd_wss_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); #ifdef SNDRV_DEBUG_MCE snd_printk("init: (5)\n"); #endif } -static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) +static int snd_wss_open(struct snd_wss *chip, unsigned int mode) { unsigned long flags; mutex_lock(&chip->open_mutex); if ((chip->mode & mode) || - ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) { + ((chip->mode & WSS_MODE_OPEN) && chip->single_dma)) { mutex_unlock(&chip->open_mutex); return -EAGAIN; } - if (chip->mode & CS4231_MODE_OPEN) { + if (chip->mode & WSS_MODE_OPEN) { chip->mode |= mode; mutex_unlock(&chip->open_mutex); return 0; } /* ok. now enable and ack CODEC IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | - CS4231_RECORD_IRQ | - CS4231_TIMER_IRQ); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + snd_wss_out(chip, CS4231_IRQ_STATUS, + CS4231_PLAYBACK_IRQ | + CS4231_RECORD_IRQ | + CS4231_TIMER_IRQ); + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE; - snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | - CS4231_RECORD_IRQ | - CS4231_TIMER_IRQ); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); + snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); + snd_wss_out(chip, CS4231_IRQ_STATUS, + CS4231_PLAYBACK_IRQ | + CS4231_RECORD_IRQ | + CS4231_TIMER_IRQ); + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); spin_unlock_irqrestore(&chip->reg_lock, flags); chip->mode = mode; @@ -764,48 +864,49 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) return 0; } -static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) +static void snd_wss_close(struct snd_wss *chip, unsigned int mode) { unsigned long flags; mutex_lock(&chip->open_mutex); chip->mode &= ~mode; - if (chip->mode & CS4231_MODE_OPEN) { + if (chip->mode & WSS_MODE_OPEN) { mutex_unlock(&chip->open_mutex); return; } - snd_cs4231_calibrate_mute(chip, 1); + snd_wss_calibrate_mute(chip, 1); /* disable IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE; - snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); + snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); /* now disable record & playback */ if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) { spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); - snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); + snd_wss_out(chip, CS4231_IFACE_CTRL, + chip->image[CS4231_IFACE_CTRL]); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); spin_lock_irqsave(&chip->reg_lock, flags); } /* clear IRQ again */ - snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_calibrate_mute(chip, 0); + snd_wss_calibrate_mute(chip, 0); chip->mode = 0; mutex_unlock(&chip->open_mutex); @@ -815,59 +916,60 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) * timer open/close */ -static int snd_cs4231_timer_open(struct snd_timer * timer) +static int snd_wss_timer_open(struct snd_timer *timer) { - struct snd_cs4231 *chip = snd_timer_chip(timer); - snd_cs4231_open(chip, CS4231_MODE_TIMER); + struct snd_wss *chip = snd_timer_chip(timer); + snd_wss_open(chip, WSS_MODE_TIMER); return 0; } -static int snd_cs4231_timer_close(struct snd_timer * timer) +static int snd_wss_timer_close(struct snd_timer *timer) { - struct snd_cs4231 *chip = snd_timer_chip(timer); - snd_cs4231_close(chip, CS4231_MODE_TIMER); + struct snd_wss *chip = snd_timer_chip(timer); + snd_wss_close(chip, WSS_MODE_TIMER); return 0; } -static struct snd_timer_hardware snd_cs4231_timer_table = +static struct snd_timer_hardware snd_wss_timer_table = { .flags = SNDRV_TIMER_HW_AUTO, .resolution = 9945, .ticks = 65535, - .open = snd_cs4231_timer_open, - .close = snd_cs4231_timer_close, - .c_resolution = snd_cs4231_timer_resolution, - .start = snd_cs4231_timer_start, - .stop = snd_cs4231_timer_stop, + .open = snd_wss_timer_open, + .close = snd_wss_timer_close, + .c_resolution = snd_wss_timer_resolution, + .start = snd_wss_timer_start, + .stop = snd_wss_timer_stop, }; /* * ok.. exported functions.. */ -static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream, +static int snd_wss_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); unsigned char new_pdfr; int err; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) return err; - new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) | - snd_cs4231_get_rate(params_rate(hw_params)); + new_pdfr = snd_wss_get_format(chip, params_format(hw_params), + params_channels(hw_params)) | + snd_wss_get_rate(params_rate(hw_params)); chip->set_playback_format(chip, hw_params, new_pdfr); return 0; } -static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream) +static int snd_wss_playback_hw_free(struct snd_pcm_substream *substream) { return snd_pcm_lib_free_pages(substream); } -static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) +static int snd_wss_playback_prepare(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned long flags; unsigned int size = snd_pcm_lib_buffer_bytes(substream); @@ -877,39 +979,40 @@ static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) chip->p_dma_size = size; chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO); snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); - count = snd_cs4231_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1; - snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); - snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); + count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1; + snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); + snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); spin_unlock_irqrestore(&chip->reg_lock, flags); #if 0 - snd_cs4231_debug(chip); + snd_wss_debug(chip); #endif return 0; } -static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream, +static int snd_wss_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); unsigned char new_cdfr; int err; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) return err; - new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) | - snd_cs4231_get_rate(params_rate(hw_params)); + new_cdfr = snd_wss_get_format(chip, params_format(hw_params), + params_channels(hw_params)) | + snd_wss_get_rate(params_rate(hw_params)); chip->set_capture_format(chip, hw_params, new_cdfr); return 0; } -static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream) +static int snd_wss_capture_hw_free(struct snd_pcm_substream *substream) { return snd_pcm_lib_free_pages(substream); } -static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) +static int snd_wss_capture_prepare(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned long flags; unsigned int size = snd_pcm_lib_buffer_bytes(substream); @@ -919,49 +1022,52 @@ static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) chip->c_dma_size = size; chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); - count = snd_cs4231_get_count(chip->image[CS4231_REC_FORMAT], count) - 1; - if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) { - snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); - snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8)); + count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT], count) - 1; + if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) { + snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); + snd_wss_out(chip, CS4231_PLY_UPR_CNT, + (unsigned char) (count >> 8)); } else { - snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count); - snd_cs4231_out(chip, CS4231_REC_UPR_CNT, (unsigned char) (count >> 8)); + snd_wss_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count); + snd_wss_out(chip, CS4231_REC_UPR_CNT, + (unsigned char) (count >> 8)); } spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } -void snd_cs4231_overrange(struct snd_cs4231 *chip) +void snd_wss_overrange(struct snd_wss *chip) { unsigned long flags; unsigned char res; spin_lock_irqsave(&chip->reg_lock, flags); - res = snd_cs4231_in(chip, CS4231_TEST_INIT); + res = snd_wss_in(chip, CS4231_TEST_INIT); spin_unlock_irqrestore(&chip->reg_lock, flags); if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */ chip->capture_substream->runtime->overrange++; } +EXPORT_SYMBOL(snd_wss_overrange); -irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id) +irqreturn_t snd_wss_interrupt(int irq, void *dev_id) { - struct snd_cs4231 *chip = dev_id; + struct snd_wss *chip = dev_id; unsigned char status; - status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); + status = snd_wss_in(chip, CS4231_IRQ_STATUS); if (status & CS4231_TIMER_IRQ) { if (chip->timer) snd_timer_interrupt(chip->timer, chip->timer->sticks); } - if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) { + if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) { if (status & CS4231_PLAYBACK_IRQ) { - if (chip->mode & CS4231_MODE_PLAY) { + if (chip->mode & WSS_MODE_PLAY) { if (chip->playback_substream) snd_pcm_period_elapsed(chip->playback_substream); } - if (chip->mode & CS4231_MODE_RECORD) { + if (chip->mode & WSS_MODE_RECORD) { if (chip->capture_substream) { - snd_cs4231_overrange(chip); + snd_wss_overrange(chip); snd_pcm_period_elapsed(chip->capture_substream); } } @@ -973,21 +1079,22 @@ irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id) } if (status & CS4231_RECORD_IRQ) { if (chip->capture_substream) { - snd_cs4231_overrange(chip); + snd_wss_overrange(chip); snd_pcm_period_elapsed(chip->capture_substream); } } } spin_lock(&chip->reg_lock); - snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); + snd_wss_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); spin_unlock(&chip->reg_lock); return IRQ_HANDLED; } +EXPORT_SYMBOL(snd_wss_interrupt); -static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); size_t ptr; if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) @@ -996,9 +1103,9 @@ static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *s return bytes_to_frames(substream->runtime, ptr); } -static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); size_t ptr; if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) @@ -1011,7 +1118,7 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *su */ -static int snd_cs4231_probe(struct snd_cs4231 *chip) +static int snd_wss_probe(struct snd_wss *chip) { unsigned long flags; int i, id, rev; @@ -1019,103 +1126,104 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) unsigned int hw; #if 0 - snd_cs4231_debug(chip); + snd_wss_debug(chip); #endif id = 0; for (i = 0; i < 50; i++) { mb(); - if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) udelay(2000); else { spin_lock_irqsave(&chip->reg_lock, flags); - snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2); - id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f; + snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2); + id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f; spin_unlock_irqrestore(&chip->reg_lock, flags); if (id == 0x0a) break; /* this is valid value */ } } - snd_printdd("cs4231: port = 0x%lx, id = 0x%x\n", chip->port, id); + snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id); if (id != 0x0a) return -ENODEV; /* no valid device found */ - if (((hw = chip->hardware) & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) { - rev = snd_cs4231_in(chip, CS4231_VERSION) & 0xe7; + hw = chip->hardware; + if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) { + rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7; snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev); if (rev == 0x80) { - unsigned char tmp = snd_cs4231_in(chip, 23); - snd_cs4231_out(chip, 23, ~tmp); - if (snd_cs4231_in(chip, 23) != tmp) - chip->hardware = CS4231_HW_AD1845; + unsigned char tmp = snd_wss_in(chip, 23); + snd_wss_out(chip, 23, ~tmp); + if (snd_wss_in(chip, 23) != tmp) + chip->hardware = WSS_HW_AD1845; else - chip->hardware = CS4231_HW_CS4231; + chip->hardware = WSS_HW_CS4231; } else if (rev == 0xa0) { - chip->hardware = CS4231_HW_CS4231A; + chip->hardware = WSS_HW_CS4231A; } else if (rev == 0xa2) { - chip->hardware = CS4231_HW_CS4232; + chip->hardware = WSS_HW_CS4232; } else if (rev == 0xb2) { - chip->hardware = CS4231_HW_CS4232A; + chip->hardware = WSS_HW_CS4232A; } else if (rev == 0x83) { - chip->hardware = CS4231_HW_CS4236; + chip->hardware = WSS_HW_CS4236; } else if (rev == 0x03) { - chip->hardware = CS4231_HW_CS4236B; + chip->hardware = WSS_HW_CS4236B; } else { snd_printk("unknown CS chip with version 0x%x\n", rev); return -ENODEV; /* unknown CS4231 chip? */ } } spin_lock_irqsave(&chip->reg_lock, flags); - cs4231_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */ - cs4231_outb(chip, CS4231P(STATUS), 0); + wss_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */ + wss_outb(chip, CS4231P(STATUS), 0); mb(); spin_unlock_irqrestore(&chip->reg_lock, flags); chip->image[CS4231_MISC_INFO] = CS4231_MODE2; switch (chip->hardware) { - case CS4231_HW_INTERWAVE: + case WSS_HW_INTERWAVE: chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3; break; - case CS4231_HW_CS4235: - case CS4231_HW_CS4236B: - case CS4231_HW_CS4237B: - case CS4231_HW_CS4238B: - case CS4231_HW_CS4239: - if (hw == CS4231_HW_DETECT3) + case WSS_HW_CS4235: + case WSS_HW_CS4236B: + case WSS_HW_CS4237B: + case WSS_HW_CS4238B: + case WSS_HW_CS4239: + if (hw == WSS_HW_DETECT3) chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3; else - chip->hardware = CS4231_HW_CS4236; + chip->hardware = WSS_HW_CS4236; break; } chip->image[CS4231_IFACE_CTRL] = (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) | (chip->single_dma ? CS4231_SINGLE_DMA : 0); - if (chip->hardware != CS4231_HW_OPTI93X) { + if (chip->hardware != WSS_HW_OPTI93X) { chip->image[CS4231_ALT_FEATURE_1] = 0x80; chip->image[CS4231_ALT_FEATURE_2] = - chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01; + chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01; } ptr = (unsigned char *) &chip->image; - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); spin_lock_irqsave(&chip->reg_lock, flags); for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */ - snd_cs4231_out(chip, i, *ptr++); + snd_wss_out(chip, i, *ptr++); spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_cs4231_mce_up(chip); - snd_cs4231_mce_down(chip); + snd_wss_mce_up(chip); + snd_wss_mce_down(chip); mdelay(2); /* ok.. try check hardware version for CS4236+ chips */ - if ((hw & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) { - if (chip->hardware == CS4231_HW_CS4236B) { + if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) { + if (chip->hardware == WSS_HW_CS4236B) { rev = snd_cs4236_ext_in(chip, CS4236_VERSION); snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff); id = snd_cs4236_ext_in(chip, CS4236_VERSION); snd_cs4236_ext_out(chip, CS4236_VERSION, rev); snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id); if ((id & 0x1f) == 0x1d) { /* CS4235 */ - chip->hardware = CS4231_HW_CS4235; + chip->hardware = WSS_HW_CS4235; switch (id >> 5) { case 4: case 5: @@ -1130,13 +1238,13 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) case 5: case 6: case 7: - chip->hardware = CS4231_HW_CS4236B; + chip->hardware = WSS_HW_CS4236B; break; default: snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x08) { /* CS4237B */ - chip->hardware = CS4231_HW_CS4237B; + chip->hardware = WSS_HW_CS4237B; switch (id >> 5) { case 4: case 5: @@ -1147,7 +1255,7 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x09) { /* CS4238B */ - chip->hardware = CS4231_HW_CS4238B; + chip->hardware = WSS_HW_CS4238B; switch (id >> 5) { case 5: case 6: @@ -1157,7 +1265,7 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id); } } else if ((id & 0x1f) == 0x1e) { /* CS4239 */ - chip->hardware = CS4231_HW_CS4239; + chip->hardware = WSS_HW_CS4239; switch (id >> 5) { case 4: case 5: @@ -1178,7 +1286,7 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) */ -static struct snd_pcm_hardware snd_cs4231_playback = +static struct snd_pcm_hardware snd_wss_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1199,7 +1307,7 @@ static struct snd_pcm_hardware snd_cs4231_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_cs4231_capture = +static struct snd_pcm_hardware snd_wss_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1224,21 +1332,21 @@ static struct snd_pcm_hardware snd_cs4231_capture = */ -static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) +static int snd_wss_playback_open(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; int err; - runtime->hw = snd_cs4231_playback; + runtime->hw = snd_wss_playback; /* hardware bug in InterWave chipset */ - if (chip->hardware == CS4231_HW_INTERWAVE && chip->dma1 > 3) + if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3) runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW; /* hardware limitation of cheap chips */ - if (chip->hardware == CS4231_HW_CS4235 || - chip->hardware == CS4231_HW_CS4239) + if (chip->hardware == WSS_HW_CS4235 || + chip->hardware == WSS_HW_CS4239) runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max); @@ -1249,7 +1357,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) return err; } - if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) { + err = snd_wss_open(chip, WSS_MODE_PLAY); + if (err < 0) { if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma1); snd_free_pages(runtime->dma_area, runtime->dma_bytes); @@ -1261,17 +1370,17 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) return 0; } -static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) +static int snd_wss_capture_open(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; int err; - runtime->hw = snd_cs4231_capture; + runtime->hw = snd_wss_capture; /* hardware limitation of cheap chips */ - if (chip->hardware == CS4231_HW_CS4235 || - chip->hardware == CS4231_HW_CS4239) + if (chip->hardware == WSS_HW_CS4235 || + chip->hardware == WSS_HW_CS4239) runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); @@ -1282,7 +1391,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) return err; } - if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) { + err = snd_wss_open(chip, WSS_MODE_RECORD); + if (err < 0) { if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma2); snd_free_pages(runtime->dma_area, runtime->dma_bytes); @@ -1294,28 +1404,28 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) return 0; } -static int snd_cs4231_playback_close(struct snd_pcm_substream *substream) +static int snd_wss_playback_close(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); chip->playback_substream = NULL; - snd_cs4231_close(chip, CS4231_MODE_PLAY); + snd_wss_close(chip, WSS_MODE_PLAY); return 0; } -static int snd_cs4231_capture_close(struct snd_pcm_substream *substream) +static int snd_wss_capture_close(struct snd_pcm_substream *substream) { - struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); chip->capture_substream = NULL; - snd_cs4231_close(chip, CS4231_MODE_RECORD); + snd_wss_close(chip, WSS_MODE_RECORD); return 0; } #ifdef CONFIG_PM /* lowlevel suspend callback for CS4231 */ -static void snd_cs4231_suspend(struct snd_cs4231 *chip) +static void snd_wss_suspend(struct snd_wss *chip) { int reg; unsigned long flags; @@ -1323,67 +1433,68 @@ static void snd_cs4231_suspend(struct snd_cs4231 *chip) snd_pcm_suspend_all(chip->pcm); spin_lock_irqsave(&chip->reg_lock, flags); for (reg = 0; reg < 32; reg++) - chip->image[reg] = snd_cs4231_in(chip, reg); + chip->image[reg] = snd_wss_in(chip, reg); spin_unlock_irqrestore(&chip->reg_lock, flags); } /* lowlevel resume callback for CS4231 */ -static void snd_cs4231_resume(struct snd_cs4231 *chip) +static void snd_wss_resume(struct snd_wss *chip) { int reg; unsigned long flags; /* int timeout; */ - snd_cs4231_mce_up(chip); + snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); for (reg = 0; reg < 32; reg++) { switch (reg) { case CS4231_VERSION: break; default: - snd_cs4231_out(chip, reg, chip->image[reg]); + snd_wss_out(chip, reg, chip->image[reg]); break; } } spin_unlock_irqrestore(&chip->reg_lock, flags); #if 1 - snd_cs4231_mce_down(chip); + snd_wss_mce_down(chip); #else /* The following is a workaround to avoid freeze after resume on TP600E. - This is the first half of copy of snd_cs4231_mce_down(), but doesn't + This is the first half of copy of snd_wss_mce_down(), but doesn't include rescheduling. -- iwai */ - snd_cs4231_busy_wait(chip); + snd_wss_busy_wait(chip); spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit &= ~CS4231_MCE; - timeout = cs4231_inb(chip, CS4231P(REGSEL)); - cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + timeout = wss_inb(chip, CS4231P(REGSEL)); + wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || - !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { + !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) { return; } - snd_cs4231_busy_wait(chip); + snd_wss_busy_wait(chip); #endif } #endif /* CONFIG_PM */ -static int snd_cs4231_free(struct snd_cs4231 *chip) +static int snd_wss_free(struct snd_wss *chip) { release_and_free_resource(chip->res_port); release_and_free_resource(chip->res_cport); if (chip->irq >= 0) { disable_irq(chip->irq); - if (!(chip->hwshare & CS4231_HWSHARE_IRQ)) + if (!(chip->hwshare & WSS_HWSHARE_IRQ)) free_irq(chip->irq, (void *) chip); } - if (!(chip->hwshare & CS4231_HWSHARE_DMA1) && chip->dma1 >= 0) { + if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) { snd_dma_disable(chip->dma1); free_dma(chip->dma1); } - if (!(chip->hwshare & CS4231_HWSHARE_DMA2) && chip->dma2 >= 0 && chip->dma2 != chip->dma1) { + if (!(chip->hwshare & WSS_HWSHARE_DMA2) && + chip->dma2 >= 0 && chip->dma2 != chip->dma1) { snd_dma_disable(chip->dma2); free_dma(chip->dma2); } @@ -1393,39 +1504,55 @@ static int snd_cs4231_free(struct snd_cs4231 *chip) return 0; } -static int snd_cs4231_dev_free(struct snd_device *device) +static int snd_wss_dev_free(struct snd_device *device) { - struct snd_cs4231 *chip = device->device_data; - return snd_cs4231_free(chip); + struct snd_wss *chip = device->device_data; + return snd_wss_free(chip); } -const char *snd_cs4231_chip_id(struct snd_cs4231 *chip) +const char *snd_wss_chip_id(struct snd_wss *chip) { switch (chip->hardware) { - case CS4231_HW_CS4231: return "CS4231"; - case CS4231_HW_CS4231A: return "CS4231A"; - case CS4231_HW_CS4232: return "CS4232"; - case CS4231_HW_CS4232A: return "CS4232A"; - case CS4231_HW_CS4235: return "CS4235"; - case CS4231_HW_CS4236: return "CS4236"; - case CS4231_HW_CS4236B: return "CS4236B"; - case CS4231_HW_CS4237B: return "CS4237B"; - case CS4231_HW_CS4238B: return "CS4238B"; - case CS4231_HW_CS4239: return "CS4239"; - case CS4231_HW_INTERWAVE: return "AMD InterWave"; - case CS4231_HW_OPL3SA2: return chip->card->shortname; - case CS4231_HW_AD1845: return "AD1845"; - case CS4231_HW_OPTI93X: return "OPTi 93x"; - default: return "???"; + case WSS_HW_CS4231: + return "CS4231"; + case WSS_HW_CS4231A: + return "CS4231A"; + case WSS_HW_CS4232: + return "CS4232"; + case WSS_HW_CS4232A: + return "CS4232A"; + case WSS_HW_CS4235: + return "CS4235"; + case WSS_HW_CS4236: + return "CS4236"; + case WSS_HW_CS4236B: + return "CS4236B"; + case WSS_HW_CS4237B: + return "CS4237B"; + case WSS_HW_CS4238B: + return "CS4238B"; + case WSS_HW_CS4239: + return "CS4239"; + case WSS_HW_INTERWAVE: + return "AMD InterWave"; + case WSS_HW_OPL3SA2: + return chip->card->shortname; + case WSS_HW_AD1845: + return "AD1845"; + case WSS_HW_OPTI93X: + return "OPTi 93x"; + default: + return "???"; } } +EXPORT_SYMBOL(snd_wss_chip_id); -static int snd_cs4231_new(struct snd_card *card, +static int snd_wss_new(struct snd_card *card, unsigned short hardware, unsigned short hwshare, - struct snd_cs4231 ** rchip) + struct snd_wss **rchip) { - struct snd_cs4231 *chip; + struct snd_wss *chip; *rchip = NULL; chip = kzalloc(sizeof(*chip), GFP_KERNEL); @@ -1438,35 +1565,35 @@ static int snd_cs4231_new(struct snd_card *card, mutex_init(&chip->mce_mutex); mutex_init(&chip->open_mutex); chip->card = card; - chip->rate_constraint = snd_cs4231_xrate; - chip->set_playback_format = snd_cs4231_playback_format; - chip->set_capture_format = snd_cs4231_capture_format; - if (chip->hardware == CS4231_HW_OPTI93X) + chip->rate_constraint = snd_wss_xrate; + chip->set_playback_format = snd_wss_playback_format; + chip->set_capture_format = snd_wss_capture_format; + if (chip->hardware == WSS_HW_OPTI93X) memcpy(&chip->image, &snd_opti93x_original_image, sizeof(snd_opti93x_original_image)); else - memcpy(&chip->image, &snd_cs4231_original_image, - sizeof(snd_cs4231_original_image)); + memcpy(&chip->image, &snd_wss_original_image, + sizeof(snd_wss_original_image)); - *rchip = chip; - return 0; + *rchip = chip; + return 0; } -int snd_cs4231_create(struct snd_card *card, - unsigned long port, - unsigned long cport, +int snd_wss_create(struct snd_card *card, + unsigned long port, + unsigned long cport, int irq, int dma1, int dma2, unsigned short hardware, unsigned short hwshare, - struct snd_cs4231 ** rchip) + struct snd_wss **rchip) { static struct snd_device_ops ops = { - .dev_free = snd_cs4231_dev_free, + .dev_free = snd_wss_dev_free, }; - struct snd_cs4231 *chip; + struct snd_wss *chip; int err; - err = snd_cs4231_new(card, hardware, hwshare, &chip); + err = snd_wss_new(card, hardware, hwshare, &chip); if (err < 0) return err; @@ -1474,33 +1601,41 @@ int snd_cs4231_create(struct snd_card *card, chip->dma1 = -1; chip->dma2 = -1; - if ((chip->res_port = request_region(port, 4, "CS4231")) == NULL) { - snd_printk(KERN_ERR "cs4231: can't grab port 0x%lx\n", port); - snd_cs4231_free(chip); + chip->res_port = request_region(port, 4, "CS4231"); + if (!chip->res_port) { + snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port); + snd_wss_free(chip); return -EBUSY; } chip->port = port; - if ((long)cport >= 0 && (chip->res_cport = request_region(cport, 8, "CS4232 Control")) == NULL) { - snd_printk(KERN_ERR "cs4231: can't grab control port 0x%lx\n", cport); - snd_cs4231_free(chip); - return -ENODEV; + if ((long)cport >= 0) { + chip->res_cport = request_region(cport, 8, "CS4232 Control"); + if (!chip->res_cport) { + snd_printk(KERN_ERR + "wss: can't grab control port 0x%lx\n", cport); + snd_wss_free(chip); + return -ENODEV; + } } chip->cport = cport; - if (!(hwshare & CS4231_HWSHARE_IRQ) && request_irq(irq, snd_cs4231_interrupt, IRQF_DISABLED, "CS4231", (void *) chip)) { - snd_printk(KERN_ERR "cs4231: can't grab IRQ %d\n", irq); - snd_cs4231_free(chip); - return -EBUSY; - } + if (!(hwshare & WSS_HWSHARE_IRQ)) + if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED, + "CS4231", (void *) chip)) { + snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq); + snd_wss_free(chip); + return -EBUSY; + } chip->irq = irq; - if (!(hwshare & CS4231_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) { - snd_printk(KERN_ERR "cs4231: can't grab DMA1 %d\n", dma1); - snd_cs4231_free(chip); + if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) { + snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1); + snd_wss_free(chip); return -EBUSY; } chip->dma1 = dma1; - if (!(hwshare & CS4231_HWSHARE_DMA2) && dma1 != dma2 && dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) { - snd_printk(KERN_ERR "cs4231: can't grab DMA2 %d\n", dma2); - snd_cs4231_free(chip); + if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 && + dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) { + snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2); + snd_wss_free(chip); return -EBUSY; } if (dma1 == dma2 || dma2 < 0) { @@ -1510,58 +1645,60 @@ int snd_cs4231_create(struct snd_card *card, chip->dma2 = dma2; /* global setup */ - if (snd_cs4231_probe(chip) < 0) { - snd_cs4231_free(chip); + if (snd_wss_probe(chip) < 0) { + snd_wss_free(chip); return -ENODEV; } - snd_cs4231_init(chip); + snd_wss_init(chip); #if 0 - if (chip->hardware & CS4231_HW_CS4232_MASK) { + if (chip->hardware & WSS_HW_CS4232_MASK) { if (chip->res_cport == NULL) snd_printk("CS4232 control port features are not accessible\n"); } #endif /* Register device */ - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_cs4231_free(chip); + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) { + snd_wss_free(chip); return err; } #ifdef CONFIG_PM /* Power Management */ - chip->suspend = snd_cs4231_suspend; - chip->resume = snd_cs4231_resume; + chip->suspend = snd_wss_suspend; + chip->resume = snd_wss_resume; #endif *rchip = chip; return 0; } +EXPORT_SYMBOL(snd_wss_create); -static struct snd_pcm_ops snd_cs4231_playback_ops = { - .open = snd_cs4231_playback_open, - .close = snd_cs4231_playback_close, +static struct snd_pcm_ops snd_wss_playback_ops = { + .open = snd_wss_playback_open, + .close = snd_wss_playback_close, .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cs4231_playback_hw_params, - .hw_free = snd_cs4231_playback_hw_free, - .prepare = snd_cs4231_playback_prepare, - .trigger = snd_cs4231_trigger, - .pointer = snd_cs4231_playback_pointer, + .hw_params = snd_wss_playback_hw_params, + .hw_free = snd_wss_playback_hw_free, + .prepare = snd_wss_playback_prepare, + .trigger = snd_wss_trigger, + .pointer = snd_wss_playback_pointer, }; -static struct snd_pcm_ops snd_cs4231_capture_ops = { - .open = snd_cs4231_capture_open, - .close = snd_cs4231_capture_close, +static struct snd_pcm_ops snd_wss_capture_ops = { + .open = snd_wss_capture_open, + .close = snd_wss_capture_close, .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cs4231_capture_hw_params, - .hw_free = snd_cs4231_capture_hw_free, - .prepare = snd_cs4231_capture_prepare, - .trigger = snd_cs4231_trigger, - .pointer = snd_cs4231_capture_pointer, + .hw_params = snd_wss_capture_hw_params, + .hw_free = snd_wss_capture_hw_free, + .prepare = snd_wss_capture_prepare, + .trigger = snd_wss_trigger, + .pointer = snd_wss_capture_pointer, }; -int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) +int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; @@ -1573,17 +1710,17 @@ int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) mutex_init(&chip->mce_mutex); mutex_init(&chip->open_mutex); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops); /* global setup */ pcm->private_data = chip; pcm->info_flags = 0; if (chip->single_dma) pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; - if (chip->hardware != CS4231_HW_INTERWAVE) + if (chip->hardware != WSS_HW_INTERWAVE) pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; - strcpy(pcm->name, snd_cs4231_chip_id(chip)); + strcpy(pcm->name, snd_wss_chip_id(chip)); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(), @@ -1594,14 +1731,15 @@ int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) *rpcm = pcm; return 0; } +EXPORT_SYMBOL(snd_wss_pcm); -static void snd_cs4231_timer_free(struct snd_timer *timer) +static void snd_wss_timer_free(struct snd_timer *timer) { - struct snd_cs4231 *chip = timer->private_data; + struct snd_wss *chip = timer->private_data; chip->timer = NULL; } -int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rtimer) +int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer) { struct snd_timer *timer; struct snd_timer_id tid; @@ -1615,21 +1753,23 @@ int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rti tid.subdevice = 0; if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0) return err; - strcpy(timer->name, snd_cs4231_chip_id(chip)); + strcpy(timer->name, snd_wss_chip_id(chip)); timer->private_data = chip; - timer->private_free = snd_cs4231_timer_free; - timer->hw = snd_cs4231_timer_table; + timer->private_free = snd_wss_timer_free; + timer->hw = snd_wss_timer_table; chip->timer = timer; if (rtimer) *rtimer = timer; return 0; } +EXPORT_SYMBOL(snd_wss_timer); /* * MIXER part */ -static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { static char *texts[4] = { "Line", "Aux", "Mic", "Mix" @@ -1641,7 +1781,7 @@ static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele "Line", "Synth", "Mic", "Mix" }; char **ptexts = texts; - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); snd_assert(chip->card != NULL, return -EINVAL); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -1652,16 +1792,21 @@ static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele if (!strcmp(chip->card->driver, "GUS MAX")) ptexts = gusmax_texts; switch (chip->hardware) { - case CS4231_HW_INTERWAVE: ptexts = gusmax_texts; break; - case CS4231_HW_OPL3SA2: ptexts = opl3sa_texts; break; + case WSS_HW_INTERWAVE: + ptexts = gusmax_texts; + break; + case WSS_HW_OPL3SA2: + ptexts = opl3sa_texts; + break; } strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]); return 0; } -static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_wss_get_mux(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); @@ -1671,9 +1816,10 @@ static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return 0; } -static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_wss_put_mux(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned short left, right; int change; @@ -1687,14 +1833,15 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left; right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right; change = left != chip->image[CS4231_LEFT_INPUT] || - right != chip->image[CS4231_RIGHT_INPUT]; - snd_cs4231_out(chip, CS4231_LEFT_INPUT, left); - snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right); + right != chip->image[CS4231_RIGHT_INPUT]; + snd_wss_out(chip, CS4231_LEFT_INPUT, left); + snd_wss_out(chip, CS4231_RIGHT_INPUT, right); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } -int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_wss_info_single(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 16) & 0xff; @@ -1704,10 +1851,12 @@ int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in uinfo->value.integer.max = mask; return 0; } +EXPORT_SYMBOL(snd_wss_info_single); -int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_wss_get_single(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -1721,10 +1870,12 @@ int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; return 0; } +EXPORT_SYMBOL(snd_wss_get_single); -int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_wss_put_single(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -1740,12 +1891,14 @@ int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val spin_lock_irqsave(&chip->reg_lock, flags); val = (chip->image[reg] & ~(mask << shift)) | val; change = val != chip->image[reg]; - snd_cs4231_out(chip, reg, val); + snd_wss_out(chip, reg, val); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } +EXPORT_SYMBOL(snd_wss_put_single); -int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_wss_info_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 24) & 0xff; @@ -1755,10 +1908,12 @@ int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in uinfo->value.integer.max = mask; return 0; } +EXPORT_SYMBOL(snd_wss_info_double); -int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_wss_get_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -1777,10 +1932,12 @@ int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val } return 0; } +EXPORT_SYMBOL(snd_wss_get_double); -int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_wss_put_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -1803,81 +1960,98 @@ int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; - snd_cs4231_out(chip, left_reg, val1); - snd_cs4231_out(chip, right_reg, val2); + snd_wss_out(chip, left_reg, val1); + snd_wss_out(chip, right_reg, val2); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } - -static struct snd_kcontrol_new snd_cs4231_controls[] = { -CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), -CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), -CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), -CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), -CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), -CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1), -CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), -CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1), -CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), -CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), +EXPORT_SYMBOL(snd_wss_put_double); + +static struct snd_kcontrol_new snd_wss_controls[] = { +WSS_DOUBLE("PCM Playback Switch", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("PCM Playback Volume", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), +WSS_DOUBLE("Line Playback Switch", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), +WSS_DOUBLE("Line Playback Volume", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), +WSS_DOUBLE("Aux Playback Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Aux Playback Volume", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), +WSS_DOUBLE("Aux Playback Switch", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Aux Playback Volume", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), +WSS_SINGLE("Mono Playback Switch", 0, + CS4231_MONO_CTRL, 7, 1, 1), +WSS_SINGLE("Mono Playback Volume", 0, + CS4231_MONO_CTRL, 0, 15, 1), +WSS_SINGLE("Mono Output Playback Switch", 0, + CS4231_MONO_CTRL, 6, 1, 1), +WSS_SINGLE("Mono Output Playback Bypass", 0, + CS4231_MONO_CTRL, 5, 1, 0), +WSS_DOUBLE("Capture Volume", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", - .info = snd_cs4231_info_mux, - .get = snd_cs4231_get_mux, - .put = snd_cs4231_put_mux, + .info = snd_wss_info_mux, + .get = snd_wss_get_mux, + .put = snd_wss_put_mux, }, -CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), -CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), -CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) +WSS_DOUBLE("Mic Boost", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), +WSS_SINGLE("Loopback Capture Switch", 0, + CS4231_LOOPBACK, 0, 1, 0), +WSS_SINGLE("Loopback Capture Volume", 0, + CS4231_LOOPBACK, 2, 63, 1) }; static struct snd_kcontrol_new snd_opti93x_controls[] = { -CS4231_DOUBLE("Master Playback Switch", 0, - OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), -CS4231_DOUBLE("Master Playback Volume", 0, - OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), -CS4231_DOUBLE("PCM Playback Switch", 0, - CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("PCM Playback Volume", 0, - CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1), -CS4231_DOUBLE("FM Playback Switch", 0, - CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("FM Playback Volume", 0, - CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Line Playback Switch", 0, - CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), -CS4231_DOUBLE("Line Playback Volume", 0, - CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1), -CS4231_DOUBLE("Mic Playback Switch", 0, - OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Mic Playback Volume", 0, - OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Mic Boost", 0, - CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), -CS4231_DOUBLE("CD Playback Switch", 0, - CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("CD Playback Volume", 0, - CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Aux Playback Switch", 0, - OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Aux Playback Volume", 0, - OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1), -CS4231_DOUBLE("Capture Volume", 0, - CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), +WSS_DOUBLE("Master Playback Switch", 0, + OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), +WSS_DOUBLE("Master Playback Volume", 0, + OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), +WSS_DOUBLE("PCM Playback Switch", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("PCM Playback Volume", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1), +WSS_DOUBLE("FM Playback Switch", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("FM Playback Volume", 0, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1), +WSS_DOUBLE("Line Playback Switch", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), +WSS_DOUBLE("Line Playback Volume", 0, + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1), +WSS_DOUBLE("Mic Playback Switch", 0, + OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Mic Playback Volume", 0, + OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1), +WSS_DOUBLE("Mic Boost", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), +WSS_DOUBLE("CD Playback Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("CD Playback Volume", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1), +WSS_DOUBLE("Aux Playback Switch", 0, + OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Aux Playback Volume", 0, + OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1), +WSS_DOUBLE("Capture Volume", 0, + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", - .info = snd_cs4231_info_mux, - .get = snd_cs4231_get_mux, - .put = snd_cs4231_put_mux, + .info = snd_wss_info_mux, + .get = snd_wss_get_mux, + .put = snd_wss_put_mux, } }; -int snd_cs4231_mixer(struct snd_cs4231 *chip) +int snd_wss_mixer(struct snd_wss *chip) { struct snd_card *card; unsigned int idx; @@ -1889,7 +2063,7 @@ int snd_cs4231_mixer(struct snd_cs4231 *chip) strcpy(card->mixername, chip->pcm->name); - if (chip->hardware == CS4231_HW_OPTI93X) + if (chip->hardware == WSS_HW_OPTI93X) for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { err = snd_ctl_add(card, snd_ctl_new1(&snd_opti93x_controls[idx], @@ -1898,48 +2072,29 @@ int snd_cs4231_mixer(struct snd_cs4231 *chip) return err; } else - for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) { err = snd_ctl_add(card, - snd_ctl_new1(&snd_cs4231_controls[idx], + snd_ctl_new1(&snd_wss_controls[idx], chip)); if (err < 0) return err; } return 0; } - -EXPORT_SYMBOL(snd_cs4231_out); -EXPORT_SYMBOL(snd_cs4231_in); -EXPORT_SYMBOL(snd_cs4236_ext_out); -EXPORT_SYMBOL(snd_cs4236_ext_in); -EXPORT_SYMBOL(snd_cs4231_mce_up); -EXPORT_SYMBOL(snd_cs4231_mce_down); -EXPORT_SYMBOL(snd_cs4231_overrange); -EXPORT_SYMBOL(snd_cs4231_interrupt); -EXPORT_SYMBOL(snd_cs4231_chip_id); -EXPORT_SYMBOL(snd_cs4231_create); -EXPORT_SYMBOL(snd_cs4231_pcm); -EXPORT_SYMBOL(snd_cs4231_mixer); -EXPORT_SYMBOL(snd_cs4231_timer); -EXPORT_SYMBOL(snd_cs4231_info_single); -EXPORT_SYMBOL(snd_cs4231_get_single); -EXPORT_SYMBOL(snd_cs4231_put_single); -EXPORT_SYMBOL(snd_cs4231_info_double); -EXPORT_SYMBOL(snd_cs4231_get_double); -EXPORT_SYMBOL(snd_cs4231_put_double); +EXPORT_SYMBOL(snd_wss_mixer); /* * INIT part */ -static int __init alsa_cs4231_init(void) +static int __init alsa_wss_init(void) { return 0; } -static void __exit alsa_cs4231_exit(void) +static void __exit alsa_wss_exit(void) { } -module_init(alsa_cs4231_init) -module_exit(alsa_cs4231_exit) +module_init(alsa_wss_init); +module_exit(alsa_wss_exit); -- cgit v1.2.3 From 241b3ee70d2d69e88d5c144ce938b1887cd6d3fc Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:04:37 +0200 Subject: ALSA: wss_lib: use struct snd_wss instead of snd_ad1848 The snd_wss is superset of the snd_ad1848 so kill the latter and replace it with the snd_wss. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1848/ad1848.c | 6 +- sound/isa/ad1848/ad1848_lib.c | 128 ++++++++++++++++++++----------------- sound/isa/cmi8330.c | 2 +- sound/isa/opti9xx/opti92x-ad1848.c | 4 -- sound/isa/sc6000.c | 4 +- sound/isa/sgalaxy.c | 8 +-- 6 files changed, 78 insertions(+), 74 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 5f5271efdc59..74db24ae6509 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -87,7 +87,7 @@ static int __devinit snd_ad1848_match(struct device *dev, unsigned int n) static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) { struct snd_card *card; - struct snd_ad1848 *chip; + struct snd_wss *chip; struct snd_pcm *pcm; int error; @@ -142,7 +142,7 @@ static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n) static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state) { struct snd_card *card = dev_get_drvdata(dev); - struct snd_ad1848 *chip = card->private_data; + struct snd_wss *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->suspend(chip); @@ -152,7 +152,7 @@ static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t s static int snd_ad1848_resume(struct device *dev, unsigned int n) { struct snd_card *card = dev_get_drvdata(dev); - struct snd_ad1848 *chip = card->private_data; + struct snd_wss *chip = card->private_data; chip->resume(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 630c90f9ee50..e25fadffdb55 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -98,7 +98,7 @@ static unsigned char snd_ad1848_original_image[16] = * Basic I/O functions */ -static void snd_ad1848_wait(struct snd_ad1848 *chip) +static void snd_ad1848_wait(struct snd_wss *chip) { int timeout; @@ -109,7 +109,7 @@ static void snd_ad1848_wait(struct snd_ad1848 *chip) } } -void snd_ad1848_out(struct snd_ad1848 *chip, +void snd_ad1848_out(struct snd_wss *chip, unsigned char reg, unsigned char value) { @@ -128,7 +128,7 @@ void snd_ad1848_out(struct snd_ad1848 *chip, EXPORT_SYMBOL(snd_ad1848_out); -static void snd_ad1848_dout(struct snd_ad1848 *chip, +static void snd_ad1848_dout(struct snd_wss *chip, unsigned char reg, unsigned char value) { snd_ad1848_wait(chip); @@ -137,7 +137,7 @@ static void snd_ad1848_dout(struct snd_ad1848 *chip, mb(); } -static unsigned char snd_ad1848_in(struct snd_ad1848 *chip, unsigned char reg) +static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg) { snd_ad1848_wait(chip); #ifdef CONFIG_SND_DEBUG @@ -152,7 +152,7 @@ static unsigned char snd_ad1848_in(struct snd_ad1848 *chip, unsigned char reg) #if 0 -static void snd_ad1848_debug(struct snd_ad1848 *chip) +static void snd_ad1848_debug(struct snd_wss *chip) { printk("AD1848 REGS: INDEX = 0x%02x ", inb(AD1848P(chip, REGSEL))); printk(" STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS))); @@ -180,7 +180,7 @@ static void snd_ad1848_debug(struct snd_ad1848 *chip) * AD1848 detection / MCE routines */ -static void snd_ad1848_mce_up(struct snd_ad1848 *chip) +static void snd_ad1848_mce_up(struct snd_wss *chip) { unsigned long flags; int timeout; @@ -200,7 +200,7 @@ static void snd_ad1848_mce_up(struct snd_ad1848 *chip) spin_unlock_irqrestore(&chip->reg_lock, flags); } -static void snd_ad1848_mce_down(struct snd_ad1848 *chip) +static void snd_ad1848_mce_down(struct snd_wss *chip) { unsigned long flags, timeout; int reg; @@ -268,7 +268,7 @@ static unsigned int snd_ad1848_get_count(unsigned char format, return size; } -static int snd_ad1848_trigger(struct snd_ad1848 *chip, unsigned char what, +static int snd_ad1848_trigger(struct snd_wss *chip, unsigned char what, int channel, int cmd) { int result = 0; @@ -337,7 +337,7 @@ static unsigned char snd_ad1848_get_format(int format, int channels) return rformat; } -static void snd_ad1848_calibrate_mute(struct snd_ad1848 *chip, int mute) +static void snd_ad1848_calibrate_mute(struct snd_wss *chip, int mute) { unsigned long flags; @@ -361,7 +361,8 @@ static void snd_ad1848_calibrate_mute(struct snd_ad1848 *chip, int mute) spin_unlock_irqrestore(&chip->reg_lock, flags); } -static void snd_ad1848_set_data_format(struct snd_ad1848 *chip, struct snd_pcm_hw_params *hw_params) +static void snd_ad1848_set_data_format(struct snd_wss *chip, + struct snd_pcm_hw_params *hw_params) { if (hw_params == NULL) { chip->image[AD1848_DATA_FORMAT] = 0x20; @@ -373,7 +374,7 @@ static void snd_ad1848_set_data_format(struct snd_ad1848 *chip, struct snd_pcm_h // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]); } -static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode) +static int snd_ad1848_open(struct snd_wss *chip, unsigned int mode) { unsigned long flags; @@ -424,7 +425,7 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode) return 0; } -static void snd_ad1848_close(struct snd_ad1848 *chip) +static void snd_ad1848_close(struct snd_wss *chip) { unsigned long flags; @@ -464,21 +465,21 @@ static void snd_ad1848_close(struct snd_ad1848 *chip) static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd); } static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd); } static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); unsigned long flags; int err; @@ -502,15 +503,16 @@ static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream) static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned long flags; unsigned int size = snd_pcm_lib_buffer_bytes(substream); unsigned int count = snd_pcm_lib_period_bytes(substream); - chip->dma_size = size; + chip->p_dma_size = size; chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO); - snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); + snd_dma_program(chip->dma1, runtime->dma_addr, size, + DMA_MODE_WRITE | DMA_AUTOINIT); count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1; spin_lock_irqsave(&chip->reg_lock, flags); snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count); @@ -522,7 +524,7 @@ static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream) static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); unsigned long flags; int err; @@ -546,15 +548,16 @@ static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream) static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned long flags; unsigned int size = snd_pcm_lib_buffer_bytes(substream); unsigned int count = snd_pcm_lib_period_bytes(substream); - chip->dma_size = size; + chip->c_dma_size = size; chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO); - snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); + snd_dma_program(chip->dma2, runtime->dma_addr, size, + DMA_MODE_READ | DMA_AUTOINIT); count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1; spin_lock_irqsave(&chip->reg_lock, flags); snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count); @@ -565,7 +568,7 @@ static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream) static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) { - struct snd_ad1848 *chip = dev_id; + struct snd_wss *chip = dev_id; if ((chip->mode & AD1848_MODE_PLAY) && chip->playback_substream && (chip->mode & AD1848_MODE_RUNNING)) @@ -579,23 +582,23 @@ static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); size_t ptr; if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE)) return 0; - ptr = snd_dma_pointer(chip->dma, chip->dma_size); + ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); size_t ptr; if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE)) return 0; - ptr = snd_dma_pointer(chip->dma, chip->dma_size); + ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -603,8 +606,8 @@ static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *su */ -static void snd_ad1848_thinkpad_twiddle(struct snd_ad1848 *chip, int on) { - +static void snd_ad1848_thinkpad_twiddle(struct snd_wss *chip, int on) +{ int tmp; if (!chip->thinkpad_flag) return; @@ -624,14 +627,14 @@ static void snd_ad1848_thinkpad_twiddle(struct snd_ad1848 *chip, int on) { } #ifdef CONFIG_PM -static void snd_ad1848_suspend(struct snd_ad1848 *chip) +static void snd_ad1848_suspend(struct snd_wss *chip) { snd_pcm_suspend_all(chip->pcm); if (chip->thinkpad_flag) snd_ad1848_thinkpad_twiddle(chip, 0); } -static void snd_ad1848_resume(struct snd_ad1848 *chip) +static void snd_ad1848_resume(struct snd_wss *chip) { int i; @@ -651,7 +654,7 @@ static void snd_ad1848_resume(struct snd_ad1848 *chip) } #endif /* CONFIG_PM */ -static int snd_ad1848_probe(struct snd_ad1848 * chip) +static int snd_ad1848_probe(struct snd_wss *chip) { unsigned long flags; int i, id, rev, ad1847; @@ -775,7 +778,7 @@ static struct snd_pcm_hardware snd_ad1848_capture = static int snd_ad1848_playback_open(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; int err; @@ -783,15 +786,15 @@ static int snd_ad1848_playback_open(struct snd_pcm_substream *substream) return err; chip->playback_substream = substream; runtime->hw = snd_ad1848_playback; - snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); return 0; } static int snd_ad1848_capture_open(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; int err; @@ -799,15 +802,15 @@ static int snd_ad1848_capture_open(struct snd_pcm_substream *substream) return err; chip->capture_substream = substream; runtime->hw = snd_ad1848_capture; - snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); return 0; } static int snd_ad1848_playback_close(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); chip->mode &= ~AD1848_MODE_PLAY; chip->playback_substream = NULL; @@ -817,7 +820,7 @@ static int snd_ad1848_playback_close(struct snd_pcm_substream *substream) static int snd_ad1848_capture_close(struct snd_pcm_substream *substream) { - struct snd_ad1848 *chip = snd_pcm_substream_chip(substream); + struct snd_wss *chip = snd_pcm_substream_chip(substream); chip->mode &= ~AD1848_MODE_CAPTURE; chip->capture_substream = NULL; @@ -825,14 +828,14 @@ static int snd_ad1848_capture_close(struct snd_pcm_substream *substream) return 0; } -static int snd_ad1848_free(struct snd_ad1848 *chip) +static int snd_ad1848_free(struct snd_wss *chip) { release_and_free_resource(chip->res_port); if (chip->irq >= 0) free_irq(chip->irq, (void *) chip); - if (chip->dma >= 0) { - snd_dma_disable(chip->dma); - free_dma(chip->dma); + if (chip->dma1 >= 0) { + snd_dma_disable(chip->dma1); + free_dma(chip->dma1); } kfree(chip); return 0; @@ -840,11 +843,11 @@ static int snd_ad1848_free(struct snd_ad1848 *chip) static int snd_ad1848_dev_free(struct snd_device *device) { - struct snd_ad1848 *chip = device->device_data; + struct snd_wss *chip = device->device_data; return snd_ad1848_free(chip); } -static const char *snd_ad1848_chip_id(struct snd_ad1848 *chip) +static const char *snd_ad1848_chip_id(struct snd_wss *chip) { switch (chip->hardware) { case AD1848_HW_AD1847: return "AD1847"; @@ -859,12 +862,12 @@ int snd_ad1848_create(struct snd_card *card, unsigned long port, int irq, int dma, unsigned short hardware, - struct snd_ad1848 ** rchip) + struct snd_wss **rchip) { static struct snd_device_ops ops = { .dev_free = snd_ad1848_dev_free, }; - struct snd_ad1848 *chip; + struct snd_wss *chip; int err; *rchip = NULL; @@ -875,7 +878,9 @@ int snd_ad1848_create(struct snd_card *card, chip->card = card; chip->port = port; chip->irq = -1; - chip->dma = -1; + chip->dma1 = -1; + chip->dma2 = -1; + chip->single_dma = 1; chip->hardware = hardware; memcpy(&chip->image, &snd_ad1848_original_image, sizeof(snd_ad1848_original_image)); @@ -895,7 +900,8 @@ int snd_ad1848_create(struct snd_card *card, snd_ad1848_free(chip); return -EBUSY; } - chip->dma = dma; + chip->dma1 = dma; + chip->dma2 = dma; if (hardware == AD1848_HW_THINKPAD) { chip->thinkpad_flag = 1; @@ -947,7 +953,7 @@ static struct snd_pcm_ops snd_ad1848_capture_ops = { .pointer = snd_ad1848_capture_pointer, }; -int snd_ad1848_pcm(struct snd_ad1848 *chip, int device, struct snd_pcm **rpcm) +int snd_ad1848_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; @@ -964,7 +970,9 @@ int snd_ad1848_pcm(struct snd_ad1848 *chip, int device, struct snd_pcm **rpcm) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(), - 64*1024, chip->dma > 3 ? 128*1024 : 64*1024); + 64 * 1024, + chip->dma1 > 3 ? + 128 * 1024 : 64 * 1024); chip->pcm = pcm; if (rpcm) @@ -1003,7 +1011,7 @@ static int snd_ad1848_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); @@ -1015,7 +1023,7 @@ static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem static int snd_ad1848_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned short left, right; int change; @@ -1049,7 +1057,7 @@ static int snd_ad1848_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -1066,7 +1074,7 @@ static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int snd_ad1848_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; @@ -1100,7 +1108,7 @@ static int snd_ad1848_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -1122,7 +1130,7 @@ static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol); + struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -1159,7 +1167,7 @@ static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e /* */ -int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, +int snd_ad1848_add_ctl_elem(struct snd_wss *chip, const struct ad1848_mix_elem *c) { static struct snd_kcontrol_new newctls[] = { @@ -1227,7 +1235,7 @@ AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0, db_scale_6bit), }; -int snd_ad1848_mixer(struct snd_ad1848 *chip) +int snd_ad1848_mixer(struct snd_wss *chip) { struct snd_card *card; struct snd_pcm *pcm; diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index 4d198ec71e9b..aefd2f4a0572 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -151,7 +151,7 @@ struct snd_cmi8330 { struct pnp_dev *play; #endif struct snd_card *card; - struct snd_ad1848 *wss; + struct snd_wss *wss; struct snd_sb *sb; struct snd_pcm *pcm; diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index fefb8597717c..ff9baf751b22 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -706,13 +706,9 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; int error; struct snd_opti9xx *chip = card->private_data; -#if defined(CS4231) || defined(OPTi93X) struct snd_wss *codec; #ifdef CS4231 struct snd_timer *timer; -#endif -#else - struct snd_ad1848 *codec; #endif struct snd_pcm *pcm; struct snd_rawmidi *rmidi; diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index da3d152bcad4..1771f15d6d3c 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -397,7 +397,7 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, return 0; } -static int __devinit snd_sc6000_mixer(struct snd_ad1848 *chip) +static int __devinit snd_sc6000_mixer(struct snd_wss *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -483,7 +483,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) int xirq = irq[dev]; int xdma = dma[dev]; struct snd_card *card; - struct snd_ad1848 *chip; + struct snd_wss *chip; struct snd_opl3 *opl3; char __iomem *vport; char __iomem *vmss_port; diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index a07274ecb149..879c00c566ba 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -180,7 +180,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) }; -static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip) +static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -237,7 +237,7 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) static int possible_dmas[] = {1, 3, 0, -1}; int err, xirq, xdma1; struct snd_card *card; - struct snd_ad1848 *chip; + struct snd_wss *chip; card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) @@ -312,7 +312,7 @@ static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n, pm_message_t state) { struct snd_card *card = dev_get_drvdata(pdev); - struct snd_ad1848 *chip = card->private_data; + struct snd_wss *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->suspend(chip); @@ -322,7 +322,7 @@ static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n, static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) { struct snd_card *card = dev_get_drvdata(pdev); - struct snd_ad1848 *chip = card->private_data; + struct snd_wss *chip = card->private_data; chip->resume(chip); snd_ad1848_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]); -- cgit v1.2.3 From ece11c9b6db5b96179df8eb9cdc54c78953a4c0f Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:05:44 +0200 Subject: ALSA: wss_lib: use wss constants instead of ad1848 ones Use wss constants for mode. Move ad1848 hardware constants to the wss.h. Move mixer tlv macros into the ad1848_lib.c from the ad1848.h. Drop the MODE_RUNNING spurious IRQ guard on AD1848 as it doesn not seem to be needed. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1848/ad1848.c | 2 +- sound/isa/ad1848/ad1848_lib.c | 48 ++++++++++++++++++++++++-------------- sound/isa/cmi8330.c | 4 ++-- sound/isa/opti9xx/opti92x-ad1848.c | 2 +- sound/isa/sc6000.c | 2 +- sound/isa/sgalaxy.c | 2 +- 6 files changed, 36 insertions(+), 24 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 74db24ae6509..40de24b280d3 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -96,7 +96,7 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) return -EINVAL; error = snd_ad1848_create(card, port[n], irq[n], dma1[n], - thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip); + thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, &chip); if (error < 0) goto out; diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index e25fadffdb55..5aa8f6dae75b 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -283,14 +283,12 @@ static int snd_ad1848_trigger(struct snd_wss *chip, unsigned char what, return 0; } snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what); - chip->mode |= AD1848_MODE_RUNNING; } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { if (!(chip->image[AD1848_IFACE_CTRL] & what)) { spin_unlock(&chip->reg_lock); return 0; } snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what); - chip->mode &= ~AD1848_MODE_RUNNING; } else { result = -EINVAL; } @@ -378,7 +376,7 @@ static int snd_ad1848_open(struct snd_wss *chip, unsigned int mode) { unsigned long flags; - if (chip->mode & AD1848_MODE_OPEN) + if (chip->mode & WSS_MODE_OPEN) return -EAGAIN; snd_ad1848_mce_down(chip); @@ -570,11 +568,9 @@ static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) { struct snd_wss *chip = dev_id; - if ((chip->mode & AD1848_MODE_PLAY) && chip->playback_substream && - (chip->mode & AD1848_MODE_RUNNING)) + if ((chip->mode & WSS_MODE_PLAY) && chip->playback_substream) snd_pcm_period_elapsed(chip->playback_substream); - if ((chip->mode & AD1848_MODE_CAPTURE) && chip->capture_substream && - (chip->mode & AD1848_MODE_RUNNING)) + if ((chip->mode & WSS_MODE_RECORD) && chip->capture_substream) snd_pcm_period_elapsed(chip->capture_substream); outb(0, AD1848P(chip, STATUS)); /* clear global interrupt bit */ return IRQ_HANDLED; @@ -690,19 +686,19 @@ static int snd_ad1848_probe(struct snd_wss *chip) } if (id != 1) return -ENODEV; /* no valid device found */ - if (chip->hardware == AD1848_HW_DETECT) { + if (chip->hardware == WSS_HW_DETECT) { if (ad1847) { - chip->hardware = AD1848_HW_AD1847; + chip->hardware = WSS_HW_AD1847; } else { - chip->hardware = AD1848_HW_AD1848; + chip->hardware = WSS_HW_AD1848; rev = snd_ad1848_in(chip, AD1848_MISC_INFO); if (rev & 0x80) { - chip->hardware = AD1848_HW_CS4248; + chip->hardware = WSS_HW_CS4248; } else if ((rev & 0x0f) == 0x0a) { snd_ad1848_out(chip, AD1848_MISC_INFO, 0x40); for (i = 0; i < 16; ++i) { if (snd_ad1848_in(chip, i) != snd_ad1848_in(chip, i + 16)) { - chip->hardware = AD1848_HW_CMI8330; + chip->hardware = WSS_HW_CMI8330; break; } } @@ -782,7 +778,8 @@ static int snd_ad1848_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; - if ((err = snd_ad1848_open(chip, AD1848_MODE_PLAY)) < 0) + err = snd_ad1848_open(chip, WSS_MODE_PLAY); + if (err < 0) return err; chip->playback_substream = substream; runtime->hw = snd_ad1848_playback; @@ -798,7 +795,8 @@ static int snd_ad1848_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; - if ((err = snd_ad1848_open(chip, AD1848_MODE_CAPTURE)) < 0) + err = snd_ad1848_open(chip, WSS_MODE_RECORD); + if (err < 0) return err; chip->capture_substream = substream; runtime->hw = snd_ad1848_capture; @@ -812,7 +810,7 @@ static int snd_ad1848_playback_close(struct snd_pcm_substream *substream) { struct snd_wss *chip = snd_pcm_substream_chip(substream); - chip->mode &= ~AD1848_MODE_PLAY; + chip->mode &= ~WSS_MODE_PLAY; chip->playback_substream = NULL; snd_ad1848_close(chip); return 0; @@ -822,7 +820,7 @@ static int snd_ad1848_capture_close(struct snd_pcm_substream *substream) { struct snd_wss *chip = snd_pcm_substream_chip(substream); - chip->mode &= ~AD1848_MODE_CAPTURE; + chip->mode &= ~WSS_MODE_RECORD; chip->capture_substream = NULL; snd_ad1848_close(chip); return 0; @@ -903,9 +901,9 @@ int snd_ad1848_create(struct snd_card *card, chip->dma1 = dma; chip->dma2 = dma; - if (hardware == AD1848_HW_THINKPAD) { + if (hardware == WSS_HW_THINKPAD) { chip->thinkpad_flag = 1; - chip->hardware = AD1848_HW_DETECT; /* reset */ + chip->hardware = WSS_HW_DETECT; /* reset */ snd_ad1848_thinkpad_twiddle(chip, 1); } @@ -1214,6 +1212,20 @@ static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); +#define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ +{ .name = xname, \ + .index = xindex, \ + .type = AD1848_MIX_SINGLE, \ + .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert), \ + .tlv = xtlv } + +#define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ +{ .name = xname, \ + .index = xindex, \ + .type = AD1848_MIX_DOUBLE, \ + .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert), \ + .tlv = xtlv } + static struct ad1848_mix_elem snd_ad1848_controls[] = { AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), AD1848_DOUBLE_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index aefd2f4a0572..af6ba129910e 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -465,12 +465,12 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) wssport[dev] + 4, wssirq[dev], wssdma[dev], - AD1848_HW_DETECT, + WSS_HW_DETECT, &acard->wss)) < 0) { snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); return err; } - if (acard->wss->hardware != AD1848_HW_CMI8330) { + if (acard->wss->hardware != WSS_HW_CMI8330) { snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n"); return -ENODEV; } diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index ff9baf751b22..1f6d6fcd6e57 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -775,7 +775,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) #else if ((error = snd_ad1848_create(card, chip->wss_base + 4, chip->irq, chip->dma1, - AD1848_HW_DETECT, &codec)) < 0) + WSS_HW_DETECT, &codec)) < 0) return error; if ((error = snd_ad1848_pcm(codec, 0, &pcm)) < 0) return error; diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 1771f15d6d3c..0b6cf472ddcb 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -549,7 +549,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) goto err_unmap2; err = snd_ad1848_create(card, mss_port[dev] + 4, xirq, xdma, - AD1848_HW_DETECT, &chip); + WSS_HW_DETECT, &chip); if (err < 0) goto err_unmap2; card->private_data = chip; diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 879c00c566ba..9a5a7cc0e607 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -265,7 +265,7 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) if ((err = snd_ad1848_create(card, wssport[dev] + 4, xirq, xdma1, - AD1848_HW_DETECT, &chip)) < 0) + WSS_HW_DETECT, &chip)) < 0) goto _err; card->private_data = chip; -- cgit v1.2.3 From 0c5e3e98220e743f8ac095249b09ca8c87bd655b Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:06:46 +0200 Subject: ALSA: wss_lib: replace ad1848 mixer element macros with wss ones Use the wss macros instead of ad1848 ones. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1848/ad1848_lib.c | 123 ++++++++++++++++++------------------------ sound/isa/cmi8330.c | 82 ++++++++++++++++++---------- sound/isa/sgalaxy.c | 12 +++-- 3 files changed, 114 insertions(+), 103 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 5aa8f6dae75b..4f7aaf4e0989 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -1163,88 +1163,64 @@ static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -/* - */ -int snd_ad1848_add_ctl_elem(struct snd_wss *chip, - const struct ad1848_mix_elem *c) -{ - static struct snd_kcontrol_new newctls[] = { - [AD1848_MIX_SINGLE] = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_ad1848_info_single, - .get = snd_ad1848_get_single, - .put = snd_ad1848_put_single, - }, - [AD1848_MIX_DOUBLE] = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_ad1848_info_double, - .get = snd_ad1848_get_double, - .put = snd_ad1848_put_double, - }, - [AD1848_MIX_CAPTURE] = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_ad1848_info_mux, - .get = snd_ad1848_get_mux, - .put = snd_ad1848_put_mux, - }, - }; - struct snd_kcontrol *ctl; - int err; - - ctl = snd_ctl_new1(&newctls[c->type], chip); - if (! ctl) - return -ENOMEM; - strlcpy(ctl->id.name, c->name, sizeof(ctl->id.name)); - ctl->id.index = c->index; - ctl->private_value = c->private_value; - if (c->tlv) { - ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; - ctl->tlv.p = c->tlv; - } - if ((err = snd_ctl_add(chip->card, ctl)) < 0) - return err; - return 0; -} - -EXPORT_SYMBOL(snd_ad1848_add_ctl_elem); - static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); #define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ -{ .name = xname, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ + .name = xname, \ .index = xindex, \ - .type = AD1848_MIX_SINGLE, \ - .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert), \ - .tlv = xtlv } + .info = snd_ad1848_info_single, \ + .get = snd_ad1848_get_single, \ + .put = snd_ad1848_put_single, \ + .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \ + .tlv = { .p = (xtlv) } } #define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ -{ .name = xname, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ + .name = xname, \ .index = xindex, \ - .type = AD1848_MIX_DOUBLE, \ - .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert), \ - .tlv = xtlv } - -static struct ad1848_mix_elem snd_ad1848_controls[] = { -AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), -AD1848_DOUBLE_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, - db_scale_6bit), -AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -AD1848_DOUBLE_TLV("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1, - db_scale_5bit_12db_max), -AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -AD1848_DOUBLE_TLV("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1, - db_scale_5bit_12db_max), -AD1848_DOUBLE_TLV("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0, - db_scale_rec_gain), + .info = snd_ad1848_info_double, \ + .get = snd_ad1848_get_double, \ + .put = snd_ad1848_put_double, \ + .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \ + (shift_right << 19) | (mask << 24) | (invert << 22), \ + .tlv = { .p = (xtlv) } } + +static struct snd_kcontrol_new snd_ad1848_controls[] = { +WSS_DOUBLE("PCM Playback Switch", 0, + AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), +AD1848_DOUBLE_TLV("PCM Playback Volume", 0, + AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, + db_scale_6bit), +WSS_DOUBLE("Aux Playback Switch", 0, + AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +AD1848_DOUBLE_TLV("Aux Playback Volume", 0, + AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1, + db_scale_5bit_12db_max), +WSS_DOUBLE("Aux Playback Switch", 1, + AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +AD1848_DOUBLE_TLV("Aux Playback Volume", 1, + AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1, + db_scale_5bit_12db_max), +AD1848_DOUBLE_TLV("Capture Volume", 0, + AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0, + db_scale_rec_gain), { .name = "Capture Source", - .type = AD1848_MIX_CAPTURE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_ad1848_info_mux, + .get = snd_ad1848_get_mux, + .put = snd_ad1848_put_mux, }, -AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0), -AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0, - db_scale_6bit), +WSS_SINGLE("Loopback Capture Switch", 0, + AD1848_LOOPBACK, 0, 1, 0), +AD1848_SINGLE_TLV("Loopback Capture Volume", 0, + AD1848_LOOPBACK, 1, 63, 0, + db_scale_6bit), }; int snd_ad1848_mixer(struct snd_wss *chip) @@ -1261,9 +1237,12 @@ int snd_ad1848_mixer(struct snd_wss *chip) strcpy(card->mixername, pcm->name); - for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) - if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0) + for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { + err = snd_ctl_add(card, + snd_ctl_new1(&snd_ad1848_controls[idx], chip)); + if (err < 0) return err; + } return 0; } diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index af6ba129910e..ca6f602f15c2 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -174,32 +174,57 @@ MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids); #endif -static struct ad1848_mix_elem snd_cmi8330_controls[] __devinitdata = { -AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), -AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), -AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), -AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), -AD1848_DOUBLE("Line Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0), -AD1848_DOUBLE("Line Playback Volume", 0, CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0), -AD1848_DOUBLE("Line Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0), -AD1848_DOUBLE("Line Capture Volume", 0, CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0), -AD1848_DOUBLE("CD Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0), -AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0), -AD1848_DOUBLE("CD Playback Volume", 0, CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0), -AD1848_DOUBLE("CD Capture Volume", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0), -AD1848_SINGLE("Mic Playback Switch", 0, CMI8330_MUTEMUX, 0, 1, 0), -AD1848_SINGLE("Mic Playback Volume", 0, CMI8330_OUTPUTVOL, 0, 7, 0), -AD1848_SINGLE("Mic Capture Switch", 0, CMI8330_RMUX3D, 0, 1, 0), -AD1848_SINGLE("Mic Capture Volume", 0, CMI8330_OUTPUTVOL, 5, 7, 0), -AD1848_DOUBLE("Wavetable Playback Switch", 0, CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0), -AD1848_DOUBLE("Wavetable Playback Volume", 0, CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0), -AD1848_DOUBLE("Wavetable Capture Switch", 0, CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0), -AD1848_DOUBLE("Wavetable Capture Volume", 0, CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0), -AD1848_SINGLE("3D Control - Switch", 0, CMI8330_RMUX3D, 5, 1, 1), -AD1848_SINGLE("PC Speaker Playback Volume", 0, CMI8330_OUTPUTVOL, 3, 3, 0), -AD1848_SINGLE("FM Playback Switch", 0, CMI8330_RECMUX, 3, 1, 1), -AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",CAPTURE,SWITCH), 0, CMI8330_RMUX3D, 7, 1, 1), -AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",PLAYBACK,SWITCH), 0, CMI8330_MUTEMUX, 7, 1, 1), +static struct snd_kcontrol_new snd_cmi8330_controls[] __devinitdata = { +WSS_DOUBLE("Master Playback Volume", 0, + CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), +WSS_SINGLE("Loud Playback Switch", 0, + CMI8330_MUTEMUX, 6, 1, 1), +WSS_DOUBLE("PCM Playback Switch", 0, + AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("PCM Playback Volume", 0, + AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), +WSS_DOUBLE("Line Playback Switch", 0, + CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0), +WSS_DOUBLE("Line Playback Volume", 0, + CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0), +WSS_DOUBLE("Line Capture Switch", 0, + CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0), +WSS_DOUBLE("Line Capture Volume", 0, + CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0), +WSS_DOUBLE("CD Playback Switch", 0, + CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0), +WSS_DOUBLE("CD Capture Switch", 0, + CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0), +WSS_DOUBLE("CD Playback Volume", 0, + CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0), +WSS_DOUBLE("CD Capture Volume", 0, + CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0), +WSS_SINGLE("Mic Playback Switch", 0, + CMI8330_MUTEMUX, 0, 1, 0), +WSS_SINGLE("Mic Playback Volume", 0, + CMI8330_OUTPUTVOL, 0, 7, 0), +WSS_SINGLE("Mic Capture Switch", 0, + CMI8330_RMUX3D, 0, 1, 0), +WSS_SINGLE("Mic Capture Volume", 0, + CMI8330_OUTPUTVOL, 5, 7, 0), +WSS_DOUBLE("Wavetable Playback Switch", 0, + CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0), +WSS_DOUBLE("Wavetable Playback Volume", 0, + CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0), +WSS_DOUBLE("Wavetable Capture Switch", 0, + CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0), +WSS_DOUBLE("Wavetable Capture Volume", 0, + CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0), +WSS_SINGLE("3D Control - Switch", 0, + CMI8330_RMUX3D, 5, 1, 1), +WSS_SINGLE("PC Speaker Playback Volume", 0, + CMI8330_OUTPUTVOL, 3, 3, 0), +WSS_SINGLE("FM Playback Switch", 0, + CMI8330_RECMUX, 3, 1, 1), +WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0, + CMI8330_RMUX3D, 7, 1, 1), +WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0, + CMI8330_MUTEMUX, 7, 1, 1), }; #ifdef ENABLE_SB_MIXER @@ -268,7 +293,10 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 strcpy(card->mixername, "CMI8330/C3D"); for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { - if ((err = snd_ad1848_add_ctl_elem(acard->wss, &snd_cmi8330_controls[idx])) < 0) + err = snd_ctl_add(card, + snd_ctl_new1(&snd_cmi8330_controls[idx], + acard->wss)); + if (err < 0) return err; } diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 9a5a7cc0e607..5894b2d4db64 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -175,9 +175,11 @@ static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma) return snd_sgalaxy_setup_wss(wssport[dev], irq, dma); } -static struct ad1848_mix_elem snd_sgalaxy_controls[] = { -AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1), -AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) +static struct snd_kcontrol_new snd_sgalaxy_controls[] = { +WSS_DOUBLE("Aux Playback Switch", 0, + SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1), +WSS_DOUBLE("Aux Playback Volume", 0, + SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) }; static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip) @@ -210,7 +212,9 @@ static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip) return err; /* build AUX2 input */ for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) { - if ((err = snd_ad1848_add_ctl_elem(chip, &snd_sgalaxy_controls[idx])) < 0) + err = snd_ctl_add(card, + snd_ctl_new1(&snd_sgalaxy_controls[idx], chip)); + if (err < 0) return err; } return 0; -- cgit v1.2.3 From 811585e9d1769d6e282852fc0675735209547ca0 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:07:30 +0200 Subject: ALSA: wss_lib: use CS4231P instead of AD1848P (kill the AD1848P) Use CS4231P instead of AD1848P (kill the AD1848P). Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1848/ad1848_lib.c | 104 ++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 49 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 4f7aaf4e0989..07756fa36947 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -103,7 +103,7 @@ static void snd_ad1848_wait(struct snd_wss *chip) int timeout; for (timeout = 250; timeout > 0; timeout--) { - if ((inb(AD1848P(chip, REGSEL)) & AD1848_INIT) == 0) + if ((inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) == 0) break; udelay(100); } @@ -115,12 +115,12 @@ void snd_ad1848_out(struct snd_wss *chip, { snd_ad1848_wait(chip); #ifdef CONFIG_SND_DEBUG - if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) + if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) snd_printk(KERN_WARNING "auto calibration time out - " "reg = 0x%x, value = 0x%x\n", reg, value); #endif - outb(chip->mce_bit | reg, AD1848P(chip, REGSEL)); - outb(chip->image[reg] = value, AD1848P(chip, REG)); + outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL)); + outb(chip->image[reg] = value, chip->port + CS4231P(REG)); mb(); snd_printdd("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value); @@ -132,8 +132,8 @@ static void snd_ad1848_dout(struct snd_wss *chip, unsigned char reg, unsigned char value) { snd_ad1848_wait(chip); - outb(chip->mce_bit | reg, AD1848P(chip, REGSEL)); - outb(value, AD1848P(chip, REG)); + outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL)); + outb(value, chip->port + CS4231P(REG)); mb(); } @@ -141,37 +141,37 @@ static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg) { snd_ad1848_wait(chip); #ifdef CONFIG_SND_DEBUG - if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) + if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) snd_printk(KERN_WARNING "auto calibration time out - " "reg = 0x%x\n", reg); #endif - outb(chip->mce_bit | reg, AD1848P(chip, REGSEL)); + outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL)); mb(); - return inb(AD1848P(chip, REG)); + return inb(chip->port + CS4231P(REG)); } #if 0 static void snd_ad1848_debug(struct snd_wss *chip) { - printk("AD1848 REGS: INDEX = 0x%02x ", inb(AD1848P(chip, REGSEL))); - printk(" STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS))); - printk(" 0x00: left input = 0x%02x ", snd_ad1848_in(chip, 0x00)); - printk(" 0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08)); - printk(" 0x01: right input = 0x%02x ", snd_ad1848_in(chip, 0x01)); - printk(" 0x09: iface (CFIG 1) = 0x%02x\n", snd_ad1848_in(chip, 0x09)); - printk(" 0x02: AUXA left = 0x%02x ", snd_ad1848_in(chip, 0x02)); - printk(" 0x0a: pin control = 0x%02x\n", snd_ad1848_in(chip, 0x0a)); - printk(" 0x03: AUXA right = 0x%02x ", snd_ad1848_in(chip, 0x03)); - printk(" 0x0b: init & status = 0x%02x\n", snd_ad1848_in(chip, 0x0b)); - printk(" 0x04: AUXB left = 0x%02x ", snd_ad1848_in(chip, 0x04)); - printk(" 0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c)); - printk(" 0x05: AUXB right = 0x%02x ", snd_ad1848_in(chip, 0x05)); - printk(" 0x0d: loopback = 0x%02x\n", snd_ad1848_in(chip, 0x0d)); - printk(" 0x06: left output = 0x%02x ", snd_ad1848_in(chip, 0x06)); - printk(" 0x0e: data upr count = 0x%02x\n", snd_ad1848_in(chip, 0x0e)); - printk(" 0x07: right output = 0x%02x ", snd_ad1848_in(chip, 0x07)); - printk(" 0x0f: data lwr count = 0x%02x\n", snd_ad1848_in(chip, 0x0f)); + printk(KERN_DEBUG "AD1848 REGS: INDEX = 0x%02x ", inb(chip->port + CS4231P(REGSEL))); + printk(KERN_DEBUG " STATUS = 0x%02x\n", inb(chip->port + CS4231P(STATUS))); + printk(KERN_DEBUG " 0x00: left input = 0x%02x ", snd_ad1848_in(chip, 0x00)); + printk(KERN_DEBUG " 0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08)); + printk(KERN_DEBUG " 0x01: right input = 0x%02x ", snd_ad1848_in(chip, 0x01)); + printk(KERN_DEBUG " 0x09: iface (CFIG 1) = 0x%02x\n", snd_ad1848_in(chip, 0x09)); + printk(KERN_DEBUG " 0x02: AUXA left = 0x%02x ", snd_ad1848_in(chip, 0x02)); + printk(KERN_DEBUG " 0x0a: pin control = 0x%02x\n", snd_ad1848_in(chip, 0x0a)); + printk(KERN_DEBUG " 0x03: AUXA right = 0x%02x ", snd_ad1848_in(chip, 0x03)); + printk(KERN_DEBUG " 0x0b: init & status = 0x%02x\n", snd_ad1848_in(chip, 0x0b)); + printk(KERN_DEBUG " 0x04: AUXB left = 0x%02x ", snd_ad1848_in(chip, 0x04)); + printk(KERN_DEBUG " 0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c)); + printk(KERN_DEBUG " 0x05: AUXB right = 0x%02x ", snd_ad1848_in(chip, 0x05)); + printk(KERN_DEBUG " 0x0d: loopback = 0x%02x\n", snd_ad1848_in(chip, 0x0d)); + printk(KERN_DEBUG " 0x06: left output = 0x%02x ", snd_ad1848_in(chip, 0x06)); + printk(KERN_DEBUG " 0x0e: data upr count = 0x%02x\n", snd_ad1848_in(chip, 0x0e)); + printk(KERN_DEBUG " 0x07: right output = 0x%02x ", snd_ad1848_in(chip, 0x07)); + printk(KERN_DEBUG " 0x0f: data lwr count = 0x%02x\n", snd_ad1848_in(chip, 0x0f)); } #endif @@ -187,16 +187,17 @@ static void snd_ad1848_mce_up(struct snd_wss *chip) snd_ad1848_wait(chip); #ifdef CONFIG_SND_DEBUG - if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) + if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n"); #endif spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit |= AD1848_MCE; - timeout = inb(AD1848P(chip, REGSEL)); + timeout = inb(chip->port + CS4231P(REGSEL)); if (timeout == 0x80) snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); if (!(timeout & AD1848_MCE)) - outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL)); + outb(chip->mce_bit | (timeout & 0x1f), + chip->port + CS4231P(REGSEL)); spin_unlock_irqrestore(&chip->reg_lock, flags); } @@ -207,21 +208,25 @@ static void snd_ad1848_mce_down(struct snd_wss *chip) spin_lock_irqsave(&chip->reg_lock, flags); for (timeout = 5; timeout > 0; timeout--) - inb(AD1848P(chip, REGSEL)); + inb(chip->port + CS4231P(REGSEL)); /* end of cleanup sequence */ - for (timeout = 12000; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--) + for (timeout = 12000; + timeout > 0 && (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT); + timeout--) udelay(100); snd_printdd("(1) timeout = %ld\n", timeout); #ifdef CONFIG_SND_DEBUG - if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) - snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL)); + if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) + snd_printk(KERN_WARNING + "mce_down [0x%lx] - auto calibration time out (0)\n", + chip->port + CS4231P(REGSEL)); #endif chip->mce_bit &= ~AD1848_MCE; - reg = inb(AD1848P(chip, REGSEL)); - outb(chip->mce_bit | (reg & 0x1f), AD1848P(chip, REGSEL)); + reg = inb(chip->port + CS4231P(REGSEL)); + outb(chip->mce_bit | (reg & 0x1f), chip->port + CS4231P(REGSEL)); if (reg == 0x80) snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((reg & AD1848_MCE) == 0) { @@ -252,7 +257,8 @@ static void snd_ad1848_mce_down(struct snd_wss *chip) "mce_down - auto calibration time out (2)\n"); snd_printdd("(4) jiffies = %lu\n", jiffies); - snd_printd("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL))); + snd_printd("mce_down - exit = 0x%x\n", + inb(chip->port + CS4231P(REGSEL))); } static unsigned int snd_ad1848_get_count(unsigned char format, @@ -412,8 +418,8 @@ static int snd_ad1848_open(struct snd_wss *chip, unsigned int mode) /* ok. now enable and ack CODEC IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); - outb(0, AD1848P(chip, STATUS)); /* clear IRQ */ - outb(0, AD1848P(chip, STATUS)); /* clear IRQ */ + outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ + outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE; snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]); spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -431,8 +437,8 @@ static void snd_ad1848_close(struct snd_wss *chip) return; /* disable IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); - outb(0, AD1848P(chip, STATUS)); /* clear IRQ */ - outb(0, AD1848P(chip, STATUS)); /* clear IRQ */ + outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ + outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE; snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]); spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -449,8 +455,8 @@ static void snd_ad1848_close(struct snd_wss *chip) /* clear IRQ again */ spin_lock_irqsave(&chip->reg_lock, flags); - outb(0, AD1848P(chip, STATUS)); /* clear IRQ */ - outb(0, AD1848P(chip, STATUS)); /* clear IRQ */ + outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ + outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ spin_unlock_irqrestore(&chip->reg_lock, flags); chip->mode = 0; @@ -572,7 +578,7 @@ static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) snd_pcm_period_elapsed(chip->playback_substream); if ((chip->mode & WSS_MODE_RECORD) && chip->capture_substream) snd_pcm_period_elapsed(chip->capture_substream); - outb(0, AD1848P(chip, STATUS)); /* clear global interrupt bit */ + outb(0, chip->port + CS4231P(STATUS)); /* clear global interrupt bit */ return IRQ_HANDLED; } @@ -638,8 +644,8 @@ static void snd_ad1848_resume(struct snd_wss *chip) snd_ad1848_thinkpad_twiddle(chip, 1); /* clear any pendings IRQ */ - inb(AD1848P(chip, STATUS)); - outb(0, AD1848P(chip, STATUS)); + inb(chip->port + CS4231P(STATUS)); + outb(0, chip->port + CS4231P(STATUS)); mb(); snd_ad1848_mce_down(chip); @@ -662,7 +668,7 @@ static int snd_ad1848_probe(struct snd_wss *chip) id = ad1847 = 0; for (i = 0; i < 1000; i++) { mb(); - if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) + if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) udelay(500); else { spin_lock_irqsave(&chip->reg_lock, flags); @@ -707,8 +713,8 @@ static int snd_ad1848_probe(struct snd_wss *chip) } } spin_lock_irqsave(&chip->reg_lock, flags); - inb(AD1848P(chip, STATUS)); /* clear any pendings IRQ */ - outb(0, AD1848P(chip, STATUS)); + inb(chip->port + CS4231P(STATUS)); /* clear any pendings IRQ */ + outb(0, chip->port + CS4231P(STATUS)); mb(); spin_unlock_irqrestore(&chip->reg_lock, flags); -- cgit v1.2.3 From 5664daa1c1fa250dd7f6b336278b0402638e8edc Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:08:32 +0200 Subject: ALSA: wss_lib: use wss mixer code instead of ad1848 one Use the wss mixer code and kill the ad1848 mixer code. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1848/ad1848.c | 2 +- sound/isa/ad1848/ad1848_lib.c | 261 ------------------------------------- sound/isa/opti9xx/opti92x-ad1848.c | 22 ++-- sound/isa/sc6000.c | 4 +- sound/isa/sgalaxy.c | 5 +- sound/isa/wss/wss_lib.c | 61 ++++++++- 6 files changed, 73 insertions(+), 282 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 40de24b280d3..d5a96631587c 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -106,7 +106,7 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - error = snd_ad1848_mixer(chip); + error = snd_wss_mixer(chip); if (error < 0) goto out; diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 07756fa36947..5de046014337 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -994,267 +994,6 @@ const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction) EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); -/* - * MIXER part - */ - -static int snd_ad1848_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - static char *texts[4] = { - "Line", "Aux", "Mic", "Mix" - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - - spin_lock_irqsave(&chip->reg_lock, flags); - ucontrol->value.enumerated.item[0] = (chip->image[AD1848_LEFT_INPUT] & AD1848_MIXS_ALL) >> 6; - ucontrol->value.enumerated.item[1] = (chip->image[AD1848_RIGHT_INPUT] & AD1848_MIXS_ALL) >> 6; - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -static int snd_ad1848_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - unsigned short left, right; - int change; - - if (ucontrol->value.enumerated.item[0] > 3 || - ucontrol->value.enumerated.item[1] > 3) - return -EINVAL; - left = ucontrol->value.enumerated.item[0] << 6; - right = ucontrol->value.enumerated.item[1] << 6; - spin_lock_irqsave(&chip->reg_lock, flags); - left = (chip->image[AD1848_LEFT_INPUT] & ~AD1848_MIXS_ALL) | left; - right = (chip->image[AD1848_RIGHT_INPUT] & ~AD1848_MIXS_ALL) | right; - change = left != chip->image[AD1848_LEFT_INPUT] || - right != chip->image[AD1848_RIGHT_INPUT]; - snd_ad1848_out(chip, AD1848_LEFT_INPUT, left); - snd_ad1848_out(chip, AD1848_RIGHT_INPUT, right); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return change; -} - -static int snd_ad1848_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 16) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0xff; - - spin_lock_irqsave(&chip->reg_lock, flags); - ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask; - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (invert) - ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; - return 0; -} - -static int snd_ad1848_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0xff; - int change; - unsigned short val; - - val = (ucontrol->value.integer.value[0] & mask); - if (invert) - val = mask - val; - val <<= shift; - spin_lock_irqsave(&chip->reg_lock, flags); - val = (chip->image[reg] & ~(mask << shift)) | val; - change = val != chip->image[reg]; - snd_ad1848_out(chip, reg, val); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return change; -} - -static int snd_ad1848_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 24) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int left_reg = kcontrol->private_value & 0xff; - int right_reg = (kcontrol->private_value >> 8) & 0xff; - int shift_left = (kcontrol->private_value >> 16) & 0x07; - int shift_right = (kcontrol->private_value >> 19) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - - spin_lock_irqsave(&chip->reg_lock, flags); - ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask; - ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask; - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (invert) { - ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; - ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; - } - return 0; -} - -static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - unsigned long flags; - int left_reg = kcontrol->private_value & 0xff; - int right_reg = (kcontrol->private_value >> 8) & 0xff; - int shift_left = (kcontrol->private_value >> 16) & 0x07; - int shift_right = (kcontrol->private_value >> 19) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - int change; - unsigned short val1, val2; - - val1 = ucontrol->value.integer.value[0] & mask; - val2 = ucontrol->value.integer.value[1] & mask; - if (invert) { - val1 = mask - val1; - val2 = mask - val2; - } - val1 <<= shift_left; - val2 <<= shift_right; - spin_lock_irqsave(&chip->reg_lock, flags); - if (left_reg != right_reg) { - val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; - val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; - change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; - snd_ad1848_out(chip, left_reg, val1); - snd_ad1848_out(chip, right_reg, val2); - } else { - val1 = (chip->image[left_reg] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2; - change = val1 != chip->image[left_reg]; - snd_ad1848_out(chip, left_reg, val1); - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - return change; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); - -#define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .name = xname, \ - .index = xindex, \ - .info = snd_ad1848_info_single, \ - .get = snd_ad1848_get_single, \ - .put = snd_ad1848_put_single, \ - .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \ - .tlv = { .p = (xtlv) } } - -#define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .name = xname, \ - .index = xindex, \ - .info = snd_ad1848_info_double, \ - .get = snd_ad1848_get_double, \ - .put = snd_ad1848_put_double, \ - .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \ - (shift_right << 19) | (mask << 24) | (invert << 22), \ - .tlv = { .p = (xtlv) } } - -static struct snd_kcontrol_new snd_ad1848_controls[] = { -WSS_DOUBLE("PCM Playback Switch", 0, - AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), -AD1848_DOUBLE_TLV("PCM Playback Volume", 0, - AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, - db_scale_6bit), -WSS_DOUBLE("Aux Playback Switch", 0, - AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), -AD1848_DOUBLE_TLV("Aux Playback Volume", 0, - AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1, - db_scale_5bit_12db_max), -WSS_DOUBLE("Aux Playback Switch", 1, - AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), -AD1848_DOUBLE_TLV("Aux Playback Volume", 1, - AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1, - db_scale_5bit_12db_max), -AD1848_DOUBLE_TLV("Capture Volume", 0, - AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0, - db_scale_rec_gain), -{ - .name = "Capture Source", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_ad1848_info_mux, - .get = snd_ad1848_get_mux, - .put = snd_ad1848_put_mux, -}, -WSS_SINGLE("Loopback Capture Switch", 0, - AD1848_LOOPBACK, 0, 1, 0), -AD1848_SINGLE_TLV("Loopback Capture Volume", 0, - AD1848_LOOPBACK, 1, 63, 0, - db_scale_6bit), -}; - -int snd_ad1848_mixer(struct snd_wss *chip) -{ - struct snd_card *card; - struct snd_pcm *pcm; - unsigned int idx; - int err; - - snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); - - pcm = chip->pcm; - card = chip->card; - - strcpy(card->mixername, pcm->name); - - for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_ad1848_controls[idx], chip)); - if (err < 0) - return err; - } - - return 0; -} - -EXPORT_SYMBOL(snd_ad1848_mixer); - /* * INIT part */ diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 1f6d6fcd6e57..4f172a219244 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -757,6 +757,15 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) error = snd_wss_pcm(codec, 0, &pcm); if (error < 0) return error; +#else + error = snd_ad1848_create(card, chip->wss_base + 4, chip->irq, + chip->dma1, WSS_HW_DETECT, &codec); + if (error < 0) + return error; + error = snd_ad1848_pcm(codec, 0, &pcm); + if (error < 0) + return error; +#endif error = snd_wss_mixer(codec); if (error < 0) return error; @@ -764,23 +773,14 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) error = snd_wss_timer(codec, 0, &timer); if (error < 0) return error; -#else /* OPTI93X */ +#endif +#ifdef OPTi93X error = request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec); if (error < 0) { snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); return error; } -#endif -#else - if ((error = snd_ad1848_create(card, chip->wss_base + 4, - chip->irq, chip->dma1, - WSS_HW_DETECT, &codec)) < 0) - return error; - if ((error = snd_ad1848_pcm(codec, 0, &pcm)) < 0) - return error; - if ((error = snd_ad1848_mixer(codec)) < 0) - return error; #endif strcpy(card->driver, chip->name); sprintf(card->shortname, "OPTi %s", card->driver); diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 0b6cf472ddcb..ef98fe7dced8 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -560,9 +560,9 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) "error creating new ad1848 PCM device\n"); goto err_unmap2; } - err = snd_ad1848_mixer(chip); + err = snd_wss_mixer(chip); if (err < 0) { - snd_printk(KERN_ERR PFX "error creating new ad1848 mixer\n"); + snd_printk(KERN_ERR PFX "error creating new WSS mixer\n"); goto err_unmap2; } err = snd_sc6000_mixer(chip); diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 5894b2d4db64..e4f06de3480c 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -277,8 +277,9 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) snd_printdd(PFX "error creating new ad1848 PCM device\n"); goto _err; } - if ((err = snd_ad1848_mixer(chip)) < 0) { - snd_printdd(PFX "error creating new ad1848 mixer\n"); + err = snd_wss_mixer(chip); + if (err < 0) { + snd_printdd(PFX "error creating new WSS mixer\n"); goto _err; } if ((err = snd_sgalaxy_mixer(chip)) < 0) { diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index a982997805c4..1688f07a14b0 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1957,16 +1958,58 @@ int snd_wss_put_double(struct snd_kcontrol *kcontrol, val1 <<= shift_left; val2 <<= shift_right; spin_lock_irqsave(&chip->reg_lock, flags); - val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; - val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; - change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; - snd_wss_out(chip, left_reg, val1); - snd_wss_out(chip, right_reg, val2); + if (left_reg != right_reg) { + val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; + val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; + change = val1 != chip->image[left_reg] || + val2 != chip->image[right_reg]; + snd_wss_out(chip, left_reg, val1); + snd_wss_out(chip, right_reg, val2); + } else { + mask = (mask << shift_left) | (mask << shift_right); + val1 = (chip->image[left_reg] & ~mask) | val1 | val2; + change = val1 != chip->image[left_reg]; + snd_wss_out(chip, left_reg, val1); + } spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } EXPORT_SYMBOL(snd_wss_put_double); +static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); +static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); +static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); + +static struct snd_kcontrol_new snd_ad1848_controls[] = { +WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, + 7, 7, 1, 1), +WSS_DOUBLE_TLV("PCM Playback Volume", 0, + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1, + db_scale_6bit), +WSS_DOUBLE("Aux Playback Switch", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE_TLV("Aux Playback Volume", 0, + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1, + db_scale_5bit_12db_max), +WSS_DOUBLE("Aux Playback Switch", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), +WSS_DOUBLE_TLV("Aux Playback Volume", 1, + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1, + db_scale_5bit_12db_max), +WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, + 0, 0, 15, 0, db_scale_rec_gain), +{ + .name = "Capture Source", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_wss_info_mux, + .get = snd_wss_get_mux, + .put = snd_wss_put_mux, +}, +WSS_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), +WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 1, 63, 0, + db_scale_6bit), +}; + static struct snd_kcontrol_new snd_wss_controls[] = { WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), @@ -2071,6 +2114,14 @@ int snd_wss_mixer(struct snd_wss *chip) if (err < 0) return err; } + else if (chip->hardware & WSS_HW_AD1848_MASK) + for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { + err = snd_ctl_add(card, + snd_ctl_new1(&snd_ad1848_controls[idx], + chip)); + if (err < 0) + return err; + } else for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) { err = snd_ctl_add(card, -- cgit v1.2.3 From ead893c0deeec165524cc8a06e7e739d7d84b4c4 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:09:32 +0200 Subject: ALSA: wss_lib: use wss pcm code instead of ad1848 one Use the wss pcm code and kill the ad1848 pcm code. The AD1848 chip is much slower than CS4231 chips so the waiting loop was increased 100x (10x is not enough). Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/Kconfig | 5 +- sound/isa/ad1848/ad1848.c | 2 +- sound/isa/ad1848/ad1848_lib.c | 544 +------------------------------------ sound/isa/cmi8330.c | 2 +- sound/isa/opti9xx/opti92x-ad1848.c | 7 +- sound/isa/sc6000.c | 4 +- sound/isa/sgalaxy.c | 5 +- sound/isa/wss/wss_lib.c | 126 +++++++-- 8 files changed, 122 insertions(+), 573 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 87055568ccd4..cca11d5dc33b 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -1,12 +1,13 @@ # ALSA ISA drivers -config SND_AD1848_LIB +config SND_WSS_LIB tristate select SND_PCM -config SND_WSS_LIB +config SND_AD1848_LIB tristate select SND_PCM + select SND_WSS_LIB config SND_SB_COMMON tristate diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index d5a96631587c..17970c2f27e7 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -102,7 +102,7 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) card->private_data = chip; - error = snd_ad1848_pcm(chip, 0, &pcm); + error = snd_wss_pcm(chip, 0, &pcm); if (error < 0) goto out; diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 5de046014337..aa803d38a8ad 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -46,34 +46,6 @@ MODULE_LICENSE("GPL"); * Some variables */ -static unsigned char freq_bits[14] = { - /* 5510 */ 0x00 | AD1848_XTAL2, - /* 6620 */ 0x0E | AD1848_XTAL2, - /* 8000 */ 0x00 | AD1848_XTAL1, - /* 9600 */ 0x0E | AD1848_XTAL1, - /* 11025 */ 0x02 | AD1848_XTAL2, - /* 16000 */ 0x02 | AD1848_XTAL1, - /* 18900 */ 0x04 | AD1848_XTAL2, - /* 22050 */ 0x06 | AD1848_XTAL2, - /* 27042 */ 0x04 | AD1848_XTAL1, - /* 32000 */ 0x06 | AD1848_XTAL1, - /* 33075 */ 0x0C | AD1848_XTAL2, - /* 37800 */ 0x08 | AD1848_XTAL2, - /* 44100 */ 0x0A | AD1848_XTAL2, - /* 48000 */ 0x0C | AD1848_XTAL1 -}; - -static unsigned int rates[14] = { - 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, - 27042, 32000, 33075, 37800, 44100, 48000 -}; - -static struct snd_pcm_hw_constraint_list hw_constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - static unsigned char snd_ad1848_original_image[16] = { 0x00, /* 00 - lic */ @@ -128,15 +100,6 @@ void snd_ad1848_out(struct snd_wss *chip, EXPORT_SYMBOL(snd_ad1848_out); -static void snd_ad1848_dout(struct snd_wss *chip, - unsigned char reg, unsigned char value) -{ - snd_ad1848_wait(chip); - outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL)); - outb(value, chip->port + CS4231P(REG)); - mb(); -} - static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg) { snd_ad1848_wait(chip); @@ -261,315 +224,6 @@ static void snd_ad1848_mce_down(struct snd_wss *chip) inb(chip->port + CS4231P(REGSEL))); } -static unsigned int snd_ad1848_get_count(unsigned char format, - unsigned int size) -{ - switch (format & 0xe0) { - case AD1848_LINEAR_16: - size >>= 1; - break; - } - if (format & AD1848_STEREO) - size >>= 1; - return size; -} - -static int snd_ad1848_trigger(struct snd_wss *chip, unsigned char what, - int channel, int cmd) -{ - int result = 0; - -#if 0 - printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(AD1848P(card, STATUS))); -#endif - spin_lock(&chip->reg_lock); - if (cmd == SNDRV_PCM_TRIGGER_START) { - if (chip->image[AD1848_IFACE_CTRL] & what) { - spin_unlock(&chip->reg_lock); - return 0; - } - snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what); - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - if (!(chip->image[AD1848_IFACE_CTRL] & what)) { - spin_unlock(&chip->reg_lock); - return 0; - } - snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what); - } else { - result = -EINVAL; - } - spin_unlock(&chip->reg_lock); - return result; -} - -/* - * CODEC I/O - */ - -static unsigned char snd_ad1848_get_rate(unsigned int rate) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(rates); i++) - if (rate == rates[i]) - return freq_bits[i]; - snd_BUG(); - return freq_bits[ARRAY_SIZE(rates) - 1]; -} - -static int snd_ad1848_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - return snd_pcm_lib_ioctl(substream, cmd, arg); -} - -static unsigned char snd_ad1848_get_format(int format, int channels) -{ - unsigned char rformat; - - rformat = AD1848_LINEAR_8; - switch (format) { - case SNDRV_PCM_FORMAT_A_LAW: rformat = AD1848_ALAW_8; break; - case SNDRV_PCM_FORMAT_MU_LAW: rformat = AD1848_ULAW_8; break; - case SNDRV_PCM_FORMAT_S16_LE: rformat = AD1848_LINEAR_16; break; - } - if (channels > 1) - rformat |= AD1848_STEREO; -#if 0 - snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode); -#endif - return rformat; -} - -static void snd_ad1848_calibrate_mute(struct snd_wss *chip, int mute) -{ - unsigned long flags; - - mute = mute ? 1 : 0; - spin_lock_irqsave(&chip->reg_lock, flags); - if (chip->calibrate_mute == mute) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - return; - } - if (!mute) { - snd_ad1848_dout(chip, AD1848_LEFT_INPUT, chip->image[AD1848_LEFT_INPUT]); - snd_ad1848_dout(chip, AD1848_RIGHT_INPUT, chip->image[AD1848_RIGHT_INPUT]); - } - snd_ad1848_dout(chip, AD1848_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_LEFT_INPUT]); - snd_ad1848_dout(chip, AD1848_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_RIGHT_INPUT]); - snd_ad1848_dout(chip, AD1848_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_LEFT_INPUT]); - snd_ad1848_dout(chip, AD1848_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_RIGHT_INPUT]); - snd_ad1848_dout(chip, AD1848_LEFT_OUTPUT, mute ? 0x80 : chip->image[AD1848_LEFT_OUTPUT]); - snd_ad1848_dout(chip, AD1848_RIGHT_OUTPUT, mute ? 0x80 : chip->image[AD1848_RIGHT_OUTPUT]); - chip->calibrate_mute = mute; - spin_unlock_irqrestore(&chip->reg_lock, flags); -} - -static void snd_ad1848_set_data_format(struct snd_wss *chip, - struct snd_pcm_hw_params *hw_params) -{ - if (hw_params == NULL) { - chip->image[AD1848_DATA_FORMAT] = 0x20; - } else { - chip->image[AD1848_DATA_FORMAT] = - snd_ad1848_get_format(params_format(hw_params), params_channels(hw_params)) | - snd_ad1848_get_rate(params_rate(hw_params)); - } - // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]); -} - -static int snd_ad1848_open(struct snd_wss *chip, unsigned int mode) -{ - unsigned long flags; - - if (chip->mode & WSS_MODE_OPEN) - return -EAGAIN; - - snd_ad1848_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("open: (1)\n"); -#endif - snd_ad1848_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO | - AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO | - AD1848_CALIB_MODE); - chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB; - snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("open: (2)\n"); -#endif - - snd_ad1848_set_data_format(chip, NULL); - - snd_ad1848_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_down(chip); - -#ifdef SNDRV_DEBUG_MCE - snd_printk("open: (3)\n"); -#endif - - /* ok. now enable and ack CODEC IRQ */ - spin_lock_irqsave(&chip->reg_lock, flags); - outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ - outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ - chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE; - snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - chip->mode = mode; - - return 0; -} - -static void snd_ad1848_close(struct snd_wss *chip) -{ - unsigned long flags; - - if (!chip->mode) - return; - /* disable IRQ */ - spin_lock_irqsave(&chip->reg_lock, flags); - outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ - outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ - chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE; - snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - /* now disable capture & playback */ - - snd_ad1848_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO | - AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO); - snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_down(chip); - - /* clear IRQ again */ - spin_lock_irqsave(&chip->reg_lock, flags); - outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ - outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */ - spin_unlock_irqrestore(&chip->reg_lock, flags); - - chip->mode = 0; -} - -/* - * ok.. exported functions.. - */ - -static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd); -} - -static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd); -} - -static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - unsigned long flags; - int err; - - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) - return err; - snd_ad1848_calibrate_mute(chip, 1); - snd_ad1848_set_data_format(chip, hw_params); - snd_ad1848_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_down(chip); - snd_ad1848_calibrate_mute(chip, 0); - return 0; -} - -static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long flags; - unsigned int size = snd_pcm_lib_buffer_bytes(substream); - unsigned int count = snd_pcm_lib_period_bytes(substream); - - chip->p_dma_size = size; - chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO); - snd_dma_program(chip->dma1, runtime->dma_addr, size, - DMA_MODE_WRITE | DMA_AUTOINIT); - count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1; - spin_lock_irqsave(&chip->reg_lock, flags); - snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count); - snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - unsigned long flags; - int err; - - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) - return err; - snd_ad1848_calibrate_mute(chip, 1); - snd_ad1848_set_data_format(chip, hw_params); - snd_ad1848_mce_up(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_down(chip); - snd_ad1848_calibrate_mute(chip, 0); - return 0; -} - -static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long flags; - unsigned int size = snd_pcm_lib_buffer_bytes(substream); - unsigned int count = snd_pcm_lib_period_bytes(substream); - - chip->c_dma_size = size; - chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO); - snd_dma_program(chip->dma2, runtime->dma_addr, size, - DMA_MODE_READ | DMA_AUTOINIT); - count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1; - spin_lock_irqsave(&chip->reg_lock, flags); - snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count); - snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) { struct snd_wss *chip = dev_id; @@ -582,28 +236,6 @@ static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE)) - return 0; - ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); - return bytes_to_frames(substream->runtime, ptr); -} - -static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE)) - return 0; - ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); - return bytes_to_frames(substream->runtime, ptr); -} - /* */ @@ -728,6 +360,16 @@ static int snd_ad1848_probe(struct snd_wss *chip) snd_ad1848_out(chip, i, *ptr++); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_ad1848_mce_up(chip); + /* init needed for WSS pcm */ + spin_lock_irqsave(&chip->reg_lock, flags); + chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | + AD1848_PLAYBACK_PIO | + AD1848_CAPTURE_ENABLE | + AD1848_CAPTURE_PIO | + AD1848_CALIB_MODE); + chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB; + snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]); + spin_unlock_irqrestore(&chip->reg_lock, flags); snd_ad1848_mce_down(chip); return 0; /* all things are ok.. */ } @@ -736,102 +378,6 @@ static int snd_ad1848_probe(struct snd_wss *chip) */ -static struct snd_pcm_hardware snd_ad1848_playback = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | - SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE), - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - .rate_min = 5510, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = 64, - .period_bytes_max = (128*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static struct snd_pcm_hardware snd_ad1848_capture = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | - SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE), - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - .rate_min = 5510, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = 64, - .period_bytes_max = (128*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -/* - - */ - -static int snd_ad1848_playback_open(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - err = snd_ad1848_open(chip, WSS_MODE_PLAY); - if (err < 0) - return err; - chip->playback_substream = substream; - runtime->hw = snd_ad1848_playback; - snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); - return 0; -} - -static int snd_ad1848_capture_open(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - err = snd_ad1848_open(chip, WSS_MODE_RECORD); - if (err < 0) - return err; - chip->capture_substream = substream; - runtime->hw = snd_ad1848_capture; - snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); - return 0; -} - -static int snd_ad1848_playback_close(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - - chip->mode &= ~WSS_MODE_PLAY; - chip->playback_substream = NULL; - snd_ad1848_close(chip); - return 0; -} - -static int snd_ad1848_capture_close(struct snd_pcm_substream *substream) -{ - struct snd_wss *chip = snd_pcm_substream_chip(substream); - - chip->mode &= ~WSS_MODE_RECORD; - chip->capture_substream = NULL; - snd_ad1848_close(chip); - return 0; -} - static int snd_ad1848_free(struct snd_wss *chip) { release_and_free_resource(chip->res_port); @@ -851,17 +397,6 @@ static int snd_ad1848_dev_free(struct snd_device *device) return snd_ad1848_free(chip); } -static const char *snd_ad1848_chip_id(struct snd_wss *chip) -{ - switch (chip->hardware) { - case AD1848_HW_AD1847: return "AD1847"; - case AD1848_HW_AD1848: return "AD1848"; - case AD1848_HW_CS4248: return "CS4248"; - case AD1848_HW_CMI8330: return "CMI8330/C3D"; - default: return "???"; - } -} - int snd_ad1848_create(struct snd_card *card, unsigned long port, int irq, int dma, @@ -935,65 +470,6 @@ int snd_ad1848_create(struct snd_card *card, EXPORT_SYMBOL(snd_ad1848_create); -static struct snd_pcm_ops snd_ad1848_playback_ops = { - .open = snd_ad1848_playback_open, - .close = snd_ad1848_playback_close, - .ioctl = snd_ad1848_ioctl, - .hw_params = snd_ad1848_playback_hw_params, - .hw_free = snd_ad1848_playback_hw_free, - .prepare = snd_ad1848_playback_prepare, - .trigger = snd_ad1848_playback_trigger, - .pointer = snd_ad1848_playback_pointer, -}; - -static struct snd_pcm_ops snd_ad1848_capture_ops = { - .open = snd_ad1848_capture_open, - .close = snd_ad1848_capture_close, - .ioctl = snd_ad1848_ioctl, - .hw_params = snd_ad1848_capture_hw_params, - .hw_free = snd_ad1848_capture_hw_free, - .prepare = snd_ad1848_capture_prepare, - .trigger = snd_ad1848_capture_trigger, - .pointer = snd_ad1848_capture_pointer, -}; - -int snd_ad1848_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) -{ - struct snd_pcm *pcm; - int err; - - if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0) - return err; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops); - - pcm->private_data = chip; - pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; - strcpy(pcm->name, snd_ad1848_chip_id(chip)); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_isa_data(), - 64 * 1024, - chip->dma1 > 3 ? - 128 * 1024 : 64 * 1024); - - chip->pcm = pcm; - if (rpcm) - *rpcm = pcm; - return 0; -} - -EXPORT_SYMBOL(snd_ad1848_pcm); - -const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction) -{ - return direction == SNDRV_PCM_STREAM_PLAYBACK ? - &snd_ad1848_playback_ops : &snd_ad1848_capture_ops; -} - -EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); - /* * INIT part */ diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index ca6f602f15c2..6f7e8bb6ae60 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -413,7 +413,7 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 * chip->streams[CMI_SB_STREAM].private_data = chip->sb; /* AD1848 */ - ops = snd_ad1848_get_pcm_ops(CMI_AD_STREAM); + ops = snd_wss_get_pcm_ops(CMI_AD_STREAM); chip->streams[CMI_AD_STREAM].ops = *ops; chip->streams[CMI_AD_STREAM].open = ops->open; chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM]; diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 4f172a219244..561d4b3ed098 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -754,18 +754,15 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) #ifdef OPTi93X chip->codec = codec; #endif - error = snd_wss_pcm(codec, 0, &pcm); - if (error < 0) - return error; #else error = snd_ad1848_create(card, chip->wss_base + 4, chip->irq, chip->dma1, WSS_HW_DETECT, &codec); if (error < 0) return error; - error = snd_ad1848_pcm(codec, 0, &pcm); +#endif + error = snd_wss_pcm(codec, 0, &pcm); if (error < 0) return error; -#endif error = snd_wss_mixer(codec); if (error < 0) return error; diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index ef98fe7dced8..2f89ecb95ded 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -554,10 +554,10 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) goto err_unmap2; card->private_data = chip; - err = snd_ad1848_pcm(chip, 0, NULL); + err = snd_wss_pcm(chip, 0, NULL); if (err < 0) { snd_printk(KERN_ERR PFX - "error creating new ad1848 PCM device\n"); + "error creating new WSS PCM device\n"); goto err_unmap2; } err = snd_wss_mixer(chip); diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index e4f06de3480c..b43d6678ba20 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -273,8 +273,9 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) goto _err; card->private_data = chip; - if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) { - snd_printdd(PFX "error creating new ad1848 PCM device\n"); + err = snd_wss_pcm(chip, 0, NULL); + if (err < 0) { + snd_printdd(PFX "error creating new WSS PCM device\n"); goto _err; } err = snd_wss_mixer(chip); diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 1688f07a14b0..57d1e8ee6bbb 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -380,7 +380,7 @@ static void snd_wss_busy_wait(struct snd_wss *chip) for (timeout = 5; timeout > 0; timeout--) wss_inb(chip, CS4231P(REGSEL)); /* end of cleanup sequence */ - for (timeout = 250; + for (timeout = 25000; timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(10); @@ -413,6 +413,7 @@ void snd_wss_mce_down(struct snd_wss *chip) unsigned long flags; unsigned long end_time; int timeout; + int hw_mask = WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK | WSS_HW_AD1848; snd_wss_busy_wait(chip); @@ -427,10 +428,8 @@ void snd_wss_mce_down(struct snd_wss *chip) spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); - if ((timeout & CS4231_MCE) == 0 || - !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) { + if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask)) return; - } /* * Wait for (possible -- during init auto-calibration may not be set) @@ -601,12 +600,14 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute) mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]); snd_wss_dout(chip, CS4231_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]); - snd_wss_dout(chip, CS4231_LEFT_LINE_IN, - mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); - snd_wss_dout(chip, CS4231_RIGHT_LINE_IN, - mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); - snd_wss_dout(chip, CS4231_MONO_CTRL, - mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); + if (!(chip->hardware & WSS_HW_AD1848_MASK)) { + snd_wss_dout(chip, CS4231_LEFT_LINE_IN, + mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); + snd_wss_dout(chip, CS4231_RIGHT_LINE_IN, + mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); + snd_wss_dout(chip, CS4231_MONO_CTRL, + mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); + } if (chip->hardware == WSS_HW_INTERWAVE) { snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]); @@ -706,7 +707,10 @@ static void snd_wss_capture_format(struct snd_wss *chip, snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); } - snd_wss_out(chip, CS4231_REC_FORMAT, cdfr); + if (chip->hardware & WSS_HW_AD1848_MASK) + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr); + else + snd_wss_out(chip, CS4231_REC_FORMAT, cdfr); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_wss_mce_down(chip); } @@ -818,7 +822,9 @@ static void snd_wss_init(struct snd_wss *chip) snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); - snd_wss_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]); + if (!(chip->hardware & WSS_HW_AD1848_MASK)) + snd_wss_out(chip, CS4231_REC_FORMAT, + chip->image[CS4231_REC_FORMAT]); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_wss_mce_down(chip); @@ -844,20 +850,24 @@ static int snd_wss_open(struct snd_wss *chip, unsigned int mode) } /* ok. now enable and ack CODEC IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); - snd_wss_out(chip, CS4231_IRQ_STATUS, - CS4231_PLAYBACK_IRQ | - CS4231_RECORD_IRQ | - CS4231_TIMER_IRQ); - snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + if (!(chip->hardware & WSS_HW_AD1848_MASK)) { + snd_wss_out(chip, CS4231_IRQ_STATUS, + CS4231_PLAYBACK_IRQ | + CS4231_RECORD_IRQ | + CS4231_TIMER_IRQ); + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + } wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE; snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); - snd_wss_out(chip, CS4231_IRQ_STATUS, - CS4231_PLAYBACK_IRQ | - CS4231_RECORD_IRQ | - CS4231_TIMER_IRQ); - snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + if (!(chip->hardware & WSS_HW_AD1848_MASK)) { + snd_wss_out(chip, CS4231_IRQ_STATUS, + CS4231_PLAYBACK_IRQ | + CS4231_RECORD_IRQ | + CS4231_TIMER_IRQ); + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + } spin_unlock_irqrestore(&chip->reg_lock, flags); chip->mode = mode; @@ -879,7 +889,8 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode) /* disable IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); - snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + if (!(chip->hardware & WSS_HW_AD1848_MASK)) + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE; @@ -902,7 +913,8 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode) } /* clear IRQ again */ - snd_wss_out(chip, CS4231_IRQ_STATUS, 0); + if (!(chip->hardware & WSS_HW_AD1848_MASK)) + snd_wss_out(chip, CS4231_IRQ_STATUS, 0); wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -1023,7 +1035,13 @@ static int snd_wss_capture_prepare(struct snd_pcm_substream *substream) chip->c_dma_size = size; chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); - count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT], count) - 1; + if (chip->hardware & WSS_HW_AD1848_MASK) + count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], + count); + else + count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT], + count); + count--; if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) { snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count); snd_wss_out(chip, CS4231_PLY_UPR_CNT, @@ -1341,6 +1359,11 @@ static int snd_wss_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_wss_playback; + /* hardware limitation of older chipsets */ + if (chip->hardware & WSS_HW_AD1848_MASK) + runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM | + SNDRV_PCM_FMTBIT_S16_BE); + /* hardware bug in InterWave chipset */ if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3) runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW; @@ -1379,6 +1402,11 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_wss_capture; + /* hardware limitation of older chipsets */ + if (chip->hardware & WSS_HW_AD1848_MASK) + runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM | + SNDRV_PCM_FMTBIT_S16_BE); + /* hardware limitation of cheap chips */ if (chip->hardware == WSS_HW_CS4235 || chip->hardware == WSS_HW_CS4239) @@ -1423,6 +1451,26 @@ static int snd_wss_capture_close(struct snd_pcm_substream *substream) return 0; } +static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on) +{ + int tmp; + + if (!chip->thinkpad_flag) + return; + + outb(0x1c, AD1848_THINKPAD_CTL_PORT1); + tmp = inb(AD1848_THINKPAD_CTL_PORT2); + + if (on) + /* turn it on */ + tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT; + else + /* turn it off */ + tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT; + + outb(tmp, AD1848_THINKPAD_CTL_PORT2); +} + #ifdef CONFIG_PM /* lowlevel suspend callback for CS4231 */ @@ -1436,6 +1484,8 @@ static void snd_wss_suspend(struct snd_wss *chip) for (reg = 0; reg < 32; reg++) chip->image[reg] = snd_wss_in(chip, reg); spin_unlock_irqrestore(&chip->reg_lock, flags); + if (chip->thinkpad_flag) + snd_wss_thinkpad_twiddle(chip, 0); } /* lowlevel resume callback for CS4231 */ @@ -1445,6 +1495,8 @@ static void snd_wss_resume(struct snd_wss *chip) unsigned long flags; /* int timeout; */ + if (chip->thinkpad_flag) + snd_wss_thinkpad_twiddle(chip, 1); snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); for (reg = 0; reg < 32; reg++) { @@ -1542,6 +1594,14 @@ const char *snd_wss_chip_id(struct snd_wss *chip) return "AD1845"; case WSS_HW_OPTI93X: return "OPTi 93x"; + case WSS_HW_AD1847: + return "AD1847"; + case WSS_HW_AD1848: + return "AD1848"; + case WSS_HW_CS4248: + return "CS4248"; + case WSS_HW_CMI8330: + return "CMI8330/C3D"; default: return "???"; } @@ -1704,7 +1764,8 @@ int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0) + err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm); + if (err < 0) return err; spin_lock_init(&chip->reg_lock); @@ -1714,6 +1775,12 @@ int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops); + /* temporary */ + if (chip->hardware & WSS_HW_AD1848_MASK) { + chip->rate_constraint = snd_wss_xrate; + chip->set_playback_format = snd_wss_playback_format; + chip->set_capture_format = snd_wss_capture_format; + } /* global setup */ pcm->private_data = chip; pcm->info_flags = 0; @@ -2134,6 +2201,13 @@ int snd_wss_mixer(struct snd_wss *chip) } EXPORT_SYMBOL(snd_wss_mixer); +const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction) +{ + return direction == SNDRV_PCM_STREAM_PLAYBACK ? + &snd_wss_playback_ops : &snd_wss_capture_ops; +} +EXPORT_SYMBOL(snd_wss_get_pcm_ops); + /* * INIT part */ -- cgit v1.2.3 From 760fc6b838d8c783c363e8bdb3714bd92a8945c4 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:10:47 +0200 Subject: ALSA: wss_lib: use wss detection code instead of ad1848 one Use the wss detection code and kill the ad1848 library. The library is fully assimilated into the new wss library. This required reworking of the AD1848 family code so the code is changed to correctly detect chips from the AD1848 and CS4231 families. I have tested it on following cards: Gallant SC-6600 (codec: AD1848, driver: snd-sc6600) SoundScape VIVO/90 (codec: AD1845, driver: snd-sscape) SG Waverider (codec: CS4231A, driver: Rene Herman's snd-galaxy) Opti930 (codec: built-in - CS4231 compatible, driver: snd-opti93x) Opti931 (codec: built-in - CS4231 compatible, driver: snd-opti93x) Gallant SC-70P (chip/codec: CS4237B, driver: snd-cs4236) Audio Plus 3D (chip/codec: CMI8330A, driver: snd-cmi8330) Dell Latitude CP (chip/codec: cs4236, driver snd-cs4232) Sound playback and recording works on all these cards. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/Kconfig | 15 +- sound/isa/ad1848/Makefile | 2 - sound/isa/ad1848/ad1848.c | 7 +- sound/isa/ad1848/ad1848_lib.c | 487 ------------------------------------- sound/isa/cmi8330.c | 22 +- sound/isa/opti9xx/opti92x-ad1848.c | 15 -- sound/isa/sc6000.c | 6 +- sound/isa/sgalaxy.c | 13 +- sound/isa/wss/wss_lib.c | 150 +++++++++--- 9 files changed, 150 insertions(+), 567 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index cca11d5dc33b..ec80444c2a96 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -4,11 +4,6 @@ config SND_WSS_LIB tristate select SND_PCM -config SND_AD1848_LIB - tristate - select SND_PCM - select SND_WSS_LIB - config SND_SB_COMMON tristate @@ -56,7 +51,7 @@ config SND_AD1816A config SND_AD1848 tristate "Generic AD1848/CS4248 driver" - select SND_AD1848_LIB + select SND_WSS_LIB help Say Y here to include support for AD1848 (Analog Devices) or CS4248 (Cirrus Logic - Crystal Semiconductors) chips. @@ -97,7 +92,7 @@ config SND_AZT2320 config SND_CMI8330 tristate "C-Media CMI8330" - select SND_AD1848_LIB + select SND_WSS_LIB select SND_SB16_DSP help Say Y here to include support for soundcards based on the @@ -193,7 +188,7 @@ config SND_ES18XX config SND_SC6000 tristate "Gallant SC-6000, Audio Excel DSP 16" depends on HAS_IOPORT - select SND_AD1848_LIB + select SND_WSS_LIB select SND_OPL3_LIB select SND_MPU401_UART help @@ -280,7 +275,7 @@ config SND_OPTI92X_AD1848 select SND_OPL3_LIB select SND_OPL4_LIB select SND_MPU401_UART - select SND_AD1848_LIB + select SND_WSS_LIB help Say Y here to include support for soundcards based on Opti 82C92x or OTI-601 chips and using an AD1848 codec. @@ -373,7 +368,7 @@ config SND_SB16_CSP config SND_SGALAXY tristate "Aztech Sound Galaxy" - select SND_AD1848_LIB + select SND_WSS_LIB help Say Y here to include support for Aztech Sound Galaxy soundcards. diff --git a/sound/isa/ad1848/Makefile b/sound/isa/ad1848/Makefile index ae23331e9200..3d6dea3ff927 100644 --- a/sound/isa/ad1848/Makefile +++ b/sound/isa/ad1848/Makefile @@ -3,10 +3,8 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-ad1848-lib-objs := ad1848_lib.o snd-ad1848-objs := ad1848.o # Toplevel Module Dependency obj-$(CONFIG_SND_AD1848) += snd-ad1848.o -obj-$(CONFIG_SND_AD1848_LIB) += snd-ad1848-lib.o diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 17970c2f27e7..b68d20edc20f 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #define CRD_NAME "Generic AD1848/AD1847/CS4248" @@ -95,8 +95,9 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) if (!card) return -EINVAL; - error = snd_ad1848_create(card, port[n], irq[n], dma1[n], - thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, &chip); + error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1, + thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT, + 0, &chip); if (error < 0) goto out; diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index aa803d38a8ad..e69de29bb2d1 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -1,487 +0,0 @@ -/* - * Copyright (c) by Jaroslav Kysela - * Routines for control of AD1848/AD1847/CS4248 - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define SNDRV_MAIN_OBJECT_FILE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248"); -MODULE_LICENSE("GPL"); - -#if 0 -#define SNDRV_DEBUG_MCE -#endif - -/* - * Some variables - */ - -static unsigned char snd_ad1848_original_image[16] = -{ - 0x00, /* 00 - lic */ - 0x00, /* 01 - ric */ - 0x9f, /* 02 - la1ic */ - 0x9f, /* 03 - ra1ic */ - 0x9f, /* 04 - la2ic */ - 0x9f, /* 05 - ra2ic */ - 0xbf, /* 06 - loc */ - 0xbf, /* 07 - roc */ - 0x20, /* 08 - dfr */ - AD1848_AUTOCALIB, /* 09 - ic */ - 0x00, /* 0a - pc */ - 0x00, /* 0b - ti */ - 0x00, /* 0c - mi */ - 0x00, /* 0d - lbc */ - 0x00, /* 0e - dru */ - 0x00, /* 0f - drl */ -}; - -/* - * Basic I/O functions - */ - -static void snd_ad1848_wait(struct snd_wss *chip) -{ - int timeout; - - for (timeout = 250; timeout > 0; timeout--) { - if ((inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) == 0) - break; - udelay(100); - } -} - -void snd_ad1848_out(struct snd_wss *chip, - unsigned char reg, - unsigned char value) -{ - snd_ad1848_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) - snd_printk(KERN_WARNING "auto calibration time out - " - "reg = 0x%x, value = 0x%x\n", reg, value); -#endif - outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL)); - outb(chip->image[reg] = value, chip->port + CS4231P(REG)); - mb(); - snd_printdd("codec out - reg 0x%x = 0x%x\n", - chip->mce_bit | reg, value); -} - -EXPORT_SYMBOL(snd_ad1848_out); - -static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg) -{ - snd_ad1848_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) - snd_printk(KERN_WARNING "auto calibration time out - " - "reg = 0x%x\n", reg); -#endif - outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL)); - mb(); - return inb(chip->port + CS4231P(REG)); -} - -#if 0 - -static void snd_ad1848_debug(struct snd_wss *chip) -{ - printk(KERN_DEBUG "AD1848 REGS: INDEX = 0x%02x ", inb(chip->port + CS4231P(REGSEL))); - printk(KERN_DEBUG " STATUS = 0x%02x\n", inb(chip->port + CS4231P(STATUS))); - printk(KERN_DEBUG " 0x00: left input = 0x%02x ", snd_ad1848_in(chip, 0x00)); - printk(KERN_DEBUG " 0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08)); - printk(KERN_DEBUG " 0x01: right input = 0x%02x ", snd_ad1848_in(chip, 0x01)); - printk(KERN_DEBUG " 0x09: iface (CFIG 1) = 0x%02x\n", snd_ad1848_in(chip, 0x09)); - printk(KERN_DEBUG " 0x02: AUXA left = 0x%02x ", snd_ad1848_in(chip, 0x02)); - printk(KERN_DEBUG " 0x0a: pin control = 0x%02x\n", snd_ad1848_in(chip, 0x0a)); - printk(KERN_DEBUG " 0x03: AUXA right = 0x%02x ", snd_ad1848_in(chip, 0x03)); - printk(KERN_DEBUG " 0x0b: init & status = 0x%02x\n", snd_ad1848_in(chip, 0x0b)); - printk(KERN_DEBUG " 0x04: AUXB left = 0x%02x ", snd_ad1848_in(chip, 0x04)); - printk(KERN_DEBUG " 0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c)); - printk(KERN_DEBUG " 0x05: AUXB right = 0x%02x ", snd_ad1848_in(chip, 0x05)); - printk(KERN_DEBUG " 0x0d: loopback = 0x%02x\n", snd_ad1848_in(chip, 0x0d)); - printk(KERN_DEBUG " 0x06: left output = 0x%02x ", snd_ad1848_in(chip, 0x06)); - printk(KERN_DEBUG " 0x0e: data upr count = 0x%02x\n", snd_ad1848_in(chip, 0x0e)); - printk(KERN_DEBUG " 0x07: right output = 0x%02x ", snd_ad1848_in(chip, 0x07)); - printk(KERN_DEBUG " 0x0f: data lwr count = 0x%02x\n", snd_ad1848_in(chip, 0x0f)); -} - -#endif - -/* - * AD1848 detection / MCE routines - */ - -static void snd_ad1848_mce_up(struct snd_wss *chip) -{ - unsigned long flags; - int timeout; - - snd_ad1848_wait(chip); -#ifdef CONFIG_SND_DEBUG - if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) - snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n"); -#endif - spin_lock_irqsave(&chip->reg_lock, flags); - chip->mce_bit |= AD1848_MCE; - timeout = inb(chip->port + CS4231P(REGSEL)); - if (timeout == 0x80) - snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); - if (!(timeout & AD1848_MCE)) - outb(chip->mce_bit | (timeout & 0x1f), - chip->port + CS4231P(REGSEL)); - spin_unlock_irqrestore(&chip->reg_lock, flags); -} - -static void snd_ad1848_mce_down(struct snd_wss *chip) -{ - unsigned long flags, timeout; - int reg; - - spin_lock_irqsave(&chip->reg_lock, flags); - for (timeout = 5; timeout > 0; timeout--) - inb(chip->port + CS4231P(REGSEL)); - /* end of cleanup sequence */ - for (timeout = 12000; - timeout > 0 && (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT); - timeout--) - udelay(100); - - snd_printdd("(1) timeout = %ld\n", timeout); - -#ifdef CONFIG_SND_DEBUG - if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) - snd_printk(KERN_WARNING - "mce_down [0x%lx] - auto calibration time out (0)\n", - chip->port + CS4231P(REGSEL)); -#endif - - chip->mce_bit &= ~AD1848_MCE; - reg = inb(chip->port + CS4231P(REGSEL)); - outb(chip->mce_bit | (reg & 0x1f), chip->port + CS4231P(REGSEL)); - if (reg == 0x80) - snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); - if ((reg & AD1848_MCE) == 0) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - return; - } - - /* - * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low. - * It may take up to 5 sample periods (at most 907 us @ 5.5125 kHz) for - * the process to _start_, so it is important to wait at least that long - * before checking. Otherwise we might think AC has finished when it - * has in fact not begun. It could take 128 (no AC) or 384 (AC) cycles - * for ACI to drop. This gives a wait of at most 70 ms with a more - * typical value of 3-9 ms. - */ - timeout = jiffies + msecs_to_jiffies(250); - do { - spin_unlock_irqrestore(&chip->reg_lock, flags); - msleep(1); - spin_lock_irqsave(&chip->reg_lock, flags); - reg = snd_ad1848_in(chip, AD1848_TEST_INIT) & - AD1848_CALIB_IN_PROGRESS; - } while (reg && time_before(jiffies, timeout)); - spin_unlock_irqrestore(&chip->reg_lock, flags); - if (reg) - snd_printk(KERN_ERR - "mce_down - auto calibration time out (2)\n"); - - snd_printdd("(4) jiffies = %lu\n", jiffies); - snd_printd("mce_down - exit = 0x%x\n", - inb(chip->port + CS4231P(REGSEL))); -} - -static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) -{ - struct snd_wss *chip = dev_id; - - if ((chip->mode & WSS_MODE_PLAY) && chip->playback_substream) - snd_pcm_period_elapsed(chip->playback_substream); - if ((chip->mode & WSS_MODE_RECORD) && chip->capture_substream) - snd_pcm_period_elapsed(chip->capture_substream); - outb(0, chip->port + CS4231P(STATUS)); /* clear global interrupt bit */ - return IRQ_HANDLED; -} - -/* - - */ - -static void snd_ad1848_thinkpad_twiddle(struct snd_wss *chip, int on) -{ - int tmp; - - if (!chip->thinkpad_flag) return; - - outb(0x1c, AD1848_THINKPAD_CTL_PORT1); - tmp = inb(AD1848_THINKPAD_CTL_PORT2); - - if (on) - /* turn it on */ - tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT; - else - /* turn it off */ - tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT; - - outb(tmp, AD1848_THINKPAD_CTL_PORT2); - -} - -#ifdef CONFIG_PM -static void snd_ad1848_suspend(struct snd_wss *chip) -{ - snd_pcm_suspend_all(chip->pcm); - if (chip->thinkpad_flag) - snd_ad1848_thinkpad_twiddle(chip, 0); -} - -static void snd_ad1848_resume(struct snd_wss *chip) -{ - int i; - - if (chip->thinkpad_flag) - snd_ad1848_thinkpad_twiddle(chip, 1); - - /* clear any pendings IRQ */ - inb(chip->port + CS4231P(STATUS)); - outb(0, chip->port + CS4231P(STATUS)); - mb(); - - snd_ad1848_mce_down(chip); - for (i = 0; i < 16; i++) - snd_ad1848_out(chip, i, chip->image[i]); - snd_ad1848_mce_up(chip); - snd_ad1848_mce_down(chip); -} -#endif /* CONFIG_PM */ - -static int snd_ad1848_probe(struct snd_wss *chip) -{ - unsigned long flags; - int i, id, rev, ad1847; - unsigned char *ptr; - -#if 0 - snd_ad1848_debug(chip); -#endif - id = ad1847 = 0; - for (i = 0; i < 1000; i++) { - mb(); - if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) - udelay(500); - else { - spin_lock_irqsave(&chip->reg_lock, flags); - snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00); - snd_ad1848_out(chip, AD1848_LEFT_INPUT, 0xaa); - snd_ad1848_out(chip, AD1848_RIGHT_INPUT, 0x45); - rev = snd_ad1848_in(chip, AD1848_RIGHT_INPUT); - if (rev == 0x65) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - id = 1; - ad1847 = 1; - break; - } - if (snd_ad1848_in(chip, AD1848_LEFT_INPUT) == 0xaa && rev == 0x45) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - id = 1; - break; - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - } - } - if (id != 1) - return -ENODEV; /* no valid device found */ - if (chip->hardware == WSS_HW_DETECT) { - if (ad1847) { - chip->hardware = WSS_HW_AD1847; - } else { - chip->hardware = WSS_HW_AD1848; - rev = snd_ad1848_in(chip, AD1848_MISC_INFO); - if (rev & 0x80) { - chip->hardware = WSS_HW_CS4248; - } else if ((rev & 0x0f) == 0x0a) { - snd_ad1848_out(chip, AD1848_MISC_INFO, 0x40); - for (i = 0; i < 16; ++i) { - if (snd_ad1848_in(chip, i) != snd_ad1848_in(chip, i + 16)) { - chip->hardware = WSS_HW_CMI8330; - break; - } - } - snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00); - } - } - } - spin_lock_irqsave(&chip->reg_lock, flags); - inb(chip->port + CS4231P(STATUS)); /* clear any pendings IRQ */ - outb(0, chip->port + CS4231P(STATUS)); - mb(); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - chip->image[AD1848_MISC_INFO] = 0x00; - chip->image[AD1848_IFACE_CTRL] = - (chip->image[AD1848_IFACE_CTRL] & ~AD1848_SINGLE_DMA) | AD1848_SINGLE_DMA; - ptr = (unsigned char *) &chip->image; - snd_ad1848_mce_down(chip); - spin_lock_irqsave(&chip->reg_lock, flags); - for (i = 0; i < 16; i++) /* ok.. fill all AD1848 registers */ - snd_ad1848_out(chip, i, *ptr++); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_up(chip); - /* init needed for WSS pcm */ - spin_lock_irqsave(&chip->reg_lock, flags); - chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | - AD1848_PLAYBACK_PIO | - AD1848_CAPTURE_ENABLE | - AD1848_CAPTURE_PIO | - AD1848_CALIB_MODE); - chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB; - snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_ad1848_mce_down(chip); - return 0; /* all things are ok.. */ -} - -/* - - */ - -static int snd_ad1848_free(struct snd_wss *chip) -{ - release_and_free_resource(chip->res_port); - if (chip->irq >= 0) - free_irq(chip->irq, (void *) chip); - if (chip->dma1 >= 0) { - snd_dma_disable(chip->dma1); - free_dma(chip->dma1); - } - kfree(chip); - return 0; -} - -static int snd_ad1848_dev_free(struct snd_device *device) -{ - struct snd_wss *chip = device->device_data; - return snd_ad1848_free(chip); -} - -int snd_ad1848_create(struct snd_card *card, - unsigned long port, - int irq, int dma, - unsigned short hardware, - struct snd_wss **rchip) -{ - static struct snd_device_ops ops = { - .dev_free = snd_ad1848_dev_free, - }; - struct snd_wss *chip; - int err; - - *rchip = NULL; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - spin_lock_init(&chip->reg_lock); - chip->card = card; - chip->port = port; - chip->irq = -1; - chip->dma1 = -1; - chip->dma2 = -1; - chip->single_dma = 1; - chip->hardware = hardware; - memcpy(&chip->image, &snd_ad1848_original_image, sizeof(snd_ad1848_original_image)); - - if ((chip->res_port = request_region(port, 4, "AD1848")) == NULL) { - snd_printk(KERN_ERR "ad1848: can't grab port 0x%lx\n", port); - snd_ad1848_free(chip); - return -EBUSY; - } - if (request_irq(irq, snd_ad1848_interrupt, IRQF_DISABLED, "AD1848", (void *) chip)) { - snd_printk(KERN_ERR "ad1848: can't grab IRQ %d\n", irq); - snd_ad1848_free(chip); - return -EBUSY; - } - chip->irq = irq; - if (request_dma(dma, "AD1848")) { - snd_printk(KERN_ERR "ad1848: can't grab DMA %d\n", dma); - snd_ad1848_free(chip); - return -EBUSY; - } - chip->dma1 = dma; - chip->dma2 = dma; - - if (hardware == WSS_HW_THINKPAD) { - chip->thinkpad_flag = 1; - chip->hardware = WSS_HW_DETECT; /* reset */ - snd_ad1848_thinkpad_twiddle(chip, 1); - } - - if (snd_ad1848_probe(chip) < 0) { - snd_ad1848_free(chip); - return -ENODEV; - } - - /* Register device */ - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_ad1848_free(chip); - return err; - } - -#ifdef CONFIG_PM - chip->suspend = snd_ad1848_suspend; - chip->resume = snd_ad1848_resume; -#endif - - *rchip = chip; - return 0; -} - -EXPORT_SYMBOL(snd_ad1848_create); - -/* - * INIT part - */ - -static int __init alsa_ad1848_init(void) -{ - return 0; -} - -static void __exit alsa_ad1848_exit(void) -{ -} - -module_init(alsa_ad1848_init) -module_exit(alsa_ad1848_exit) diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index 6f7e8bb6ae60..e49aec700a55 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include @@ -180,9 +180,9 @@ WSS_DOUBLE("Master Playback Volume", 0, WSS_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), WSS_DOUBLE("PCM Playback Switch", 0, - AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), WSS_DOUBLE("PCM Playback Volume", 0, - AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), WSS_DOUBLE("Line Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0), WSS_DOUBLE("Line Playback Volume", 0, @@ -489,12 +489,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) int i, err; acard = card->private_data; - if ((err = snd_ad1848_create(card, - wssport[dev] + 4, - wssirq[dev], - wssdma[dev], - WSS_HW_DETECT, - &acard->wss)) < 0) { + err = snd_wss_create(card, wssport[dev] + 4, -1, + wssirq[dev], + wssdma[dev], -1, + WSS_HW_DETECT, 0, &acard->wss); + if (err < 0) { snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); return err; } @@ -517,9 +516,10 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) return err; } - snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */ + snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */ for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++) - snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]); + snd_wss_out(acard->wss, i, + snd_cmi8330_image[i - CMI8330_RMUX3D]); if ((err = snd_cmi8330_mixer(card, acard)) < 0) { snd_printk(KERN_ERR PFX "failed to create mixers\n"); diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 561d4b3ed098..cb5f66bde5d3 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -33,11 +33,7 @@ #include #include #include -#if defined(CS4231) || defined(OPTi93X) #include -#else -#include -#endif /* CS4231 */ #include #include #ifndef OPTi93X @@ -148,9 +144,7 @@ struct snd_opti9xx { long wss_base; int irq; int dma1; -#if defined(CS4231) || defined(OPTi93X) int dma2; -#endif /* CS4231 || OPTi93X */ long fm_port; @@ -225,9 +219,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, chip->wss_base = -1; chip->irq = -1; chip->dma1 = -1; -#if defined(CS4231) || defined (OPTi93X) chip->dma2 = -1; -#endif /* CS4231 || OPTi93X */ chip->fm_port = -1; chip->mpu_port = -1; chip->mpu_irq = -1; @@ -740,7 +732,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) if (error) return error; -#if defined(CS4231) || defined(OPTi93X) error = snd_wss_create(card, chip->wss_base + 4, -1, chip->irq, chip->dma1, chip->dma2, #ifdef CS4231 @@ -753,12 +744,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) return error; #ifdef OPTi93X chip->codec = codec; -#endif -#else - error = snd_ad1848_create(card, chip->wss_base + 4, chip->irq, - chip->dma1, WSS_HW_DETECT, &codec); - if (error < 0) - return error; #endif error = snd_wss_pcm(codec, 0, &pcm); if (error < 0) diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 2f89ecb95ded..ca35924dc3b3 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -548,8 +548,8 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) if (err < 0) goto err_unmap2; - err = snd_ad1848_create(card, mss_port[dev] + 4, xirq, xdma, - WSS_HW_DETECT, &chip); + err = snd_wss_create(card, mss_port[dev] + 4, -1, xirq, xdma, -1, + WSS_HW_DETECT, 0, &chip); if (err < 0) goto err_unmap2; card->private_data = chip; diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index b43d6678ba20..2c7503bf1271 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #define SNDRV_LEGACY_FIND_FREE_IRQ #define SNDRV_LEGACY_FIND_FREE_DMA @@ -267,9 +267,10 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0) goto _err; - if ((err = snd_ad1848_create(card, wssport[dev] + 4, - xirq, xdma1, - WSS_HW_DETECT, &chip)) < 0) + err = snd_wss_create(card, wssport[dev] + 4, -1, + xirq, xdma1, -1, + WSS_HW_DETECT, 0, &chip); + if (err < 0) goto _err; card->private_data = chip; @@ -331,8 +332,8 @@ static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) struct snd_wss *chip = card->private_data; chip->resume(chip); - snd_ad1848_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]); - snd_ad1848_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]); + snd_wss_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]); + snd_wss_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 57d1e8ee6bbb..a5602f515f49 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1073,7 +1073,11 @@ irqreturn_t snd_wss_interrupt(int irq, void *dev_id) struct snd_wss *chip = dev_id; unsigned char status; - status = snd_wss_in(chip, CS4231_IRQ_STATUS); + if (chip->hardware & WSS_HW_AD1848_MASK) + /* pretend it was the only possible irq for AD1848 */ + status = CS4231_PLAYBACK_IRQ; + else + status = snd_wss_in(chip, CS4231_IRQ_STATUS); if (status & CS4231_TIMER_IRQ) { if (chip->timer) snd_timer_interrupt(chip->timer, chip->timer->sticks); @@ -1105,7 +1109,11 @@ irqreturn_t snd_wss_interrupt(int irq, void *dev_id) } spin_lock(&chip->reg_lock); - snd_wss_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); + status = ~CS4231_ALL_IRQS | ~status; + if (chip->hardware & WSS_HW_AD1848_MASK) + wss_outb(chip, CS4231P(STATUS), 0); + else + snd_wss_outm(chip, CS4231_IRQ_STATUS, status, 0); spin_unlock(&chip->reg_lock); return IRQ_HANDLED; } @@ -1137,36 +1145,112 @@ static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *subst */ -static int snd_wss_probe(struct snd_wss *chip) +static int snd_ad1848_probe(struct snd_wss *chip) { unsigned long flags; - int i, id, rev; - unsigned char *ptr; - unsigned int hw; + int i, id, rev, ad1847; -#if 0 - snd_wss_debug(chip); -#endif id = 0; - for (i = 0; i < 50; i++) { + ad1847 = 0; + for (i = 0; i < 1000; i++) { mb(); - if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) - udelay(2000); + if (inb(chip->port + CS4231P(REGSEL)) & CS4231_INIT) + msleep(1); else { spin_lock_irqsave(&chip->reg_lock, flags); - snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2); - id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f; + snd_wss_out(chip, CS4231_MISC_INFO, 0x00); + snd_wss_out(chip, CS4231_LEFT_INPUT, 0xaa); + snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x45); + rev = snd_wss_in(chip, CS4231_RIGHT_INPUT); + if (rev == 0x65) { + spin_unlock_irqrestore(&chip->reg_lock, flags); + id = 1; + ad1847 = 1; + break; + } + if (snd_wss_in(chip, CS4231_LEFT_INPUT) == 0xaa && + rev == 0x45) { + spin_unlock_irqrestore(&chip->reg_lock, flags); + id = 1; + break; + } spin_unlock_irqrestore(&chip->reg_lock, flags); - if (id == 0x0a) - break; /* this is valid value */ } } - snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id); - if (id != 0x0a) + if (id != 1) return -ENODEV; /* no valid device found */ + id = 0; + if (chip->hardware == WSS_HW_DETECT) + id = ad1847 ? WSS_HW_AD1847 : WSS_HW_AD1848; + + spin_lock_irqsave(&chip->reg_lock, flags); + inb(chip->port + CS4231P(STATUS)); /* clear any pendings IRQ */ + outb(0, chip->port + CS4231P(STATUS)); + mb(); + if (id == WSS_HW_AD1848) { + /* check if there are more than 16 registers */ + rev = snd_wss_in(chip, CS4231_MISC_INFO); + snd_wss_out(chip, CS4231_MISC_INFO, 0x40); + for (i = 0; i < 16; ++i) { + if (snd_wss_in(chip, i) != snd_wss_in(chip, i + 16)) { + id = WSS_HW_CMI8330; + break; + } + } + snd_wss_out(chip, CS4231_MISC_INFO, 0x00); + if (id != WSS_HW_CMI8330 && (rev & 0x80)) + id = WSS_HW_CS4248; + if (id == WSS_HW_CMI8330 && (rev & 0x0f) != 0x0a) + id = 0; + } + if (id == WSS_HW_CMI8330) { + /* verify it is not CS4231 by changing the version register */ + /* on CMI8330 it is volume control register and can be set 0 */ + snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2); + snd_wss_dout(chip, CS4231_VERSION, 0x00); + rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7; + if (rev) + id = 0; + snd_wss_out(chip, CS4231_MISC_INFO, 0); + } + if (id) + chip->hardware = id; + + spin_unlock_irqrestore(&chip->reg_lock, flags); + return 0; /* all things are ok.. */ +} + +static int snd_wss_probe(struct snd_wss *chip) +{ + unsigned long flags; + int i, id, rev, regnum; + unsigned char *ptr; + unsigned int hw; + + id = snd_ad1848_probe(chip); + if (id < 0) + return id; hw = chip->hardware; if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) { + for (i = 0; i < 50; i++) { + mb(); + if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + msleep(2); + else { + spin_lock_irqsave(&chip->reg_lock, flags); + snd_wss_out(chip, CS4231_MISC_INFO, + CS4231_MODE2); + id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f; + spin_unlock_irqrestore(&chip->reg_lock, flags); + if (id == 0x0a) + break; /* this is valid value */ + } + } + snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id); + if (id != 0x0a) + return -ENODEV; /* no valid device found */ + rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7; snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev); if (rev == 0x80) { @@ -1197,7 +1281,8 @@ static int snd_wss_probe(struct snd_wss *chip) mb(); spin_unlock_irqrestore(&chip->reg_lock, flags); - chip->image[CS4231_MISC_INFO] = CS4231_MODE2; + if (!(chip->hardware & WSS_HW_AD1848_MASK)) + chip->image[CS4231_MISC_INFO] = CS4231_MODE2; switch (chip->hardware) { case WSS_HW_INTERWAVE: chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3; @@ -1223,9 +1308,10 @@ static int snd_wss_probe(struct snd_wss *chip) chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01; } ptr = (unsigned char *) &chip->image; + regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32; snd_wss_mce_down(chip); spin_lock_irqsave(&chip->reg_lock, flags); - for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */ + for (i = 0; i < regnum; i++) /* ok.. fill all registers */ snd_wss_out(chip, i, *ptr++); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_wss_mce_up(chip); @@ -1635,6 +1721,10 @@ static int snd_wss_new(struct snd_card *card, else memcpy(&chip->image, &snd_wss_original_image, sizeof(snd_wss_original_image)); + if (chip->hardware & WSS_HW_AD1848_MASK) { + chip->image[CS4231_PIN_CTRL] = 0; + chip->image[CS4231_TEST_INIT] = 0; + } *rchip = chip; return 0; @@ -1662,7 +1752,7 @@ int snd_wss_create(struct snd_card *card, chip->dma1 = -1; chip->dma2 = -1; - chip->res_port = request_region(port, 4, "CS4231"); + chip->res_port = request_region(port, 4, "WSS"); if (!chip->res_port) { snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port); snd_wss_free(chip); @@ -1681,20 +1771,20 @@ int snd_wss_create(struct snd_card *card, chip->cport = cport; if (!(hwshare & WSS_HWSHARE_IRQ)) if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED, - "CS4231", (void *) chip)) { + "WSS", (void *) chip)) { snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq); snd_wss_free(chip); return -EBUSY; } chip->irq = irq; - if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) { + if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) { snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1); snd_wss_free(chip); return -EBUSY; } chip->dma1 = dma1; if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 && - dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) { + dma2 >= 0 && request_dma(dma2, "WSS - 2")) { snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2); snd_wss_free(chip); return -EBUSY; @@ -1705,6 +1795,12 @@ int snd_wss_create(struct snd_card *card, } else chip->dma2 = dma2; + if (hardware == WSS_HW_THINKPAD) { + chip->thinkpad_flag = 1; + chip->hardware = WSS_HW_DETECT; /* reset */ + snd_wss_thinkpad_twiddle(chip, 1); + } + /* global setup */ if (snd_wss_probe(chip) < 0) { snd_wss_free(chip); @@ -1775,12 +1871,6 @@ int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops); - /* temporary */ - if (chip->hardware & WSS_HW_AD1848_MASK) { - chip->rate_constraint = snd_wss_xrate; - chip->set_playback_format = snd_wss_playback_format; - chip->set_capture_format = snd_wss_capture_format; - } /* global setup */ pcm->private_data = chip; pcm->info_flags = 0; -- cgit v1.2.3 From 31eca307fd9b1eb9ec138eb01bcfed16af60dabb Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 31 Jul 2008 21:11:46 +0200 Subject: ALSA: wss_lib: fix opti93x capture formats limitations Limit opti93x cards capture formats to only linear ones. Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index a5602f515f49..f2df77bd1308 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1495,8 +1495,10 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream) /* hardware limitation of cheap chips */ if (chip->hardware == WSS_HW_CS4235 || - chip->hardware == WSS_HW_CS4239) - runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; + chip->hardware == WSS_HW_CS4239 || + chip->hardware == WSS_HW_OPTI93X) + runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | + SNDRV_PCM_FMTBIT_S16_LE; snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); -- cgit v1.2.3 From a0d9274cd888ada59fe2734f45019d84bc40ac3d Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Mon, 4 Aug 2008 05:26:26 +0200 Subject: ALSA: wss_lib: opti92x-ad1848 WSS_HW_DETECT fix snd-opti92x-ad1848 mistakingly passes WSS_HW_OPTI93X currently. This fixes it as tested with a OPTi 82C929A/AD1848 card. Signed-off-by: Rene Herman Acked-by: Krzysztof Helt Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/opti9xx/opti92x-ad1848.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index cb5f66bde5d3..19706b0d8497 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -719,6 +719,8 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) chip->dma1 = dma1; #if defined(CS4231) || defined(OPTi93X) chip->dma2 = dma2; +#else + chip->dma2 = -1; #endif if (chip->wss_base == SNDRV_AUTO_PORT) { @@ -734,10 +736,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) error = snd_wss_create(card, chip->wss_base + 4, -1, chip->irq, chip->dma1, chip->dma2, -#ifdef CS4231 - WSS_HW_DETECT, 0, -#else /* OPTi93x */ +#ifdef OPTi93X WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, +#else + WSS_HW_DETECT, 0, #endif &codec); if (error < 0) -- cgit v1.2.3 From f1789f451d2ee18ff2bbc5afe78e1a7b9b714003 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 3 Aug 2008 17:57:21 +0200 Subject: ALSA: wss_lib: remove second mutexes initialization Remove initializations of spinlock and mutexes which are done earlier in snd_wss_new(). The snd_wss_new() is called from snd_wss_create(). Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index f2df77bd1308..fff8a3b79fdf 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1866,10 +1866,6 @@ int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) if (err < 0) return err; - spin_lock_init(&chip->reg_lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops); -- cgit v1.2.3 From ebae22590dccd2b8495c97e85290f5e07af7dc62 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Mon, 4 Aug 2008 01:23:43 +0200 Subject: ALSA: snd-cs4236: add Techmakers MF-4236PW PnP card ID Add the Techmakers MF-4236PW (Crystal CX4236B-XQ3) PnP card ID. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/cs423x/cs4236.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/isa') diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 3ff0f1229910..91f9c15d3e30 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -239,6 +239,8 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { { .id = "CSC9836", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, /* Gallant SC-70P */ { .id = "CSC9837", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, + /* Techmakers MF-4236PW */ + { .id = "CSCa736", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, /* TerraTec AudioSystem EWS64XL - CS4236B */ { .id = "CSCa836", .devs = { { "CSCa800" }, { "CSCa810" }, { "CSCa803" } } }, /* TerraTec AudioSystem EWS64XL - CS4236B */ -- cgit v1.2.3 From 6ddfa7432adc24c7471abe9d338a78540d0d025b Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Tue, 5 Aug 2008 09:33:33 +0200 Subject: ALSA: wss_lib: fix AZT2320 probe. After the transition from cs4321_lib to wss_lib, azt2320 probe visits snd_ad1848_probe during detection. It expects register 0 (LEFT_INPUT) to be able to retain the value 0xaa during detection but AZT2320 does not support MIC gain meaning it reads back as 0x8a instead. Signed-off-by: Rene Herman Acked-by: Krzysztof Helt Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index fff8a3b79fdf..866e8686dbe7 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1168,11 +1168,13 @@ static int snd_ad1848_probe(struct snd_wss *chip) ad1847 = 1; break; } - if (snd_wss_in(chip, CS4231_LEFT_INPUT) == 0xaa && - rev == 0x45) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - id = 1; - break; + if (rev == 0x45) { + rev = snd_wss_in(chip, CS4231_LEFT_INPUT); + if (rev == 0xaa || rev == 0x8a) { + spin_unlock_irqrestore(&chip->reg_lock, flags); + id = 1; + break; + } } spin_unlock_irqrestore(&chip->reg_lock, flags); } -- cgit v1.2.3 From c9a7dc2c5279830c0ad77715c0ace3e1edb07f4c Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 6 Aug 2008 08:09:34 +0200 Subject: ALSA: wss_lib: rework snd_ad1848_probe() Make snd_ad1848_probe() easier to follow. With an exception for only trying once as soon as the codec is out of init (which should be all that's needed) the detection logic should be unchanged. Signed-off-by: Rene Herman Acked-by: Krzysztof Helt Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 133 +++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 64 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 866e8686dbe7..011da7a2315d 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1147,79 +1147,84 @@ static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *subst static int snd_ad1848_probe(struct snd_wss *chip) { + unsigned long timeout = jiffies + msecs_to_jiffies(1000); unsigned long flags; - int i, id, rev, ad1847; + unsigned char r; + unsigned short hardware = 0; + int err = 0; + int i; - id = 0; - ad1847 = 0; - for (i = 0; i < 1000; i++) { - mb(); - if (inb(chip->port + CS4231P(REGSEL)) & CS4231_INIT) - msleep(1); - else { - spin_lock_irqsave(&chip->reg_lock, flags); - snd_wss_out(chip, CS4231_MISC_INFO, 0x00); - snd_wss_out(chip, CS4231_LEFT_INPUT, 0xaa); - snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x45); - rev = snd_wss_in(chip, CS4231_RIGHT_INPUT); - if (rev == 0x65) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - id = 1; - ad1847 = 1; - break; - } - if (rev == 0x45) { - rev = snd_wss_in(chip, CS4231_LEFT_INPUT); - if (rev == 0xaa || rev == 0x8a) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - id = 1; - break; - } - } - spin_unlock_irqrestore(&chip->reg_lock, flags); - } + while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { + if (time_after(jiffies, timeout)) + return -ENODEV; + cond_resched(); } - if (id != 1) - return -ENODEV; /* no valid device found */ - id = 0; - if (chip->hardware == WSS_HW_DETECT) - id = ad1847 ? WSS_HW_AD1847 : WSS_HW_AD1848; - spin_lock_irqsave(&chip->reg_lock, flags); - inb(chip->port + CS4231P(STATUS)); /* clear any pendings IRQ */ - outb(0, chip->port + CS4231P(STATUS)); - mb(); - if (id == WSS_HW_AD1848) { - /* check if there are more than 16 registers */ - rev = snd_wss_in(chip, CS4231_MISC_INFO); - snd_wss_out(chip, CS4231_MISC_INFO, 0x40); - for (i = 0; i < 16; ++i) { - if (snd_wss_in(chip, i) != snd_wss_in(chip, i + 16)) { - id = WSS_HW_CMI8330; - break; - } + + /* set CS423x MODE 1 */ + snd_wss_out(chip, CS4231_MISC_INFO, 0); + + snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x45); /* 0x55 & ~0x10 */ + r = snd_wss_in(chip, CS4231_RIGHT_INPUT); + if (r != 0x45) { + /* RMGE always high on AD1847 */ + if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45) { + err = -ENODEV; + goto out; + } + hardware = WSS_HW_AD1847; + } else { + snd_wss_out(chip, CS4231_LEFT_INPUT, 0xaa); + r = snd_wss_in(chip, CS4231_LEFT_INPUT); + /* L/RMGE always low on AT2320 */ + if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) { + err = -ENODEV; + goto out; } - snd_wss_out(chip, CS4231_MISC_INFO, 0x00); - if (id != WSS_HW_CMI8330 && (rev & 0x80)) - id = WSS_HW_CS4248; - if (id == WSS_HW_CMI8330 && (rev & 0x0f) != 0x0a) - id = 0; } - if (id == WSS_HW_CMI8330) { - /* verify it is not CS4231 by changing the version register */ - /* on CMI8330 it is volume control register and can be set 0 */ - snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2); - snd_wss_dout(chip, CS4231_VERSION, 0x00); - rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7; - if (rev) - id = 0; - snd_wss_out(chip, CS4231_MISC_INFO, 0); + + /* clear pending IRQ */ + wss_inb(chip, CS4231P(STATUS)); + wss_outb(chip, CS4231P(STATUS), 0); + mb(); + + if ((chip->hardware & WSS_HW_TYPE_MASK) != WSS_HW_DETECT) + goto out; + + if (hardware) { + chip->hardware = hardware; + goto out; } - if (id) - chip->hardware = id; + r = snd_wss_in(chip, CS4231_MISC_INFO); + + /* set CS423x MODE 2 */ + snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2); + for (i = 0; i < 16; i++) { + if (snd_wss_in(chip, i) != snd_wss_in(chip, 16 + i)) { + /* we have more than 16 registers: check ID */ + if ((r & 0xf) != 0xa) + goto out_mode; + /* + * on CMI8330, CS4231_VERSION is volume control and + * can be set to 0 + */ + snd_wss_dout(chip, CS4231_VERSION, 0); + r = snd_wss_in(chip, CS4231_VERSION) & 0xe7; + if (!r) + chip->hardware = WSS_HW_CMI8330; + goto out_mode; + } + } + if (r & 0x80) + chip->hardware = WSS_HW_CS4248; + else + chip->hardware = WSS_HW_AD1848; +out_mode: + snd_wss_out(chip, CS4231_MISC_INFO, 0); +out: spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; /* all things are ok.. */ + return err; } static int snd_wss_probe(struct snd_wss *chip) -- cgit v1.2.3 From 3caf8c080ef0bd0ccdc20bb57b150b6e40a86fd3 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Fri, 8 Aug 2008 16:39:21 +0200 Subject: ALSA: wss_lib: missing closing brace in (ifdeffed out) debug function. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 011da7a2315d..6b7a0fc6f71d 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -282,7 +282,7 @@ static void snd_wss_debug(struct snd_wss *chip) printk(KERN_DEBUG "CS4231 REGS: INDEX = 0x%02x " " STATUS = 0x%02x\n", - wss_inb(chip, CS4231P(REGSEL), + wss_inb(chip, CS4231P(REGSEL)), wss_inb(chip, CS4231P(STATUS))); printk(KERN_DEBUG " 0x00: left input = 0x%02x " -- cgit v1.2.3 From 622207dc31895b4e82c39100db8635d885c795e2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 8 Aug 2008 17:11:45 +0200 Subject: ALSA: Kill snd_assert() in sound/isa/* Kill snd_assert() in sound/isa/*, either removed or replaced with if () with snd_BUG_ON(). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1816a/ad1816a_lib.c | 6 ++++-- sound/isa/cs423x/cs4236_lib.c | 3 ++- sound/isa/es1688/es1688_lib.c | 3 ++- sound/isa/gus/gus_main.c | 6 ++++-- sound/isa/gus/gus_mixer.c | 6 ++++-- sound/isa/gus/gus_pcm.c | 12 ++++++++---- sound/isa/opti9xx/miro.c | 3 ++- sound/isa/sb/emu8000.c | 3 ++- sound/isa/sb/emu8000_patch.c | 3 ++- sound/isa/sb/sb16_csp.c | 9 ++++++--- sound/isa/sb/sb16_main.c | 3 ++- sound/isa/sb/sb8_main.c | 8 ++++++-- sound/isa/sb/sb_common.c | 3 ++- sound/isa/sb/sb_mixer.c | 9 ++++++--- sound/isa/wavefront/wavefront_fx.c | 8 ++++---- sound/isa/wavefront/wavefront_midi.c | 24 ++++++++++++++++-------- sound/isa/wavefront/wavefront_synth.c | 7 ++++--- sound/isa/wss/wss_lib.c | 6 ++++-- 18 files changed, 80 insertions(+), 42 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 4b8dfe2e3dcb..3bfca7c59baf 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c @@ -394,7 +394,8 @@ static int snd_ad1816a_timer_open(struct snd_timer *timer) static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer) { - snd_assert(timer != NULL, return 0); + if (snd_BUG_ON(!timer)) + return 0; return 10000; } @@ -961,7 +962,8 @@ int __devinit snd_ad1816a_mixer(struct snd_ad1816a *chip) unsigned int idx; int err; - snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->card)) + return -EINVAL; card = chip->card; diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index 33e9cf178b8b..6a85fdc53b60 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c @@ -967,7 +967,8 @@ int snd_cs4236_mixer(struct snd_wss *chip) int err; struct snd_kcontrol_new *kcontrol; - snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->card)) + return -EINVAL; card = chip->card; strcpy(card->mixername, snd_wss_chip_id(chip)); diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 1e1e575b1db3..4fbb508a817f 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -1009,7 +1009,8 @@ int snd_es1688_mixer(struct snd_es1688 *chip) int err; unsigned char reg, val; - snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->card)) + return -EINVAL; card = chip->card; diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index cccc16c8113f..12eb98f2f931 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c @@ -276,9 +276,11 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches) static unsigned char dmas[8] = {6, 1, 0, 2, 0, 3, 4, 5}; - snd_assert(gus != NULL, return -EINVAL); + if (snd_BUG_ON(!gus)) + return -EINVAL; card = gus->card; - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; gus->mix_cntrl_reg &= 0xf8; gus->mix_cntrl_reg |= 0x01; /* disable MIC, LINE IN, enable LINE OUT */ diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c index ebdb33469306..0dd43414016e 100644 --- a/sound/isa/gus/gus_mixer.c +++ b/sound/isa/gus/gus_mixer.c @@ -161,9 +161,11 @@ int snd_gf1_new_mixer(struct snd_gus_card * gus) unsigned int idx, max; int err; - snd_assert(gus != NULL, return -EINVAL); + if (snd_BUG_ON(!gus)) + return -EINVAL; card = gus->card; - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; if (gus->ics_flag) snd_component_add(card, "ICS2101"); diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 99731dc97325..38510aeb21c6 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -352,8 +352,10 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream, bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); len = samples_to_bytes(runtime, count); - snd_assert(bpos <= pcmp->dma_size, return -EIO); - snd_assert(bpos + len <= pcmp->dma_size, return -EIO); + if (snd_BUG_ON(bpos > pcmp->dma_size)) + return -EIO; + if (snd_BUG_ON(bpos + len > pcmp->dma_size)) + return -EIO; if (copy_from_user(runtime->dma_area + bpos, src, len)) return -EFAULT; if (snd_gf1_pcm_use_dma && len > 32) { @@ -381,8 +383,10 @@ static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream, bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); len = samples_to_bytes(runtime, count); - snd_assert(bpos <= pcmp->dma_size, return -EIO); - snd_assert(bpos + len <= pcmp->dma_size, return -EIO); + if (snd_BUG_ON(bpos > pcmp->dma_size)) + return -EIO; + if (snd_BUG_ON(bpos + len > pcmp->dma_size)) + return -EIO; snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count); if (snd_gf1_pcm_use_dma && len > 32) { return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len); diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 4641daa7844d..440755cc0013 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -675,7 +675,8 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro) unsigned int idx; int err; - snd_assert(miro != NULL && miro->card != NULL, return -EINVAL); + if (snd_BUG_ON(!miro || !miro->card)) + return -EINVAL; card = miro->card; diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index b35be7d9a9fa..96678d5d3834 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -1023,7 +1023,8 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) { int i, err = 0; - snd_assert(emu != NULL && card != NULL, return -EINVAL); + if (snd_BUG_ON(!emu || !card)) + return -EINVAL; spin_lock_init(&emu->control_lock); diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c index 1be16c9700f0..c99c6078be33 100644 --- a/sound/isa/sb/emu8000_patch.c +++ b/sound/isa/sb/emu8000_patch.c @@ -156,7 +156,8 @@ snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, struct snd_emu8000 *emu; emu = rec->hw; - snd_assert(sp != NULL, return -EINVAL); + if (snd_BUG_ON(!sp)) + return -EINVAL; if (sp->v.size == 0) return 0; diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 35f3d7b16536..49037d074c71 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -198,7 +198,8 @@ static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned i struct snd_sb_csp_start start_info; int err; - snd_assert(p != NULL, return -EINVAL); + if (snd_BUG_ON(!p)) + return -EINVAL; if (snd_sb_csp_check_version(p)) return -ENODEV; @@ -1046,7 +1047,8 @@ static int snd_sb_qsound_build(struct snd_sb_csp * p) struct snd_card *card; int err; - snd_assert(p != NULL, return -EINVAL); + if (snd_BUG_ON(!p)) + return -EINVAL; card = p->chip->card; p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2; @@ -1071,7 +1073,8 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p) struct snd_card *card; unsigned long flags; - snd_assert(p != NULL, return); + if (snd_BUG_ON(!p)) + return; card = p->chip->card; diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index f7e8192270ae..2a6cc1cfe945 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -669,7 +669,8 @@ static int snd_sb16_capture_close(struct snd_pcm_substream *substream) static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what) { if (chip->dma8 < 0 || chip->dma16 < 0) { - snd_assert(what == 0, return -EINVAL); + if (snd_BUG_ON(what)) + return -EINVAL; return 0; } if (what == 0) { diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index fe03bb820532..658d55769c9c 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -111,7 +111,9 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) switch (chip->hardware) { case SB_HW_PRO: if (runtime->channels > 1) { - snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); + if (snd_BUG_ON(rate != SB8_RATE(11025) && + rate != SB8_RATE(22050))) + return -EINVAL; chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; break; } @@ -237,7 +239,9 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) switch (chip->hardware) { case SB_HW_PRO: if (runtime->channels > 1) { - snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); + if (snd_BUG_ON(rate != SB8_RATE(11025) && + rate != SB8_RATE(22050))) + return -EINVAL; chip->capture_format = SB_DSP_HI_INPUT_AUTO; break; } diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index b432d9ae874b..27a651502251 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c @@ -219,7 +219,8 @@ int snd_sbdsp_create(struct snd_card *card, .dev_free = snd_sbdsp_dev_free, }; - snd_assert(r_chip != NULL, return -EINVAL); + if (snd_BUG_ON(!r_chip)) + return -EINVAL; *r_chip = NULL; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 73d4572d136b..406a431af91e 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c @@ -792,7 +792,8 @@ int snd_sbmixer_new(struct snd_sb *chip) struct snd_card *card; int err; - snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->card)) + return -EINVAL; card = chip->card; @@ -925,7 +926,8 @@ static unsigned char als4000_saved_regs[] = { static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) { unsigned char *val = chip->saved_regs; - snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); + if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs))) + return; for (; num_regs; num_regs--) *val++ = snd_sbmixer_read(chip, *regs++); } @@ -933,7 +935,8 @@ static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) { unsigned char *val = chip->saved_regs; - snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); + if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs))) + return; for (; num_regs; num_regs--) snd_sbmixer_write(chip, *regs++, *val++); } diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 2efaa7f205aa..dfc449a2194e 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -180,11 +180,11 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file, unsigned short *pd; int err = 0; - snd_assert(sdev->card != NULL, return -ENODEV); - card = sdev->card; - - snd_assert(card->private_data != NULL, return -ENODEV); + if (snd_BUG_ON(!card)) + return -ENODEV; + if (snd_BUG_ON(!card->private_data)) + return -ENODEV; acard = card->private_data; dev = &acard->wavefront; diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index a33384a55b0f..f14a7c0b6998 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c @@ -235,8 +235,10 @@ static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; - snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); - snd_assert(substream->rmidi->private_data != NULL, return -EIO); + if (snd_BUG_ON(!substream || !substream->rmidi)) + return -ENXIO; + if (snd_BUG_ON(!substream->rmidi->private_data)) + return -ENXIO; mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); @@ -257,8 +259,10 @@ static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substrea snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; - snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); - snd_assert(substream->rmidi->private_data != NULL, return -EIO); + if (snd_BUG_ON(!substream || !substream->rmidi)) + return -ENXIO; + if (snd_BUG_ON(!substream->rmidi->private_data)) + return -ENXIO; mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); @@ -279,8 +283,10 @@ static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substrea snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; - snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); - snd_assert(substream->rmidi->private_data != NULL, return -EIO); + if (snd_BUG_ON(!substream || !substream->rmidi)) + return -ENXIO; + if (snd_BUG_ON(!substream->rmidi->private_data)) + return -ENXIO; mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); @@ -300,8 +306,10 @@ static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substre snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; - snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); - snd_assert(substream->rmidi->private_data != NULL, return -EIO); + if (snd_BUG_ON(!substream || !substream->rmidi)) + return -ENXIO; + if (snd_BUG_ON(!substream->rmidi->private_data)) + return -ENXIO; mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 0bb9b9256601..4c410820a994 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -1648,9 +1648,10 @@ snd_wavefront_synth_ioctl (struct snd_hwdep *hw, struct file *file, card = (struct snd_card *) hw->card; - snd_assert(card != NULL, return -ENODEV); - - snd_assert(card->private_data != NULL, return -ENODEV); + if (snd_BUG_ON(!card)) + return -ENODEV; + if (snd_BUG_ON(!card->private_data)) + return -ENODEV; acard = card->private_data; dev = &acard->wavefront; diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 6b7a0fc6f71d..c5beec65936d 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1946,7 +1946,8 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, char **ptexts = texts; struct snd_wss *chip = snd_kcontrol_chip(kcontrol); - snd_assert(chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip->card)) + return -EINVAL; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 2; uinfo->value.enumerated.items = 4; @@ -2262,7 +2263,8 @@ int snd_wss_mixer(struct snd_wss *chip) unsigned int idx; int err; - snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->pcm)) + return -EINVAL; card = chip->card; -- cgit v1.2.3 From 503c10d8a7dd3aa627dc57990c95a8a4dd4fa4b5 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 17 Aug 2008 20:01:14 +0200 Subject: ALSA: opl3sa2: drop snd_card pointer from the snd_opl3sa2 structure Remove card pointer from the snd_opl3sa2 structure and break circular reference snd_card->snd_opl3sa2->snd_card. Signed-off-by: Krzysztof Helt Acked-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/opl3sa2.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 949fee5cd070..1ac29270a402 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -124,7 +124,6 @@ static int pnpc_registered; #define OPL3SA2_PM_D3 (OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX) struct snd_opl3sa2 { - struct snd_card *card; int version; /* 2 or 3 */ unsigned long port; /* control port */ struct resource *res_port; /* control port resource */ @@ -222,14 +221,13 @@ static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsig spin_unlock_irqrestore(&chip->reg_lock, flags); } -static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip) +static int __devinit snd_opl3sa2_detect(struct snd_card *card) { - struct snd_card *card; + struct snd_opl3sa2 *chip = card->private_data; unsigned long port; unsigned char tmp, tmp1; char str[2]; - card = chip->card; port = chip->port; if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) { snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port); @@ -298,12 +296,14 @@ static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip) static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) { unsigned short status; - struct snd_opl3sa2 *chip = dev_id; + struct snd_card *card = dev_id; + struct snd_opl3sa2 *chip; int handled = 0; - if (chip == NULL || chip->card == NULL) + if (card == NULL || card->private_data == NULL) return IRQ_NONE; + chip = card->private_data; status = snd_opl3sa2_read(chip, OPL3SA2_IRQ_STATUS); if (status & 0x20) { @@ -327,8 +327,10 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) snd_opl3sa2_read(chip, OPL3SA2_MASTER_RIGHT); snd_opl3sa2_read(chip, OPL3SA2_MASTER_LEFT); if (chip->master_switch && chip->master_volume) { - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, + &chip->master_switch->id); + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, + &chip->master_volume->id); } } return IRQ_RETVAL(handled); @@ -512,9 +514,9 @@ static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol) chip->master_volume = NULL; } -static int __devinit snd_opl3sa2_mixer(struct snd_opl3sa2 *chip) +static int __devinit snd_opl3sa2_mixer(struct snd_card *card) { - struct snd_card *card = chip->card; + struct snd_opl3sa2 *chip = card->private_data; struct snd_ctl_elem_id id1, id2; struct snd_kcontrol *kctl; unsigned int idx; @@ -650,7 +652,6 @@ static struct snd_card *snd_opl3sa2_card_new(int dev) chip = card->private_data; spin_lock_init(&chip->reg_lock); chip->irq = -1; - chip->card = card; card->private_free = snd_opl3sa2_free; return card; } @@ -672,9 +673,12 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) xdma2 = dma2[dev]; if (xdma2 < 0) chip->single_dma = 1; - if ((err = snd_opl3sa2_detect(chip)) < 0) + err = snd_opl3sa2_detect(card); + if (err < 0) return err; - if (request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED, "OPL3-SA2", chip)) { + err = request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED, + "OPL3-SA2", card); + if (err) { snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); return -ENODEV; } @@ -694,7 +698,8 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) err = snd_wss_mixer(wss); if (err < 0) return err; - if ((err = snd_opl3sa2_mixer(chip)) < 0) + err = snd_opl3sa2_mixer(card); + if (err < 0) return err; err = snd_wss_timer(wss, 0, NULL); if (err < 0) -- cgit v1.2.3 From ace457c77ba8c0705e14d95c65e73d7e569bd7b9 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 17 Aug 2008 22:38:27 +0200 Subject: ALSA: wss_lib: snd_wss_calibrate_mute improvement Mute sound by setting mute bit without setting volume to 0. It makes both source code and binary shorter. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index c5beec65936d..2a5defa5e636 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -574,7 +574,7 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute) { unsigned long flags; - mute = mute ? 1 : 0; + mute = mute ? 0x80 : 0; spin_lock_irqsave(&chip->reg_lock, flags); if (chip->calibrate_mute == mute) { spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -589,34 +589,34 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute) chip->image[CS4231_LOOPBACK]); } snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT, - mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]); + mute | chip->image[CS4231_AUX1_LEFT_INPUT]); snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT, - mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]); + mute | chip->image[CS4231_AUX1_RIGHT_INPUT]); snd_wss_dout(chip, CS4231_AUX2_LEFT_INPUT, - mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]); + mute | chip->image[CS4231_AUX2_LEFT_INPUT]); snd_wss_dout(chip, CS4231_AUX2_RIGHT_INPUT, - mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]); + mute | chip->image[CS4231_AUX2_RIGHT_INPUT]); snd_wss_dout(chip, CS4231_LEFT_OUTPUT, - mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]); + mute | chip->image[CS4231_LEFT_OUTPUT]); snd_wss_dout(chip, CS4231_RIGHT_OUTPUT, - mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]); + mute | chip->image[CS4231_RIGHT_OUTPUT]); if (!(chip->hardware & WSS_HW_AD1848_MASK)) { snd_wss_dout(chip, CS4231_LEFT_LINE_IN, - mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]); + mute | chip->image[CS4231_LEFT_LINE_IN]); snd_wss_dout(chip, CS4231_RIGHT_LINE_IN, - mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]); + mute | chip->image[CS4231_RIGHT_LINE_IN]); snd_wss_dout(chip, CS4231_MONO_CTRL, mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]); } if (chip->hardware == WSS_HW_INTERWAVE) { snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT, - mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]); + mute | chip->image[CS4231_LEFT_MIC_INPUT]); snd_wss_dout(chip, CS4231_RIGHT_MIC_INPUT, - mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]); + mute | chip->image[CS4231_RIGHT_MIC_INPUT]); snd_wss_dout(chip, CS4231_LINE_LEFT_OUTPUT, - mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]); + mute | chip->image[CS4231_LINE_LEFT_OUTPUT]); snd_wss_dout(chip, CS4231_LINE_RIGHT_OUTPUT, - mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]); + mute | chip->image[CS4231_LINE_RIGHT_OUTPUT]); } chip->calibrate_mute = mute; spin_unlock_irqrestore(&chip->reg_lock, flags); -- cgit v1.2.3 From f87426e085cba525d41bd7639121e2b74fb7e50c Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Tue, 19 Aug 2008 21:51:49 +0200 Subject: ALSA: opl3sa2: replace nd_opl3sa2_info_xxx() with snd_wss_info_xxx() Replace snd_opl3sa2_info_xxx() with snd_wss_info_xxx(). Drop check of card->private_data which cannot be NULL if card is not NULL (spotted by Rene Herman). Signed-off-by: Krzysztof Helt Reviewed-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/opl3sa2.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 1ac29270a402..58c972b2af03 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -300,7 +300,7 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) struct snd_opl3sa2 *chip; int handled = 0; - if (card == NULL || card->private_data == NULL) + if (card == NULL) return IRQ_NONE; chip = card->private_data; @@ -338,29 +338,18 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) #define OPL3SA2_SINGLE(xname, xindex, reg, shift, mask, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_opl3sa2_info_single, \ + .info = snd_wss_info_single, \ .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \ .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } #define OPL3SA2_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ .name = xname, .index = xindex, \ - .info = snd_opl3sa2_info_single, \ + .info = snd_wss_info_single, \ .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \ .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \ .tlv = { .p = (xtlv) } } -static int snd_opl3sa2_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 16) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol); @@ -404,29 +393,18 @@ static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_ #define OPL3SA2_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_opl3sa2_info_double, \ + .info = snd_wss_info_double, \ .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \ .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } #define OPL3SA2_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ .name = xname, .index = xindex, \ - .info = snd_opl3sa2_info_double, \ + .info = snd_wss_info_double, \ .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \ .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \ .tlv = { .p = (xtlv) } } -static int snd_opl3sa2_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 24) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol); -- cgit v1.2.3 From 36463a9660a69018c98f6bde93183a523667e598 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Thu, 21 Aug 2008 23:07:43 +0200 Subject: ALSA: snd-ad1816a: add different TerraTec EWS64 S model Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1816a/ad1816a.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/isa') diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 68f1260b5602..77524244a846 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -83,8 +83,10 @@ static struct pnp_card_device_id snd_ad1816a_pnpids[] = { { .id = "MDK1605", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, /* Shark Predator ISA - added by Ken Arromdee */ { .id = "SMM7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, - /* Analog Devices AD1816A - Terratec AudioSystem EWS64S */ + /* Analog Devices AD1816A - Terratec AudioSystem EWS64 S */ { .id = "TER1112", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, + /* Analog Devices AD1816A - Terratec AudioSystem EWS64 S */ + { .id = "TER1112", .devs = { { .id = "TER1100" }, { .id = "TER1101" } } }, /* Analog Devices AD1816A - Terratec Base 64 */ { .id = "TER1411", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, /* end */ -- cgit v1.2.3 From f83a59c3c15471e866b6af09f82a9ac1eb76fce7 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 24 Aug 2008 18:08:03 +0200 Subject: ALSA: wss_lib: do not mess mixer settings during probe Use the wss_dout function which does not mess shadowed register values during chip probing. Otherwise, user ends up with stupid mixer settings after driver loading. Signed-off-by: Krzysztof Helt Acked-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/wss/wss_lib.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 2a5defa5e636..3d6c5f2838af 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1162,9 +1162,9 @@ static int snd_ad1848_probe(struct snd_wss *chip) spin_lock_irqsave(&chip->reg_lock, flags); /* set CS423x MODE 1 */ - snd_wss_out(chip, CS4231_MISC_INFO, 0); + snd_wss_dout(chip, CS4231_MISC_INFO, 0); - snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x45); /* 0x55 & ~0x10 */ + snd_wss_dout(chip, CS4231_RIGHT_INPUT, 0x45); /* 0x55 & ~0x10 */ r = snd_wss_in(chip, CS4231_RIGHT_INPUT); if (r != 0x45) { /* RMGE always high on AD1847 */ @@ -1174,7 +1174,7 @@ static int snd_ad1848_probe(struct snd_wss *chip) } hardware = WSS_HW_AD1847; } else { - snd_wss_out(chip, CS4231_LEFT_INPUT, 0xaa); + snd_wss_dout(chip, CS4231_LEFT_INPUT, 0xaa); r = snd_wss_in(chip, CS4231_LEFT_INPUT); /* L/RMGE always low on AT2320 */ if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) { @@ -1199,7 +1199,7 @@ static int snd_ad1848_probe(struct snd_wss *chip) r = snd_wss_in(chip, CS4231_MISC_INFO); /* set CS423x MODE 2 */ - snd_wss_out(chip, CS4231_MISC_INFO, CS4231_MODE2); + snd_wss_dout(chip, CS4231_MISC_INFO, CS4231_MODE2); for (i = 0; i < 16; i++) { if (snd_wss_in(chip, i) != snd_wss_in(chip, 16 + i)) { /* we have more than 16 registers: check ID */ @@ -1221,7 +1221,7 @@ static int snd_ad1848_probe(struct snd_wss *chip) else chip->hardware = WSS_HW_AD1848; out_mode: - snd_wss_out(chip, CS4231_MISC_INFO, 0); + snd_wss_dout(chip, CS4231_MISC_INFO, 0); out: spin_unlock_irqrestore(&chip->reg_lock, flags); return err; -- cgit v1.2.3 From ac68c16a44df6dd9edfde31917ae304526f60398 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 27 Aug 2008 15:31:03 +0200 Subject: ALSA: remove obsolete *_FIRMARE_IN_KERNEL in isa/Kconfig Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/isa') diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index ec80444c2a96..660beb41f767 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -360,7 +360,7 @@ config SND_SBAWE config SND_SB16_CSP bool "Sound Blaster 16/AWE CSP support" depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) - select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL + select FW_LOADER help Say Y here to include support for the CSP core. This special coprocessor can do variable tasks like various compression and -- cgit v1.2.3 From ea88663cdcf64bfc14feaf033e902ce3c432156e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 4 Sep 2008 09:20:40 +0200 Subject: ALSA: remove stale files Empty files remained likely due to wrong patching. Remove them now. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/isa/ad1848/ad1848_lib.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 sound/isa/ad1848/ad1848_lib.c (limited to 'sound/isa') diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c deleted file mode 100644 index e69de29bb2d1..000000000000 -- cgit v1.2.3