diff options
61 files changed, 398 insertions, 264 deletions
diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index bf7f9a9aeba0..9341130257ea 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -536,7 +536,6 @@ #define CS35L41_MAX_CACHE_REG 36 #define CS35L41_OTP_SIZE_WORDS 32 -#define CS35L41_NUM_OTP_ELEM 100 #define CS35L41_VALID_PDATA 0x80000000 #define CS35L41_NUM_SUPPLIES 2 diff --git a/include/sound/soc.h b/include/sound/soc.h index 7a1650b303f1..d3d3a26e8867 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1263,6 +1263,10 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev, struct device_node *of_node, struct snd_soc_dai_link *dai_link); void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link); +int snd_soc_of_get_dai_link_cpus(struct device *dev, + struct device_node *of_node, + struct snd_soc_dai_link *dai_link); +void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link); int snd_soc_add_pcm_runtime(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 33e43013ff77..0365b583ba70 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -46,35 +46,6 @@ */ #undef ENABLE_MIC_INPUT -static struct clk *mclk; - -static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card, - struct snd_soc_dapm_context *dapm, - enum snd_soc_bias_level level) -{ - static int mclk_on; - int ret = 0; - - switch (level) { - case SND_SOC_BIAS_ON: - case SND_SOC_BIAS_PREPARE: - if (!mclk_on) - ret = clk_enable(mclk); - if (ret == 0) - mclk_on = 1; - break; - - case SND_SOC_BIAS_OFF: - case SND_SOC_BIAS_STANDBY: - if (mclk_on) - clk_disable(mclk); - mclk_on = 0; - break; - } - - return ret; -} - static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = { SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), @@ -135,7 +106,6 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { .owner = THIS_MODULE, .dai_link = &at91sam9g20ek_dai, .num_links = 1, - .set_bias_level = at91sam9g20ek_set_bias_level, .dapm_widgets = at91sam9g20ek_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets), @@ -148,7 +118,6 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *codec_np, *cpu_np; - struct clk *pllb; struct snd_soc_card *card = &snd_soc_at91sam9g20ek; int ret; @@ -158,35 +127,10 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) ret = atmel_ssc_set_audio(0); if (ret) { - dev_err(&pdev->dev, "ssc channel is not valid\n"); - return -EINVAL; - } - - /* - * Codec MCLK is supplied by PCK0 - set it up. - */ - mclk = clk_get(NULL, "pck0"); - if (IS_ERR(mclk)) { - dev_err(&pdev->dev, "Failed to get MCLK\n"); - ret = PTR_ERR(mclk); - goto err; - } - - pllb = clk_get(NULL, "pllb"); - if (IS_ERR(pllb)) { - dev_err(&pdev->dev, "Failed to get PLLB\n"); - ret = PTR_ERR(pllb); - goto err_mclk; - } - ret = clk_set_parent(mclk, pllb); - clk_put(pllb); - if (ret != 0) { - dev_err(&pdev->dev, "Failed to set MCLK parent\n"); - goto err_mclk; + dev_err(&pdev->dev, "ssc channel is not valid: %d\n", ret); + return ret; } - clk_set_rate(mclk, MCLK_RATE); - card->dev = &pdev->dev; /* Parse device node info */ @@ -204,7 +148,8 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) codec_np = of_parse_phandle(np, "atmel,audio-codec", 0); if (!codec_np) { dev_err(&pdev->dev, "codec info missing\n"); - return -EINVAL; + ret = -EINVAL; + goto err; } at91sam9g20ek_dai.codecs->of_node = codec_np; @@ -215,7 +160,8 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) if (!cpu_np) { dev_err(&pdev->dev, "dai and pcm info missing\n"); of_node_put(codec_np); - return -EINVAL; + ret = -EINVAL; + goto err; } at91sam9g20ek_dai.cpus->of_node = cpu_np; at91sam9g20ek_dai.platforms->of_node = cpu_np; @@ -226,13 +172,11 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card() failed\n"); + goto err; } - return ret; + return 0; -err_mclk: - clk_put(mclk); - mclk = NULL; err: atmel_ssc_put_audio(0); return ret; @@ -242,8 +186,6 @@ static int at91sam9g20ek_audio_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - clk_disable(mclk); - mclk = NULL; snd_soc_unregister_card(card); atmel_ssc_put_audio(0); diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c index 3d509a65e4ca..4cb8d87f9011 100644 --- a/sound/soc/codecs/ad193x-i2c.c +++ b/sound/soc/codecs/ad193x-i2c.c @@ -20,10 +20,10 @@ static const struct i2c_device_id ad193x_id[] = { }; MODULE_DEVICE_TABLE(i2c, ad193x_id); -static int ad193x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad193x_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(ad193x_id, client); config = ad193x_regmap_config; config.val_bits = 8; @@ -38,7 +38,7 @@ static struct i2c_driver ad193x_i2c_driver = { .driver = { .name = "ad193x", }, - .probe = ad193x_i2c_probe, + .probe_new = ad193x_i2c_probe, .id_table = ad193x_id, }; module_i2c_driver(ad193x_i2c_driver); diff --git a/sound/soc/codecs/adau1372-i2c.c b/sound/soc/codecs/adau1372-i2c.c index fc87a76ff1ee..8ed0ffdedbc9 100644 --- a/sound/soc/codecs/adau1372-i2c.c +++ b/sound/soc/codecs/adau1372-i2c.c @@ -14,7 +14,7 @@ #include "adau1372.h" -static int adau1372_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int adau1372_i2c_probe(struct i2c_client *client) { return adau1372_probe(&client->dev, devm_regmap_init_i2c(client, &adau1372_regmap_config), NULL); @@ -30,7 +30,7 @@ static struct i2c_driver adau1372_i2c_driver = { .driver = { .name = "adau1372", }, - .probe = adau1372_i2c_probe, + .probe_new = adau1372_i2c_probe, .id_table = adau1372_i2c_ids, }; module_i2c_driver(adau1372_i2c_driver); diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 46128aaceae9..a9032b5c8d78 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1473,8 +1473,7 @@ static const struct snd_soc_component_driver adau1373_component_driver = { .non_legacy_dai_naming = 1, }; -static int adau1373_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adau1373_i2c_probe(struct i2c_client *client) { struct adau1373 *adau1373; int ret; @@ -1508,7 +1507,7 @@ static struct i2c_driver adau1373_i2c_driver = { .driver = { .name = "adau1373", }, - .probe = adau1373_i2c_probe, + .probe_new = adau1373_i2c_probe, .id_table = adau1373_i2c_id, }; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index dba9af753188..98768e5300f0 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -785,8 +785,7 @@ static const struct regmap_config adau1701_regmap = { .reg_read = adau1701_reg_read, }; -static int adau1701_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adau1701_i2c_probe(struct i2c_client *client) { struct adau1701 *adau1701; struct device *dev = &client->dev; @@ -878,7 +877,7 @@ static struct i2c_driver adau1701_i2c_driver = { .name = "adau1701", .of_match_table = of_match_ptr(adau1701_dt_ids), }, - .probe = adau1701_i2c_probe, + .probe_new = adau1701_i2c_probe, .id_table = adau1701_i2c_id, }; diff --git a/sound/soc/codecs/adau1761-i2c.c b/sound/soc/codecs/adau1761-i2c.c index c8fce37e5cfa..0683caf86aea 100644 --- a/sound/soc/codecs/adau1761-i2c.c +++ b/sound/soc/codecs/adau1761-i2c.c @@ -14,10 +14,12 @@ #include "adau1761.h" -static int adau1761_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id adau1761_i2c_ids[]; + +static int adau1761_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(adau1761_i2c_ids, client); config = adau1761_regmap_config; config.val_bits = 8; @@ -59,7 +61,7 @@ static struct i2c_driver adau1761_i2c_driver = { .name = "adau1761", .of_match_table = of_match_ptr(adau1761_i2c_dt_ids), }, - .probe = adau1761_i2c_probe, + .probe_new = adau1761_i2c_probe, .remove = adau1761_i2c_remove, .id_table = adau1761_i2c_ids, }; diff --git a/sound/soc/codecs/adau1781-i2c.c b/sound/soc/codecs/adau1781-i2c.c index 1c476429ad99..e046de0ebcc7 100644 --- a/sound/soc/codecs/adau1781-i2c.c +++ b/sound/soc/codecs/adau1781-i2c.c @@ -14,10 +14,12 @@ #include "adau1781.h" -static int adau1781_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id adau1781_i2c_ids[]; + +static int adau1781_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(adau1781_i2c_ids, client); config = adau1781_regmap_config; config.val_bits = 8; @@ -55,7 +57,7 @@ static struct i2c_driver adau1781_i2c_driver = { .name = "adau1781", .of_match_table = of_match_ptr(adau1781_i2c_dt_ids), }, - .probe = adau1781_i2c_probe, + .probe_new = adau1781_i2c_probe, .remove = adau1781_i2c_remove, .id_table = adau1781_i2c_ids, }; diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c index 82a49c85d536..9f137a0634d5 100644 --- a/sound/soc/codecs/adau1977-i2c.c +++ b/sound/soc/codecs/adau1977-i2c.c @@ -14,10 +14,12 @@ #include "adau1977.h" -static int adau1977_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id adau1977_i2c_ids[]; + +static int adau1977_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(adau1977_i2c_ids, client); config = adau1977_regmap_config; config.val_bits = 8; @@ -40,7 +42,7 @@ static struct i2c_driver adau1977_i2c_driver = { .driver = { .name = "adau1977", }, - .probe = adau1977_i2c_probe, + .probe_new = adau1977_i2c_probe, .id_table = adau1977_i2c_ids, }; module_i2c_driver(adau1977_i2c_driver); diff --git a/sound/soc/codecs/adau7118-i2c.c b/sound/soc/codecs/adau7118-i2c.c index aa7afb3b826d..afed48401b25 100644 --- a/sound/soc/codecs/adau7118-i2c.c +++ b/sound/soc/codecs/adau7118-i2c.c @@ -48,8 +48,7 @@ static const struct regmap_config adau7118_regmap_config = { .volatile_reg = adau7118_volatile, }; -static int adau7118_probe_i2c(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int adau7118_probe_i2c(struct i2c_client *i2c) { struct regmap *map; @@ -79,7 +78,7 @@ static struct i2c_driver adau7118_driver = { .name = "adau7118", .of_match_table = adau7118_of_match, }, - .probe = adau7118_probe_i2c, + .probe_new = adau7118_probe_i2c, .id_table = adau7118_id, }; module_i2c_driver(adau7118_driver); diff --git a/sound/soc/codecs/adav803.c b/sound/soc/codecs/adav803.c index 0f565b851ea5..bf181bbaabed 100644 --- a/sound/soc/codecs/adav803.c +++ b/sound/soc/codecs/adav803.c @@ -19,8 +19,7 @@ static const struct i2c_device_id adav803_id[] = { }; MODULE_DEVICE_TABLE(i2c, adav803_id); -static int adav803_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adav803_probe(struct i2c_client *client) { return adav80x_bus_probe(&client->dev, devm_regmap_init_i2c(client, &adav80x_regmap_config)); @@ -30,7 +29,7 @@ static struct i2c_driver adav803_driver = { .driver = { .name = "adav803", }, - .probe = adav803_probe, + .probe_new = adav803_probe, .id_table = adav803_id, }; module_i2c_driver(adav803_driver); diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 933e3d627e5f..badfc55bc5fa 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -346,8 +346,7 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, return 0; } -static int cs35l32_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l32_i2c_probe(struct i2c_client *i2c_client) { struct cs35l32_private *cs35l32; struct cs35l32_platform_data *pdata = @@ -576,7 +575,7 @@ static struct i2c_driver cs35l32_i2c_driver = { .of_match_table = cs35l32_of_match, }, .id_table = cs35l32_id, - .probe = cs35l32_i2c_probe, + .probe_new = cs35l32_i2c_probe, .remove = cs35l32_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 2a6f5e46d031..47dc0f6d90a2 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -1116,8 +1116,7 @@ static int cs35l33_of_get_pdata(struct device *dev, return 0; } -static int cs35l33_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l33_i2c_probe(struct i2c_client *i2c_client) { struct cs35l33_private *cs35l33; struct cs35l33_pdata *pdata = dev_get_platdata(&i2c_client->dev); @@ -1286,7 +1285,7 @@ static struct i2c_driver cs35l33_i2c_driver = { }, .id_table = cs35l33_id, - .probe = cs35l33_i2c_probe, + .probe_new = cs35l33_i2c_probe, .remove = cs35l33_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index ed678241c22b..50d509a06071 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -994,8 +994,7 @@ static const char * const cs35l34_core_supplies[] = { "VP", }; -static int cs35l34_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l34_i2c_probe(struct i2c_client *i2c_client) { struct cs35l34_private *cs35l34; struct cs35l34_platform_data *pdata = @@ -1217,7 +1216,7 @@ static struct i2c_driver cs35l34_i2c_driver = { }, .id_table = cs35l34_id, - .probe = cs35l34_i2c_probe, + .probe_new = cs35l34_i2c_probe, .remove = cs35l34_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 961a3e07e70f..6b70afb70a67 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1466,8 +1466,7 @@ static const struct reg_sequence cs35l35_errata_patch[] = { { 0x7F, 0x00 }, }; -static int cs35l35_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l35_i2c_probe(struct i2c_client *i2c_client) { struct cs35l35_private *cs35l35; struct device *dev = &i2c_client->dev; @@ -1658,7 +1657,7 @@ static struct i2c_driver cs35l35_i2c_driver = { .of_match_table = cs35l35_of_match, }, .id_table = cs35l35_id, - .probe = cs35l35_i2c_probe, + .probe_new = cs35l35_i2c_probe, .remove = cs35l35_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index d83c1b318c1c..cc5e80222916 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -1700,8 +1700,7 @@ static const struct reg_sequence cs35l36_revb0_errata_patch[] = { { CS35L36_TESTKEY_CTRL, CS35L36_TEST_LOCK2 }, }; -static int cs35l36_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l36_i2c_probe(struct i2c_client *i2c_client) { struct cs35l36_private *cs35l36; struct device *dev = &i2c_client->dev; @@ -1947,7 +1946,7 @@ static struct i2c_driver cs35l36_i2c_driver = { .of_match_table = cs35l36_of_match, }, .id_table = cs35l36_id, - .probe = cs35l36_i2c_probe, + .probe_new = cs35l36_i2c_probe, .remove = cs35l36_i2c_remove, }; module_i2c_driver(cs35l36_i2c_driver); diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c index faad5c638cb8..86d866aeb680 100644 --- a/sound/soc/codecs/cs35l41-i2c.c +++ b/sound/soc/codecs/cs35l41-i2c.c @@ -29,8 +29,7 @@ static const struct i2c_device_id cs35l41_id_i2c[] = { MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); -static int cs35l41_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs35l41_i2c_probe(struct i2c_client *client) { struct cs35l41_private *cs35l41; struct device *dev = &client->dev; @@ -91,7 +90,7 @@ static struct i2c_driver cs35l41_i2c_driver = { .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), }, .id_table = cs35l41_id_i2c, - .probe = cs35l41_i2c_probe, + .probe_new = cs35l41_i2c_probe, .remove = cs35l41_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index e5a56bcbb223..9aa2b8948c61 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -422,7 +422,7 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) } } -static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { +static const struct cs35l41_otp_packed_element_t otp_map_1[] = { /* addr shift size */ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ @@ -525,7 +525,7 @@ static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ }; -static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { +static const struct cs35l41_otp_packed_element_t otp_map_2[] = { /* addr shift size */ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ @@ -671,35 +671,35 @@ static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { { .id = 0x01, .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_1), .bit_offset = 16, .word_offset = 2, }, { .id = 0x02, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x03, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x06, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x08, .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_1), .bit_offset = 16, .word_offset = 2, }, @@ -822,8 +822,8 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) word_offset = otp_map_match->word_offset; for (i = 0; i < otp_map_match->num_elements; i++) { - dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", - bit_offset, word_offset, bit_sum % 32); + dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d, otp_map[i].size = %u\n", + bit_offset, word_offset, bit_sum % 32, otp_map[i].size); if (bit_offset + otp_map[i].size - 1 >= 32) { otp_val = (otp_mem[word_offset] & GENMASK(31, bit_offset)) >> bit_offset; diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index 20126cc675b1..b44939166e5d 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -731,7 +731,7 @@ static int cs4234_powerup(struct cs4234 *cs4234) return 0; } -static int cs4234_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) +static int cs4234_i2c_probe(struct i2c_client *i2c_client) { struct cs4234 *cs4234; struct device *dev = &i2c_client->dev; @@ -908,7 +908,7 @@ static struct i2c_driver cs4234_i2c_driver = { .pm = &cs4234_pm, .of_match_table = cs4234_of_match, }, - .probe = cs4234_i2c_probe, + .probe_new = cs4234_i2c_probe, .remove = cs4234_i2c_remove, }; module_i2c_driver(cs4234_i2c_driver); diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 4415fb364d4d..86bfa8d5ec78 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -568,8 +568,7 @@ static const struct regmap_config cs4265_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int cs4265_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs4265_i2c_probe(struct i2c_client *i2c_client) { struct cs4265_private *cs4265; int ret; @@ -653,7 +652,7 @@ static struct i2c_driver cs4265_i2c_driver = { .of_match_table = cs4265_of_match, }, .id_table = cs4265_id, - .probe = cs4265_i2c_probe, + .probe_new = cs4265_i2c_probe, .remove = cs4265_i2c_remove, }; diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 2d239e983a83..07cac01f87bd 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -677,8 +677,7 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client) * This function is called whenever the I2C subsystem finds a device that * matches the device ID given via a prior call to i2c_add_driver(). */ -static int cs4270_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs4270_i2c_probe(struct i2c_client *i2c_client) { struct cs4270_private *cs4270; unsigned int val; @@ -765,7 +764,7 @@ static struct i2c_driver cs4270_i2c_driver = { .of_match_table = cs4270_of_match, }, .id_table = cs4270_id, - .probe = cs4270_i2c_probe, + .probe_new = cs4270_i2c_probe, .remove = cs4270_i2c_remove, }; diff --git a/sound/soc/codecs/cs4271-i2c.c b/sound/soc/codecs/cs4271-i2c.c index 0a174236f573..0e8a7cf0da50 100644 --- a/sound/soc/codecs/cs4271-i2c.c +++ b/sound/soc/codecs/cs4271-i2c.c @@ -11,8 +11,7 @@ #include <sound/soc.h> #include "cs4271.h" -static int cs4271_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs4271_i2c_probe(struct i2c_client *client) { struct regmap_config config; @@ -35,7 +34,7 @@ static struct i2c_driver cs4271_i2c_driver = { .name = "cs4271", .of_match_table = of_match_ptr(cs4271_dt_ids), }, - .probe = cs4271_i2c_probe, + .probe_new = cs4271_i2c_probe, .id_table = cs4271_i2c_id, }; module_i2c_driver(cs4271_i2c_driver); diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index c8409d50e934..4fade2388797 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -2194,8 +2194,7 @@ static int __maybe_unused cs42l42_resume(struct device *dev) return 0; } -static int cs42l42_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l42_i2c_probe(struct i2c_client *i2c_client) { struct cs42l42_private *cs42l42; int ret, i, devid; @@ -2399,7 +2398,7 @@ static struct i2c_driver cs42l42_i2c_driver = { .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), }, .id_table = cs42l42_id, - .probe = cs42l42_i2c_probe, + .probe_new = cs42l42_i2c_probe, .remove = cs42l42_i2c_remove, }; diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c index 3cb21a2ba29f..3613fb12d623 100644 --- a/sound/soc/codecs/cs42l51-i2c.c +++ b/sound/soc/codecs/cs42l51-i2c.c @@ -19,8 +19,7 @@ static struct i2c_device_id cs42l51_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); -static int cs42l51_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cs42l51_i2c_probe(struct i2c_client *i2c) { struct regmap_config config; @@ -46,7 +45,7 @@ static struct i2c_driver cs42l51_i2c_driver = { .of_match_table = cs42l51_of_match, .pm = &cs42l51_pm_ops, }, - .probe = cs42l51_i2c_probe, + .probe_new = cs42l51_i2c_probe, .remove = cs42l51_i2c_remove, .id_table = cs42l51_i2c_id, }; diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 80161151b3f2..9b182b585be4 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1086,8 +1086,7 @@ static const struct regmap_config cs42l52_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int cs42l52_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l52_i2c_probe(struct i2c_client *i2c_client) { struct cs42l52_private *cs42l52; struct cs42l52_platform_data *pdata = dev_get_platdata(&i2c_client->dev); @@ -1226,7 +1225,7 @@ static struct i2c_driver cs42l52_i2c_driver = { .of_match_table = cs42l52_of_match, }, .id_table = cs42l52_id, - .probe = cs42l52_i2c_probe, + .probe_new = cs42l52_i2c_probe, }; module_i2c_driver(cs42l52_i2c_driver); diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 3cf8a0b4478c..2c4e09b43199 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1167,8 +1167,7 @@ static int cs42l56_handle_of_data(struct i2c_client *i2c_client, return 0; } -static int cs42l56_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l56_i2c_probe(struct i2c_client *i2c_client) { struct cs42l56_private *cs42l56; struct cs42l56_platform_data *pdata = @@ -1350,7 +1349,7 @@ static struct i2c_driver cs42l56_i2c_driver = { .of_match_table = cs42l56_of_match, }, .id_table = cs42l56_id, - .probe = cs42l56_i2c_probe, + .probe_new = cs42l56_i2c_probe, .remove = cs42l56_i2c_remove, }; diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 018463f34e12..5a9166289f36 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1274,8 +1274,7 @@ static const struct regmap_config cs42l73_regmap = { .use_single_write = true, }; -static int cs42l73_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l73_i2c_probe(struct i2c_client *i2c_client) { struct cs42l73_private *cs42l73; struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev); @@ -1386,7 +1385,7 @@ static struct i2c_driver cs42l73_i2c_driver = { .of_match_table = cs42l73_of_match, }, .id_table = cs42l73_id, - .probe = cs42l73_i2c_probe, + .probe_new = cs42l73_i2c_probe, }; diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c index 0214e3ab9da0..cb06a06d48b0 100644 --- a/sound/soc/codecs/cs42xx8-i2c.c +++ b/sound/soc/codecs/cs42xx8-i2c.c @@ -17,8 +17,7 @@ #include "cs42xx8.h" -static int cs42xx8_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cs42xx8_i2c_probe(struct i2c_client *i2c) { int ret = cs42xx8_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &cs42xx8_regmap_config)); @@ -51,7 +50,7 @@ static struct i2c_driver cs42xx8_i2c_driver = { .pm = &cs42xx8_pm, .of_match_table = cs42xx8_of_match, }, - .probe = cs42xx8_i2c_probe, + .probe_new = cs42xx8_i2c_probe, .remove = cs42xx8_i2c_remove, .id_table = cs42xx8_i2c_id, }; diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index 44b20c1ef851..e38552a961ef 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -2418,8 +2418,7 @@ static int cs43130_handle_device_data(struct i2c_client *i2c_client, return 0; } -static int cs43130_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs43130_i2c_probe(struct i2c_client *client) { struct cs43130_private *cs43130; int ret; @@ -2702,7 +2701,7 @@ static struct i2c_driver cs43130_i2c_driver = { .pm = &cs43130_runtime_pm, }, .id_table = cs43130_i2c_id, - .probe = cs43130_i2c_probe, + .probe_new = cs43130_i2c_probe, .remove = cs43130_i2c_remove, }; diff --git a/sound/soc/codecs/cs4341.c b/sound/soc/codecs/cs4341.c index 29d05e32d341..8ac043f1aae0 100644 --- a/sound/soc/codecs/cs4341.c +++ b/sound/soc/codecs/cs4341.c @@ -225,8 +225,7 @@ static int cs4341_probe(struct device *dev) } #if IS_ENABLED(CONFIG_I2C) -static int cs4341_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cs4341_i2c_probe(struct i2c_client *i2c) { struct cs4341_priv *cs4341; @@ -260,7 +259,7 @@ static struct i2c_driver cs4341_i2c_driver = { .name = "cs4341-i2c", .of_match_table = of_match_ptr(cs4341_dt_ids), }, - .probe = cs4341_i2c_probe, + .probe_new = cs4341_i2c_probe, .id_table = cs4341_i2c_id, }; #endif diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 786c69a8ec4a..4ec4bed9ee08 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -278,8 +278,7 @@ static const struct regmap_config cs4349_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int cs4349_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs4349_i2c_probe(struct i2c_client *client) { struct cs4349_private *cs4349; int ret; @@ -382,7 +381,7 @@ static struct i2c_driver cs4349_i2c_driver = { .pm = &cs4349_runtime_pm, }, .id_table = cs4349_i2c_id, - .probe = cs4349_i2c_probe, + .probe_new = cs4349_i2c_probe, .remove = cs4349_i2c_remove, }; diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index f2087bd38dbc..703545273900 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -918,8 +918,7 @@ static struct regmap_config cs53l30_regmap = { .use_single_write = true, }; -static int cs53l30_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs53l30_i2c_probe(struct i2c_client *client) { const struct device_node *np = client->dev.of_node; struct device *dev = &client->dev; @@ -1125,7 +1124,7 @@ static struct i2c_driver cs53l30_i2c_driver = { .pm = &cs53l30_runtime_pm, }, .id_table = cs53l30_id, - .probe = cs53l30_i2c_probe, + .probe_new = cs53l30_i2c_probe, .remove = cs53l30_i2c_remove, }; diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 8af344b2fdbf..3fa3042e4424 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1206,8 +1206,7 @@ static const struct regmap_config da7210_regmap_config_i2c = { .cache_type = REGCACHE_RBTREE, }; -static int da7210_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7210_i2c_probe(struct i2c_client *i2c) { struct da7210_priv *da7210; int ret; @@ -1250,7 +1249,7 @@ static struct i2c_driver da7210_i2c_driver = { .driver = { .name = "da7210", }, - .probe = da7210_i2c_probe, + .probe_new = da7210_i2c_probe, .id_table = da7210_i2c_id, }; #endif diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 3ab89387b4e6..2e645dc60eda 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1946,8 +1946,7 @@ static const char *da7213_supply_names[DA7213_NUM_SUPPLIES] = { [DA7213_SUPPLY_VDDIO] = "VDDIO", }; -static int da7213_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7213_i2c_probe(struct i2c_client *i2c) { struct da7213_priv *da7213; int i, ret; @@ -2040,7 +2039,7 @@ static struct i2c_driver da7213_i2c_driver = { .acpi_match_table = ACPI_PTR(da7213_acpi_match), .pm = &da7213_pm, }, - .probe = da7213_i2c_probe, + .probe_new = da7213_i2c_probe, .id_table = da7213_i2c_id, }; diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index ea426d986d4c..a5d7c350a3de 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3258,8 +3258,19 @@ static const struct regmap_config da7218_regmap_config = { * I2C layer */ -static int da7218_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id da7218_i2c_id[]; + +static inline int da7218_i2c_get_id(struct i2c_client *i2c) +{ + const struct i2c_device_id *id = i2c_match_id(da7218_i2c_id, i2c); + + if (id) + return (uintptr_t)id->driver_data; + else + return -EINVAL; +} + +static int da7218_i2c_probe(struct i2c_client *i2c) { struct da7218_priv *da7218; int ret; @@ -3273,7 +3284,7 @@ static int da7218_i2c_probe(struct i2c_client *i2c, if (i2c->dev.of_node) da7218->dev_id = da7218_of_get_id(&i2c->dev); else - da7218->dev_id = id->driver_data; + da7218->dev_id = da7218_i2c_get_id(i2c); if ((da7218->dev_id != DA7217_DEV_ID) && (da7218->dev_id != DA7218_DEV_ID)) { @@ -3311,7 +3322,7 @@ static struct i2c_driver da7218_i2c_driver = { .name = "da7218", .of_match_table = da7218_of_match, }, - .probe = da7218_i2c_probe, + .probe_new = da7218_i2c_probe, .id_table = da7218_i2c_id, }; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 13009d08b09a..a28d3601b932 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2649,8 +2649,7 @@ static const struct snd_soc_component_driver soc_component_dev_da7219 = { * I2C layer */ -static int da7219_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7219_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct da7219_priv *da7219; @@ -2705,7 +2704,7 @@ static struct i2c_driver da7219_i2c_driver = { .of_match_table = of_match_ptr(da7219_of_match), .acpi_match_table = ACPI_PTR(da7219_acpi_match), }, - .probe = da7219_i2c_probe, + .probe_new = da7219_i2c_probe, .remove = da7219_i2c_remove, .id_table = da7219_i2c_id, }; diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 42d6a3fc3af5..f14cddf23f42 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1506,8 +1506,7 @@ static const struct snd_soc_component_driver soc_component_dev_da732x = { .non_legacy_dai_naming = 1, }; -static int da732x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da732x_i2c_probe(struct i2c_client *i2c) { struct da732x_priv *da732x; unsigned int reg; @@ -1562,7 +1561,7 @@ static struct i2c_driver da732x_i2c_driver = { .driver = { .name = "da7320", }, - .probe = da732x_i2c_probe, + .probe_new = da732x_i2c_probe, .remove = da732x_i2c_remove, .id_table = da732x_i2c_id, }; diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index a9676b261129..9d8c8adc5d76 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1473,8 +1473,7 @@ static const struct regmap_config da9055_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int da9055_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da9055_i2c_probe(struct i2c_client *i2c) { struct da9055_priv *da9055; struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev); @@ -1533,7 +1532,7 @@ static struct i2c_driver da9055_i2c_driver = { .name = "da9055-codec", .of_match_table = of_match_ptr(da9055_of_match), }, - .probe = da9055_i2c_probe, + .probe_new = da9055_i2c_probe, .id_table = da9055_i2c_id, }; diff --git a/sound/soc/codecs/lpass-macro-common.c b/sound/soc/codecs/lpass-macro-common.c index 6cede75ed3b5..3c661fd61173 100644 --- a/sound/soc/codecs/lpass-macro-common.c +++ b/sound/soc/codecs/lpass-macro-common.c @@ -24,42 +24,45 @@ struct lpass_macro *lpass_macro_pds_init(struct device *dev) return ERR_PTR(-ENOMEM); l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro"); - if (IS_ERR_OR_NULL(l_pds->macro_pd)) - return NULL; - - ret = pm_runtime_get_sync(l_pds->macro_pd); - if (ret < 0) { - pm_runtime_put_noidle(l_pds->macro_pd); + if (IS_ERR_OR_NULL(l_pds->macro_pd)) { + ret = PTR_ERR(l_pds->macro_pd); goto macro_err; } + ret = pm_runtime_resume_and_get(l_pds->macro_pd); + if (ret < 0) + goto macro_sync_err; + l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec"); - if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) + if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) { + ret = PTR_ERR(l_pds->dcodec_pd); goto dcodec_err; + } - ret = pm_runtime_get_sync(l_pds->dcodec_pd); - if (ret < 0) { - pm_runtime_put_noidle(l_pds->dcodec_pd); + ret = pm_runtime_resume_and_get(l_pds->dcodec_pd); + if (ret < 0) goto dcodec_sync_err; - } return l_pds; dcodec_sync_err: dev_pm_domain_detach(l_pds->dcodec_pd, false); dcodec_err: pm_runtime_put(l_pds->macro_pd); -macro_err: +macro_sync_err: dev_pm_domain_detach(l_pds->macro_pd, false); +macro_err: return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(lpass_macro_pds_init); void lpass_macro_pds_exit(struct lpass_macro *pds) { - pm_runtime_put(pds->macro_pd); - dev_pm_domain_detach(pds->macro_pd, false); - pm_runtime_put(pds->dcodec_pd); - dev_pm_domain_detach(pds->dcodec_pd, false); + if (pds) { + pm_runtime_put(pds->macro_pd); + dev_pm_domain_detach(pds->macro_pd, false); + pm_runtime_put(pds->dcodec_pd); + dev_pm_domain_detach(pds->dcodec_pd, false); + } } EXPORT_SYMBOL_GPL(lpass_macro_pds_exit); diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index 1cba8ec7cedb..7e4ac6560dee 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -42,8 +42,8 @@ static const struct rt5682s_platform_data i2s_default_platform_data = { }; static const char *rt5682s_supply_names[RT5682S_NUM_SUPPLIES] = { - "AVDD", - "MICVDD", + [RT5682S_SUPPLY_AVDD] = "AVDD", + [RT5682S_SUPPLY_MICVDD] = "MICVDD", }; static const struct reg_sequence patch_list[] = { @@ -3025,8 +3025,18 @@ static struct snd_soc_dai_driver rt5682s_dai[] = { static void rt5682s_i2c_disable_regulators(void *data) { struct rt5682s_priv *rt5682s = data; + struct device *dev = regmap_get_device(rt5682s->regmap); + int ret; + + ret = regulator_disable(rt5682s->supplies[RT5682S_SUPPLY_AVDD].consumer); + if (ret) + dev_err(dev, "Failed to disable supply AVDD: %d\n", ret); - regulator_bulk_disable(ARRAY_SIZE(rt5682s->supplies), rt5682s->supplies); + usleep_range(1000, 1500); + + ret = regulator_disable(rt5682s->supplies[RT5682S_SUPPLY_MICVDD].consumer); + if (ret) + dev_err(dev, "Failed to disable supply MICVDD: %d\n", ret); } static int rt5682s_i2c_probe(struct i2c_client *i2c, @@ -3071,9 +3081,16 @@ static int rt5682s_i2c_probe(struct i2c_client *i2c, if (ret) return ret; - ret = regulator_bulk_enable(ARRAY_SIZE(rt5682s->supplies), rt5682s->supplies); + ret = regulator_enable(rt5682s->supplies[RT5682S_SUPPLY_MICVDD].consumer); + if (ret) { + dev_err(&i2c->dev, "Failed to enable supply MICVDD: %d\n", ret); + return ret; + } + usleep_range(1000, 1500); + + ret = regulator_enable(rt5682s->supplies[RT5682S_SUPPLY_AVDD].consumer); if (ret) { - dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + dev_err(&i2c->dev, "Failed to enable supply AVDD: %d\n", ret); return ret; } diff --git a/sound/soc/codecs/rt5682s.h b/sound/soc/codecs/rt5682s.h index 397a2531b6f6..7353831c73dd 100644 --- a/sound/soc/codecs/rt5682s.h +++ b/sound/soc/codecs/rt5682s.h @@ -1434,7 +1434,11 @@ struct pll_calc_map { bool sel_ps; }; -#define RT5682S_NUM_SUPPLIES 2 +enum { + RT5682S_SUPPLY_AVDD, + RT5682S_SUPPLY_MICVDD, + RT5682S_NUM_SUPPLIES, +}; struct rt5682s_priv { struct snd_soc_component *component; diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 09449c6c4024..83acbdbb8e0d 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -735,8 +735,7 @@ static const struct regmap_config ssm2518_regmap_config = { .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults), }; -static int ssm2518_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ssm2518_i2c_probe(struct i2c_client *i2c) { struct ssm2518_platform_data *pdata = i2c->dev.platform_data; struct ssm2518 *ssm2518; @@ -815,7 +814,7 @@ static struct i2c_driver ssm2518_driver = { .name = "ssm2518", .of_match_table = of_match_ptr(ssm2518_dt_ids), }, - .probe = ssm2518_i2c_probe, + .probe_new = ssm2518_i2c_probe, .id_table = ssm2518_i2c_ids, }; module_i2c_driver(ssm2518_driver); diff --git a/sound/soc/codecs/ssm2602-i2c.c b/sound/soc/codecs/ssm2602-i2c.c index afab81383d3a..3c85772901f5 100644 --- a/sound/soc/codecs/ssm2602-i2c.c +++ b/sound/soc/codecs/ssm2602-i2c.c @@ -13,15 +13,17 @@ #include "ssm2602.h" +static const struct i2c_device_id ssm2602_i2c_id[]; + /* * ssm2602 2 wire address is determined by GPIO5 * state during powerup. * low = 0x1a * high = 0x1b */ -static int ssm2602_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ssm2602_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_match_id(ssm2602_i2c_id, client); return ssm2602_probe(&client->dev, id->driver_data, devm_regmap_init_i2c(client, &ssm2602_regmap_config)); } @@ -47,7 +49,7 @@ static struct i2c_driver ssm2602_i2c_driver = { .name = "ssm2602", .of_match_table = ssm2602_of_match, }, - .probe = ssm2602_i2c_probe, + .probe_new = ssm2602_i2c_probe, .id_table = ssm2602_i2c_id, }; module_i2c_driver(ssm2602_i2c_driver); diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 811b1a2c404a..08ced09ef001 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -444,8 +444,7 @@ static const struct regmap_config ssm4567_regmap_config = { .num_reg_defaults = ARRAY_SIZE(ssm4567_reg_defaults), }; -static int ssm4567_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ssm4567_i2c_probe(struct i2c_client *i2c) { struct ssm4567 *ssm4567; int ret; @@ -502,7 +501,7 @@ static struct i2c_driver ssm4567_driver = { .of_match_table = of_match_ptr(ssm4567_of_match), .acpi_match_table = ACPI_PTR(ssm4567_acpi_match), }, - .probe = ssm4567_i2c_probe, + .probe_new = ssm4567_i2c_probe, .id_table = ssm4567_i2c_ids, }; module_i2c_driver(ssm4567_driver); diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index a02a77fef360..04bb8e392497 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2162,8 +2162,9 @@ static const struct of_device_id wm8904_of_match[] = { MODULE_DEVICE_TABLE(of, wm8904_of_match); #endif -static int wm8904_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id wm8904_i2c_id[]; + +static int wm8904_i2c_probe(struct i2c_client *i2c) { struct wm8904_priv *wm8904; unsigned int val; @@ -2197,6 +2198,8 @@ static int wm8904_i2c_probe(struct i2c_client *i2c, return -EINVAL; wm8904->devtype = (enum wm8904_type)match->data; } else { + const struct i2c_device_id *id = + i2c_match_id(wm8904_i2c_id, i2c); wm8904->devtype = id->driver_data; } @@ -2328,7 +2331,7 @@ static struct i2c_driver wm8904_i2c_driver = { .name = "wm8904", .of_match_table = of_match_ptr(wm8904_of_match), }, - .probe = wm8904_i2c_probe, + .probe_new = wm8904_i2c_probe, .id_table = wm8904_i2c_id, }; diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index a7e01106fbc0..cf2c32eac773 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1167,10 +1167,12 @@ static struct spi_driver wm8985_spi_driver = { #endif #if IS_ENABLED(CONFIG_I2C) -static int wm8985_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id wm8985_i2c_id[]; + +static int wm8985_i2c_probe(struct i2c_client *i2c) { struct wm8985_priv *wm8985; + const struct i2c_device_id *id = i2c_match_id(wm8985_i2c_id, i2c); int ret; wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL); @@ -1205,7 +1207,7 @@ static struct i2c_driver wm8985_i2c_driver = { .driver = { .name = "wm8985", }, - .probe = wm8985_i2c_probe, + .probe_new = wm8985_i2c_probe, .id_table = wm8985_i2c_id }; #endif diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c index e21e11dac000..3a42d68c0247 100644 --- a/sound/soc/intel/atom/sst/sst.c +++ b/sound/soc/intel/atom/sst/sst.c @@ -360,7 +360,6 @@ void sst_context_cleanup(struct intel_sst_drv *ctx) sst_unregister(ctx->dev); sst_set_fw_state_locked(ctx, SST_SHUTDOWN); sysfs_remove_group(&ctx->dev->kobj, &sst_fw_version_attr_group); - flush_scheduled_work(); destroy_workqueue(ctx->post_msg_wq); cpu_latency_qos_remove_request(ctx->qos); kfree(ctx->fw_sg_list.src); diff --git a/sound/soc/intel/catpt/messages.h b/sound/soc/intel/catpt/messages.h index 978a20b3f471..c17e948d9f52 100644 --- a/sound/soc/intel/catpt/messages.h +++ b/sound/soc/intel/catpt/messages.h @@ -219,11 +219,9 @@ int catpt_ipc_free_stream(struct catpt_dev *cdev, u8 stream_hw_id); enum catpt_ssp_iface { CATPT_SSP_IFACE_0 = 0, CATPT_SSP_IFACE_1 = 1, - CATPT_SSP_IFACE_LAST = CATPT_SSP_IFACE_1, + CATPT_SSP_COUNT, }; -#define CATPT_SSP_COUNT (CATPT_SSP_IFACE_LAST + 1) - enum catpt_mclk_frequency { CATPT_MCLK_OFF = 0, CATPT_MCLK_FREQ_6_MHZ = 1, diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 28d0dfb4033c..750653404ba3 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -197,6 +197,8 @@ config SND_SOC_SC7280 select SND_SOC_LPASS_MACRO_COMMON imply SND_SOC_LPASS_RX_MACRO imply SND_SOC_LPASS_TX_MACRO + select SND_SOC_RT5682_I2C + select SND_SOC_RT5682S help Add support for audio on Qualcomm Technologies Inc. SC7280 SoC-based systems. diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c index bd0bf9c8cb28..8c0bbae490dd 100644 --- a/sound/soc/qcom/sc7280.c +++ b/sound/soc/qcom/sc7280.c @@ -12,14 +12,21 @@ #include <sound/jack.h> #include <sound/pcm.h> #include <sound/soc.h> +#include <sound/rt5682s.h> #include <linux/soundwire/sdw.h> +#include "../codecs/rt5682.h" +#include "../codecs/rt5682s.h" #include "common.h" #include "lpass.h" +#define DEFAULT_MCLK_RATE 19200000 +#define RT5682_PLL1_FREQ (48000 * 512) + struct sc7280_snd_data { struct snd_soc_card card; struct sdw_stream_runtime *sruntime[LPASS_MAX_PORTS]; + u32 pri_mi2s_clk_count; struct snd_soc_jack hs_jack; struct snd_soc_jack hdmi_jack; bool jack_setup; @@ -69,6 +76,7 @@ static int sc7280_headset_init(struct snd_soc_pcm_runtime *rtd) pdata->jack_setup = true; } switch (cpu_dai->id) { + case MI2S_PRIMARY: case LPASS_CDC_DMA_RX0: case LPASS_CDC_DMA_TX3: for_each_rtd_codec_dais(rtd, i, codec_dai) { @@ -110,11 +118,51 @@ static int sc7280_hdmi_init(struct snd_soc_pcm_runtime *rtd) return snd_soc_component_set_jack(component, &pdata->hdmi_jack, NULL); } +static int sc7280_rt5682_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_card *card = rtd->card; + struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card); + int ret; + + if (++data->pri_mi2s_clk_count == 1) { + snd_soc_dai_set_sysclk(cpu_dai, + LPASS_MCLK0, + DEFAULT_MCLK_RATE, + SNDRV_PCM_STREAM_PLAYBACK); + } + snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_CBC_CFC | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_I2S); + + ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1, + 1536000, RT5682_PLL1_FREQ); + if (ret) { + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1, + RT5682_PLL1_FREQ, + SND_SOC_CLOCK_IN); + + if (ret) { + dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", + ret); + return ret; + } + + return 0; +} + static int sc7280_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); switch (cpu_dai->id) { + case MI2S_PRIMARY: case LPASS_CDC_DMA_TX3: return sc7280_headset_init(rtd); case LPASS_CDC_DMA_RX0: @@ -227,10 +275,66 @@ static int sc7280_snd_hw_free(struct snd_pcm_substream *substream) return 0; } +static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card); + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + + switch (cpu_dai->id) { + case MI2S_PRIMARY: + if (--data->pri_mi2s_clk_count == 0) { + snd_soc_dai_set_sysclk(cpu_dai, + LPASS_MCLK0, + 0, + SNDRV_PCM_STREAM_PLAYBACK); + } + break; + case MI2S_SECONDARY: + break; + case LPASS_DP_RX: + break; + default: + dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__, + cpu_dai->id); + break; + } +} + +static int sc7280_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + int ret = 0; + + switch (cpu_dai->id) { + case MI2S_PRIMARY: + ret = sc7280_rt5682_init(rtd); + break; + case MI2S_SECONDARY: + break; + case LPASS_DP_RX: + break; + default: + dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__, + cpu_dai->id); + return -EINVAL; + } + return ret; +} + static const struct snd_soc_ops sc7280_ops = { + .startup = sc7280_snd_startup, .hw_params = sc7280_snd_hw_params, .hw_free = sc7280_snd_hw_free, .prepare = sc7280_snd_prepare, + .shutdown = sc7280_snd_shutdown, +}; + +static const struct snd_soc_dapm_widget sc7280_snd_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), }; static int sc7280_snd_platform_probe(struct platform_device *pdev) @@ -252,6 +356,9 @@ static int sc7280_snd_platform_probe(struct platform_device *pdev) card->driver_name = "SC7280"; card->dev = dev; + card->dapm_widgets = sc7280_snd_widgets; + card->num_dapm_widgets = ARRAY_SIZE(sc7280_snd_widgets); + ret = qcom_snd_parse_of(card); if (ret) return ret; diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 8b83f39c3ac9..76998a4a4cad 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -386,11 +386,11 @@ static struct snd_soc_codec_conf bells_codec_conf[] = { }, }; -static struct snd_soc_dapm_widget bells_widgets[] = { +static const struct snd_soc_dapm_widget bells_widgets[] = { SND_SOC_DAPM_MIC("DMIC", NULL), }; -static struct snd_soc_dapm_route bells_routes[] = { +static const struct snd_soc_dapm_route bells_routes[] = { { "Sub CLK_SYS", NULL, "OPCLK" }, { "CLKIN", NULL, "OPCLK" }, diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index 34067cc314ff..26c42892c059 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -228,7 +228,7 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("WM1250 Output"), }; -static struct snd_soc_dapm_widget widgets[] = { +static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("AMIC", NULL), @@ -239,7 +239,7 @@ static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; -static struct snd_soc_dapm_route audio_paths[] = { +static const struct snd_soc_dapm_route audio_paths[] = { { "Headphone", NULL, "HPOUT1L" }, { "Headphone", NULL, "HPOUT1R" }, diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 7b12ccd2a9b2..8e4579fdcd7b 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -140,7 +140,7 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), }; -static struct snd_soc_dapm_widget widgets[] = { +static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -150,7 +150,7 @@ static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_MIC("Main DMIC", NULL), }; -static struct snd_soc_dapm_route audio_paths[] = { +static const struct snd_soc_dapm_route audio_paths[] = { { "Sub IN1", NULL, "HPOUT2L" }, { "Sub IN2", NULL, "HPOUT2R" }, diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 37b1f4f60b21..1ae1a5aae72f 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -261,7 +261,7 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), }; -static struct snd_soc_dapm_widget widgets[] = { +static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -271,7 +271,7 @@ static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_MIC("Main DMIC", NULL), }; -static struct snd_soc_dapm_route audio_paths[] = { +static const struct snd_soc_dapm_route audio_paths[] = { { "IN1RN", NULL, "MICB1" }, { "IN1RP", NULL, "MICB1" }, { "IN1RN", NULL, "MICB2" }, diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 8d3149a47a4c..4a56abfc243e 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -130,7 +130,7 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("DMIC"), }; -static struct snd_soc_dapm_widget widgets[] = { +static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -140,7 +140,7 @@ static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_SPK("Main Speaker", NULL), }; -static struct snd_soc_dapm_route audio_paths[] = { +static const struct snd_soc_dapm_route audio_paths[] = { { "Headphone", NULL, "HPOUTL" }, { "Headphone", NULL, "HPOUTR" }, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ce153ac2c3ab..d8426df67dd9 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3390,6 +3390,86 @@ err: } EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs); +/* + * snd_soc_of_put_dai_link_cpus - Dereference device nodes in the codecs array + * @dai_link: DAI link + * + * Dereference device nodes acquired by snd_soc_of_get_dai_link_cpus(). + */ +void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link) +{ + struct snd_soc_dai_link_component *component; + int index; + + for_each_link_cpus(dai_link, index, component) { + if (!component->of_node) + break; + of_node_put(component->of_node); + component->of_node = NULL; + } +} +EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_cpus); + +/* + * snd_soc_of_get_dai_link_cpus - Parse a list of CPU DAIs in the devicetree + * @dev: Card device + * @of_node: Device node + * @dai_link: DAI link + * + * Is analogous to snd_soc_of_get_dai_link_codecs but parses a list of CPU DAIs + * instead. + * + * Returns 0 for success + */ +int snd_soc_of_get_dai_link_cpus(struct device *dev, + struct device_node *of_node, + struct snd_soc_dai_link *dai_link) +{ + struct of_phandle_args args; + struct snd_soc_dai_link_component *component; + char *name; + int index, num_codecs, ret; + + /* Count the number of CODECs */ + name = "sound-dai"; + num_codecs = of_count_phandle_with_args(of_node, name, + "#sound-dai-cells"); + if (num_codecs <= 0) { + if (num_codecs == -ENOENT) + dev_err(dev, "No 'sound-dai' property\n"); + else + dev_err(dev, "Bad phandle in 'sound-dai'\n"); + return num_codecs; + } + component = devm_kcalloc(dev, + num_codecs, sizeof(*component), + GFP_KERNEL); + if (!component) + return -ENOMEM; + dai_link->cpus = component; + dai_link->num_cpus = num_codecs; + + /* Parse the list */ + for_each_link_cpus(dai_link, index, component) { + ret = of_parse_phandle_with_args(of_node, name, + "#sound-dai-cells", + index, &args); + if (ret) + goto err; + component->of_node = args.np; + ret = snd_soc_get_dai_name(&args, &component->dai_name); + if (ret < 0) + goto err; + } + return 0; +err: + snd_soc_of_put_dai_link_codecs(dai_link); + dai_link->cpus = NULL; + dai_link->num_cpus = 0; + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_cpus); + static int __init snd_soc_init(void) { snd_soc_debugfs_init(); diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index de1778c4002b..3b5718a3516d 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -15,36 +15,6 @@ #include "sof-priv.h" #include "sof-audio.h" -static void update_mute_led(struct snd_sof_control *scontrol, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int temp = 0; - int mask; - int i; - - mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - - for (i = 0; i < scontrol->num_channels; i++) { - if (ucontrol->value.integer.value[i]) { - temp |= mask; - break; - } - } - - if (temp == scontrol->led_ctl.led_value) - return; - - scontrol->led_ctl.led_value = temp; - -#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO) - if (!scontrol->led_ctl.direction) - ledtrig_audio_set(LED_AUDIO_MUTE, temp ? LED_OFF : LED_ON); - else - ledtrig_audio_set(LED_AUDIO_MICMUTE, temp ? LED_OFF : LED_ON); -#endif -} - int snd_sof_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -121,9 +91,6 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - if (scontrol->led_ctl.use_led) - update_mute_led(scontrol, kcontrol, ucontrol); - if (tplg_ops->control->switch_put) return tplg_ops->control->switch_put(scontrol, ucontrol); diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 2f8450a8c0a1..2e1c76ed087d 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1592,6 +1592,7 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_ if (scontrol->priv_size > 0) { memcpy(cdata->data, scontrol->priv, scontrol->priv_size); kfree(scontrol->priv); + scontrol->priv = NULL; if (cdata->data->magic != SOF_ABI_MAGIC) { dev_err(sdev->dev, "Wrong ABI magic 0x%08x.\n", cdata->data->magic); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 0d9b640ae24c..e537b1258aa8 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -473,6 +473,7 @@ struct snd_sof_dev { struct list_head route_list; struct snd_soc_component *component; u32 enabled_cores_mask; /* keep track of enabled cores */ + bool led_present; /* FW configuration */ struct sof_ipc_window *info_window; diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 9b11e9795a7a..e47a64934c04 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -773,6 +773,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, struct snd_soc_tplg_mixer_control *mc = container_of(hdr, struct snd_soc_tplg_mixer_control, hdr); int tlv[TLV_ITEMS]; + unsigned int mask; int ret; /* validate topology data */ @@ -821,6 +822,16 @@ skip: goto err; } + if (scontrol->led_ctl.use_led) { + mask = scontrol->led_ctl.direction ? SNDRV_CTL_ELEM_ACCESS_MIC_LED : + SNDRV_CTL_ELEM_ACCESS_SPK_LED; + scontrol->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; + scontrol->access |= mask; + kc->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; + kc->access |= mask; + sdev->led_present = true; + } + dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n", scontrol->comp_id, scontrol->num_channels); @@ -2027,6 +2038,7 @@ static struct snd_soc_tplg_ops sof_tplg_ops = { int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) { + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); const struct firmware *fw; int ret; @@ -2049,6 +2061,10 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) } release_firmware(fw); + + if (ret >= 0 && sdev->led_present) + ret = snd_ctl_led_request(); + return ret; } EXPORT_SYMBOL(snd_sof_load_topology); |