summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/hda_register.h2
-rw-r--r--sound/firewire/cmp.c47
-rw-r--r--sound/firewire/cmp.h1
-rw-r--r--sound/pci/hda/hda_auto_parser.c61
-rw-r--r--sound/pci/hda/hda_local.h28
-rw-r--r--sound/pci/hda/patch_analog.c6
-rw-r--r--sound/pci/hda/patch_cirrus.c8
-rw-r--r--sound/pci/hda/patch_conexant.c36
-rw-r--r--sound/pci/hda/patch_cs8409-tables.c2
-rw-r--r--sound/pci/hda/patch_cs8409.h2
-rw-r--r--sound/pci/hda/patch_realtek.c118
-rw-r--r--sound/pci/hda/patch_sigmatel.c22
-rw-r--r--sound/pci/hda/patch_via.c2
-rw-r--r--sound/pci/ice1712/prodigy192.c9
-rw-r--r--sound/sh/aica.c2
-rw-r--r--sound/sparc/dbri.c2
-rw-r--r--sound/usb/mixer.c3
-rw-r--r--sound/usb/mixer_scarlett2.c220
18 files changed, 298 insertions, 273 deletions
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index 5ff31e6d41c1..db1cc0b897fd 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -180,7 +180,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define SD_STS_FIFO_READY 0x20 /* FIFO ready */
/* INTCTL and INTSTS */
-#define AZX_INT_ALL_STREAM 0xff /* all stream interrupts */
+#define AZX_INT_ALL_STREAM 0x3fffffff /* all stream interrupts */
#define AZX_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
#define AZX_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c
index b596bec19774..f5028a061a91 100644
--- a/sound/firewire/cmp.c
+++ b/sound/firewire/cmp.c
@@ -333,53 +333,6 @@ retry_after_bus_reset:
}
EXPORT_SYMBOL(cmp_connection_establish);
-/**
- * cmp_connection_update - update the connection after a bus reset
- * @c: the connection manager
- *
- * This function must be called from the driver's .update handler to
- * reestablish any connection that might have been active.
- *
- * Returns zero on success, or a negative error code. On an error, the
- * connection is broken and the caller must stop transmitting iso packets.
- */
-int cmp_connection_update(struct cmp_connection *c)
-{
- int err;
-
- mutex_lock(&c->mutex);
-
- if (!c->connected) {
- mutex_unlock(&c->mutex);
- return 0;
- }
-
- err = fw_iso_resources_update(&c->resources);
- if (err < 0)
- goto err_unconnect;
-
- if (c->direction == CMP_OUTPUT)
- err = pcr_modify(c, opcr_set_modify, pcr_set_check,
- SUCCEED_ON_BUS_RESET);
- else
- err = pcr_modify(c, ipcr_set_modify, pcr_set_check,
- SUCCEED_ON_BUS_RESET);
-
- if (err < 0)
- goto err_unconnect;
-
- mutex_unlock(&c->mutex);
-
- return 0;
-
-err_unconnect:
- c->connected = false;
- mutex_unlock(&c->mutex);
-
- return err;
-}
-EXPORT_SYMBOL(cmp_connection_update);
-
static __be32 pcr_break_modify(struct cmp_connection *c, __be32 pcr)
{
return pcr & ~cpu_to_be32(PCR_BCAST_CONN | PCR_P2P_CONN_MASK);
diff --git a/sound/firewire/cmp.h b/sound/firewire/cmp.h
index 26ab88000e34..66fc08b742d2 100644
--- a/sound/firewire/cmp.h
+++ b/sound/firewire/cmp.h
@@ -47,7 +47,6 @@ int cmp_connection_reserve(struct cmp_connection *connection,
void cmp_connection_release(struct cmp_connection *connection);
int cmp_connection_establish(struct cmp_connection *connection);
-int cmp_connection_update(struct cmp_connection *connection);
void cmp_connection_break(struct cmp_connection *connection);
#endif
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 7c6b1fe8dfcc..8e74be038b0f 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -956,6 +956,28 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup);
+/* check whether the given quirk entry matches with vendor/device pair */
+static bool hda_quirk_match(u16 vendor, u16 device, const struct hda_quirk *q)
+{
+ if (q->subvendor != vendor)
+ return false;
+ return !q->subdevice ||
+ (device & q->subdevice_mask) == q->subdevice;
+}
+
+/* look through the quirk list and return the matching entry */
+static const struct hda_quirk *
+hda_quirk_lookup_id(u16 vendor, u16 device, const struct hda_quirk *list)
+{
+ const struct hda_quirk *q;
+
+ for (q = list; q->subvendor || q->subdevice; q++) {
+ if (hda_quirk_match(vendor, device, q))
+ return q;
+ }
+ return NULL;
+}
+
/**
* snd_hda_pick_fixup - Pick up a fixup matching with PCI/codec SSID or model string
* @codec: the HDA codec
@@ -975,14 +997,16 @@ EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup);
*/
void snd_hda_pick_fixup(struct hda_codec *codec,
const struct hda_model_fixup *models,
- const struct snd_pci_quirk *quirk,
+ const struct hda_quirk *quirk,
const struct hda_fixup *fixlist)
{
- const struct snd_pci_quirk *q;
+ const struct hda_quirk *q;
int id = HDA_FIXUP_ID_NOT_SET;
const char *name = NULL;
const char *type = NULL;
unsigned int vendor, device;
+ u16 pci_vendor, pci_device;
+ u16 codec_vendor, codec_device;
if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
return;
@@ -1013,27 +1037,42 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
if (!quirk)
return;
+ if (codec->bus->pci) {
+ pci_vendor = codec->bus->pci->subsystem_vendor;
+ pci_device = codec->bus->pci->subsystem_device;
+ }
+
+ codec_vendor = codec->core.subsystem_id >> 16;
+ codec_device = codec->core.subsystem_id & 0xffff;
+
/* match with the SSID alias given by the model string "XXXX:YYYY" */
if (codec->modelname &&
sscanf(codec->modelname, "%04x:%04x", &vendor, &device) == 2) {
- q = snd_pci_quirk_lookup_id(vendor, device, quirk);
+ q = hda_quirk_lookup_id(vendor, device, quirk);
if (q) {
type = "alias SSID";
goto found_device;
}
}
- /* match with the PCI SSID */
- q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
- if (q) {
- type = "PCI SSID";
- goto found_device;
+ /* match primarily with the PCI SSID */
+ for (q = quirk; q->subvendor || q->subdevice; q++) {
+ /* if the entry is specific to codec SSID, check with it */
+ if (!codec->bus->pci || q->match_codec_ssid) {
+ if (hda_quirk_match(codec_vendor, codec_device, q)) {
+ type = "codec SSID";
+ goto found_device;
+ }
+ } else {
+ if (hda_quirk_match(pci_vendor, pci_device, q)) {
+ type = "PCI SSID";
+ goto found_device;
+ }
+ }
}
/* match with the codec SSID */
- q = snd_pci_quirk_lookup_id(codec->core.subsystem_id >> 16,
- codec->core.subsystem_id & 0xffff,
- quirk);
+ q = hda_quirk_lookup_id(codec_vendor, codec_device, quirk);
if (q) {
type = "codec SSID";
goto found_device;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 53a5a62b78fa..763f79f6f32e 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -292,6 +292,32 @@ struct hda_fixup {
} v;
};
+/*
+ * extended form of snd_pci_quirk:
+ * for PCI SSID matching, use SND_PCI_QUIRK() like before;
+ * for codec SSID matching, use the new HDA_CODEC_QUIRK() instead
+ */
+struct hda_quirk {
+ unsigned short subvendor; /* PCI subvendor ID */
+ unsigned short subdevice; /* PCI subdevice ID */
+ unsigned short subdevice_mask; /* bitmask to match */
+ bool match_codec_ssid; /* match only with codec SSID */
+ int value; /* value */
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ const char *name; /* name of the device (optional) */
+#endif
+};
+
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+#define HDA_CODEC_QUIRK(vend, dev, xname, val) \
+ { _SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname),\
+ .match_codec_ssid = true }
+#else
+#define HDA_CODEC_QUIRK(vend, dev, xname, val) \
+ { _SND_PCI_QUIRK_ID(vend, dev), .value = (val), \
+ .match_codec_ssid = true }
+#endif
+
struct snd_hda_pin_quirk {
unsigned int codec; /* Codec vendor/device ID */
unsigned short subvendor; /* PCI subvendor ID */
@@ -351,7 +377,7 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action);
void __snd_hda_apply_fixup(struct hda_codec *codec, int id, int action, int depth);
void snd_hda_pick_fixup(struct hda_codec *codec,
const struct hda_model_fixup *models,
- const struct snd_pci_quirk *quirk,
+ const struct hda_quirk *quirk,
const struct hda_fixup *fixlist);
void snd_hda_pick_pin_fixup(struct hda_codec *codec,
const struct snd_hda_pin_quirk *pin_quirk,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 1e9dadcdc51b..56354fe060a1 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -345,7 +345,7 @@ static const struct hda_fixup ad1986a_fixups[] = {
},
};
-static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
+static const struct hda_quirk ad1986a_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC),
SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9V", AD1986A_FIXUP_LAPTOP_IMIC),
SND_PCI_QUIRK(0x1043, 0x1443, "ASUS Z99He", AD1986A_FIXUP_EAPD),
@@ -588,7 +588,7 @@ static const struct hda_fixup ad1981_fixups[] = {
},
};
-static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
+static const struct hda_quirk ad1981_fixup_tbl[] = {
SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD),
SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
@@ -1061,7 +1061,7 @@ static const struct hda_fixup ad1884_fixups[] = {
},
};
-static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
+static const struct hda_quirk ad1884_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART),
SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_THINKPAD),
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 654724559355..06e046214a41 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -385,7 +385,7 @@ static const struct hda_model_fixup cs420x_models[] = {
{}
};
-static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
+static const struct hda_quirk cs420x_fixup_tbl[] = {
SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
@@ -634,13 +634,13 @@ static const struct hda_model_fixup cs4208_models[] = {
{}
};
-static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
+static const struct hda_quirk cs4208_fixup_tbl[] = {
SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS4208_MAC_AUTO),
{} /* terminator */
};
/* codec SSID matching */
-static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
+static const struct hda_quirk cs4208_mac_fixup_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
SND_PCI_QUIRK(0x106b, 0x6c00, "MacMini 7,1", CS4208_MACMINI),
SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
@@ -818,7 +818,7 @@ static const struct hda_model_fixup cs421x_models[] = {
{}
};
-static const struct snd_pci_quirk cs421x_fixup_tbl[] = {
+static const struct hda_quirk cs421x_fixup_tbl[] = {
/* Test Intel board + CDB2410 */
SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
{} /* terminator */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c74f6742c359..e7107a14fa9d 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -830,23 +830,6 @@ static const struct hda_pintbl cxt_pincfg_sws_js201d[] = {
{}
};
-/* pincfg quirk for Tuxedo Sirius;
- * unfortunately the (PCI) SSID conflicts with System76 Pangolin pang14,
- * which has incompatible pin setup, so we check the codec SSID (luckily
- * different one!) and conditionally apply the quirk here
- */
-static void cxt_fixup_sirius_top_speaker(struct hda_codec *codec,
- const struct hda_fixup *fix,
- int action)
-{
- /* ignore for incorrectly picked-up pang14 */
- if (codec->core.subsystem_id == 0x278212b3)
- return;
- /* set up the top speaker pin */
- if (action == HDA_FIXUP_ACT_PRE_PROBE)
- snd_hda_codec_set_pincfg(codec, 0x1d, 0x82170111);
-}
-
static const struct hda_fixup cxt_fixups[] = {
[CXT_PINCFG_LENOVO_X200] = {
.type = HDA_FIXUP_PINS,
@@ -1011,12 +994,15 @@ static const struct hda_fixup cxt_fixups[] = {
.v.pins = cxt_pincfg_sws_js201d,
},
[CXT_PINCFG_TOP_SPEAKER] = {
- .type = HDA_FIXUP_FUNC,
- .v.func = cxt_fixup_sirius_top_speaker,
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x1d, 0x82170111 },
+ { }
+ },
},
};
-static const struct snd_pci_quirk cxt5045_fixups[] = {
+static const struct hda_quirk cxt5045_fixups[] = {
SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT_FIXUP_HP_530),
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT_FIXUP_TOSHIBA_P105),
/* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
@@ -1036,7 +1022,7 @@ static const struct hda_model_fixup cxt5045_fixup_models[] = {
{}
};
-static const struct snd_pci_quirk cxt5047_fixups[] = {
+static const struct hda_quirk cxt5047_fixups[] = {
/* HP laptops have really bad sound over 0 dB on NID 0x10.
*/
SND_PCI_QUIRK_VENDOR(0x103c, "HP", CXT_FIXUP_CAP_MIX_AMP_5047),
@@ -1048,7 +1034,7 @@ static const struct hda_model_fixup cxt5047_fixup_models[] = {
{}
};
-static const struct snd_pci_quirk cxt5051_fixups[] = {
+static const struct hda_quirk cxt5051_fixups[] = {
SND_PCI_QUIRK(0x103c, 0x360b, "Compaq CQ60", CXT_PINCFG_COMPAQ_CQ60),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
{}
@@ -1059,7 +1045,7 @@ static const struct hda_model_fixup cxt5051_fixup_models[] = {
{}
};
-static const struct snd_pci_quirk cxt5066_fixups[] = {
+static const struct hda_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
@@ -1111,8 +1097,8 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205),
- SND_PCI_QUIRK(0x2782, 0x12c3, "Sirius Gen1", CXT_PINCFG_TOP_SPEAKER),
- SND_PCI_QUIRK(0x2782, 0x12c5, "Sirius Gen2", CXT_PINCFG_TOP_SPEAKER),
+ HDA_CODEC_QUIRK(0x2782, 0x12c3, "Sirius Gen1", CXT_PINCFG_TOP_SPEAKER),
+ HDA_CODEC_QUIRK(0x2782, 0x12c5, "Sirius Gen2", CXT_PINCFG_TOP_SPEAKER),
{}
};
diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c
index 36b411d1a960..759f48038273 100644
--- a/sound/pci/hda/patch_cs8409-tables.c
+++ b/sound/pci/hda/patch_cs8409-tables.c
@@ -473,7 +473,7 @@ struct sub_codec dolphin_cs42l42_1 = {
* Arrays Used for all projects using CS8409
******************************************************************************/
-const struct snd_pci_quirk cs8409_fixup_tbl[] = {
+const struct hda_quirk cs8409_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE),
SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE),
SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE),
diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h
index 937e9387abdc..5e48115caf09 100644
--- a/sound/pci/hda/patch_cs8409.h
+++ b/sound/pci/hda/patch_cs8409.h
@@ -355,7 +355,7 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc
extern const struct hda_pcm_stream cs42l42_48k_pcm_analog_playback;
extern const struct hda_pcm_stream cs42l42_48k_pcm_analog_capture;
-extern const struct snd_pci_quirk cs8409_fixup_tbl[];
+extern const struct hda_quirk cs8409_fixup_tbl[];
extern const struct hda_model_fixup cs8409_models[];
extern const struct hda_fixup cs8409_fixups[];
extern const struct hda_verb cs8409_cs42l42_init_verbs[];
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 3bbf5fab2881..d62cb4ab8ae0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1565,7 +1565,7 @@ static const struct hda_fixup alc880_fixups[] = {
},
};
-static const struct snd_pci_quirk alc880_fixup_tbl[] = {
+static const struct hda_quirk alc880_fixup_tbl[] = {
SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
@@ -1874,7 +1874,7 @@ static const struct hda_fixup alc260_fixups[] = {
},
};
-static const struct snd_pci_quirk alc260_fixup_tbl[] = {
+static const struct hda_quirk alc260_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
@@ -2566,7 +2566,7 @@ static const struct hda_fixup alc882_fixups[] = {
},
};
-static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+static const struct hda_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
@@ -2910,7 +2910,7 @@ static const struct hda_fixup alc262_fixups[] = {
},
};
-static const struct snd_pci_quirk alc262_fixup_tbl[] = {
+static const struct hda_quirk alc262_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
@@ -3071,7 +3071,7 @@ static const struct hda_model_fixup alc268_fixup_models[] = {
{}
};
-static const struct snd_pci_quirk alc268_fixup_tbl[] = {
+static const struct hda_quirk alc268_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
/* below is codec SSID since multiple Toshiba laptops have the
@@ -7730,8 +7730,6 @@ enum {
ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
ALC298_FIXUP_LENOVO_C940_DUET7,
- ALC287_FIXUP_LENOVO_14IRP8_DUETITL,
- ALC287_FIXUP_LENOVO_LEGION_7,
ALC287_FIXUP_13S_GEN2_SPEAKERS,
ALC256_FIXUP_SET_COEF_DEFAULTS,
ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
@@ -7776,8 +7774,6 @@ enum {
ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1,
ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318,
ALC256_FIXUP_CHROME_BOOK,
- ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7,
- ALC287_FIXUP_LENOVO_SSID_17AA3820,
ALC245_FIXUP_CLEVO_NOISY_MIC,
ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE,
};
@@ -7799,72 +7795,6 @@ static void alc298_fixup_lenovo_c940_duet7(struct hda_codec *codec,
__snd_hda_apply_fixup(codec, id, action, 0);
}
-/* A special fixup for Lenovo Slim/Yoga Pro 9 14IRP8 and Yoga DuetITL 2021;
- * 14IRP8 PCI SSID will mistakenly be matched with the DuetITL codec SSID,
- * so we need to apply a different fixup in this case. The only DuetITL codec
- * SSID reported so far is the 17aa:3802 while the 14IRP8 has the 17aa:38be
- * and 17aa:38bf. If it weren't for the PCI SSID, the 14IRP8 models would
- * have matched correctly by their codecs.
- */
-static void alc287_fixup_lenovo_14irp8_duetitl(struct hda_codec *codec,
- const struct hda_fixup *fix,
- int action)
-{
- int id;
-
- if (codec->core.subsystem_id == 0x17aa3802)
- id = ALC287_FIXUP_YOGA7_14ITL_SPEAKERS; /* DuetITL */
- else
- id = ALC287_FIXUP_TAS2781_I2C; /* 14IRP8 */
- __snd_hda_apply_fixup(codec, id, action, 0);
-}
-
-/* Similar to above the Lenovo Yoga Pro 7 14ARP8 PCI SSID matches the codec SSID of the
- Legion Y9000X 2022 IAH7.*/
-static void alc287_fixup_lenovo_14arp8_legion_iah7(struct hda_codec *codec,
- const struct hda_fixup *fix,
- int action)
-{
- int id;
-
- if (codec->core.subsystem_id == 0x17aa386e)
- id = ALC287_FIXUP_CS35L41_I2C_2; /* Legion Y9000X 2022 IAH7 */
- else
- id = ALC285_FIXUP_SPEAKER2_TO_DAC1; /* Yoga Pro 7 14ARP8 */
- __snd_hda_apply_fixup(codec, id, action, 0);
-}
-
-/* Another hilarious PCI SSID conflict with Lenovo Legion Pro 7 16ARX8H (with
- * TAS2781 codec) and Legion 7i 16IAX7 (with CS35L41 codec);
- * we apply a corresponding fixup depending on the codec SSID instead
- */
-static void alc287_fixup_lenovo_legion_7(struct hda_codec *codec,
- const struct hda_fixup *fix,
- int action)
-{
- int id;
-
- if (codec->core.subsystem_id == 0x17aa38a8)
- id = ALC287_FIXUP_TAS2781_I2C; /* Legion Pro 7 16ARX8H */
- else
- id = ALC287_FIXUP_CS35L41_I2C_2; /* Legion 7i 16IAX7 */
- __snd_hda_apply_fixup(codec, id, action, 0);
-}
-
-/* Yet more conflicting PCI SSID (17aa:3820) on two Lenovo models */
-static void alc287_fixup_lenovo_ssid_17aa3820(struct hda_codec *codec,
- const struct hda_fixup *fix,
- int action)
-{
- int id;
-
- if (codec->core.subsystem_id == 0x17aa3820)
- id = ALC269_FIXUP_ASPIRE_HEADSET_MIC; /* IdeaPad 330-17IKB 81DM */
- else /* 0x17aa3802 */
- id = ALC287_FIXUP_YOGA7_14ITL_SPEAKERS; /* "Yoga Duet 7 13ITL6 */
- __snd_hda_apply_fixup(codec, id, action, 0);
-}
-
static const struct hda_fixup alc269_fixups[] = {
[ALC269_FIXUP_GPIO2] = {
.type = HDA_FIXUP_FUNC,
@@ -9775,14 +9705,6 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc298_fixup_lenovo_c940_duet7,
},
- [ALC287_FIXUP_LENOVO_14IRP8_DUETITL] = {
- .type = HDA_FIXUP_FUNC,
- .v.func = alc287_fixup_lenovo_14irp8_duetitl,
- },
- [ALC287_FIXUP_LENOVO_LEGION_7] = {
- .type = HDA_FIXUP_FUNC,
- .v.func = alc287_fixup_lenovo_legion_7,
- },
[ALC287_FIXUP_13S_GEN2_SPEAKERS] = {
.type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) {
@@ -9967,10 +9889,6 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
},
- [ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7] = {
- .type = HDA_FIXUP_FUNC,
- .v.func = alc287_fixup_lenovo_14arp8_legion_iah7,
- },
[ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc287_fixup_yoga9_14iap7_bass_spk_pin,
@@ -10105,10 +10023,6 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC225_FIXUP_HEADSET_JACK
},
- [ALC287_FIXUP_LENOVO_SSID_17AA3820] = {
- .type = HDA_FIXUP_FUNC,
- .v.func = alc287_fixup_lenovo_ssid_17aa3820,
- },
[ALC245_FIXUP_CLEVO_NOISY_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_limit_int_mic_boost,
@@ -10127,7 +10041,7 @@ static const struct hda_fixup alc269_fixups[] = {
},
};
-static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
@@ -10856,11 +10770,13 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340),
SND_PCI_QUIRK(0x17aa, 0x334b, "Lenovo ThinkCentre M70 Gen5", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
- SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga Pro 9 14IRP8 / DuetITL 2021", ALC287_FIXUP_LENOVO_14IRP8_DUETITL),
+ HDA_CODEC_QUIRK(0x17aa, 0x3802, "DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
+ SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga Pro 9 14IRP8", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS),
- SND_PCI_QUIRK(0x17aa, 0x3820, "IdeaPad 330 / Yoga Duet 7", ALC287_FIXUP_LENOVO_SSID_17AA3820),
+ HDA_CODEC_QUIRK(0x17aa, 0x3820, "IdeaPad 330-17IKB 81DM", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
+ SND_PCI_QUIRK(0x17aa, 0x3820, "Yoga Duet 7 13ITL6", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
@@ -10874,8 +10790,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3865, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3866, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
- SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7 / Yoga Pro 7 14ARP8", ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7),
- SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7/7i", ALC287_FIXUP_LENOVO_LEGION_7),
+ HDA_CODEC_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x386e, "Yoga Pro 7 14ARP8", ALC285_FIXUP_SPEAKER2_TO_DAC1),
+ HDA_CODEC_QUIRK(0x17aa, 0x386f, "Legion Pro 7 16ARX8H", ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3878, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
@@ -11044,7 +10962,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
{}
};
-static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
+static const struct hda_quirk alc269_fixup_vendor_tbl[] = {
SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
@@ -11977,7 +11895,7 @@ static const struct hda_fixup alc861_fixups[] = {
}
};
-static const struct snd_pci_quirk alc861_fixup_tbl[] = {
+static const struct hda_quirk alc861_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
@@ -12081,7 +11999,7 @@ static const struct hda_fixup alc861vd_fixups[] = {
},
};
-static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
+static const struct hda_quirk alc861vd_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
@@ -12882,7 +12800,7 @@ static const struct hda_fixup alc662_fixups[] = {
},
};
-static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+static const struct hda_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
SND_PCI_QUIRK(0x1019, 0x9859, "JP-IK LEAP W502", ALC897_FIXUP_HEADSET_MIC_PIN3),
SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index ae1a34c68c61..bde6b7373858 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1462,7 +1462,7 @@ static const struct hda_model_fixup stac9200_models[] = {
{}
};
-static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
+static const struct hda_quirk stac9200_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_REF),
@@ -1683,7 +1683,7 @@ static const struct hda_model_fixup stac925x_models[] = {
{}
};
-static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
+static const struct hda_quirk stac925x_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
@@ -1957,7 +1957,7 @@ static const struct hda_model_fixup stac92hd73xx_models[] = {
{}
};
-static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
+static const struct hda_quirk stac92hd73xx_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_92HD73XX_REF),
@@ -2753,7 +2753,7 @@ static const struct hda_model_fixup stac92hd83xxx_models[] = {
{}
};
-static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
+static const struct hda_quirk stac92hd83xxx_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_92HD83XXX_REF),
@@ -3236,7 +3236,7 @@ static const struct hda_model_fixup stac92hd71bxx_models[] = {
{}
};
-static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
+static const struct hda_quirk stac92hd71bxx_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_92HD71BXX_REF),
@@ -3496,7 +3496,7 @@ static const struct hda_pintbl ecs202_pin_configs[] = {
};
/* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
-static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
+static const struct hda_quirk stac922x_intel_mac_fixup_tbl[] = {
SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3),
SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
@@ -3640,7 +3640,7 @@ static const struct hda_model_fixup stac922x_models[] = {
{}
};
-static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
+static const struct hda_quirk stac922x_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_D945_REF),
@@ -3968,7 +3968,7 @@ static const struct hda_model_fixup stac927x_models[] = {
{}
};
-static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
+static const struct hda_quirk stac927x_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_D965_REF),
@@ -4178,7 +4178,7 @@ static const struct hda_model_fixup stac9205_models[] = {
{}
};
-static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
+static const struct hda_quirk stac9205_fixup_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_9205_REF),
@@ -4255,7 +4255,7 @@ static const struct hda_fixup stac92hd95_fixups[] = {
},
};
-static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
+static const struct hda_quirk stac92hd95_fixup_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
{} /* terminator */
};
@@ -5002,7 +5002,7 @@ static const struct hda_fixup stac9872_fixups[] = {
},
};
-static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
+static const struct hda_quirk stac9872_fixup_tbl[] = {
SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
"Sony VAIO F/S", STAC_9872_VAIO),
{} /* terminator */
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index a8ef4bb70dd0..d0893059b1b9 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1035,7 +1035,7 @@ static const struct hda_fixup via_fixups[] = {
},
};
-static const struct snd_pci_quirk vt2002p_fixups[] = {
+static const struct hda_quirk vt2002p_fixups[] = {
SND_PCI_QUIRK(0x1043, 0x13f7, "Asus B23E", VIA_FIXUP_POWER_SAVE),
SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 096ec76f5304..a12dafbf53ab 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -170,14 +170,9 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
tmp = stac9460_get(ice, idx);
ovol = 0x7f - (tmp & 0x7f);
change = (ovol != nvol);
- if (change) {
- ovol = (0x7f - nvol) | (tmp & 0x80);
- /*
- dev_dbg(ice->card->dev, "DAC Volume: reg 0x%02x: 0x%02x\n",
- idx, ovol);
- */
+ if (change)
stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
- }
+
return change;
}
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 936cd6e91529..66b33623549f 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -315,8 +315,6 @@ static void aica_period_elapsed(struct timer_list *t)
static void spu_begin_dma(struct snd_pcm_substream *substream)
{
struct snd_card_aica *dreamcastcard;
- struct snd_pcm_runtime *runtime;
- runtime = substream->runtime;
dreamcastcard = substream->pcm->private_data;
/*get the queue to do the work */
schedule_work(&(dreamcastcard->spu_dma_work));
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 050e98f32d36..b5d53c5550d3 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2616,7 +2616,7 @@ static int dbri_probe(struct platform_device *op)
strcpy(card->driver, "DBRI");
strcpy(card->shortname, "Sun DBRI");
rp = &op->resource[0];
- sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
+ sprintf(card->longname, "%s at 0x%02lx:0x%016llx, irq %d",
card->shortname,
rp->flags & 0xffL, (unsigned long long)rp->start, irq);
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 9945ae55b0d0..b6c3d2ee416e 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2224,7 +2224,8 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
len = get_term_name(state->chip, iterm, kctl->id.name,
sizeof(kctl->id.name), 0);
if (!len)
- len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
+ snprintf(kctl->id.name, sizeof(kctl->id.name), "Mixer Source %d", in_ch + 1);
+
append_ctl_name(kctl, " Volume");
usb_audio_dbg(state->chip, "[%d] MU [%s] ch = %d, val = %d/%d\n",
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 4cddf84db631..7f595c1752a5 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -11,7 +11,7 @@
* - Clarett 2Pre/4Pre/8Pre USB
* - Clarett+ 2Pre/4Pre/8Pre
*
- * Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu>
+ * Copyright (c) 2018-2024 by Geoffrey D. Bennett <g at b4.vu>
* Copyright (c) 2020-2021 by Vladimir Sadovnikov <sadko4u@gmail.com>
* Copyright (c) 2022 by Christian Colglazier <christian@cacolglazier.com>
*
@@ -1079,6 +1079,9 @@ struct scarlett2_device_info {
/* minimum firmware version required */
u16 min_firmware_version;
+ /* has a downloadable device map */
+ u8 has_devmap;
+
/* support for main/alt speaker switching */
u8 has_speaker_switching;
@@ -1253,7 +1256,7 @@ struct scarlett2_data {
u8 phantom_switch[SCARLETT2_PHANTOM_SWITCH_MAX];
u8 phantom_persistence;
u8 input_select_switch;
- u8 input_link_switch[SCARLETT2_INPUT_GAIN_MAX / 2];
+ u8 input_link_switch[SCARLETT2_INPUT_GAIN_MAX];
u8 gain[SCARLETT2_INPUT_GAIN_MAX];
u8 autogain_switch[SCARLETT2_INPUT_GAIN_MAX];
u8 autogain_status[SCARLETT2_INPUT_GAIN_MAX];
@@ -1284,7 +1287,7 @@ struct scarlett2_data {
struct snd_kcontrol *input_mute_ctls[SCARLETT2_INPUT_MUTE_SWITCH_MAX];
struct snd_kcontrol *phantom_ctls[SCARLETT2_PHANTOM_SWITCH_MAX];
struct snd_kcontrol *input_select_ctl;
- struct snd_kcontrol *input_link_ctls[SCARLETT2_INPUT_GAIN_MAX / 2];
+ struct snd_kcontrol *input_link_ctls[SCARLETT2_INPUT_GAIN_MAX];
struct snd_kcontrol *input_gain_ctls[SCARLETT2_INPUT_GAIN_MAX];
struct snd_kcontrol *autogain_ctls[SCARLETT2_INPUT_GAIN_MAX];
struct snd_kcontrol *autogain_status_ctls[SCARLETT2_INPUT_GAIN_MAX];
@@ -1773,6 +1776,7 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
static const struct scarlett2_device_info vocaster_one_info = {
.config_set = &scarlett2_config_set_vocaster,
.min_firmware_version = 1769,
+ .has_devmap = 1,
.phantom_count = 1,
.inputs_per_phantom = 1,
@@ -1815,6 +1819,7 @@ static const struct scarlett2_device_info vocaster_one_info = {
static const struct scarlett2_device_info vocaster_two_info = {
.config_set = &scarlett2_config_set_vocaster,
.min_firmware_version = 1769,
+ .has_devmap = 1,
.phantom_count = 2,
.inputs_per_phantom = 1,
@@ -1858,6 +1863,7 @@ static const struct scarlett2_device_info vocaster_two_info = {
static const struct scarlett2_device_info solo_gen4_info = {
.config_set = &scarlett2_config_set_gen4_solo,
.min_firmware_version = 2115,
+ .has_devmap = 1,
.level_input_count = 1,
.air_input_count = 1,
@@ -1912,6 +1918,7 @@ static const struct scarlett2_device_info solo_gen4_info = {
static const struct scarlett2_device_info s2i2_gen4_info = {
.config_set = &scarlett2_config_set_gen4_2i2,
.min_firmware_version = 2115,
+ .has_devmap = 1,
.level_input_count = 2,
.air_input_count = 2,
@@ -1966,6 +1973,7 @@ static const struct scarlett2_device_info s2i2_gen4_info = {
static const struct scarlett2_device_info s4i4_gen4_info = {
.config_set = &scarlett2_config_set_gen4_4i4,
.min_firmware_version = 2089,
+ .has_devmap = 1,
.level_input_count = 2,
.air_input_count = 2,
@@ -2264,6 +2272,8 @@ static int scarlett2_get_port_start_num(
#define SCARLETT2_USB_GET_DATA 0x00800000
#define SCARLETT2_USB_SET_DATA 0x00800001
#define SCARLETT2_USB_DATA_CMD 0x00800002
+#define SCARLETT2_USB_INFO_DEVMAP 0x0080000c
+#define SCARLETT2_USB_GET_DEVMAP 0x0080000d
#define SCARLETT2_USB_CONFIG_SAVE 6
@@ -2277,6 +2287,14 @@ static int scarlett2_get_port_start_num(
#define SCARLETT2_SEGMENT_SETTINGS_NAME "App_Settings"
#define SCARLETT2_SEGMENT_FIRMWARE_NAME "App_Upgrade"
+/* Gen 4 device firmware provides access to a base64-encoded
+ * zlib-compressed JSON description of the device's capabilities and
+ * configuration. This device map is made available in
+ * /proc/asound/cardX/device-map.json.zz.b64
+ */
+#define SCARLETT2_DEVMAP_BLOCK_SIZE 1024
+#define SCARLETT2_DEVMAP_FILENAME "device-map.json.zz.b64"
+
/* proprietary request/response format */
struct scarlett2_usb_packet {
__le32 cmd;
@@ -3409,7 +3427,7 @@ static int scarlett2_update_autogain(struct usb_mixer_interface *mixer)
private->num_autogain_status_texts - 1;
- for (int i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++)
+ for (i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++)
if (scarlett2_has_config_item(private,
scarlett2_ag_target_configs[i])) {
err = scarlett2_usb_get_config(
@@ -3420,7 +3438,7 @@ static int scarlett2_update_autogain(struct usb_mixer_interface *mixer)
}
/* convert from negative dBFS as used by the device */
- for (int i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++)
+ for (i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++)
private->ag_targets[i] = -ag_target_values[i];
return 0;
@@ -3439,7 +3457,7 @@ static void scarlett2_autogain_update_access(struct usb_mixer_interface *mixer)
scarlett2_set_ctl_access(private->input_select_ctl, val);
if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_LINK_SWITCH))
- for (i = 0; i < info->gain_input_count / 2; i++)
+ for (i = 0; i < info->gain_input_count; i++)
scarlett2_set_ctl_access(private->input_link_ctls[i],
val);
for (i = 0; i < info->gain_input_count; i++)
@@ -3480,7 +3498,7 @@ static void scarlett2_autogain_notify_access(struct usb_mixer_interface *mixer)
&private->input_select_ctl->id);
if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_LINK_SWITCH))
- for (i = 0; i < info->gain_input_count / 2; i++)
+ for (i = 0; i < info->gain_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
&private->input_link_ctls[i]->id);
for (i = 0; i < info->gain_input_count; i++)
@@ -3825,7 +3843,7 @@ static int scarlett2_update_input_select(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- int link_count = info->gain_input_count / 2;
+ int link_count = info->gain_input_count;
int err;
private->input_select_updated = 0;
@@ -3847,10 +3865,6 @@ static int scarlett2_update_input_select(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- /* simplified because no model yet has link_count > 1 */
- if (private->input_link_switch[0])
- private->input_select_switch = 0;
-
return 0;
}
@@ -3887,9 +3901,9 @@ static int scarlett2_input_select_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
int oval, val, err;
- int max_val = private->input_link_switch[0] ? 0 : 1;
mutex_lock(&private->data_mutex);
@@ -3907,19 +3921,18 @@ static int scarlett2_input_select_ctl_put(
if (val < 0)
val = 0;
- else if (val > max_val)
- val = max_val;
+ else if (val >= info->gain_input_count)
+ val = info->gain_input_count - 1;
if (oval == val)
goto unlock;
private->input_select_switch = val;
- /* Send switch change to the device if inputs not linked */
- if (!private->input_link_switch[0])
- err = scarlett2_usb_set_config(
- mixer, SCARLETT2_CONFIG_INPUT_SELECT_SWITCH,
- 1, val);
+ /* Send new value to the device */
+ err = scarlett2_usb_set_config(
+ mixer, SCARLETT2_CONFIG_INPUT_SELECT_SWITCH,
+ 0, val);
if (err == 0)
err = 1;
@@ -3936,8 +3949,7 @@ static int scarlett2_input_select_ctl_info(
struct scarlett2_data *private = mixer->private_data;
int inputs = private->info->gain_input_count;
- int i, j;
- int err;
+ int i, err;
char **values = kcalloc(inputs, sizeof(char *), GFP_KERNEL);
if (!values)
@@ -3954,21 +3966,11 @@ static int scarlett2_input_select_ctl_info(
if (err < 0)
goto unlock;
- /* Loop through each input
- * Linked inputs have one value for the pair
- */
- for (i = 0, j = 0; i < inputs; i++) {
- if (private->input_link_switch[i / 2]) {
- values[j++] = kasprintf(
- GFP_KERNEL, "Input %d-%d", i + 1, i + 2);
- i++;
- } else {
- values[j++] = kasprintf(
- GFP_KERNEL, "Input %d", i + 1);
- }
- }
+ /* Loop through each input */
+ for (i = 0; i < inputs; i++)
+ values[i] = kasprintf(GFP_KERNEL, "Input %d", i + 1);
- err = snd_ctl_enum_info(uinfo, 1, j,
+ err = snd_ctl_enum_info(uinfo, 1, i,
(const char * const *)values);
unlock:
@@ -4077,18 +4079,8 @@ static int scarlett2_input_link_ctl_put(
private->input_link_switch[index] = val;
- /* Notify of change in input select options available */
- snd_ctl_notify(mixer->chip->card,
- SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
- &private->input_select_ctl->id);
- private->input_select_updated = 1;
-
- /* Send switch change to the device
- * Link for channels 1-2 is at index 1
- * No device yet has more than 2 channels linked
- */
err = scarlett2_usb_set_config(
- mixer, SCARLETT2_CONFIG_INPUT_LINK_SWITCH, index + 1, val);
+ mixer, SCARLETT2_CONFIG_INPUT_LINK_SWITCH, index, val);
if (err == 0)
err = 1;
@@ -5385,6 +5377,8 @@ static int scarlett2_compressor_ctl_put(
int index = elem->control;
int channel = index / SCARLETT2_COMPRESSOR_PARAM_COUNT;
int param_index = index % SCARLETT2_COMPRESSOR_PARAM_COUNT;
+ const struct compressor_param *param = &compressor_params[param_index];
+
int oval, val, err;
s32 scaled_val;
@@ -5406,8 +5400,6 @@ static int scarlett2_compressor_ctl_put(
private->compressor_values[index] = val;
- const struct compressor_param *param = &compressor_params[param_index];
-
scaled_val = val << param->scale_bits;
/* Send change to the device */
@@ -6916,10 +6908,9 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_LINK_SWITCH)) {
- for (i = 0; i < info->gain_input_count / 2; i++) {
+ for (i = 0; i < info->gain_input_count; i++) {
scnprintf(s, sizeof(s),
- "Line In %d-%d Link Capture Switch",
- (i * 2) + 1, (i * 2) + 2);
+ "Line In %d Link Capture Switch", i + 1);
err = scarlett2_add_new_ctl(
mixer, &scarlett2_input_link_ctl,
i, 1, s, &private->input_link_ctls[i]);
@@ -8246,7 +8237,7 @@ static void scarlett2_notify_input_select(struct usb_mixer_interface *mixer)
SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
&private->input_select_ctl->id);
- for (i = 0; i < info->gain_input_count / 2; i++)
+ for (i = 0; i < info->gain_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->input_link_ctls[i]->id);
}
@@ -9518,7 +9509,7 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw,
SCARLETT2_FLASH_BLOCK_SIZE;
if (count < 0 || *offset < 0 || *offset + count >= flash_size)
- return -EINVAL;
+ return -ENOSPC;
if (!count)
return 0;
@@ -9591,6 +9582,116 @@ static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer)
return 0;
}
+/*** device-map file ***/
+
+static ssize_t scarlett2_devmap_read(
+ struct snd_info_entry *entry,
+ void *file_private_data,
+ struct file *file,
+ char __user *buf,
+ size_t count,
+ loff_t pos)
+{
+ struct usb_mixer_interface *mixer = entry->private_data;
+ u8 *resp_buf;
+ const size_t block_size = SCARLETT2_DEVMAP_BLOCK_SIZE;
+ size_t copied = 0;
+
+ if (pos >= entry->size)
+ return 0;
+
+ if (pos + count > entry->size)
+ count = entry->size - pos;
+
+ resp_buf = kmalloc(block_size, GFP_KERNEL);
+ if (!resp_buf)
+ return -ENOMEM;
+
+ while (count > 0) {
+ /* SCARLETT2_USB_GET_DEVMAP reads only on block boundaries,
+ * so we need to read a whole block and copy the requested
+ * chunk to userspace.
+ */
+
+ __le32 req;
+ int err;
+
+ /* offset within the block that we're reading */
+ size_t offset = pos % block_size;
+
+ /* read_size is block_size except for the last block */
+ size_t block_start = pos - offset;
+ size_t read_size = min_t(size_t,
+ block_size,
+ entry->size - block_start);
+
+ /* size of the chunk to copy to userspace */
+ size_t copy_size = min_t(size_t, count, read_size - offset);
+
+ /* request the block */
+ req = cpu_to_le32(pos / block_size);
+ err = scarlett2_usb(mixer, SCARLETT2_USB_GET_DEVMAP,
+ &req, sizeof(req), resp_buf, read_size);
+ if (err < 0) {
+ kfree(resp_buf);
+ return copied ? copied : err;
+ }
+
+ if (copy_to_user(buf, resp_buf + offset, copy_size)) {
+ kfree(resp_buf);
+ return -EFAULT;
+ }
+
+ buf += copy_size;
+ pos += copy_size;
+ copied += copy_size;
+ count -= copy_size;
+ }
+
+ kfree(resp_buf);
+ return copied;
+}
+
+static const struct snd_info_entry_ops scarlett2_devmap_ops = {
+ .read = scarlett2_devmap_read,
+};
+
+static int scarlett2_devmap_init(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ __le16 config_len_buf[2];
+ int config_len;
+ struct snd_info_entry *entry;
+ int err;
+
+ /* If the device doesn't support the DEVMAP commands, don't
+ * create the /proc/asound/cardX/scarlett.json.zlib entry
+ */
+ if (!info->has_devmap)
+ return 0;
+
+ err = scarlett2_usb(mixer, SCARLETT2_USB_INFO_DEVMAP,
+ NULL, 0, &config_len_buf, sizeof(config_len_buf));
+ if (err < 0)
+ return err;
+
+ config_len = le16_to_cpu(config_len_buf[1]);
+
+ err = snd_card_proc_new(card, SCARLETT2_DEVMAP_FILENAME, &entry);
+ if (err < 0)
+ return err;
+
+ entry->content = SNDRV_INFO_CONTENT_DATA;
+ entry->private_data = mixer;
+ entry->c.ops = &scarlett2_devmap_ops;
+ entry->size = config_len;
+ entry->mode = S_IFREG | 0444;
+
+ return 0;
+}
+
int snd_scarlett2_init(struct usb_mixer_interface *mixer)
{
struct snd_usb_audio *chip = mixer->chip;
@@ -9641,11 +9742,20 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer)
}
err = scarlett2_hwdep_init(mixer);
- if (err < 0)
+ if (err < 0) {
usb_audio_err(mixer->chip,
"Error creating %s hwdep device: %d",
entry->series_name,
err);
+ return err;
+ }
+
+ err = scarlett2_devmap_init(mixer);
+ if (err < 0)
+ usb_audio_err(mixer->chip,
+ "Error creating %s devmap entry: %d",
+ entry->series_name,
+ err);
return err;
}