1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3
4 Copyright Echo Digital Audio Corporation (c) 1998 - 2004
5 All rights reserved
6 www.echoaudio.com
7
8 This file is part of Echo Digital Audio's generic driver library.
9 *************************************************************************
10
11 Translation from C++ and adaptation for use in ALSA-Driver
12 were made by Giuliano Pochini <pochini@shiny.it>
13
14 ****************************************************************************/
15
16
17 /******************************************************************************
18 MIDI lowlevel code
19 ******************************************************************************/
20
21 /* Start and stop Midi input */
enable_midi_input(struct echoaudio * chip,char enable)22 static int enable_midi_input(struct echoaudio *chip, char enable)
23 {
24 dev_dbg(chip->card->dev, "enable_midi_input(%d)\n", enable);
25
26 if (wait_handshake(chip))
27 return -EIO;
28
29 if (enable) {
30 chip->mtc_state = MIDI_IN_STATE_NORMAL;
31 chip->comm_page->flags |=
32 cpu_to_le32(DSP_FLAG_MIDI_INPUT);
33 } else
34 chip->comm_page->flags &=
35 ~cpu_to_le32(DSP_FLAG_MIDI_INPUT);
36
37 clear_handshake(chip);
38 return send_vector(chip, DSP_VC_UPDATE_FLAGS);
39 }
40
41
42
43 /* Send a buffer full of MIDI data to the DSP
44 Returns how many actually written or < 0 on error */
write_midi(struct echoaudio * chip,u8 * data,int bytes)45 static int write_midi(struct echoaudio *chip, u8 *data, int bytes)
46 {
47 if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE))
48 return -EINVAL;
49
50 if (wait_handshake(chip))
51 return -EIO;
52
53 /* HF4 indicates that it is safe to write MIDI output data */
54 if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4))
55 return 0;
56
57 chip->comm_page->midi_output[0] = bytes;
58 memcpy(&chip->comm_page->midi_output[1], data, bytes);
59 chip->comm_page->midi_out_free_count = 0;
60 clear_handshake(chip);
61 send_vector(chip, DSP_VC_MIDI_WRITE);
62 dev_dbg(chip->card->dev, "write_midi: %d\n", bytes);
63 return bytes;
64 }
65
66
67
68 /* Run the state machine for MIDI input data
69 MIDI time code sync isn't supported by this code right now, but you still need
70 this state machine to parse the incoming MIDI data stream. Every time the DSP
71 sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data
72 stream. The DSP sample position is represented as a 32 bit unsigned value,
73 with the high 16 bits first, followed by the low 16 bits. Since these aren't
74 real MIDI bytes, the following logic is needed to skip them. */
mtc_process_data(struct echoaudio * chip,short midi_byte)75 static inline int mtc_process_data(struct echoaudio *chip, short midi_byte)
76 {
77 switch (chip->mtc_state) {
78 case MIDI_IN_STATE_NORMAL:
79 if (midi_byte == 0xF1)
80 chip->mtc_state = MIDI_IN_STATE_TS_HIGH;
81 break;
82 case MIDI_IN_STATE_TS_HIGH:
83 chip->mtc_state = MIDI_IN_STATE_TS_LOW;
84 return MIDI_IN_SKIP_DATA;
85 break;
86 case MIDI_IN_STATE_TS_LOW:
87 chip->mtc_state = MIDI_IN_STATE_F1_DATA;
88 return MIDI_IN_SKIP_DATA;
89 break;
90 case MIDI_IN_STATE_F1_DATA:
91 chip->mtc_state = MIDI_IN_STATE_NORMAL;
92 break;
93 }
94 return 0;
95 }
96
97
98
99 /* This function is called from the IRQ handler and it reads the midi data
100 from the DSP's buffer. It returns the number of bytes received. */
midi_service_irq(struct echoaudio * chip)101 static int midi_service_irq(struct echoaudio *chip)
102 {
103 short int count, midi_byte, i, received;
104
105 /* The count is at index 0, followed by actual data */
106 count = le16_to_cpu(chip->comm_page->midi_input[0]);
107
108 if (snd_BUG_ON(count >= MIDI_IN_BUFFER_SIZE))
109 return 0;
110
111 /* Get the MIDI data from the comm page */
112 received = 0;
113 for (i = 1; i <= count; i++) {
114 /* Get the MIDI byte */
115 midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]);
116
117 /* Parse the incoming MIDI stream. The incoming MIDI data
118 consists of MIDI bytes and timestamps for the MIDI time code
119 0xF1 bytes. mtc_process_data() is a little state machine that
120 parses the stream. If you get MIDI_IN_SKIP_DATA back, then
121 this is a timestamp byte, not a MIDI byte, so don't store it
122 in the MIDI input buffer. */
123 if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA)
124 continue;
125
126 chip->midi_buffer[received++] = (u8)midi_byte;
127 }
128
129 return received;
130 }
131
132
133
134
135 /******************************************************************************
136 MIDI interface
137 ******************************************************************************/
138
snd_echo_midi_input_open(struct snd_rawmidi_substream * substream)139 static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream)
140 {
141 struct echoaudio *chip = substream->rmidi->private_data;
142
143 chip->midi_in = substream;
144 return 0;
145 }
146
147
148
snd_echo_midi_input_trigger(struct snd_rawmidi_substream * substream,int up)149 static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream,
150 int up)
151 {
152 struct echoaudio *chip = substream->rmidi->private_data;
153
154 if (up != chip->midi_input_enabled) {
155 guard(spinlock_irq)(&chip->lock);
156 enable_midi_input(chip, up);
157 chip->midi_input_enabled = up;
158 }
159 }
160
161
162
snd_echo_midi_input_close(struct snd_rawmidi_substream * substream)163 static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream)
164 {
165 struct echoaudio *chip = substream->rmidi->private_data;
166
167 chip->midi_in = NULL;
168 return 0;
169 }
170
171
172
snd_echo_midi_output_open(struct snd_rawmidi_substream * substream)173 static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream)
174 {
175 struct echoaudio *chip = substream->rmidi->private_data;
176
177 chip->tinuse = 0;
178 chip->midi_full = 0;
179 chip->midi_out = substream;
180 return 0;
181 }
182
183
184
snd_echo_midi_output_write(struct timer_list * t)185 static void snd_echo_midi_output_write(struct timer_list *t)
186 {
187 struct echoaudio *chip = timer_container_of(chip, t, timer);
188 int bytes, sent, time;
189 unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1];
190
191 /* No interrupts are involved: we have to check at regular intervals
192 if the card's output buffer has room for new data. */
193 sent = 0;
194 guard(spinlock_irqsave)(&chip->lock);
195 chip->midi_full = 0;
196 if (!snd_rawmidi_transmit_empty(chip->midi_out)) {
197 bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf,
198 MIDI_OUT_BUFFER_SIZE - 1);
199 dev_dbg(chip->card->dev, "Try to send %d bytes...\n", bytes);
200 sent = write_midi(chip, buf, bytes);
201 if (sent < 0) {
202 dev_err(chip->card->dev,
203 "write_midi() error %d\n", sent);
204 /* retry later */
205 sent = 9000;
206 chip->midi_full = 1;
207 } else if (sent > 0) {
208 dev_dbg(chip->card->dev, "%d bytes sent\n", sent);
209 snd_rawmidi_transmit_ack(chip->midi_out, sent);
210 } else {
211 /* Buffer is full. DSP's internal buffer is 64 (128 ?)
212 bytes long. Let's wait until half of them are sent */
213 dev_dbg(chip->card->dev, "Full\n");
214 sent = 32;
215 chip->midi_full = 1;
216 }
217 }
218
219 /* We restart the timer only if there is some data left to send */
220 if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) {
221 /* The timer will expire slightly after the data has been
222 sent */
223 time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */
224 mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000);
225 dev_dbg(chip->card->dev,
226 "Timer armed(%d)\n", ((time * HZ + 999) / 1000));
227 }
228 }
229
230
231
snd_echo_midi_output_trigger(struct snd_rawmidi_substream * substream,int up)232 static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream,
233 int up)
234 {
235 struct echoaudio *chip = substream->rmidi->private_data;
236 bool remove_timer = false;
237
238 dev_dbg(chip->card->dev, "snd_echo_midi_output_trigger(%d)\n", up);
239 scoped_guard(spinlock_irq, &chip->lock) {
240 if (up) {
241 if (!chip->tinuse) {
242 timer_setup(&chip->timer, snd_echo_midi_output_write,
243 0);
244 chip->tinuse = 1;
245 }
246 } else {
247 if (chip->tinuse) {
248 chip->tinuse = 0;
249 remove_timer = true;
250 }
251 }
252 }
253
254 if (remove_timer) {
255 timer_delete_sync(&chip->timer);
256 dev_dbg(chip->card->dev, "Timer removed\n");
257 return;
258 }
259
260 if (up && !chip->midi_full)
261 snd_echo_midi_output_write(&chip->timer);
262 }
263
264
265
snd_echo_midi_output_close(struct snd_rawmidi_substream * substream)266 static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream)
267 {
268 struct echoaudio *chip = substream->rmidi->private_data;
269
270 chip->midi_out = NULL;
271 return 0;
272 }
273
274
275
276 static const struct snd_rawmidi_ops snd_echo_midi_input = {
277 .open = snd_echo_midi_input_open,
278 .close = snd_echo_midi_input_close,
279 .trigger = snd_echo_midi_input_trigger,
280 };
281
282 static const struct snd_rawmidi_ops snd_echo_midi_output = {
283 .open = snd_echo_midi_output_open,
284 .close = snd_echo_midi_output_close,
285 .trigger = snd_echo_midi_output_trigger,
286 };
287
288
289
290 /* <--snd_echo_probe() */
snd_echo_midi_create(struct snd_card * card,struct echoaudio * chip)291 static int snd_echo_midi_create(struct snd_card *card,
292 struct echoaudio *chip)
293 {
294 int err;
295
296 err = snd_rawmidi_new(card, card->shortname, 0, 1, 1, &chip->rmidi);
297 if (err < 0)
298 return err;
299
300 strscpy(chip->rmidi->name, card->shortname);
301 chip->rmidi->private_data = chip;
302
303 snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
304 &snd_echo_midi_input);
305 snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
306 &snd_echo_midi_output);
307
308 chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
309 SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
310 return 0;
311 }
312