^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for AMD InterWave soundcard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * 1999/07/22 Erik Inge Bolso <knan@mo.himolde.no>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * * mixer group handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/isa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/gus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/wss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/tea6330t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define SNDRV_LEGACY_FIND_FREE_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define SNDRV_LEGACY_FIND_FREE_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifndef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) MODULE_DESCRIPTION("AMD InterWave");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Plug & Play},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) "{STB,SoundRage32},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) "{MED,MED3210},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) "{Dynasonix,Dynasonix Pro},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) "{Panasonic,PCA761AW}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_DESCRIPTION("AMD InterWave STB with TEA6330T");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_SUPPORTED_DEVICE("{{AMD,InterWave STB with TEA6330T}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x210,0x220,0x230,0x240,0x250,0x260 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static long port_tc[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x350,0x360,0x370,0x380 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int midi[SNDRV_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int effect[SNDRV_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PFX "interwave-stb: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define INTERWAVE_DRIVER "snd_interwave_stb"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define INTERWAVE_PNP_DRIVER "interwave-stb"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PFX "interwave: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define INTERWAVE_DRIVER "snd_interwave"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define INTERWAVE_PNP_DRIVER "interwave"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) MODULE_PARM_DESC(index, "Index value for InterWave soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MODULE_PARM_DESC(id, "ID string for InterWave soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MODULE_PARM_DESC(enable, "Enable InterWave soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) module_param_array(isapnp, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) module_param_hw_array(port, long, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MODULE_PARM_DESC(port, "Port # for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) module_param_hw_array(port_tc, long, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MODULE_PARM_DESC(port_tc, "Tone control (TEA6330T - i2c bus) port # for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) module_param_hw_array(irq, int, irq, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MODULE_PARM_DESC(irq, "IRQ # for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) module_param_hw_array(dma1, int, dma, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MODULE_PARM_DESC(dma1, "DMA1 # for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) module_param_hw_array(dma2, int, dma, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MODULE_PARM_DESC(dma2, "DMA2 # for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) module_param_array(joystick_dac, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) module_param_array(midi, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) MODULE_PARM_DESC(midi, "MIDI UART enable for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) module_param_array(pcm_channels, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) module_param_array(effect, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct snd_interwave {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct snd_gus_card *gus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct snd_wss *wss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct resource *i2c_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned short gus_status_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned short pcm_status_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct pnp_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct pnp_dev *devtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int isa_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int pnp_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static const struct pnp_card_device_id snd_interwave_pnpids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifndef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Gravis UltraSound Plug & Play */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) { .id = "GRV0001", .devs = { { .id = "GRV0000" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* STB SoundRage32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { .id = "STB011a", .devs = { { .id = "STB0010" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* MED3210 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { .id = "DXP3201", .devs = { { .id = "DXP0010" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Dynasonic Pro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* This device also have CDC1117:DynaSonix Pro Audio Effects Processor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { .id = "CDC1111", .devs = { { .id = "CDC1112" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Panasonic PCA761AW Audio Card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { .id = "ADV55ff", .devs = { { .id = "ADV0010" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* InterWave STB without TEA6330T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { .id = "ADV550a", .devs = { { .id = "ADV0010" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* InterWave STB with TEA6330T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { .id = "ADV550a", .devs = { { .id = "ADV0010" }, { .id = "ADV0015" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { .id = "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) MODULE_DEVICE_TABLE(pnp_card, snd_interwave_pnpids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned long port = bus->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) outb((data << 1) | ctrl, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned long port = bus->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned char res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) res = inb(port) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned long port = bus->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned char res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) res = (inb(port) & 2) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static struct snd_i2c_bit_ops snd_interwave_i2c_bit_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .setlines = snd_interwave_i2c_setlines,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .getclock = snd_interwave_i2c_getclockline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .getdata = snd_interwave_i2c_getdataline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int snd_interwave_detect_stb(struct snd_interwave *iwcard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct snd_gus_card *gus, int dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct snd_i2c_bus **rbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned long port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct snd_i2c_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct snd_card *card = iwcard->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) char name[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *rbus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) port = port_tc[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (port == SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) port = 0x350;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (gus->gf1.port == 0x250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) port = 0x360;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) while (port <= 0x380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) port += 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (iwcard->i2c_res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) snd_printk(KERN_ERR "interwave: can't grab i2c bus port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) sprintf(name, "InterWave-%i", card->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if ((err = snd_i2c_bus_create(card, name, NULL, &bus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) bus->private_value = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) bus->hw_ops.bit = &snd_interwave_i2c_bit_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if ((err = snd_tea6330t_detect(bus, 0)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *rbus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int snd_interwave_detect(struct snd_interwave *iwcard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct snd_gus_card *gus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) , struct snd_i2c_bus **rbus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned char rev1, rev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) snd_printdd("[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n", gus->gf1.port, rev1, rev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if ((rev1 & 0xf0) == (rev2 & 0xf0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) (rev1 & 0x0f) != (rev2 & 0x0f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) snd_printdd("[0x%lx] InterWave check - passed\n", gus->gf1.port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) gus->interwave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) strcpy(gus->card->shortname, "AMD InterWave");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) gus->revision = rev1 >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #ifndef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return 0; /* ok.. We have an InterWave board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return snd_interwave_detect_stb(iwcard, gus, dev, rbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) snd_printdd("[0x%lx] InterWave check - failed\n", gus->gf1.port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct snd_interwave *iwcard = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int loop, max = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) loop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (inb(iwcard->gus_status_reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) snd_gus_interrupt(irq, iwcard->gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) loop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) snd_wss_interrupt(irq, iwcard->wss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) loop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) } while (loop && --max > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static void snd_interwave_reset(struct snd_gus_card *gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void snd_interwave_bank_sizes(struct snd_gus_card *gus, int *sizes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) unsigned int local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned char d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for (idx = 0; idx < 4; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) sizes[idx] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) d = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) for (local = idx << 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) local < (idx << 22) + 0x400000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) local += 0x40000, d++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) snd_gf1_poke(gus, local, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) snd_gf1_poke(gus, local + 1, d + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) printk(KERN_DEBUG "d = 0x%x, local = 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) "local + 1 = 0x%x, idx << 22 = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) snd_gf1_peek(gus, local),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) snd_gf1_peek(gus, local + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) snd_gf1_peek(gus, idx << 22));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (snd_gf1_peek(gus, local) != d ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) snd_gf1_peek(gus, local + 1) != d + 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) snd_gf1_peek(gus, idx << 22) != 0x55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) sizes[idx]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) printk(KERN_DEBUG "sizes: %i %i %i %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sizes[0], sizes[1], sizes[2], sizes[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct rom_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* 000 */ unsigned char iwave[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* 008 */ unsigned char rom_hdr_revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* 009 */ unsigned char series_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* 010 */ unsigned char series_name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* 026 */ unsigned char date[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* 036 */ unsigned short vendor_revision_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* 038 */ unsigned short vendor_revision_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* 040 */ unsigned int rom_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* 044 */ unsigned char copyright[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* 172 */ unsigned char vendor_name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* 236 */ unsigned char rom_description[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* 364 */ unsigned char pad[147];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* 511 */ unsigned char csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static void snd_interwave_detect_memory(struct snd_gus_card *gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static const unsigned int lmc[13] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 0x00000001, 0x00000101, 0x01010101, 0x00000401,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 0x04040401, 0x00040101, 0x04040101, 0x00000004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 0x00000404, 0x04040404, 0x00000010, 0x00001010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 0x10101010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int bank_pos, pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) unsigned int i, lmct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int psizes[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) unsigned char iwave[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) unsigned char csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) snd_interwave_reset(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) snd_gf1_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01); /* enhanced mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01); /* DRAM I/O cycles selected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff10) | 0x004c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* ok.. simple test of memory size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) pages = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) snd_gf1_poke(gus, 0, 0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) snd_gf1_poke(gus, 1, 0xaa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (snd_gf1_peek(gus, 0) == 0x55 && snd_gf1_peek(gus, 1) == 0xaa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (0) /* ok.. for testing of 0k RAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) snd_interwave_bank_sizes(gus, psizes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) lmct = (psizes[3] << 24) | (psizes[2] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) (psizes[1] << 8) | psizes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) printk(KERN_DEBUG "lmct = 0x%08x\n", lmct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) for (i = 0; i < ARRAY_SIZE(lmc); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (lmct == lmc[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) printk(KERN_DEBUG "found !!! %i\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) snd_interwave_bank_sizes(gus, psizes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (i >= ARRAY_SIZE(lmc) && !gus->gf1.enh_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) gus->gf1.mem_alloc.banks_8[i].address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) gus->gf1.mem_alloc.banks_16[i].address = i << 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) gus->gf1.mem_alloc.banks_8[i].size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) gus->gf1.mem_alloc.banks_16[i].size = psizes[i] << 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pages += psizes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) pages <<= 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) gus->gf1.memory = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x03); /* select ROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff1f) | (4 << 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) gus->gf1.rom_banks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) gus->gf1.rom_memory = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) for (bank_pos = 0; bank_pos < 16L * 1024L * 1024L; bank_pos += 4L * 1024L * 1024L) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) for (i = 0; i < 8; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) iwave[i] = snd_gf1_peek(gus, bank_pos + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (strncmp(iwave, "INTRWAVE", 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) continue; /* first check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) for (i = 0; i < sizeof(struct rom_hdr); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) csum += snd_gf1_peek(gus, bank_pos + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (csum != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) continue; /* not valid rom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) gus->gf1.rom_banks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) gus->gf1.rom_present |= 1 << (bank_pos >> 22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) gus->gf1.rom_memory = snd_gf1_peek(gus, bank_pos + 40) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (snd_gf1_peek(gus, bank_pos + 41) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) (snd_gf1_peek(gus, bank_pos + 42) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) (snd_gf1_peek(gus, bank_pos + 43) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (gus->gf1.rom_memory > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) gus->card->type = SNDRV_CARD_TYPE_IW_DYNASONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x00); /* select RAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (!gus->gf1.enh_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) snd_interwave_reset(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static void snd_interwave_init(int dev, struct snd_gus_card *gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* ok.. some InterWave specific initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) snd_gf1_write8(gus, SNDRV_GF1_GB_COMPATIBILITY, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) snd_gf1_write8(gus, SNDRV_GF1_GB_DECODE_CONTROL, 0x49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) snd_gf1_write8(gus, SNDRV_GF1_GB_EMULATION_IRQ, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) gus->equal_irq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) gus->codec_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) gus->interwave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) gus->max_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) gus->joystick_dac = joystick_dac[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static const struct snd_kcontrol_new snd_interwave_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) WSS_DOUBLE("Master Playback Switch", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) WSS_DOUBLE("Master Playback Volume", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) WSS_DOUBLE("Mic Playback Switch", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) WSS_DOUBLE("Mic Playback Volume", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static int snd_interwave_mixer(struct snd_wss *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct snd_card *card = chip->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct snd_ctl_elem_id id1, id2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) memset(&id1, 0, sizeof(id1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) memset(&id2, 0, sizeof(id2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* remove mono microphone controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) strcpy(id1.name, "Mic Playback Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if ((err = snd_ctl_remove_id(card, &id1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) strcpy(id1.name, "Mic Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if ((err = snd_ctl_remove_id(card, &id1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* add new master and mic controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) snd_wss_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* reassign AUXA to SYNTHESIZER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) strcpy(id1.name, "Aux Playback Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) strcpy(id2.name, "Synth Playback Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) strcpy(id1.name, "Aux Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) strcpy(id2.name, "Synth Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* reassign AUXB to CD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) strcpy(id2.name, "CD Playback Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) strcpy(id1.name, "Aux Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) strcpy(id2.name, "CD Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int snd_interwave_pnp(int dev, struct snd_interwave *iwcard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct pnp_card_link *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) const struct pnp_card_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct pnp_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (iwcard->dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) iwcard->devtc = pnp_request_card_device(card, id->devs[1].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (iwcard->devtc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* Synth & Codec initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pdev = iwcard->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) err = pnp_activate_dev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) snd_printk(KERN_ERR "InterWave PnP configure failure (out of resources?)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (pnp_port_start(pdev, 0) + 0x100 != pnp_port_start(pdev, 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) pnp_port_start(pdev, 0) + 0x10c != pnp_port_start(pdev, 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) snd_printk(KERN_ERR "PnP configure failure (wrong ports)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) port[dev] = pnp_port_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dma1[dev] = pnp_dma(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (dma2[dev] >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dma2[dev] = pnp_dma(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) irq[dev] = pnp_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) snd_printdd("isapnp IW: sb port=0x%llx, gf1 port=0x%llx, codec port=0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) (unsigned long long)pnp_port_start(pdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) (unsigned long long)pnp_port_start(pdev, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) (unsigned long long)pnp_port_start(pdev, 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Tone Control initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) pdev = iwcard->devtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) err = pnp_activate_dev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) snd_printk(KERN_ERR "InterWave ToneControl PnP configure failure (out of resources?)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) port_tc[dev] = pnp_port_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) snd_printdd("isapnp IW: tone control port=0x%lx\n", port_tc[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static void snd_interwave_free(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct snd_interwave *iwcard = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (iwcard == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) release_and_free_resource(iwcard->i2c_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (iwcard->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) free_irq(iwcard->irq, (void *)iwcard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int snd_interwave_card_new(struct device *pdev, int dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct snd_card **cardp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct snd_interwave *iwcard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sizeof(struct snd_interwave), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) iwcard = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) iwcard->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) iwcard->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) card->private_free = snd_interwave_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) *cardp = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int snd_interwave_probe(struct snd_card *card, int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int xirq, xdma1, xdma2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct snd_interwave *iwcard = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct snd_wss *wss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct snd_gus_card *gus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct snd_i2c_bus *i2c_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) xirq = irq[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) xdma1 = dma1[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) xdma2 = dma2[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if ((err = snd_gus_create(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) port[dev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) -xirq, xdma1, xdma2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 0, 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pcm_channels[dev], effect[dev], &gus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if ((err = snd_interwave_detect(iwcard, gus, dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) , &i2c_bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) )) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) iwcard->gus_status_reg = gus->gf1.reg_irqstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) snd_interwave_init(dev, gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) snd_interwave_detect_memory(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if ((err = snd_gus_initialize(gus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (request_irq(xirq, snd_interwave_interrupt, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) "InterWave", iwcard)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) iwcard->irq = xirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) card->sync_irq = iwcard->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) err = snd_wss_create(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) gus->gf1.port + 0x10c, -1, xirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) xdma2 < 0 ? xdma1 : xdma2, xdma1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) WSS_HW_INTERWAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) WSS_HWSHARE_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) WSS_HWSHARE_DMA1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) WSS_HWSHARE_DMA2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) &wss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) err = snd_wss_pcm(wss, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) sprintf(wss->pcm->name + strlen(wss->pcm->name), " rev %c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) gus->revision + 'A');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) strcat(wss->pcm->name, " (codec)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) err = snd_wss_timer(wss, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) err = snd_wss_mixer(wss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (pcm_channels[dev] > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) err = snd_gf1_pcm_new(gus, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) err = snd_interwave_mixer(wss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) #ifdef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct snd_ctl_elem_id id1, id2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) memset(&id1, 0, sizeof(id1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) memset(&id2, 0, sizeof(id2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) strcpy(id1.name, "Master Playback Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) strcpy(id2.name, id1.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) id2.index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) strcpy(id1.name, "Master Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) strcpy(id2.name, id1.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) gus->uart_enable = midi[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if ((err = snd_gf1_rawmidi_new(gus, 0)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #ifndef SNDRV_STB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) str = "AMD InterWave";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) str = "Dynasonic 3-D";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) str = "InterWave STB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) strcpy(card->driver, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) strcpy(card->shortname, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sprintf(card->longname, "%s at 0x%lx, irq %i, dma %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) gus->gf1.port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) xirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) xdma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (xdma2 >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) iwcard->wss = wss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) iwcard->gus = gus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static int snd_interwave_isa_probe1(int dev, struct device *devptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) err = snd_interwave_card_new(devptr, dev, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if ((err = snd_interwave_probe(card, dev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dev_set_drvdata(devptr, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int snd_interwave_isa_match(struct device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!enable[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (isapnp[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static int snd_interwave_isa_probe(struct device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static const int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static const int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (irq[dev] == SNDRV_AUTO_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (dma1[dev] == SNDRV_AUTO_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (dma2[dev] == SNDRV_AUTO_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (port[dev] != SNDRV_AUTO_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return snd_interwave_isa_probe1(dev, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static const long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) port[dev] = possible_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) err = snd_interwave_isa_probe1(dev, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (! err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) snd_card_free(dev_get_drvdata(devptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static struct isa_driver snd_interwave_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .match = snd_interwave_isa_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .probe = snd_interwave_isa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .remove = snd_interwave_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* FIXME: suspend,resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) .name = INTERWAVE_DRIVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int snd_interwave_pnp_detect(struct pnp_card_link *pcard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) const struct pnp_card_device_id *pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) for ( ; dev < SNDRV_CARDS; dev++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (enable[dev] && isapnp[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) res = snd_interwave_card_new(&pcard->card->dev, dev, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if ((res = snd_interwave_probe(card, dev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) pnp_set_card_drvdata(pcard, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static void snd_interwave_pnp_remove(struct pnp_card_link *pcard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) snd_card_free(pnp_get_card_drvdata(pcard));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) pnp_set_card_drvdata(pcard, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static struct pnp_card_driver interwave_pnpc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .flags = PNP_DRIVER_RES_DISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .name = INTERWAVE_PNP_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .id_table = snd_interwave_pnpids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .probe = snd_interwave_pnp_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) .remove = snd_interwave_pnp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* FIXME: suspend,resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static int __init alsa_card_interwave_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) isa_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) err = pnp_register_card_driver(&interwave_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) pnp_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (isa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static void __exit alsa_card_interwave_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (pnp_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) pnp_unregister_card_driver(&interwave_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (isa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) isa_unregister_driver(&snd_interwave_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) module_init(alsa_card_interwave_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) module_exit(alsa_card_interwave_exit)