Skip to content

Commit 33cd763

Browse files
committed
ALSA: ump: Export MIDI1 / UMP conversion helpers
Yet more preliminary work for the upcoming USB gadget support. Now export the helpers to convert between legacy MIDI1 and UMP data for handling the MIDI 1.0 USB interface. The header file is moved to include/sound. The API functions are slightly changed, so that they can be used without the direct access to snd_ump object. The allocation is done in ump.c itself as it's a simple kcalloc(). Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 4dce2f0 commit 33cd763

File tree

3 files changed

+57
-66
lines changed

3 files changed

+57
-66
lines changed

sound/core/ump_convert.h renamed to include/sound/ump_convert.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
2-
#ifndef __UMP_CONVERT_H
3-
#define __UMP_CONVERT_H
2+
#ifndef __SOUND_UMP_CONVERT_H
3+
#define __SOUND_UMP_CONVERT_H
44

55
#include <sound/ump_msg.h>
66

@@ -31,13 +31,16 @@ struct ump_cvt_to_ump {
3131
struct ump_cvt_to_ump_bank bank[16]; /* per channel */
3232
};
3333

34-
int snd_ump_convert_init(struct snd_ump_endpoint *ump);
35-
void snd_ump_convert_free(struct snd_ump_endpoint *ump);
36-
int snd_ump_convert_from_ump(struct snd_ump_endpoint *ump,
37-
const u32 *data, unsigned char *dst,
34+
int snd_ump_convert_from_ump(const u32 *data, unsigned char *dst,
3835
unsigned char *group_ret);
39-
void snd_ump_convert_to_ump(struct snd_ump_endpoint *ump,
40-
unsigned char group, unsigned char c);
41-
void snd_ump_reset_convert_to_ump(struct snd_ump_endpoint *ump,
42-
unsigned char group);
43-
#endif /* __UMP_CONVERT_H */
36+
void snd_ump_convert_to_ump(struct ump_cvt_to_ump *cvt, unsigned char group,
37+
unsigned int protocol, unsigned char c);
38+
39+
/* reset the converter context, called at each open to ump */
40+
static inline void snd_ump_convert_reset(struct ump_cvt_to_ump *ctx)
41+
{
42+
memset(ctx, 0, sizeof(*ctx));
43+
44+
}
45+
46+
#endif /* __SOUND_UMP_CONVERT_H */

sound/core/ump.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <sound/core.h>
1212
#include <sound/rawmidi.h>
1313
#include <sound/ump.h>
14-
#include "ump_convert.h"
14+
#include <sound/ump_convert.h>
1515

1616
#define ump_err(ump, fmt, args...) dev_err(&(ump)->core.dev, fmt, ##args)
1717
#define ump_warn(ump, fmt, args...) dev_warn(&(ump)->core.dev, fmt, ##args)
@@ -87,7 +87,7 @@ static void snd_ump_endpoint_free(struct snd_rawmidi *rmidi)
8787
ump->private_free(ump);
8888

8989
#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
90-
snd_ump_convert_free(ump);
90+
kfree(ump->out_cvts);
9191
#endif
9292
}
9393

