Skip to content

Commit 6b779f8

Browse files
committed
Merge tag 'sound-6.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A small collection of fixes: - Revert of FireWire changes that caused a long-time regression - Another long-time regression fix for AMD HDMI - MIDI2 UMP fixes - HD-audio Conexant codec fixes and a quirk" * tag 'sound-6.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda: Conditionally use snooping for AMD HDMI ALSA: usb-audio: Correct surround channels in UAC1 channel map ALSA: seq: ump: Explicitly reset RPN with Null RPN ALSA: seq: ump: Transmit RPN/NRPN message at each MSB/LSB data reception ALSA: seq: ump: Use the common RPN/bank conversion context ALSA: ump: Explicitly reset RPN with Null RPN ALSA: ump: Transmit RPN/NRPN message at each MSB/LSB data reception Revert "ALSA: firewire-lib: operate for period elapse event in process context" Revert "ALSA: firewire-lib: obsolete workqueue for period update" ALSA: hda/realtek: Add quirk for Acer Aspire E5-574G ALSA: seq: ump: Optimize conversions from SysEx to UMP ALSA: hda/conexant: Mute speakers at suspend / shutdown ALSA: hda/generic: Add a helper to mute speakers at suspend/shutdown ALSA: hda: conexant: Fix headset auto detect fail in the polling mode
2 parents 29b4a69 + 478689b commit 6b779f8

File tree

13 files changed

+241
-142
lines changed

13 files changed

+241
-142
lines changed

include/sound/ump_convert.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct ump_cvt_to_ump_bank {
1313
unsigned char cc_nrpn_msb, cc_nrpn_lsb;
1414
unsigned char cc_data_msb, cc_data_lsb;
1515
unsigned char cc_bank_msb, cc_bank_lsb;
16+
bool cc_data_msb_set, cc_data_lsb_set;
1617
};
1718

1819
/* context for converting from MIDI1 byte stream to UMP packet */

sound/core/seq/seq_ports.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define __SND_SEQ_PORTS_H
88

99
#include <sound/seq_kernel.h>
10+
#include <sound/ump_convert.h>
1011
#include "seq_lock.h"
1112

1213
/* list of 'exported' ports */
@@ -42,17 +43,6 @@ struct snd_seq_port_subs_info {
4243
int (*close)(void *private_data, struct snd_seq_port_subscribe *info);
4344
};
4445

45-
/* context for converting from legacy control event to UMP packet */
46-
struct snd_seq_ump_midi2_bank {
47-
bool rpn_set;
48-
bool nrpn_set;
49-
bool bank_set;
50-
unsigned char cc_rpn_msb, cc_rpn_lsb;
51-
unsigned char cc_nrpn_msb, cc_nrpn_lsb;
52-
unsigned char cc_data_msb, cc_data_lsb;
53-
unsigned char cc_bank_msb, cc_bank_lsb;
54-
};
55-
5646
struct snd_seq_client_port {
5747

5848
struct snd_seq_addr addr; /* client/port number */
@@ -88,7 +78,7 @@ struct snd_seq_client_port {
8878
unsigned char ump_group;
8979

9080
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
91-
struct snd_seq_ump_midi2_bank midi2_bank[16]; /* per channel */
81+
struct ump_cvt_to_ump_bank midi2_bank[16]; /* per channel */
9282
#endif
9383
};
9484

sound/core/seq/seq_ump_convert.c

Lines changed: 83 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ static int cvt_ump_midi1_to_midi2(struct snd_seq_client *dest,
368368
struct snd_seq_ump_event ev_cvt;
369369
const union snd_ump_midi1_msg *midi1 = (const union snd_ump_midi1_msg *)event->ump;
370370
union snd_ump_midi2_msg *midi2 = (union snd_ump_midi2_msg *)ev_cvt.ump;
371-
struct snd_seq_ump_midi2_bank *cc;
371+
struct ump_cvt_to_ump_bank *cc;
372372

373373
ev_cvt = *event;
374374
memset(&ev_cvt.ump, 0, sizeof(ev_cvt.ump));
@@ -789,28 +789,45 @@ static int paf_ev_to_ump_midi2(const struct snd_seq_event *event,
789789
return 1;
790790
}
791791

792+
static void reset_rpn(struct ump_cvt_to_ump_bank *cc)
793+
{
794+
cc->rpn_set = 0;
795+
cc->nrpn_set = 0;
796+
cc->cc_rpn_msb = cc->cc_rpn_lsb = 0;
797+
cc->cc_data_msb = cc->cc_data_lsb = 0;
798+
cc->cc_data_msb_set = cc->cc_data_lsb_set = 0;
799+
}
800+
792801
/* set up the MIDI2 RPN/NRPN packet data from the parsed info */
793-
static void fill_rpn(struct snd_seq_ump_midi2_bank *cc,
794-
union snd_ump_midi2_msg *data,
795-
unsigned char channel)
802+
static int fill_rpn(struct ump_cvt_to_ump_bank *cc,
803+
union snd_ump_midi2_msg *data,
804+
unsigned char channel,
805+
bool flush)
796806
{
807+
if (!(cc->cc_data_lsb_set || cc->cc_data_msb_set))
808+
return 0; // skip
809+
/* when not flushing, wait for complete data set */
810+
if (!flush && (!cc->cc_data_lsb_set || !cc->cc_data_msb_set))
811+
return 0; // skip
812+
797813
if (cc->rpn_set) {
798814
data->rpn.status = UMP_MSG_STATUS_RPN;
799815
data->rpn.bank = cc->cc_rpn_msb;
800816
data->rpn.index = cc->cc_rpn_lsb;
801-
cc->rpn_set = 0;
802-
cc->cc_rpn_msb = cc->cc_rpn_lsb = 0;
803-
} else {
817+
} else if (cc->nrpn_set) {
804818
data->rpn.status = UMP_MSG_STATUS_NRPN;
805819
data->rpn.bank = cc->cc_nrpn_msb;
806820
data->rpn.index = cc->cc_nrpn_lsb;
807-
cc->nrpn_set = 0;
808-
cc->cc_nrpn_msb = cc->cc_nrpn_lsb = 0;
821+
} else {
822+
return 0; // skip
809823
}
824+
810825
data->rpn.data = upscale_14_to_32bit((cc->cc_data_msb << 7) |
811826
cc->cc_data_lsb);
812827
data->rpn.channel = channel;
813-
cc->cc_data_msb = cc->cc_data_lsb = 0;
828+
829+
reset_rpn(cc);
830+
return 1;
814831
}
815832

816833
/* convert CC event to MIDI 2.0 UMP */
@@ -822,29 +839,39 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
822839
unsigned char channel = event->data.control.channel & 0x0f;
823840
unsigned char index = event->data.control.param & 0x7f;
824841
unsigned char val = event->data.control.value & 0x7f;
825-
struct snd_seq_ump_midi2_bank *cc = &dest_port->midi2_bank[channel];
842+
struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel];
843+
int ret;
826844

827845
/* process special CC's (bank/rpn/nrpn) */
828846
switch (index) {
829847
case UMP_CC_RPN_MSB:
848+
ret = fill_rpn(cc, data, channel, true);
830849
cc->rpn_set = 1;
831850
cc->cc_rpn_msb = val;
832-
return 0; // skip
851+
if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f)
852+
reset_rpn(cc);
853+
return ret;
833854
case UMP_CC_RPN_LSB:
855+
ret = fill_rpn(cc, data, channel, true);
834856
cc->rpn_set = 1;
835857
cc->cc_rpn_lsb = val;
836-
return 0; // skip
858+
if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f)
859+
reset_rpn(cc);
860+
return ret;
837861
case UMP_CC_NRPN_MSB:
862+
ret = fill_rpn(cc, data, channel, true);
838863
cc->nrpn_set = 1;
839864
cc->cc_nrpn_msb = val;
840-
return 0; // skip
865+
return ret;
841866
case UMP_CC_NRPN_LSB:
867+
ret = fill_rpn(cc, data, channel, true);
842868
cc->nrpn_set = 1;
843869
cc->cc_nrpn_lsb = val;
844-
return 0; // skip
870+
return ret;
845871
case UMP_CC_DATA:
872+
cc->cc_data_msb_set = 1;
846873
cc->cc_data_msb = val;
847-
return 0; // skip
874+
return fill_rpn(cc, data, channel, false);
848875
case UMP_CC_BANK_SELECT:
849876
cc->bank_set = 1;
850877
cc->cc_bank_msb = val;
@@ -854,11 +881,9 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
854881
cc->cc_bank_lsb = val;
855882
return 0; // skip
856883
case UMP_CC_DATA_LSB:
884+
cc->cc_data_lsb_set = 1;
857885
cc->cc_data_lsb = val;
858-
if (!(cc->rpn_set || cc->nrpn_set))
859-
return 0; // skip
860-
fill_rpn(cc, data, channel);
861-
return 1;
886+
return fill_rpn(cc, data, channel, false);
862887
}
863888

864889
data->cc.status = status;
@@ -887,7 +912,7 @@ static int pgm_ev_to_ump_midi2(const struct snd_seq_event *event,
887912
unsigned char status)
888913
{
889914
unsigned char channel = event->data.control.channel & 0x0f;
890-
struct snd_seq_ump_midi2_bank *cc = &dest_port->midi2_bank[channel];
915+
struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel];
891916

