^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __SOUND_RAWMIDI_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __SOUND_RAWMIDI_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Abstract layer for MIDI v1.0 stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sound/asound.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #if IS_ENABLED(CONFIG_SND_SEQUENCER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/seq_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Raw MIDI interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SNDRV_RAWMIDI_DEVICES 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SNDRV_RAWMIDI_LFLG_OUTPUT (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SNDRV_RAWMIDI_LFLG_INPUT (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SNDRV_RAWMIDI_LFLG_OPEN (3<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SNDRV_RAWMIDI_LFLG_APPEND (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct snd_rawmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct snd_rawmidi_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct snd_seq_port_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct snd_rawmidi_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int (*open) (struct snd_rawmidi_substream * substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int (*close) (struct snd_rawmidi_substream * substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void (*trigger) (struct snd_rawmidi_substream * substream, int up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void (*drain) (struct snd_rawmidi_substream * substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct snd_rawmidi_global_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int (*dev_register) (struct snd_rawmidi * rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int (*dev_unregister) (struct snd_rawmidi * rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void (*get_port_info)(struct snd_rawmidi *rmidi, int number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct snd_seq_port_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct snd_rawmidi_runtime {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct snd_rawmidi_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int drain: 1, /* drain stage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) oss: 1; /* OSS compatible mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* midi stream buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned char *buffer; /* buffer for MIDI data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) size_t buffer_size; /* size of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) size_t appl_ptr; /* application pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) size_t hw_ptr; /* hardware pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) size_t avail_min; /* min avail for wakeup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) size_t avail; /* max used buffer for wakeup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) size_t xruns; /* over/underruns counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int buffer_ref; /* buffer reference count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* misc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) wait_queue_head_t sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* event handler (new bytes, input only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void (*event)(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* defers calls to event [input] or ops->trigger [output] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct work_struct event_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void *private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) void (*private_free)(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct snd_rawmidi_substream {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct list_head list; /* list of all substream for given stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int stream; /* direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int number; /* substream number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) bool opened; /* open flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) bool append; /* append flag (merge more streams) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bool active_sensing; /* send active sensing when close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int use_count; /* use counter (for output) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) size_t bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct snd_rawmidi_str *pstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) char name[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct snd_rawmidi_runtime *runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* hardware layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) const struct snd_rawmidi_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct snd_rawmidi_file {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct snd_rawmidi_substream *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct snd_rawmidi_substream *output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct snd_rawmidi_str {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned int substream_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned int substream_opened;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct list_head substreams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct snd_rawmidi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned int device; /* device number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned int info_flags; /* SNDRV_RAWMIDI_INFO_XXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) char id[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) char name[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #ifdef CONFIG_SND_OSSEMUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int ossreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) const struct snd_rawmidi_global_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct snd_rawmidi_str streams[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void *private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void (*private_free) (struct snd_rawmidi *rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct mutex open_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) wait_queue_head_t open_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct snd_info_entry *proc_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #if IS_ENABLED(CONFIG_SND_SEQUENCER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct snd_seq_device *seq_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* main rawmidi functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int snd_rawmidi_new(struct snd_card *card, char *id, int device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int output_count, int input_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct snd_rawmidi **rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const struct snd_rawmidi_ops *ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) const unsigned char *buffer, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned char *buffer, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned char *buffer, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned char *buffer, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* main midi functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int mode, struct snd_rawmidi_file *rfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct snd_rawmidi_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct snd_rawmidi_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned char *buf, long count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) const unsigned char *buf, long count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif /* __SOUND_RAWMIDI_H */