ASoC rt5677: Prepare to support Lenovo Yoga Book tablets

Merge series from Yauhen Kharuzhy <jekhor@gmail.com>:

There are two Intel Cherry Trail-based devices using the RT5677 as a sound
codec: Lenovo Yoga Book YB1-X90 (Android tablet) and YB1-X91 (Windows
tablet).

They both have the same hardware configuration, but the X90 doesn't have
correct ACPI table definitions for many peripherals, whereas the X91 does.

Devices missing in the ACPI are defined in the board-specific driver
platform/x86/x86-android-tablets. In the X91 tablet, an ACPI _CRS method
for the RT5677 contains GPIO configuration entries which were not
supported by the codec driver before.

To support such device definitions, some modifications are added to the
RT5677 code: ACPI, SPI, and I2C matching ids have been introduced,
as well as some GPIO-related magic.
This commit is contained in:
Mark Brown 2026-02-23 14:49:36 +00:00
commit 910a78d816
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 44 additions and 5 deletions

View File

@ -624,12 +624,19 @@ static const struct acpi_device_id rt5677_spi_acpi_id[] = {
MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id);
#endif
static const struct spi_device_id rt5677_spi_ids[] = {
{ "rt5677", 0 },
{ },
};
MODULE_DEVICE_TABLE(spi, rt5677_spi_ids);
static struct spi_driver rt5677_spi_driver = {
.driver = {
.name = DRV_NAME,
.acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
},
.probe = rt5677_spi_probe,
.id_table = rt5677_spi_ids,
};
module_spi_driver(rt5677_spi_driver);

View File

@ -5204,10 +5204,17 @@ MODULE_DEVICE_TABLE(of, rt5677_of_match);
static const struct acpi_device_id rt5677_acpi_match[] = {
{ "10EC5677", RT5677 },
{ "RT5677CE", RT5677 },
{ "10EC5677", RT5677 },
{ }
};
MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match);
static const struct i2c_device_id rt5677_i2c_id[] = {
{ "rt5677", RT5677 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
struct device *dev)
{
@ -5529,9 +5536,17 @@ static int rt5677_init_irq(struct i2c_client *i2c)
return ret;
}
static const struct acpi_gpio_params rt5677_acpi_reset_gpios = {0, 0, true};
static const struct acpi_gpio_params rt5677_acpi_ldo2_gpios = {1, 0, false};
static const struct acpi_gpio_mapping rt5677_acpi_gpios[] = {
{ "realtek,reset-gpios", &rt5677_acpi_reset_gpios, 1 },
{ "realtek,pow-ldo2-gpios", &rt5677_acpi_ldo2_gpios, 1 },
{},
};
static int rt5677_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct rt5677_priv *rt5677;
int ret;
unsigned int val;
@ -5546,10 +5561,13 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
INIT_DELAYED_WORK(&rt5677->dsp_work, rt5677_dsp_work);
i2c_set_clientdata(i2c, rt5677);
rt5677->type = (enum rt5677_type)(uintptr_t)device_get_match_data(dev);
rt5677->type = (enum rt5677_type)(uintptr_t)i2c_get_match_data(i2c);
if (rt5677->type == 0)
return -EINVAL;
if (devm_acpi_dev_add_driver_gpios(rt5677->dev, rt5677_acpi_gpios))
dev_warn(rt5677->dev, "Unable to add GPIO mapping table\n");
rt5677_read_device_properties(rt5677, &i2c->dev);
/* pow-ldo2 and reset are optional. The codec pins may be statically
@ -5563,14 +5581,21 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
dev_err(&i2c->dev, "Failed to request POW_LDO2: %d\n", ret);
return ret;
}
rt5677->reset_pin = devm_gpiod_get_optional(&i2c->dev,
"realtek,reset", GPIOD_OUT_LOW);
"realtek,reset", GPIOD_OUT_HIGH);
if (IS_ERR(rt5677->reset_pin)) {
ret = PTR_ERR(rt5677->reset_pin);
dev_err(&i2c->dev, "Failed to request RESET: %d\n", ret);
return ret;
}
if (rt5677->reset_pin) {
msleep(1);
gpiod_set_value_cansleep(rt5677->reset_pin, 0);
}
if (rt5677->pow_ldo2 || rt5677->reset_pin) {
/* Wait a while until I2C bus becomes available. The datasheet
* does not specify the exact we should wait but startup
@ -5596,7 +5621,13 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
return ret;
}
regmap_read(rt5677->regmap, RT5677_VENDOR_ID2, &val);
ret = regmap_read(rt5677->regmap, RT5677_VENDOR_ID2, &val);
if (ret) {
dev_err(&i2c->dev,
"Failed to read ID register: %d\n", ret);
return -ENODEV;
}
if (val != RT5677_DEVICE_ID) {
dev_err(&i2c->dev,
"Device with ID register %#x is not rt5677\n", val);
@ -5665,6 +5696,7 @@ static struct i2c_driver rt5677_i2c_driver = {
.of_match_table = rt5677_of_match,
.acpi_match_table = rt5677_acpi_match,
},
.id_table = rt5677_i2c_id,
.probe = rt5677_i2c_probe,
.remove = rt5677_i2c_remove,
};

View File

@ -421,7 +421,7 @@
#define RT5677_DAC3_R_VOL_MASK (0xff)
#define RT5677_DAC3_R_VOL_SFT 0
/* DAC3 Digital Volume (0x19) */
/* DAC1 Digital Volume (0x19) */
#define RT5677_DAC1_L_VOL_MASK (0xff << 8)
#define RT5677_DAC1_L_VOL_SFT 8
#define RT5677_DAC1_R_VOL_MASK (0xff)