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>
This commit is contained in:
Jianeng Ceng
2024-04-07 20:52:36 +08:00
committed by Eric Lai
parent 3f431844c6
commit 28b0156369
4 changed files with 144 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
## SPDX-License-Identifier: GPL-2.0-only
config DRIVERS_I2C_RT5645
bool
depends on HAVE_ACPI_TABLES

View File

@@ -0,0 +1,3 @@
## SPDX-License-Identifier: GPL-2.0-only
ramstage-$(CONFIG_DRIVERS_I2C_RT5645) += rt5645.c

View File

@@ -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;
};

View File

@@ -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
};