diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2005-10-20 16:57:51 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-11-04 07:19:26 -0500 |
commit | 8a5afd29dc16a9e687f63195cb635ecd611482d0 (patch) | |
tree | dff1950bd5302e5b2752e32075166638be1436dd /sound/pci/ca0106/ca0106_main.c | |
parent | b0b9811956db489ca43596c37ef2f38582454e51 (diff) |
[ALSA] snd-ca0106: Add midi support.
Modules: PCI drivers,CA0106 driver
Author: Tilman Kranz <tilde@tk-sls.de>
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Diffstat (limited to 'sound/pci/ca0106/ca0106_main.c')
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index f6920ef5b4ea..aaaef9e66af6 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -338,6 +338,18 @@ static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb) | |||
338 | spin_unlock_irqrestore(&emu->emu_lock, flags); | 338 | spin_unlock_irqrestore(&emu->emu_lock, flags); |
339 | } | 339 | } |
340 | 340 | ||
341 | static void snd_ca0106_intr_disable(ca0106_t *emu, unsigned int intrenb) | ||
342 | { | ||
343 | unsigned long flags; | ||
344 | unsigned int enable; | ||
345 | |||
346 | spin_lock_irqsave(&emu->emu_lock, flags); | ||
347 | enable = inl(emu->port + INTE) & ~intrenb; | ||
348 | outl(enable, emu->port + INTE); | ||
349 | spin_unlock_irqrestore(&emu->emu_lock, flags); | ||
350 | } | ||
351 | |||
352 | |||
341 | static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime) | 353 | static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime) |
342 | { | 354 | { |
343 | kfree(runtime->private_data); | 355 | kfree(runtime->private_data); |
@@ -1040,6 +1052,15 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, | |||
1040 | 1052 | ||
1041 | snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76); | 1053 | snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76); |
1042 | spin_lock(&chip->emu_lock); | 1054 | spin_lock(&chip->emu_lock); |
1055 | |||
1056 | if (chip->midi.dev_id && | ||
1057 | (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) { | ||
1058 | if (chip->midi.interrupt) | ||
1059 | chip->midi.interrupt(&chip->midi, status); | ||
1060 | else | ||
1061 | chip->midi.interrupt_disable(&chip->midi, chip->midi.tx_enable | chip->midi.rx_enable); | ||
1062 | } | ||
1063 | |||
1043 | // acknowledge the interrupt if necessary | 1064 | // acknowledge the interrupt if necessary |
1044 | outl(status, chip->port+IPR); | 1065 | outl(status, chip->port+IPR); |
1045 | 1066 | ||
@@ -1309,6 +1330,82 @@ static int __devinit snd_ca0106_create(snd_card_t *card, | |||
1309 | return 0; | 1330 | return 0; |
1310 | } | 1331 | } |
1311 | 1332 | ||
1333 | |||
1334 | void ca0106_midi_interrupt_enable(ca_midi_t *midi, int intr){ | ||
1335 | snd_ca0106_intr_enable((ca0106_t *)(midi->dev_id), intr); | ||
1336 | } | ||
1337 | |||
1338 | void ca0106_midi_interrupt_disable(ca_midi_t *midi, int intr){ | ||
1339 | snd_ca0106_intr_disable((ca0106_t *)(midi->dev_id), intr); | ||
1340 | } | ||
1341 | |||
1342 | unsigned char ca0106_midi_read(ca_midi_t *midi, int idx){ | ||
1343 | return (unsigned char)snd_ca0106_ptr_read((ca0106_t *)(midi->dev_id), midi->port + idx, 0); | ||
1344 | } | ||
1345 | |||
1346 | void ca0106_midi_write(ca_midi_t *midi, int data, int idx){ | ||
1347 | snd_ca0106_ptr_write((ca0106_t *)(midi->dev_id), midi->port + idx, 0, data); | ||
1348 | } | ||
1349 | |||
1350 | snd_card_t *ca0106_dev_id_card(void *dev_id){ | ||
1351 | return ((ca0106_t *)dev_id)->card; | ||
1352 | } | ||
1353 | |||
1354 | int ca0106_dev_id_port(void *dev_id){ | ||
1355 | return ((ca0106_t *)dev_id)->port; | ||
1356 | } | ||
1357 | |||
1358 | static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel) | ||
1359 | { | ||
1360 | ca_midi_t *midi; | ||
1361 | char *name; | ||
1362 | int err; | ||
1363 | |||
1364 | if(channel==CA0106_MIDI_CHAN_B) { | ||
1365 | name = "CA0106 MPU-401 (UART) B"; | ||
1366 | midi = &chip->midi2; | ||
1367 | midi->tx_enable = INTE_MIDI_TX_B; | ||
1368 | midi->rx_enable = INTE_MIDI_RX_B; | ||
1369 | midi->ipr_tx = IPR_MIDI_TX_B; | ||
1370 | midi->ipr_rx = IPR_MIDI_RX_B; | ||
1371 | midi->port = MIDI_UART_B_DATA; | ||
1372 | } else { | ||
1373 | name = "CA0106 MPU-401 (UART)"; | ||
1374 | midi = &chip->midi; | ||
1375 | midi->tx_enable = INTE_MIDI_TX_A; | ||
1376 | midi->rx_enable = INTE_MIDI_TX_B; | ||
1377 | midi->ipr_tx = IPR_MIDI_TX_A; | ||
1378 | midi->ipr_rx = IPR_MIDI_RX_A; | ||
1379 | midi->port = MIDI_UART_A_DATA; | ||
1380 | } | ||
1381 | |||
1382 | midi->reset = CA0106_MPU401_RESET; | ||
1383 | midi->enter_uart = CA0106_MPU401_ENTER_UART; | ||
1384 | midi->ack = CA0106_MPU401_ACK; | ||
1385 | |||
1386 | midi->input_avail = CA0106_MIDI_INPUT_AVAIL; | ||
1387 | midi->output_ready = CA0106_MIDI_OUTPUT_READY; | ||
1388 | |||
1389 | midi->channel = channel; | ||
1390 | |||
1391 | midi->interrupt_enable = ca0106_midi_interrupt_enable; | ||
1392 | midi->interrupt_disable = ca0106_midi_interrupt_disable; | ||
1393 | |||
1394 | midi->read = ca0106_midi_read; | ||
1395 | midi->write = ca0106_midi_write; | ||
1396 | |||
1397 | midi->get_dev_id_card = ca0106_dev_id_card; | ||
1398 | midi->get_dev_id_port = ca0106_dev_id_port; | ||
1399 | |||
1400 | midi->dev_id = chip; | ||
1401 | |||
1402 | if ((err = ca_midi_init(chip, midi, 0, name)) < 0) | ||
1403 | return err; | ||
1404 | |||
1405 | return 0; | ||
1406 | } | ||
1407 | |||
1408 | |||
1312 | static int __devinit snd_ca0106_probe(struct pci_dev *pci, | 1409 | static int __devinit snd_ca0106_probe(struct pci_dev *pci, |
1313 | const struct pci_device_id *pci_id) | 1410 | const struct pci_device_id *pci_id) |
1314 | { | 1411 | { |
@@ -1360,6 +1457,20 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, | |||
1360 | return err; | 1457 | return err; |
1361 | } | 1458 | } |
1362 | 1459 | ||
1460 | #ifdef CONFIG_SND_DEBUG_DETECT | ||
1461 | printk("ca0106: probe for MIDI channel A ..."); | ||
1462 | #endif | ||
1463 | if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) { | ||
1464 | snd_card_free(card); | ||
1465 | #ifdef CONFIG_SND_DEBUG_DETECT | ||
1466 | printk(" failed, err=0x%x\n",err); | ||
1467 | #endif | ||
1468 | return err; | ||
1469 | } | ||
1470 | #ifdef CONFIG_SND_DEBUG_DETECT | ||
1471 | printk(" done.\n"); | ||
1472 | #endif | ||
1473 | |||
1363 | snd_ca0106_proc_init(chip); | 1474 | snd_ca0106_proc_init(chip); |
1364 | 1475 | ||
1365 | if ((err = snd_card_register(card)) < 0) { | 1476 | if ((err = snd_card_register(card)) < 0) { |