2015-10-12 13:10:23 +03:00
/*
* tascam - midi . c - a part of driver for TASCAM FireWire series
*
* Copyright ( c ) 2015 Takashi Sakamoto
*
* Licensed under the terms of the GNU General Public License , version 2.
*/
# include "tascam.h"
static int midi_capture_open ( struct snd_rawmidi_substream * substream )
{
/* Do nothing. */
return 0 ;
}
static int midi_playback_open ( struct snd_rawmidi_substream * substream )
{
struct snd_tscm * tscm = substream - > rmidi - > private_data ;
2017-04-14 10:46:30 +03:00
snd_fw_async_midi_port_init ( & tscm - > out_ports [ substream - > number ] ) ;
2015-10-12 13:10:23 +03:00
return 0 ;
}
static int midi_capture_close ( struct snd_rawmidi_substream * substream )
{
/* Do nothing. */
return 0 ;
}
static int midi_playback_close ( struct snd_rawmidi_substream * substream )
2017-04-14 10:46:32 +03:00
{
return 0 ;
}
static void midi_playback_drain ( struct snd_rawmidi_substream * substream )
2015-10-12 13:10:23 +03:00
{
struct snd_tscm * tscm = substream - > rmidi - > private_data ;
snd_fw_async_midi_port_finish ( & tscm - > out_ports [ substream - > number ] ) ;
}
static void midi_capture_trigger ( struct snd_rawmidi_substream * substrm , int up )
{
struct snd_tscm * tscm = substrm - > rmidi - > private_data ;
unsigned long flags ;
spin_lock_irqsave ( & tscm - > lock , flags ) ;
if ( up )
tscm - > tx_midi_substreams [ substrm - > number ] = substrm ;
else
tscm - > tx_midi_substreams [ substrm - > number ] = NULL ;
spin_unlock_irqrestore ( & tscm - > lock , flags ) ;
}
static void midi_playback_trigger ( struct snd_rawmidi_substream * substrm , int up )
{
struct snd_tscm * tscm = substrm - > rmidi - > private_data ;
unsigned long flags ;
spin_lock_irqsave ( & tscm - > lock , flags ) ;
if ( up )
snd_fw_async_midi_port_run ( & tscm - > out_ports [ substrm - > number ] ,
substrm ) ;
spin_unlock_irqrestore ( & tscm - > lock , flags ) ;
}
int snd_tscm_create_midi_devices ( struct snd_tscm * tscm )
{
2017-01-05 19:29:54 +03:00
static const struct snd_rawmidi_ops capture_ops = {
2017-01-05 15:48:12 +03:00
. open = midi_capture_open ,
. close = midi_capture_close ,
. trigger = midi_capture_trigger ,
} ;
2017-01-05 19:29:54 +03:00
static const struct snd_rawmidi_ops playback_ops = {
2017-01-05 15:48:12 +03:00
. open = midi_playback_open ,
. close = midi_playback_close ,
2017-04-14 10:46:32 +03:00
. drain = midi_playback_drain ,
2017-01-05 15:48:12 +03:00
. trigger = midi_playback_trigger ,
} ;
2015-10-12 13:10:23 +03:00
struct snd_rawmidi * rmidi ;
struct snd_rawmidi_str * stream ;
struct snd_rawmidi_substream * subs ;
int err ;
err = snd_rawmidi_new ( tscm - > card , tscm - > card - > driver , 0 ,
tscm - > spec - > midi_playback_ports ,
tscm - > spec - > midi_capture_ports ,
& rmidi ) ;
if ( err < 0 )
return err ;
snprintf ( rmidi - > name , sizeof ( rmidi - > name ) ,
" %s MIDI " , tscm - > card - > shortname ) ;
rmidi - > private_data = tscm ;
rmidi - > info_flags | = SNDRV_RAWMIDI_INFO_INPUT ;
snd_rawmidi_set_ops ( rmidi , SNDRV_RAWMIDI_STREAM_INPUT ,
2017-01-05 15:48:12 +03:00
& capture_ops ) ;
2015-10-12 13:10:23 +03:00
stream = & rmidi - > streams [ SNDRV_RAWMIDI_STREAM_INPUT ] ;
/* Set port names for MIDI input. */
list_for_each_entry ( subs , & stream - > substreams , list ) {
/* TODO: support virtual MIDI ports. */
if ( subs - > number < tscm - > spec - > midi_capture_ports ) {
/* Hardware MIDI ports. */
snprintf ( subs - > name , sizeof ( subs - > name ) ,
" %s MIDI %d " ,
tscm - > card - > shortname , subs - > number + 1 ) ;
}
}
rmidi - > info_flags | = SNDRV_RAWMIDI_INFO_OUTPUT ;
snd_rawmidi_set_ops ( rmidi , SNDRV_RAWMIDI_STREAM_OUTPUT ,
2017-01-05 15:48:12 +03:00
& playback_ops ) ;
2015-10-12 13:10:23 +03:00
stream = & rmidi - > streams [ SNDRV_RAWMIDI_STREAM_OUTPUT ] ;
/* Set port names for MIDI ourput. */
list_for_each_entry ( subs , & stream - > substreams , list ) {
if ( subs - > number < tscm - > spec - > midi_playback_ports ) {
/* Hardware MIDI ports only. */
snprintf ( subs - > name , sizeof ( subs - > name ) ,
" %s MIDI %d " ,
tscm - > card - > shortname , subs - > number + 1 ) ;
}
}
rmidi - > info_flags | = SNDRV_RAWMIDI_INFO_DUPLEX ;
return 0 ;
}