diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt index a6600f6dea64..206aba1b34bb 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt @@ -9,6 +9,7 @@ Required properties: - "rockchip,rk3066-i2s": for rk3066 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288 + - "rockchip,rk3368-i2s", "rockchip,rk3066-i2s": for rk3368 - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399 - reg: physical base address of the controller and length of memory mapped region. diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index b281a46d769d..f91221b1ddf0 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -1084,13 +1084,28 @@ static int rt5514_parse_dt(struct rt5514_priv *rt5514, struct device *dev) return 0; } +static __maybe_unused int rt5514_i2c_resume(struct device *dev) +{ + struct rt5514_priv *rt5514 = dev_get_drvdata(dev); + unsigned int val; + + /* + * Add a bogus read to avoid rt5514's confusion after s2r in case it + * saw glitches on the i2c lines and thought the other side sent a + * start bit. + */ + regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); + + return 0; +} + static int rt5514_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct rt5514_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5514_priv *rt5514; int ret; - unsigned int val; + unsigned int val = ~0; rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv), GFP_KERNEL); @@ -1120,8 +1135,16 @@ static int rt5514_i2c_probe(struct i2c_client *i2c, return ret; } - regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); - if (val != RT5514_DEVICE_ID) { + /* + * The rt5514 can get confused if the i2c lines glitch together, as + * can happen at bootup as regulators are turned off and on. If it's + * in this glitched state the first i2c read will fail, so we'll give + * it one change to retry. + */ + ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); + if (ret || val != RT5514_DEVICE_ID) + ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); + if (ret || val != RT5514_DEVICE_ID) { dev_err(&i2c->dev, "Device with ID register %x is not rt5514\n", val); return -ENODEV; @@ -1149,10 +1172,15 @@ static int rt5514_i2c_remove(struct i2c_client *i2c) return 0; } -struct i2c_driver rt5514_i2c_driver = { +static const struct dev_pm_ops rt5514_i2_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume) +}; + +static struct i2c_driver rt5514_i2c_driver = { .driver = { .name = "rt5514", .of_match_table = of_match_ptr(rt5514_of_match), + .pm = &rt5514_i2_pm_ops, }, .probe = rt5514_i2c_probe, .remove = rt5514_i2c_remove, diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index e149f3ce5401..87844a45886a 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3542,6 +3542,15 @@ static const struct i2c_device_id rt5645_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); +#ifdef CONFIG_OF +static const struct of_device_id rt5645_of_match[] = { + { .compatible = "realtek,rt5645", }, + { .compatible = "realtek,rt5650", }, + { } +}; +MODULE_DEVICE_TABLE(of, rt5645_of_match); +#endif + #ifdef CONFIG_ACPI static const struct acpi_device_id rt5645_acpi_match[] = { { "10EC5645", 0 }, @@ -3912,6 +3921,7 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c) static struct i2c_driver rt5645_i2c_driver = { .driver = { .name = "rt5645", + .of_match_table = of_match_ptr(rt5645_of_match), .acpi_match_table = ACPI_PTR(rt5645_acpi_match), }, .probe = rt5645_i2c_probe, diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index abc802a5a479..65ac4518ad06 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5035,6 +5035,12 @@ static const struct i2c_device_id rt5677_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); +static const struct of_device_id rt5677_of_match[] = { + { .compatible = "realtek,rt5677", }, + { } +}; +MODULE_DEVICE_TABLE(of, rt5677_of_match); + static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false }; static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false }; static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false }; @@ -5294,6 +5300,7 @@ static int rt5677_i2c_remove(struct i2c_client *i2c) static struct i2c_driver rt5677_i2c_driver = { .driver = { .name = "rt5677", + .of_match_table = rt5677_of_match, }, .probe = rt5677_i2c_probe, .remove = rt5677_i2c_remove, diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c index b60abf322ce1..dbc53e48c52c 100644 --- a/sound/soc/rockchip/rk3288_hdmi_analog.c +++ b/sound/soc/rockchip/rk3288_hdmi_analog.c @@ -93,6 +93,9 @@ static int rk_hw_params(struct snd_pcm_substream *substream, case 96000: mclk = 12288000; break; + case 192000: + mclk = 24576000; + break; case 11025: case 22050: case 44100: