Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
0004  *  Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
0005  *            Jaroslav Kysela <perex@perex.cz>
0006  *  Copyright (C) 2002, 2008 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
0007  *
0008  *  Framework borrowed from Massimo Piccioni's card-als100.c.
0009  *
0010  * NOTES
0011  *
0012  *  Since Avance does not provide any meaningful documentation, and I
0013  *  bought an ALS4000 based soundcard, I was forced to base this driver
0014  *  on reverse engineering.
0015  *
0016  *  Note: this is no longer true (thank you!):
0017  *  pretty verbose chip docu (ALS4000a.PDF) can be found on the ALSA web site.
0018  *  Page numbers stated anywhere below with the "SPECS_PAGE:" tag
0019  *  refer to: ALS4000a.PDF specs Ver 1.0, May 28th, 1998.
0020  *
0021  *  The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
0022  *  ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport 
0023  *  interface. These subsystems can be mapped into ISA io-port space, 
0024  *  using the PCI-interface. In addition, the PCI-bit provides DMA and IRQ 
0025  *  services to the subsystems.
0026  * 
0027  * While ALS4000 is very similar to a SoundBlaster, the differences in
0028  * DMA and capturing require more changes to the SoundBlaster than
0029  * desirable, so I made this separate driver.
0030  * 
0031  * The ALS4000 can do real full duplex playback/capture.
0032  *
0033  * FMDAC:
0034  * - 0x4f -> port 0x14
0035  * - port 0x15 |= 1
0036  *
0037  * Enable/disable 3D sound:
0038  * - 0x50 -> port 0x14
0039  * - change bit 6 (0x40) of port 0x15
0040  *
0041  * Set QSound:
0042  * - 0xdb -> port 0x14
0043  * - set port 0x15:
0044  *   0x3e (mode 3), 0x3c (mode 2), 0x3a (mode 1), 0x38 (mode 0)
0045  *
0046  * Set KSound:
0047  * - value -> some port 0x0c0d
0048  *
0049  * ToDo:
0050  * - by default, don't enable legacy game and use PCI game I/O
0051  * - power management? (card can do voice wakeup according to datasheet!!)
0052  */
0053 
0054 #include <linux/io.h>
0055 #include <linux/init.h>
0056 #include <linux/pci.h>
0057 #include <linux/gameport.h>
0058 #include <linux/module.h>
0059 #include <linux/dma-mapping.h>
0060 #include <sound/core.h>
0061 #include <sound/pcm.h>
0062 #include <sound/rawmidi.h>
0063 #include <sound/mpu401.h>
0064 #include <sound/opl3.h>
0065 #include <sound/sb.h>
0066 #include <sound/initval.h>
0067 
0068 MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>, Andreas Mohr");
0069 MODULE_DESCRIPTION("Avance Logic ALS4000");
0070 MODULE_LICENSE("GPL");
0071 
0072 #if IS_REACHABLE(CONFIG_GAMEPORT)
0073 #define SUPPORT_JOYSTICK 1
0074 #endif
0075 
0076 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;  /* Index 0-MAX */
0077 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;   /* ID for this card */
0078 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
0079 #ifdef SUPPORT_JOYSTICK
0080 static int joystick_port[SNDRV_CARDS];
0081 #endif
0082 
0083 module_param_array(index, int, NULL, 0444);
0084 MODULE_PARM_DESC(index, "Index value for ALS4000 soundcard.");
0085 module_param_array(id, charp, NULL, 0444);
0086 MODULE_PARM_DESC(id, "ID string for ALS4000 soundcard.");
0087 module_param_array(enable, bool, NULL, 0444);
0088 MODULE_PARM_DESC(enable, "Enable ALS4000 soundcard.");
0089 #ifdef SUPPORT_JOYSTICK
0090 module_param_hw_array(joystick_port, int, ioport, NULL, 0444);
0091 MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 = disabled)");
0092 #endif
0093 
0094 struct snd_card_als4000 {
0095     /* most frequent access first */
0096     unsigned long iobase;
0097     struct pci_dev *pci;
0098     struct snd_sb *chip;
0099 #ifdef SUPPORT_JOYSTICK
0100     struct gameport *gameport;
0101 #endif
0102 };
0103 
0104 static const struct pci_device_id snd_als4000_ids[] = {
0105     { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* ALS4000 */
0106     { 0, }
0107 };
0108 
0109 MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
0110 
0111 enum als4k_iobase_t {
0112     /* IOx: B == Byte, W = Word, D = DWord; SPECS_PAGE: 37 */
0113     ALS4K_IOD_00_AC97_ACCESS = 0x00,
0114     ALS4K_IOW_04_AC97_READ = 0x04,
0115     ALS4K_IOB_06_AC97_STATUS = 0x06,
0116     ALS4K_IOB_07_IRQSTATUS = 0x07,
0117     ALS4K_IOD_08_GCR_DATA = 0x08,
0118     ALS4K_IOB_0C_GCR_INDEX = 0x0c,
0119     ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU = 0x0e,
0120     ALS4K_IOB_10_ADLIB_ADDR0 = 0x10,
0121     ALS4K_IOB_11_ADLIB_ADDR1 = 0x11,
0122     ALS4K_IOB_12_ADLIB_ADDR2 = 0x12,
0123     ALS4K_IOB_13_ADLIB_ADDR3 = 0x13,
0124     ALS4K_IOB_14_MIXER_INDEX = 0x14,
0125     ALS4K_IOB_15_MIXER_DATA = 0x15,
0126     ALS4K_IOB_16_ESP_RESET = 0x16,
0127     ALS4K_IOB_16_ACK_FOR_CR1E = 0x16, /* 2nd function */
0128     ALS4K_IOB_18_OPL_ADDR0 = 0x18,
0129     ALS4K_IOB_19_OPL_ADDR1 = 0x19,
0130     ALS4K_IOB_1A_ESP_RD_DATA = 0x1a,
0131     ALS4K_IOB_1C_ESP_CMD_DATA = 0x1c,
0132     ALS4K_IOB_1C_ESP_WR_STATUS = 0x1c, /* 2nd function */
0133     ALS4K_IOB_1E_ESP_RD_STATUS8 = 0x1e,
0134     ALS4K_IOB_1F_ESP_RD_STATUS16 = 0x1f,
0135     ALS4K_IOB_20_ESP_GAMEPORT_200 = 0x20,
0136     ALS4K_IOB_21_ESP_GAMEPORT_201 = 0x21,
0137     ALS4K_IOB_30_MIDI_DATA = 0x30,
0138     ALS4K_IOB_31_MIDI_STATUS = 0x31,
0139     ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */
0140 };
0141 
0142 enum als4k_iobase_0e_t {
0143     ALS4K_IOB_0E_MPU_IRQ = 0x10,
0144     ALS4K_IOB_0E_CR1E_IRQ = 0x40,
0145     ALS4K_IOB_0E_SB_DMA_IRQ = 0x80,
0146 };
0147 
0148 enum als4k_gcr_t { /* all registers 32bit wide; SPECS_PAGE: 38 to 42 */
0149     ALS4K_GCR8C_MISC_CTRL = 0x8c,
0150     ALS4K_GCR90_TEST_MODE_REG = 0x90,
0151     ALS4K_GCR91_DMA0_ADDR = 0x91,
0152     ALS4K_GCR92_DMA0_MODE_COUNT = 0x92,
0153     ALS4K_GCR93_DMA1_ADDR = 0x93,
0154     ALS4K_GCR94_DMA1_MODE_COUNT = 0x94,
0155     ALS4K_GCR95_DMA3_ADDR = 0x95,
0156     ALS4K_GCR96_DMA3_MODE_COUNT = 0x96,
0157     ALS4K_GCR99_DMA_EMULATION_CTRL = 0x99,
0158     ALS4K_GCRA0_FIFO1_CURRENT_ADDR = 0xa0,
0159     ALS4K_GCRA1_FIFO1_STATUS_BYTECOUNT = 0xa1,
0160     ALS4K_GCRA2_FIFO2_PCIADDR = 0xa2,
0161     ALS4K_GCRA3_FIFO2_COUNT = 0xa3,
0162     ALS4K_GCRA4_FIFO2_CURRENT_ADDR = 0xa4,
0163     ALS4K_GCRA5_FIFO1_STATUS_BYTECOUNT = 0xa5,
0164     ALS4K_GCRA6_PM_CTRL = 0xa6,
0165     ALS4K_GCRA7_PCI_ACCESS_STORAGE = 0xa7,
0166     ALS4K_GCRA8_LEGACY_CFG1 = 0xa8,
0167     ALS4K_GCRA9_LEGACY_CFG2 = 0xa9,
0168     ALS4K_GCRFF_DUMMY_SCRATCH = 0xff,
0169 };
0170 
0171 enum als4k_gcr8c_t {
0172     ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE = 0x8000,
0173     ALS4K_GCR8C_CHIP_REV_MASK = 0xf0000
0174 };
0175 
0176 static inline void snd_als4k_iobase_writeb(unsigned long iobase,
0177                         enum als4k_iobase_t reg,
0178                         u8 val)
0179 {
0180     outb(val, iobase + reg);
0181 }
0182 
0183 static inline void snd_als4k_iobase_writel(unsigned long iobase,
0184                         enum als4k_iobase_t reg,
0185                         u32 val)
0186 {
0187     outl(val, iobase + reg);
0188 }
0189 
0190 static inline u8 snd_als4k_iobase_readb(unsigned long iobase,
0191                         enum als4k_iobase_t reg)
0192 {
0193     return inb(iobase + reg);
0194 }
0195 
0196 static inline u32 snd_als4k_iobase_readl(unsigned long iobase,
0197                         enum als4k_iobase_t reg)
0198 {
0199     return inl(iobase + reg);
0200 }
0201 
0202 static inline void snd_als4k_gcr_write_addr(unsigned long iobase,
0203                          enum als4k_gcr_t reg,
0204                          u32 val)
0205 {
0206     snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
0207     snd_als4k_iobase_writel(iobase, ALS4K_IOD_08_GCR_DATA, val);
0208 }
0209 
0210 static inline void snd_als4k_gcr_write(struct snd_sb *sb,
0211                      enum als4k_gcr_t reg,
0212                      u32 val)
0213 {
0214     snd_als4k_gcr_write_addr(sb->alt_port, reg, val);
0215 }   
0216 
0217 static inline u32 snd_als4k_gcr_read_addr(unsigned long iobase,
0218                          enum als4k_gcr_t reg)
0219 {
0220     /* SPECS_PAGE: 37/38 */
0221     snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
0222     return snd_als4k_iobase_readl(iobase, ALS4K_IOD_08_GCR_DATA);
0223 }
0224 
0225 static inline u32 snd_als4k_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg)
0226 {
0227     return snd_als4k_gcr_read_addr(sb->alt_port, reg);
0228 }
0229 
0230 enum als4k_cr_t { /* all registers 8bit wide; SPECS_PAGE: 20 to 23 */
0231     ALS4K_CR0_SB_CONFIG = 0x00,
0232     ALS4K_CR2_MISC_CONTROL = 0x02,
0233     ALS4K_CR3_CONFIGURATION = 0x03,
0234     ALS4K_CR17_FIFO_STATUS = 0x17,
0235     ALS4K_CR18_ESP_MAJOR_VERSION = 0x18,
0236     ALS4K_CR19_ESP_MINOR_VERSION = 0x19,
0237     ALS4K_CR1A_MPU401_UART_MODE_CONTROL = 0x1a,
0238     ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO = 0x1c,
0239     ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI = 0x1d,
0240     ALS4K_CR1E_FIFO2_CONTROL = 0x1e, /* secondary PCM FIFO (recording) */
0241     ALS4K_CR3A_MISC_CONTROL = 0x3a,
0242     ALS4K_CR3B_CRC32_BYTE0 = 0x3b, /* for testing, activate via CR3A */
0243     ALS4K_CR3C_CRC32_BYTE1 = 0x3c,
0244     ALS4K_CR3D_CRC32_BYTE2 = 0x3d,
0245     ALS4K_CR3E_CRC32_BYTE3 = 0x3e,
0246 };
0247 
0248 enum als4k_cr0_t {
0249     ALS4K_CR0_DMA_CONTIN_MODE_CTRL = 0x02, /* IRQ/FIFO controlled for 0/1 */
0250     ALS4K_CR0_DMA_90H_MODE_CTRL = 0x04, /* IRQ/FIFO controlled for 0/1 */
0251     ALS4K_CR0_MX80_81_REG_WRITE_ENABLE = 0x80,
0252 };
0253 
0254 static inline void snd_als4_cr_write(struct snd_sb *chip,
0255                     enum als4k_cr_t reg,
0256                     u8 data)
0257 {
0258     /* Control Register is reg | 0xc0 (bit 7, 6 set) on sbmixer_index
0259      * NOTE: assumes chip->mixer_lock to be locked externally already!
0260      * SPECS_PAGE: 6 */
0261     snd_sbmixer_write(chip, reg | 0xc0, data);
0262 }
0263 
0264 static inline u8 snd_als4_cr_read(struct snd_sb *chip,
0265                     enum als4k_cr_t reg)
0266 {
0267     /* NOTE: assumes chip->mixer_lock to be locked externally already! */
0268     return snd_sbmixer_read(chip, reg | 0xc0);
0269 }
0270 
0271 
0272 
0273 static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
0274 {
0275     if (!(chip->mode & SB_RATE_LOCK)) {
0276         snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
0277         snd_sbdsp_command(chip, rate>>8);
0278         snd_sbdsp_command(chip, rate);
0279     }
0280 }
0281 
0282 static inline void snd_als4000_set_capture_dma(struct snd_sb *chip,
0283                            dma_addr_t addr, unsigned size)
0284 {
0285     /* SPECS_PAGE: 40 */
0286     snd_als4k_gcr_write(chip, ALS4K_GCRA2_FIFO2_PCIADDR, addr);
0287     snd_als4k_gcr_write(chip, ALS4K_GCRA3_FIFO2_COUNT, (size-1));
0288 }
0289 
0290 static inline void snd_als4000_set_playback_dma(struct snd_sb *chip,
0291                         dma_addr_t addr,
0292                         unsigned size)
0293 {
0294     /* SPECS_PAGE: 38 */
0295     snd_als4k_gcr_write(chip, ALS4K_GCR91_DMA0_ADDR, addr);
0296     snd_als4k_gcr_write(chip, ALS4K_GCR92_DMA0_MODE_COUNT,
0297                             (size-1)|0x180000);
0298 }
0299 
0300 #define ALS4000_FORMAT_SIGNED   (1<<0)
0301 #define ALS4000_FORMAT_16BIT    (1<<1)
0302 #define ALS4000_FORMAT_STEREO   (1<<2)
0303 
0304 static int snd_als4000_get_format(struct snd_pcm_runtime *runtime)
0305 {
0306     int result;
0307 
0308     result = 0;
0309     if (snd_pcm_format_signed(runtime->format))
0310         result |= ALS4000_FORMAT_SIGNED;
0311     if (snd_pcm_format_physical_width(runtime->format) == 16)
0312         result |= ALS4000_FORMAT_16BIT;
0313     if (runtime->channels > 1)
0314         result |= ALS4000_FORMAT_STEREO;
0315     return result;
0316 }
0317 
0318 /* structure for setting up playback */
0319 static const struct {
0320     unsigned char dsp_cmd, dma_on, dma_off, format;
0321 } playback_cmd_vals[]={
0322 /* ALS4000_FORMAT_U8_MONO */
0323 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_MONO },
0324 /* ALS4000_FORMAT_S8_MONO */    
0325 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_MONO },
0326 /* ALS4000_FORMAT_U16L_MONO */
0327 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_MONO },
0328 /* ALS4000_FORMAT_S16L_MONO */
0329 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_MONO },
0330 /* ALS4000_FORMAT_U8_STEREO */
0331 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_STEREO },
0332 /* ALS4000_FORMAT_S8_STEREO */  
0333 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_STEREO },
0334 /* ALS4000_FORMAT_U16L_STEREO */
0335 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_STEREO },
0336 /* ALS4000_FORMAT_S16L_STEREO */
0337 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_STEREO },
0338 };
0339 #define playback_cmd(chip) (playback_cmd_vals[(chip)->playback_format])
0340 
0341 /* structure for setting up capture */
0342 enum { CMD_WIDTH8=0x04, CMD_SIGNED=0x10, CMD_MONO=0x80, CMD_STEREO=0xA0 };
0343 static const unsigned char capture_cmd_vals[]=
0344 {
0345 CMD_WIDTH8|CMD_MONO,            /* ALS4000_FORMAT_U8_MONO */
0346 CMD_WIDTH8|CMD_SIGNED|CMD_MONO,     /* ALS4000_FORMAT_S8_MONO */    
0347 CMD_MONO,               /* ALS4000_FORMAT_U16L_MONO */
0348 CMD_SIGNED|CMD_MONO,            /* ALS4000_FORMAT_S16L_MONO */
0349 CMD_WIDTH8|CMD_STEREO,          /* ALS4000_FORMAT_U8_STEREO */
0350 CMD_WIDTH8|CMD_SIGNED|CMD_STEREO,   /* ALS4000_FORMAT_S8_STEREO */  
0351 CMD_STEREO,             /* ALS4000_FORMAT_U16L_STEREO */
0352 CMD_SIGNED|CMD_STEREO,          /* ALS4000_FORMAT_S16L_STEREO */
0353 };  
0354 #define capture_cmd(chip) (capture_cmd_vals[(chip)->capture_format])
0355 
0356 static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
0357 {
0358     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0359     struct snd_pcm_runtime *runtime = substream->runtime;
0360     unsigned long size;
0361     unsigned count;
0362 
0363     chip->capture_format = snd_als4000_get_format(runtime);
0364         
0365     size = snd_pcm_lib_buffer_bytes(substream);
0366     count = snd_pcm_lib_period_bytes(substream);
0367     
0368     if (chip->capture_format & ALS4000_FORMAT_16BIT)
0369         count >>= 1;
0370     count--;
0371 
0372     spin_lock_irq(&chip->reg_lock);
0373     snd_als4000_set_rate(chip, runtime->rate);
0374     snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
0375     spin_unlock_irq(&chip->reg_lock);
0376     spin_lock_irq(&chip->mixer_lock);
0377     snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff);
0378     snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8);
0379     spin_unlock_irq(&chip->mixer_lock);
0380     return 0;
0381 }
0382 
0383 static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
0384 {
0385     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0386     struct snd_pcm_runtime *runtime = substream->runtime;
0387     unsigned long size;
0388     unsigned count;
0389 
0390     chip->playback_format = snd_als4000_get_format(runtime);
0391     
0392     size = snd_pcm_lib_buffer_bytes(substream);
0393     count = snd_pcm_lib_period_bytes(substream);
0394     
0395     if (chip->playback_format & ALS4000_FORMAT_16BIT)
0396         count >>= 1;
0397     count--;
0398     
0399     /* FIXME: from second playback on, there's a lot more clicks and pops
0400      * involved here than on first playback. Fiddling with
0401      * tons of different settings didn't help (DMA, speaker on/off,
0402      * reordering, ...). Something seems to get enabled on playback
0403      * that I haven't found out how to disable again, which then causes
0404      * the switching pops to reach the speakers the next time here. */
0405     spin_lock_irq(&chip->reg_lock);
0406     snd_als4000_set_rate(chip, runtime->rate);
0407     snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
0408     
0409     /* SPEAKER_ON not needed, since dma_on seems to also enable speaker */
0410     /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
0411     snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
0412     snd_sbdsp_command(chip, playback_cmd(chip).format);
0413     snd_sbdsp_command(chip, count & 0xff);
0414     snd_sbdsp_command(chip, count >> 8);
0415     snd_sbdsp_command(chip, playback_cmd(chip).dma_off);    
0416     spin_unlock_irq(&chip->reg_lock);
0417     
0418     return 0;
0419 }
0420 
0421 static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int cmd)
0422 {
0423     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0424     int result = 0;
0425     
0426     /* FIXME race condition in here!!!
0427        chip->mode non-atomic update gets consistently protected
0428        by reg_lock always, _except_ for this place!!
0429        Probably need to take reg_lock as outer (or inner??) lock, too.
0430        (or serialize both lock operations? probably not, though... - racy?)
0431     */
0432     spin_lock(&chip->mixer_lock);
0433     switch (cmd) {
0434     case SNDRV_PCM_TRIGGER_START:
0435     case SNDRV_PCM_TRIGGER_RESUME:
0436         chip->mode |= SB_RATE_LOCK_CAPTURE;
0437         snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
0438                              capture_cmd(chip));
0439         break;
0440     case SNDRV_PCM_TRIGGER_STOP:
0441     case SNDRV_PCM_TRIGGER_SUSPEND:
0442         chip->mode &= ~SB_RATE_LOCK_CAPTURE;
0443         snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
0444                              capture_cmd(chip));
0445         break;
0446     default:
0447         result = -EINVAL;
0448         break;
0449     }
0450     spin_unlock(&chip->mixer_lock);
0451     return result;
0452 }
0453 
0454 static int snd_als4000_playback_trigger(struct snd_pcm_substream *substream, int cmd)
0455 {
0456     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0457     int result = 0;
0458 
0459     spin_lock(&chip->reg_lock);
0460     switch (cmd) {
0461     case SNDRV_PCM_TRIGGER_START:
0462     case SNDRV_PCM_TRIGGER_RESUME:
0463         chip->mode |= SB_RATE_LOCK_PLAYBACK;
0464         snd_sbdsp_command(chip, playback_cmd(chip).dma_on);
0465         break;
0466     case SNDRV_PCM_TRIGGER_STOP:
0467     case SNDRV_PCM_TRIGGER_SUSPEND:
0468         snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
0469         chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
0470         break;
0471     default:
0472         result = -EINVAL;
0473         break;
0474     }
0475     spin_unlock(&chip->reg_lock);
0476     return result;
0477 }
0478 
0479 static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *substream)
0480 {
0481     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0482     unsigned int result;
0483 
0484     spin_lock(&chip->reg_lock); 
0485     result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR);
0486     spin_unlock(&chip->reg_lock);
0487     result &= 0xffff;
0488     return bytes_to_frames( substream->runtime, result );
0489 }
0490 
0491 static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *substream)
0492 {
0493     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0494     unsigned result;
0495 
0496     spin_lock(&chip->reg_lock); 
0497     result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR);
0498     spin_unlock(&chip->reg_lock);
0499     result &= 0xffff;
0500     return bytes_to_frames( substream->runtime, result );
0501 }
0502 
0503 /* FIXME: this IRQ routine doesn't really support IRQ sharing (we always
0504  * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not).
0505  * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK
0506  * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ
0507  * register (alt_port + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU). Probably something
0508  * could be optimized here to query/write one register only...
0509  * And even if both registers need to be queried, then there's still the
0510  * question of whether it's actually correct to ACK PCI IRQ before reading
0511  * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear*
0512  * SB IRQ status.
0513  * (hmm, SPECS_PAGE: 38 mentions it the other way around!)
0514  * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS??
0515  * */
0516 static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
0517 {
0518     struct snd_sb *chip = dev_id;
0519     unsigned pci_irqstatus;
0520     unsigned sb_irqstatus;
0521 
0522     /* find out which bit of the ALS4000 PCI block produced the interrupt,
0523        SPECS_PAGE: 38, 5 */
0524     pci_irqstatus = snd_als4k_iobase_readb(chip->alt_port,
0525                  ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU);
0526     if ((pci_irqstatus & ALS4K_IOB_0E_SB_DMA_IRQ)
0527      && (chip->playback_substream)) /* playback */
0528         snd_pcm_period_elapsed(chip->playback_substream);
0529     if ((pci_irqstatus & ALS4K_IOB_0E_CR1E_IRQ)
0530      && (chip->capture_substream)) /* capturing */
0531         snd_pcm_period_elapsed(chip->capture_substream);
0532     if ((pci_irqstatus & ALS4K_IOB_0E_MPU_IRQ)
0533      && (chip->rmidi)) /* MPU401 interrupt */
0534         snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
0535     /* ACK the PCI block IRQ */
0536     snd_als4k_iobase_writeb(chip->alt_port,
0537              ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU, pci_irqstatus);
0538     
0539     spin_lock(&chip->mixer_lock);
0540     /* SPECS_PAGE: 20 */
0541     sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
0542     spin_unlock(&chip->mixer_lock);
0543     
0544     if (sb_irqstatus & SB_IRQTYPE_8BIT)
0545         snd_sb_ack_8bit(chip);
0546     if (sb_irqstatus & SB_IRQTYPE_16BIT)
0547         snd_sb_ack_16bit(chip);
0548     if (sb_irqstatus & SB_IRQTYPE_MPUIN)
0549         inb(chip->mpu_port);
0550     if (sb_irqstatus & ALS4K_IRQTYPE_CR1E_DMA)
0551         snd_als4k_iobase_readb(chip->alt_port,
0552                     ALS4K_IOB_16_ACK_FOR_CR1E);
0553 
0554     /* dev_dbg(chip->card->dev, "als4000: irq 0x%04x 0x%04x\n",
0555                      pci_irqstatus, sb_irqstatus); */
0556 
0557     /* only ack the things we actually handled above */
0558     return IRQ_RETVAL(
0559          (pci_irqstatus & (ALS4K_IOB_0E_SB_DMA_IRQ|ALS4K_IOB_0E_CR1E_IRQ|
0560                 ALS4K_IOB_0E_MPU_IRQ))
0561       || (sb_irqstatus & (SB_IRQTYPE_8BIT|SB_IRQTYPE_16BIT|
0562                 SB_IRQTYPE_MPUIN|ALS4K_IRQTYPE_CR1E_DMA))
0563     );
0564 }
0565 
0566 /*****************************************************************/
0567 
0568 static const struct snd_pcm_hardware snd_als4000_playback =
0569 {
0570     .info =         (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
0571                  SNDRV_PCM_INFO_MMAP_VALID),
0572     .formats =      SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
0573                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,  /* formats */
0574     .rates =        SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
0575     .rate_min =     4000,
0576     .rate_max =     48000,
0577     .channels_min =     1,
0578     .channels_max =     2,
0579     .buffer_bytes_max = 65536,
0580     .period_bytes_min = 64,
0581     .period_bytes_max = 65536,
0582     .periods_min =      1,
0583     .periods_max =      1024,
0584     .fifo_size =        0
0585 };
0586 
0587 static const struct snd_pcm_hardware snd_als4000_capture =
0588 {
0589     .info =         (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
0590                  SNDRV_PCM_INFO_MMAP_VALID),
0591     .formats =      SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
0592                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,  /* formats */
0593     .rates =        SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
0594     .rate_min =     4000,
0595     .rate_max =     48000,
0596     .channels_min =     1,
0597     .channels_max =     2,
0598     .buffer_bytes_max = 65536,
0599     .period_bytes_min = 64,
0600     .period_bytes_max = 65536,
0601     .periods_min =      1,
0602     .periods_max =      1024,
0603     .fifo_size =        0
0604 };
0605 
0606 /*****************************************************************/
0607 
0608 static int snd_als4000_playback_open(struct snd_pcm_substream *substream)
0609 {
0610     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0611     struct snd_pcm_runtime *runtime = substream->runtime;
0612 
0613     chip->playback_substream = substream;
0614     runtime->hw = snd_als4000_playback;
0615     return 0;
0616 }
0617 
0618 static int snd_als4000_playback_close(struct snd_pcm_substream *substream)
0619 {
0620     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0621 
0622     chip->playback_substream = NULL;
0623     return 0;
0624 }
0625 
0626 static int snd_als4000_capture_open(struct snd_pcm_substream *substream)
0627 {
0628     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0629     struct snd_pcm_runtime *runtime = substream->runtime;
0630 
0631     chip->capture_substream = substream;
0632     runtime->hw = snd_als4000_capture;
0633     return 0;
0634 }
0635 
0636 static int snd_als4000_capture_close(struct snd_pcm_substream *substream)
0637 {
0638     struct snd_sb *chip = snd_pcm_substream_chip(substream);
0639 
0640     chip->capture_substream = NULL;
0641     return 0;
0642 }
0643 
0644 /******************************************************************/
0645 
0646 static const struct snd_pcm_ops snd_als4000_playback_ops = {
0647     .open =     snd_als4000_playback_open,
0648     .close =    snd_als4000_playback_close,
0649     .prepare =  snd_als4000_playback_prepare,
0650     .trigger =  snd_als4000_playback_trigger,
0651     .pointer =  snd_als4000_playback_pointer
0652 };
0653 
0654 static const struct snd_pcm_ops snd_als4000_capture_ops = {
0655     .open =     snd_als4000_capture_open,
0656     .close =    snd_als4000_capture_close,
0657     .prepare =  snd_als4000_capture_prepare,
0658     .trigger =  snd_als4000_capture_trigger,
0659     .pointer =  snd_als4000_capture_pointer
0660 };
0661 
0662 static int snd_als4000_pcm(struct snd_sb *chip, int device)
0663 {
0664     struct snd_pcm *pcm;
0665     int err;
0666 
0667     err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm);
0668     if (err < 0)
0669         return err;
0670     pcm->private_data = chip;
0671     pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
0672     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_als4000_playback_ops);
0673     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_als4000_capture_ops);
0674 
0675     snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
0676                        &chip->pci->dev, 64*1024, 64*1024);
0677 
0678     chip->pcm = pcm;
0679 
0680     return 0;
0681 }
0682 
0683 /******************************************************************/
0684 
0685 static void snd_als4000_set_addr(unsigned long iobase,
0686                     unsigned int sb_io,
0687                     unsigned int mpu_io,
0688                     unsigned int opl_io,
0689                     unsigned int game_io)
0690 {
0691     u32 cfg1 = 0;
0692     u32 cfg2 = 0;
0693 
0694     if (mpu_io > 0)
0695         cfg2 |= (mpu_io | 1) << 16;
0696     if (sb_io > 0)
0697         cfg2 |= (sb_io | 1);
0698     if (game_io > 0)
0699         cfg1 |= (game_io | 1) << 16;
0700     if (opl_io > 0)
0701         cfg1 |= (opl_io | 1);
0702     snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA8_LEGACY_CFG1, cfg1);
0703     snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA9_LEGACY_CFG2, cfg2);
0704 }
0705 
0706 static void snd_als4000_configure(struct snd_sb *chip)
0707 {
0708     u8 tmp;
0709     int i;
0710 
0711     /* do some more configuration */
0712     spin_lock_irq(&chip->mixer_lock);
0713     tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG);
0714     snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
0715                 tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
0716     /* always select DMA channel 0, since we do not actually use DMA
0717      * SPECS_PAGE: 19/20 */
0718     snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
0719     snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
0720                  tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
0721     spin_unlock_irq(&chip->mixer_lock);
0722     
0723     spin_lock_irq(&chip->reg_lock);
0724     /* enable interrupts */
0725     snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL,
0726                     ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE);
0727 
0728     /* SPECS_PAGE: 39 */
0729     for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
0730         snd_als4k_gcr_write(chip, i, 0);
0731     /* enable burst mode to prevent dropouts during high PCI bus usage */
0732     snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
0733         (snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL) & ~0x07) | 0x04);
0734     spin_unlock_irq(&chip->reg_lock);
0735 }
0736 
0737 #ifdef SUPPORT_JOYSTICK
0738 static int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
0739 {
0740     struct gameport *gp;
0741     struct resource *r;
0742     int io_port;
0743 
0744     if (joystick_port[dev] == 0)
0745         return -ENODEV;
0746 
0747     if (joystick_port[dev] == 1) { /* auto-detect */
0748         for (io_port = 0x200; io_port <= 0x218; io_port += 8) {
0749             r = devm_request_region(&acard->pci->dev, io_port, 8,
0750                         "ALS4000 gameport");
0751             if (r)
0752                 break;
0753         }
0754     } else {
0755         io_port = joystick_port[dev];
0756         r = devm_request_region(&acard->pci->dev, io_port, 8,
0757                     "ALS4000 gameport");
0758     }
0759 
0760     if (!r) {
0761         dev_warn(&acard->pci->dev, "cannot reserve joystick ports\n");
0762         return -EBUSY;
0763     }
0764 
0765     acard->gameport = gp = gameport_allocate_port();
0766     if (!gp) {
0767         dev_err(&acard->pci->dev, "cannot allocate memory for gameport\n");
0768         return -ENOMEM;
0769     }
0770 
0771     gameport_set_name(gp, "ALS4000 Gameport");
0772     gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci));
0773     gameport_set_dev_parent(gp, &acard->pci->dev);
0774     gp->io = io_port;
0775 
0776     /* Enable legacy joystick port */
0777     snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
0778 
0779     gameport_register_port(acard->gameport);
0780 
0781     return 0;
0782 }
0783 
0784 static void snd_als4000_free_gameport(struct snd_card_als4000 *acard)
0785 {
0786     if (acard->gameport) {
0787         gameport_unregister_port(acard->gameport);
0788         acard->gameport = NULL;
0789 
0790         /* disable joystick */
0791         snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
0792     }
0793 }
0794 #else
0795 static inline int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev) { return -ENOSYS; }
0796 static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { }
0797 #endif
0798 
0799 static void snd_card_als4000_free( struct snd_card *card )
0800 {
0801     struct snd_card_als4000 *acard = card->private_data;
0802 
0803     /* make sure that interrupts are disabled */
0804     snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0);
0805     /* free resources */
0806     snd_als4000_free_gameport(acard);
0807 }
0808 
0809 static int __snd_card_als4000_probe(struct pci_dev *pci,
0810                     const struct pci_device_id *pci_id)
0811 {
0812     static int dev;
0813     struct snd_card *card;
0814     struct snd_card_als4000 *acard;
0815     unsigned long iobase;
0816     struct snd_sb *chip;
0817     struct snd_opl3 *opl3;
0818     unsigned short word;
0819     int err;
0820 
0821     if (dev >= SNDRV_CARDS)
0822         return -ENODEV;
0823     if (!enable[dev]) {
0824         dev++;
0825         return -ENOENT;
0826     }
0827 
0828     /* enable PCI device */
0829     err = pcim_enable_device(pci);
0830     if (err < 0)
0831         return err;
0832 
0833     /* check, if we can restrict PCI DMA transfers to 24 bits */
0834     if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {
0835         dev_err(&pci->dev, "architecture does not support 24bit PCI busmaster DMA\n");
0836         return -ENXIO;
0837     }
0838 
0839     err = pci_request_regions(pci, "ALS4000");
0840     if (err < 0)
0841         return err;
0842     iobase = pci_resource_start(pci, 0);
0843 
0844     pci_read_config_word(pci, PCI_COMMAND, &word);
0845     pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
0846     pci_set_master(pci);
0847     
0848     err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0849                 sizeof(*acard) /* private_data: acard */,
0850                 &card);
0851     if (err < 0)
0852         return err;
0853 
0854     acard = card->private_data;
0855     acard->pci = pci;
0856     acard->iobase = iobase;
0857     card->private_free = snd_card_als4000_free;
0858 
0859     /* disable all legacy ISA stuff */
0860     snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
0861 
0862     err = snd_sbdsp_create(card,
0863                    iobase + ALS4K_IOB_10_ADLIB_ADDR0,
0864                    pci->irq,
0865         /* internally registered as IRQF_SHARED in case of ALS4000 SB */
0866                    snd_als4000_interrupt,
0867                    -1,
0868                    -1,
0869                    SB_HW_ALS4000,
0870                    &chip);
0871     if (err < 0)
0872         return err;
0873     acard->chip = chip;
0874 
0875     chip->pci = pci;
0876     chip->alt_port = iobase;
0877 
0878     snd_als4000_configure(chip);
0879 
0880     strcpy(card->driver, "ALS4000");
0881     strcpy(card->shortname, "Avance Logic ALS4000");
0882     sprintf(card->longname, "%s at 0x%lx, irq %i",
0883         card->shortname, chip->alt_port, chip->irq);
0884 
0885     err = snd_mpu401_uart_new(card, 0, MPU401_HW_ALS4000,
0886                   iobase + ALS4K_IOB_30_MIDI_DATA,
0887                   MPU401_INFO_INTEGRATED |
0888                   MPU401_INFO_IRQ_HOOK,
0889                   -1, &chip->rmidi);
0890     if (err < 0) {
0891         dev_err(&pci->dev, "no MPU-401 device at 0x%lx?\n",
0892                 iobase + ALS4K_IOB_30_MIDI_DATA);
0893         return err;
0894     }
0895     /* FIXME: ALS4000 has interesting MPU401 configuration features
0896      * at ALS4K_CR1A_MPU401_UART_MODE_CONTROL
0897      * (pass-thru / UART switching, fast MIDI clock, etc.),
0898      * however there doesn't seem to be an ALSA API for this...
0899      * SPECS_PAGE: 21 */
0900 
0901     err = snd_als4000_pcm(chip, 0);
0902     if (err < 0)
0903         return err;
0904 
0905     err = snd_sbmixer_new(chip);
0906     if (err < 0)
0907         return err;
0908 
0909     if (snd_opl3_create(card,
0910                 iobase + ALS4K_IOB_10_ADLIB_ADDR0,
0911                 iobase + ALS4K_IOB_12_ADLIB_ADDR2,
0912                 OPL3_HW_AUTO, 1, &opl3) < 0) {
0913         dev_err(&pci->dev, "no OPL device at 0x%lx-0x%lx?\n",
0914                iobase + ALS4K_IOB_10_ADLIB_ADDR0,
0915                iobase + ALS4K_IOB_12_ADLIB_ADDR2);
0916     } else {
0917         err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
0918         if (err < 0)
0919             return err;
0920     }
0921 
0922     snd_als4000_create_gameport(acard, dev);
0923 
0924     err = snd_card_register(card);
0925     if (err < 0)
0926         return err;
0927 
0928     pci_set_drvdata(pci, card);
0929     dev++;
0930     return 0;
0931 }
0932 
0933 static int snd_card_als4000_probe(struct pci_dev *pci,
0934                   const struct pci_device_id *pci_id)
0935 {
0936     return snd_card_free_on_error(&pci->dev, __snd_card_als4000_probe(pci, pci_id));
0937 }
0938 
0939 #ifdef CONFIG_PM_SLEEP
0940 static int snd_als4000_suspend(struct device *dev)
0941 {
0942     struct snd_card *card = dev_get_drvdata(dev);
0943     struct snd_card_als4000 *acard = card->private_data;
0944     struct snd_sb *chip = acard->chip;
0945 
0946     snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
0947     
0948     snd_sbmixer_suspend(chip);
0949     return 0;
0950 }
0951 
0952 static int snd_als4000_resume(struct device *dev)
0953 {
0954     struct snd_card *card = dev_get_drvdata(dev);
0955     struct snd_card_als4000 *acard = card->private_data;
0956     struct snd_sb *chip = acard->chip;
0957 
0958     snd_als4000_configure(chip);
0959     snd_sbdsp_reset(chip);
0960     snd_sbmixer_resume(chip);
0961 
0962 #ifdef SUPPORT_JOYSTICK
0963     if (acard->gameport)
0964         snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
0965 #endif
0966 
0967     snd_power_change_state(card, SNDRV_CTL_POWER_D0);
0968     return 0;
0969 }
0970 
0971 static SIMPLE_DEV_PM_OPS(snd_als4000_pm, snd_als4000_suspend, snd_als4000_resume);
0972 #define SND_ALS4000_PM_OPS  &snd_als4000_pm
0973 #else
0974 #define SND_ALS4000_PM_OPS  NULL
0975 #endif /* CONFIG_PM_SLEEP */
0976 
0977 static struct pci_driver als4000_driver = {
0978     .name = KBUILD_MODNAME,
0979     .id_table = snd_als4000_ids,
0980     .probe = snd_card_als4000_probe,
0981     .driver = {
0982         .pm = SND_ALS4000_PM_OPS,
0983     },
0984 };
0985 
0986 module_pci_driver(als4000_driver);