// SPDX-License-Identifier: GPL-2.0
/*
 * Intel HDA audio (Azalia) for ivybridge
 *
 * Originally from coreboot file bd82x6x/azalia.c
 *
 * Copyright (C) 2008 Advanced Micro Devices, Inc.
 * Copyright (C) 2008-2009 coresystems GmbH
 * Copyright (C) 2011 The ChromiumOS Authors.
 * Copyright 2018 Google LLC
 */

#define LOG_CATEGORY UCLASS_SOUND

#include <common.h>
#include <dm.h>
#include <hda_codec.h>
#include <log.h>
#include <pch.h>
#include <sound.h>
#include <linux/bitops.h>

static int bd82x6x_azalia_probe(struct udevice *dev)
{
	struct pci_child_plat *plat;
	struct hda_codec_priv *priv;
	struct udevice *pch;
	u32 codec_mask;
	int conf;
	int ret;

	/* Only init after relocation */
	if (!(gd->flags & GD_FLG_RELOC))
		return 0;

	ret = hda_codec_init(dev);
	if (ret) {
		log_debug("Cannot set up HDA codec (err=%d)\n", ret);
		return ret;
	}
	priv = dev_get_priv(dev);

	ret = uclass_first_device_err(UCLASS_PCH, &pch);
	log_debug("PCH %p %s\n", pch, pch->name);
	if (ret)
		return ret;

	conf = pch_ioctl(pch, PCH_REQ_HDA_CONFIG, NULL, 0);
	log_debug("conf = %x\n", conf);
	if (conf >= 0) {
		dm_pci_clrset_config32(dev, 0x120, 7 << 24 | 0xfe,
				       1 << 24 | /* 2 << 24 for server */
				       conf);

		dm_pci_clrset_config16(dev, 0x78, 0, 1 << 1);
	} else {
		log_debug("V1CTL disabled\n");
	}
	dm_pci_clrset_config32(dev, 0x114, 0xfe, 0);

	/* Set VCi enable bit */
	dm_pci_clrset_config32(dev, 0x120, 0, 1U << 31);

	/* Enable HDMI codec */
	dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 1);
	dm_pci_clrset_config8(dev, 0x43, 0, 1 << 6);

	/* Additional programming steps */
	dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 13);
	dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 10);
	dm_pci_clrset_config32(dev, 0xd0, 1U << 31, 0);

	/* Additional step on Panther Point */
	plat = dev_get_parent_plat(dev);
	if (plat->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA)
		dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 17);

	dm_pci_write_config8(dev, 0x3c, 0xa); /* unused? */

	/* Audio Control: Select Azalia mode */
	dm_pci_clrset_config8(dev, 0x40, 0, 1);
	dm_pci_clrset_config8(dev, 0x4d, 1 << 7, 0); /* Docking not supported */
	codec_mask = hda_codec_detect(priv->regs);
	log_debug("codec_mask = %02x\n", codec_mask);

	if (codec_mask) {
		ret = hda_codecs_init(dev, priv->regs, codec_mask);
		if (ret) {
			log_err("Codec init failed (err=%d)\n", ret);
			return ret;
		}
	}

	/* Enable dynamic clock gating */
	dm_pci_clrset_config8(dev, 0x43, 7, BIT(2) | BIT(0));

	ret = hda_codec_finish_init(dev);
	if (ret) {
		log_debug("Cannot set up HDA codec (err=%d)\n", ret);
		return ret;
	}

	return 0;
}

static int bd82x6x_azalia_setup(struct udevice *dev)
{
	return 0;
}

int bd82x6x_azalia_start_beep(struct udevice *dev, int frequency_hz)
{
	return hda_codec_start_beep(dev, frequency_hz);
}

int bd82x6x_azalia_stop_beep(struct udevice *dev)
{
	return hda_codec_stop_beep(dev);
}

static const struct sound_ops bd82x6x_azalia_ops = {
	.setup		= bd82x6x_azalia_setup,
	.start_beep	= bd82x6x_azalia_start_beep,
	.stop_beep	= bd82x6x_azalia_stop_beep,
};

static const struct udevice_id bd82x6x_azalia_ids[] = {
	{ .compatible = "intel,hd-audio" },
	{ }
};

U_BOOT_DRIVER(bd82x6x_azalia_drv) = {
	.name		= "bd82x6x-hda",
	.id		= UCLASS_SOUND,
	.of_match	= bd82x6x_azalia_ids,
	.probe		= bd82x6x_azalia_probe,
	.ops		= &bd82x6x_azalia_ops,
	.priv_auto	= sizeof(struct hda_codec_priv),
};
