diff options
| -rw-r--r-- | sound/pci/ice1712/ice1724.c | 95 | ||||
| -rw-r--r-- | sound/pci/ice1712/prodigy192.c | 4 |
2 files changed, 81 insertions, 18 deletions
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 13ea94f317cb..4490422fb930 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
| @@ -223,6 +223,32 @@ static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice) | |||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | /* | 225 | /* |
| 226 | * MPU401 accessor | ||
| 227 | */ | ||
| 228 | static unsigned char snd_vt1724_mpu401_read(struct snd_mpu401 *mpu, | ||
| 229 | unsigned long addr) | ||
| 230 | { | ||
| 231 | /* fix status bits to the standard position */ | ||
| 232 | /* only RX_EMPTY and TX_FULL are checked */ | ||
| 233 | if (addr == MPU401C(mpu)) | ||
| 234 | return (inb(addr) & 0x0c) << 4; | ||
| 235 | else | ||
| 236 | return inb(addr); | ||
| 237 | } | ||
| 238 | |||
| 239 | static void snd_vt1724_mpu401_write(struct snd_mpu401 *mpu, | ||
| 240 | unsigned char data, unsigned long addr) | ||
| 241 | { | ||
| 242 | if (addr == MPU401C(mpu)) { | ||
| 243 | if (data == MPU401_ENTER_UART) | ||
| 244 | outb(0x01, addr); | ||
| 245 | /* what else? */ | ||
| 246 | } else | ||
| 247 | outb(data, addr); | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 251 | /* | ||
| 226 | * Interrupt handler | 252 | * Interrupt handler |
| 227 | */ | 253 | */ |
| 228 | 254 | ||
| @@ -230,24 +256,53 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) | |||
| 230 | { | 256 | { |
| 231 | struct snd_ice1712 *ice = dev_id; | 257 | struct snd_ice1712 *ice = dev_id; |
| 232 | unsigned char status; | 258 | unsigned char status; |
| 259 | unsigned char status_mask = | ||
| 260 | VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; | ||
| 233 | int handled = 0; | 261 | int handled = 0; |
| 262 | #ifdef CONFIG_SND_DEBUG | ||
| 263 | int timeout = 0; | ||
| 264 | #endif | ||
| 234 | 265 | ||
| 235 | while (1) { | 266 | while (1) { |
| 236 | status = inb(ICEREG1724(ice, IRQSTAT)); | 267 | status = inb(ICEREG1724(ice, IRQSTAT)); |
| 268 | status &= status_mask; | ||
| 237 | if (status == 0) | 269 | if (status == 0) |
| 238 | break; | 270 | break; |
| 239 | 271 | #ifdef CONFIG_SND_DEBUG | |
| 272 | if (++timeout > 10) { | ||
| 273 | printk(KERN_ERR | ||
| 274 | "ice1724: Too long irq loop, status = 0x%x\n", | ||
| 275 | status); | ||
| 276 | break; | ||
| 277 | } | ||
| 278 | #endif | ||
| 240 | handled = 1; | 279 | handled = 1; |
| 241 | /* these should probably be separated at some point, | 280 | if (status & VT1724_IRQ_MPU_TX) { |
| 242 | * but as we don't currently have MPU support on the board | ||
| 243 | * I will leave it | ||
| 244 | */ | ||
| 245 | if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) { | ||
| 246 | if (ice->rmidi[0]) | 281 | if (ice->rmidi[0]) |
| 247 | snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data); | 282 | snd_mpu401_uart_interrupt_tx(irq, |
| 248 | outb(status & (VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX), ICEREG1724(ice, IRQSTAT)); | 283 | ice->rmidi[0]->private_data); |
| 249 | status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX); | 284 | else /* disable TX to be sure */ |
| 285 | outb(inb(ICEREG1724(ice, IRQMASK)) | | ||
| 286 | VT1724_IRQ_MPU_TX, | ||
| 287 | ICEREG1724(ice, IRQMASK)); | ||
| 288 | /* Due to mysterical reasons, MPU_TX is always | ||
| 289 | * generated (and can't be cleared) when a PCM | ||
| 290 | * playback is going. So let's ignore at the | ||
| 291 | * next loop. | ||
| 292 | */ | ||
| 293 | status_mask &= ~VT1724_IRQ_MPU_TX; | ||
| 294 | } | ||
| 295 | if (status & VT1724_IRQ_MPU_RX) { | ||
| 296 | if (ice->rmidi[0]) | ||
| 297 | snd_mpu401_uart_interrupt(irq, | ||
| 298 | ice->rmidi[0]->private_data); | ||
| 299 | else /* disable RX to be sure */ | ||
| 300 | outb(inb(ICEREG1724(ice, IRQMASK)) | | ||
| 301 | VT1724_IRQ_MPU_RX, | ||
| 302 | ICEREG1724(ice, IRQMASK)); | ||
| 250 | } | 303 | } |
| 304 | /* ack MPU irq */ | ||
| 305 | outb(status, ICEREG1724(ice, IRQSTAT)); | ||
| 251 | if (status & VT1724_IRQ_MTPCM) { | 306 | if (status & VT1724_IRQ_MTPCM) { |
| 252 | /* | 307 | /* |
| 253 | * Multi-track PCM | 308 | * Multi-track PCM |
| @@ -2236,10 +2291,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card, | |||
| 2236 | } | 2291 | } |
| 2237 | 2292 | ||
| 2238 | /* unmask used interrupts */ | 2293 | /* unmask used interrupts */ |
| 2239 | if (! (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401)) | 2294 | mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; |
| 2240 | mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; | ||
| 2241 | else | ||
| 2242 | mask = 0; | ||
| 2243 | outb(mask, ICEREG1724(ice, IRQMASK)); | 2295 | outb(mask, ICEREG1724(ice, IRQMASK)); |
| 2244 | /* don't handle FIFO overrun/underruns (just yet), | 2296 | /* don't handle FIFO overrun/underruns (just yet), |
| 2245 | * since they cause machine lockups | 2297 | * since they cause machine lockups |
| @@ -2373,14 +2425,29 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, | |||
| 2373 | 2425 | ||
| 2374 | if (! c->no_mpu401) { | 2426 | if (! c->no_mpu401) { |
| 2375 | if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { | 2427 | if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { |
| 2428 | struct snd_mpu401 *mpu; | ||
| 2376 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, | 2429 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, |
| 2377 | ICEREG1724(ice, MPU_CTRL), | 2430 | ICEREG1724(ice, MPU_CTRL), |
| 2378 | MPU401_INFO_INTEGRATED, | 2431 | (MPU401_INFO_INTEGRATED | |
| 2432 | MPU401_INFO_TX_IRQ), | ||
| 2379 | ice->irq, 0, | 2433 | ice->irq, 0, |
| 2380 | &ice->rmidi[0])) < 0) { | 2434 | &ice->rmidi[0])) < 0) { |
| 2381 | snd_card_free(card); | 2435 | snd_card_free(card); |
| 2382 | return err; | 2436 | return err; |
| 2383 | } | 2437 | } |
| 2438 | mpu = ice->rmidi[0]->private_data; | ||
| 2439 | mpu->read = snd_vt1724_mpu401_read; | ||
| 2440 | mpu->write = snd_vt1724_mpu401_write; | ||
| 2441 | /* unmask MPU RX/TX irqs */ | ||
| 2442 | outb(inb(ICEREG1724(ice, IRQMASK)) & | ||
| 2443 | ~(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX), | ||
| 2444 | ICEREG1724(ice, IRQMASK)); | ||
| 2445 | #if 0 /* for testing */ | ||
| 2446 | /* set watermarks */ | ||
| 2447 | outb(VT1724_MPU_RX_FIFO | 0x1, | ||
| 2448 | ICEREG1724(ice, MPU_FIFO_WM)); | ||
| 2449 | outb(0x1, ICEREG1724(ice, MPU_FIFO_WM)); | ||
| 2450 | #endif | ||
| 2384 | } | 2451 | } |
| 2385 | } | 2452 | } |
| 2386 | 2453 | ||
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 25ceb67a9c16..48d3679292a7 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c | |||
| @@ -812,10 +812,6 @@ struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { | |||
| 812 | .build_controls = prodigy192_add_controls, | 812 | .build_controls = prodigy192_add_controls, |
| 813 | .eeprom_size = sizeof(prodigy71_eeprom), | 813 | .eeprom_size = sizeof(prodigy71_eeprom), |
| 814 | .eeprom_data = prodigy71_eeprom, | 814 | .eeprom_data = prodigy71_eeprom, |
| 815 | /* the current MPU401 code loops infinitely | ||
| 816 | * when opening midi device | ||
| 817 | */ | ||
| 818 | .no_mpu401 = 1, | ||
| 819 | }, | 815 | }, |
| 820 | { } /* terminator */ | 816 | { } /* terminator */ |
| 821 | }; | 817 | }; |
