// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Helpers for UMP <-> MIDI 1.0 byte stream conversion
 */

#include <linux/module.h>
#include <linux/export.h>
#include <sound/core.h>
#include <sound/asound.h>
#include <sound/ump.h>
#include <sound/ump_convert.h>

/*
 * Upgrade / downgrade value bits
 */
static u8 downscale_32_to_7bit(u32 src)
{
	return src >> 25;
}

static u16 downscale_32_to_14bit(u32 src)
{
	return src >> 18;
}

static u8 downscale_16_to_7bit(u16 src)
{
	return src >> 9;
}

static u16 upscale_7_to_16bit(u8 src)
{
	u16 val, repeat;

	val = (u16)src << 9;
	if (src <= 0x40)
		return val;
	repeat = src & 0x3f;
	return val | (repeat << 3) | (repeat >> 3);
}

static u32 upscale_7_to_32bit(u8 src)
{
	u32 val, repeat;

	val = src << 25;
	if (src <= 0x40)
		return val;
	repeat = src & 0x3f;
	return val | (repeat << 19) | (repeat << 13) |
		(repeat << 7) | (repeat << 1) | (repeat >> 5);
}

static u32 upscale_14_to_32bit(u16 src)
{
	u32 val, repeat;

	val = src << 18;
	if (src <= 0x2000)
		return val;
	repeat = src & 0x1fff;
	return val | (repeat << 5) | (repeat >> 8);
}

/*
 * UMP -> MIDI 1 byte stream conversion
 */
/* convert a UMP System message to MIDI 1.0 byte stream */
static int cvt_ump_system_to_legacy(u32 data, unsigned char *buf)
{
	buf[0] = ump_message_status_channel(data);
	switch (ump_message_status_code(data)) {
	case UMP_SYSTEM_STATUS_MIDI_TIME_CODE:
	case UMP_SYSTEM_STATUS_SONG_SELECT:
		buf[1] = (data >> 8) & 0x7f;
		return 2;
	case UMP_SYSTEM_STATUS_SONG_POSITION:
		buf[1] = (data >> 8) & 0x7f;
		buf[2] = data & 0x7f;
		return 3;
	default:
		return 1;
	}
}

/* convert a UMP MIDI 1.0 Channel Voice message to MIDI 1.0 byte stream */
static int cvt_ump_midi1_to_legacy(u32 data, unsigned char *buf)
{
	buf[0] = ump_message_status_channel(data);
	buf[1] = (data >> 8) & 0xff;
	switch (ump_message_status_code(data)) {
	case UMP_MSG_STATUS_PROGRAM:
	case UMP_MSG_STATUS_CHANNEL_PRESSURE:
		return 2;
	default:
		buf[2] = data & 0xff;
		return 3;
	}
}

/* convert a UMP MIDI 2.0 Channel Voice message to MIDI 1.0 byte stream */
static int cvt_ump_midi2_to_legacy(const union snd_ump_midi2_msg *midi2,
				   unsigned char *buf)
{
	unsigned char status = midi2->note.status;
	unsigned char channel = midi2->note.channel;
	u16 v;

	buf[0] = (status << 4) | channel;
	switch (status) {
	case UMP_MSG_STATUS_NOTE_OFF:
	case UMP_MSG_STATUS_NOTE_ON:
		buf[1] = midi2->note.note;
		buf[2] = downscale_16_to_7bit(midi2->note.velocity);
		if (status == UMP_MSG_STATUS_NOTE_ON && !buf[2])
			buf[2] = 1;
		return 3;
	case UMP_MSG_STATUS_POLY_PRESSURE:
		buf[1] = midi2->paf.note;
		buf[2] = downscale_32_to_7bit(midi2->paf.data);
		return 3;
	case UMP_MSG_STATUS_CC:
		buf[1] = midi2->cc.index;
		buf[2] = downscale_32_to_7bit(midi2->cc.data);
		return 3;
	case UMP_MSG_STATUS_CHANNEL_PRESSURE:
		buf[1] = downscale_32_to_7bit(midi2->caf.data);
		return 2;
	case UMP_MSG_STATUS_PROGRAM:
		if (midi2->pg.bank_valid) {
			buf[0] = channel | (UMP_MSG_STATUS_CC << 4);
			buf[1] = UMP_CC_BANK_SELECT;
			buf[2] = midi2->pg.bank_msb;
			buf[3] = channel | (UMP_MSG_STATUS_CC << 4);
			buf[4] = UMP_CC_BANK_SELECT_LSB;
			buf[5] = midi2->pg.bank_lsb;
			buf[6] = channel | (UMP_MSG_STATUS_PROGRAM << 4);
			buf[7] = midi2->pg.program;
			return 8;
		}
		buf[1] = midi2->pg.program;
		return 2;
	case UMP_MSG_STATUS_PITCH_BEND:
		v = downscale_32_to_14bit(midi2->pb.data);
		buf[1] = v & 0x7f;
		buf[2] = v >> 7;
		return 3;
	case UMP_MSG_STATUS_RPN:
	case UMP_MSG_STATUS_NRPN:
		buf[0] = channel | (UMP_MSG_STATUS_CC << 4);
		buf[1] = status == UMP_MSG_STATUS_RPN ? UMP_CC_RPN_MSB : UMP_CC_NRPN_MSB;
		buf[2] = midi2->rpn.bank;
		buf[3] = buf[0];
		buf[4] = status == UMP_MSG_STATUS_RPN ? UMP_CC_RPN_LSB : UMP_CC_NRPN_LSB;
		buf[5] = midi2->rpn.index;
		buf[6] = buf[0];
		buf[7] = UMP_CC_DATA;
		v = downscale_32_to_14bit(midi2->rpn.data);
		buf[8] = v >> 7;
		buf[9] = buf[0];
		buf[10] = UMP_CC_DATA_LSB;
		buf[11] = v & 0x7f;
		return 12;
	default:
		return 0;
	}
}

