summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJianeng Ceng <cengjianeng@huaqin.corp-partner.google.com>2024-04-07 20:52:36 +0800
committerEric Lai <ericllai@google.com>2024-04-24 06:13:27 +0000
commit28b01563693c6d51c74c7fd2893978809c372989 (patch)
tree3b00828067639d188338a626abae4859755f45c1 /src
parent3f431844c6cecffa658ec7e2f97aaa903e898b12 (diff)
drivers/i2c/rt5645: Add RT5645 amp driver
RT5663 is very old and it was used the hard code like RT53 or 10EC5663, which is the different series from RT5645/5650, it may caused some ambiguity. Because I2C generic driver dose not support dsd gpio setting, we declared the new rt5645 series driver for expansion. Add RT5645 AMP support. The kernel driver of 5650 is written in rt5645.c. Add acpi name cbj-sleeve-gpios for power gate GPIO. ALC5650 DataSheet Rev 0.93 Realtek upstream link: https://lore.kernel.org/all/20240404035747.118064-1-derek.fang@realtek.com/ Hide the device because of Microsoft Windows. BUG=None TEST=verified in anraggar and probe device rt5650 succeed ``` \_SB.PCI0.I2C3.RT58: Realtek RT5650 ``` Change-Id: I602fcc4dd8576043943f6e20884edc4703350320 Signed-off-by: Jianeng Ceng <cengjianeng@huaqin.corp-partner.google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81773 Reviewed-by: Matt DeVillier <matt.devillier@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Eric Lai <ericllai@google.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/drivers/i2c/rt5645/Kconfig5
-rw-r--r--src/drivers/i2c/rt5645/Makefile.mk3
-rw-r--r--src/drivers/i2c/rt5645/chip.h17
-rw-r--r--src/drivers/i2c/rt5645/rt5645.c119
4 files changed, 144 insertions, 0 deletions
diff --git a/src/drivers/i2c/rt5645/Kconfig b/src/drivers/i2c/rt5645/Kconfig
new file mode 100644
index 0000000000..76cfee8851
--- /dev/null
+++ b/src/drivers/i2c/rt5645/Kconfig
@@ -0,0 +1,5 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+config DRIVERS_I2C_RT5645
+ bool
+ depends on HAVE_ACPI_TABLES
diff --git a/src/drivers/i2c/rt5645/Makefile.mk b/src/drivers/i2c/rt5645/Makefile.mk
new file mode 100644
index 0000000000..69d5f7e86b
--- /dev/null
+++ b/src/drivers/i2c/rt5645/Makefile.mk
@@ -0,0 +1,3 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ramstage-$(CONFIG_DRIVERS_I2C_RT5645) += rt5645.c
diff --git a/src/drivers/i2c/rt5645/chip.h b/src/drivers/i2c/rt5645/chip.h
new file mode 100644
index 0000000000..e8537ee6a8
--- /dev/null
+++ b/src/drivers/i2c/rt5645/chip.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi_device.h>
+
+struct drivers_i2c_rt5645_config {
+ const char *desc; /* Device Description */
+ const char *name; /* ACPI Device Name */
+ const char *hid; /* ACPI _HID */
+ struct acpi_gpio cbj_sleeve; /* sleeve power gate GPIO */
+ struct acpi_gpio hp_detect;
+ unsigned int uid;
+ unsigned int bus_speed;
+ /* Allow GPIO based interrupt or PIRQ */
+ struct acpi_gpio irq_gpio;
+ struct acpi_irq irq;
+ uint32_t jd_mode;
+};
diff --git a/src/drivers/i2c/rt5645/rt5645.c b/src/drivers/i2c/rt5645/rt5645.c
new file mode 100644
index 0000000000..28434ee456
--- /dev/null
+++ b/src/drivers/i2c/rt5645/rt5645.c
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi_device.h>
+#include <acpi/acpigen.h>
+#include <console/console.h>
+#include <device/device.h>
+#include "chip.h"
+
+#define RT5645_ACPI_NAME "RT58"
+#define RT5645_ACPI_HID "10EC5650"
+
+#define RT5645_DP_INT(key, val) \
+ acpi_dp_add_integer(dp, "realtek," key, (val))
+
+static void rt5645_fill_ssdt(const struct device *dev)
+{
+ struct drivers_i2c_rt5645_config *config = dev->chip_info;
+ const char *path;
+ const char *scope = acpi_device_scope(dev);
+ int cbj_sleeve_index = -1, irq_gpio_index = -1, hp_detect_index = -1;
+ struct acpi_i2c i2c = {
+ .address = dev->path.i2c.device,
+ .mode_10bit = dev->path.i2c.mode_10bit,
+ .speed = config->bus_speed ? : I2C_SPEED_FAST,
+ .resource = scope,
+ };
+ struct acpi_dp *dp;
+ int curr_index = 0;
+
+ if (!config)
+ return;
+
+ const char *name = acpi_device_name(dev);
+ if (!scope || !name)
+ return;
+
+ /* Device */
+ acpigen_write_scope(scope);
+ acpigen_write_device(name);
+
+ if (config->hid)
+ acpigen_write_name_string("_HID", config->hid);
+ else
+ acpigen_write_name_string("_HID", RT5645_ACPI_HID);
+ acpigen_write_name_integer("_UID", 0);
+ if (config->desc)
+ acpigen_write_name_string("_DDN", config->desc);
+ /* Hide the device because of Microsoft Windows */
+ acpigen_write_STA(ACPI_STATUS_DEVICE_HIDDEN_ON);
+
+ /* Resources */
+ acpigen_write_name("_CRS");
+ acpigen_write_resourcetemplate_header();
+ acpi_device_write_i2c(&i2c);
+
+ /* Use either Interrupt() or GpioInt() */
+ if (config->irq_gpio.pin_count)
+ irq_gpio_index = acpi_device_write_dsd_gpio(&config->irq_gpio,
+ &curr_index);
+ else
+ acpi_device_write_interrupt(&config->irq);
+
+ /* Add I2C GPIO index */
+ cbj_sleeve_index = acpi_device_write_dsd_gpio(&config->cbj_sleeve,
+ &curr_index);
+ hp_detect_index = acpi_device_write_dsd_gpio(&config->hp_detect,
+ &curr_index);
+ acpigen_write_resourcetemplate_footer();
+
+ /* _DSD for devicetree properties */
+ /* This points to the first pin in the first gpio entry in _CRS */
+ path = acpi_device_path(dev);
+ dp = acpi_dp_new_table("_DSD");
+ if (config->irq_gpio.pin_count)
+ acpi_dp_add_gpio(dp, "irq-gpios", path, irq_gpio_index, 0,
+ config->irq_gpio.active_low);
+ if (config->cbj_sleeve.pin_count)
+ acpi_dp_add_gpio(dp, "cbj-sleeve-gpios", path, cbj_sleeve_index, 0,
+ config->cbj_sleeve.active_low);
+ if (config->hp_detect.pin_count)
+ acpi_dp_add_gpio(dp, "hp-detect-gpios", path, hp_detect_index, 0,
+ config->hp_detect.active_low);
+ RT5645_DP_INT("jd-mode", config->jd_mode);
+ acpi_dp_write(dp);
+
+ acpigen_pop_len(); /* Device */
+ acpigen_pop_len(); /* Scope */
+
+ printk(BIOS_INFO, "%s: %s address 0%xh\n", path,
+ config->desc ? : dev->chip_ops->name, dev->path.i2c.device);
+}
+
+static const char *rt5645_acpi_name(const struct device *dev)
+{
+ struct drivers_i2c_rt5645_config *config = dev->chip_info;
+ static char name[5];
+ if (config->name)
+ return config->name;
+
+ snprintf(name, sizeof(name), "D%03.3X", dev->path.i2c.device);
+ return name;
+}
+
+static struct device_operations rt5645_ops = {
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources,
+ .acpi_name = rt5645_acpi_name,
+ .acpi_fill_ssdt = rt5645_fill_ssdt,
+};
+
+static void rt5645_enable(struct device *dev)
+{
+ dev->ops = &rt5645_ops;
+}
+
+struct chip_operations drivers_i2c_rt5645_ops = {
+ .name = "ASoC RT5645 Codec driver",
+ .enable_dev = rt5645_enable
+};