Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)