diff options
author | Jianeng Ceng <cengjianeng@huaqin.corp-partner.google.com> | 2024-04-07 20:52:36 +0800 |
---|---|---|
committer | Eric Lai <ericllai@google.com> | 2024-04-24 06:13:27 +0000 |
commit | 28b01563693c6d51c74c7fd2893978809c372989 (patch) | |
tree | 3b00828067639d188338a626abae4859755f45c1 /src/drivers/i2c/rt5645/rt5645.c | |
parent | 3f431844c6cecffa658ec7e2f97aaa903e898b12 (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/drivers/i2c/rt5645/rt5645.c')
-rw-r--r-- | src/drivers/i2c/rt5645/rt5645.c | 119 |
1 files changed, 119 insertions, 0 deletions
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 +}; |