u-boot/drivers/sound/ivybridge_sound.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

141 lines
3.3 KiB
C

// 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>
#include <asm/global_data.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),
};