blob: 7e9f4d2c4828e08fc1df4a3c27b9b7ab1e8843b5 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Laurie0a7c49e2013-06-20 12:40:55 -07002
3#include <console/console.h>
Elyes HAOUASeaf2ae72020-08-03 15:33:49 +02004#include <device/azalia_device.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Elyes HAOUASa3022052020-08-11 16:47:47 +02006
Duncan Laurie0a7c49e2013-06-20 12:40:55 -07007#include "hda_verb.h"
8
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08009int hda_codec_detect(u8 *base)
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070010{
11 u8 reg8;
12
13 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
Angel Pons7f839f62020-12-05 19:02:14 +010014 if (azalia_exit_reset(base) < 0)
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070015 goto no_codec;
16
17 /* Write back the value once reset bit is set. */
18 write16(base + HDA_GCAP_REG, read16(base + HDA_GCAP_REG));
19
Angel Ponsf20ef652021-03-18 17:09:49 +010020 /*
21 * Clear the "State Change Status Register" STATESTS bits
22 * for each of the "SDIN Stat Change Status Flag"
23 */
24 write8(base + HDA_STATESTS_REG, 0xf);
25
26 /* Turn off the link and poll RESET# bit until it reads back as 0 */
27 if (azalia_enter_reset(base) < 0)
28 goto no_codec;
29
30 /* Turn on the link and poll RESET# bit until it reads back as 1 */
31 if (azalia_exit_reset(base) < 0)
32 goto no_codec;
33
Angel Pons90cdf702020-10-24 23:00:34 +020034 /* Read in Codec location (BAR + 0xe)[2..0] */
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070035 reg8 = read8(base + HDA_STATESTS_REG);
36 reg8 &= 0x0f;
37 if (!reg8)
38 goto no_codec;
39
40 return reg8;
41
42no_codec:
Angel Pons2e0053b2020-12-05 19:06:55 +010043 /* Codec not found, put HDA back in reset */
44 azalia_enter_reset(base);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070045 printk(BIOS_DEBUG, "HDA: No codec!\n");
46 return 0;
47}