/* convert a UMP 7-bit SysEx message to MIDI 1.0 byte stream */
static int cvt_ump_sysex7_to_legacy(const u32 *data, unsigned char *buf)
{
	unsigned char status;
	unsigned char bytes;
	int size, offset;

	status = ump_sysex_message_status(*data);
	if (status > UMP_SYSEX_STATUS_END)
		return 0; // unsupported, skip
	bytes = ump_sysex_message_length(*data);
	if (bytes > 6)
		return 0; // skip

	size = 0;
	if (status == UMP_SYSEX_STATUS_SINGLE ||
	    status == UMP_SYSEX_STATUS_START) {
		buf[0] = UMP_MIDI1_MSG_SYSEX_START;
		size = 1;
	}

	offset = 8;
	for (; bytes; bytes--, size++) {
		buf[size] = (*data >> offset) & 0x7f;
		if (!offset) {
			offset = 24;
			data++;
		} else {
			offset -= 8;
		}
	}

	if (status == UMP_SYSEX_STATUS_SINGLE ||
	    status == UMP_SYSEX_STATUS_END)
		buf[size++] = UMP_MIDI1_MSG_SYSEX_END;

	return size;
}

/**
 * snd_ump_convert_from_ump - convert from UMP to legacy MIDI
 * @data: UMP packet
 * @buf: buffer to store legacy MIDI data
 * @group_ret: pointer to store the target group
 *
 * Convert from a UMP packet @data to MIDI 1.0 bytes at @buf.
 * The target group is stored at @group_ret.
 *
 * The function returns the number of bytes of MIDI 1.0 stream.
 */
