0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
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;
0077 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0078 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
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
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, },
0106 { 0, }
0107 };
0108
0109 MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
0110
0111 enum als4k_iobase_t {
0112
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,
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,
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,
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 {
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
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 {
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,
0241 ALS4K_CR3A_MISC_CONTROL = 0x3a,
0242 ALS4K_CR3B_CRC32_BYTE0 = 0x3b,
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,
0250 ALS4K_CR0_DMA_90H_MODE_CTRL = 0x04,
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
0259
0260
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
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
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
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
0319 static const struct {
0320 unsigned char dsp_cmd, dma_on, dma_off, format;
0321 } playback_cmd_vals[]={
0322
0323 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_MONO },
0324
0325 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_MONO },
0326
0327 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_MONO },
0328
0329 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_MONO },
0330
0331 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_STEREO },
0332
0333 { SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_STEREO },
0334
0335 { SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_STEREO },
0336
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
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,
0346 CMD_WIDTH8|CMD_SIGNED|CMD_MONO,
0347 CMD_MONO,
0348 CMD_SIGNED|CMD_MONO,
0349 CMD_WIDTH8|CMD_STEREO,
0350 CMD_WIDTH8|CMD_SIGNED|CMD_STEREO,
0351 CMD_STEREO,
0352 CMD_SIGNED|CMD_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
0400
0401
0402
0403
0404
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
0410
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
0427
0428
0429
0430
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
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
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
0523
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))
0528 snd_pcm_period_elapsed(chip->playback_substream);
0529 if ((pci_irqstatus & ALS4K_IOB_0E_CR1E_IRQ)
0530 && (chip->capture_substream))
0531 snd_pcm_period_elapsed(chip->capture_substream);
0532 if ((pci_irqstatus & ALS4K_IOB_0E_MPU_IRQ)
0533 && (chip->rmidi))
0534 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
0535
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
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
0555
0556
0557
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,
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,
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
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
0717
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
0725 snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL,
0726 ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE);
0727
0728
0729 for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
0730 snd_als4k_gcr_write(chip, i, 0);
0731
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) {
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
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
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
0804 snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0);
0805
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
0829 err = pcim_enable_device(pci);
0830 if (err < 0)
0831 return err;
0832
0833
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) ,
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
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
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
0896
0897
0898
0899
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
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);