Commit 77bdbae9 authored by Connor McAdams's avatar Connor McAdams Committed by Takashi Iwai
Browse files

ALSA: hda/ca0132 - Add pre-init function for SoundBlaster AE-7.



Add pre DSP initialization function for the AE-7.

Signed-off-by: default avatarConnor McAdams <conmanx360@gmail.com>
Link: https://lore.kernel.org/r/20200825201040.30339-15-conmanx360@gmail.com


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 4e356d56
Loading
Loading
Loading
Loading
+55 −15
Original line number Diff line number Diff line
@@ -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,24 +8823,42 @@ 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;
	}

	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);

	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);