|
@@ -76,12 +76,16 @@
|
|
|
#define SCP_GET 1
|
|
|
|
|
|
#define EFX_FILE "ctefx.bin"
|
|
|
+#define SBZ_EFX_FILE "ctefx-sbz.bin"
|
|
|
+#define R3DI_EFX_FILE "ctefx-r3di.bin"
|
|
|
|
|
|
#ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP
|
|
|
MODULE_FIRMWARE(EFX_FILE);
|
|
|
+MODULE_FIRMWARE(SBZ_EFX_FILE);
|
|
|
+MODULE_FIRMWARE(R3DI_EFX_FILE);
|
|
|
#endif
|
|
|
|
|
|
-static char *dirstr[2] = { "Playback", "Capture" };
|
|
|
+static const char *dirstr[2] = { "Playback", "Capture" };
|
|
|
|
|
|
enum {
|
|
|
SPEAKER_OUT,
|
|
@@ -738,6 +742,7 @@ struct ca0132_spec {
|
|
|
unsigned int scp_resp_header;
|
|
|
unsigned int scp_resp_data[4];
|
|
|
unsigned int scp_resp_count;
|
|
|
+ bool alt_firmware_present;
|
|
|
|
|
|
/* mixer and effects related */
|
|
|
unsigned char dmic_ctl;
|
|
@@ -766,6 +771,8 @@ struct ca0132_spec {
|
|
|
enum {
|
|
|
QUIRK_NONE,
|
|
|
QUIRK_ALIENWARE,
|
|
|
+ QUIRK_SBZ,
|
|
|
+ QUIRK_R3DI,
|
|
|
};
|
|
|
|
|
|
static const struct hda_pintbl alienware_pincfgs[] = {
|
|
@@ -786,6 +793,10 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
|
|
|
SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
|
|
|
SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
|
|
|
SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
|
|
|
+ SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
|
|
|
+ SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
|
|
|
+ SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
|
|
|
+ SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI),
|
|
|
{}
|
|
|
};
|
|
|
|
|
@@ -3211,7 +3222,7 @@ static int ca0132_select_out(struct hda_codec *codec)
|
|
|
pin_ctl & ~PIN_HP);
|
|
|
/* enable speaker node */
|
|
|
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
|
|
|
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
|
+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
|
snd_hda_set_pin_ctl(codec, spec->out_pins[0],
|
|
|
pin_ctl | PIN_OUT);
|
|
|
} else {
|
|
@@ -4374,11 +4385,49 @@ static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k)
|
|
|
static bool ca0132_download_dsp_images(struct hda_codec *codec)
|
|
|
{
|
|
|
bool dsp_loaded = false;
|
|
|
+ struct ca0132_spec *spec = codec->spec;
|
|
|
const struct dsp_image_seg *dsp_os_image;
|
|
|
const struct firmware *fw_entry;
|
|
|
-
|
|
|
- if (request_firmware(&fw_entry, EFX_FILE, codec->card->dev) != 0)
|
|
|
- return false;
|
|
|
+ /*
|
|
|
+ * Alternate firmwares for different variants. The Recon3Di apparently
|
|
|
+ * can use the default firmware, but I'll leave the option in case
|
|
|
+ * it needs it again.
|
|
|
+ */
|
|
|
+ switch (spec->quirk) {
|
|
|
+ case QUIRK_SBZ:
|
|
|
+ if (request_firmware(&fw_entry, SBZ_EFX_FILE,
|
|
|
+ codec->card->dev) != 0) {
|
|
|
+ codec_dbg(codec, "SBZ alt firmware not detected. ");
|
|
|
+ spec->alt_firmware_present = false;
|
|
|
+ } else {
|
|
|
+ codec_dbg(codec, "Sound Blaster Z firmware selected.");
|
|
|
+ spec->alt_firmware_present = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case QUIRK_R3DI:
|
|
|
+ if (request_firmware(&fw_entry, R3DI_EFX_FILE,
|
|
|
+ codec->card->dev) != 0) {
|
|
|
+ codec_dbg(codec, "Recon3Di alt firmware not detected.");
|
|
|
+ spec->alt_firmware_present = false;
|
|
|
+ } else {
|
|
|
+ codec_dbg(codec, "Recon3Di firmware selected.");
|
|
|
+ spec->alt_firmware_present = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ spec->alt_firmware_present = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * Use default ctefx.bin if no alt firmware is detected, or if none
|
|
|
+ * exists for your particular codec.
|
|
|
+ */
|
|
|
+ if (!spec->alt_firmware_present) {
|
|
|
+ codec_dbg(codec, "Default firmware selected.");
|
|
|
+ if (request_firmware(&fw_entry, EFX_FILE,
|
|
|
+ codec->card->dev) != 0)
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
|
|
|
if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
|
|
@@ -4480,7 +4529,7 @@ static struct hda_verb ca0132_base_exit_verbs[] = {
|
|
|
{}
|
|
|
};
|
|
|
|
|
|
-/* Other verbs tables. Sends after DSP download. */
|
|
|
+/* Other verbs tables. Sends after DSP download. */
|
|
|
static struct hda_verb ca0132_init_verbs0[] = {
|
|
|
/* chip init verbs */
|
|
|
{0x15, 0x70D, 0xF0},
|