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

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.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 4e356d56
......@@ -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);
......
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