int snd_ump_convert_from_ump(const u32 *data,
			     unsigned char *buf,
			     unsigned char *group_ret)
{
	*group_ret = ump_message_group(*data);

	switch (ump_message_type(*data)) {
	case UMP_MSG_TYPE_SYSTEM:
		return cvt_ump_system_to_legacy(*data, buf);
	case UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE:
		return cvt_ump_midi1_to_legacy(*data, buf);
	case UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE:
		return cvt_ump_midi2_to_legacy((const union snd_ump_midi2_msg *)data,
					       buf);
	case UMP_MSG_TYPE_DATA:
		return cvt_ump_sysex7_to_legacy(data, buf);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_ump_convert_from_ump);

/*
 * MIDI 1 byte stream -> UMP conversion
 */
/* convert MIDI 1.0 SysEx to a UMP packet */
static int cvt_legacy_sysex_to_ump(struct ump_cvt_to_ump *cvt,
				   unsigned char group, u32 *data, bool finish)
{
	unsigned char status;
	bool start = cvt->in_sysex == 1;
	int i, offset;

	if (start && finish)
		status = UMP_SYSEX_STATUS_SINGLE;
	else if (start)
		status = UMP_SYSEX_STATUS_START;
	else if (finish)
		status = UMP_SYSEX_STATUS_END;
	else
		status = UMP_SYSEX_STATUS_CONTINUE;
	*data = ump_compose(UMP_MSG_TYPE_DATA, group, status, cvt->len);
	offset = 8;
	for (i = 0; i < cvt->len; i++) {
		*data |= cvt->buf[i] << offset;
		if (!offset) {
			offset = 24;
			data++;
		} else
			offset -= 8;
	}
	cvt->len = 0;
	if (finish)
		cvt->in_sysex = 0;
	else
		cvt->in_sysex++;
	return 8;
}

/* convert to a UMP System message */
static int cvt_legacy_system_to_ump(struct ump_cvt_to_ump *cvt,
				    unsigned char group, u32 *data)
{
	data[0] = ump_compose(UMP_MSG_TYPE_SYSTEM, group, 0, cvt->buf[0]);
	if (cvt->cmd_bytes > 1)
		data[0] |= cvt->buf[1] << 8;
	if (cvt->cmd_bytes > 2)
		data[0] |= cvt->buf[2];
	return 4;
}

static void fill_rpn(struct ump_cvt_to_ump_bank *cc,
		     union snd_ump_midi2_msg *midi2)
{
	if (cc->rpn_set) {
		midi2->rpn.status = UMP_MSG_STATUS_RPN;
		midi2->rpn.bank = cc->cc_rpn_msb;
		midi2->rpn.index = cc->cc_rpn_lsb;
		cc->rpn_set = 0;
		cc->cc_rpn_msb = cc->cc_rpn_lsb = 0;
	} else {
		midi2->rpn.status = UMP_MSG_STATUS_NRPN;
		midi2->rpn.bank = cc->cc_nrpn_msb;
		midi2->rpn.index = cc->cc_nrpn_lsb;
		cc->nrpn_set = 0;
		cc->cc_nrpn_msb = cc->cc_nrpn_lsb = 0;
	}
	midi2->rpn.data = upscale_14_to_32bit((cc->cc_data_msb << 7) |
					      cc->cc_data_lsb);
	cc->cc_data_msb = cc->cc_data_lsb = 0;
}

/* convert to a MIDI 1.0 Channel Voice message */
static int cvt_legacy_cmd_to_ump(struct ump_cvt_to_ump *cvt,
				 unsigned char group,
				 unsigned int protocol,
				 u32 *data, unsigned char bytes)
{
	const unsigned char *buf = cvt->buf;
	struct ump_cvt_to_ump_bank *cc;
	union snd_ump_midi2_msg *midi2 = (union snd_ump_midi2_msg *)data;
	unsigned char status, channel;

	BUILD_BUG_ON(sizeof(union snd_ump_midi1_msg) != 4);
	BUILD_BUG_ON(sizeof(union snd_ump_midi2_msg) != 8);

	/* for MIDI 1.0 UMP, it's easy, just pack it into UMP */
	if (protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI1) {
		data[0] = ump_compose(UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE,
				      group, 0, buf[0]);
		data[0] |= buf[1] << 8;
		if (bytes > 2)
			data[0] |= buf[2];
		return 4;
	}

	status = *buf >> 4;
	channel = *buf & 0x0f;
	cc = &cvt->bank[channel];

	/* special handling: treat note-on with 0 velocity as note-off */
	if (status == UMP_MSG_STATUS_NOTE_ON && !buf[2])
		status = UMP_MSG_STATUS_NOTE_OFF;

	/* initialize the packet */
	data[0] = ump_compose(UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE,
			      group, status, channel);
	data[1] = 0;

	switch (status) {
	case UMP_MSG_STATUS_NOTE_ON:
	case UMP_MSG_STATUS_NOTE_OFF:
		midi2->note.note = buf[1];
		midi2->note.velocity = upscale_7_to_16bit(buf[2]);
		break;
	case UMP_MSG_STATUS_POLY_PRESSURE:
		midi2->paf.note = buf[1];
		midi2->paf.data = upscale_7_to_32bit(buf[2]);
		break;
	case UMP_MSG_STATUS_CC:
		switch (buf[1]) {
		case UMP_CC_RPN_MSB:
			cc->rpn_set = 1;
			cc->cc_rpn_msb = buf[2];
			return 0; // skip
		case UMP_CC_RPN_LSB:
			cc->rpn_set = 1;
			cc->cc_rpn_lsb = buf[2];
			return 0; // skip
		case UMP_CC_NRPN_MSB:
			cc->nrpn_set = 1;
			cc->cc_nrpn_msb = buf[2];
			return 0; // skip
		case UMP_CC_NRPN_LSB:
			cc->nrpn_set = 1;
			cc->cc_nrpn_lsb = buf[2];
			return 0; // skip
		case UMP_CC_DATA:
			cc->cc_data_msb = buf[2];
			return 0; // skip
		case UMP_CC_BANK_SELECT:
			cc->bank_set = 1;
			cc->cc_bank_msb = buf[2];
			return 0; // skip
		case UMP_CC_BANK_SELECT_LSB:
			cc->bank_set = 1;
			cc->cc_bank_lsb = buf[2];
			return 0; // skip
		case UMP_CC_DATA_LSB:
			cc->cc_data_lsb = buf[2];
			if (cc->rpn_set || cc->nrpn_set)
				fill_rpn(cc, midi2);
			else
				return 0; // skip
			break;
		default:
			midi2->cc.index = buf[1];
			midi2->cc.data = upscale_7_to_32bit(buf[2]);
			break;
		}
		break;
	case UMP_MSG_STATUS_PROGRAM:
		midi2->pg.program = buf[1];
		if (cc->bank_set) {
			midi2->pg.bank_valid = 1;
			midi2->pg.bank_msb = cc->cc_bank_msb;
			midi2->pg.bank_lsb = cc->cc_bank_lsb;
			cc->bank_set = 0;
			cc->cc_bank_msb = cc->cc_bank_lsb = 0;
		}
		break;
	case UMP_MSG_STATUS_CHANNEL_PRESSURE:
		midi2->caf.data = upscale_7_to_32bit(buf[1]);
		break;
	case UMP_MSG_STATUS_PITCH_BEND:
		midi2->pb.data = upscale_14_to_32bit(buf[1] | (buf[2] << 7));
		break;
	default:
		return 0;
	}

	return 8;
}

static int do_convert_to_ump(struct ump_cvt_to_ump *cvt, unsigned char group,
			     unsigned int protocol, unsigned char c, u32 *data)
{
	/* bytes for 0x80-0xf0 */
	static unsigned char cmd_bytes[8] = {
		3, 3, 3, 3, 2, 2, 3, 0
	};
	/* bytes for 0xf0-0xff */
	static unsigned char system_bytes[16] = {
		0, 2, 3, 2, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1
	};
	unsigned char bytes;

	if (c == UMP_MIDI1_MSG_SYSEX_START) {
		cvt->in_sysex = 1;
		cvt->len = 0;
		return 0;
	}
	if (c == UMP_MIDI1_MSG_SYSEX_END) {
		if (!cvt->in_sysex)
			return 0; /* skip */
		return cvt_legacy_sysex_to_ump(cvt, group, data, true);
	}

	if ((c & 0xf0) == UMP_MIDI1_MSG_REALTIME) {
		bytes = system_bytes[c & 0x0f];
		if (!bytes)
			return 0; /* skip */
		if (bytes == 1) {
			data[0] = ump_compose(UMP_MSG_TYPE_SYSTEM, group, 0, c);
			return 4;
		}
		cvt->buf[0] = c;
		cvt->len = 1;
		cvt->cmd_bytes = bytes;
		cvt->in_sysex = 0; /* abort SysEx */
		return 0;
	}

	if (c & 0x80) {
		bytes = cmd_bytes[(c >> 4) & 7];
		cvt->buf[0] = c;
		cvt->len = 1;
		cvt->cmd_bytes = bytes;
		cvt->in_sysex = 0; /* abort SysEx */
		return 0;
	}

	if (cvt->in_sysex) {
		cvt->buf[cvt->len++] = c;
		if (cvt->len == 6)
			return cvt_legacy_sysex_to_ump(cvt, group, data, false);
		return 0;
	}

	if (!cvt->len)
		return 0;

	cvt->buf[cvt->len++] = c;
	if (cvt->len < cvt->cmd_bytes)
		return 0;
	cvt->len = 1;
	if ((cvt->buf[0] & 0xf0) == UMP_MIDI1_MSG_REALTIME)
		return cvt_legacy_system_to_ump(cvt, group, data);
	return cvt_legacy_cmd_to_ump(cvt, group, protocol, data, cvt->cmd_bytes);
}

/**
 * snd_ump_convert_to_ump - convert legacy MIDI byte to UMP packet
 * @cvt: converter context
 * @group: target UMP group
 * @protocol: target UMP protocol
 * @c: MIDI 1.0 byte data
 *
 * Feed a MIDI 1.0 byte @c and convert to a UMP packet if completed.
 * The result is stored in the buffer in @cvt.
 */
void snd_ump_convert_to_ump(struct ump_cvt_to_ump *cvt, unsigned char group,
			    unsigned int protocol, unsigned char c)
{
	cvt->ump_bytes = do_convert_to_ump(cvt, group, protocol, c, cvt->ump);
}
EXPORT_SYMBOL_GPL(snd_ump_convert_to_ump);