@@ -1002,7 +1002,7 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
10021002
goto unlock;
10031003
}
10041004
ump->legacy_out_opens++;
1005-
snd_ump_reset_convert_to_ump(ump, group);
1005+
snd_ump_convert_reset(&ump->out_cvts[group]);
10061006
}
10071007
spin_lock_irq(&ump->legacy_locks[dir]);
10081008
ump->legacy_substreams[dir][group] = substream;
@@ -1091,7 +1091,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
10911091
ctx = &ump->out_cvts[group];
10921092
while (!ctx->ump_bytes &&
10931093
snd_rawmidi_transmit(substream, &c, 1) > 0)
1094-
snd_ump_convert_to_ump(ump, group, c);
1094+
snd_ump_convert_to_ump(ctx, group, ump->info.protocol, c);
10951095
if (ctx->ump_bytes && ctx->ump_bytes <= count) {
10961096
size = ctx->ump_bytes;
10971097
memcpy(buffer, ctx->ump, size);
@@ -1113,7 +1113,7 @@ static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src,
11131113
const int dir = SNDRV_RAWMIDI_STREAM_INPUT;
11141114
int size;
11151115

1116-
size = snd_ump_convert_from_ump(ump, src, buf, &group);
1116+
size = snd_ump_convert_from_ump(src, buf, &group);
11171117
if (size <= 0)
11181118
return;
11191119
spin_lock_irqsave(&ump->legacy_locks[dir], flags);
@@ -1130,17 +1130,17 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
11301130
bool input, output;
11311131
int err;
11321132

1133-
err = snd_ump_convert_init(ump);
1134-
if (err < 0)
1135-
return err;
1133+
ump->out_cvts = kcalloc(16, sizeof(*ump->out_cvts), GFP_KERNEL);
1134+
if (!ump->out_cvts)
1135+
return -ENOMEM;
11361136

11371137
input = ump->core.info_flags & SNDRV_RAWMIDI_INFO_INPUT;
11381138
output = ump->core.info_flags & SNDRV_RAWMIDI_INFO_OUTPUT;
11391139
err = snd_rawmidi_new(ump->core.card, id, device,
11401140
output ? 16 : 0, input ? 16 : 0,
11411141
&rmidi);
11421142
if (err < 0) {
1143-
snd_ump_convert_free(ump);
1143+
kfree(ump->out_cvts);
11441144
return err;
11451145
}
11461146

sound/core/ump_convert.c

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <sound/core.h>
99
#include <sound/asound.h>
1010
#include <sound/ump.h>
11-
#include "ump_convert.h"
11+
#include <sound/ump_convert.h>
1212

1313
/*
1414
* Upgrade / downgrade value bits
@@ -205,12 +205,18 @@ static int cvt_ump_sysex7_to_legacy(const u32 *data, unsigned char *buf)
205205
return size;
206206
}
207207

208-
/* convert from a UMP packet @data to MIDI 1.0 bytes at @buf;
209-
* the target group is stored at @group_ret,
210-
* returns the number of bytes of MIDI 1.0 stream
208+
/**
209+
* snd_ump_convert_from_ump - convert from UMP to legacy MIDI
210+
* @data: UMP packet
211+
* @buf: buffer to store legacy MIDI data
212+
* @group_ret: pointer to store the target group
213+
*
214+
* Convert from a UMP packet @data to MIDI 1.0 bytes at @buf.
215+
* The target group is stored at @group_ret.
216+
*
217+
* The function returns the number of bytes of MIDI 1.0 stream.
211218
*/
212-
int snd_ump_convert_from_ump(struct snd_ump_endpoint *ump,
213-
const u32 *data,
219+
int snd_ump_convert_from_ump(const u32 *data,
214220
unsigned char *buf,
215221
unsigned char *group_ret)
216222
{
@@ -230,6 +236,7 @@ int snd_ump_convert_from_ump(struct snd_ump_endpoint *ump,
230236

231237
return 0;
232238
}
239+
EXPORT_SYMBOL_GPL(snd_ump_convert_from_ump);
233240

234241
/*
235242
* MIDI 1 byte stream -> UMP conversion
@@ -302,10 +309,10 @@ static void fill_rpn(struct ump_cvt_to_ump_bank *cc,
302309
}
303310

304311
/* convert to a MIDI 1.0 Channel Voice message */
305-
static int cvt_legacy_cmd_to_ump(struct snd_ump_endpoint *ump,
306-
struct ump_cvt_to_ump *cvt,
307-
unsigned char group, u32 *data,
308-
unsigned char bytes)
312+
static int cvt_legacy_cmd_to_ump(struct ump_cvt_to_ump *cvt,
313+
unsigned char group,
314+
unsigned int protocol,
315+
u32 *data, unsigned char bytes)
309316
{
310317
const unsigned char *buf = cvt->buf;
311318
struct ump_cvt_to_ump_bank *cc;
@@ -316,7 +323,7 @@ static int cvt_legacy_cmd_to_ump(struct snd_ump_endpoint *ump,
316323
BUILD_BUG_ON(sizeof(union snd_ump_midi2_msg) != 8);
317324

318325
/* for MIDI 1.0 UMP, it's easy, just pack it into UMP */
319-
if (ump->info.protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI1) {
326+
if (protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI1) {
320327
data[0] = ump_compose(UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE,
321328
group, 0, buf[0]);
322329
data[0] |= buf[1] << 8;
@@ -413,8 +420,8 @@ static int cvt_legacy_cmd_to_ump(struct snd_ump_endpoint *ump,
413420
return 8;
414421
}
415422

416-
static int do_convert_to_ump(struct snd_ump_endpoint *ump,
417-
unsigned char group, unsigned char c, u32 *data)
423+
static int do_convert_to_ump(struct ump_cvt_to_ump *cvt, unsigned char group,
424+
unsigned int protocol, unsigned char c, u32 *data)
418425
{
419426
/* bytes for 0x80-0xf0 */
420427
static unsigned char cmd_bytes[8] = {
@@ -424,7 +431,6 @@ static int do_convert_to_ump(struct snd_ump_endpoint *ump,
424431
static unsigned char system_bytes[16] = {
425432
0, 2, 3, 2, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1
426433
};
427-
struct ump_cvt_to_ump *cvt = &ump->out_cvts[group];
428434
unsigned char bytes;
429435

430436
if (c == UMP_MIDI1_MSG_SYSEX_START) {
@@ -478,40 +484,22 @@ static int do_convert_to_ump(struct snd_ump_endpoint *ump,
478484
cvt->len = 1;
479485
if ((cvt->buf[0] & 0xf0) == UMP_MIDI1_MSG_REALTIME)
480486
return cvt_legacy_system_to_ump(cvt, group, data);
481-
return cvt_legacy_cmd_to_ump(ump, cvt, group, data, cvt->cmd_bytes);
487+
return cvt_legacy_cmd_to_ump(cvt, group, protocol, data, cvt->cmd_bytes);
482488
}
483489

484-
/* feed a MIDI 1.0 byte @c and convert to a UMP packet;
485-
* the target group is @group,
486-
* the result is stored in out_cvts[group].ump[] and out_cvts[group].ump_bytes
490+
/**
491+
* snd_ump_convert_to_ump - convert legacy MIDI byte to UMP packet
492+
* @cvt: converter context
493+
* @group: target UMP group
494+
* @protocol: target UMP protocol
495+
* @c: MIDI 1.0 byte data
496+
*
497+
* Feed a MIDI 1.0 byte @c and convert to a UMP packet if completed.
498+
* The result is stored in the buffer in @cvt.
487499
*/
488-
void snd_ump_convert_to_ump(struct snd_ump_endpoint *ump,
489-
unsigned char group, unsigned char c)
500+
void snd_ump_convert_to_ump(struct ump_cvt_to_ump *cvt, unsigned char group,
501+
unsigned int protocol, unsigned char c)
490502
{
491-
struct ump_cvt_to_ump *cvt = &ump->out_cvts[group];
492-
493-
cvt->ump_bytes = do_convert_to_ump(ump, group, c, cvt->ump);
494-
}
495-
496-
/* reset the converter context, called at each open */
497-
void snd_ump_reset_convert_to_ump(struct snd_ump_endpoint *ump,
498-
unsigned char group)
499-
{
500-
memset(&ump->out_cvts[group], 0, sizeof(*ump->out_cvts));
501-
}
502-
503-
/* initialize converters */
504-
int snd_ump_convert_init(struct snd_ump_endpoint *ump)
505-
{
506-
ump->out_cvts = kcalloc(16, sizeof(*ump->out_cvts), GFP_KERNEL);
507-
if (!ump->out_cvts)
508-
return -ENOMEM;
509-
return 0;
510-
}
511-
512-
/* release resources */
513-
void snd_ump_convert_free(struct snd_ump_endpoint *ump)
514-
{
515-
kfree(ump->out_cvts);
516-
ump->out_cvts = NULL;
503+
cvt->ump_bytes = do_convert_to_ump(cvt, group, protocol, c, cvt->ump);
517504
}
505+
EXPORT_SYMBOL_GPL(snd_ump_convert_to_ump);

0 commit comments

Comments
 (0)