summaryrefslogtreecommitdiff
path: root/src/mainboard/google/octopus/mainboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/google/octopus/mainboard.c')
-rw-r--r--src/mainboard/google/octopus/mainboard.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/mainboard/google/octopus/mainboard.c b/src/mainboard/google/octopus/mainboard.c
index e6dbd0330b..91d29cf61c 100644
--- a/src/mainboard/google/octopus/mainboard.c
+++ b/src/mainboard/google/octopus/mainboard.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h>
+#include <baseboard/cbi_ssfc.h>
#include <baseboard/variants.h>
#include <boardid.h>
#include <bootstate.h>
@@ -8,6 +9,7 @@
#include <device/device.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
+#include <drivers/i2c/generic/chip.h>
#include <ec/google/chromeec/ec.h>
#include <ec/ec.h>
#include <intelblocks/xhci.h>
@@ -22,6 +24,9 @@
#include <variant/ec.h>
#include <variant/gpio.h>
+extern struct chip_operations drivers_i2c_generic_ops;
+extern struct chip_operations drivers_i2c_da7219_ops;
+
static bool is_cnvi_held_in_reset(void)
{
struct device *dev = pcidev_path_on_root(PCH_DEVFN_CNVI);
@@ -46,6 +51,41 @@ static void disable_wifi_wake(void)
gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
}
+/*
+ * GPIO_137 for two audio codecs right now has the different configuration so
+ * if SSFC indicates that codec is different than default one then GPIO_137
+ * needs to be overridden for the corresponding second source.
+ */
+static void gpio_modification_by_ssfc(struct pad_config *table, size_t num)
+{
+ /* For RT5682, GPIO 137 should be set as EDGE_BOTH. */
+ const struct pad_config rt5682_gpio_137 = PAD_CFG_GPI_APIC_IOS(GPIO_137,
+ NONE, DEEP, EDGE_BOTH, INVERT, HIZCRx1, DISPUPD);
+
+ if (table == NULL || num == 0)
+ return;
+
+ /*
+ * Currently we only have the case of RT5682 as the second source. And
+ * in case of Ampton which used RT5682 as the default source, it didn't
+ * provide override_table right now so it will be returned ealier since
+ * table above is NULL.
+ */
+ if (ssfc_get_audio_codec() != SSFC_AUDIO_CODEC_RT5682)
+ return;
+
+ while (num--) {
+ if (table->pad == GPIO_137) {
+ *table = rt5682_gpio_137;
+ printk(BIOS_INFO,
+ "Configure GPIO 137 based on SSFC.\n");
+ return;
+ }
+
+ table++;
+ }
+}
+
static void mainboard_init(void *chip_info)
{
int boardid;
@@ -58,6 +98,8 @@ static void mainboard_init(void *chip_info)
base_pads = variant_base_gpio_table(&base_num);
override_pads = variant_override_gpio_table(&override_num);
+ gpio_modification_by_ssfc((struct pad_config *)override_pads,
+ override_num);
gpio_configure_pads_with_override(base_pads, base_num,
override_pads, override_num);
@@ -128,10 +170,47 @@ static void wifi_device_update(void)
dev->enabled = 0;
}
+/*
+ * Base on SSFC value in the CBI from EC to enable one of audio codec sources in
+ * the device tree.
+ */
+static void audio_codec_device_update(void)
+{
+ struct device *audio_dev = NULL;
+ struct bus *audio_i2c_bus =
+ pcidev_path_on_root(PCH_DEVFN_I2C5)->link_list;
+ enum ssfc_audio_codec codec = ssfc_get_audio_codec();
+
+ while ((audio_dev = dev_bus_each_child(audio_i2c_bus, audio_dev))) {
+ if (audio_dev->chip_info == NULL)
+ continue;
+
+ if ((audio_dev->chip_ops == &drivers_i2c_da7219_ops) &&
+ (codec == SSFC_AUDIO_CODEC_DA7219)) {
+ printk(BIOS_INFO, "enable DA7219.\n");
+ continue;
+ }
+
+ if ((audio_dev->chip_ops == &drivers_i2c_generic_ops) &&
+ (codec == SSFC_AUDIO_CODEC_RT5682)) {
+ struct drivers_i2c_generic_config *cfg =
+ audio_dev->chip_info;
+
+ if (cfg != NULL && !strcmp(cfg->hid, "10EC5682")) {
+ printk(BIOS_INFO, "enable RT5682.\n");
+ continue;
+ }
+ }
+
+ audio_dev->enabled = 0;
+ }
+}
+
void mainboard_devtree_update(struct device *dev)
{
/* Apply common devtree updates. */
wifi_device_update();
+ audio_codec_device_update();
/* Defer to variant for board-specific updates. */
variant_update_devtree(dev);