linux/sound/pci/echoaudio/midi.c
<<
>>
Prefs
   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 */
  37static int enable_midi_input(struct echoaudio *chip, char enable)
  38{
  39        DE_MID(("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
  59Returns how many actually written or < 0 on error */
  60static 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        DE_MID(("write_midi: %d\n", bytes));
  78        return bytes;
  79}
  80
  81
  82
  83/* Run the state machine for MIDI input data
  84MIDI time code sync isn't supported by this code right now, but you still need
  85this state machine to parse the incoming MIDI data stream.  Every time the DSP
  86sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data
  87stream. The DSP sample position is represented as a 32 bit unsigned value,
  88with the high 16 bits first, followed by the low 16 bits. Since these aren't
  89real MIDI bytes, the following logic is needed to skip them. */
  90static 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
 115from the DSP's buffer.  It returns the number of bytes received. */
 116static 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        i = 1;
 128        received = 0;
 129        for (i = 1; i <= count; i++) {
 130                /* Get the MIDI byte */
 131                midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]);
 132
 133                /* Parse the incoming MIDI stream. The incoming MIDI data
 134                consists of MIDI bytes and timestamps for the MIDI time code
 135                0xF1 bytes. mtc_process_data() is a little state machine that
 136                parses the stream. If you get MIDI_IN_SKIP_DATA back, then
 137                this is a timestamp byte, not a MIDI byte, so don't store it
 138                in the MIDI input buffer. */
 139                if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA)
 140                        continue;
 141
 142                chip->midi_buffer[received++] = (u8)midi_byte;
 143        }
 144
 145        return received;
 146}
 147
 148
 149
 150
 151/******************************************************************************
 152        MIDI interface
 153******************************************************************************/
 154
 155static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream)
 156{
 157        struct echoaudio *chip = substream->rmidi->private_data;
 158
 159        chip->midi_in = substream;
 160        DE_MID(("rawmidi_iopen\n"));
 161        return 0;
 162}
 163
 164
 165
 166static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream,
 167                                        int up)
 168{
 169        struct echoaudio *chip = substream->rmidi->private_data;
 170
 171        if (up != chip->midi_input_enabled) {
 172                spin_lock_irq(&chip->lock);
 173                enable_midi_input(chip, up);
 174                spin_unlock_irq(&chip->lock);
 175                chip->midi_input_enabled = up;
 176        }
 177}
 178
 179
 180
 181static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream)
 182{
 183        struct echoaudio *chip = substream->rmidi->private_data;
 184
 185        chip->midi_in = NULL;
 186        DE_MID(("rawmidi_iclose\n"));
 187        return 0;
 188}
 189
 190
 191
 192static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream)
 193{
 194        struct echoaudio *chip = substream->rmidi->private_data;
 195
 196        chip->tinuse = 0;
 197        chip->midi_full = 0;
 198        chip->midi_out = substream;
 199        DE_MID(("rawmidi_oopen\n"));
 200        return 0;
 201}
 202
 203
 204
 205static void snd_echo_midi_output_write(unsigned long data)
 206{
 207        struct echoaudio *chip = (struct echoaudio *)data;
 208        unsigned long flags;
 209        int bytes, sent, time;
 210        unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1];
 211
 212        DE_MID(("snd_echo_midi_output_write\n"));
 213        /* No interrupts are involved: we have to check at regular intervals
 214        if the card's output buffer has room for new data. */
 215        sent = bytes = 0;
 216        spin_lock_irqsave(&chip->lock, flags);
 217        chip->midi_full = 0;
 218        if (!snd_rawmidi_transmit_empty(chip->midi_out)) {
 219                bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf,
 220                                                  MIDI_OUT_BUFFER_SIZE - 1);
 221                DE_MID(("Try to send %d bytes...\n", bytes));
 222                sent = write_midi(chip, buf, bytes);
 223                if (sent < 0) {
 224                        snd_printk(KERN_ERR "write_midi() error %d\n", sent);
 225                        /* retry later */
 226                        sent = 9000;
 227                        chip->midi_full = 1;
 228                } else if (sent > 0) {
 229                        DE_MID(("%d bytes sent\n", sent));
 230                        snd_rawmidi_transmit_ack(chip->midi_out, sent);
 231                } else {
 232                        /* Buffer is full. DSP's internal buffer is 64 (128 ?)
 233                        bytes long. Let's wait until half of them are sent */
 234                        DE_MID(("Full\n"));
 235                        sent = 32;
 236                        chip->midi_full = 1;
 237                }
 238        }
 239
 240        /* We restart the timer only if there is some data left to send */
 241        if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) {
 242                /* The timer will expire slightly after the data has been
 243                   sent */
 244                time = (sent << 3) / 25 + 1;    /* 8/25=0.32ms to send a byte */
 245                mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000);
 246                DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000)));
 247        }
 248        spin_unlock_irqrestore(&chip->lock, flags);
 249}
 250
 251
 252
 253static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream,
 254                                         int up)
 255{
 256        struct echoaudio *chip = substream->rmidi->private_data;
 257
 258        DE_MID(("snd_echo_midi_output_trigger(%d)\n", up));
 259        spin_lock_irq(&chip->lock);
 260        if (up) {
 261                if (!chip->tinuse) {
 262                        init_timer(&chip->timer);
 263                        chip->timer.function = snd_echo_midi_output_write;
 264                        chip->timer.data = (unsigned long)chip;
 265                        chip->tinuse = 1;
 266                }
 267        } else {
 268                if (chip->tinuse) {
 269                        chip->tinuse = 0;
 270                        spin_unlock_irq(&chip->lock);
 271                        del_timer_sync(&chip->timer);
 272                        DE_MID(("Timer removed\n"));
 273                        return;
 274                }
 275        }
 276        spin_unlock_irq(&chip->lock);
 277
 278        if (up && !chip->midi_full)
 279                snd_echo_midi_output_write((unsigned long)chip);
 280}
 281
 282
 283
 284static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream)
 285{
 286        struct echoaudio *chip = substream->rmidi->private_data;
 287
 288        chip->midi_out = NULL;
 289        DE_MID(("rawmidi_oclose\n"));
 290        return 0;
 291}
 292
 293
 294
 295static struct snd_rawmidi_ops snd_echo_midi_input = {
 296        .open = snd_echo_midi_input_open,
 297        .close = snd_echo_midi_input_close,
 298        .trigger = snd_echo_midi_input_trigger,
 299};
 300
 301static struct snd_rawmidi_ops snd_echo_midi_output = {
 302        .open = snd_echo_midi_output_open,
 303        .close = snd_echo_midi_output_close,
 304        .trigger = snd_echo_midi_output_trigger,
 305};
 306
 307
 308
 309/* <--snd_echo_probe() */
 310static int __devinit snd_echo_midi_create(struct snd_card *card,
 311                                          struct echoaudio *chip)
 312{
 313        int err;
 314
 315        if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1,
 316                                   &chip->rmidi)) < 0)
 317                return err;
 318
 319        strcpy(chip->rmidi->name, card->shortname);
 320        chip->rmidi->private_data = chip;
 321
 322        snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
 323                            &snd_echo_midi_input);
 324        snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
 325                            &snd_echo_midi_output);
 326
 327        chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
 328                SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
 329        DE_INIT(("MIDI ok\n"));
 330        return 0;
 331}
 332