ALSA: hda/ca0132 - Add pre-init function for SoundBlaster AE-7.
authorConnor McAdams <conmanx360@gmail.com>
Tue, 25 Aug 2020 20:10:33 +0000 (16:10 -0400)
committerTakashi Iwai <tiwai@suse.de>
Wed, 26 Aug 2020 08:28:13 +0000 (10:28 +0200)
Add pre DSP initialization function for the AE-7.

Signed-off-by: Connor McAdams <conmanx360@gmail.com>
Link: https://lore.kernel.org/r/20200825201040.30339-15-conmanx360@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/patch_ca0132.c

index 10aaa48..cd46112 100644 (file)
@@ -8786,6 +8786,16 @@ static void ca0132_mmio_init(struct hda_codec *codec)
        }
 }
 
+static const unsigned int ca0132_ae5_register_set_addresses[] = {
+       0x304, 0x304, 0x304, 0x304, 0x100, 0x304, 0x100, 0x304, 0x100, 0x304,
+       0x100, 0x304, 0x86c, 0x800, 0x86c, 0x800, 0x804
+};
+
+static const unsigned char ca0132_ae5_register_set_data[] = {
+       0x0f, 0x0e, 0x1f, 0x0c, 0x3f, 0x08, 0x7f, 0x00, 0xff, 0x00, 0x6b,
+       0x01, 0x6b, 0x57
+};
+
 /*
  * This function writes to some SFR's, does some region2 writes, and then
  * eventually resets the codec with the 0x7ff verb. Not quite sure why it does
@@ -8794,6 +8804,18 @@ static void ca0132_mmio_init(struct hda_codec *codec)
 static void ae5_register_set(struct hda_codec *codec)
 {
        struct ca0132_spec *spec = codec->spec;
+       unsigned int count = ARRAY_SIZE(ca0132_ae5_register_set_addresses);
+       const unsigned int *addr = ca0132_ae5_register_set_addresses;
+       const unsigned char *data = ca0132_ae5_register_set_data;
+       unsigned int i, cur_addr;
+       unsigned char tmp[3];
+
+       if (ca0132_quirk(spec) == QUIRK_AE7) {
+               snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+                                   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x41);
+               snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+                                   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc8);
+       }
 
        chipio_8051_write_direct(codec, 0x93, 0x10);
        snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
@@ -8801,25 +8823,43 @@ static void ae5_register_set(struct hda_codec *codec)
        snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
                            VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
 
-       writeb(0x0f, spec->mem_base + 0x304);
-       writeb(0x0f, spec->mem_base + 0x304);
-       writeb(0x0f, spec->mem_base + 0x304);
-       writeb(0x0f, spec->mem_base + 0x304);
-       writeb(0x0e, spec->mem_base + 0x100);
-       writeb(0x1f, spec->mem_base + 0x304);
-       writeb(0x0c, spec->mem_base + 0x100);
-       writeb(0x3f, spec->mem_base + 0x304);
-       writeb(0x08, spec->mem_base + 0x100);
-       writeb(0x7f, spec->mem_base + 0x304);
-       writeb(0x00, spec->mem_base + 0x100);
-       writeb(0xff, spec->mem_base + 0x304);
+       if (ca0132_quirk(spec) == QUIRK_AE7) {
+               tmp[0] = 0x03;
+               tmp[1] = 0x03;
+               tmp[2] = 0x07;
+       } else {
+               tmp[0] = 0x0f;
+               tmp[1] = 0x0f;
+               tmp[2] = 0x0f;
+       }
 
-       ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
+       for (i = cur_addr = 0; i < 3; i++, cur_addr++)
+               writeb(tmp[i], spec->mem_base + addr[cur_addr]);
+
+       /*
+        * First writes are in single bytes, final are in 4 bytes. So, we use
+        * writeb, then writel.
+        */
+       for (i = 0; cur_addr < 12; i++, cur_addr++)
+               writeb(data[i], spec->mem_base + addr[cur_addr]);
+
+       for (; cur_addr < count; i++, cur_addr++)
+               writel(data[i], spec->mem_base + addr[cur_addr]);
+
+       writel(0x00800001, spec->mem_base + 0x20c);
+
+       if (ca0132_quirk(spec) == QUIRK_AE7) {
+               ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
+               ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
+       } else {
+               ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
+       }
 
        chipio_8051_write_direct(codec, 0x90, 0x00);
        chipio_8051_write_direct(codec, 0x90, 0x10);
 
-       ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
+       if (ca0132_quirk(spec) == QUIRK_AE5)
+               ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
 
        chipio_write(codec, 0x18b0a4, 0x000000c2);
 
@@ -8918,7 +8958,7 @@ static int ca0132_init(struct hda_codec *codec)
 
        snd_hda_power_up_pm(codec);
 
-       if (ca0132_quirk(spec) == QUIRK_AE5)
+       if (ca0132_quirk(spec) == QUIRK_AE5 || ca0132_quirk(spec) == QUIRK_AE7)
                ae5_register_set(codec);
 
        ca0132_init_unsol(codec);