892917
data->pg.status = status;
893918
data->pg.channel = channel;
@@ -924,8 +949,9 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
924949
{
925950
unsigned char channel = event->data.control.channel & 0x0f;
926951
unsigned char index = event->data.control.param & 0x7f;
927-
struct snd_seq_ump_midi2_bank *cc = &dest_port->midi2_bank[channel];
952+
struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel];
928953
unsigned char msb, lsb;
954+
int ret;
929955

930956
msb = (event->data.control.value >> 7) & 0x7f;
931957
lsb = event->data.control.value & 0x7f;
@@ -939,28 +965,27 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
939965
cc->cc_bank_lsb = lsb;
940966
return 0; // skip
941967
case UMP_CC_RPN_MSB:
942-
cc->cc_rpn_msb = msb;
943-
fallthrough;
944968
case UMP_CC_RPN_LSB:
945-
cc->rpn_set = 1;
969+
ret = fill_rpn(cc, data, channel, true);
970+
cc->cc_rpn_msb = msb;
946971
cc->cc_rpn_lsb = lsb;
947-
return 0; // skip
972+
cc->rpn_set = 1;
973+
if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f)
974+
reset_rpn(cc);
975+
return ret;
948976
case UMP_CC_NRPN_MSB:
949-
cc->cc_nrpn_msb = msb;
950-
fallthrough;
951977
case UMP_CC_NRPN_LSB:
978+
ret = fill_rpn(cc, data, channel, true);
979+
cc->cc_nrpn_msb = msb;
952980
cc->nrpn_set = 1;
953981
cc->cc_nrpn_lsb = lsb;
954-
return 0; // skip
982+
return ret;
955983
case UMP_CC_DATA:
956-
cc->cc_data_msb = msb;
957-
fallthrough;
958984
case UMP_CC_DATA_LSB:
985+
cc->cc_data_msb_set = cc->cc_data_lsb_set = 1;
986+
cc->cc_data_msb = msb;
959987
cc->cc_data_lsb = lsb;
960-
if (!(cc->rpn_set || cc->nrpn_set))
961-
return 0; // skip
962-
fill_rpn(cc, data, channel);
963-
return 1;
988+
return fill_rpn(cc, data, channel, false);
964989
}
965990

966991
data->cc.status = UMP_MSG_STATUS_CC;
@@ -1192,44 +1217,53 @@ static int cvt_sysex_to_ump(struct snd_seq_client *dest,
11921217
{
11931218
struct snd_seq_ump_event ev_cvt;
11941219
unsigned char status;
1195-
u8 buf[6], *xbuf;
1220+
u8 buf[8], *xbuf;
11961221
int offset = 0;
11971222
int len, err;
1223+
bool finished = false;
11981224

11991225
if (!snd_seq_ev_is_variable(event))
12001226
return 0;
12011227

12021228
setup_ump_event(&ev_cvt, event);
1203-
for (;;) {
1229+
while (!finished) {
12041230
len = snd_seq_expand_var_event_at(event, sizeof(buf), buf, offset);
12051231
if (len <= 0)
12061232
break;
1207-
if (WARN_ON(len > 6))
1233+
if (WARN_ON(len > sizeof(buf)))
12081234
break;
1209-
offset += len;
1235+
12101236
xbuf = buf;
1237+
status = UMP_SYSEX_STATUS_CONTINUE;
1238+
/* truncate the sysex start-marker */
12111239
if (*xbuf == UMP_MIDI1_MSG_SYSEX_START) {
12121240
status = UMP_SYSEX_STATUS_START;
1213-
xbuf++;
12141241
len--;
1215-
if (len > 0 && xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
1242+
offset++;
1243+
xbuf++;
1244+
}
1245+
1246+
/* if the last of this packet or the 1st byte of the next packet
1247+
* is the end-marker, finish the transfer with this packet
1248+
*/
1249+
if (len > 0 && len < 8 &&
1250+
xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
1251+
if (status == UMP_SYSEX_STATUS_START)
12161252
status = UMP_SYSEX_STATUS_SINGLE;
1217-
len--;
1218-
}
1219-
} else {
1220-
if (xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
1253+
else
12211254
status = UMP_SYSEX_STATUS_END;
1222-
len--;
1223-
} else {
1224-
status = UMP_SYSEX_STATUS_CONTINUE;
1225-
}
1255+
len--;
1256+
finished = true;
12261257
}
1258+
1259+
len = min(len, 6);
12271260
fill_sysex7_ump(dest_port, ev_cvt.ump, status, xbuf, len);
12281261
err = __snd_seq_deliver_single_event(dest, dest_port,
12291262
(struct snd_seq_event *)&ev_cvt,
12301263
atomic, hop);
12311264
if (err < 0)
12321265
return err;
1266+
offset += len;
12331267
}
12341268
return 0;
12351269
}

0 commit comments

Comments
 (0)