Commit 262eef26 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-6.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Just a few small fixes:

   - A regression fix for HDMI audio on HD-audio AMD codecs

   - Fixes for LINE6 MIDI handling

   - HD-audio quirk for Dell laptops"

* tag 'sound-6.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/hdmi: Static PCM mapping again with AMD HDMI codecs
  ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops
  ALSA: line6: fix stack overflow in line6_midi_transmit
  ALSA: line6: correct midi status byte when receiving data from podxt
parents bff687b3 090ddad4
......@@ -167,6 +167,7 @@ struct hdmi_spec {
struct hdmi_ops ops;
bool dyn_pin_out;
bool static_pcm_mapping;
/* hdmi interrupt trigger control flag for Nvidia codec */
bool hdmi_intr_trig_ctrl;
bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
......@@ -1525,6 +1526,7 @@ static void update_eld(struct hda_codec *codec,
*/
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
if (!spec->static_pcm_mapping) {
if (eld->eld_valid) {
hdmi_attach_hda_pcm(spec, per_pin);
hdmi_pcm_setup_pin(spec, per_pin);
......@@ -1532,6 +1534,8 @@ static void update_eld(struct hda_codec *codec,
hdmi_pcm_reset_pin(spec, per_pin);
hdmi_detach_hda_pcm(spec, per_pin);
}
}
/* if pcm_idx == -1, it means this is in monitor connection event
* we can get the correct pcm_idx now.
*/
......@@ -2281,8 +2285,8 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
struct hdmi_spec *spec = codec->spec;
int idx, pcm_num;
/* limit the PCM devices to the codec converters */
pcm_num = spec->num_cvts;
/* limit the PCM devices to the codec converters or available PINs */
pcm_num = min(spec->num_cvts, spec->num_pins);
codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
for (idx = 0; idx < pcm_num; idx++) {
......@@ -2379,6 +2383,11 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
struct hdmi_eld *pin_eld = &per_pin->sink_eld;
if (spec->static_pcm_mapping) {
hdmi_attach_hda_pcm(spec, per_pin);
hdmi_pcm_setup_pin(spec, per_pin);
}
pin_eld->eld_valid = false;
hdmi_present_sense(per_pin, 0);
}
......@@ -4419,6 +4428,8 @@ static int patch_atihdmi(struct hda_codec *codec)
spec = codec->spec;
spec->static_pcm_mapping = true;
spec->ops.pin_get_eld = atihdmi_pin_get_eld;
spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe;
spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;
......
......@@ -7175,6 +7175,7 @@ enum {
ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN,
ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
ALC236_FIXUP_DELL_DUAL_CODECS,
};
/* A special fixup for Lenovo C940 and Yoga Duet 7;
......@@ -9130,6 +9131,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
},
[ALC236_FIXUP_DELL_DUAL_CODECS] = {
.type = HDA_FIXUP_PINS,
.v.func = alc1220_fixup_gb_dual_codecs,
.chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
},
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
......@@ -9232,6 +9239,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
......
......@@ -304,7 +304,8 @@ static void line6_data_received(struct urb *urb)
for (;;) {
done =
line6_midibuf_read(mb, line6->buffer_message,
LINE6_MIDI_MESSAGE_MAXLEN);
LINE6_MIDI_MESSAGE_MAXLEN,
LINE6_MIDIBUF_READ_RX);
if (done <= 0)
break;
......
......@@ -44,7 +44,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
int req, done;
for (;;) {
req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
LINE6_FALLBACK_MAXPACKETSIZE);
done = snd_rawmidi_transmit_peek(substream, chunk, req);
if (done == 0)
......@@ -56,7 +57,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
for (;;) {
done = line6_midibuf_read(mb, chunk,
LINE6_FALLBACK_MAXPACKETSIZE);
LINE6_FALLBACK_MAXPACKETSIZE,
LINE6_MIDIBUF_READ_TX);
if (done == 0)
break;
......
......@@ -9,6 +9,7 @@
#include "midibuf.h"
static int midibuf_message_length(unsigned char code)
{
int message_length;
......@@ -20,12 +21,7 @@ static int midibuf_message_length(unsigned char code)
message_length = length[(code >> 4) - 8];
} else {
/*
Note that according to the MIDI specification 0xf2 is
the "Song Position Pointer", but this is used by Line 6
to send sysex messages to the host.
*/
static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
1, 1, 1, -1, 1, 1
};
message_length = length[code & 0x0f];
......@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
}
int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
int length)
int length, int read_type)
{
int bytes_used;
int length1, length2;
......@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
length1 = this->size - this->pos_read;
/* check MIDI command length */
command = this->buf[this->pos_read];
/*
PODxt always has status byte lower nibble set to 0010,
when it means to send 0000, so we correct if here so
that control/program changes come on channel 1 and
sysex message status byte is correct
*/
if (read_type == LINE6_MIDIBUF_READ_RX) {
if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
unsigned char fixed = command & 0xf0;
this->buf[this->pos_read] = fixed;
command = fixed;
}
}
/* check MIDI command length */
if (command & 0x80) {
midi_length = midibuf_message_length(command);
this->command_prev = command;
......
......@@ -8,6 +8,9 @@
#ifndef MIDIBUF_H
#define MIDIBUF_H
#define LINE6_MIDIBUF_READ_TX 0
#define LINE6_MIDIBUF_READ_RX 1
struct midi_buffer {
unsigned char *buf;
int size;
......@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
int length);
int length, int read_type);
extern void line6_midibuf_reset(struct midi_buffer *mb);
extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
int length);
......
......@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
};
static const char pod_version_header[] = {
0xf2, 0x7e, 0x7f, 0x06, 0x02
0xf0, 0x7e, 0x7f, 0x06, 0x02
};
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment