diff options
author | Andreas Mohr <andi@lisas.de> | 2008-08-20 04:04:56 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-08-25 03:57:11 -0400 |
commit | c08744498491759168119255fae2a1bd9532a268 (patch) | |
tree | 288f76b14ed64cf769afa98b3a132dea26c8a833 /sound/pci/als4000.c | |
parent | 281712fa02bfb196d915503787e3ad351ed1be0a (diff) |
ALSA: als4000 - Code clean up
- use specs-derived register name enums instead of open-coded numeric
values, for better understanding of things
- fix naming confusion ("gcr" was _NOT_ the GCR register stuff, but
instead the io _base_ which has multiplexed _access_ to GCR config
space, at _sub_ registers 0x08 and 0x0c)
- add FIXME comments about a race condition and MPU401 features
Signed-off-by: Andreas Mohr <andi@lisas.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/als4000.c')
-rw-r--r-- | sound/pci/als4000.c | 206 |
1 files changed, 148 insertions, 58 deletions
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 27ce6136ab00..92d8c47cd3b2 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -60,6 +60,7 @@ | |||
60 | * | 60 | * |
61 | * ToDo: | 61 | * ToDo: |
62 | * - Proper shared IRQ handling? | 62 | * - Proper shared IRQ handling? |
63 | * - by default, don't enable legacy game and use PCI game I/O | ||
63 | * - power management? (card can do voice wakeup according to datasheet!!) | 64 | * - power management? (card can do voice wakeup according to datasheet!!) |
64 | */ | 65 | */ |
65 | 66 | ||
@@ -107,7 +108,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 | |||
107 | 108 | ||
108 | struct snd_card_als4000 { | 109 | struct snd_card_als4000 { |
109 | /* most frequent access first */ | 110 | /* most frequent access first */ |
110 | unsigned long gcr; | 111 | unsigned long iobase; |
111 | struct pci_dev *pci; | 112 | struct pci_dev *pci; |
112 | struct snd_sb *chip; | 113 | struct snd_sb *chip; |
113 | #ifdef SUPPORT_JOYSTICK | 114 | #ifdef SUPPORT_JOYSTICK |
@@ -122,24 +123,89 @@ static struct pci_device_id snd_als4000_ids[] = { | |||
122 | 123 | ||
123 | MODULE_DEVICE_TABLE(pci, snd_als4000_ids); | 124 | MODULE_DEVICE_TABLE(pci, snd_als4000_ids); |
124 | 125 | ||
125 | static inline void snd_als4000_gcr_write_addr(unsigned long port, u32 reg, u32 val) | 126 | enum als4k_iobase_t { |
127 | /* IOx: B == Byte, W = Word, D = DWord */ | ||
128 | ALS4K_IOD_00_AC97_ACCESS = 0x00, | ||
129 | ALS4K_IOW_04_AC97_READ = 0x04, | ||
130 | ALS4K_IOB_06_AC97_STATUS = 0x06, | ||
131 | ALS4K_IOB_07_IRQSTATUS = 0x07, | ||
132 | ALS4K_IOD_08_GCR_DATA = 0x08, | ||
133 | ALS4K_IOB_0C_GCR_INDEX = 0x0c, | ||
134 | ALS4K_IOB_0E_SB_MPU_IRQ = 0x0e, | ||
135 | ALS4K_IOB_10_ADLIB_ADDR0 = 0x10, | ||
136 | ALS4K_IOB_11_ADLIB_ADDR1 = 0x11, | ||
137 | ALS4K_IOB_12_ADLIB_ADDR2 = 0x12, | ||
138 | ALS4K_IOB_13_ADLIB_ADDR3 = 0x13, | ||
139 | ALS4K_IOB_14_MIXER_INDEX = 0x14, | ||
140 | ALS4K_IOB_15_MIXER_DATA = 0x15, | ||
141 | ALS4K_IOB_16_ESP_RST_PORT = 0x16, | ||
142 | ALS4K_IOB_16_CR1E_ACK_PORT = 0x16, /* 2nd function */ | ||
143 | ALS4K_IOB_18_OPL_ADDR0 = 0x18, | ||
144 | ALS4K_IOB_19_OPL_ADDR1 = 0x19, | ||
145 | ALS4K_IOB_1A_ESP_RD_DATA = 0x1a, | ||
146 | ALS4K_IOB_1C_ESP_CMD_DATA = 0x1c, | ||
147 | ALS4K_IOB_1C_ESP_WR_STATUS = 0x1c, /* 2nd function */ | ||
148 | ALS4K_IOB_1E_ESP_RD_STATUS8 = 0x1e, | ||
149 | ALS4K_IOB_1F_ESP_RD_STATUS16 = 0x1f, | ||
150 | ALS4K_IOB_20_ESP_GAMEPORT_200 = 0x20, | ||
151 | ALS4K_IOB_21_ESP_GAMEPORT_201 = 0x21, | ||
152 | ALS4K_IOB_30_MIDI_DATA = 0x30, | ||
153 | ALS4K_IOB_31_MIDI_STATUS = 0x31, | ||
154 | ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */ | ||
155 | }; | ||
156 | |||
157 | enum als4k_gcr_t { | ||
158 | /* all registers 32bit wide */ | ||
159 | ALS4K_GCR_8C_MISC_CTRL = 0x8c, | ||
160 | ALS4K_GCR_90_TEST_MODE_REG = 0x90, | ||
161 | ALS4K_GCR_91_DMA0_ADDR = 0x91, | ||
162 | ALS4K_GCR_92_DMA0_MODE_COUNT = 0x92, | ||
163 | ALS4K_GCR_93_DMA1_ADDR = 0x93, | ||
164 | ALS4K_GCR_94_DMA1_MODE_COUNT = 0x94, | ||
165 | ALS4K_GCR_95_DMA3_ADDR = 0x95, | ||
166 | ALS4K_GCR_96_DMA3_MODE_COUNT = 0x96, | ||
167 | ALS4K_GCR_99_DMA_EMULATION_CTRL = 0x99, | ||
168 | ALS4K_GCR_A0_FIFO1_CURRENT_ADDR = 0xa0, | ||
169 | ALS4K_GCR_A1_FIFO1_STATUS_BYTECOUNT = 0xa1, | ||
170 | ALS4K_GCR_A2_FIFO2_PCIADDR = 0xa2, | ||
171 | ALS4K_GCR_A3_FIFO2_COUNT = 0xa3, | ||
172 | ALS4K_GCR_A4_FIFO2_CURRENT_ADDR = 0xa4, | ||
173 | ALS4K_GCR_A5_FIFO1_STATUS_BYTECOUNT = 0xa5, | ||
174 | ALS4K_GCR_A6_PM_CTRL = 0xa6, | ||
175 | ALS4K_GCR_A7_PCI_ACCESS_STORAGE = 0xa7, | ||
176 | ALS4K_GCR_A8_LEGACY_CFG1 = 0xa8, | ||
177 | ALS4K_GCR_A9_LEGACY_CFG2 = 0xa9, | ||
178 | ALS4K_GCR_FF_DUMMY_SCRATCH = 0xff, | ||
179 | }; | ||
180 | |||
181 | enum als4k_gcr_8c_t { | ||
182 | ALS4K_GCR_8C_IRQ_MASK_CTRL_ENABLE = 0x8000, | ||
183 | ALS4K_GCR_8C_CHIP_REV_MASK = 0xf0000 | ||
184 | }; | ||
185 | |||
186 | static inline void snd_als4000_gcr_write_addr(unsigned long iobase, | ||
187 | enum als4k_gcr_t reg, | ||
188 | u32 val) | ||
126 | { | 189 | { |
127 | outb(reg, port+0x0c); | 190 | outb(reg, iobase + ALS4K_IOB_0C_GCR_INDEX); |
128 | outl(val, port+0x08); | 191 | outl(val, iobase + ALS4K_IOD_08_GCR_DATA); |
129 | } | 192 | } |
130 | 193 | ||
131 | static inline void snd_als4000_gcr_write(struct snd_sb *sb, u32 reg, u32 val) | 194 | static inline void snd_als4000_gcr_write(struct snd_sb *sb, |
195 | enum als4k_gcr_t reg, | ||
196 | u32 val) | ||
132 | { | 197 | { |
133 | snd_als4000_gcr_write_addr(sb->alt_port, reg, val); | 198 | snd_als4000_gcr_write_addr(sb->alt_port, reg, val); |
134 | } | 199 | } |
135 | 200 | ||
136 | static inline u32 snd_als4000_gcr_read_addr(unsigned long port, u32 reg) | 201 | static inline u32 snd_als4000_gcr_read_addr(unsigned long iobase, |
202 | enum als4k_gcr_t reg) | ||
137 | { | 203 | { |
138 | outb(reg, port+0x0c); | 204 | outb(reg, iobase + ALS4K_IOB_0C_GCR_INDEX); |
139 | return inl(port+0x08); | 205 | return inl(iobase + ALS4K_IOD_08_GCR_DATA); |
140 | } | 206 | } |
141 | 207 | ||
142 | static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, u32 reg) | 208 | static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg) |
143 | { | 209 | { |
144 | return snd_als4000_gcr_read_addr(sb->alt_port, reg); | 210 | return snd_als4000_gcr_read_addr(sb->alt_port, reg); |
145 | } | 211 | } |
@@ -156,15 +222,17 @@ static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate) | |||
156 | static inline void snd_als4000_set_capture_dma(struct snd_sb *chip, | 222 | static inline void snd_als4000_set_capture_dma(struct snd_sb *chip, |
157 | dma_addr_t addr, unsigned size) | 223 | dma_addr_t addr, unsigned size) |
158 | { | 224 | { |
159 | snd_als4000_gcr_write(chip, 0xa2, addr); | 225 | snd_als4000_gcr_write(chip, ALS4K_GCR_A2_FIFO2_PCIADDR, addr); |
160 | snd_als4000_gcr_write(chip, 0xa3, (size-1)); | 226 | snd_als4000_gcr_write(chip, ALS4K_GCR_A3_FIFO2_COUNT, (size-1)); |
161 | } | 227 | } |
162 | 228 | ||
163 | static inline void snd_als4000_set_playback_dma(struct snd_sb *chip, | 229 | static inline void snd_als4000_set_playback_dma(struct snd_sb *chip, |
164 | dma_addr_t addr, unsigned size) | 230 | dma_addr_t addr, |
231 | unsigned size) | ||
165 | { | 232 | { |
166 | snd_als4000_gcr_write(chip, 0x91, addr); | 233 | snd_als4000_gcr_write(chip, ALS4K_GCR_91_DMA0_ADDR, addr); |
167 | snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000); | 234 | snd_als4000_gcr_write(chip, ALS4K_GCR_92_DMA0_MODE_COUNT, |
235 | (size-1)|0x180000); | ||
168 | } | 236 | } |
169 | 237 | ||
170 | #define ALS4000_FORMAT_SIGNED (1<<0) | 238 | #define ALS4000_FORMAT_SIGNED (1<<0) |
@@ -305,6 +373,12 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int | |||
305 | struct snd_sb *chip = snd_pcm_substream_chip(substream); | 373 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
306 | int result = 0; | 374 | int result = 0; |
307 | 375 | ||
376 | /* FIXME race condition in here!!! | ||
377 | chip->mode non-atomic update gets consistently protected | ||
378 | by reg_lock always, _except_ for this place!! | ||
379 | Probably need to take reg_lock as outer (or inner??) lock, too. | ||
380 | (or serialize both lock operations? probably not, though... - racy?) | ||
381 | */ | ||
308 | spin_lock(&chip->mixer_lock); | 382 | spin_lock(&chip->mixer_lock); |
309 | switch (cmd) { | 383 | switch (cmd) { |
310 | case SNDRV_PCM_TRIGGER_START: | 384 | case SNDRV_PCM_TRIGGER_START: |
@@ -356,7 +430,8 @@ static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *s | |||
356 | unsigned int result; | 430 | unsigned int result; |
357 | 431 | ||
358 | spin_lock(&chip->reg_lock); | 432 | spin_lock(&chip->reg_lock); |
359 | result = snd_als4000_gcr_read(chip, 0xa4) & 0xffff; | 433 | result = snd_als4000_gcr_read(chip, ALS4K_GCR_A4_FIFO2_CURRENT_ADDR); |
434 | result &= 0xffff; | ||
360 | spin_unlock(&chip->reg_lock); | 435 | spin_unlock(&chip->reg_lock); |
361 | return bytes_to_frames( substream->runtime, result ); | 436 | return bytes_to_frames( substream->runtime, result ); |
362 | } | 437 | } |
@@ -367,7 +442,8 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * | |||
367 | unsigned result; | 442 | unsigned result; |
368 | 443 | ||
369 | spin_lock(&chip->reg_lock); | 444 | spin_lock(&chip->reg_lock); |
370 | result = snd_als4000_gcr_read(chip, 0xa0) & 0xffff; | 445 | result = snd_als4000_gcr_read(chip, ALS4K_GCR_A0_FIFO1_CURRENT_ADDR); |
446 | result &= 0xffff; | ||
371 | spin_unlock(&chip->reg_lock); | 447 | spin_unlock(&chip->reg_lock); |
372 | return bytes_to_frames( substream->runtime, result ); | 448 | return bytes_to_frames( substream->runtime, result ); |
373 | } | 449 | } |
@@ -376,12 +452,13 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * | |||
376 | * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not). | 452 | * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not). |
377 | * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK | 453 | * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK |
378 | * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ | 454 | * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ |
379 | * register (alt_port + 0x0e). Probably something could be optimized here to | 455 | * register (alt_port + ALS4K_IOB_0E_SB_MPU_IRQ). Probably something |
380 | * query/write one register only... | 456 | * could be optimized here to query/write one register only... |
381 | * And even if both registers need to be queried, then there's still the | 457 | * And even if both registers need to be queried, then there's still the |
382 | * question of whether it's actually correct to ACK PCI IRQ before reading | 458 | * question of whether it's actually correct to ACK PCI IRQ before reading |
383 | * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear* | 459 | * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear* |
384 | * SB IRQ status. | 460 | * SB IRQ status. |
461 | * (hmm, page 38 mentions it the other way around!) | ||
385 | * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS?? | 462 | * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS?? |
386 | * */ | 463 | * */ |
387 | static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) | 464 | static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) |
@@ -391,7 +468,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) | |||
391 | unsigned sb_status; | 468 | unsigned sb_status; |
392 | 469 | ||
393 | /* find out which bit of the ALS4000 produced the interrupt */ | 470 | /* find out which bit of the ALS4000 produced the interrupt */ |
394 | gcr_status = inb(chip->alt_port + 0xe); | 471 | gcr_status = inb(chip->alt_port + ALS4K_IOB_0E_SB_MPU_IRQ); |
395 | 472 | ||
396 | if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */ | 473 | if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */ |
397 | snd_pcm_period_elapsed(chip->playback_substream); | 474 | snd_pcm_period_elapsed(chip->playback_substream); |
@@ -400,7 +477,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) | |||
400 | if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ | 477 | if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ |
401 | snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); | 478 | snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); |
402 | /* release the gcr */ | 479 | /* release the gcr */ |
403 | outb(gcr_status, chip->alt_port + 0xe); | 480 | outb(gcr_status, chip->alt_port + ALS4K_IOB_0E_SB_MPU_IRQ); |
404 | 481 | ||
405 | spin_lock(&chip->mixer_lock); | 482 | spin_lock(&chip->mixer_lock); |
406 | sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); | 483 | sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); |
@@ -543,25 +620,25 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device) | |||
543 | 620 | ||
544 | /******************************************************************/ | 621 | /******************************************************************/ |
545 | 622 | ||
546 | static void snd_als4000_set_addr(unsigned long gcr, | 623 | static void snd_als4000_set_addr(unsigned long iobase, |
547 | unsigned int sb, | 624 | unsigned int sb_io, |
548 | unsigned int mpu, | 625 | unsigned int mpu_io, |
549 | unsigned int opl, | 626 | unsigned int opl_io, |
550 | unsigned int game) | 627 | unsigned int game_io) |
551 | { | 628 | { |
552 | u32 confA = 0; | 629 | u32 cfg1 = 0; |
553 | u32 confB = 0; | 630 | u32 cfg2 = 0; |
554 | 631 | ||
555 | if (mpu > 0) | 632 | if (mpu_io > 0) |
556 | confB |= (mpu | 1) << 16; | 633 | cfg2 |= (mpu_io | 1) << 16; |
557 | if (sb > 0) | 634 | if (sb_io > 0) |
558 | confB |= (sb | 1); | 635 | cfg2 |= (sb_io | 1); |
559 | if (game > 0) | 636 | if (game_io > 0) |
560 | confA |= (game | 1) << 16; | 637 | cfg1 |= (game_io | 1) << 16; |
561 | if (opl > 0) | 638 | if (opl_io > 0) |
562 | confA |= (opl | 1); | 639 | cfg1 |= (opl_io | 1); |
563 | snd_als4000_gcr_write_addr(gcr, 0xa8, confA); | 640 | snd_als4000_gcr_write_addr(iobase, ALS4K_GCR_A8_LEGACY_CFG1, cfg1); |
564 | snd_als4000_gcr_write_addr(gcr, 0xa9, confB); | 641 | snd_als4000_gcr_write_addr(iobase, ALS4K_GCR_A9_LEGACY_CFG2, cfg2); |
565 | } | 642 | } |
566 | 643 | ||
567 | static void snd_als4000_configure(struct snd_sb *chip) | 644 | static void snd_als4000_configure(struct snd_sb *chip) |
@@ -579,12 +656,15 @@ static void snd_als4000_configure(struct snd_sb *chip) | |||
579 | spin_unlock_irq(&chip->mixer_lock); | 656 | spin_unlock_irq(&chip->mixer_lock); |
580 | 657 | ||
581 | spin_lock_irq(&chip->reg_lock); | 658 | spin_lock_irq(&chip->reg_lock); |
582 | /* magic number. Enables interrupts(?) */ | 659 | /* enable interrupts */ |
583 | snd_als4000_gcr_write(chip, 0x8c, 0x28000); | 660 | snd_als4000_gcr_write(chip, ALS4K_GCR_8C_MISC_CTRL, |
584 | for(i = 0x91; i <= 0x96; ++i) | 661 | ALS4K_GCR_8C_IRQ_MASK_CTRL_ENABLE); |
662 | |||
663 | for (i = ALS4K_GCR_91_DMA0_ADDR; i <= ALS4K_GCR_96_DMA3_MODE_COUNT; ++i) | ||
585 | snd_als4000_gcr_write(chip, i, 0); | 664 | snd_als4000_gcr_write(chip, i, 0); |
586 | 665 | ||
587 | snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99)); | 666 | snd_als4000_gcr_write(chip, ALS4K_GCR_99_DMA_EMULATION_CTRL, |
667 | snd_als4000_gcr_read(chip, ALS4K_GCR_99_DMA_EMULATION_CTRL)); | ||
588 | spin_unlock_irq(&chip->reg_lock); | 668 | spin_unlock_irq(&chip->reg_lock); |
589 | } | 669 | } |
590 | 670 | ||
@@ -628,7 +708,7 @@ static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard, | |||
628 | gameport_set_port_data(gp, r); | 708 | gameport_set_port_data(gp, r); |
629 | 709 | ||
630 | /* Enable legacy joystick port */ | 710 | /* Enable legacy joystick port */ |
631 | snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); | 711 | snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1); |
632 | 712 | ||
633 | gameport_register_port(acard->gameport); | 713 | gameport_register_port(acard->gameport); |
634 | 714 | ||
@@ -643,7 +723,9 @@ static void snd_als4000_free_gameport(struct snd_card_als4000 *acard) | |||
643 | gameport_unregister_port(acard->gameport); | 723 | gameport_unregister_port(acard->gameport); |
644 | acard->gameport = NULL; | 724 | acard->gameport = NULL; |
645 | 725 | ||
646 | snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */ | 726 | /* disable joystick */ |
727 | snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0); | ||
728 | |||
647 | release_and_free_resource(r); | 729 | release_and_free_resource(r); |
648 | } | 730 | } |
649 | } | 731 | } |
@@ -654,10 +736,10 @@ static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { } | |||
654 | 736 | ||
655 | static void snd_card_als4000_free( struct snd_card *card ) | 737 | static void snd_card_als4000_free( struct snd_card *card ) |
656 | { | 738 | { |
657 | struct snd_card_als4000 * acard = (struct snd_card_als4000 *)card->private_data; | 739 | struct snd_card_als4000 *acard = card->private_data; |
658 | 740 | ||
659 | /* make sure that interrupts are disabled */ | 741 | /* make sure that interrupts are disabled */ |
660 | snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0); | 742 | snd_als4000_gcr_write_addr(acard->iobase, ALS4K_GCR_8C_MISC_CTRL, 0); |
661 | /* free resources */ | 743 | /* free resources */ |
662 | snd_als4000_free_gameport(acard); | 744 | snd_als4000_free_gameport(acard); |
663 | pci_release_regions(acard->pci); | 745 | pci_release_regions(acard->pci); |
@@ -670,7 +752,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
670 | static int dev; | 752 | static int dev; |
671 | struct snd_card *card; | 753 | struct snd_card *card; |
672 | struct snd_card_als4000 *acard; | 754 | struct snd_card_als4000 *acard; |
673 | unsigned long gcr; | 755 | unsigned long iobase; |
674 | struct snd_sb *chip; | 756 | struct snd_sb *chip; |
675 | struct snd_opl3 *opl3; | 757 | struct snd_opl3 *opl3; |
676 | unsigned short word; | 758 | unsigned short word; |
@@ -699,7 +781,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
699 | pci_disable_device(pci); | 781 | pci_disable_device(pci); |
700 | return err; | 782 | return err; |
701 | } | 783 | } |
702 | gcr = pci_resource_start(pci, 0); | 784 | iobase = pci_resource_start(pci, 0); |
703 | 785 | ||
704 | pci_read_config_word(pci, PCI_COMMAND, &word); | 786 | pci_read_config_word(pci, PCI_COMMAND, &word); |
705 | pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); | 787 | pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); |
@@ -713,16 +795,16 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
713 | return -ENOMEM; | 795 | return -ENOMEM; |
714 | } | 796 | } |
715 | 797 | ||
716 | acard = (struct snd_card_als4000 *)card->private_data; | 798 | acard = card->private_data; |
717 | acard->pci = pci; | 799 | acard->pci = pci; |
718 | acard->gcr = gcr; | 800 | acard->iobase = iobase; |
719 | card->private_free = snd_card_als4000_free; | 801 | card->private_free = snd_card_als4000_free; |
720 | 802 | ||
721 | /* disable all legacy ISA stuff */ | 803 | /* disable all legacy ISA stuff */ |
722 | snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); | 804 | snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0); |
723 | 805 | ||
724 | if ((err = snd_sbdsp_create(card, | 806 | if ((err = snd_sbdsp_create(card, |
725 | gcr + 0x10, | 807 | iobase + ALS4K_IOB_10_ADLIB_ADDR0, |
726 | pci->irq, | 808 | pci->irq, |
727 | snd_als4000_interrupt, | 809 | snd_als4000_interrupt, |
728 | -1, | 810 | -1, |
@@ -734,7 +816,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
734 | acard->chip = chip; | 816 | acard->chip = chip; |
735 | 817 | ||
736 | chip->pci = pci; | 818 | chip->pci = pci; |
737 | chip->alt_port = gcr; | 819 | chip->alt_port = iobase; |
738 | snd_card_set_dev(card, &pci->dev); | 820 | snd_card_set_dev(card, &pci->dev); |
739 | 821 | ||
740 | snd_als4000_configure(chip); | 822 | snd_als4000_configure(chip); |
@@ -745,11 +827,16 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
745 | card->shortname, chip->alt_port, chip->irq); | 827 | card->shortname, chip->alt_port, chip->irq); |
746 | 828 | ||
747 | if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, | 829 | if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, |
748 | gcr+0x30, MPU401_INFO_INTEGRATED, | 830 | iobase + ALS4K_IOB_30_MIDI_DATA, |
831 | MPU401_INFO_INTEGRATED, | ||
749 | pci->irq, 0, &chip->rmidi)) < 0) { | 832 | pci->irq, 0, &chip->rmidi)) < 0) { |
750 | printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30); | 833 | printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", |
834 | iobase + ALS4K_IOB_30_MIDI_DATA); | ||
751 | goto out_err; | 835 | goto out_err; |
752 | } | 836 | } |
837 | /* FIXME: ALS4000 has interesting MPU401 configuration features | ||
838 | * at CR 0x1A (pass-thru / UART switching, fast MIDI clock, etc.), | ||
839 | * however there doesn't seem to be an ALSA API for this... */ | ||
753 | 840 | ||
754 | if ((err = snd_als4000_pcm(chip, 0)) < 0) { | 841 | if ((err = snd_als4000_pcm(chip, 0)) < 0) { |
755 | goto out_err; | 842 | goto out_err; |
@@ -758,10 +845,13 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
758 | goto out_err; | 845 | goto out_err; |
759 | } | 846 | } |
760 | 847 | ||
761 | if (snd_opl3_create(card, gcr+0x10, gcr+0x12, | 848 | if (snd_opl3_create(card, |
849 | iobase + ALS4K_IOB_10_ADLIB_ADDR0, | ||
850 | iobase + ALS4K_IOB_12_ADLIB_ADDR2, | ||
762 | OPL3_HW_AUTO, 1, &opl3) < 0) { | 851 | OPL3_HW_AUTO, 1, &opl3) < 0) { |
763 | printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n", | 852 | printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n", |
764 | gcr+0x10, gcr+0x12 ); | 853 | iobase + ALS4K_IOB_10_ADLIB_ADDR0, |
854 | iobase + ALS4K_IOB_12_ADLIB_ADDR2); | ||
765 | } else { | 855 | } else { |
766 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { | 856 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { |
767 | goto out_err; | 857 | goto out_err; |
@@ -831,13 +921,13 @@ static int snd_als4000_resume(struct pci_dev *pci) | |||
831 | 921 | ||
832 | #ifdef SUPPORT_JOYSTICK | 922 | #ifdef SUPPORT_JOYSTICK |
833 | if (acard->gameport) | 923 | if (acard->gameport) |
834 | snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); | 924 | snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1); |
835 | #endif | 925 | #endif |
836 | 926 | ||
837 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 927 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
838 | return 0; | 928 | return 0; |
839 | } | 929 | } |
840 | #endif | 930 | #endif /* CONFIG_PM */ |
841 | 931 | ||
842 | 932 | ||
843 | static struct pci_driver driver = { | 933 | static struct pci_driver driver = { |