mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
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:
commit
910a78d816
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user