1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <baseboard/cbi_ssfc.h>
5 #include <baseboard/variants.h>
8 #include <console/console.h>
9 #include <device/device.h>
10 #include <device/pci_def.h>
11 #include <device/pci_ops.h>
12 #include <drivers/i2c/generic/chip.h>
13 #include <ec/google/chromeec/ec.h>
15 #include <intelblocks/xhci.h>
20 #include <soc/pci_devs.h>
22 #include <variant/ec.h>
23 #include <variant/gpio.h>
25 extern struct chip_operations drivers_i2c_generic_ops
;
26 extern struct chip_operations drivers_i2c_cs42l42_ops
;
27 extern struct chip_operations drivers_i2c_da7219_ops
;
29 static bool is_cnvi_held_in_reset(void)
31 struct device
*dev
= pcidev_path_on_root(PCH_DEVFN_CNVI
);
32 uint32_t reg
= pci_read_config32(dev
, PCI_VENDOR_ID
);
35 * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
36 * assume that it is being held in reset.
38 if (reg
== 0xffffffff)
44 static void disable_wifi_wake(void)
46 static const struct pad_config wifi_wake_gpio
[] = {
47 PAD_NC(GPIO_119
, UP_20K
),
50 gpio_configure_pads(wifi_wake_gpio
, ARRAY_SIZE(wifi_wake_gpio
));
54 * GPIO_137 for two audio codecs right now has the different configuration so
55 * if SSFC indicates that codec is different than default one then GPIO_137
56 * needs to be overridden for the corresponding second source.
58 static void gpio_modification_by_ssfc(struct pad_config
*table
, size_t num
)
60 /* For RT5682, GPIO 137 should be set as EDGE_BOTH. */
61 const struct pad_config rt5682_gpio_137
= PAD_CFG_GPI_APIC_IOS(GPIO_137
,
62 NONE
, DEEP
, EDGE_BOTH
, INVERT
, HIZCRx1
, DISPUPD
);
63 enum ssfc_audio_codec codec
= ssfc_get_audio_codec();
65 if (table
== NULL
|| num
== 0)
69 * Currently we only have the case of RT5682 as the second source. And
70 * in case of Ampton which used RT5682 as the default source, it didn't
71 * provide override_table right now so it will be returned earlier since
72 * table above is NULL.
74 if ((codec
!= SSFC_AUDIO_CODEC_RT5682
) &&
75 (codec
!= SSFC_AUDIO_CODEC_RT5682_VS
))
79 if (table
->pad
== GPIO_137
) {
80 *table
= rt5682_gpio_137
;
82 "Configure GPIO 137 based on SSFC.\n");
90 static void mainboard_init(void *chip_info
)
93 const struct pad_config
*base_pads
;
94 const struct pad_config
*override_pads
;
95 size_t base_num
, override_num
;
98 printk(BIOS_INFO
, "Board ID: %d\n", boardid
);
100 base_pads
= baseboard_gpio_table(&base_num
);
101 override_pads
= variant_override_gpio_table(&override_num
);
102 gpio_modification_by_ssfc((struct pad_config
*)override_pads
,
105 gpio_configure_pads_with_override(base_pads
, base_num
,
106 override_pads
, override_num
);
108 if (!is_cnvi_held_in_reset())
114 static unsigned long mainboard_write_acpi_tables(
115 const struct device
*device
, unsigned long current
, acpi_rsdp_t
*rsdp
)
117 uintptr_t start_addr
;
121 start_addr
= current
;
128 variant_nhlt_init(nhlt
);
130 end_addr
= nhlt_soc_serialize(nhlt
, start_addr
);
132 if (end_addr
!= start_addr
)
133 acpi_add_table(rsdp
, (void *)start_addr
);
138 static void mainboard_enable(struct device
*dev
)
140 dev
->ops
->write_acpi_tables
= mainboard_write_acpi_tables
;
143 struct chip_operations mainboard_ops
= {
144 .init
= mainboard_init
,
145 .enable_dev
= mainboard_enable
,
148 void __weak
variant_update_devtree(struct device
*dev
)
150 /* Place holder for common updates. */
154 * Check if CNVi PCI device is released from reset. If yes, then the system is
155 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
156 * be disabled. If CNVi device is held in reset, then disable it.
158 static void wifi_device_update(void)
163 if (is_cnvi_held_in_reset())
164 devfn
= PCH_DEVFN_CNVI
;
166 devfn
= PCH_DEVFN_PCIE1
;
168 dev
= pcidev_path_on_root(devfn
);
174 * Base on SSFC value in the CBI from EC to enable one of audio codec sources in
177 static void audio_codec_device_update(void)
179 struct device
*audio_dev
= NULL
;
180 struct bus
*audio_i2c_bus
=
181 pcidev_path_on_root(PCH_DEVFN_I2C5
)->downstream
;
182 enum ssfc_audio_codec codec
= ssfc_get_audio_codec();
184 while ((audio_dev
= dev_bus_each_child(audio_i2c_bus
, audio_dev
))) {
185 if (audio_dev
->chip_info
== NULL
)
188 if ((audio_dev
->chip_ops
== &drivers_i2c_da7219_ops
) &&
189 (codec
== SSFC_AUDIO_CODEC_DA7219
)) {
190 printk(BIOS_INFO
, "enable DA7219.\n");
194 if (audio_dev
->chip_ops
== &drivers_i2c_generic_ops
) {
195 struct drivers_i2c_generic_config
*cfg
=
196 audio_dev
->chip_info
;
198 if ((cfg
!= NULL
&& !strcmp(cfg
->hid
, "10EC5682")) &&
199 (codec
== SSFC_AUDIO_CODEC_RT5682
)) {
200 printk(BIOS_INFO
, "enable RT5682 VD.\n");
204 if ((cfg
!= NULL
&& !strcmp(cfg
->hid
, "10EC5682")) &&
205 (codec
== SSFC_AUDIO_CODEC_RT5682_VS
)) {
206 cfg
->hid
= "RTL5682";
207 printk(BIOS_INFO
, "enable RT5682 VS.\n");
211 if ((cfg
!= NULL
&& !strcmp(cfg
->hid
, "RTL5682")) &&
212 (codec
== SSFC_AUDIO_CODEC_RT5682_VS
)) {
213 printk(BIOS_INFO
, "enable RT5682 VS.\n");
218 if ((audio_dev
->chip_ops
== &drivers_i2c_cs42l42_ops
) &&
219 (codec
== SSFC_AUDIO_CODEC_CS42L42
)) {
220 printk(BIOS_INFO
, "enable CS42L42.\n");
224 printk(BIOS_INFO
, "%s has been disabled\n", audio_dev
->chip_ops
->name
);
225 audio_dev
->enabled
= 0;
229 void mainboard_devtree_update(struct device
*dev
)
231 /* Apply common devtree updates. */
232 wifi_device_update();
233 audio_codec_device_update();
235 /* Defer to variant for board-specific updates. */
236 variant_update_devtree(dev
);
239 bool __weak
variant_ext_usb_status(unsigned int port_type
, unsigned int port_id
)
241 /* All externally visible USB ports are present */
245 static void disable_unused_devices(void *unused
)
247 usb_xhci_disable_unused(variant_ext_usb_status
);
250 BOOT_STATE_INIT_ENTRY(BS_DEV_INIT
, BS_ON_EXIT
, disable_unused_devices
, NULL
);