Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/au88x0/au88x0_mpu401.c
10817 views
1
/*
2
* Copyright (c) by Jaroslav Kysela <[email protected]>
3
* Routines for control of MPU-401 in UART mode
4
*
5
* Modified for the Aureal Vortex based Soundcards
6
* by Manuel Jander ([email protected]).
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
*
22
*/
23
24
#include <linux/time.h>
25
#include <linux/init.h>
26
#include <sound/core.h>
27
#include <sound/mpu401.h>
28
#include "au88x0.h"
29
30
/* Check for mpu401 mmio support. */
31
/* MPU401 legacy support is only provided as a emergency fallback *
32
* for older versions of ALSA. Its usage is strongly discouraged. */
33
#ifndef MPU401_HW_AUREAL
34
#define VORTEX_MPU401_LEGACY
35
#endif
36
37
/* Vortex MPU401 defines. */
38
#define MIDI_CLOCK_DIV 0x61
39
/* Standart MPU401 defines. */
40
#define MPU401_RESET 0xff
41
#define MPU401_ENTER_UART 0x3f
42
#define MPU401_ACK 0xfe
43
44
static int __devinit snd_vortex_midi(vortex_t * vortex)
45
{
46
struct snd_rawmidi *rmidi;
47
int temp, mode;
48
struct snd_mpu401 *mpu;
49
unsigned long port;
50
51
#ifdef VORTEX_MPU401_LEGACY
52
/* EnableHardCodedMPU401Port() */
53
/* Enable Legacy MIDI Interface port. */
54
port = (0x03 << 5); /* FIXME: static address. 0x330 */
55
temp =
56
(hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_PORT) |
57
CTRL_MIDI_EN | port;
58
hwwrite(vortex->mmio, VORTEX_CTRL, temp);
59
#else
60
/* Disable Legacy MIDI Interface port. */
61
temp =
62
(hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_PORT) &
63
~CTRL_MIDI_EN;
64
hwwrite(vortex->mmio, VORTEX_CTRL, temp);
65
#endif
66
/* Mpu401UartInit() */
67
mode = 1;
68
temp = hwread(vortex->mmio, VORTEX_CTRL2) & 0xffff00cf;
69
temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4;
70
hwwrite(vortex->mmio, VORTEX_CTRL2, temp);
71
hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET);
72
73
/* Check if anything is OK. */
74
temp = hwread(vortex->mmio, VORTEX_MIDI_DATA);
75
if (temp != MPU401_ACK /*0xfe */ ) {
76
printk(KERN_ERR "midi port doesn't acknowledge!\n");
77
return -ENODEV;
78
}
79
/* Enable MPU401 interrupts. */
80
hwwrite(vortex->mmio, VORTEX_IRQ_CTRL,
81
hwread(vortex->mmio, VORTEX_IRQ_CTRL) | IRQ_MIDI);
82
83
/* Create MPU401 instance. */
84
#ifdef VORTEX_MPU401_LEGACY
85
if ((temp =
86
snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330,
87
0, 0, 0, &rmidi)) != 0) {
88
hwwrite(vortex->mmio, VORTEX_CTRL,
89
(hwread(vortex->mmio, VORTEX_CTRL) &
90
~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
91
return temp;
92
}
93
#else
94
port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
95
if ((temp =
96
snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
97
MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO,
98
0, 0, &rmidi)) != 0) {
99
hwwrite(vortex->mmio, VORTEX_CTRL,
100
(hwread(vortex->mmio, VORTEX_CTRL) &
101
~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
102
return temp;
103
}
104
mpu = rmidi->private_data;
105
mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD);
106
#endif
107
/* Overwrite MIDI name */
108
snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI %d", CARD_NAME_SHORT , vortex->card->number);
109
110
vortex->rmidi = rmidi;
111
return 0;
112
}
113
114