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