diff options
Diffstat (limited to 'sound/soc/codecs')
270 files changed, 3700 insertions, 759 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index c6043fa58c74..fc65283031cd 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1345,7 +1345,6 @@ static const struct snd_soc_component_driver soc_component_dev_pm860x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pm860x_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6165db92a629..d16b4efb88a7 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -219,6 +219,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_TAS2562 imply SND_SOC_TAS2764 imply SND_SOC_TAS2770 + imply SND_SOC_TAS2780 imply SND_SOC_TAS5086 imply SND_SOC_TAS571X imply SND_SOC_TAS5720 @@ -308,6 +309,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_WM9712 imply SND_SOC_WM9713 imply SND_SOC_WSA881X + imply SND_SOC_WSA883X imply SND_SOC_ZL38060 help Normally ASoC codec drivers are only built if a machine driver which @@ -937,6 +939,16 @@ config SND_SOC_HDAC_HDA tristate select SND_HDA +config SND_SOC_HDA + tristate "HD-Audio codec driver" + select SND_HDA_EXT_CORE + select SND_HDA + help + This enables HD-Audio codec support in ASoC subsystem. Compared + to SND_SOC_HDAC_HDA, driver's behavior is identical to HD-Audio + legacy solution - including the dynamic resource allocation + based on actual codec capabilities. + config SND_SOC_ICS43432 tristate "ICS43423 and compatible i2s microphones" @@ -1524,6 +1536,13 @@ config SND_SOC_TAS2770 tristate "Texas Instruments TAS2770 speaker amplifier" depends on I2C +config SND_SOC_TAS2780 + tristate "Texas Instruments TAS2780 Mono Audio amplifier" + depends on I2C + help + Enable support for Texas Instruments TAS2780 high-efficiency + digital input mono Class-D audio power amplifiers. + config SND_SOC_TAS5086 tristate "Texas Instruments TAS5086 speaker amplifier" depends on I2C @@ -1975,6 +1994,15 @@ config SND_SOC_WSA881X This enables support for Qualcomm WSA8810/WSA8815 Class-D Smart Speaker Amplifier. +config SND_SOC_WSA883X + tristate "WSA883X Codec" + depends on SOUNDWIRE + select REGMAP_SOUNDWIRE + tristate + help + This enables support for Qualcomm WSA8830/WSA8835 Class-D + Smart Speaker Amplifier. + config SND_SOC_ZL38060 tristate "Microsemi ZL38060 Connected Home Audio Processor" depends on SPI_MASTER diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 28dc4edfd01f..92fd441d426a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -106,6 +106,7 @@ snd-soc-es8328-spi-objs := es8328-spi.o snd-soc-gtm601-objs := gtm601.o snd-soc-hdac-hdmi-objs := hdac_hdmi.o snd-soc-hdac-hda-objs := hdac_hda.o +snd-soc-hda-codec-objs := hda.o hda-dai.o snd-soc-ics43432-objs := ics43432.o snd-soc-inno-rk3036-objs := inno_rk3036.o snd-soc-isabelle-objs := isabelle.o @@ -337,6 +338,7 @@ snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o snd-soc-wsa881x-objs := wsa881x.o +snd-soc-wsa883x-objs := wsa883x.o snd-soc-zl38060-objs := zl38060.o # Amp snd-soc-max9877-objs := max9877.o @@ -346,6 +348,7 @@ snd-soc-tpa6130a2-objs := tpa6130a2.o snd-soc-tas2552-objs := tas2552.o snd-soc-tas2562-objs := tas2562.o snd-soc-tas2764-objs := tas2764.o +snd-soc-tas2780-objs := tas2780.o # Mux snd-soc-simple-mux-objs := simple-mux.o @@ -458,6 +461,7 @@ obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o obj-$(CONFIG_SND_SOC_HDAC_HDA) += snd-soc-hdac-hda.o +obj-$(CONFIG_SND_SOC_HDA) += snd-soc-hda-codec.o obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o @@ -589,6 +593,7 @@ obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS2562) += snd-soc-tas2562.o obj-$(CONFIG_SND_SOC_TAS2764) += snd-soc-tas2764.o +obj-$(CONFIG_SND_SOC_TAS2780) += snd-soc-tas2780.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o @@ -688,6 +693,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o +obj-$(CONFIG_SND_SOC_WSA883X) += snd-soc-wsa883x.o obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o # Amp diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index aefafb0b7b97..68342917419e 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -12,8 +12,6 @@ * Mikko Sarmanne <mikko.sarmanne@symbio.com>, * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>, * for ST-Ericsson. - * - * License terms: */ #include <linux/kernel.h> @@ -2525,7 +2523,6 @@ static const struct snd_soc_component_driver ab8500_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ab8500_codec_driver_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h index 0ac87d0446c2..2a6f6409f1f8 100644 --- a/sound/soc/codecs/ab8500-codec.h +++ b/sound/soc/codecs/ab8500-codec.h @@ -11,8 +11,6 @@ * Mikko J. Lehto <mikko.lehto@symbio.com>, * Mikko Sarmanne <mikko.sarmanne@symbio.com>, * for ST-Ericsson. - * - * License terms: */ #ifndef AB8500_CODEC_REGISTERS_H diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 6ad9c9443b5d..cc12052e1920 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -119,7 +119,6 @@ static const struct snd_soc_component_driver soc_component_dev_ac97 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ac97_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 29e1689da67f..2c64df96b5ce 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -332,7 +332,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad1836 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct reg_default ad1836_reg_defaults[] = { diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 30b98b4267e1..1d3c4d94b4ae 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -523,7 +523,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad193x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; const struct regmap_config ad193x_regmap_config = { diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9fd2023da218..5e777d7fd5d9 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -302,7 +302,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad1980 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ad1980_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index b98bf19f594e..f6090ac57e93 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -58,7 +58,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad73311 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ad73311_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index a9032b5c8d78..7f832d00ab17 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1470,7 +1470,6 @@ static const struct snd_soc_component_driver adau1373_component_driver = { .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int adau1373_i2c_probe(struct i2c_client *client) diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 98768e5300f0..135a7db7fcf9 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -772,7 +772,6 @@ static const struct snd_soc_component_driver adau1701_component_drv = { .set_sysclk = adau1701_set_sysclk, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config adau1701_regmap = { diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 8f887227981f..3ccc7acac205 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -930,7 +930,6 @@ static const struct snd_soc_component_driver adau1761_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index 74dc3344b259..ff6be24863bf 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -439,7 +439,6 @@ static const struct snd_soc_component_driver adau1781_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index 5fcbdf2ec313..7a9672f94fc6 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -876,7 +876,6 @@ static const struct snd_soc_component_driver adau1977_component_driver = { .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int adau1977_setup_micbias(struct adau1977 *adau1977) diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c index 0e00de6ce3fb..401bafabc8eb 100644 --- a/sound/soc/codecs/adau7002.c +++ b/sound/soc/codecs/adau7002.c @@ -91,7 +91,6 @@ static const struct snd_soc_component_driver adau7002_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int adau7002_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/adau7118.c b/sound/soc/codecs/adau7118.c index 841229dcbca1..bbb097249887 100644 --- a/sound/soc/codecs/adau7118.c +++ b/sound/soc/codecs/adau7118.c @@ -442,7 +442,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = { .num_dapm_widgets = ARRAY_SIZE(adau7118_widgets), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void adau7118_regulator_disable(void *data) diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 90f3a5e9e31f..fcff35f26cec 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -842,7 +842,6 @@ static const struct snd_soc_component_driver adav80x_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int adav80x_bus_probe(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 1d07e2699f04..44aa06e03486 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -62,7 +62,6 @@ static const struct snd_soc_component_driver soc_component_dev_ads117x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ads117x_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index dc4747c77a7a..ce99f30b4613 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -248,7 +248,6 @@ static const struct snd_soc_component_driver soc_component_device_ak4104 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4104_regmap = { diff --git a/sound/soc/codecs/ak4118.c b/sound/soc/codecs/ak4118.c index 5c4a78c16733..b6d9a10bdccd 100644 --- a/sound/soc/codecs/ak4118.c +++ b/sound/soc/codecs/ak4118.c @@ -342,7 +342,6 @@ static const struct snd_soc_component_driver soc_component_drv_ak4118 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4118_regmap = { diff --git a/sound/soc/codecs/ak4375.c b/sound/soc/codecs/ak4375.c index 9a7b662016b9..1ed004ba7cd2 100644 --- a/sound/soc/codecs/ak4375.c +++ b/sound/soc/codecs/ak4375.c @@ -473,7 +473,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4375 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4375_regmap = { diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c index baa9ff5d0ce5..ea33cc83c86c 100644 --- a/sound/soc/codecs/ak4458.c +++ b/sound/soc/codecs/ak4458.c @@ -725,7 +725,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4458 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_codec_dev_ak4497 = { @@ -740,7 +739,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4497 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4458_regmap = { diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index cc803e730c6e..8c8c93eea704 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -402,7 +402,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4535 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ak4535_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index 8e60e2b56ad6..b9607de5a191 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c @@ -67,7 +67,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4554 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ak4554_soc_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 93606e5afd8f..f75c19ef3551 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -827,7 +827,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4613 = { .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void ak4613_parse_of(struct ak4613_priv *priv, @@ -921,18 +920,12 @@ static int ak4613_i2c_probe(struct i2c_client *i2c) &ak4613_dai, 1); } -static int ak4613_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static struct i2c_driver ak4613_i2c_driver = { .driver = { .name = "ak4613-codec", .of_match_table = ak4613_of_match, }, .probe_new = ak4613_i2c_probe, - .remove = ak4613_i2c_remove, .id_table = ak4613_i2c_id, }; diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index d8d9cc712d67..88851e94b045 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -535,7 +535,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4641 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4641_regmap = { diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 3c20ff5595eb..914d5b1969f8 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -559,7 +559,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4642 = { .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4642_regmap = { diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 60edcbe56014..cd76765f8cc0 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -616,7 +616,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4671 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4671_regmap = { diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index c76bfff24602..0c5e00679c7d 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c @@ -77,7 +77,6 @@ static const struct snd_soc_component_driver soc_component_ak5386 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c index c94cfde3e4a8..887d2c04d647 100644 --- a/sound/soc/codecs/ak5558.c +++ b/sound/soc/codecs/ak5558.c @@ -393,7 +393,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak5558 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_codec_dev_ak5552 = { @@ -408,7 +407,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak5552 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak5558_regmap = { diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 8e6235d2c544..9ef01b1dd294 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -956,7 +956,6 @@ static const struct snd_soc_component_driver soc_component_device_alc5623 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config alc5623_regmap = { diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 641bdfddae16..a770704a4e17 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1078,7 +1078,6 @@ static const struct snd_soc_component_driver soc_component_device_alc5632 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config alc5632_regmap = { diff --git a/sound/soc/codecs/bd28623.c b/sound/soc/codecs/bd28623.c index a6267cb86d86..82a94211d012 100644 --- a/sound/soc/codecs/bd28623.c +++ b/sound/soc/codecs/bd28623.c @@ -161,7 +161,6 @@ static const struct snd_soc_component_driver soc_codec_bd = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver soc_dai_bd = { diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index cf17b9741bd8..4086b6a53de8 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c @@ -69,7 +69,6 @@ static const struct snd_soc_component_driver soc_component_dev_bt_sco = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int bt_sco_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index ffdf8b615efa..4f9dabd9d78a 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -1660,7 +1660,6 @@ static struct snd_soc_component_driver soc_codec_dev_cpcap = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cpcap_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 0aae5790222a..14403b76c724 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -126,7 +126,6 @@ static const struct snd_soc_component_driver soc_component_dev_cq93vc = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cq93vc_platform_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 8b0a9c788a26..11e7b3f6d410 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -995,6 +995,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", priv->ap_shm_phys_addr, priv->ap_shm_len); } + of_node_put(node); } #endif diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index badfc55bc5fa..8ff6f66be86f 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -236,7 +236,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l32 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Current and threshold powerup sequence Pg37 in datasheet */ diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 47dc0f6d90a2..082025fa0370 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -840,7 +840,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l33 = { .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs35l33_regmap = { diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 50d509a06071..472ac982779b 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -787,7 +787,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l34 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs35l34_regmap = { diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 6b70afb70a67..714a759dca21 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1087,7 +1087,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l35 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs35l35_regmap = { diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index dfe85dc2cd20..4dc13e6f4874 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -1300,7 +1300,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l36 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs35l36_regmap = { diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 198cfe54a46f..04be71435491 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1308,7 +1308,8 @@ int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, return 0; } - dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); + if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) + dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); return -ENOMSG; } @@ -1327,6 +1328,85 @@ int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap) } EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata); +int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap, + enum cs35l41_boost_type b_type) +{ + if (!cs35l41_safe_reset(regmap, b_type)) { + dev_dbg(dev, "System does not support Suspend\n"); + return -EINVAL; + } + + dev_dbg(dev, "Enter hibernate\n"); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188); + + // Don't wait for ACK since bus activity would wake the device + regmap_write(regmap, CS35L41_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE); + + return 0; +} +EXPORT_SYMBOL_GPL(cs35l41_enter_hibernate); + +static void cs35l41_wait_for_pwrmgt_sts(struct device *dev, struct regmap *regmap) +{ + const int pwrmgt_retries = 10; + unsigned int sts; + int i, ret; + + for (i = 0; i < pwrmgt_retries; i++) { + ret = regmap_read(regmap, CS35L41_PWRMGT_STS, &sts); + if (ret) + dev_err(dev, "Failed to read PWRMGT_STS: %d\n", ret); + else if (!(sts & CS35L41_WR_PEND_STS_MASK)) + return; + + udelay(20); + } + + dev_err(dev, "Timed out reading PWRMGT_STS\n"); +} + +int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap) +{ + const int wake_retries = 20; + const int sleep_retries = 5; + int ret, i, j; + + for (i = 0; i < sleep_retries; i++) { + dev_dbg(dev, "Exit hibernate\n"); + + for (j = 0; j < wake_retries; j++) { + ret = cs35l41_set_cspl_mbox_cmd(dev, regmap, + CSPL_MBOX_CMD_OUT_OF_HIBERNATE); + if (!ret) + break; + + usleep_range(100, 200); + } + + if (j < wake_retries) { + dev_dbg(dev, "Wake success at cycle: %d\n", j); + return 0; + } + + dev_err(dev, "Wake failed, re-enter hibernate: %d\n", ret); + + cs35l41_wait_for_pwrmgt_sts(dev, regmap); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088); + + cs35l41_wait_for_pwrmgt_sts(dev, regmap); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188); + + cs35l41_wait_for_pwrmgt_sts(dev, regmap); + regmap_write(regmap, CS35L41_PWRMGT_CTL, 0x3); + } + + dev_err(dev, "Timed out waking device\n"); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(cs35l41_exit_hibernate); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c index 9e19c946a66b..5c8bb24909eb 100644 --- a/sound/soc/codecs/cs35l41-spi.c +++ b/sound/soc/codecs/cs35l41-spi.c @@ -74,6 +74,7 @@ MODULE_DEVICE_TABLE(of, cs35l41_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id cs35l41_acpi_match[] = { { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ + { "CLSA3541", 0 }, /* Cirrus Logic PnP ID + part ID */ {}, }; MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 71ab2a5d1c55..c223d83e02cf 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -6,6 +6,7 @@ // // Author: David Rhodes <david.rhodes@cirrus.com> +#include <linux/acpi.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/init.h> @@ -1142,6 +1143,30 @@ err_dsp: return ret; } +static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41) +{ + acpi_handle handle = ACPI_HANDLE(cs35l41->dev); + const char *sub; + + /* If there is no ACPI_HANDLE, there is no ACPI for this system, return 0 */ + if (!handle) + return 0; + + sub = acpi_get_subsystem_id(handle); + if (IS_ERR(sub)) { + /* If bad ACPI, return 0 and fallback to legacy firmware path, otherwise fail */ + if (PTR_ERR(sub) == -ENODATA) + return 0; + else + return PTR_ERR(sub); + } + + cs35l41->dsp.system_name = sub; + dev_dbg(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name); + + return 0; +} + int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg) { u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; @@ -1270,6 +1295,10 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * goto err; } + ret = cs35l41_acpi_get_name(cs35l41); + if (ret < 0) + goto err; + ret = cs35l41_dsp_init(cs35l41); if (ret < 0) goto err; @@ -1316,6 +1345,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41) pm_runtime_disable(cs35l41->dev); regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + kfree(cs35l41->dsp.system_name); wm_adsp2_remove(&cs35l41->dsp); cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); @@ -1335,15 +1365,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) return 0; - dev_dbg(cs35l41->dev, "Enter hibernate\n"); - - cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); - - // Don't wait for ACK since bus activity would wake the device - regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, - CSPL_MBOX_CMD_HIBERNATE); + cs35l41_enter_hibernate(dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type); regcache_cache_only(cs35l41->regmap, true); regcache_mark_dirty(cs35l41->regmap); @@ -1351,65 +1373,6 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) return 0; } -static void cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41) -{ - const int pwrmgt_retries = 10; - unsigned int sts; - int i, ret; - - for (i = 0; i < pwrmgt_retries; i++) { - ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, &sts); - if (ret) - dev_err(cs35l41->dev, "Failed to read PWRMGT_STS: %d\n", ret); - else if (!(sts & CS35L41_WR_PEND_STS_MASK)) - return; - - udelay(20); - } - - dev_err(cs35l41->dev, "Timed out reading PWRMGT_STS\n"); -} - -static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) -{ - const int wake_retries = 20; - const int sleep_retries = 5; - int ret, i, j; - - for (i = 0; i < sleep_retries; i++) { - dev_dbg(cs35l41->dev, "Exit hibernate\n"); - - for (j = 0; j < wake_retries; j++) { - ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, - CSPL_MBOX_CMD_OUT_OF_HIBERNATE); - if (!ret) - break; - - usleep_range(100, 200); - } - - if (j < wake_retries) { - dev_dbg(cs35l41->dev, "Wake success at cycle: %d\n", j); - return 0; - } - - dev_err(cs35l41->dev, "Wake failed, re-enter hibernate: %d\n", ret); - - cs35l41_wait_for_pwrmgt_sts(cs35l41); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); - - cs35l41_wait_for_pwrmgt_sts(cs35l41); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); - - cs35l41_wait_for_pwrmgt_sts(cs35l41); - regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3); - } - - dev_err(cs35l41->dev, "Timed out waking device\n"); - - return -ETIMEDOUT; -} - static int __maybe_unused cs35l41_runtime_resume(struct device *dev) { struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); @@ -1422,7 +1385,7 @@ static int __maybe_unused cs35l41_runtime_resume(struct device *dev) regcache_cache_only(cs35l41->regmap, false); - ret = cs35l41_exit_hibernate(cs35l41); + ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); if (ret) return ret; diff --git a/sound/soc/codecs/cs35l45-i2c.c b/sound/soc/codecs/cs35l45-i2c.c index 38a4dbc9e9fe..06c2ddffb9c5 100644 --- a/sound/soc/codecs/cs35l45-i2c.c +++ b/sound/soc/codecs/cs35l45-i2c.c @@ -40,7 +40,9 @@ static int cs35l45_i2c_remove(struct i2c_client *client) { struct cs35l45_private *cs35l45 = i2c_get_clientdata(client); - return cs35l45_remove(cs35l45); + cs35l45_remove(cs35l45); + + return 0; } static const struct of_device_id cs35l45_of_match[] = { diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index 2367c1a4c10e..d15b3b77c7eb 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -500,6 +500,8 @@ static const struct snd_soc_component_driver cs35l45_component = { .num_controls = ARRAY_SIZE(cs35l45_controls), .name = "cs35l45", + + .endianness = 1, }; static int __maybe_unused cs35l45_runtime_suspend(struct device *dev) @@ -665,7 +667,7 @@ err: } EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45); -int cs35l45_remove(struct cs35l45_private *cs35l45) +void cs35l45_remove(struct cs35l45_private *cs35l45) { pm_runtime_disable(cs35l45->dev); @@ -673,8 +675,6 @@ int cs35l45_remove(struct cs35l45_private *cs35l45) regulator_disable(cs35l45->vdd_a); /* VDD_BATT must be the last to power-off */ regulator_disable(cs35l45->vdd_batt); - - return 0; } EXPORT_SYMBOL_NS_GPL(cs35l45_remove, SND_SOC_CS35L45); diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h index 4e266d19cd1c..53fe9d2b7b15 100644 --- a/sound/soc/codecs/cs35l45.h +++ b/sound/soc/codecs/cs35l45.h @@ -209,9 +209,9 @@ struct cs35l45_private { extern const struct dev_pm_ops cs35l45_pm_ops; extern const struct regmap_config cs35l45_i2c_regmap; extern const struct regmap_config cs35l45_spi_regmap; -int cs35l45_apply_patch(struct cs35l45_private *cs43l45); +int cs35l45_apply_patch(struct cs35l45_private *cs35l45); unsigned int cs35l45_get_clk_freq_id(unsigned int freq); int cs35l45_probe(struct cs35l45_private *cs35l45); -int cs35l45_remove(struct cs35l45_private *cs35l45); +void cs35l45_remove(struct cs35l45_private *cs35l45); #endif /* CS35L45_H */ diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index 881c5ba70c0e..b49a3cf21ebe 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -660,7 +660,6 @@ static const struct snd_soc_component_driver soc_component_cs4234 = { .controls = cs4234_snd_controls, .num_controls = ARRAY_SIZE(cs4234_snd_controls), .set_bias_level = cs4234_set_bias_level, - .non_legacy_dai_naming = 1, .idle_bias_on = 1, .suspend_bias_off = 1, .endianness = 1, diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 86bfa8d5ec78..76c19802d5fe 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -553,7 +553,6 @@ static const struct snd_soc_component_driver soc_component_cs4265 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs4265_regmap = { diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 531f63b01554..ba67e43edf35 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -619,7 +619,6 @@ static const struct snd_soc_component_driver soc_component_device_cs4270 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* @@ -663,7 +662,6 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client) /** * cs4270_i2c_probe - initialize the I2C interface of the CS4270 * @i2c_client: the I2C client object - * @id: the I2C device ID (ignored) * * 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(). diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 7663f89ac6a2..2021cf442606 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -642,7 +642,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs4271 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs4271_common_probe(struct device *dev, diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 4fade2388797..d545a593a251 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -581,7 +581,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l42 = { .num_controls = ARRAY_SIZE(cs42l42_snd_controls), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Switch to SCLK. Atomic delay after the write to allow the switch to complete. */ @@ -1701,8 +1700,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) break; default: - if (cs42l42->plug_state != CS42L42_TS_TRANS) - cs42l42->plug_state = CS42L42_TS_TRANS; + cs42l42->plug_state = CS42L42_TS_TRANS; } } diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 0e933181b5db..51721edd8f53 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -600,7 +600,6 @@ static const struct snd_soc_component_driver soc_component_device_cs42l51 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool cs42l51_writeable_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 10e696406a71..90bf535fc5a5 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1061,7 +1061,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l52 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Current and threshold powerup sequence Pg37 */ diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 510c94265b1f..03e2540a0ba1 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1114,7 +1114,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l56 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs42l56_regmap = { diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 5a9166289f36..0a146319755a 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1256,7 +1256,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l73 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs42l73_regmap = { diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 5d6ef660f851..d14eb2f6e1dd 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c @@ -497,7 +497,6 @@ static const struct snd_soc_component_driver cs42xx8_driver = { .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; const struct cs42xx8_driver_data cs42448_data = { diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index a2bce0f9f247..ca4d47cc9c91 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -2345,7 +2345,6 @@ static struct snd_soc_component_driver soc_component_dev_cs43130 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs43130_regmap = { diff --git a/sound/soc/codecs/cs4341.c b/sound/soc/codecs/cs4341.c index 8ac043f1aae0..ac1696034846 100644 --- a/sound/soc/codecs/cs4341.c +++ b/sound/soc/codecs/cs4341.c @@ -202,7 +202,6 @@ static const struct snd_soc_component_driver soc_component_cs4341 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id __maybe_unused cs4341_dt_ids[] = { diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 7069e9b54857..f7c5c2fd4304 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -260,7 +260,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs4349 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs4349_regmap = { diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 1c7d52bef893..06c4214382e3 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -1356,7 +1356,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l15 = { .num_dapm_routes = ARRAY_SIZE(cs47l15_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l15_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 6356f81aafc5..f9a2b865d717 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1203,7 +1203,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l24 = { .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l24_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index db2f844b8b17..c1032d6c9143 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -1638,7 +1638,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l35 = { .num_dapm_routes = ARRAY_SIZE(cs47l35_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l35_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index d4fedc5ad516..215d8211aa59 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -2582,7 +2582,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l85 = { .num_dapm_routes = ARRAY_SIZE(cs47l85_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l85_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index 5aec937a2462..1ad6526c7871 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -2497,7 +2497,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l90 = { .num_dapm_routes = ARRAY_SIZE(cs47l90_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l90_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index 444026b7d54b..fe576d64e089 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -1964,7 +1964,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l92 = { .num_dapm_routes = ARRAY_SIZE(cs47l92_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l92_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 360ca2ffd506..8796d8e84b7a 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -899,7 +899,6 @@ static const struct snd_soc_component_driver cs53l30_driver = { .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs53l30_regmap = { diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 1af0bf5f1e2f..43c0cac0ec9e 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -411,7 +411,6 @@ static const struct snd_soc_component_driver cx20442_component_dev = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cx20442_platform_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cx2072x.c b/sound/soc/codecs/cx2072x.c index b35debb5818d..b6667e8a6099 100644 --- a/sound/soc/codecs/cx2072x.c +++ b/sound/soc/codecs/cx2072x.c @@ -710,22 +710,19 @@ static int cx2072x_config_i2spcm(struct cx2072x_priv *cx2072x) regdbt2.ulval = 0xac; - /* set master/slave */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: reg2.r.tx_master = 1; reg3.r.rx_master = 1; - dev_dbg(dev, "Sets Master mode\n"); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg2.r.tx_master = 0; reg3.r.rx_master = 0; - dev_dbg(dev, "Sets Slave mode\n"); break; default: - dev_err(dev, "Unsupported DAI master mode\n"); + dev_err(dev, "Unsupported DAI clocking mode\n"); return -EINVAL; } @@ -1009,9 +1006,9 @@ static int cx2072x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) dev_dbg(dev, "set_dai_fmt- %08x\n", fmt); /* set master/slave */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_CBC_CFC: break; default: diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 3fa3042e4424..f838466bfebf 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1173,7 +1173,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7210 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #if IS_ENABLED(CONFIG_I2C) @@ -1335,6 +1334,8 @@ static int __init da7210_modinit(void) int ret = 0; #if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&da7210_i2c_driver); + if (ret) + return ret; #endif #if defined(CONFIG_SPI_MASTER) ret = spi_register_driver(&da7210_spi_driver); diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 2e645dc60eda..544ccbcfc884 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1922,7 +1922,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7213 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config da7213_regmap_config = { diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index a5d7c350a3de..91372909d184 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3040,7 +3040,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7218 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 7fdef38ed8cd..50ecf30e6136 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2647,7 +2647,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7219 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; @@ -2693,11 +2692,6 @@ static int da7219_i2c_probe(struct i2c_client *i2c) return ret; } -static int da7219_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static const struct i2c_device_id da7219_i2c_id[] = { { "da7219", }, { } @@ -2711,7 +2705,6 @@ static struct i2c_driver da7219_i2c_driver = { .acpi_match_table = ACPI_PTR(da7219_acpi_match), }, .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 f14cddf23f42..2c5b0b74201c 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1503,7 +1503,6 @@ static const struct snd_soc_component_driver soc_component_dev_da732x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int da732x_i2c_probe(struct i2c_client *i2c) @@ -1546,11 +1545,6 @@ err: return ret; } -static int da732x_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static const struct i2c_device_id da732x_i2c_id[] = { { "da7320", 0}, { } @@ -1562,7 +1556,6 @@ static struct i2c_driver da732x_i2c_driver = { .name = "da7320", }, .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 9d8c8adc5d76..28043b4530df 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1460,7 +1460,6 @@ static const struct snd_soc_component_driver soc_component_dev_da9055 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config da9055_regmap_config = { diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index d1a30ca4571a..4fd6f97e5a49 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -140,7 +140,6 @@ static const struct snd_soc_component_driver soc_dmic = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int dmic_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c index f443351677df..f5150d2f95da 100644 --- a/sound/soc/codecs/es7134.c +++ b/sound/soc/codecs/es7134.c @@ -213,7 +213,6 @@ static const struct snd_soc_component_driver es7134_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver es7154_dai = { diff --git a/sound/soc/codecs/es7241.c b/sound/soc/codecs/es7241.c index 0baa86241cf9..339553cfbb48 100644 --- a/sound/soc/codecs/es7241.c +++ b/sound/soc/codecs/es7241.c @@ -232,7 +232,6 @@ static const struct snd_soc_component_driver es7241_component_driver = { .num_dapm_routes = ARRAY_SIZE(es7241_dapm_routes), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void es7241_parse_fmt(struct device *dev, struct es7241_data *priv) diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 4407166bb338..de7185f73e1e 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -401,10 +401,8 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai, u8 clksw; u8 mask; - if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { - dev_err(component->dev, "Codec driver only supports consumer mode\n"); - return -EINVAL; - } + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBP_CFP) + serdata1 |= ES8316_SERDATA1_MASTER; if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) { dev_err(component->dev, "Codec driver only supports I2S format\n"); @@ -464,6 +462,8 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); u8 wordlen = 0; + u8 bclk_divider; + u16 lrck_divider; int i; /* Validate supported sample rates that are autodetected from MCLK */ @@ -477,19 +477,24 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, } if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS) return -EINVAL; - + lrck_divider = es8316->sysclk / params_rate(params); + bclk_divider = lrck_divider / 4; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: wordlen = ES8316_SERDATA2_LEN_16; + bclk_divider /= 16; break; case SNDRV_PCM_FORMAT_S20_3LE: wordlen = ES8316_SERDATA2_LEN_20; + bclk_divider /= 20; break; case SNDRV_PCM_FORMAT_S24_LE: wordlen = ES8316_SERDATA2_LEN_24; + bclk_divider /= 24; break; case SNDRV_PCM_FORMAT_S32_LE: wordlen = ES8316_SERDATA2_LEN_32; + bclk_divider /= 32; break; default: return -EINVAL; @@ -499,6 +504,11 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, ES8316_SERDATA2_LEN_MASK, wordlen); snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, ES8316_SERDATA2_LEN_MASK, wordlen); + snd_soc_component_update_bits(component, ES8316_SERDATA1, 0x1f, bclk_divider); + snd_soc_component_update_bits(component, ES8316_CLKMGR_ADCDIV1, 0x0f, lrck_divider >> 8); + snd_soc_component_update_bits(component, ES8316_CLKMGR_ADCDIV2, 0xff, lrck_divider & 0xff); + snd_soc_component_update_bits(component, ES8316_CLKMGR_DACDIV1, 0x0f, lrck_divider >> 8); + snd_soc_component_update_bits(component, ES8316_CLKMGR_DACDIV2, 0xff, lrck_divider & 0xff); return 0; } @@ -769,7 +779,6 @@ static const struct snd_soc_component_driver soc_component_dev_es8316 = { .num_dapm_routes = ARRAY_SIZE(es8316_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_range es8316_volatile_ranges[] = { diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index dd53dfd87b04..160adc706cc6 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -844,7 +844,6 @@ static const struct snd_soc_component_driver es8328_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int es8328_probe(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/gtm601.c b/sound/soc/codecs/gtm601.c index e1235e695b0f..c6b1e77ffccd 100644 --- a/sound/soc/codecs/gtm601.c +++ b/sound/soc/codecs/gtm601.c @@ -73,7 +73,6 @@ static const struct snd_soc_component_driver soc_component_dev_gtm601 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int gtm601_platform_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/hda-dai.c b/sound/soc/codecs/hda-dai.c new file mode 100644 index 000000000000..5371ff086261 --- /dev/null +++ b/sound/soc/codecs/hda-dai.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski <cezary.rojewski@intel.com> +// + +#include <sound/soc.h> +#include <sound/hda_codec.h> +#include "hda.h" + +static int hda_codec_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct hda_pcm_stream *stream_info; + struct hda_codec *codec; + struct hda_pcm *pcm; + int ret; + + codec = dev_to_hda_codec(dai->dev); + stream_info = snd_soc_dai_get_dma_data(dai, substream); + pcm = container_of(stream_info, struct hda_pcm, stream[substream->stream]); + + dev_dbg(dai->dev, "open stream codec: %08x, info: %p, pcm: %p %s substream: %p\n", + codec->core.vendor_id, stream_info, pcm, pcm->name, substream); + + snd_hda_codec_pcm_get(pcm); + + ret = stream_info->ops.open(stream_info, codec, substream); + if (ret < 0) { + dev_err(dai->dev, "codec open failed: %d\n", ret); + snd_hda_codec_pcm_put(pcm); + return ret; + } + + return 0; +} + +static void hda_codec_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct hda_pcm_stream *stream_info; + struct hda_codec *codec; + struct hda_pcm *pcm; + int ret; + + codec = dev_to_hda_codec(dai->dev); + stream_info = snd_soc_dai_get_dma_data(dai, substream); + pcm = container_of(stream_info, struct hda_pcm, stream[substream->stream]); + + dev_dbg(dai->dev, "close stream codec: %08x, info: %p, pcm: %p %s substream: %p\n", + codec->core.vendor_id, stream_info, pcm, pcm->name, substream); + + ret = stream_info->ops.close(stream_info, codec, substream); + if (ret < 0) + dev_err(dai->dev, "codec close failed: %d\n", ret); + + snd_hda_codec_pcm_put(pcm); +} + +static int hda_codec_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct hda_pcm_stream *stream_info; + struct hda_codec *codec; + + codec = dev_to_hda_codec(dai->dev); + stream_info = snd_soc_dai_get_dma_data(dai, substream); + + snd_hda_codec_cleanup(codec, stream_info, substream); + + return 0; +} + +static int hda_codec_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct hda_pcm_stream *stream_info; + struct hdac_stream *stream; + struct hda_codec *codec; + unsigned int format; + int ret; + + codec = dev_to_hda_codec(dai->dev); + stream = substream->runtime->private_data; + stream_info = snd_soc_dai_get_dma_data(dai, substream); + format = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format, + runtime->sample_bits, 0); + + ret = snd_hda_codec_prepare(codec, stream_info, stream->stream_tag, format, substream); + if (ret < 0) { + dev_err(dai->dev, "codec prepare failed: %d\n", ret); + return ret; + } + + return 0; +} + +const struct snd_soc_dai_ops snd_soc_hda_codec_dai_ops = { + .startup = hda_codec_dai_startup, + .shutdown = hda_codec_dai_shutdown, + .hw_free = hda_codec_dai_hw_free, + .prepare = hda_codec_dai_prepare, +}; +EXPORT_SYMBOL_GPL(snd_soc_hda_codec_dai_ops); diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c new file mode 100644 index 000000000000..ad20a3dff9b7 --- /dev/null +++ b/sound/soc/codecs/hda.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski <cezary.rojewski@intel.com> +// + +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <sound/soc.h> +#include <sound/hdaudio_ext.h> +#include <sound/hda_i915.h> +#include <sound/hda_codec.h> +#include "hda.h" + +static int hda_codec_create_dais(struct hda_codec *codec, int pcm_count, + struct snd_soc_dai_driver **drivers) +{ + struct device *dev = &codec->core.dev; + struct snd_soc_dai_driver *drvs; + struct hda_pcm *pcm; + int i; + + drvs = devm_kcalloc(dev, pcm_count, sizeof(*drvs), GFP_KERNEL); + if (!drvs) + return -ENOMEM; + + pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); + + for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { + struct snd_soc_pcm_stream *stream; + int dir; + + dev_info(dev, "creating for %s %d\n", pcm->name, i); + drvs[i].id = i; + drvs[i].name = pcm->name; + drvs[i].ops = &snd_soc_hda_codec_dai_ops; + + dir = SNDRV_PCM_STREAM_PLAYBACK; + stream = &drvs[i].playback; + if (!pcm->stream[dir].substreams) { + dev_info(dev, "skipping playback dai for %s\n", pcm->name); + goto capture_dais; + } + + stream->stream_name = + devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, + snd_pcm_direction_name(dir)); + if (!stream->stream_name) + return -ENOMEM; + stream->channels_min = pcm->stream[dir].channels_min; + stream->channels_max = pcm->stream[dir].channels_max; + stream->rates = pcm->stream[dir].rates; + stream->formats = pcm->stream[dir].formats; + stream->sig_bits = pcm->stream[dir].maxbps; + +capture_dais: + dir = SNDRV_PCM_STREAM_CAPTURE; + stream = &drvs[i].capture; + if (!pcm->stream[dir].substreams) { + dev_info(dev, "skipping capture dai for %s\n", pcm->name); + continue; + } + + stream->stream_name = + devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, + snd_pcm_direction_name(dir)); + if (!stream->stream_name) + return -ENOMEM; + stream->channels_min = pcm->stream[dir].channels_min; + stream->channels_max = pcm->stream[dir].channels_max; + stream->rates = pcm->stream[dir].rates; + stream->formats = pcm->stream[dir].formats; + stream->sig_bits = pcm->stream[dir].maxbps; + } + + *drivers = drvs; + return 0; +} + +static int hda_codec_register_dais(struct hda_codec *codec, struct snd_soc_component *component) +{ + struct snd_soc_dai_driver *drvs = NULL; + struct snd_soc_dapm_context *dapm; + struct hda_pcm *pcm; + int ret, pcm_count = 0; + + if (list_empty(&codec->pcm_list_head)) + return -EINVAL; + list_for_each_entry(pcm, &codec->pcm_list_head, list) + pcm_count++; + + ret = hda_codec_create_dais(codec, pcm_count, &drvs); + if (ret < 0) + return ret; + + dapm = snd_soc_component_get_dapm(component); + + list_for_each_entry(pcm, &codec->pcm_list_head, list) { + struct snd_soc_dai *dai; + + dai = snd_soc_register_dai(component, drvs, false); + if (!dai) { + dev_err(component->dev, "register dai for %s failed\n", pcm->name); + return -EINVAL; + } + + ret = snd_soc_dapm_new_dai_widgets(dapm, dai); + if (ret < 0) { + dev_err(component->dev, "create widgets failed: %d\n", ret); + snd_soc_unregister_dai(dai); + return ret; + } + + snd_soc_dai_init_dma_data(dai, &pcm->stream[0], &pcm->stream[1]); + drvs++; + } + + return 0; +} + +static void hda_codec_unregister_dais(struct hda_codec *codec, + struct snd_soc_component *component) +{ + struct snd_soc_dai *dai, *save; + struct hda_pcm *pcm; + + for_each_component_dais_safe(component, dai, save) { + list_for_each_entry(pcm, &codec->pcm_list_head, list) { + if (strcmp(dai->driver->name, pcm->name)) + continue; + + if (dai->playback_widget) + snd_soc_dapm_free_widget(dai->playback_widget); + if (dai->capture_widget) + snd_soc_dapm_free_widget(dai->capture_widget); + snd_soc_unregister_dai(dai); + break; + } + } +} + +int hda_codec_probe_complete(struct hda_codec *codec) +{ + struct hdac_device *hdev = &codec->core; + struct hdac_bus *bus = hdev->bus; + int ret; + + ret = snd_hda_codec_build_controls(codec); + if (ret < 0) { + dev_err(&hdev->dev, "unable to create controls %d\n", ret); + goto out; + } + + /* Bus suspended codecs as it does not manage their pm */ + pm_runtime_set_active(&hdev->dev); + /* rpm was forbidden in snd_hda_codec_device_new() */ + snd_hda_codec_set_power_save(codec, 2000); + snd_hda_codec_register(codec); +out: + /* Complement pm_runtime_get_sync(bus) in probe */ + pm_runtime_mark_last_busy(bus->dev); + pm_runtime_put_autosuspend(bus->dev); + + return ret; +} +EXPORT_SYMBOL_GPL(hda_codec_probe_complete); + +/* Expects codec with usage_count=1 and status=suspended */ +static int hda_codec_probe(struct snd_soc_component *component) +{ + struct hda_codec *codec = dev_to_hda_codec(component->dev); + struct hdac_device *hdev = &codec->core; + struct hdac_bus *bus = hdev->bus; + struct hdac_ext_link *hlink; + hda_codec_patch_t patch; + int ret; + +#ifdef CONFIG_PM + WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || + !pm_runtime_status_suspended(&hdev->dev)); +#endif + + hlink = snd_hdac_ext_bus_link_at(bus, hdev->addr); + if (!hlink) { + dev_err(&hdev->dev, "hdac link not found\n"); + return -EIO; + } + + pm_runtime_get_sync(bus->dev); + if (hda_codec_is_display(codec)) + snd_hdac_display_power(bus, hdev->addr, true); + snd_hdac_ext_bus_link_get(bus, hlink); + + ret = snd_hda_codec_device_new(codec->bus, component->card->snd_card, hdev->addr, codec, + false); + if (ret < 0) { + dev_err(&hdev->dev, "create hda codec failed: %d\n", ret); + goto device_new_err; + } + + ret = snd_hda_codec_set_name(codec, codec->preset->name); + if (ret < 0) { + dev_err(&hdev->dev, "name failed %s\n", codec->preset->name); + goto err; + } + + ret = snd_hdac_regmap_init(&codec->core); + if (ret < 0) { + dev_err(&hdev->dev, "regmap init failed\n"); + goto err; + } + + patch = (hda_codec_patch_t)codec->preset->driver_data; + if (!patch) { + dev_err(&hdev->dev, "no patch specified?\n"); + ret = -EINVAL; + goto err; + } + + ret = patch(codec); + if (ret < 0) { + dev_err(&hdev->dev, "patch failed %d\n", ret); + goto err; + } + + /* configure codec for 1:1 PCM:DAI mapping */ + codec->mst_no_extra_pcms = 1; + + ret = snd_hda_codec_parse_pcms(codec); + if (ret < 0) { + dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret); + goto parse_pcms_err; + } + + ret = hda_codec_register_dais(codec, component); + if (ret < 0) { + dev_err(&hdev->dev, "update dais failed: %d\n", ret); + goto parse_pcms_err; + } + + if (!hda_codec_is_display(codec)) { + ret = hda_codec_probe_complete(codec); + if (ret < 0) + goto complete_err; + } + + codec->core.lazy_cache = true; + + return 0; + +complete_err: + hda_codec_unregister_dais(codec, component); +parse_pcms_err: + if (codec->patch_ops.free) + codec->patch_ops.free(codec); +err: + snd_hda_codec_cleanup_for_unbind(codec); +device_new_err: + if (hda_codec_is_display(codec)) + snd_hdac_display_power(bus, hdev->addr, false); + + snd_hdac_ext_bus_link_put(bus, hlink); + + pm_runtime_mark_last_busy(bus->dev); + pm_runtime_put_autosuspend(bus->dev); + return ret; +} + +/* Leaves codec with usage_count=1 and status=suspended */ +static void hda_codec_remove(struct snd_soc_component *component) +{ + struct hda_codec *codec = dev_to_hda_codec(component->dev); + struct hdac_device *hdev = &codec->core; + struct hdac_bus *bus = hdev->bus; + struct hdac_ext_link *hlink; + bool was_registered = codec->core.registered; + + /* Don't allow any more runtime suspends */ + pm_runtime_forbid(&hdev->dev); + + hda_codec_unregister_dais(codec, component); + + if (codec->patch_ops.free) + codec->patch_ops.free(codec); + + snd_hda_codec_cleanup_for_unbind(codec); + pm_runtime_put_noidle(&hdev->dev); + /* snd_hdac_device_exit() is only called on bus remove */ + pm_runtime_set_suspended(&hdev->dev); + + if (hda_codec_is_display(codec)) + snd_hdac_display_power(bus, hdev->addr, false); + + hlink = snd_hdac_ext_bus_link_at(bus, hdev->addr); + if (hlink) + snd_hdac_ext_bus_link_put(bus, hlink); + /* + * HDMI card's hda_codec_probe_complete() (see late_probe()) may + * not be called due to early error, leaving bus uc unbalanced + */ + if (!was_registered) { + pm_runtime_mark_last_busy(bus->dev); + pm_runtime_put_autosuspend(bus->dev); + } + +#ifdef CONFIG_PM + WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || + !pm_runtime_status_suspended(&hdev->dev)); +#endif +} + +static const struct snd_soc_dapm_route hda_dapm_routes[] = { + {"AIF1TX", NULL, "Codec Input Pin1"}, + {"AIF2TX", NULL, "Codec Input Pin2"}, + {"AIF3TX", NULL, "Codec Input Pin3"}, + + {"Codec Output Pin1", NULL, "AIF1RX"}, + {"Codec Output Pin2", NULL, "AIF2RX"}, + {"Codec Output Pin3", NULL, "AIF3RX"}, +}; + +static const struct snd_soc_dapm_widget hda_dapm_widgets[] = { + /* Audio Interface */ + SND_SOC_DAPM_AIF_IN("AIF1RX", "Analog Codec Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF2RX", "Digital Codec Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF3RX", "Alt Analog Codec Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1TX", "Analog Codec Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF2TX", "Digital Codec Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF3TX", "Alt Analog Codec Capture", 0, SND_SOC_NOPM, 0, 0), + + /* Input Pins */ + SND_SOC_DAPM_INPUT("Codec Input Pin1"), + SND_SOC_DAPM_INPUT("Codec Input Pin2"), + SND_SOC_DAPM_INPUT("Codec Input Pin3"), + + /* Output Pins */ + SND_SOC_DAPM_OUTPUT("Codec Output Pin1"), + SND_SOC_DAPM_OUTPUT("Codec Output Pin2"), + SND_SOC_DAPM_OUTPUT("Codec Output Pin3"), +}; + +static struct snd_soc_dai_driver card_binder_dai = { + .id = -1, + .name = "codec-probing-DAI", +}; + +static int hda_hdev_attach(struct hdac_device *hdev) +{ + struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); + struct snd_soc_component_driver *comp_drv; + + comp_drv = devm_kzalloc(&hdev->dev, sizeof(*comp_drv), GFP_KERNEL); + if (!comp_drv) + return -ENOMEM; + + /* + * It's save to rely on dev_name() rather than a copy as component + * driver's lifetime is directly tied to hda codec one + */ + comp_drv->name = dev_name(&hdev->dev); + comp_drv->probe = hda_codec_probe; + comp_drv->remove = hda_codec_remove; + comp_drv->idle_bias_on = false; + if (!hda_codec_is_display(codec)) { + comp_drv->dapm_widgets = hda_dapm_widgets; + comp_drv->num_dapm_widgets = ARRAY_SIZE(hda_dapm_widgets); + comp_drv->dapm_routes = hda_dapm_routes; + comp_drv->num_dapm_routes = ARRAY_SIZE(hda_dapm_routes); + } + + return snd_soc_register_component(&hdev->dev, comp_drv, &card_binder_dai, 1); +} + +static int hda_hdev_detach(struct hdac_device *hdev) +{ + struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); + + if (codec->core.registered) + cancel_delayed_work_sync(&codec->jackpoll_work); + + snd_soc_unregister_component(&hdev->dev); + + return 0; +} + +const struct hdac_ext_bus_ops soc_hda_ext_bus_ops = { + .hdev_attach = hda_hdev_attach, + .hdev_detach = hda_hdev_detach, +}; +EXPORT_SYMBOL_GPL(soc_hda_ext_bus_ops); + +MODULE_DESCRIPTION("HD-Audio codec driver"); +MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/hda.h b/sound/soc/codecs/hda.h new file mode 100644 index 000000000000..78a2be4945b1 --- /dev/null +++ b/sound/soc/codecs/hda.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright(c) 2021-2022 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski <cezary.rojewski@intel.com> + */ + +#ifndef SND_SOC_CODECS_HDA_H +#define SND_SOC_CODECS_HDA_H + +#define hda_codec_is_display(codec) \ + ((((codec)->core.vendor_id >> 16) & 0xFFFF) == 0x8086) + +extern const struct snd_soc_dai_ops snd_soc_hda_codec_dai_ops; + +extern const struct hdac_ext_bus_ops soc_hda_ext_bus_ops; +int hda_codec_probe_complete(struct hda_codec *codec); + +#endif diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 66408a98298b..cb23650ad522 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2058,7 +2058,6 @@ static const struct snd_soc_component_driver hdmi_hda_codec = { .remove = hdmi_codec_remove, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx, diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index b773466619b2..5679102de91f 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -606,18 +606,18 @@ static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai, /* Reset daifmt */ memset(cf, 0, sizeof(*cf)); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - cf->bit_clk_master = 1; - cf->frame_clk_master = 1; + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + cf->bit_clk_provider = 1; + cf->frame_clk_provider = 1; break; - case SND_SOC_DAIFMT_CBS_CFM: - cf->frame_clk_master = 1; + case SND_SOC_DAIFMT_CBC_CFP: + cf->frame_clk_provider = 1; break; - case SND_SOC_DAIFMT_CBM_CFS: - cf->bit_clk_master = 1; + case SND_SOC_DAIFMT_CBP_CFC: + cf->bit_clk_provider = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -977,7 +977,6 @@ static const struct snd_soc_component_driver hdmi_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, .set_jack = hdmi_codec_set_jack, }; diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c index de4c8460ab3d..58a382254718 100644 --- a/sound/soc/codecs/ics43432.c +++ b/sound/soc/codecs/ics43432.c @@ -41,7 +41,6 @@ static const struct snd_soc_component_driver ics43432_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ics43432_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index ca0f4c1911e4..8222cde6e3b9 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c @@ -387,7 +387,6 @@ static const struct snd_soc_component_driver rk3036_codec_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rk3036_codec_regmap_config = { diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 39be31e1282e..50105d72b2b7 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1095,7 +1095,6 @@ static const struct snd_soc_component_driver soc_component_dev_isabelle = { .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config isabelle_regmap_config = { diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 081485f784e9..7c25acf6ff0d 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -291,8 +291,6 @@ static const struct snd_soc_component_driver soc_codec_dev_jz4740_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; static const struct regmap_config jz4740_codec_regmap_config = { diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index bd0078e4499b..a2e782cc4276 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1399,7 +1399,6 @@ static const struct snd_soc_component_driver soc_component_dev_lm49453 = { .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config lm49453_regmap_config = { @@ -1442,11 +1441,6 @@ static int lm49453_i2c_probe(struct i2c_client *i2c) return ret; } -static int lm49453_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static const struct i2c_device_id lm49453_i2c_id[] = { { "lm49453", 0 }, { } @@ -1458,7 +1452,6 @@ static struct i2c_driver lm49453_i2c_driver = { .name = "lm49453", }, .probe_new = lm49453_i2c_probe, - .remove = lm49453_i2c_remove, .id_table = lm49453_i2c_id, }; diff --git a/sound/soc/codecs/lochnagar-sc.c b/sound/soc/codecs/lochnagar-sc.c index 54a8ba7ed3c2..13fbd8830b09 100644 --- a/sound/soc/codecs/lochnagar-sc.c +++ b/sound/soc/codecs/lochnagar-sc.c @@ -217,7 +217,6 @@ static const struct snd_soc_component_driver lochnagar_sc_driver = { .dapm_routes = lochnagar_sc_routes, .num_dapm_routes = ARRAY_SIZE(lochnagar_sc_routes), - .non_legacy_dai_naming = 1, .endianness = 1, }; diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index d18b56e60433..1ea10dc70748 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -199,6 +199,7 @@ struct va_macro { struct clk *mclk; struct clk *macro; struct clk *dcodec; + struct clk *fsgen; struct clk_hw hw; struct lpass_macro *pds; @@ -467,9 +468,9 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - return va_macro_mclk_enable(va, true); + return clk_prepare_enable(va->fsgen); case SND_SOC_DAPM_POST_PMD: - return va_macro_mclk_enable(va, false); + clk_disable_unprepare(va->fsgen); } return 0; @@ -1473,6 +1474,12 @@ static int va_macro_probe(struct platform_device *pdev) if (ret) goto err_clkout; + va->fsgen = clk_hw_get_clk(&va->hw, "fsgen"); + if (IS_ERR(va->fsgen)) { + ret = PTR_ERR(va->fsgen); + goto err_clkout; + } + ret = devm_snd_soc_register_component(dev, &va_macro_component_drv, va_macro_dais, ARRAY_SIZE(va_macro_dais)); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 5ef2e1279ee7..5435a49604cf 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1734,7 +1734,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98088 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id max98088_i2c_id[] = { @@ -1746,18 +1745,18 @@ MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); static int max98088_i2c_probe(struct i2c_client *i2c) { - struct max98088_priv *max98088; - int ret; - const struct i2c_device_id *id; + struct max98088_priv *max98088; + int ret; + const struct i2c_device_id *id; - max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), - GFP_KERNEL); - if (max98088 == NULL) - return -ENOMEM; + max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), + GFP_KERNEL); + if (max98088 == NULL) + return -ENOMEM; - max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap); - if (IS_ERR(max98088->regmap)) - return PTR_ERR(max98088->regmap); + max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap); + if (IS_ERR(max98088->regmap)) + return PTR_ERR(max98088->regmap); max98088->mclk = devm_clk_get(&i2c->dev, "mclk"); if (IS_ERR(max98088->mclk)) @@ -1765,14 +1764,14 @@ static int max98088_i2c_probe(struct i2c_client *i2c) return PTR_ERR(max98088->mclk); id = i2c_match_id(max98088_i2c_id, i2c); - max98088->devtype = id->driver_data; + max98088->devtype = id->driver_data; - i2c_set_clientdata(i2c, max98088); - max98088->pdata = i2c->dev.platform_data; + i2c_set_clientdata(i2c, max98088); + max98088->pdata = i2c->dev.platform_data; - ret = devm_snd_soc_register_component(&i2c->dev, - &soc_component_dev_max98088, &max98088_dai[0], 2); - return ret; + ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_max98088, + &max98088_dai[0], 2); + return ret; } #if defined(CONFIG_OF) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 576277a82d41..142083b13ac3 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1591,9 +1591,9 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, cdata->fmt = fmt; regval = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* Set to slave mode PLL - MAS mode off */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: + /* Set to consumer mode PLL - MAS mode off */ snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_MSB, 0x00); snd_soc_component_write(component, @@ -1602,8 +1602,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, M98090_USE_M1_MASK, 0); max98090->master = false; break; - case SND_SOC_DAIFMT_CBM_CFM: - /* Set to master mode */ + case SND_SOC_DAIFMT_CBP_CFP: + /* Set to provider mode */ if (max98090->tdm_slots == 4) { /* TDM */ regval |= M98090_MAS_MASK | @@ -1619,8 +1619,6 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, } max98090->master = true; break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: default: dev_err(component->dev, "DAI clock mode unsupported"); return -EINVAL; @@ -2521,7 +2519,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98090 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98090_regmap = { diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 7bca99fa61b5..44aa58fcc23f 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2103,7 +2103,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98095 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id max98095_i2c_id[] = { diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 918812763884..2a2b286f1747 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -93,7 +93,6 @@ static const struct snd_soc_component_driver max98357a_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops max98357a_dai_ops = { diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 800f2bca6a0f..bac9d1bcf60a 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c @@ -351,7 +351,6 @@ static const struct snd_soc_component_driver max98371_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98371_regmap = { diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c index 4fe065ece17c..3e04c7f0cce4 100644 --- a/sound/soc/codecs/max98373-i2c.c +++ b/sound/soc/codecs/max98373-i2c.c @@ -442,7 +442,6 @@ static bool max98373_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case MAX98373_R2000_SW_RESET ... MAX98373_R2009_INT_FLAG3: - case MAX98373_R203E_AMP_PATH_GAIN: case MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK: case MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK: case MAX98373_R20B6_BDE_CUR_STATE_READBACK: diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index e14fe98349a5..f90a6a7ba83b 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -5,6 +5,7 @@ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/module.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/slab.h> #include <linux/cdev.h> @@ -436,12 +437,22 @@ const struct snd_soc_component_driver soc_codec_dev_max98373 = { .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(soc_codec_dev_max98373); +static int max98373_sdw_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + const struct snd_soc_component_driver soc_codec_dev_max98373_sdw = { - .probe = NULL, + .probe = max98373_sdw_probe, .controls = max98373_snd_controls, .num_controls = ARRAY_SIZE(max98373_snd_controls), .dapm_widgets = max98373_dapm_widgets, @@ -450,7 +461,6 @@ const struct snd_soc_component_driver soc_codec_dev_max98373_sdw = { .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(soc_codec_dev_max98373_sdw); diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 2a6b1648c884..5c08166a8dc6 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -10,7 +10,7 @@ #include <linux/cdev.h> #include <linux/dmi.h> #include <linux/firmware.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/of_gpio.h> @@ -983,7 +983,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98390 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98390_regmap = { diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index 34db38812807..364b4b7ee033 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -5,11 +5,18 @@ #include <linux/i2c.h> #include <linux/module.h> #include <sound/pcm_params.h> +#include <linux/regulator/consumer.h> #include <sound/soc.h> #include <linux/gpio.h> #include <sound/tlv.h> #include "max98396.h" +static const char * const max98396_core_supplies[MAX98396_NUM_CORE_SUPPLIES] = { + "avdd", + "dvdd", + "dvddio", +}; + static struct reg_default max98396_reg[] = { {MAX98396_R2000_SW_RESET, 0x00}, {MAX98396_R2001_INT_RAW1, 0x00}, @@ -368,7 +375,8 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) break; default: - dev_err(component->dev, "DAI invert mode unsupported\n"); + dev_err(component->dev, "DAI invert mode %d unsupported\n", + fmt & SND_SOC_DAIFMT_INV_MASK); return -EINVAL; } @@ -387,6 +395,8 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) format |= MAX98396_PCM_FORMAT_TDM_MODE0; break; default: + dev_err(component->dev, "DAI format %d unsupported\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); return -EINVAL; } @@ -428,46 +438,68 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) return 0; } -/* BCLKs per LRCLK */ -static const int bclk_sel_table[] = { - 32, 48, 64, 96, 128, 192, 256, 384, 512, 320, +#define MAX98396_BSEL_32 0x2 +#define MAX98396_BSEL_48 0x3 +#define MAX98396_BSEL_64 0x4 +#define MAX98396_BSEL_96 0x5 +#define MAX98396_BSEL_128 0x6 +#define MAX98396_BSEL_192 0x7 +#define MAX98396_BSEL_256 0x8 +#define MAX98396_BSEL_384 0x9 +#define MAX98396_BSEL_512 0xa +#define MAX98396_BSEL_320 0xb +#define MAX98396_BSEL_250 0xc +#define MAX98396_BSEL_125 0xd + +/* Refer to table 5 in the datasheet */ +static const struct max98396_pcm_config { + int in, out, width, bsel, max_sr; +} max98396_pcm_configs[] = { + { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 192000 }, + { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 192000 }, + { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 192000 }, + { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 192000 }, + { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 192000 }, + { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 192000 }, + { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 192000 }, + { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 192000 }, + { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 192000 }, + { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 96000 }, + { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 96000 }, + { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 96000 }, + { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 96000 }, + { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 96000 }, + { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 96000 }, + { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 96000 }, + { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 96000 }, + { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 96000 }, + { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 96000 }, + { .in = 8, .out = 16, .width = 16, .bsel = MAX98396_BSEL_128, .max_sr = 96000 }, + { .in = 8, .out = 24, .width = 24, .bsel = MAX98396_BSEL_192, .max_sr = 96000 }, + { .in = 8, .out = 32, .width = 32, .bsel = MAX98396_BSEL_256, .max_sr = 96000 }, + { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 96000 }, + { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 96000 }, + { .in = 16, .out = 32, .width = 16, .bsel = MAX98396_BSEL_256, .max_sr = 96000 }, + { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 48000 }, + { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 48000 }, + { .in = 10, .out = 40, .width = 32, .bsel = MAX98396_BSEL_320, .max_sr = 48000 }, + { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 48000 }, + { .in = 16, .out = 48, .width = 24, .bsel = MAX98396_BSEL_384, .max_sr = 48000 }, + { .in = 16, .out = 64, .width = 32, .bsel = MAX98396_BSEL_512, .max_sr = 48000 }, }; -static int max98396_get_bclk_sel(int bclk) +static int max98396_pcm_config_index(int in_slots, int out_slots, int width) { int i; - /* match BCLKs per LRCLK */ - for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) { - if (bclk_sel_table[i] == bclk) - return i + 2; - } - return 0; -} -static int max98396_set_clock(struct snd_soc_component *component, - struct snd_pcm_hw_params *params) -{ - struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); - /* BCLK/LRCLK ratio calculation */ - int blr_clk_ratio = params_channels(params) * max98396->ch_size; - int value; + for (i = 0; i < ARRAY_SIZE(max98396_pcm_configs); i++) { + const struct max98396_pcm_config *c = &max98396_pcm_configs[i]; - if (!max98396->tdm_mode) { - /* BCLK configuration */ - value = max98396_get_bclk_sel(blr_clk_ratio); - if (!value) { - dev_err(component->dev, "format unsupported %d\n", - params_format(params)); - return -EINVAL; - } - - regmap_update_bits(max98396->regmap, - MAX98396_R2042_PCM_CLK_SETUP, - MAX98396_PCM_CLK_SETUP_BSEL_MASK, - value); + if (in_slots == c->in && out_slots <= c->out && width == c->width) + return i; } - return 0; + return -1; } static int max98396_dai_hw_params(struct snd_pcm_substream *substream, @@ -478,8 +510,7 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); unsigned int sampling_rate = 0; unsigned int chan_sz = 0; - int ret, reg; - int status; + int ret, reg, status, bsel = 0; bool update = false; /* pcm mode configuration */ @@ -499,8 +530,6 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, goto err; } - max98396->ch_size = snd_pcm_format_width(params_format(params)); - dev_dbg(component->dev, "format supported %d", params_format(params)); @@ -548,6 +577,33 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, goto err; } + if (max98396->tdm_mode) { + if (params_rate(params) > max98396->tdm_max_samplerate) { + dev_err(component->dev, "TDM sample rate %d too high", + params_rate(params)); + goto err; + } + } else { + /* BCLK configuration */ + ret = max98396_pcm_config_index(params_channels(params), + params_channels(params), + snd_pcm_format_width(params_format(params))); + if (ret < 0) { + dev_err(component->dev, + "no PCM config for %d channels, format %d\n", + params_channels(params), params_format(params)); + goto err; + } + + bsel = max98396_pcm_configs[ret].bsel; + + if (params_rate(params) > max98396_pcm_configs[ret].max_sr) { + dev_err(component->dev, "sample rate %d too high", + params_rate(params)); + goto err; + } + } + ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status); if (ret < 0) goto err; @@ -593,12 +649,16 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, MAX98396_IVADC_SR_MASK, sampling_rate << MAX98396_IVADC_SR_SHIFT); - ret = max98396_set_clock(component, params); + if (bsel) + regmap_update_bits(max98396->regmap, + MAX98396_R2042_PCM_CLK_SETUP, + MAX98396_PCM_CLK_SETUP_BSEL_MASK, + bsel); if (status && update) max98396_global_enable_onoff(max98396->regmap, true); - return ret; + return 0; err: return -EINVAL; @@ -623,13 +683,16 @@ static int max98396_dai_tdm_slot(struct snd_soc_dai *dai, max98396->tdm_mode = true; /* BCLK configuration */ - bsel = max98396_get_bclk_sel(slots * slot_width); - if (bsel == 0) { - dev_err(component->dev, "BCLK %d not supported\n", - slots * slot_width); + ret = max98396_pcm_config_index(slots, slots, slot_width); + if (ret < 0) { + dev_err(component->dev, "no TDM config for %d slots %d bits\n", + slots, slot_width); return -EINVAL; } + bsel = max98396_pcm_configs[ret].bsel; + max98396->tdm_max_samplerate = max98396_pcm_configs[ret].max_sr; + /* Channel size configuration */ switch (slot_width) { case 16: @@ -642,7 +705,7 @@ static int max98396_dai_tdm_slot(struct snd_soc_dai *dai, chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32; break; default: - dev_err(component->dev, "format unsupported %d\n", + dev_err(component->dev, "slot width %d unsupported\n", slot_width); return -EINVAL; } @@ -1331,6 +1394,12 @@ static int max98396_probe(struct snd_soc_component *component) regmap_write(max98396->regmap, MAX98397_R2057_PCM_RX_SRC2, 0x10); } + /* Supply control */ + regmap_update_bits(max98396->regmap, + MAX98396_R20A0_AMP_SUPPLY_CTL, + MAX98396_AMP_SUPPLY_NOVBAT, + (max98396->vbat == NULL) ? + MAX98396_AMP_SUPPLY_NOVBAT : 0); /* Enable DC blocker */ regmap_update_bits(max98396->regmap, MAX98396_R2092_AMP_DSP_CFG, 1, 1); @@ -1360,6 +1429,9 @@ static int max98396_probe(struct snd_soc_component *component) regmap_write(max98396->regmap, MAX98396_R2045_PCM_TX_CTRL_2, max98396->i_slot); + regmap_write(max98396->regmap, + MAX98396_R204A_PCM_TX_CTRL_7, + max98396->spkfb_slot); if (max98396->v_slot < 8) if (max98396->device_id == CODEC_TYPE_MAX98396) @@ -1426,12 +1498,38 @@ static int max98396_suspend(struct device *dev) regcache_cache_only(max98396->regmap, true); regcache_mark_dirty(max98396->regmap); + regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (max98396->pvdd) + regulator_disable(max98396->pvdd); + + if (max98396->vbat) + regulator_disable(max98396->vbat); + return 0; } static int max98396_resume(struct device *dev) { struct max98396_priv *max98396 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (ret < 0) + return ret; + + if (max98396->pvdd) { + ret = regulator_enable(max98396->pvdd); + if (ret < 0) + return ret; + } + + if (max98396->vbat) { + ret = regulator_enable(max98396->vbat); + if (ret < 0) + return ret; + } regcache_cache_only(max98396->regmap, false); max98396_reset(max98396, dev); @@ -1455,7 +1553,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98396 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_codec_dev_max98397 = { @@ -1469,7 +1566,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98397 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98396_regmap = { @@ -1509,17 +1605,35 @@ static void max98396_read_device_property(struct device *dev, else max98396->i_slot = 1; + if (!device_property_read_u32(dev, "adi,spkfb-slot-no", &value)) + max98396->spkfb_slot = value & 0xF; + else + max98396->spkfb_slot = 2; + if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value)) max98396->bypass_slot = value & 0xF; else max98396->bypass_slot = 0; } +static void max98396_core_supplies_disable(void *priv) +{ + struct max98396_priv *max98396 = priv; + + regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); +} + +static void max98396_supply_disable(void *r) +{ + regulator_disable((struct regulator *) r); +} + static int max98396_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max98396_priv *max98396 = NULL; - int ret, reg; + int i, ret, reg; max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL); @@ -1545,6 +1659,69 @@ static int max98396_i2c_probe(struct i2c_client *i2c, return ret; } + /* Obtain regulator supplies */ + for (i = 0; i < MAX98396_NUM_CORE_SUPPLIES; i++) + max98396->core_supplies[i].supply = max98396_core_supplies[i]; + + ret = devm_regulator_bulk_get(&i2c->dev, MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret); + return ret; + } + + max98396->vbat = devm_regulator_get_optional(&i2c->dev, "vbat"); + if (IS_ERR(max98396->vbat)) { + if (PTR_ERR(max98396->vbat) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + max98396->vbat = NULL; + } + + max98396->pvdd = devm_regulator_get_optional(&i2c->dev, "pvdd"); + if (IS_ERR(max98396->pvdd)) { + if (PTR_ERR(max98396->pvdd) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + max98396->pvdd = NULL; + } + + ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (ret < 0) { + dev_err(&i2c->dev, "Unable to enable core supplies: %d", ret); + return ret; + } + + ret = devm_add_action_or_reset(&i2c->dev, max98396_core_supplies_disable, + max98396); + if (ret < 0) + return ret; + + if (max98396->pvdd) { + ret = regulator_enable(max98396->pvdd); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(&i2c->dev, + max98396_supply_disable, + max98396->pvdd); + if (ret < 0) + return ret; + } + + if (max98396->vbat) { + ret = regulator_enable(max98396->vbat); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(&i2c->dev, + max98396_supply_disable, + max98396->vbat); + if (ret < 0) + return ret; + } + /* update interleave mode info */ if (device_property_read_bool(&i2c->dev, "adi,interleave_mode")) max98396->interleave_mode = true; diff --git a/sound/soc/codecs/max98396.h b/sound/soc/codecs/max98396.h index 694411038597..7278c779989a 100644 --- a/sound/soc/codecs/max98396.h +++ b/sound/soc/codecs/max98396.h @@ -274,6 +274,9 @@ #define MAX98396_DSP_SPK_SAFE_EN_SHIFT (5) #define MAX98396_DSP_SPK_WB_FLT_EN_SHIFT (6) +/* MAX98396_R20A0_AMP_SUPPLY_CTL */ +#define MAX98396_AMP_SUPPLY_NOVBAT (0x1 << 0) + /* MAX98396_R20E0_IV_SENSE_PATH_CFG */ #define MAX98396_IV_SENSE_DCBLK_EN_MASK (0x3 << 0) #define MAX98396_IV_SENSE_DCBLK_EN_SHIFT (0) @@ -291,15 +294,20 @@ enum { CODEC_TYPE_MAX98397, }; +#define MAX98396_NUM_CORE_SUPPLIES 3 + struct max98396_priv { struct regmap *regmap; struct gpio_desc *reset_gpio; + struct regulator_bulk_data core_supplies[MAX98396_NUM_CORE_SUPPLIES]; + struct regulator *pvdd, *vbat; unsigned int v_slot; unsigned int i_slot; + unsigned int spkfb_slot; unsigned int bypass_slot; bool interleave_mode; - unsigned int ch_size; bool tdm_mode; + int tdm_max_samplerate; int device_id; }; #endif diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 9ca6fc254883..a6733396b0ca 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -296,7 +296,6 @@ static const struct snd_soc_component_driver soc_component_dev_max9850 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int max9850_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/max98520.c b/sound/soc/codecs/max98520.c index f0f085ecab55..5edd6f90f8a7 100644 --- a/sound/soc/codecs/max98520.c +++ b/sound/soc/codecs/max98520.c @@ -657,7 +657,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98520 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98520_regmap = { diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 82f20a8e27ad..771b3dcd6cc3 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -448,9 +448,9 @@ static int max9860_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct snd_soc_component *component = dai->component; struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_CBC_CFC: max9860->fmt = fmt; return 0; @@ -537,7 +537,6 @@ static const struct snd_soc_component_driver max9860_component_driver = { .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #ifdef CONFIG_PM diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index eb628b7e84f5..6d2941a9dbd6 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -589,7 +589,6 @@ static const struct snd_soc_component_driver max9867_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool max9867_volatile_register(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c index 63849ebcfd35..c24d9f2c8874 100644 --- a/sound/soc/codecs/max98925.c +++ b/sound/soc/codecs/max98925.c @@ -544,7 +544,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98925 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98925_regmap = { diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 56e0a87c7112..bffd56e240e9 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c @@ -496,7 +496,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98926 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98926_regmap = { diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index b7cff76d7b5b..9cce7c0f0142 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -832,7 +832,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98927 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98927_regmap = { diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 08517547e66c..71490f11d96a 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -727,7 +727,6 @@ static const struct snd_soc_component_driver soc_component_dev_mc13783 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int __init mc13783_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index de8fcbdd85be..3c6ac77379cb 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -537,7 +537,6 @@ static const struct snd_soc_component_driver soc_component_dev_ml26124 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ml26124_i2c_regmap = { diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index e52a559c52d6..78e543eb3c83 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -1128,7 +1128,6 @@ static const struct snd_soc_component_driver pm8916_wcd_analog = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pm8916_wcd_analog_parse_dt(struct device *dev, diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 20a07c92b2fc..d490a0f18675 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -328,8 +328,8 @@ static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM( static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM( "RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); -/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */ -static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); +/* Digital Gain control -84 dB to +40 dB in 1 dB steps */ +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); /* Cutoff Freq for High Pass Filter at -3dB */ static const char * const hpf_cutoff_text[] = { @@ -510,15 +510,15 @@ static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum), SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum), SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0), @@ -553,22 +553,22 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3), WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4), WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5), - SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, + -84, 40, digital_gain), }; @@ -1155,7 +1155,6 @@ static const struct snd_soc_component_driver msm8916_wcd_digital = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config msm8916_codec_regmap_config = { diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index 60b209efe52d..93f35e8d26fc 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -2479,6 +2479,7 @@ static int mt6358_platform_driver_probe(struct platform_device *pdev) static const struct of_device_id mt6358_of_match[] = { {.compatible = "mediatek,mt6358-sound",}, + {.compatible = "mediatek,mt6366-sound",}, {} }; MODULE_DEVICE_TABLE(of, mt6358_of_match); diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c index 6d3d170144a0..c190628e2905 100644 --- a/sound/soc/codecs/mt6359-accdet.c +++ b/sound/soc/codecs/mt6359-accdet.c @@ -675,6 +675,7 @@ static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv) sizeof(struct three_key_threshold)); } + of_node_put(node); dev_warn(priv->dev, "accdet caps=%x\n", priv->caps); return 0; diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index 23709b180409..c9a453ce8a2a 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -2778,6 +2778,7 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) ret = of_property_read_u32(np, "mediatek,mic-type-2", &priv->mux_select[MUX_MIC_TYPE_2]); + of_node_put(np); if (ret) { dev_info(priv->dev, "%s() failed to read mic-type-2, use default (%d)\n", diff --git a/sound/soc/codecs/nau8315.c b/sound/soc/codecs/nau8315.c index 2b66e3f7a8b7..ad4dce9e5080 100644 --- a/sound/soc/codecs/nau8315.c +++ b/sound/soc/codecs/nau8315.c @@ -93,7 +93,6 @@ static const struct snd_soc_component_driver nau8315_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops nau8315_dai_ops = { diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index 347c715e22a4..58f70a02f18a 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -806,7 +806,6 @@ static const struct snd_soc_component_driver nau8540_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config nau8540_regmap_config = { diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index 7b3b1e4ac246..ccb512c21d74 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -866,7 +866,6 @@ static const struct snd_soc_component_driver nau8810_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int nau8810_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/nau8821.c b/sound/soc/codecs/nau8821.c index ce4e7f46bb06..2d21339932e6 100644 --- a/sound/soc/codecs/nau8821.c +++ b/sound/soc/codecs/nau8821.c @@ -29,11 +29,14 @@ #define NAU_FVCO_MAX 100000000 #define NAU_FVCO_MIN 90000000 +#define NAU8821_BUTTON SND_JACK_BTN_0 + /* the maximum frequency of CLK_ADC and CLK_DAC */ #define CLK_DA_AD_MAX 6144000 static int nau8821_configure_sysclk(struct nau8821 *nau8821, int clk_id, unsigned int freq); +static bool nau8821_is_jack_inserted(struct regmap *regmap); struct nau8821_fll { int mclk_src; @@ -493,7 +496,33 @@ static int nau8821_output_dac_event(struct snd_soc_dapm_widget *w, return 0; } +static int system_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + dev_dbg(nau8821->dev, "system clock control : POWER OFF\n"); + /* Set clock source to disable or internal clock before the + * playback or capture end. Codec needs clock for Jack + * detection and button press if jack inserted; otherwise, + * the clock should be closed. + */ + if (nau8821_is_jack_inserted(nau8821->regmap)) { + nau8821_configure_sysclk(nau8821, + NAU8821_CLK_INTERNAL, 0); + } else { + nau8821_configure_sysclk(nau8821, NAU8821_CLK_DIS, 0); + } + } + return 0; +} + static const struct snd_soc_dapm_widget nau8821_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0, + system_clock_control, SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("MICBIAS", NAU8821_R74_MIC_BIAS, NAU8821_MICBIAS_POWERUP_SFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("DMIC Clock", SND_SOC_NOPM, 0, 0, @@ -605,6 +634,9 @@ static const struct snd_soc_dapm_route nau8821_dapm_routes[] = { {"AIFTX", NULL, "ADCL Digital path"}, {"AIFTX", NULL, "ADCR Digital path"}, + {"AIFTX", NULL, "System Clock"}, + {"AIFRX", NULL, "System Clock"}, + {"DDACL", NULL, "AIFRX"}, {"DDACR", NULL, "AIFRX"}, @@ -911,6 +943,20 @@ static void nau8821_eject_jack(struct nau8821 *nau8821) /* Recover to normal channel input */ regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE, NAU8821_ADC_R_SRC_EN, 0); + if (nau8821->key_enable) { + regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK, + NAU8821_IRQ_KEY_RELEASE_EN | + NAU8821_IRQ_KEY_PRESS_EN, + NAU8821_IRQ_KEY_RELEASE_EN | + NAU8821_IRQ_KEY_PRESS_EN); + regmap_update_bits(regmap, + NAU8821_R12_INTERRUPT_DIS_CTRL, + NAU8821_IRQ_KEY_RELEASE_DIS | + NAU8821_IRQ_KEY_PRESS_DIS, + NAU8821_IRQ_KEY_RELEASE_DIS | + NAU8821_IRQ_KEY_PRESS_DIS); + } + } static void nau8821_jdet_work(struct work_struct *work) @@ -940,6 +986,15 @@ static void nau8821_jdet_work(struct work_struct *work) */ regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE, NAU8821_ADC_R_SRC_EN, NAU8821_ADC_R_SRC_EN); + if (nau8821->key_enable) { + regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK, + NAU8821_IRQ_KEY_RELEASE_EN | + NAU8821_IRQ_KEY_PRESS_EN, 0); + regmap_update_bits(regmap, + NAU8821_R12_INTERRUPT_DIS_CTRL, + NAU8821_IRQ_KEY_RELEASE_DIS | + NAU8821_IRQ_KEY_PRESS_DIS, 0); + } } else { dev_dbg(nau8821->dev, "Headphone connected\n"); event |= SND_JACK_HEADPHONE; @@ -999,6 +1054,13 @@ static irqreturn_t nau8821_interrupt(int irq, void *data) nau8821_eject_jack(nau8821); event_mask |= SND_JACK_HEADSET; clear_irq = NAU8821_JACK_EJECT_IRQ_MASK; + } else if (active_irq & NAU8821_KEY_SHORT_PRESS_IRQ) { + event |= NAU8821_BUTTON; + event_mask |= NAU8821_BUTTON; + clear_irq = NAU8821_KEY_SHORT_PRESS_IRQ; + } else if (active_irq & NAU8821_KEY_RELEASE_IRQ) { + event_mask = NAU8821_BUTTON; + clear_irq = NAU8821_KEY_RELEASE_IRQ; } else if ((active_irq & NAU8821_JACK_INSERT_IRQ_MASK) == NAU8821_JACK_INSERT_DETECTED) { regmap_update_bits(regmap, NAU8821_R71_ANALOG_ADC_1, @@ -1430,7 +1492,6 @@ static const struct snd_soc_component_driver nau8821_component_driver = { .dapm_routes = nau8821_dapm_routes, .num_dapm_routes = ARRAY_SIZE(nau8821_dapm_routes), .suspend_bias_off = 1, - .non_legacy_dai_naming = 1, .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, @@ -1490,6 +1551,7 @@ static void nau8821_print_device_properties(struct nau8821 *nau8821) nau8821->jack_eject_debounce); dev_dbg(dev, "dmic-clk-threshold: %d\n", nau8821->dmic_clk_threshold); + dev_dbg(dev, "key_enable: %d\n", nau8821->key_enable); } static int nau8821_read_device_properties(struct device *dev, @@ -1503,6 +1565,8 @@ static int nau8821_read_device_properties(struct device *dev, "nuvoton,jkdet-pull-enable"); nau8821->jkdet_pull_up = device_property_read_bool(dev, "nuvoton,jkdet-pull-up"); + nau8821->key_enable = device_property_read_bool(dev, + "nuvoton,key-enable"); ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity", &nau8821->jkdet_polarity); if (ret) @@ -1665,15 +1729,6 @@ static int nau8821_i2c_probe(struct i2c_client *i2c) return ret; } -static int nau8821_i2c_remove(struct i2c_client *i2c_client) -{ - struct nau8821 *nau8821 = i2c_get_clientdata(i2c_client); - - devm_free_irq(nau8821->dev, nau8821->irq, nau8821); - - return 0; -} - static const struct i2c_device_id nau8821_i2c_ids[] = { { "nau8821", 0 }, { } @@ -1703,7 +1758,6 @@ static struct i2c_driver nau8821_driver = { .acpi_match_table = ACPI_PTR(nau8821_acpi_match), }, .probe_new = nau8821_i2c_probe, - .remove = nau8821_i2c_remove, .id_table = nau8821_i2c_ids, }; module_i2c_driver(nau8821_driver); diff --git a/sound/soc/codecs/nau8821.h b/sound/soc/codecs/nau8821.h index a92edfeb9d3a..c44251f54d48 100644 --- a/sound/soc/codecs/nau8821.h +++ b/sound/soc/codecs/nau8821.h @@ -525,6 +525,7 @@ struct nau8821 { int jack_eject_debounce; int fs; int dmic_clk_threshold; + int key_enable; }; int nau8821_enable_jack_detect(struct snd_soc_component *component, diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 08f6c56dc387..1aef281a9972 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -726,6 +726,17 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, struct nau8822_pll *pll_param = &nau8822->pll; int ret, fs; + if (freq_in == pll_param->freq_in && + freq_out == pll_param->freq_out) + return 0; + + if (freq_out == 0) { + dev_dbg(component->dev, "PLL disabled\n"); + snd_soc_component_update_bits(component, + NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_OFF); + return 0; + } + fs = freq_out / 256; ret = nau8822_calc_pll(freq_in, fs, pll_param); @@ -762,6 +773,9 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, snd_soc_component_update_bits(component, NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_ON); + pll_param->freq_in = freq_in; + pll_param->freq_out = freq_out; + return 0; } @@ -1069,7 +1083,6 @@ static const struct snd_soc_component_driver soc_component_dev_nau8822 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config nau8822_regmap_config = { diff --git a/sound/soc/codecs/nau8822.h b/sound/soc/codecs/nau8822.h index b45d42c15de6..547ec057f853 100644 --- a/sound/soc/codecs/nau8822.h +++ b/sound/soc/codecs/nau8822.h @@ -198,6 +198,8 @@ struct nau8822_pll { int mclk_scaler; int pll_frac; int pll_int; + int freq_in; + int freq_out; }; /* Codec Private Data */ diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 2a7c93508535..ad54d70f7d8e 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -1544,7 +1544,6 @@ static const struct snd_soc_component_driver nau8824_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops nau8824_dai_ops = { diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 20e45a337b8f..54ef7b0fa878 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -1440,7 +1440,7 @@ static struct snd_soc_dai_driver nau8825_dai = { .capture = { .stream_name = "Capture", .channels_min = 1, - .channels_max = 1, + .channels_max = 2, /* Only 1 channel of data */ .rates = NAU8825_RATES, .formats = NAU8825_FORMATS, }, @@ -2478,7 +2478,6 @@ static const struct snd_soc_component_driver nau8825_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void nau8825_reset_chip(struct regmap *regmap) diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 20eb04c8a41a..3591f6f53901 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -290,7 +290,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm1681 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id pcm1681_i2c_id[] = { diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c index 35788b57e11f..3ab381e9a856 100644 --- a/sound/soc/codecs/pcm1789.c +++ b/sound/soc/codecs/pcm1789.c @@ -229,7 +229,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm1789 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int pcm1789_common_init(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index ee60373d7d25..f52ff66b6e64 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -207,7 +207,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm179x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int pcm179x_common_init(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/pcm186x.c b/sound/soc/codecs/pcm186x.c index fda9d7ee3fe6..dd21803ba13c 100644 --- a/sound/soc/codecs/pcm186x.c +++ b/sound/soc/codecs/pcm186x.c @@ -578,7 +578,6 @@ static struct snd_soc_component_driver soc_codec_dev_pcm1863 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_component_driver soc_codec_dev_pcm1865 = { @@ -593,7 +592,6 @@ static struct snd_soc_component_driver soc_codec_dev_pcm1865 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool pcm186x_volatile(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index aef40ec40aa1..09c6c1326833 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -102,7 +102,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm3008 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pcm3008_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index cf27f05dc46a..9d6431338fb7 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -716,7 +716,6 @@ static const struct snd_soc_component_driver pcm3168a_driver = { .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int pcm3168a_probe(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c index f39f98bbc97f..3401a25341e6 100644 --- a/sound/soc/codecs/pcm5102a.c +++ b/sound/soc/codecs/pcm5102a.c @@ -28,7 +28,6 @@ static struct snd_soc_component_driver soc_component_dev_pcm5102a = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pcm5102a_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index a3ff4a07aff7..767463e82665 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -1512,7 +1512,6 @@ static const struct snd_soc_component_driver pcm512x_component_driver = { .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_range_cfg pcm512x_range = { diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c index 86b679cf7aef..1d523bfd9d84 100644 --- a/sound/soc/codecs/rk3328_codec.c +++ b/sound/soc/codecs/rk3328_codec.c @@ -69,11 +69,11 @@ static int rk3328_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) snd_soc_component_get_drvdata(dai->component); unsigned int val; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: val = PIN_DIRECTION_IN | DAC_I2S_MODE_SLAVE; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: val = PIN_DIRECTION_OUT | DAC_I2S_MODE_MASTER; break; default: diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c index cce6f4e7992f..2a5b274bfc0f 100644 --- a/sound/soc/codecs/rk817_codec.c +++ b/sound/soc/codecs/rk817_codec.c @@ -444,7 +444,6 @@ static const struct snd_soc_component_driver soc_codec_dev_rk817 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, .controls = rk817_volume_controls, .num_controls = ARRAY_SIZE(rk817_volume_controls), .dapm_routes = rk817_dapm_routes, diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index 08dbaef84d4e..c1568216126e 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -2176,7 +2176,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1011 = { .set_pll = rt1011_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1011_regmap = { diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 7a06f2654afb..57d0f1c69e46 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -1071,7 +1071,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1015 = { .set_pll = rt1015_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1015_regmap = { diff --git a/sound/soc/codecs/rt1015p.c b/sound/soc/codecs/rt1015p.c index 415cfb3b2f0d..06800dad8798 100644 --- a/sound/soc/codecs/rt1015p.c +++ b/sound/soc/codecs/rt1015p.c @@ -89,7 +89,6 @@ static const struct snd_soc_component_driver rt1015p_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver rt1015p_dai_driver = { diff --git a/sound/soc/codecs/rt1016.c b/sound/soc/codecs/rt1016.c index e31c4736627f..37eeec650f03 100644 --- a/sound/soc/codecs/rt1016.c +++ b/sound/soc/codecs/rt1016.c @@ -595,7 +595,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1016 = { .set_pll = rt1016_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1016_regmap = { diff --git a/sound/soc/codecs/rt1019.c b/sound/soc/codecs/rt1019.c index f3f15fbe85d0..b66bfecbb879 100644 --- a/sound/soc/codecs/rt1019.c +++ b/sound/soc/codecs/rt1019.c @@ -522,7 +522,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1019 = { .num_dapm_widgets = ARRAY_SIZE(rt1019_dapm_widgets), .dapm_routes = rt1019_dapm_routes, .num_dapm_routes = ARRAY_SIZE(rt1019_dapm_routes), - .non_legacy_dai_naming = 1, .endianness = 1, }; diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c index 58d97e3c5087..5b39a440b6dc 100644 --- a/sound/soc/codecs/rt1305.c +++ b/sound/soc/codecs/rt1305.c @@ -946,7 +946,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1305 = { .set_pll = rt1305_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1305_regmap = { diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 72f673f278ee..0be6e72ff5a9 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -608,7 +608,19 @@ static const struct sdw_slave_ops rt1308_slave_ops = { .bus_config = rt1308_bus_config, }; +static int rt1308_sdw_component_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_component_sdw_rt1308 = { + .probe = rt1308_sdw_component_probe, .controls = rt1308_snd_controls, .num_controls = ARRAY_SIZE(rt1308_snd_controls), .dapm_widgets = rt1308_dapm_widgets, diff --git a/sound/soc/codecs/rt1308.c b/sound/soc/codecs/rt1308.c index eec2b1760408..d2a8e9fe3e23 100644 --- a/sound/soc/codecs/rt1308.c +++ b/sound/soc/codecs/rt1308.c @@ -765,7 +765,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1308 = { .set_pll = rt1308_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1308_regmap = { diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 2d6b5f9d4d77..e53396606a1c 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -590,7 +590,19 @@ static struct sdw_slave_ops rt1316_slave_ops = { .update_status = rt1316_update_status, }; +static int rt1316_sdw_component_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_component_sdw_rt1316 = { + .probe = rt1316_sdw_component_probe, .controls = rt1316_snd_controls, .num_controls = ARRAY_SIZE(rt1316_snd_controls), .dapm_widgets = rt1316_dapm_widgets, diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index ab093bdb5552..f2c50b11e4d0 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -980,14 +980,11 @@ static int rt274_probe(struct snd_soc_component *component) struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); rt274->component = component; + INIT_DELAYED_WORK(&rt274->jack_detect_work, rt274_jack_detect_work); - if (rt274->i2c->irq) { - INIT_DELAYED_WORK(&rt274->jack_detect_work, - rt274_jack_detect_work); + if (rt274->i2c->irq) schedule_delayed_work(&rt274->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } @@ -996,6 +993,7 @@ static void rt274_remove(struct snd_soc_component *component) struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt274->jack_detect_work); + rt274->component = NULL; } #ifdef CONFIG_PM @@ -1075,7 +1073,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt274 = { .num_dapm_routes = ARRAY_SIZE(rt274_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt274_regmap = { diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index ad8ea1fa7c23..c4f7c4c2d793 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -311,7 +311,8 @@ static void rt286_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt286_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); @@ -335,7 +336,6 @@ int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *j return 0; } -EXPORT_SYMBOL_GPL(rt286_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -947,17 +947,11 @@ static int rt286_probe(struct snd_soc_component *component) struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); rt286->component = component; + INIT_DELAYED_WORK(&rt286->jack_detect_work, rt286_jack_detect_work); - if (rt286->i2c->irq) { - regmap_update_bits(rt286->regmap, - RT286_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt286->jack_detect_work, - rt286_jack_detect_work); + if (rt286->i2c->irq) schedule_delayed_work(&rt286->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(50)); return 0; } @@ -966,6 +960,7 @@ static void rt286_remove(struct snd_soc_component *component) struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt286->jack_detect_work); + rt286->component = NULL; } #ifdef CONFIG_PM @@ -1055,6 +1050,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt286 = { .suspend = rt286_suspend, .resume = rt286_resume, .set_bias_level = rt286_set_bias_level, + .set_jack = rt286_mic_detect, .controls = rt286_snd_controls, .num_controls = ARRAY_SIZE(rt286_snd_controls), .dapm_widgets = rt286_dapm_widgets, @@ -1063,7 +1059,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt286 = { .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt286_regmap = { diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index f27a4e71d5b6..4b7a3bd6043d 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h @@ -196,7 +196,5 @@ enum { RT286_AIFS, }; -int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); - #endif /* __RT286_H__ */ diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index c291786dc82d..b0b53d4f07df 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -326,39 +326,37 @@ static void rt298_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt298_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm; - bool hp = false; - bool mic = false; - int status = 0; - /* If jack in NULL, disable HS jack */ - if (!jack) { + rt298->jack = jack; + + if (jack) { + /* Enable IRQ */ + if (rt298->jack->status & SND_JACK_HEADPHONE) + snd_soc_dapm_force_enable_pin(dapm, "LDO1"); + if (rt298->jack->status & SND_JACK_MICROPHONE) { + snd_soc_dapm_force_enable_pin(dapm, "HV"); + snd_soc_dapm_force_enable_pin(dapm, "VREF"); + } + regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); + /* Send an initial empty report */ + snd_soc_jack_report(rt298->jack, rt298->jack->status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + } else { + /* Disable IRQ */ regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0); - dapm = snd_soc_component_get_dapm(component); + snd_soc_dapm_disable_pin(dapm, "HV"); + snd_soc_dapm_disable_pin(dapm, "VREF"); snd_soc_dapm_disable_pin(dapm, "LDO1"); - snd_soc_dapm_sync(dapm); - return 0; } - - rt298->jack = jack; - regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); - - rt298_jack_detect(rt298, &hp, &mic); - if (hp) - status |= SND_JACK_HEADPHONE; - - if (mic) - status |= SND_JACK_MICROPHONE; - - snd_soc_jack_report(rt298->jack, status, - SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + snd_soc_dapm_sync(dapm); return 0; } -EXPORT_SYMBOL_GPL(rt298_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -1011,17 +1009,11 @@ static int rt298_probe(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); rt298->component = component; + INIT_DELAYED_WORK(&rt298->jack_detect_work, rt298_jack_detect_work); - if (rt298->i2c->irq) { - regmap_update_bits(rt298->regmap, - RT298_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt298->jack_detect_work, - rt298_jack_detect_work); + if (rt298->i2c->irq) schedule_delayed_work(&rt298->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } @@ -1030,6 +1022,7 @@ static void rt298_remove(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt298->jack_detect_work); + rt298->component = NULL; } #ifdef CONFIG_PM @@ -1120,6 +1113,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .suspend = rt298_suspend, .resume = rt298_resume, .set_bias_level = rt298_set_bias_level, + .set_jack = rt298_mic_detect, .controls = rt298_snd_controls, .num_controls = ARRAY_SIZE(rt298_snd_controls), .dapm_widgets = rt298_dapm_widgets, @@ -1128,7 +1122,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt298_regmap = { diff --git a/sound/soc/codecs/rt298.h b/sound/soc/codecs/rt298.h index ed2b8fd87f4c..f1be9c135401 100644 --- a/sound/soc/codecs/rt298.h +++ b/sound/soc/codecs/rt298.h @@ -207,7 +207,5 @@ enum { RT298_AIFS, }; -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); - #endif /* __RT298_H__ */ diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index be8ece4630df..b9bcf04d4dc9 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -1173,7 +1173,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5514 = { .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5514_i2c_regmap = { diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 37f1bf552eff..970d6c4a358e 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -1304,7 +1304,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5616 = { .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5616_regmap = { diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index c941e878471c..957f6b19beec 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1666,7 +1666,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5631 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id rt5631_i2c_id[] = { diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 18b3da9211e3..38ab8d4291c2 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2567,10 +2567,18 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); } +static const struct snd_soc_dapm_route rt5640_hda_jack_dapm_routes[] = { + {"IN1P", NULL, "MICBIAS1"}, + {"IN2P", NULL, "MICBIAS1"}, + {"IN3P", NULL, "MICBIAS1"}, +}; + static void rt5640_enable_hda_jack_detect( struct snd_soc_component *component, struct snd_soc_jack *jack) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int ret; /* Select JD1 for Mic */ @@ -2609,6 +2617,9 @@ static void rt5640_enable_hda_jack_detect( /* sync initial jack state */ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); + + snd_soc_dapm_add_routes(dapm, rt5640_hda_jack_dapm_routes, + ARRAY_SIZE(rt5640_hda_jack_dapm_routes)); } static int rt5640_set_jack(struct snd_soc_component *component, @@ -2881,8 +2892,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5640 = { .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; static const struct regmap_config rt5640_regmap = { diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 507aba8de3cc..8635bc6567dc 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3534,7 +3534,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5645 = { .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5645_regmap = { diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index d11d201b1d03..df90af906563 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -2161,7 +2161,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5651 = { .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5651_regmap = { diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 6efa90f46362..5e21e3c37ab5 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -3801,7 +3801,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5659 = { .set_pll = rt5659_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index d5f9926625d2..341baa29fdb1 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1208,7 +1208,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5660 = { .num_dapm_routes = ARRAY_SIZE(rt5660_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5660_regmap = { diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index e51eed8a79ab..ca981b374b0c 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -3258,7 +3258,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5663 = { .set_jack = rt5663_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5663_v2_regmap = { diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 4a8d62e1dd2b..6e66cc218fa8 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4617,7 +4617,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5665 = { .set_jack = rt5665_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 01566f036ca1..beb0951ff680 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -2362,7 +2362,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5668 = { .set_jack = rt5668_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5668_regmap = { diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8a97f6db04d5..60dbfa2a54f1 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2852,7 +2852,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5670 = { .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5670_regmap = { diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 4a8c267d4fbc..31a2dd0aafb6 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5189,7 +5189,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5677 = { .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5677_regmap_physical = { diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 2b6c6d6b9771..2df95e792900 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -3064,7 +3064,6 @@ const struct snd_soc_component_driver rt5682_soc_component_dev = { .set_jack = rt5682_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(rt5682_soc_component_dev); diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index 4d44eddee901..eb47e7cd485a 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -2893,7 +2893,6 @@ static const struct snd_soc_component_driver rt5682s_soc_component_dev = { .set_jack = rt5682s_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int rt5682s_parse_dt(struct rt5682s_priv *rt5682s, struct device *dev) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 9bceeeb830b1..055c3ae974d8 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -818,9 +818,14 @@ static const struct snd_soc_dapm_route rt700_audio_map[] = { static int rt700_probe(struct snd_soc_component *component) { struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + int ret; rt700->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 5ad53bbc8528..925268121901 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1194,10 +1194,15 @@ static int rt711_sdca_parse_dt(struct rt711_sdca_priv *rt711, struct device *dev static int rt711_sdca_probe(struct snd_soc_component *component) { struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711_sdca_parse_dt(rt711, &rt711->slave->dev); rt711->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 9df800abfc2d..1bf618089194 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -935,10 +935,15 @@ static int rt711_parse_dt(struct rt711_priv *rt711, struct device *dev) static int rt711_probe(struct snd_soc_component *component) { struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711_parse_dt(rt711, &rt711->slave->dev); rt711->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 5857d0866307..ce8bbc76199a 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -758,7 +758,19 @@ static const struct snd_soc_dapm_route rt715_sdca_audio_map[] = { {"ADC 25 Mux", "DMIC4", "DMIC4"}, }; +static int rt715_sdca_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = { + .probe = rt715_sdca_probe, .controls = rt715_sdca_snd_controls, .num_controls = ARRAY_SIZE(rt715_sdca_snd_controls), .dapm_widgets = rt715_sdca_dapm_widgets, diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 418e006b19ef..e93240521c74 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -737,7 +737,19 @@ static int rt715_set_bias_level(struct snd_soc_component *component, return 0; } +static int rt715_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_rt715 = { + .probe = rt715_probe, .set_bias_level = rt715_set_bias_level, .controls = rt715_snd_controls, .num_controls = ARRAY_SIZE(rt715_snd_controls), diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 3363d1696ad7..3fafd9fc5cfd 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1536,7 +1536,6 @@ static const struct snd_soc_component_driver sgtl5000_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sgtl5000_regmap = { diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 8bd2edf70f13..d87141ba8438 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -239,7 +239,6 @@ static const struct snd_soc_component_driver soc_component_dev_si476x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int si476x_platform_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 276db978e587..862e0b654a1c 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c @@ -43,7 +43,6 @@ static struct snd_soc_component_driver soc_codec_spdif_dir = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver dir_stub_dai = { diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index 2c8cebfc6603..736518921555 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c @@ -43,7 +43,6 @@ static struct snd_soc_component_driver soc_codec_spdif_dit = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver dit_stub_dai = { diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 83acbdbb8e0d..6d8847848299 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -409,8 +409,8 @@ static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) bool invert_fclk; int ret; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -721,7 +721,6 @@ static const struct snd_soc_component_driver ssm2518_component_driver = { .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ssm2518_regmap_config = { diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 7964e922b07f..cbbe83b85ada 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -411,11 +411,11 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int iface = 0; /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface |= 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -624,7 +624,6 @@ static const struct snd_soc_component_driver soc_component_dev_ssm2602 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 08ced09ef001..4b0265617c7b 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -278,8 +278,8 @@ static int ssm4567_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int ctrl1 = 0; bool invert_fclk; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -427,7 +427,6 @@ static const struct snd_soc_component_driver ssm4567_component_driver = { .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ssm4567_regmap_config = { diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 8585cbef4c9b..8c86b578eba8 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -601,8 +601,8 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai, struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component); u8 confb = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -1014,7 +1014,6 @@ static const struct snd_soc_component_driver sta32x_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sta32x_regmap = { diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index 9189fb3648f7..7b2c5b57d5d4 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -630,8 +630,8 @@ static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai, struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component); unsigned int confb = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -1057,7 +1057,6 @@ static const struct snd_soc_component_driver sta350_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sta350_regmap = { diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index d90e5512a731..313957099145 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -322,7 +322,6 @@ static const struct snd_soc_component_driver sta529_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sta529_regmap = { diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index d99f6e466d0a..1824a71fe053 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -313,8 +313,6 @@ static const struct snd_soc_component_driver soc_component_dev_stac9766 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; static int stac9766_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index 3be4940e3c77..f076878908ee 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -199,10 +199,10 @@ static int stih407_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream) static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { dev_err(dai->component->dev, - "%s: ERROR: Unsupporter master mask 0x%x\n", - __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); + "%s: ERROR: Unsupported clocking mask 0x%x\n", + __func__, fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK); return -EINVAL; } @@ -398,7 +398,6 @@ static struct snd_soc_component_driver sti_sas_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id sti_sas_dev_match[] = { diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index b5c9c61ff5a8..8bd667da8767 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -347,17 +347,17 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct tas2552_data *tas2552 = dev_get_drvdata(component->dev); u8 serial_format; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: serial_format = 0x00; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: serial_format = TAS2552_WCLKDIR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: serial_format = TAS2552_BCLKDIR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR); break; default: @@ -581,7 +581,7 @@ static int tas2552_component_probe(struct snd_soc_component *component) gpiod_set_value(tas2552->enable_gpio, 1); - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0) { dev_err(component->dev, "Enabling device failed: %d\n", ret); @@ -668,7 +668,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas2552 = { .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config tas2552_regmap_config = { diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c index e62a3da16aed..dc088a1c6721 100644 --- a/sound/soc/codecs/tas2562.c +++ b/sound/soc/codecs/tas2562.c @@ -589,7 +589,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas2110 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = { @@ -629,7 +628,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas2562 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops tas2562_speaker_dai_ops = { diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index 4cb788f3e5f7..846d9d3ecc9d 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -558,7 +558,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = { .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct reg_default tas2764_reg_defaults[] = { diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index c1dbd978d550..3cb634c28261 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -340,11 +340,11 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; int ret; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: - dev_err(tas2770->dev, "ASI format master is not found\n"); + dev_err(tas2770->dev, "ASI invalid DAI clocking\n"); return -EINVAL; } @@ -546,7 +546,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2770 = { .num_dapm_routes = ARRAY_SIZE(tas2770_audio_map), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int tas2770_register_codec(struct tas2770_priv *tas2770) diff --git a/sound/soc/codecs/tas2780.c b/sound/soc/codecs/tas2780.c new file mode 100644 index 000000000000..a6db6f0e5431 --- /dev/null +++ b/sound/soc/codecs/tas2780.c @@ -0,0 +1,663 @@ +// SPDX-License-Identifier: GPL-2.0 +// Driver for the Texas Instruments TAS2780 Mono +// Audio amplifier +// Copyright (C) 2022 Texas Instruments Inc. + +#include <linux/module.h> +#include <linux/err.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/regmap.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <sound/soc.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/tlv.h> + +#include "tas2780.h" + +struct tas2780_priv { + struct snd_soc_component *component; + struct gpio_desc *reset_gpio; + struct regmap *regmap; + struct device *dev; + int v_sense_slot; + int i_sense_slot; +}; + +static void tas2780_reset(struct tas2780_priv *tas2780) +{ + int ret = 0; + + if (tas2780->reset_gpio) { + gpiod_set_value_cansleep(tas2780->reset_gpio, 0); + usleep_range(2000, 2050); + gpiod_set_value_cansleep(tas2780->reset_gpio, 1); + usleep_range(2000, 2050); + } + + snd_soc_component_write(tas2780->component, TAS2780_SW_RST, + TAS2780_RST); + if (ret) + dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n", + __func__, ret); +} + +#ifdef CONFIG_PM +static int tas2780_codec_suspend(struct snd_soc_component *component) +{ + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, + TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_SHUTDOWN); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n", + __func__, ret); + goto err; + } + ret = 0; + regcache_cache_only(tas2780->regmap, true); + regcache_mark_dirty(tas2780->regmap); +err: + return ret; +} + +static int tas2780_codec_resume(struct snd_soc_component *component) +{ + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, + TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_ACTIVE); + + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n", + __func__, ret); + goto err; + } + ret = 0; + regcache_cache_only(tas2780->regmap, false); + ret = regcache_sync(tas2780->regmap); +err: + return ret; +} +#endif + +static const char * const tas2780_ASI1_src[] = { + "I2C offset", "Left", "Right", "LeftRightDiv2", +}; + +static SOC_ENUM_SINGLE_DECL( + tas2780_ASI1_src_enum, TAS2780_TDM_CFG2, 4, tas2780_ASI1_src); + +static const struct snd_kcontrol_new tas2780_asi1_mux = + SOC_DAPM_ENUM("ASI1 Source", tas2780_ASI1_src_enum); + +static const struct snd_kcontrol_new isense_switch = + SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL, + TAS2780_ISENSE_POWER_EN, 1, 1); +static const struct snd_kcontrol_new vsense_switch = + SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL, + TAS2780_VSENSE_POWER_EN, 1, 1); + +static const struct snd_soc_dapm_widget tas2780_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2780_asi1_mux), + SND_SOC_DAPM_SWITCH("ISENSE", TAS2780_PWR_CTRL, + TAS2780_ISENSE_POWER_EN, 1, &isense_switch), + SND_SOC_DAPM_SWITCH("VSENSE", TAS2780_PWR_CTRL, + TAS2780_VSENSE_POWER_EN, 1, &vsense_switch), + SND_SOC_DAPM_OUTPUT("OUT"), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON") +}; + +static const struct snd_soc_dapm_route tas2780_audio_map[] = { + {"ASI1 Sel", "I2C offset", "ASI1"}, + {"ASI1 Sel", "Left", "ASI1"}, + {"ASI1 Sel", "Right", "ASI1"}, + {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, + {"OUT", NULL, "ASI1 Sel"}, + {"ISENSE", "Switch", "IMON"}, + {"VSENSE", "Switch", "VMON"}, +}; + +static int tas2780_mute(struct snd_soc_dai *dai, int mute, int direction) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, + TAS2780_PWR_CTRL_MASK, + mute ? TAS2780_PWR_CTRL_MUTE : 0); + if (ret < 0) { + dev_err(tas2780->dev, "%s: Failed to set powercontrol\n", + __func__); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_set_bitwidth(struct tas2780_priv *tas2780, int bitwidth) +{ + struct snd_soc_component *component = tas2780->component; + int sense_en; + int val; + int ret; + int slot_size; + + switch (bitwidth) { + case SNDRV_PCM_FORMAT_S16_LE: + ret = snd_soc_component_update_bits(component, + TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXW_MASK, + TAS2780_TDM_CFG2_RXW_16BITS); + slot_size = TAS2780_TDM_CFG2_RXS_16BITS; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ret = snd_soc_component_update_bits(component, + TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXW_MASK, + TAS2780_TDM_CFG2_RXW_24BITS); + slot_size = TAS2780_TDM_CFG2_RXS_24BITS; + break; + case SNDRV_PCM_FORMAT_S32_LE: + ret = snd_soc_component_update_bits(component, + TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXW_MASK, + TAS2780_TDM_CFG2_RXW_32BITS); + slot_size = TAS2780_TDM_CFG2_RXS_32BITS; + break; + + default: + ret = -EINVAL; + } + + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x set bitwidth error\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXS_MASK, slot_size); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x set RX slot size error\n", + __func__, ret); + goto err; + } + + val = snd_soc_component_read(tas2780->component, TAS2780_PWR_CTRL); + if (val < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x read PWR_CTRL error\n", + __func__, val); + ret = val; + goto err; + } + + if (val & (1 << TAS2780_VSENSE_POWER_EN)) + sense_en = 0; + else + sense_en = TAS2780_TDM_CFG5_VSNS_ENABLE; + + ret = snd_soc_component_update_bits(tas2780->component, + TAS2780_TDM_CFG5, TAS2780_TDM_CFG5_VSNS_ENABLE, sense_en); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x enable vSNS error\n", + __func__, ret); + goto err; + } + + if (val & (1 << TAS2780_ISENSE_POWER_EN)) + sense_en = 0; + else + sense_en = TAS2780_TDM_CFG6_ISNS_ENABLE; + + ret = snd_soc_component_update_bits(tas2780->component, + TAS2780_TDM_CFG6, TAS2780_TDM_CFG6_ISNS_ENABLE, sense_en); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x enable iSNS error\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_set_samplerate( + struct tas2780_priv *tas2780, int samplerate) +{ + struct snd_soc_component *component = tas2780->component; + int ramp_rate_val; + int ret; + + switch (samplerate) { + case 48000: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ | + TAS2780_TDM_CFG0_44_1_48KHZ; + break; + case 44100: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ | + TAS2780_TDM_CFG0_44_1_48KHZ; + break; + case 96000: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ | + TAS2780_TDM_CFG0_88_2_96KHZ; + break; + case 88200: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ | + TAS2780_TDM_CFG0_88_2_96KHZ; + break; + default: + return -EINVAL; + } + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG0, + TAS2780_TDM_CFG0_SMP_MASK | TAS2780_TDM_CFG0_MASK, + ramp_rate_val); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set ramp_rate_val\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret; + + ret = tas2780_set_bitwidth(tas2780, params_format(params)); + if (ret < 0) + return ret; + + return tas2780_set_samplerate(tas2780, params_rate(params)); +} + +static int tas2780_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; + int iface; + int ret = 0; + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + asi_cfg_1 = TAS2780_TDM_CFG1_RX_RISING; + break; + case SND_SOC_DAIFMT_IB_NF: + asi_cfg_1 = TAS2780_TDM_CFG1_RX_FALLING; + break; + default: + dev_err(tas2780->dev, "ASI format Inverse is not found\n"); + return -EINVAL; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1, + TAS2780_TDM_CFG1_RX_MASK, asi_cfg_1); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set asi_cfg_1\n", + __func__, ret); + goto err; + } + + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) + || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) + == SND_SOC_DAIFMT_DSP_A)){ + iface = TAS2780_TDM_CFG2_SCFG_I2S; + tdm_rx_start_slot = 1; + } else { + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) + == SND_SOC_DAIFMT_DSP_B) + || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) + == SND_SOC_DAIFMT_LEFT_J)) { + iface = TAS2780_TDM_CFG2_SCFG_LEFT_J; + tdm_rx_start_slot = 0; + } else { + dev_err(tas2780->dev, + "%s:DAI Format is not found, fmt=0x%x\n", + __func__, fmt); + ret = -EINVAL; + goto err; + } + } + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1, + TAS2780_TDM_CFG1_MASK, + (tdm_rx_start_slot << TAS2780_TDM_CFG1_51_SHIFT)); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set tdm_rx_start_slot\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_SCFG_MASK, iface); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x Failed to set iface\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, + unsigned int rx_mask, + int slots, int slot_width) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int left_slot, right_slot; + int slots_cfg; + int slot_size; + int ret = 0; + + if (tx_mask == 0 || rx_mask != 0) + return -EINVAL; + + if (slots == 1) { + if (tx_mask != 1) + return -EINVAL; + left_slot = 0; + right_slot = 0; + } else { + left_slot = __ffs(tx_mask); + tx_mask &= ~(1 << left_slot); + if (tx_mask == 0) { + right_slot = left_slot; + } else { + right_slot = __ffs(tx_mask); + tx_mask &= ~(1 << right_slot); + } + } + + if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) + return -EINVAL; + + slots_cfg = (right_slot << TAS2780_TDM_CFG3_RXS_SHIFT) | left_slot; + ret = snd_soc_component_write(component, TAS2780_TDM_CFG3, slots_cfg); + if (ret) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set slots_cfg\n", + __func__, ret); + goto err; + } + + switch (slot_width) { + case 16: + slot_size = TAS2780_TDM_CFG2_RXS_16BITS; + break; + case 24: + slot_size = TAS2780_TDM_CFG2_RXS_24BITS; + break; + case 32: + slot_size = TAS2780_TDM_CFG2_RXS_32BITS; + break; + default: + ret = -EINVAL; + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXS_MASK, slot_size); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set slot_size\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG5, + TAS2780_TDM_CFG5_50_MASK, tas2780->v_sense_slot); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set v_sense_slot\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG6, + TAS2780_TDM_CFG6_50_MASK, tas2780->i_sense_slot); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set i_sense_slot\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static const struct snd_soc_dai_ops tas2780_dai_ops = { + .mute_stream = tas2780_mute, + .hw_params = tas2780_hw_params, + .set_fmt = tas2780_set_fmt, + .set_tdm_slot = tas2780_set_dai_tdm_slot, + .no_capture_mute = 1, +}; + +#define TAS2780_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +#define TAS2780_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) + +static struct snd_soc_dai_driver tas2780_dai_driver[] = { + { + .name = "tas2780 ASI1", + .id = 0, + .playback = { + .stream_name = "ASI1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = TAS2780_RATES, + .formats = TAS2780_FORMATS, + }, + .capture = { + .stream_name = "ASI1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = TAS2780_RATES, + .formats = TAS2780_FORMATS, + }, + .ops = &tas2780_dai_ops, + .symmetric_rate = 1, + }, +}; + +static int tas2780_codec_probe(struct snd_soc_component *component) +{ + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + tas2780->component = component; + + tas2780_reset(tas2780); + ret = snd_soc_component_update_bits(component, + TAS2780_IC_CFG, TAS2780_IC_CFG_MASK, + TAS2780_IC_CFG_ENABLE); + if (ret < 0) + dev_err(tas2780->dev, "%s:errCode:0x%0x\n", + __func__, ret); + + return ret; +} + +static DECLARE_TLV_DB_SCALE(tas2780_digital_tlv, 1100, 50, 0); +static DECLARE_TLV_DB_SCALE(tas2780_playback_volume, -10000, 50, 0); + +static const struct snd_kcontrol_new tas2780_snd_controls[] = { + SOC_SINGLE_TLV("Speaker Volume", TAS2780_DVC, 0, + TAS2780_DVC_MAX, 1, tas2780_playback_volume), + SOC_SINGLE_TLV("Amp Gain Volume", TAS2780_CHNL_0, 0, 0x14, 0, + tas2780_digital_tlv), +}; + +static const struct snd_soc_component_driver soc_component_driver_tas2780 = { + .probe = tas2780_codec_probe, +#ifdef CONFIG_PM + .suspend = tas2780_codec_suspend, + .resume = tas2780_codec_resume, +#endif + .controls = tas2780_snd_controls, + .num_controls = ARRAY_SIZE(tas2780_snd_controls), + .dapm_widgets = tas2780_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tas2780_dapm_widgets), + .dapm_routes = tas2780_audio_map, + .num_dapm_routes = ARRAY_SIZE(tas2780_audio_map), + .idle_bias_on = 1, + .endianness = 1, +}; + +static const struct reg_default tas2780_reg_defaults[] = { + { TAS2780_PAGE, 0x00 }, + { TAS2780_SW_RST, 0x00 }, + { TAS2780_PWR_CTRL, 0x1a }, + { TAS2780_DVC, 0x00 }, + { TAS2780_CHNL_0, 0x00 }, + { TAS2780_TDM_CFG0, 0x09 }, + { TAS2780_TDM_CFG1, 0x02 }, + { TAS2780_TDM_CFG2, 0x0a }, + { TAS2780_TDM_CFG3, 0x10 }, + { TAS2780_TDM_CFG5, 0x42 }, +}; + +static const struct regmap_range_cfg tas2780_regmap_ranges[] = { + { + .range_min = 0, + .range_max = 1 * 128, + .selector_reg = TAS2780_PAGE, + .selector_mask = 0xff, + .selector_shift = 0, + .window_start = 0, + .window_len = 128, + }, +}; + +static const struct regmap_config tas2780_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .reg_defaults = tas2780_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tas2780_reg_defaults), + .cache_type = REGCACHE_RBTREE, + .ranges = tas2780_regmap_ranges, + .num_ranges = ARRAY_SIZE(tas2780_regmap_ranges), + .max_register = 1 * 128, +}; + +static int tas2780_parse_dt(struct device *dev, struct tas2780_priv *tas2780) +{ + int ret = 0; + + tas2780->reset_gpio = devm_gpiod_get_optional(tas2780->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(tas2780->reset_gpio)) { + if (PTR_ERR(tas2780->reset_gpio) == -EPROBE_DEFER) { + tas2780->reset_gpio = NULL; + return -EPROBE_DEFER; + } + } + + ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", + &tas2780->i_sense_slot); + if (ret) + tas2780->i_sense_slot = 0; + + ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", + &tas2780->v_sense_slot); + if (ret) + tas2780->v_sense_slot = 2; + + return 0; +} + +static int tas2780_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tas2780_priv *tas2780; + int result; + + tas2780 = devm_kzalloc(&client->dev, sizeof(struct tas2780_priv), + GFP_KERNEL); + if (!tas2780) + return -ENOMEM; + tas2780->dev = &client->dev; + i2c_set_clientdata(client, tas2780); + dev_set_drvdata(&client->dev, tas2780); + + tas2780->regmap = devm_regmap_init_i2c(client, &tas2780_i2c_regmap); + if (IS_ERR(tas2780->regmap)) { + result = PTR_ERR(tas2780->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + result); + return result; + } + + if (client->dev.of_node) { + result = tas2780_parse_dt(&client->dev, tas2780); + if (result) { + dev_err(tas2780->dev, + "%s: Failed to parse devicetree\n", __func__); + return result; + } + } + + return devm_snd_soc_register_component(tas2780->dev, + &soc_component_driver_tas2780, tas2780_dai_driver, + ARRAY_SIZE(tas2780_dai_driver)); +} + +static const struct i2c_device_id tas2780_i2c_id[] = { + { "tas2780", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, tas2780_i2c_id); + +#if defined(CONFIG_OF) +static const struct of_device_id tas2780_of_match[] = { + { .compatible = "ti,tas2780" }, + {}, +}; +MODULE_DEVICE_TABLE(of, tas2780_of_match); +#endif + +static struct i2c_driver tas2780_i2c_driver = { + .driver = { + .name = "tas2780", + .of_match_table = of_match_ptr(tas2780_of_match), + }, + .probe = tas2780_i2c_probe, + .id_table = tas2780_i2c_id, +}; +module_i2c_driver(tas2780_i2c_driver); + +MODULE_AUTHOR("Raphael Xu <raphael-xu@ti.com>"); +MODULE_DESCRIPTION("TAS2780 I2C Smart Amplifier driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tas2780.h b/sound/soc/codecs/tas2780.h new file mode 100644 index 000000000000..661c25df4e29 --- /dev/null +++ b/sound/soc/codecs/tas2780.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * TAS2780.h - ALSA SoC Texas Instruments TAS2780 Mono Audio Amplifier + * + * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com + * + * Author: Raphael Xu <raphael-xu@ti.com> + */ + +#ifndef __TAS2780_H__ +#define __TAS2780_H__ + +/* Book Control Register */ +#define TAS2780_BOOKCTL_PAGE 0 +#define TAS2780_BOOKCTL_REG 127 +#define TAS2780_REG(page, reg) ((page * 128) + reg) + +/* Page */ +#define TAS2780_PAGE TAS2780_REG(0X0, 0x00) +#define TAS2780_PAGE_PAGE_MASK 255 + +/* Software Reset */ +#define TAS2780_SW_RST TAS2780_REG(0X0, 0x01) +#define TAS2780_RST BIT(0) + +/* Power Control */ +#define TAS2780_PWR_CTRL TAS2780_REG(0X0, 0x02) +#define TAS2780_PWR_CTRL_MASK GENMASK(1, 0) +#define TAS2780_PWR_CTRL_ACTIVE 0x0 +#define TAS2780_PWR_CTRL_MUTE BIT(0) +#define TAS2780_PWR_CTRL_SHUTDOWN BIT(1) + +#define TAS2780_VSENSE_POWER_EN 3 +#define TAS2780_ISENSE_POWER_EN 4 + +/* Digital Volume Control */ +#define TAS2780_DVC TAS2780_REG(0X0, 0x1a) +#define TAS2780_DVC_MAX 0xc9 + +#define TAS2780_CHNL_0 TAS2780_REG(0X0, 0x03) + +/* TDM Configuration Reg0 */ +#define TAS2780_TDM_CFG0 TAS2780_REG(0X0, 0x08) +#define TAS2780_TDM_CFG0_SMP_MASK BIT(5) +#define TAS2780_TDM_CFG0_SMP_48KHZ 0x0 +#define TAS2780_TDM_CFG0_SMP_44_1KHZ BIT(5) +#define TAS2780_TDM_CFG0_MASK GENMASK(3, 1) +#define TAS2780_TDM_CFG0_44_1_48KHZ BIT(3) +#define TAS2780_TDM_CFG0_88_2_96KHZ (BIT(3) | BIT(1)) + +/* TDM Configuration Reg1 */ +#define TAS2780_TDM_CFG1 TAS2780_REG(0X0, 0x09) +#define TAS2780_TDM_CFG1_MASK GENMASK(5, 1) +#define TAS2780_TDM_CFG1_51_SHIFT 1 +#define TAS2780_TDM_CFG1_RX_MASK BIT(0) +#define TAS2780_TDM_CFG1_RX_RISING 0x0 +#define TAS2780_TDM_CFG1_RX_FALLING BIT(0) + +/* TDM Configuration Reg2 */ +#define TAS2780_TDM_CFG2 TAS2780_REG(0X0, 0x0a) +#define TAS2780_TDM_CFG2_RXW_MASK GENMASK(3, 2) +#define TAS2780_TDM_CFG2_RXW_16BITS 0x0 +#define TAS2780_TDM_CFG2_RXW_24BITS BIT(3) +#define TAS2780_TDM_CFG2_RXW_32BITS (BIT(3) | BIT(2)) +#define TAS2780_TDM_CFG2_RXS_MASK GENMASK(1, 0) +#define TAS2780_TDM_CFG2_RXS_16BITS 0x0 +#define TAS2780_TDM_CFG2_RXS_24BITS BIT(0) +#define TAS2780_TDM_CFG2_RXS_32BITS BIT(1) +#define TAS2780_TDM_CFG2_SCFG_MASK GENMASK(5, 4) +#define TAS2780_TDM_CFG2_SCFG_I2S 0x0 +#define TAS2780_TDM_CFG2_SCFG_LEFT_J BIT(4) +#define TAS2780_TDM_CFG2_SCFG_RIGHT_J BIT(5) + +/* TDM Configuration Reg3 */ +#define TAS2780_TDM_CFG3 TAS2780_REG(0X0, 0x0c) +#define TAS2780_TDM_CFG3_RXS_MASK GENMASK(7, 4) +#define TAS2780_TDM_CFG3_RXS_SHIFT 0x4 +#define TAS2780_TDM_CFG3_MASK GENMASK(3, 0) + +/* TDM Configuration Reg4 */ +#define TAS2780_TDM_CFG4 TAS2780_REG(0X0, 0x0d) +#define TAS2780_TDM_CFG4_TX_OFFSET_MASK GENMASK(3, 1) + +/* TDM Configuration Reg5 */ +#define TAS2780_TDM_CFG5 TAS2780_REG(0X0, 0x0e) +#define TAS2780_TDM_CFG5_VSNS_MASK BIT(6) +#define TAS2780_TDM_CFG5_VSNS_ENABLE BIT(6) +#define TAS2780_TDM_CFG5_50_MASK GENMASK(5, 0) + +/* TDM Configuration Reg6 */ +#define TAS2780_TDM_CFG6 TAS2780_REG(0X0, 0x0f) +#define TAS2780_TDM_CFG6_ISNS_MASK BIT(6) +#define TAS2780_TDM_CFG6_ISNS_ENABLE BIT(6) +#define TAS2780_TDM_CFG6_50_MASK GENMASK(5, 0) + +/* IC CFG */ +#define TAS2780_IC_CFG TAS2780_REG(0X0, 0x5c) +#define TAS2780_IC_CFG_MASK GENMASK(7, 6) +#define TAS2780_IC_CFG_ENABLE (BIT(7) | BIT(6)) + +#endif /* __TAS2780_H__ */ diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 5c0df3cd4832..a864984225bc 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -318,7 +318,7 @@ static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai, struct tas5086_private *priv = snd_soc_component_get_drvdata(component); /* The TAS5086 can only be slave to all clocks */ - if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { + if ((format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { dev_err(component->dev, "Invalid clocking mode\n"); return -EINVAL; } @@ -888,7 +888,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas5086 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id tas5086_i2c_id[] = { diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index 7b599664db20..4e7f20db57c4 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -756,7 +756,6 @@ static const struct snd_soc_component_driver tas571x_component = { .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver tas571x_dai = { diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index 17034abef568..3885c0bf0b01 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c @@ -89,8 +89,8 @@ static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) u8 serial_format; int ret; - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { - dev_vdbg(component->dev, "DAI Format master is not found\n"); + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { + dev_vdbg(component->dev, "DAI clocking invalid\n"); return -EINVAL; } @@ -572,7 +572,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas5720 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_component_dev_tas5722 = { @@ -589,7 +588,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas5722 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* PCM rates supported by the TAS5720 driver */ diff --git a/sound/soc/codecs/tas5805m.c b/sound/soc/codecs/tas5805m.c index fa0e81ec875a..b1bb614534f7 100644 --- a/sound/soc/codecs/tas5805m.c +++ b/sound/soc/codecs/tas5805m.c @@ -367,7 +367,6 @@ static const struct snd_soc_component_driver soc_codec_dev_tas5805m = { .num_dapm_routes = ARRAY_SIZE(tas5805m_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction) diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c index 22b53856e691..63d2983c3fcf 100644 --- a/sound/soc/codecs/tas6424.c +++ b/sound/soc/codecs/tas6424.c @@ -160,11 +160,11 @@ static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) dev_dbg(component->dev, "%s() fmt=0x%0x\n", __func__, fmt); /* clock masters */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: - dev_err(component->dev, "Invalid DAI master/slave interface\n"); + dev_err(component->dev, "Invalid DAI clocking\n"); return -EINVAL; } @@ -375,7 +375,6 @@ static struct snd_soc_component_driver soc_codec_dev_tas6424 = { .num_dapm_routes = ARRAY_SIZE(tas6424_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops tas6424_speaker_dai_ops = { diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c index 3d8e8c2276f0..9f7902ec40db 100644 --- a/sound/soc/codecs/tfa9879.c +++ b/sound/soc/codecs/tfa9879.c @@ -111,8 +111,8 @@ static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) int i2s_set; int sck_pol; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -235,7 +235,6 @@ static const struct snd_soc_component_driver tfa9879_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config tfa9879_regmap = { diff --git a/sound/soc/codecs/tfa989x.c b/sound/soc/codecs/tfa989x.c index dc86852752c5..1c27429b9af6 100644 --- a/sound/soc/codecs/tfa989x.c +++ b/sound/soc/codecs/tfa989x.c @@ -40,12 +40,14 @@ #define TFA989X_I2S_SEL_REG 0x0a #define TFA989X_I2S_SEL_REG_SPKR_MSK GENMASK(10, 9) /* speaker impedance */ #define TFA989X_I2S_SEL_REG_DCFG_MSK GENMASK(14, 11) /* DCDC compensation */ +#define TFA989X_HIDE_UNHIDE_KEY 0x40 #define TFA989X_PWM_CONTROL 0x41 #define TFA989X_CURRENTSENSE1 0x46 #define TFA989X_CURRENTSENSE2 0x47 #define TFA989X_CURRENTSENSE3 0x48 #define TFA989X_CURRENTSENSE4 0x49 +#define TFA9890_REVISION 0x80 #define TFA9895_REVISION 0x12 #define TFA9897_REVISION 0x97 @@ -136,7 +138,6 @@ static const struct snd_soc_component_driver tfa989x_component = { .num_dapm_routes = ARRAY_SIZE(tfa989x_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const unsigned int tfa989x_rates[] = { @@ -188,6 +189,33 @@ static struct snd_soc_dai_driver tfa989x_dai = { .ops = &tfa989x_dai_ops, }; +static int tfa9890_init(struct regmap *regmap) +{ + int ret; + + /* unhide keys to allow updating them */ + ret = regmap_write(regmap, TFA989X_HIDE_UNHIDE_KEY, 0x5a6b); + if (ret) + return ret; + + /* update PLL registers */ + ret = regmap_set_bits(regmap, 0x59, 0x3); + if (ret) + return ret; + + /* hide keys again */ + ret = regmap_write(regmap, TFA989X_HIDE_UNHIDE_KEY, 0x0000); + if (ret) + return ret; + + return regmap_write(regmap, TFA989X_CURRENTSENSE2, 0x7BE1); +} + +static const struct tfa989x_rev tfa9890_rev = { + .rev = TFA9890_REVISION, + .init = tfa9890_init, +}; + static const struct reg_sequence tfa9895_reg_init[] = { /* some other registers must be set for optimal amplifier behaviour */ { TFA989X_BAT_PROT, 0x13ab }, @@ -376,6 +404,7 @@ static int tfa989x_i2c_probe(struct i2c_client *i2c) } static const struct of_device_id tfa989x_of_match[] = { + { .compatible = "nxp,tfa9890", .data = &tfa9890_rev }, { .compatible = "nxp,tfa9895", .data = &tfa9895_rev }, { .compatible = "nxp,tfa9897", .data = &tfa9897_rev }, { } diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c index 82532ad00c3c..748998e48af9 100644 --- a/sound/soc/codecs/tlv320adc3xxx.c +++ b/sound/soc/codecs/tlv320adc3xxx.c @@ -1252,8 +1252,7 @@ static int adc3xxx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) int master = 0; int ret; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { case SND_SOC_DAIFMT_CBP_CFP: master = 1; clkdir = ADC3XXX_BCLK_MASTER | ADC3XXX_WCLK_MASTER; diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 0b729658fde8..2844a9d2bc4a 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -712,16 +712,14 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, bool inverted_bclk = false; /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg2 |= ADCX140_BCLK_FSYNC_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: default: - dev_err(component->dev, "Invalid DAI master/slave interface\n"); + dev_err(component->dev, "Invalid DAI clock provider\n"); return -EINVAL; } @@ -1054,7 +1052,6 @@ static const struct snd_soc_component_driver soc_codec_driver_adcx140 = { .idle_bias_on = 0, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver adcx140_dai_driver[] = { diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 2400093e2c99..c47aa4d4162d 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -429,12 +429,11 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_reg = snd_soc_component_read(component, TLV320AIC23_DIGT_FMT) & (~0x03); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg |= TLV320AIC23_MS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: iface_reg &= ~TLV320AIC23_MS_MASTER; break; default: @@ -587,7 +586,6 @@ static const struct snd_soc_component_driver soc_component_dev_tlv320aic23 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int tlv320aic23_probe(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 077415a57225..8bae4b475068 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -32,7 +32,7 @@ struct aic26 { struct spi_device *spi; struct regmap *regmap; struct snd_soc_component *component; - int master; + int clock_provider; int datfm; int mclk; @@ -117,8 +117,8 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, reg = dval << 2; snd_soc_component_write(component, AIC26_REG_PLL_PROG2, reg); - /* Audio Control 3 (master mode, fsref rate) */ - if (aic26->master) + /* Audio Control 3 (clock provider mode, fsref rate) */ + if (aic26->clock_provider) reg = 0x0800; if (fsref == 48000) reg = 0x2000; @@ -178,10 +178,9 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n", codec_dai, fmt); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break; + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: aic26->clock_provider = 1; break; + case SND_SOC_DAIFMT_CBC_CFC: aic26->clock_provider = 0; break; default: dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL; } @@ -332,7 +331,6 @@ static const struct snd_soc_component_driver aic26_soc_component_dev = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config aic26_regmap = { @@ -363,7 +361,7 @@ static int aic26_spi_probe(struct spi_device *spi) /* Initialize the driver data */ aic26->spi = spi; dev_set_drvdata(&spi->dev, aic26); - aic26->master = 1; + aic26->clock_provider = 1; ret = devm_snd_soc_register_component(&spi->dev, &aic26_soc_component_dev, &aic26_dai, 1); diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index b2e59581c17a..0847302121f6 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1033,8 +1033,8 @@ static int aic31xx_clock_master_routes(struct snd_soc_component *component, struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component); int ret; - fmt &= SND_SOC_DAIFMT_MASTER_MASK; - if (fmt == SND_SOC_DAIFMT_CBS_CFS && + fmt &= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; + if (fmt == SND_SOC_DAIFMT_CBC_CFC && aic31xx->master_dapm_route_applied) { /* * Remove the DAPM route(s) for codec clock master modes, @@ -1051,7 +1051,7 @@ static int aic31xx_clock_master_routes(struct snd_soc_component *component, return ret; aic31xx->master_dapm_route_applied = false; - } else if (fmt != SND_SOC_DAIFMT_CBS_CFS && + } else if (fmt != SND_SOC_DAIFMT_CBC_CFC && !aic31xx->master_dapm_route_applied) { /* * Add the needed DAPM route(s) for codec clock master modes, @@ -1083,21 +1083,20 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, dev_dbg(component->dev, "## %s: fmt = 0x%x\n", __func__, fmt); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: iface_reg1 |= AIC31XX_WCLK_MASTER; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: iface_reg1 |= AIC31XX_BCLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: - dev_err(component->dev, "Invalid DAI master/slave interface\n"); + dev_err(component->dev, "Invalid DAI clock provider\n"); return -EINVAL; } @@ -1418,7 +1417,6 @@ static const struct snd_soc_component_driver soc_codec_driver_aic31xx = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops aic31xx_dai_ops = { diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 8f42fd7bc053..4b74805cdd2e 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -615,15 +615,14 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 iface_reg_2 = 0; u8 iface_reg_3 = 0; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: - printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); + printk(KERN_ERR "aic32x4: invalid clock provider\n"); return -EINVAL; } @@ -1078,7 +1077,6 @@ static const struct snd_soc_component_driver soc_component_dev_aic32x4 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_kcontrol_new aic32x4_tas2505_snd_controls[] = { @@ -1200,7 +1198,6 @@ static const struct snd_soc_component_driver soc_component_dev_aic32x4_tas2505 = .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index d53037b1509d..08938801daec 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1253,22 +1253,21 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_areg = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLA) & 0x3f; iface_breg = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLB) & 0x3f; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: aic3x->master = 1; iface_areg |= BIT_CLK_MASTER | WORD_CLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: aic3x->master = 0; iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER); break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: aic3x->master = 1; iface_areg |= BIT_CLK_MASTER; iface_areg &= ~WORD_CLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: aic3x->master = 1; iface_areg |= WORD_CLK_MASTER; iface_areg &= ~BIT_CLK_MASTER; @@ -1698,7 +1697,6 @@ static const struct snd_soc_component_driver soc_component_dev_aic3x = { .num_dapm_routes = ARRAY_SIZE(intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void aic3x_configure_ocmv(struct device *dev, struct aic3x_priv *aic3x) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 66f1d1cd6cf0..17ae3b1d96fb 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1317,16 +1317,14 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai, aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A); aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - /* Codec Master */ + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK); break; - case SND_SOC_DAIFMT_CBS_CFS: - /* Codec Slave */ + case SND_SOC_DAIFMT_CBC_CFC: if (dac33->fifo_mode) { - dev_err(component->dev, "FIFO mode requires master mode\n"); + dev_err(component->dev, "FIFO mode requires provider mode\n"); return -EINVAL; } else aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK); @@ -1433,7 +1431,6 @@ static const struct snd_soc_component_driver soc_component_dev_tlv320dac33 = { .num_dapm_routes = ARRAY_SIZE(audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c index 4fb0bb01bcdc..fa0c525189c2 100644 --- a/sound/soc/codecs/tscs42xx.c +++ b/sound/soc/codecs/tscs42xx.c @@ -1358,7 +1358,6 @@ static const struct snd_soc_component_driver soc_codec_dev_tscs42xx = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static inline void init_coeff_ram_cache(struct tscs42xx *tscs42xx) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 0ba3546ef870..e48768233e20 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -34,6 +34,14 @@ #define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) +struct twl4030_board_params { + unsigned int digimic_delay; /* in ms */ + unsigned int ramp_delay_value; + unsigned int offset_cncl_path; + unsigned int hs_extmute:1; + int hs_extmute_gpio; +}; + /* codec private data */ struct twl4030_priv { unsigned int codec_powered; @@ -58,7 +66,7 @@ struct twl4030_priv { u8 carkitl_enabled, carkitr_enabled; u8 ctl_cache[TWL4030_REG_PRECKR_CTL - TWL4030_REG_EAR_CTL + 1]; - struct twl4030_codec_data *pdata; + struct twl4030_board_params *board_params; }; static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030) @@ -193,73 +201,71 @@ static void twl4030_codec_enable(struct snd_soc_component *component, int enable udelay(10); } -static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, - struct device_node *node) +static void +twl4030_get_board_param_values(struct twl4030_board_params *board_params, + struct device_node *node) { int value; - of_property_read_u32(node, "ti,digimic_delay", - &pdata->digimic_delay); - of_property_read_u32(node, "ti,ramp_delay_value", - &pdata->ramp_delay_value); - of_property_read_u32(node, "ti,offset_cncl_path", - &pdata->offset_cncl_path); + of_property_read_u32(node, "ti,digimic_delay", &board_params->digimic_delay); + of_property_read_u32(node, "ti,ramp_delay_value", &board_params->ramp_delay_value); + of_property_read_u32(node, "ti,offset_cncl_path", &board_params->offset_cncl_path); if (!of_property_read_u32(node, "ti,hs_extmute", &value)) - pdata->hs_extmute = value; + board_params->hs_extmute = value; - pdata->hs_extmute_gpio = of_get_named_gpio(node, - "ti,hs_extmute_gpio", 0); - if (gpio_is_valid(pdata->hs_extmute_gpio)) - pdata->hs_extmute = 1; + board_params->hs_extmute_gpio = of_get_named_gpio(node, "ti,hs_extmute_gpio", 0); + if (gpio_is_valid(board_params->hs_extmute_gpio)) + board_params->hs_extmute = 1; } -static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_component *component) +static struct twl4030_board_params* +twl4030_get_board_params(struct snd_soc_component *component) { - struct twl4030_codec_data *pdata = dev_get_platdata(component->dev); + struct twl4030_board_params *board_params = NULL; struct device_node *twl4030_codec_node = NULL; twl4030_codec_node = of_get_child_by_name(component->dev->parent->of_node, "codec"); - if (!pdata && twl4030_codec_node) { - pdata = devm_kzalloc(component->dev, - sizeof(struct twl4030_codec_data), - GFP_KERNEL); - if (!pdata) { + if (twl4030_codec_node) { + board_params = devm_kzalloc(component->dev, + sizeof(struct twl4030_board_params), + GFP_KERNEL); + if (!board_params) { of_node_put(twl4030_codec_node); return NULL; } - twl4030_setup_pdata_of(pdata, twl4030_codec_node); + twl4030_get_board_param_values(board_params, twl4030_codec_node); of_node_put(twl4030_codec_node); } - return pdata; + return board_params; } static void twl4030_init_chip(struct snd_soc_component *component) { - struct twl4030_codec_data *pdata; + struct twl4030_board_params *board_params; struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); u8 reg, byte; int i = 0; - pdata = twl4030_get_pdata(component); + board_params = twl4030_get_board_params(component); - if (pdata && pdata->hs_extmute) { - if (gpio_is_valid(pdata->hs_extmute_gpio)) { + if (board_params && board_params->hs_extmute) { + if (gpio_is_valid(board_params->hs_extmute_gpio)) { int ret; - if (!pdata->hs_extmute_gpio) + if (!board_params->hs_extmute_gpio) dev_warn(component->dev, "Extmute GPIO is 0 is this correct?\n"); - ret = gpio_request_one(pdata->hs_extmute_gpio, + ret = gpio_request_one(board_params->hs_extmute_gpio, GPIOF_OUT_INIT_LOW, "hs_extmute"); if (ret) { dev_err(component->dev, "Failed to get hs_extmute GPIO\n"); - pdata->hs_extmute_gpio = -1; + board_params->hs_extmute_gpio = -1; } } else { u8 pin_mux; @@ -290,14 +296,14 @@ static void twl4030_init_chip(struct snd_soc_component *component) twl4030_write(component, TWL4030_REG_ARXR2_APGA_CTL, 0x32); /* Machine dependent setup */ - if (!pdata) + if (!board_params) return; - twl4030->pdata = pdata; + twl4030->board_params = board_params; reg = twl4030_read(component, TWL4030_REG_HS_POPN_SET); reg &= ~TWL4030_RAMP_DELAY; - reg |= (pdata->ramp_delay_value << 2); + reg |= (board_params->ramp_delay_value << 2); twl4030_write(component, TWL4030_REG_HS_POPN_SET, reg); /* initiate offset cancellation */ @@ -305,7 +311,7 @@ static void twl4030_init_chip(struct snd_soc_component *component) reg = twl4030_read(component, TWL4030_REG_ANAMICL); reg &= ~TWL4030_OFFSET_CNCL_SEL; - reg |= pdata->offset_cncl_path; + reg |= board_params->offset_cncl_path; twl4030_write(component, TWL4030_REG_ANAMICL, reg | TWL4030_CNCL_OFFSET_START); @@ -692,7 +698,7 @@ static void headset_ramp(struct snd_soc_component *component, int ramp) { unsigned char hs_gain, hs_pop; struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); - struct twl4030_codec_data *pdata = twl4030->pdata; + struct twl4030_board_params *board_params = twl4030->board_params; /* Base values for ramp delay calculation: 2^19 - 2^26 */ unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864}; @@ -705,9 +711,9 @@ static void headset_ramp(struct snd_soc_component *component, int ramp) /* Enable external mute control, this dramatically reduces * the pop-noise */ - if (pdata && pdata->hs_extmute) { - if (gpio_is_valid(pdata->hs_extmute_gpio)) { - gpio_set_value(pdata->hs_extmute_gpio, 1); + if (board_params && board_params->hs_extmute) { + if (gpio_is_valid(board_params->hs_extmute_gpio)) { + gpio_set_value(board_params->hs_extmute_gpio, 1); } else { hs_pop |= TWL4030_EXTMUTE; twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop); @@ -741,9 +747,9 @@ static void headset_ramp(struct snd_soc_component *component, int ramp) } /* Disable external mute */ - if (pdata && pdata->hs_extmute) { - if (gpio_is_valid(pdata->hs_extmute_gpio)) { - gpio_set_value(pdata->hs_extmute_gpio, 0); + if (board_params && board_params->hs_extmute) { + if (gpio_is_valid(board_params->hs_extmute_gpio)) { + gpio_set_value(board_params->hs_extmute_gpio, 0); } else { hs_pop &= ~TWL4030_EXTMUTE; twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop); @@ -806,10 +812,10 @@ static int digimic_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); - struct twl4030_codec_data *pdata = twl4030->pdata; + struct twl4030_board_params *board_params = twl4030->board_params; - if (pdata && pdata->digimic_delay) - twl4030_wait_ms(pdata->digimic_delay); + if (board_params && board_params->digimic_delay) + twl4030_wait_ms(board_params->digimic_delay); return 0; } @@ -2168,10 +2174,11 @@ static int twl4030_soc_probe(struct snd_soc_component *component) static void twl4030_soc_remove(struct snd_soc_component *component) { struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); - struct twl4030_codec_data *pdata = twl4030->pdata; + struct twl4030_board_params *board_params = twl4030->board_params; - if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) - gpio_free(pdata->hs_extmute_gpio); + if (board_params && board_params->hs_extmute && + gpio_is_valid(board_params->hs_extmute_gpio)) + gpio_free(board_params->hs_extmute_gpio); } static const struct snd_soc_component_driver soc_component_dev_twl4030 = { @@ -2188,7 +2195,6 @@ static const struct snd_soc_component_driver soc_component_dev_twl4030 = { .num_dapm_routes = ARRAY_SIZE(intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int twl4030_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b37203336c4e..dd5ee5dc0cd7 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1153,7 +1153,6 @@ static const struct snd_soc_component_driver soc_component_dev_twl6040 = { .suspend_bias_off = 1, .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int twl6040_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/uda1334.c b/sound/soc/codecs/uda1334.c index 8670a2a05a56..eace96533600 100644 --- a/sound/soc/codecs/uda1334.c +++ b/sound/soc/codecs/uda1334.c @@ -169,7 +169,7 @@ static int uda1334_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int uda1334_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK | - SND_SOC_DAIFMT_MASTER_MASK); + SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK); if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC)) { @@ -236,7 +236,6 @@ static const struct snd_soc_component_driver soc_component_dev_uda1334 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id uda1334_of_match[] = { diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 037833c509f7..2db3d8a60c7a 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -527,7 +527,6 @@ static const struct snd_soc_component_driver soc_component_dev_uda134x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config uda134x_regmap_config = { diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index b5004842520b..fdaaee845176 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -736,7 +736,6 @@ static const struct snd_soc_component_driver soc_component_dev_uda1380 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int uda1380_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index c53c2ef33e1a..98baef594bf3 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -714,12 +714,11 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) struct snd_soc_component *component = mbhc->component; int ret; - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0 && ret != -EACCES) { dev_err_ratelimited(component->dev, - "pm_runtime_get_sync failed in %s, ret %d\n", + "pm_runtime_resume_and_get failed in %s, ret %d\n", __func__, ret); - pm_runtime_put_noidle(component->dev); return ret; } @@ -1097,12 +1096,11 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); component = mbhc->component; - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0 && ret != -EACCES) { dev_err_ratelimited(component->dev, - "pm_runtime_get_sync failed in %s, ret %d\n", + "pm_runtime_resume_and_get failed in %s, ret %d\n", __func__, ret); - pm_runtime_put_noidle(component->dev); return; } micbias_mv = wcd_mbhc_get_micbias(mbhc); @@ -1306,7 +1304,7 @@ exit: static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) { struct wcd_mbhc *mbhc = data; - u8 clamp_state = 0; + u8 clamp_state; u8 clamp_retry = WCD_MBHC_FAKE_INS_RETRY; /* diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 3cb7a3eab8c7..beeeb35e8032 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -24,6 +24,8 @@ #include "wcd9335.h" #include "wcd-clsh-v2.h" +#include <dt-bindings/sound/qcom,wcd9335.h> + #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) @@ -204,17 +206,6 @@ enum wcd9335_sido_voltage { }; enum { - AIF1_PB = 0, - AIF1_CAP, - AIF2_PB, - AIF2_CAP, - AIF3_PB, - AIF3_CAP, - AIF4_PB, - NUM_CODEC_DAIS, -}; - -enum { COMPANDER_1, /* HPH_L */ COMPANDER_2, /* HPH_R */ COMPANDER_3, /* LO1_DIFF */ @@ -1818,11 +1809,11 @@ static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai, tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0; shift = (tx_port << 1); shift_val = 0x03; - } else if ((tx_port >= 4) && (tx_port < 8)) { + } else if (tx_port < 8) { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1; shift = ((tx_port - 4) << 1); shift_val = 0x03; - } else if ((tx_port >= 8) && (tx_port < 11)) { + } else if (tx_port < 11) { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2; shift = ((tx_port - 8) << 1); shift_val = 0x03; @@ -2264,51 +2255,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, static const struct snd_kcontrol_new wcd9335_snd_controls[] = { /* -84dB min - 40dB max */ - SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", - WCD9335_CDC_RX0_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", - WCD9335_CDC_RX1_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", - WCD9335_CDC_RX2_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", - WCD9335_CDC_RX3_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", - WCD9335_CDC_RX4_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", - WCD9335_CDC_RX5_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", - WCD9335_CDC_RX6_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", - WCD9335_CDC_RX7_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", - WCD9335_CDC_RX8_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL, + -84, 40, digital_gain), SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 02232f64110e..626278e4c923 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -475,7 +475,6 @@ static const struct snd_soc_component_driver soc_component_dev_wl1273 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wl1273_platform_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 1bef1c500c8e..034a4e858c7e 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -789,7 +789,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm0010 = { .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index b6366dea15a6..98343626078b 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c @@ -144,7 +144,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm1250_ev1 = { .set_bias_level = wm1250_ev1_set_bias_level, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm1250_ev1_pdata(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index ede5f2a982a6..14b4fd97488c 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -803,7 +803,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm2000 = { .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), .idle_bias_on = 1, .use_pmdown_time = 1, - .non_legacy_dai_naming = 1, }; static int wm2000_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 1cd544580c83..7b4e162a298c 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -2104,7 +2104,6 @@ static const struct snd_soc_component_driver soc_component_wm2200 = { .dapm_routes = wm2200_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static irqreturn_t wm2200_irq(int irq, void *data) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index a89870918174..35a85ce6b464 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2389,7 +2389,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm5100 = { .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm5100_regmap = { diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b034df47a5ef..af7d324e3352 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2028,7 +2028,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm5102 = { .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm5102_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4ab7a672f8de..f3f4a10bf0f7 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2385,7 +2385,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm5110 = { .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm5110_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 41504ce2a682..66bd281095e1 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1613,7 +1613,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8350 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8350_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index bf5e77c86aed..19ce839f6ef7 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1322,7 +1322,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8400 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8400_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index c6439d25006b..e13f9780a111 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -592,7 +592,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8510 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8510_of_match[] = { diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index ba35a0221dc8..66f6371d8acf 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -422,7 +422,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8523 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8523_of_match[] = { diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c index 81f858f6bd67..b56dcac60244 100644 --- a/sound/soc/codecs/wm8524.c +++ b/sound/soc/codecs/wm8524.c @@ -203,7 +203,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8524 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8524_of_match[] = { diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 84020195314d..ca796aa0aeb7 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -966,7 +966,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8580 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8580_regmap = { diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index b68a1ebcd061..383c6796e8a3 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -378,7 +378,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8711 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8711_of_match[] = { diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 1a118b75b539..d6b0a570dd87 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -55,7 +55,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8727 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8727_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 119ff0a1bb35..a3dbdbf40723 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -221,7 +221,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8728 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8728_of_match[] = { diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 2408c4a591d5..d5ab3ba126a6 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -561,7 +561,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8731 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int wm8731_init(struct device *dev, struct wm8731_priv *wm8731) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 5778091d1c09..90b54343370c 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -583,7 +583,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8737 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8737_of_match[] = { diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 871e2c5421b8..c7afa4f2795d 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -528,7 +528,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8741 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8741_of_match[] = { diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 1426fc1f7c5a..2f6ee8d6639f 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -719,7 +719,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8750 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8750_of_match[] = { diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 931134d334ec..bb18f58dc670 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1492,7 +1492,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8753 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8753_of_match[] = { diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 5f394065030d..e03fee8869c3 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -617,7 +617,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8770 = { .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8770_of_match[] = { diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index f164cb6744c4..936ea24621b0 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -436,7 +436,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8776 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8776_of_match[] = { diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index f89855c616eb..95ff4339d103 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -99,7 +99,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8782 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8782_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 21bf0cfa1e7e..0b234bae480e 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -546,7 +546,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8804 = { .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; const struct regmap_config wm8804_regmap_config = { diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 84a3daf0c11e..d6420df3505d 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1214,7 +1214,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8900 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8900_regmap = { diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 3c95c2aea515..54e0a7628cd5 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1893,7 +1893,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8903 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8903_regmap = { diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 04bb8e392497..ca6a01a230af 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2131,7 +2131,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8904 = { .set_bias_level = wm8904_set_bias_level, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8904_regmap = { diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 589394d420ce..8dac9fd88547 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -734,7 +734,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8940 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8940_regmap = { diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 80e3cbd704ee..05ef45672ebc 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -952,7 +952,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8955 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8955_regmap = { diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8c8f32b23083..37956516d997 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -1378,7 +1378,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8960 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8960_regmap = { diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 69eb731dbf4b..7dc6aaf65576 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -895,7 +895,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8961 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8961_regmap = { diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 5cca89364280..398c448ea854 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3502,7 +3502,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8962 = { .set_pll = wm8962_set_fll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Improve power consumption for IN4 DC measurement mode */ diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 8a289b048e66..4db9248de54b 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -659,7 +659,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8971 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8971_regmap = { diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index a8d7809f3f64..010a394c705c 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -682,7 +682,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8974 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8974_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 141f50bfec68..a682f8020eb6 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -1005,7 +1005,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8978 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8978_regmap_config = { diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index ae89554d47bc..50e6ac6ccbe0 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -987,7 +987,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8983 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8983_regmap = { diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index cf2c32eac773..751aa6730833 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1116,7 +1116,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8985 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8985_regmap = { diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 27538d6598cf..5dbdf647cd97 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -823,7 +823,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8988 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8988_regmap = { diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c9448a59c872..589af286f133 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1217,7 +1217,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8990 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8990_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 998bc89bb7e1..30121993b7b4 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1243,7 +1243,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8991 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8991_regmap = { diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index f4da77ec9d6c..8db98b5a06bf 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1621,7 +1621,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8993 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8993_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f117ec0c489f..d3cfd3788f2a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4614,7 +4614,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8994 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8994_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index ea9727446707..eed48bf339f2 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2182,7 +2182,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8995 = { .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8995_regmap = { diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index f7bb27d1c76d..17f307a31046 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2695,8 +2695,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8996 = { .set_pll = wm8996_set_fll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 38ef631d1a1f..210ad662fc26 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1105,7 +1105,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8997 = { .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8997_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index ab5481187c71..79fc6bbaa3aa 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c @@ -1332,7 +1332,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8998 = { .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8998_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 87b58448cea7..d5151877d0fa 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1284,7 +1284,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9081 = { .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm9081_regmap = { diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index f7d80f1e37a8..ef3524c3f07f 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -543,7 +543,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9090 = { .suspend_bias_off = 1, .idle_bias_on = 1, .use_pmdown_time = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm9090_regmap = { diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 99fe8f316624..d04902ef1d5f 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -368,7 +368,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9705 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm9705_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 7515c9d4006e..df9b7980706b 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -692,7 +692,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9712 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm9712_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index e0ce32dd4a81..5d2e54e06e30 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1257,7 +1257,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9713 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm9713_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index a7784ac15dde..cfaa45ede916 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -675,21 +675,12 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { - struct cs_dsp_coeff_ctl *cs_ctl; + struct cs_dsp_coeff_ctl *cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); struct wm_coeff_ctl *ctl; struct snd_kcontrol *kcontrol; char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; int ret; - cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); - if (!cs_ctl) - return -EINVAL; - - ctl = cs_ctl->priv; - - if (len > cs_ctl->len) - return -EINVAL; - ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); if (ret) return ret; @@ -697,6 +688,8 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) return 0; + ctl = cs_ctl->priv; + if (dsp->component->name_prefix) snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s", dsp->component->name_prefix, ctl->name); @@ -720,16 +713,8 @@ EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { - struct cs_dsp_coeff_ctl *cs_ctl; - - cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); - if (!cs_ctl) - return -EINVAL; - - if (len > cs_ctl->len) - return -EINVAL; - - return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); + return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg), + 0, buf, len); } EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index f3a56f3ce487..6c8b1db649b8 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -749,11 +749,9 @@ static int wsa881x_put_pa_gain(struct snd_kcontrol *kc, unsigned int mask = (1 << fls(max)) - 1; int val, ret, min_gain, max_gain; - ret = pm_runtime_get_sync(comp->dev); - if (ret < 0 && ret != -EACCES) { - pm_runtime_put_noidle(comp->dev); + ret = pm_runtime_resume_and_get(comp->dev); + if (ret < 0 && ret != -EACCES) return ret; - } max_gain = (max - ucontrol->value.integer.value[0]) & mask; /* @@ -1175,11 +1173,17 @@ static int __maybe_unused wsa881x_runtime_resume(struct device *dev) struct sdw_slave *slave = dev_to_sdw_dev(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); struct wsa881x_priv *wsa881x = dev_get_drvdata(dev); + unsigned long time; gpiod_direction_output(wsa881x->sd_n, 1); - wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + time = wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + if (!time) { + dev_err(dev, "Initialization not complete, timed out\n"); + gpiod_direction_output(wsa881x->sd_n, 0); + return -ETIMEDOUT; + } regcache_cache_only(regmap, false); regcache_sync(regmap); diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c new file mode 100644 index 000000000000..63e1d7aa6137 --- /dev/null +++ b/sound/soc/codecs/wsa883x.c @@ -0,0 +1,1511 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/bitops.h> +#include <linux/debugfs.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/printk.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_registers.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc-dapm.h> +#include <sound/soc.h> +#include <sound/tlv.h> + +#define WSA883X_BASE 0x3000 +#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE + 0x00000001) +#define WSA883X_REF_CTRL (WSA883X_ANA_BG_TSADC_BASE + 0x0000) +#define WSA883X_TEST_CTL_0 (WSA883X_ANA_BG_TSADC_BASE + 0x0001) +#define WSA883X_BIAS_0 (WSA883X_ANA_BG_TSADC_BASE + 0x0002) +#define WSA883X_OP_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0003) +#define WSA883X_IREF_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0004) +#define WSA883X_ISENS_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0005) +#define WSA883X_CLK_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0006) +#define WSA883X_TEST_CTL_1 (WSA883X_ANA_BG_TSADC_BASE + 0x0007) +#define WSA883X_BIAS_1 (WSA883X_ANA_BG_TSADC_BASE + 0x0008) +#define WSA883X_ADC_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0009) +#define WSA883X_DOUT_MSB (WSA883X_ANA_BG_TSADC_BASE + 0x000A) +#define WSA883X_DOUT_LSB (WSA883X_ANA_BG_TSADC_BASE + 0x000B) +#define WSA883X_VBAT_SNS (WSA883X_ANA_BG_TSADC_BASE + 0x000C) +#define WSA883X_ITRIM_CODE (WSA883X_ANA_BG_TSADC_BASE + 0x000D) + +#define WSA883X_ANA_IVSENSE_BASE (WSA883X_BASE + 0x0000000F) +#define WSA883X_EN (WSA883X_ANA_IVSENSE_BASE + 0x0000) +#define WSA883X_OVERRIDE1 (WSA883X_ANA_IVSENSE_BASE + 0x0001) +#define WSA883X_OVERRIDE2 (WSA883X_ANA_IVSENSE_BASE + 0x0002) +#define WSA883X_VSENSE1 (WSA883X_ANA_IVSENSE_BASE + 0x0003) +#define WSA883X_ISENSE1 (WSA883X_ANA_IVSENSE_BASE + 0x0004) +#define WSA883X_ISENSE2 (WSA883X_ANA_IVSENSE_BASE + 0x0005) +#define WSA883X_ISENSE_CAL (WSA883X_ANA_IVSENSE_BASE + 0x0006) +#define WSA883X_MISC (WSA883X_ANA_IVSENSE_BASE + 0x0007) +#define WSA883X_ADC_0 (WSA883X_ANA_IVSENSE_BASE + 0x0008) +#define WSA883X_ADC_1 (WSA883X_ANA_IVSENSE_BASE + 0x0009) +#define WSA883X_ADC_2 (WSA883X_ANA_IVSENSE_BASE + 0x000A) +#define WSA883X_ADC_3 (WSA883X_ANA_IVSENSE_BASE + 0x000B) +#define WSA883X_ADC_4 (WSA883X_ANA_IVSENSE_BASE + 0x000C) +#define WSA883X_ADC_5 (WSA883X_ANA_IVSENSE_BASE + 0x000D) +#define WSA883X_ADC_6 (WSA883X_ANA_IVSENSE_BASE + 0x000E) +#define WSA883X_ADC_7 (WSA883X_ANA_IVSENSE_BASE + 0x000F) +#define WSA883X_STATUS (WSA883X_ANA_IVSENSE_BASE + 0x0010) + +#define WSA883X_ANA_SPK_TOP_BASE (WSA883X_BASE + 0x00000025) +#define WSA883X_DAC_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0000) +#define WSA883X_DAC_EN_DEBUG_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0001) +#define WSA883X_DAC_OPAMP_BIAS1_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0002) +#define WSA883X_DAC_OPAMP_BIAS2_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0003) +#define WSA883X_DAC_VCM_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0004) +#define WSA883X_DAC_VOLTAGE_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0005) +#define WSA883X_ATEST1_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0006) +#define WSA883X_ATEST2_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0007) +#define WSA883X_SPKR_TOP_BIAS_REG1 (WSA883X_ANA_SPK_TOP_BASE + 0x0008) +#define WSA883X_SPKR_TOP_BIAS_REG2 (WSA883X_ANA_SPK_TOP_BASE + 0x0009) +#define WSA883X_SPKR_TOP_BIAS_REG3 (WSA883X_ANA_SPK_TOP_BASE + 0x000A) +#define WSA883X_SPKR_TOP_BIAS_REG4 (WSA883X_ANA_SPK_TOP_BASE + 0x000B) +#define WSA883X_SPKR_CLIP_DET_REG (WSA883X_ANA_SPK_TOP_BASE + 0x000C) +#define WSA883X_SPKR_DRV_LF_BLK_EN (WSA883X_ANA_SPK_TOP_BASE + 0x000D) +#define WSA883X_SPKR_DRV_LF_EN (WSA883X_ANA_SPK_TOP_BASE + 0x000E) +#define WSA883X_SPKR_DRV_LF_MASK_DCC_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x000F) +#define WSA883X_SPKR_DRV_LF_MISC_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0010) +#define WSA883X_SPKR_DRV_LF_REG_GAIN (WSA883X_ANA_SPK_TOP_BASE + 0x0011) +#define WSA883X_SPKR_DRV_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0012) +#define WSA883X_SPKR_DRV_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE + 0x0013) +#define WSA883X_SPKR_PWM_CLK_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0014) +#define WSA883X_SPKR_PWM_FREQ_SEL_MASK BIT(3) +#define WSA883X_SPKR_PWM_FREQ_F300KHZ 0 +#define WSA883X_SPKR_PWM_FREQ_F600KHZ 1 +#define WSA883X_SPKR_PDRV_HS_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0015) +#define WSA883X_SPKR_PDRV_LS_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0016) +#define WSA883X_SPKR_PWRSTG_DBG (WSA883X_ANA_SPK_TOP_BASE + 0x0017) +#define WSA883X_SPKR_OCP_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0018) +#define WSA883X_SPKR_BBM_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0019) +#define WSA883X_PA_STATUS0 (WSA883X_ANA_SPK_TOP_BASE + 0x001A) +#define WSA883X_PA_STATUS1 (WSA883X_ANA_SPK_TOP_BASE + 0x001B) +#define WSA883X_PA_STATUS2 (WSA883X_ANA_SPK_TOP_BASE + 0x001C) + +#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE + 0x00000043) +#define WSA883X_EN_CTRL (WSA883X_ANA_BOOST_BASE + 0x0000) +#define WSA883X_CURRENT_LIMIT (WSA883X_ANA_BOOST_BASE + 0x0001) +#define WSA883X_IBIAS1 (WSA883X_ANA_BOOST_BASE + 0x0002) +#define WSA883X_IBIAS2 (WSA883X_ANA_BOOST_BASE + 0x0003) +#define WSA883X_IBIAS3 (WSA883X_ANA_BOOST_BASE + 0x0004) +#define WSA883X_LDO_PROG (WSA883X_ANA_BOOST_BASE + 0x0005) +#define WSA883X_STABILITY_CTRL1 (WSA883X_ANA_BOOST_BASE + 0x0006) +#define WSA883X_STABILITY_CTRL2 (WSA883X_ANA_BOOST_BASE + 0x0007) +#define WSA883X_PWRSTAGE_CTRL1 (WSA883X_ANA_BOOST_BASE + 0x0008) +#define WSA883X_PWRSTAGE_CTRL2 (WSA883X_ANA_BOOST_BASE + 0x0009) +#define WSA883X_BYPASS_1 (WSA883X_ANA_BOOST_BASE + 0x000A) +#define WSA883X_BYPASS_2 (WSA883X_ANA_BOOST_BASE + 0x000B) +#define WSA883X_ZX_CTRL_1 (WSA883X_ANA_BOOST_BASE + 0x000C) +#define WSA883X_ZX_CTRL_2 (WSA883X_ANA_BOOST_BASE + 0x000D) +#define WSA883X_MISC1 (WSA883X_ANA_BOOST_BASE + 0x000E) +#define WSA883X_MISC2 (WSA883X_ANA_BOOST_BASE + 0x000F) +#define WSA883X_GMAMP_SUP1 (WSA883X_ANA_BOOST_BASE + 0x0010) +#define WSA883X_PWRSTAGE_CTRL3 (WSA883X_ANA_BOOST_BASE + 0x0011) +#define WSA883X_PWRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE + 0x0012) +#define WSA883X_TEST1 (WSA883X_ANA_BOOST_BASE + 0x0013) +#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE + 0x0014) +#define WSA883X_SPARE2 (WSA883X_ANA_BOOST_BASE + 0x0015) + +#define WSA883X_ANA_PON_LDOL_BASE (WSA883X_BASE + 0x00000059) +#define WSA883X_PON_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0000) +#define WSA883X_PON_CLT_1 (WSA883X_ANA_PON_LDOL_BASE + 0x0001) +#define WSA883X_PON_CTL_2 (WSA883X_ANA_PON_LDOL_BASE + 0x0002) +#define WSA883X_PON_CTL_3 (WSA883X_ANA_PON_LDOL_BASE + 0x0003) +#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0004) +#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE + 0x0005) +#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE + 0x0006) +#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0007) +#define WSA883X_PADSW_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0008) +#define WSA883X_TEST_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0009) +#define WSA883X_TEST_1 (WSA883X_ANA_PON_LDOL_BASE + 0x000A) +#define WSA883X_STATUS_0 (WSA883X_ANA_PON_LDOL_BASE + 0x000B) +#define WSA883X_STATUS_1 (WSA883X_ANA_PON_LDOL_BASE + 0x000C) + +#define WSA883X_DIG_CTRL_BASE (WSA883X_BASE + 0x00000400) +#define WSA883X_CHIP_ID0 (WSA883X_DIG_CTRL_BASE + 0x0001) +#define WSA883X_CHIP_ID1 (WSA883X_DIG_CTRL_BASE + 0x0002) +#define WSA883X_CHIP_ID2 (WSA883X_DIG_CTRL_BASE + 0x0003) +#define WSA883X_CHIP_ID3 (WSA883X_DIG_CTRL_BASE + 0x0004) +#define WSA883X_BUS_ID (WSA883X_DIG_CTRL_BASE + 0x0005) +#define WSA883X_CDC_RST_CTL (WSA883X_DIG_CTRL_BASE + 0x0006) +#define WSA883X_TOP_CLK_CFG (WSA883X_DIG_CTRL_BASE + 0x0007) +#define WSA883X_CDC_PATH_MODE (WSA883X_DIG_CTRL_BASE + 0x0008) +#define WSA883X_RXD_MODE_MASK BIT(1) +#define WSA883X_RXD_MODE_NORMAL 0 +#define WSA883X_RXD_MODE_HIFI 1 +#define WSA883X_CDC_CLK_CTL (WSA883X_DIG_CTRL_BASE + 0x0009) +#define WSA883X_SWR_RESET_EN (WSA883X_DIG_CTRL_BASE + 0x000A) +#define WSA883X_RESET_CTL (WSA883X_DIG_CTRL_BASE + 0x000B) +#define WSA883X_PA_FSM_CTL (WSA883X_DIG_CTRL_BASE + 0x0010) +#define WSA883X_GLOBAL_PA_EN_MASK BIT(0) +#define WSA883X_GLOBAL_PA_ENABLE 1 +#define WSA883X_PA_FSM_TIMER0 (WSA883X_DIG_CTRL_BASE + 0x0011) +#define WSA883X_PA_FSM_TIMER1 (WSA883X_DIG_CTRL_BASE + 0x0012) +#define WSA883X_PA_FSM_STA (WSA883X_DIG_CTRL_BASE + 0x0013) +#define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE + 0x0014) +#define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE + 0x0015) +#define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE + 0x0016) +#define WSA883X_PA_FSM_DBG (WSA883X_DIG_CTRL_BASE + 0x0017) +#define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE + 0x0020) +#define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE + 0x0021) +#define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE + 0x0022) +#define WSA883X_TEMP_LSB (WSA883X_DIG_CTRL_BASE + 0x0023) +#define WSA883X_TEMP_CONFIG0 (WSA883X_DIG_CTRL_BASE + 0x0024) +#define WSA883X_TEMP_CONFIG1 (WSA883X_DIG_CTRL_BASE + 0x0025) +#define WSA883X_VBAT_ADC_FLT_CTL (WSA883X_DIG_CTRL_BASE + 0x0026) +#define WSA883X_VBAT_ADC_FLT_EN_MASK BIT(0) +#define WSA883X_VBAT_ADC_COEF_SEL_MASK GENMASK(3, 1) +#define WSA883X_VBAT_ADC_COEF_F_1DIV2 0x0 +#define WSA883X_VBAT_ADC_COEF_F_1DIV16 0x3 +#define WSA883X_VBAT_DIN_MSB (WSA883X_DIG_CTRL_BASE + 0x0027) +#define WSA883X_VBAT_DIN_LSB (WSA883X_DIG_CTRL_BASE + 0x0028) +#define WSA883X_VBAT_DOUT (WSA883X_DIG_CTRL_BASE + 0x0029) +#define WSA883X_SDM_PDM9_LSB (WSA883X_DIG_CTRL_BASE + 0x002A) +#define WSA883X_SDM_PDM9_MSB (WSA883X_DIG_CTRL_BASE + 0x002B) +#define WSA883X_CDC_RX_CTL (WSA883X_DIG_CTRL_BASE + 0x0030) +#define WSA883X_CDC_SPK_DSM_A1_0 (WSA883X_DIG_CTRL_BASE + 0x0031) +#define WSA883X_CDC_SPK_DSM_A1_1 (WSA883X_DIG_CTRL_BASE + 0x0032) +#define WSA883X_CDC_SPK_DSM_A2_0 (WSA883X_DIG_CTRL_BASE + 0x0033) +#define WSA883X_CDC_SPK_DSM_A2_1 (WSA883X_DIG_CTRL_BASE + 0x0034) +#define WSA883X_CDC_SPK_DSM_A3_0 (WSA883X_DIG_CTRL_BASE + 0x0035) +#define WSA883X_CDC_SPK_DSM_A3_1 (WSA883X_DIG_CTRL_BASE + 0x0036) +#define WSA883X_CDC_SPK_DSM_A4_0 (WSA883X_DIG_CTRL_BASE + 0x0037) +#define WSA883X_CDC_SPK_DSM_A4_1 (WSA883X_DIG_CTRL_BASE + 0x0038) +#define WSA883X_CDC_SPK_DSM_A5_0 (WSA883X_DIG_CTRL_BASE + 0x0039) +#define WSA883X_CDC_SPK_DSM_A5_1 (WSA883X_DIG_CTRL_BASE + 0x003A) +#define WSA883X_CDC_SPK_DSM_A6_0 (WSA883X_DIG_CTRL_BASE + 0x003B) +#define WSA883X_CDC_SPK_DSM_A7_0 (WSA883X_DIG_CTRL_BASE + 0x003C) +#define WSA883X_CDC_SPK_DSM_C_0 (WSA883X_DIG_CTRL_BASE + 0x003D) +#define WSA883X_CDC_SPK_DSM_C_1 (WSA883X_DIG_CTRL_BASE + 0x003E) +#define WSA883X_CDC_SPK_DSM_C_2 (WSA883X_DIG_CTRL_BASE + 0x003F) +#define WSA883X_CDC_SPK_DSM_C_3 (WSA883X_DIG_CTRL_BASE + 0x0040) +#define WSA883X_CDC_SPK_DSM_R1 (WSA883X_DIG_CTRL_BASE + 0x0041) +#define WSA883X_CDC_SPK_DSM_R2 (WSA883X_DIG_CTRL_BASE + 0x0042) +#define WSA883X_CDC_SPK_DSM_R3 (WSA883X_DIG_CTRL_BASE + 0x0043) +#define WSA883X_CDC_SPK_DSM_R4 (WSA883X_DIG_CTRL_BASE + 0x0044) +#define WSA883X_CDC_SPK_DSM_R5 (WSA883X_DIG_CTRL_BASE + 0x0045) +#define WSA883X_CDC_SPK_DSM_R6 (WSA883X_DIG_CTRL_BASE + 0x0046) +#define WSA883X_CDC_SPK_DSM_R7 (WSA883X_DIG_CTRL_BASE + 0x0047) +#define WSA883X_CDC_SPK_GAIN_PDM_0 (WSA883X_DIG_CTRL_BASE + 0x0048) +#define WSA883X_CDC_SPK_GAIN_PDM_1 (WSA883X_DIG_CTRL_BASE + 0x0049) +#define WSA883X_CDC_SPK_GAIN_PDM_2 (WSA883X_DIG_CTRL_BASE + 0x004A) +#define WSA883X_PDM_WD_CTL (WSA883X_DIG_CTRL_BASE + 0x004B) +#define WSA883X_PDM_EN_MASK BIT(0) +#define WSA883X_PDM_ENABLE BIT(0) +#define WSA883X_DEM_BYPASS_DATA0 (WSA883X_DIG_CTRL_BASE + 0x004C) +#define WSA883X_DEM_BYPASS_DATA1 (WSA883X_DIG_CTRL_BASE + 0x004D) +#define WSA883X_DEM_BYPASS_DATA2 (WSA883X_DIG_CTRL_BASE + 0x004E) +#define WSA883X_DEM_BYPASS_DATA3 (WSA883X_DIG_CTRL_BASE + 0x004F) +#define WSA883X_WAVG_CTL (WSA883X_DIG_CTRL_BASE + 0x0050) +#define WSA883X_WAVG_LRA_PER_0 (WSA883X_DIG_CTRL_BASE + 0x0051) +#define WSA883X_WAVG_LRA_PER_1 (WSA883X_DIG_CTRL_BASE + 0x0052) +#define WSA883X_WAVG_DELTA_THETA_0 (WSA883X_DIG_CTRL_BASE + 0x0053) +#define WSA883X_WAVG_DELTA_THETA_1 (WSA883X_DIG_CTRL_BASE + 0x0054) +#define WSA883X_WAVG_DIRECT_AMP_0 (WSA883X_DIG_CTRL_BASE + 0x0055) +#define WSA883X_WAVG_DIRECT_AMP_1 (WSA883X_DIG_CTRL_BASE + 0x0056) +#define WSA883X_WAVG_PTRN_AMP0_0 (WSA883X_DIG_CTRL_BASE + 0x0057) +#define WSA883X_WAVG_PTRN_AMP0_1 (WSA883X_DIG_CTRL_BASE + 0x0058) +#define WSA883X_WAVG_PTRN_AMP1_0 (WSA883X_DIG_CTRL_BASE + 0x0059) +#define WSA883X_WAVG_PTRN_AMP1_1 (WSA883X_DIG_CTRL_BASE + 0x005A) +#define WSA883X_WAVG_PTRN_AMP2_0 (WSA883X_DIG_CTRL_BASE + 0x005B) +#define WSA883X_WAVG_PTRN_AMP2_1 (WSA883X_DIG_CTRL_BASE + 0x005C) +#define WSA883X_WAVG_PTRN_AMP3_0 (WSA883X_DIG_CTRL_BASE + 0x005D) +#define WSA883X_WAVG_PTRN_AMP3_1 (WSA883X_DIG_CTRL_BASE + 0x005E) +#define WSA883X_WAVG_PTRN_AMP4_0 (WSA883X_DIG_CTRL_BASE + 0x005F) +#define WSA883X_WAVG_PTRN_AMP4_1 (WSA883X_DIG_CTRL_BASE + 0x0060) +#define WSA883X_WAVG_PTRN_AMP5_0 (WSA883X_DIG_CTRL_BASE + 0x0061) +#define WSA883X_WAVG_PTRN_AMP5_1 (WSA883X_DIG_CTRL_BASE + 0x0062) +#define WSA883X_WAVG_PTRN_AMP6_0 (WSA883X_DIG_CTRL_BASE + 0x0063) +#define WSA883X_WAVG_PTRN_AMP6_1 (WSA883X_DIG_CTRL_BASE + 0x0064) +#define WSA883X_WAVG_PTRN_AMP7_0 (WSA883X_DIG_CTRL_BASE + 0x0065) +#define WSA883X_WAVG_PTRN_AMP7_1 (WSA883X_DIG_CTRL_BASE + 0x0066) +#define WSA883X_WAVG_PER_0_1 (WSA883X_DIG_CTRL_BASE + 0x0067) +#define WSA883X_WAVG_PER_2_3 (WSA883X_DIG_CTRL_BASE + 0x0068) +#define WSA883X_WAVG_PER_4_5 (WSA883X_DIG_CTRL_BASE + 0x0069) +#define WSA883X_WAVG_PER_6_7 (WSA883X_DIG_CTRL_BASE + 0x006A) +#define WSA883X_WAVG_STA (WSA883X_DIG_CTRL_BASE + 0x006B) +#define WSA883X_DRE_CTL_0 (WSA883X_DIG_CTRL_BASE + 0x006C) +#define WSA883X_DRE_OFFSET_MASK GENMASK(2, 0) +#define WSA883X_DRE_PROG_DELAY_MASK GENMASK(7, 4) +#define WSA883X_DRE_CTL_1 (WSA883X_DIG_CTRL_BASE + 0x006D) +#define WSA883X_DRE_GAIN_EN_MASK BIT(0) +#define WSA883X_DRE_GAIN_FROM_CSR 1 +#define WSA883X_DRE_IDLE_DET_CTL (WSA883X_DIG_CTRL_BASE + 0x006E) +#define WSA883X_CLSH_CTL_0 (WSA883X_DIG_CTRL_BASE + 0x0070) +#define WSA883X_CLSH_CTL_1 (WSA883X_DIG_CTRL_BASE + 0x0071) +#define WSA883X_CLSH_V_HD_PA (WSA883X_DIG_CTRL_BASE + 0x0072) +#define WSA883X_CLSH_V_PA_MIN (WSA883X_DIG_CTRL_BASE + 0x0073) +#define WSA883X_CLSH_OVRD_VAL (WSA883X_DIG_CTRL_BASE + 0x0074) +#define WSA883X_CLSH_HARD_MAX (WSA883X_DIG_CTRL_BASE + 0x0075) +#define WSA883X_CLSH_SOFT_MAX (WSA883X_DIG_CTRL_BASE + 0x0076) +#define WSA883X_CLSH_SIG_DP (WSA883X_DIG_CTRL_BASE + 0x0077) +#define WSA883X_TAGC_CTL (WSA883X_DIG_CTRL_BASE + 0x0078) +#define WSA883X_TAGC_TIME (WSA883X_DIG_CTRL_BASE + 0x0079) +#define WSA883X_TAGC_E2E_GAIN (WSA883X_DIG_CTRL_BASE + 0x007A) +#define WSA883X_TAGC_FORCE_VAL (WSA883X_DIG_CTRL_BASE + 0x007B) +#define WSA883X_VAGC_CTL (WSA883X_DIG_CTRL_BASE + 0x007C) +#define WSA883X_VAGC_TIME (WSA883X_DIG_CTRL_BASE + 0x007D) +#define WSA883X_VAGC_ATTN_LVL_1_2 (WSA883X_DIG_CTRL_BASE + 0x007E) +#define WSA883X_VAGC_ATTN_LVL_3 (WSA883X_DIG_CTRL_BASE + 0x007F) +#define WSA883X_INTR_MODE (WSA883X_DIG_CTRL_BASE + 0x0080) +#define WSA883X_INTR_MASK0 (WSA883X_DIG_CTRL_BASE + 0x0081) +#define WSA883X_INTR_MASK1 (WSA883X_DIG_CTRL_BASE + 0x0082) +#define WSA883X_INTR_STATUS0 (WSA883X_DIG_CTRL_BASE + 0x0083) +#define WSA883X_INTR_STATUS1 (WSA883X_DIG_CTRL_BASE + 0x0084) +#define WSA883X_INTR_CLEAR0 (WSA883X_DIG_CTRL_BASE + 0x0085) +#define WSA883X_INTR_CLEAR1 (WSA883X_DIG_CTRL_BASE + 0x0086) +#define WSA883X_INTR_LEVEL0 (WSA883X_DIG_CTRL_BASE + 0x0087) +#define WSA883X_INTR_LEVEL1 (WSA883X_DIG_CTRL_BASE + 0x0088) +#define WSA883X_INTR_SET0 (WSA883X_DIG_CTRL_BASE + 0x0089) +#define WSA883X_INTR_SET1 (WSA883X_DIG_CTRL_BASE + 0x008A) +#define WSA883X_INTR_TEST0 (WSA883X_DIG_CTRL_BASE + 0x008B) +#define WSA883X_INTR_TEST1 (WSA883X_DIG_CTRL_BASE + 0x008C) +#define WSA883X_OTP_CTRL0 (WSA883X_DIG_CTRL_BASE + 0x0090) +#define WSA883X_OTP_CTRL1 (WSA883X_DIG_CTRL_BASE + 0x0091) +#define WSA883X_HDRIVE_CTL_GROUP1 (WSA883X_DIG_CTRL_BASE + 0x0092) +#define WSA883X_PIN_CTL (WSA883X_DIG_CTRL_BASE + 0x0093) +#define WSA883X_PIN_CTL_OE (WSA883X_DIG_CTRL_BASE + 0x0094) +#define WSA883X_PIN_WDATA_IOPAD (WSA883X_DIG_CTRL_BASE + 0x0095) +#define WSA883X_PIN_STATUS (WSA883X_DIG_CTRL_BASE + 0x0096) +#define WSA883X_I2C_SLAVE_CTL (WSA883X_DIG_CTRL_BASE + 0x0097) +#define WSA883X_PDM_TEST_MODE (WSA883X_DIG_CTRL_BASE + 0x00A0) +#define WSA883X_ATE_TEST_MODE (WSA883X_DIG_CTRL_BASE + 0x00A1) +#define WSA883X_DIG_DEBUG_MODE (WSA883X_DIG_CTRL_BASE + 0x00A3) +#define WSA883X_DIG_DEBUG_SEL (WSA883X_DIG_CTRL_BASE + 0x00A4) +#define WSA883X_DIG_DEBUG_EN (WSA883X_DIG_CTRL_BASE + 0x00A5) +#define WSA883X_SWR_HM_TEST0 (WSA883X_DIG_CTRL_BASE + 0x00A6) +#define WSA883X_SWR_HM_TEST1 (WSA883X_DIG_CTRL_BASE + 0x00A7) +#define WSA883X_SWR_PAD_CTL (WSA883X_DIG_CTRL_BASE + 0x00A8) +#define WSA883X_TADC_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE + 0x00A9) +#define WSA883X_TADC_DEBUG_MSB (WSA883X_DIG_CTRL_BASE + 0x00AA) +#define WSA883X_TADC_DEBUG_LSB (WSA883X_DIG_CTRL_BASE + 0x00AB) +#define WSA883X_SAMPLE_EDGE_SEL (WSA883X_DIG_CTRL_BASE + 0x00AC) +#define WSA883X_SWR_EDGE_SEL (WSA883X_DIG_CTRL_BASE + 0x00AD) +#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE + 0x00AE) +#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE + 0x00AF) +#define WSA883X_ANA_CSR_DBG_ADD (WSA883X_DIG_CTRL_BASE + 0x00B0) +#define WSA883X_ANA_CSR_DBG_CTL (WSA883X_DIG_CTRL_BASE + 0x00B1) +#define WSA883X_SPARE_R (WSA883X_DIG_CTRL_BASE + 0x00BC) +#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE + 0x00BD) +#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE + 0x00BE) +#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE + 0x00BF) +#define WSA883X_SCODE (WSA883X_DIG_CTRL_BASE + 0x00C0) + +#define WSA883X_DIG_TRIM_BASE (WSA883X_BASE + 0x00000500) +#define WSA883X_OTP_REG_0 (WSA883X_DIG_TRIM_BASE + 0x0080) +#define WSA883X_ID_MASK GENMASK(3, 0) +#define WSA883X_OTP_REG_1 (WSA883X_DIG_TRIM_BASE + 0x0081) +#define WSA883X_OTP_REG_2 (WSA883X_DIG_TRIM_BASE + 0x0082) +#define WSA883X_OTP_REG_3 (WSA883X_DIG_TRIM_BASE + 0x0083) +#define WSA883X_OTP_REG_4 (WSA883X_DIG_TRIM_BASE + 0x0084) +#define WSA883X_OTP_REG_5 (WSA883X_DIG_TRIM_BASE + 0x0085) +#define WSA883X_OTP_REG_6 (WSA883X_DIG_TRIM_BASE + 0x0086) +#define WSA883X_OTP_REG_7 (WSA883X_DIG_TRIM_BASE + 0x0087) +#define WSA883X_OTP_REG_8 (WSA883X_DIG_TRIM_BASE + 0x0088) +#define WSA883X_OTP_REG_9 (WSA883X_DIG_TRIM_BASE + 0x0089) +#define WSA883X_OTP_REG_10 (WSA883X_DIG_TRIM_BASE + 0x008A) +#define WSA883X_OTP_REG_11 (WSA883X_DIG_TRIM_BASE + 0x008B) +#define WSA883X_OTP_REG_12 (WSA883X_DIG_TRIM_BASE + 0x008C) +#define WSA883X_OTP_REG_13 (WSA883X_DIG_TRIM_BASE + 0x008D) +#define WSA883X_OTP_REG_14 (WSA883X_DIG_TRIM_BASE + 0x008E) +#define WSA883X_OTP_REG_15 (WSA883X_DIG_TRIM_BASE + 0x008F) +#define WSA883X_OTP_REG_16 (WSA883X_DIG_TRIM_BASE + 0x0090) +#define WSA883X_OTP_REG_17 (WSA883X_DIG_TRIM_BASE + 0x0091) +#define WSA883X_OTP_REG_18 (WSA883X_DIG_TRIM_BASE + 0x0092) +#define WSA883X_OTP_REG_19 (WSA883X_DIG_TRIM_BASE + 0x0093) +#define WSA883X_OTP_REG_20 (WSA883X_DIG_TRIM_BASE + 0x0094) +#define WSA883X_OTP_REG_21 (WSA883X_DIG_TRIM_BASE + 0x0095) +#define WSA883X_OTP_REG_22 (WSA883X_DIG_TRIM_BASE + 0x0096) +#define WSA883X_OTP_REG_23 (WSA883X_DIG_TRIM_BASE + 0x0097) +#define WSA883X_OTP_REG_24 (WSA883X_DIG_TRIM_BASE + 0x0098) +#define WSA883X_OTP_REG_25 (WSA883X_DIG_TRIM_BASE + 0x0099) +#define WSA883X_OTP_REG_26 (WSA883X_DIG_TRIM_BASE + 0x009A) +#define WSA883X_OTP_REG_27 (WSA883X_DIG_TRIM_BASE + 0x009B) +#define WSA883X_OTP_REG_28 (WSA883X_DIG_TRIM_BASE + 0x009C) +#define WSA883X_OTP_REG_29 (WSA883X_DIG_TRIM_BASE + 0x009D) +#define WSA883X_OTP_REG_30 (WSA883X_DIG_TRIM_BASE + 0x009E) +#define WSA883X_OTP_REG_31 (WSA883X_DIG_TRIM_BASE + 0x009F) +#define WSA883X_OTP_REG_32 (WSA883X_DIG_TRIM_BASE + 0x00A0) +#define WSA883X_OTP_REG_33 (WSA883X_DIG_TRIM_BASE + 0x00A1) +#define WSA883X_OTP_REG_34 (WSA883X_DIG_TRIM_BASE + 0x00A2) +#define WSA883X_OTP_REG_35 (WSA883X_DIG_TRIM_BASE + 0x00A3) +#define WSA883X_OTP_REG_63 (WSA883X_DIG_TRIM_BASE + 0x00BF) + +#define WSA883X_DIG_EMEM_BASE (WSA883X_BASE + 0x000005C0) +#define WSA883X_EMEM_0 (WSA883X_DIG_EMEM_BASE + 0x0000) +#define WSA883X_EMEM_1 (WSA883X_DIG_EMEM_BASE + 0x0001) +#define WSA883X_EMEM_2 (WSA883X_DIG_EMEM_BASE + 0x0002) +#define WSA883X_EMEM_3 (WSA883X_DIG_EMEM_BASE + 0x0003) +#define WSA883X_EMEM_4 (WSA883X_DIG_EMEM_BASE + 0x0004) +#define WSA883X_EMEM_5 (WSA883X_DIG_EMEM_BASE + 0x0005) +#define WSA883X_EMEM_6 (WSA883X_DIG_EMEM_BASE + 0x0006) +#define WSA883X_EMEM_7 (WSA883X_DIG_EMEM_BASE + 0x0007) +#define WSA883X_EMEM_8 (WSA883X_DIG_EMEM_BASE + 0x0008) +#define WSA883X_EMEM_9 (WSA883X_DIG_EMEM_BASE + 0x0009) +#define WSA883X_EMEM_10 (WSA883X_DIG_EMEM_BASE + 0x000A) +#define WSA883X_EMEM_11 (WSA883X_DIG_EMEM_BASE + 0x000B) +#define WSA883X_EMEM_12 (WSA883X_DIG_EMEM_BASE + 0x000C) +#define WSA883X_EMEM_13 (WSA883X_DIG_EMEM_BASE + 0x000D) +#define WSA883X_EMEM_14 (WSA883X_DIG_EMEM_BASE + 0x000E) +#define WSA883X_EMEM_15 (WSA883X_DIG_EMEM_BASE + 0x000F) +#define WSA883X_EMEM_16 (WSA883X_DIG_EMEM_BASE + 0x0010) +#define WSA883X_EMEM_17 (WSA883X_DIG_EMEM_BASE + 0x0011) +#define WSA883X_EMEM_18 (WSA883X_DIG_EMEM_BASE + 0x0012) +#define WSA883X_EMEM_19 (WSA883X_DIG_EMEM_BASE + 0x0013) +#define WSA883X_EMEM_20 (WSA883X_DIG_EMEM_BASE + 0x0014) +#define WSA883X_EMEM_21 (WSA883X_DIG_EMEM_BASE + 0x0015) +#define WSA883X_EMEM_22 (WSA883X_DIG_EMEM_BASE + 0x0016) +#define WSA883X_EMEM_23 (WSA883X_DIG_EMEM_BASE + 0x0017) +#define WSA883X_EMEM_24 (WSA883X_DIG_EMEM_BASE + 0x0018) +#define WSA883X_EMEM_25 (WSA883X_DIG_EMEM_BASE + 0x0019) +#define WSA883X_EMEM_26 (WSA883X_DIG_EMEM_BASE + 0x001A) +#define WSA883X_EMEM_27 (WSA883X_DIG_EMEM_BASE + 0x001B) +#define WSA883X_EMEM_28 (WSA883X_DIG_EMEM_BASE + 0x001C) +#define WSA883X_EMEM_29 (WSA883X_DIG_EMEM_BASE + 0x001D) +#define WSA883X_EMEM_30 (WSA883X_DIG_EMEM_BASE + 0x001E) +#define WSA883X_EMEM_31 (WSA883X_DIG_EMEM_BASE + 0x001F) +#define WSA883X_EMEM_32 (WSA883X_DIG_EMEM_BASE + 0x0020) +#define WSA883X_EMEM_33 (WSA883X_DIG_EMEM_BASE + 0x0021) +#define WSA883X_EMEM_34 (WSA883X_DIG_EMEM_BASE + 0x0022) +#define WSA883X_EMEM_35 (WSA883X_DIG_EMEM_BASE + 0x0023) +#define WSA883X_EMEM_36 (WSA883X_DIG_EMEM_BASE + 0x0024) +#define WSA883X_EMEM_37 (WSA883X_DIG_EMEM_BASE + 0x0025) +#define WSA883X_EMEM_38 (WSA883X_DIG_EMEM_BASE + 0x0026) +#define WSA883X_EMEM_39 (WSA883X_DIG_EMEM_BASE + 0x0027) +#define WSA883X_EMEM_40 (WSA883X_DIG_EMEM_BASE + 0x0028) +#define WSA883X_EMEM_41 (WSA883X_DIG_EMEM_BASE + 0x0029) +#define WSA883X_EMEM_42 (WSA883X_DIG_EMEM_BASE + 0x002A) +#define WSA883X_EMEM_43 (WSA883X_DIG_EMEM_BASE + 0x002B) +#define WSA883X_EMEM_44 (WSA883X_DIG_EMEM_BASE + 0x002C) +#define WSA883X_EMEM_45 (WSA883X_DIG_EMEM_BASE + 0x002D) +#define WSA883X_EMEM_46 (WSA883X_DIG_EMEM_BASE + 0x002E) +#define WSA883X_EMEM_47 (WSA883X_DIG_EMEM_BASE + 0x002F) +#define WSA883X_EMEM_48 (WSA883X_DIG_EMEM_BASE + 0x0030) +#define WSA883X_EMEM_49 (WSA883X_DIG_EMEM_BASE + 0x0031) +#define WSA883X_EMEM_50 (WSA883X_DIG_EMEM_BASE + 0x0032) +#define WSA883X_EMEM_51 (WSA883X_DIG_EMEM_BASE + 0x0033) +#define WSA883X_EMEM_52 (WSA883X_DIG_EMEM_BASE + 0x0034) +#define WSA883X_EMEM_53 (WSA883X_DIG_EMEM_BASE + 0x0035) +#define WSA883X_EMEM_54 (WSA883X_DIG_EMEM_BASE + 0x0036) +#define WSA883X_EMEM_55 (WSA883X_DIG_EMEM_BASE + 0x0037) +#define WSA883X_EMEM_56 (WSA883X_DIG_EMEM_BASE + 0x0038) +#define WSA883X_EMEM_57 (WSA883X_DIG_EMEM_BASE + 0x0039) +#define WSA883X_EMEM_58 (WSA883X_DIG_EMEM_BASE + 0x003A) +#define WSA883X_EMEM_59 (WSA883X_DIG_EMEM_BASE + 0x003B) +#define WSA883X_EMEM_60 (WSA883X_DIG_EMEM_BASE + 0x003C) +#define WSA883X_EMEM_61 (WSA883X_DIG_EMEM_BASE + 0x003D) +#define WSA883X_EMEM_62 (WSA883X_DIG_EMEM_BASE + 0x003E) +#define WSA883X_EMEM_63 (WSA883X_DIG_EMEM_BASE + 0x003F) + +#define WSA883X_NUM_REGISTERS (WSA883X_EMEM_63 + 1) +#define WSA883X_MAX_REGISTER (WSA883X_NUM_REGISTERS - 1) +#define WSA883X_PROBE_TIMEOUT 1000 + +#define WSA883X_VERSION_1_0 0 +#define WSA883X_VERSION_1_1 1 + +#define WSA883X_MAX_SWR_PORTS 4 +#define WSA883X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define WSA883X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) + +#define WSA883X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +struct wsa883x_priv { + struct regmap *regmap; + struct device *dev; + struct regulator *vdd; + struct sdw_slave *slave; + struct sdw_stream_config sconfig; + struct sdw_stream_runtime *sruntime; + struct sdw_port_config port_config[WSA883X_MAX_SWR_PORTS]; + struct gpio_desc *sd_n; + bool port_prepared[WSA883X_MAX_SWR_PORTS]; + bool port_enable[WSA883X_MAX_SWR_PORTS]; + int version; + int variant; + int active_ports; + int dev_mode; + int comp_offset; +}; + +enum { + WSA8830 = 0, + WSA8835, + WSA8832, + WSA8835_V2 = 5, +}; + +enum { + COMP_OFFSET0, + COMP_OFFSET1, + COMP_OFFSET2, + COMP_OFFSET3, + COMP_OFFSET4, +}; + +enum wsa_port_ids { + WSA883X_PORT_DAC, + WSA883X_PORT_COMP, + WSA883X_PORT_BOOST, + WSA883X_PORT_VISENSE, +}; + +static const char * const wsa_dev_mode_text[] = { + "Speaker", "Receiver", "Ultrasound" +}; + +enum { + SPEAKER, + RECEIVER, + ULTRASOUND, +}; + +static const struct soc_enum wsa_dev_mode_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text); + +/* 4 ports */ +static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = { + { + /* DAC */ + .num = 1, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + }, { + /* COMP */ + .num = 2, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + }, { + /* BOOST */ + .num = 3, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + }, { + /* VISENSE */ + .num = 4, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + } +}; + +static struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = { + { + .num = 1, + .ch_mask = 0x1, + }, { + .num = 2, + .ch_mask = 0xf, + }, { + .num = 3, + .ch_mask = 0x3, + }, { /* IV feedback */ + .num = 4, + .ch_mask = 0x3, + }, +}; + +static struct reg_default wsa883x_defaults[] = { + { WSA883X_REF_CTRL, 0xD5 }, + { WSA883X_TEST_CTL_0, 0x06 }, + { WSA883X_BIAS_0, 0xD2 }, + { WSA883X_OP_CTL, 0xE0 }, + { WSA883X_IREF_CTL, 0x57 }, + { WSA883X_ISENS_CTL, 0x47 }, + { WSA883X_CLK_CTL, 0x87 }, + { WSA883X_TEST_CTL_1, 0x00 }, + { WSA883X_BIAS_1, 0x51 }, + { WSA883X_ADC_CTL, 0x01 }, + { WSA883X_DOUT_MSB, 0x00 }, + { WSA883X_DOUT_LSB, 0x00 }, + { WSA883X_VBAT_SNS, 0x40 }, + { WSA883X_ITRIM_CODE, 0x9F }, + { WSA883X_EN, 0x20 }, + { WSA883X_OVERRIDE1, 0x00 }, + { WSA883X_OVERRIDE2, 0x08 }, + { WSA883X_VSENSE1, 0xD3 }, + { WSA883X_ISENSE1, 0xD4 }, + { WSA883X_ISENSE2, 0x20 }, + { WSA883X_ISENSE_CAL, 0x00 }, + { WSA883X_MISC, 0x08 }, + { WSA883X_ADC_0, 0x00 }, + { WSA883X_ADC_1, 0x00 }, + { WSA883X_ADC_2, 0x40 }, + { WSA883X_ADC_3, 0x80 }, + { WSA883X_ADC_4, 0x25 }, + { WSA883X_ADC_5, 0x25 }, + { WSA883X_ADC_6, 0x08 }, + { WSA883X_ADC_7, 0x81 }, + { WSA883X_STATUS, 0x00 }, + { WSA883X_DAC_CTRL_REG, 0x53 }, + { WSA883X_DAC_EN_DEBUG_REG, 0x00 }, + { WSA883X_DAC_OPAMP_BIAS1_REG, 0x48 }, + { WSA883X_DAC_OPAMP_BIAS2_REG, 0x48 }, + { WSA883X_DAC_VCM_CTRL_REG, 0x88 }, + { WSA883X_DAC_VOLTAGE_CTRL_REG, 0xA5 }, + { WSA883X_ATEST1_REG, 0x00 }, + { WSA883X_ATEST2_REG, 0x00 }, + { WSA883X_SPKR_TOP_BIAS_REG1, 0x6A }, + { WSA883X_SPKR_TOP_BIAS_REG2, 0x65 }, + { WSA883X_SPKR_TOP_BIAS_REG3, 0x55 }, + { WSA883X_SPKR_TOP_BIAS_REG4, 0xA9 }, + { WSA883X_SPKR_CLIP_DET_REG, 0x9C }, + { WSA883X_SPKR_DRV_LF_BLK_EN, 0x0F }, + { WSA883X_SPKR_DRV_LF_EN, 0x0A }, + { WSA883X_SPKR_DRV_LF_MASK_DCC_CTL, 0x00 }, + { WSA883X_SPKR_DRV_LF_MISC_CTL, 0x3A }, + { WSA883X_SPKR_DRV_LF_REG_GAIN, 0x00 }, + { WSA883X_SPKR_DRV_OS_CAL_CTL, 0x00 }, + { WSA883X_SPKR_DRV_OS_CAL_CTL1, 0x90 }, + { WSA883X_SPKR_PWM_CLK_CTL, 0x00 }, + { WSA883X_SPKR_PDRV_HS_CTL, 0x52 }, + { WSA883X_SPKR_PDRV_LS_CTL, 0x48 }, + { WSA883X_SPKR_PWRSTG_DBG, 0x08 }, + { WSA883X_SPKR_OCP_CTL, 0xE2 }, + { WSA883X_SPKR_BBM_CTL, 0x92 }, + { WSA883X_PA_STATUS0, 0x00 }, + { WSA883X_PA_STATUS1, 0x00 }, + { WSA883X_PA_STATUS2, 0x80 }, + { WSA883X_EN_CTRL, 0x44 }, + { WSA883X_CURRENT_LIMIT, 0xCC }, + { WSA883X_IBIAS1, 0x00 }, + { WSA883X_IBIAS2, 0x00 }, + { WSA883X_IBIAS3, 0x00 }, + { WSA883X_LDO_PROG, 0x02 }, + { WSA883X_STABILITY_CTRL1, 0x8E }, + { WSA883X_STABILITY_CTRL2, 0x10 }, + { WSA883X_PWRSTAGE_CTRL1, 0x06 }, + { WSA883X_PWRSTAGE_CTRL2, 0x00 }, + { WSA883X_BYPASS_1, 0x19 }, + { WSA883X_BYPASS_2, 0x13 }, + { WSA883X_ZX_CTRL_1, 0xF0 }, + { WSA883X_ZX_CTRL_2, 0x04 }, + { WSA883X_MISC1, 0x06 }, + { WSA883X_MISC2, 0xA0 }, + { WSA883X_GMAMP_SUP1, 0x82 }, + { WSA883X_PWRSTAGE_CTRL3, 0x39 }, + { WSA883X_PWRSTAGE_CTRL4, 0x5F }, + { WSA883X_TEST1, 0x00 }, + { WSA883X_SPARE1, 0x00 }, + { WSA883X_SPARE2, 0x00 }, + { WSA883X_PON_CTL_0, 0x10 }, + { WSA883X_PON_CLT_1, 0xE0 }, + { WSA883X_PON_CTL_2, 0x90 }, + { WSA883X_PON_CTL_3, 0x70 }, + { WSA883X_CKWD_CTL_0, 0x34 }, + { WSA883X_CKWD_CTL_1, 0x0F }, + { WSA883X_CKWD_CTL_2, 0x00 }, + { WSA883X_CKSK_CTL_0, 0x00 }, + { WSA883X_PADSW_CTL_0, 0x00 }, + { WSA883X_TEST_0, 0x00 }, + { WSA883X_TEST_1, 0x00 }, + { WSA883X_STATUS_0, 0x00 }, + { WSA883X_STATUS_1, 0x00 }, + { WSA883X_CHIP_ID0, 0x00 }, + { WSA883X_CHIP_ID1, 0x00 }, + { WSA883X_CHIP_ID2, 0x02 }, + { WSA883X_CHIP_ID3, 0x02 }, + { WSA883X_BUS_ID, 0x00 }, + { WSA883X_CDC_RST_CTL, 0x01 }, + { WSA883X_TOP_CLK_CFG, 0x00 }, + { WSA883X_CDC_PATH_MODE, 0x00 }, + { WSA883X_CDC_CLK_CTL, 0xFF }, + { WSA883X_SWR_RESET_EN, 0x00 }, + { WSA883X_RESET_CTL, 0x00 }, + { WSA883X_PA_FSM_CTL, 0x00 }, + { WSA883X_PA_FSM_TIMER0, 0x80 }, + { WSA883X_PA_FSM_TIMER1, 0x80 }, + { WSA883X_PA_FSM_STA, 0x00 }, + { WSA883X_PA_FSM_ERR_COND, 0x00 }, + { WSA883X_PA_FSM_MSK, 0x00 }, + { WSA883X_PA_FSM_BYP, 0x01 }, + { WSA883X_PA_FSM_DBG, 0x00 }, + { WSA883X_TADC_VALUE_CTL, 0x03 }, + { WSA883X_TEMP_DETECT_CTL, 0x01 }, + { WSA883X_TEMP_MSB, 0x00 }, + { WSA883X_TEMP_LSB, 0x00 }, + { WSA883X_TEMP_CONFIG0, 0x00 }, + { WSA883X_TEMP_CONFIG1, 0x00 }, + { WSA883X_VBAT_ADC_FLT_CTL, 0x00 }, + { WSA883X_VBAT_DIN_MSB, 0x00 }, + { WSA883X_VBAT_DIN_LSB, 0x00 }, + { WSA883X_VBAT_DOUT, 0x00 }, + { WSA883X_SDM_PDM9_LSB, 0x00 }, + { WSA883X_SDM_PDM9_MSB, 0x00 }, + { WSA883X_CDC_RX_CTL, 0xFE }, + { WSA883X_CDC_SPK_DSM_A1_0, 0x00 }, + { WSA883X_CDC_SPK_DSM_A1_1, 0x01 }, + { WSA883X_CDC_SPK_DSM_A2_0, 0x96 }, + { WSA883X_CDC_SPK_DSM_A2_1, 0x09 }, + { WSA883X_CDC_SPK_DSM_A3_0, 0xAB }, + { WSA883X_CDC_SPK_DSM_A3_1, 0x05 }, + { WSA883X_CDC_SPK_DSM_A4_0, 0x1C }, + { WSA883X_CDC_SPK_DSM_A4_1, 0x02 }, + { WSA883X_CDC_SPK_DSM_A5_0, 0x17 }, + { WSA883X_CDC_SPK_DSM_A5_1, 0x02 }, + { WSA883X_CDC_SPK_DSM_A6_0, 0xAA }, + { WSA883X_CDC_SPK_DSM_A7_0, 0xE3 }, + { WSA883X_CDC_SPK_DSM_C_0, 0x69 }, + { WSA883X_CDC_SPK_DSM_C_1, 0x54 }, + { WSA883X_CDC_SPK_DSM_C_2, 0x02 }, + { WSA883X_CDC_SPK_DSM_C_3, 0x15 }, + { WSA883X_CDC_SPK_DSM_R1, 0xA4 }, + { WSA883X_CDC_SPK_DSM_R2, 0xB5 }, + { WSA883X_CDC_SPK_DSM_R3, 0x86 }, + { WSA883X_CDC_SPK_DSM_R4, 0x85 }, + { WSA883X_CDC_SPK_DSM_R5, 0xAA }, + { WSA883X_CDC_SPK_DSM_R6, 0xE2 }, + { WSA883X_CDC_SPK_DSM_R7, 0x62 }, + { WSA883X_CDC_SPK_GAIN_PDM_0, 0x00 }, + { WSA883X_CDC_SPK_GAIN_PDM_1, 0xFC }, + { WSA883X_CDC_SPK_GAIN_PDM_2, 0x05 }, + { WSA883X_PDM_WD_CTL, 0x00 }, + { WSA883X_DEM_BYPASS_DATA0, 0x00 }, + { WSA883X_DEM_BYPASS_DATA1, 0x00 }, + { WSA883X_DEM_BYPASS_DATA2, 0x00 }, + { WSA883X_DEM_BYPASS_DATA3, 0x00 }, + { WSA883X_WAVG_CTL, 0x06 }, + { WSA883X_WAVG_LRA_PER_0, 0xD1 }, + { WSA883X_WAVG_LRA_PER_1, 0x00 }, + { WSA883X_WAVG_DELTA_THETA_0, 0xE6 }, + { WSA883X_WAVG_DELTA_THETA_1, 0x04 }, + { WSA883X_WAVG_DIRECT_AMP_0, 0x50 }, + { WSA883X_WAVG_DIRECT_AMP_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP0_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP0_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP1_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP1_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP2_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP2_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP3_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP3_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP4_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP4_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP5_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP5_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP6_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP6_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP7_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP7_1, 0x00 }, + { WSA883X_WAVG_PER_0_1, 0x88 }, + { WSA883X_WAVG_PER_2_3, 0x88 }, + { WSA883X_WAVG_PER_4_5, 0x88 }, + { WSA883X_WAVG_PER_6_7, 0x88 }, + { WSA883X_WAVG_STA, 0x00 }, + { WSA883X_DRE_CTL_0, 0x70 }, + { WSA883X_DRE_CTL_1, 0x08 }, + { WSA883X_DRE_IDLE_DET_CTL, 0x1F }, + { WSA883X_CLSH_CTL_0, 0x37 }, + { WSA883X_CLSH_CTL_1, 0x81 }, + { WSA883X_CLSH_V_HD_PA, 0x0F }, + { WSA883X_CLSH_V_PA_MIN, 0x00 }, + { WSA883X_CLSH_OVRD_VAL, 0x00 }, + { WSA883X_CLSH_HARD_MAX, 0xFF }, + { WSA883X_CLSH_SOFT_MAX, 0xF5 }, + { WSA883X_CLSH_SIG_DP, 0x00 }, + { WSA883X_TAGC_CTL, 0x10 }, + { WSA883X_TAGC_TIME, 0x20 }, + { WSA883X_TAGC_E2E_GAIN, 0x02 }, + { WSA883X_TAGC_FORCE_VAL, 0x00 }, + { WSA883X_VAGC_CTL, 0x00 }, + { WSA883X_VAGC_TIME, 0x08 }, + { WSA883X_VAGC_ATTN_LVL_1_2, 0x21 }, + { WSA883X_VAGC_ATTN_LVL_3, 0x03 }, + { WSA883X_INTR_MODE, 0x00 }, + { WSA883X_INTR_MASK0, 0x90 }, + { WSA883X_INTR_MASK1, 0x00 }, + { WSA883X_INTR_STATUS0, 0x00 }, + { WSA883X_INTR_STATUS1, 0x00 }, + { WSA883X_INTR_CLEAR0, 0x00 }, + { WSA883X_INTR_CLEAR1, 0x00 }, + { WSA883X_INTR_LEVEL0, 0x00 }, + { WSA883X_INTR_LEVEL1, 0x00 }, + { WSA883X_INTR_SET0, 0x00 }, + { WSA883X_INTR_SET1, 0x00 }, + { WSA883X_INTR_TEST0, 0x00 }, + { WSA883X_INTR_TEST1, 0x00 }, + { WSA883X_OTP_CTRL0, 0x00 }, + { WSA883X_OTP_CTRL1, 0x00 }, + { WSA883X_HDRIVE_CTL_GROUP1, 0x00 }, + { WSA883X_PIN_CTL, 0x04 }, + { WSA883X_PIN_CTL_OE, 0x00 }, + { WSA883X_PIN_WDATA_IOPAD, 0x00 }, + { WSA883X_PIN_STATUS, 0x00 }, + { WSA883X_I2C_SLAVE_CTL, 0x00 }, + { WSA883X_PDM_TEST_MODE, 0x00 }, + { WSA883X_ATE_TEST_MODE, 0x00 }, + { WSA883X_DIG_DEBUG_MODE, 0x00 }, + { WSA883X_DIG_DEBUG_SEL, 0x00 }, + { WSA883X_DIG_DEBUG_EN, 0x00 }, + { WSA883X_SWR_HM_TEST0, 0x08 }, + { WSA883X_SWR_HM_TEST1, 0x00 }, + { WSA883X_SWR_PAD_CTL, 0x37 }, + { WSA883X_TADC_DETECT_DBG_CTL, 0x00 }, + { WSA883X_TADC_DEBUG_MSB, 0x00 }, + { WSA883X_TADC_DEBUG_LSB, 0x00 }, + { WSA883X_SAMPLE_EDGE_SEL, 0x7F }, + { WSA883X_SWR_EDGE_SEL, 0x00 }, + { WSA883X_TEST_MODE_CTL, 0x04 }, + { WSA883X_IOPAD_CTL, 0x00 }, + { WSA883X_ANA_CSR_DBG_ADD, 0x00 }, + { WSA883X_ANA_CSR_DBG_CTL, 0x12 }, + { WSA883X_SPARE_R, 0x00 }, + { WSA883X_SPARE_0, 0x00 }, + { WSA883X_SPARE_1, 0x00 }, + { WSA883X_SPARE_2, 0x00 }, + { WSA883X_SCODE, 0x00 }, + { WSA883X_OTP_REG_0, 0x05 }, + { WSA883X_OTP_REG_1, 0xFF }, + { WSA883X_OTP_REG_2, 0xC0 }, + { WSA883X_OTP_REG_3, 0xFF }, + { WSA883X_OTP_REG_4, 0xC0 }, + { WSA883X_OTP_REG_5, 0xFF }, + { WSA883X_OTP_REG_6, 0xFF }, + { WSA883X_OTP_REG_7, 0xFF }, + { WSA883X_OTP_REG_8, 0xFF }, + { WSA883X_OTP_REG_9, 0xFF }, + { WSA883X_OTP_REG_10, 0xFF }, + { WSA883X_OTP_REG_11, 0xFF }, + { WSA883X_OTP_REG_12, 0xFF }, + { WSA883X_OTP_REG_13, 0xFF }, + { WSA883X_OTP_REG_14, 0xFF }, + { WSA883X_OTP_REG_15, 0xFF }, + { WSA883X_OTP_REG_16, 0xFF }, + { WSA883X_OTP_REG_17, 0xFF }, + { WSA883X_OTP_REG_18, 0xFF }, + { WSA883X_OTP_REG_19, 0xFF }, + { WSA883X_OTP_REG_20, 0xFF }, + { WSA883X_OTP_REG_21, 0xFF }, + { WSA883X_OTP_REG_22, 0xFF }, + { WSA883X_OTP_REG_23, 0xFF }, + { WSA883X_OTP_REG_24, 0x37 }, + { WSA883X_OTP_REG_25, 0x3F }, + { WSA883X_OTP_REG_26, 0x03 }, + { WSA883X_OTP_REG_27, 0x00 }, + { WSA883X_OTP_REG_28, 0x00 }, + { WSA883X_OTP_REG_29, 0x00 }, + { WSA883X_OTP_REG_30, 0x00 }, + { WSA883X_OTP_REG_31, 0x03 }, + { WSA883X_OTP_REG_32, 0x00 }, + { WSA883X_OTP_REG_33, 0xFF }, + { WSA883X_OTP_REG_34, 0x00 }, + { WSA883X_OTP_REG_35, 0x00 }, + { WSA883X_OTP_REG_63, 0x40 }, + { WSA883X_EMEM_0, 0x00 }, + { WSA883X_EMEM_1, 0x00 }, + { WSA883X_EMEM_2, 0x00 }, + { WSA883X_EMEM_3, 0x00 }, + { WSA883X_EMEM_4, 0x00 }, + { WSA883X_EMEM_5, 0x00 }, + { WSA883X_EMEM_6, 0x00 }, + { WSA883X_EMEM_7, 0x00 }, + { WSA883X_EMEM_8, 0x00 }, + { WSA883X_EMEM_9, 0x00 }, + { WSA883X_EMEM_10, 0x00 }, + { WSA883X_EMEM_11, 0x00 }, + { WSA883X_EMEM_12, 0x00 }, + { WSA883X_EMEM_13, 0x00 }, + { WSA883X_EMEM_14, 0x00 }, + { WSA883X_EMEM_15, 0x00 }, + { WSA883X_EMEM_16, 0x00 }, + { WSA883X_EMEM_17, 0x00 }, + { WSA883X_EMEM_18, 0x00 }, + { WSA883X_EMEM_19, 0x00 }, + { WSA883X_EMEM_20, 0x00 }, + { WSA883X_EMEM_21, 0x00 }, + { WSA883X_EMEM_22, 0x00 }, + { WSA883X_EMEM_23, 0x00 }, + { WSA883X_EMEM_24, 0x00 }, + { WSA883X_EMEM_25, 0x00 }, + { WSA883X_EMEM_26, 0x00 }, + { WSA883X_EMEM_27, 0x00 }, + { WSA883X_EMEM_28, 0x00 }, + { WSA883X_EMEM_29, 0x00 }, + { WSA883X_EMEM_30, 0x00 }, + { WSA883X_EMEM_31, 0x00 }, + { WSA883X_EMEM_32, 0x00 }, + { WSA883X_EMEM_33, 0x00 }, + { WSA883X_EMEM_34, 0x00 }, + { WSA883X_EMEM_35, 0x00 }, + { WSA883X_EMEM_36, 0x00 }, + { WSA883X_EMEM_37, 0x00 }, + { WSA883X_EMEM_38, 0x00 }, + { WSA883X_EMEM_39, 0x00 }, + { WSA883X_EMEM_40, 0x00 }, + { WSA883X_EMEM_41, 0x00 }, + { WSA883X_EMEM_42, 0x00 }, + { WSA883X_EMEM_43, 0x00 }, + { WSA883X_EMEM_44, 0x00 }, + { WSA883X_EMEM_45, 0x00 }, + { WSA883X_EMEM_46, 0x00 }, + { WSA883X_EMEM_47, 0x00 }, + { WSA883X_EMEM_48, 0x00 }, + { WSA883X_EMEM_49, 0x00 }, + { WSA883X_EMEM_50, 0x00 }, + { WSA883X_EMEM_51, 0x00 }, + { WSA883X_EMEM_52, 0x00 }, + { WSA883X_EMEM_53, 0x00 }, + { WSA883X_EMEM_54, 0x00 }, + { WSA883X_EMEM_55, 0x00 }, + { WSA883X_EMEM_56, 0x00 }, + { WSA883X_EMEM_57, 0x00 }, + { WSA883X_EMEM_58, 0x00 }, + { WSA883X_EMEM_59, 0x00 }, + { WSA883X_EMEM_60, 0x00 }, + { WSA883X_EMEM_61, 0x00 }, + { WSA883X_EMEM_62, 0x00 }, + { WSA883X_EMEM_63, 0x00 }, +}; + +static bool wsa883x_readonly_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WSA883X_DOUT_MSB: + case WSA883X_DOUT_LSB: + case WSA883X_STATUS: + case WSA883X_PA_STATUS0: + case WSA883X_PA_STATUS1: + case WSA883X_PA_STATUS2: + case WSA883X_STATUS_0: + case WSA883X_STATUS_1: + case WSA883X_CHIP_ID0: + case WSA883X_CHIP_ID1: + case WSA883X_CHIP_ID2: + case WSA883X_CHIP_ID3: + case WSA883X_BUS_ID: + case WSA883X_PA_FSM_STA: + case WSA883X_PA_FSM_ERR_COND: + case WSA883X_TEMP_MSB: + case WSA883X_TEMP_LSB: + case WSA883X_VBAT_DIN_MSB: + case WSA883X_VBAT_DIN_LSB: + case WSA883X_VBAT_DOUT: + case WSA883X_SDM_PDM9_LSB: + case WSA883X_SDM_PDM9_MSB: + case WSA883X_WAVG_STA: + case WSA883X_INTR_STATUS0: + case WSA883X_INTR_STATUS1: + case WSA883X_OTP_CTRL1: + case WSA883X_PIN_STATUS: + case WSA883X_ATE_TEST_MODE: + case WSA883X_SWR_HM_TEST1: + case WSA883X_SPARE_R: + case WSA883X_OTP_REG_0: + return true; + } + return false; +} + +static bool wsa883x_writeable_register(struct device *dev, unsigned int reg) +{ + return !wsa883x_readonly_register(dev, reg); +} + +static bool wsa883x_volatile_register(struct device *dev, unsigned int reg) +{ + return wsa883x_readonly_register(dev, reg); +} + +static struct regmap_config wsa883x_regmap_config = { + .reg_bits = 32, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wsa883x_defaults, + .max_register = WSA883X_MAX_REGISTER, + .num_reg_defaults = ARRAY_SIZE(wsa883x_defaults), + .volatile_reg = wsa883x_volatile_register, + .writeable_reg = wsa883x_writeable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .can_multi_write = true, + .use_single_read = true, +}; + +static const struct reg_sequence reg_init[] = { + {WSA883X_PA_FSM_BYP, 0x00}, + {WSA883X_ADC_6, 0x02}, + {WSA883X_CDC_SPK_DSM_A2_0, 0x0A}, + {WSA883X_CDC_SPK_DSM_A2_1, 0x08}, + {WSA883X_CDC_SPK_DSM_A3_0, 0xF3}, + {WSA883X_CDC_SPK_DSM_A3_1, 0x07}, + {WSA883X_CDC_SPK_DSM_A4_0, 0x79}, + {WSA883X_CDC_SPK_DSM_A4_1, 0x02}, + {WSA883X_CDC_SPK_DSM_A5_0, 0x0B}, + {WSA883X_CDC_SPK_DSM_A5_1, 0x02}, + {WSA883X_CDC_SPK_DSM_A6_0, 0x8A}, + {WSA883X_CDC_SPK_DSM_A7_0, 0x9B}, + {WSA883X_CDC_SPK_DSM_C_0, 0x68}, + {WSA883X_CDC_SPK_DSM_C_1, 0x54}, + {WSA883X_CDC_SPK_DSM_C_2, 0xF2}, + {WSA883X_CDC_SPK_DSM_C_3, 0x20}, + {WSA883X_CDC_SPK_DSM_R1, 0x83}, + {WSA883X_CDC_SPK_DSM_R2, 0x7F}, + {WSA883X_CDC_SPK_DSM_R3, 0x9D}, + {WSA883X_CDC_SPK_DSM_R4, 0x82}, + {WSA883X_CDC_SPK_DSM_R5, 0x8B}, + {WSA883X_CDC_SPK_DSM_R6, 0x9B}, + {WSA883X_CDC_SPK_DSM_R7, 0x3F}, + {WSA883X_VBAT_SNS, 0x20}, + {WSA883X_DRE_CTL_0, 0x92}, + {WSA883X_DRE_IDLE_DET_CTL, 0x0F}, + {WSA883X_CURRENT_LIMIT, 0xC4}, + {WSA883X_VAGC_TIME, 0x0F}, + {WSA883X_VAGC_ATTN_LVL_1_2, 0x00}, + {WSA883X_VAGC_ATTN_LVL_3, 0x01}, + {WSA883X_VAGC_CTL, 0x01}, + {WSA883X_TAGC_CTL, 0x1A}, + {WSA883X_TAGC_TIME, 0x2C}, + {WSA883X_TEMP_CONFIG0, 0x02}, + {WSA883X_TEMP_CONFIG1, 0x02}, + {WSA883X_OTP_REG_1, 0x49}, + {WSA883X_OTP_REG_2, 0x80}, + {WSA883X_OTP_REG_3, 0xC9}, + {WSA883X_OTP_REG_4, 0x40}, + {WSA883X_TAGC_CTL, 0x1B}, + {WSA883X_ADC_2, 0x00}, + {WSA883X_ADC_7, 0x85}, + {WSA883X_ADC_7, 0x87}, + {WSA883X_CKWD_CTL_0, 0x14}, + {WSA883X_CKWD_CTL_1, 0x1B}, + {WSA883X_GMAMP_SUP1, 0xE2}, +}; + +static void wsa883x_init(struct wsa883x_priv *wsa883x) +{ + struct regmap *regmap = wsa883x->regmap; + int variant, version; + + regmap_read(regmap, WSA883X_OTP_REG_0, &variant); + wsa883x->variant = variant & WSA883X_ID_MASK; + + regmap_read(regmap, WSA883X_CHIP_ID0, &version); + wsa883x->version = version; + + switch (wsa883x->variant) { + case WSA8830: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n", + wsa883x->version); + break; + case WSA8835: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n", + wsa883x->version); + break; + case WSA8832: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n", + wsa883x->version); + break; + case WSA8835_V2: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n", + wsa883x->version); + break; + default: + break; + } + + wsa883x->comp_offset = COMP_OFFSET2; + + /* Initial settings */ + regmap_multi_reg_write(regmap, reg_init, ARRAY_SIZE(reg_init)); + + if (wsa883x->variant == WSA8830 || wsa883x->variant == WSA8832) { + wsa883x->comp_offset = COMP_OFFSET3; + regmap_update_bits(regmap, WSA883X_DRE_CTL_0, + WSA883X_DRE_OFFSET_MASK, + wsa883x->comp_offset); + } +} + +static int wsa883x_update_status(struct sdw_slave *slave, + enum sdw_slave_status status) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) + wsa883x_init(wsa883x); + + return 0; +} + +static int wsa883x_port_prep(struct sdw_slave *slave, + struct sdw_prepare_ch *prepare_ch, + enum sdw_port_prep_ops state) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + + if (state == SDW_OPS_PORT_POST_PREP) + wsa883x->port_prepared[prepare_ch->num - 1] = true; + else + wsa883x->port_prepared[prepare_ch->num - 1] = false; + + return 0; +} + +static struct sdw_slave_ops wsa883x_slave_ops = { + .update_status = wsa883x_update_status, + .port_prep = wsa883x_port_prep, +}; + +static int wsa_dev_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = wsa883x->dev_mode; + + return 0; +} + +static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (wsa883x->dev_mode == ucontrol->value.enumerated.item[0]) + return 0; + + wsa883x->dev_mode = ucontrol->value.enumerated.item[0]; + + return 1; +} + +static const DECLARE_TLV_DB_SCALE(pa_gain, -300, 150, -300); + +static int wsa883x_get_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *data = snd_soc_component_get_drvdata(comp); + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; + int portidx = mixer->reg; + + ucontrol->value.integer.value[0] = data->port_enable[portidx]; + + return 0; +} + +static int wsa883x_set_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *data = snd_soc_component_get_drvdata(comp); + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; + int portidx = mixer->reg; + + if (ucontrol->value.integer.value[0]) { + if (data->port_enable[portidx]) + return 0; + + data->port_enable[portidx] = true; + } else { + if (!data->port_enable[portidx]) + return 0; + + data->port_enable[portidx] = false; + } + + return 1; +} + +static int wsa883x_get_comp_offset(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->comp_offset; + + return 0; +} + +static int wsa883x_set_comp_offset(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (wsa883x->comp_offset == ucontrol->value.integer.value[0]) + return 0; + + wsa883x->comp_offset = ucontrol->value.integer.value[0]; + + return 1; +} + +static int wsa883x_codec_probe(struct snd_soc_component *comp) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(comp); + + snd_soc_component_init_regmap(comp, wsa883x->regmap); + + return 0; +} + +static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + switch (wsa883x->dev_mode) { + case RECEIVER: + snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE, + WSA883X_RXD_MODE_MASK, + WSA883X_RXD_MODE_HIFI); + snd_soc_component_write_field(component, WSA883X_SPKR_PWM_CLK_CTL, + WSA883X_SPKR_PWM_FREQ_SEL_MASK, + WSA883X_SPKR_PWM_FREQ_F600KHZ); + snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, + WSA883X_DRE_PROG_DELAY_MASK, 0x0); + break; + case SPEAKER: + snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE, + WSA883X_RXD_MODE_MASK, + WSA883X_RXD_MODE_NORMAL); + snd_soc_component_write_field(component, WSA883X_SPKR_PWM_CLK_CTL, + WSA883X_SPKR_PWM_FREQ_SEL_MASK, + WSA883X_SPKR_PWM_FREQ_F300KHZ); + snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, + WSA883X_DRE_PROG_DELAY_MASK, 0x9); + break; + default: + break; + } + + snd_soc_component_write_field(component, WSA883X_DRE_CTL_1, + WSA883X_DRE_GAIN_EN_MASK, + WSA883X_DRE_GAIN_FROM_CSR); + if (wsa883x->port_enable[WSA883X_PORT_COMP]) + snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, + WSA883X_DRE_OFFSET_MASK, + wsa883x->comp_offset); + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_COEF_SEL_MASK, + WSA883X_VBAT_ADC_COEF_F_1DIV16); + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_FLT_EN_MASK, 0x1); + snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL, + WSA883X_PDM_EN_MASK, + WSA883X_PDM_ENABLE); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, + WSA883X_GLOBAL_PA_ENABLE); + + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_FLT_EN_MASK, 0x0); + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_COEF_SEL_MASK, + WSA883X_VBAT_ADC_COEF_F_1DIV2); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, 0); + snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL, + WSA883X_PDM_EN_MASK, 0); + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget wsa883x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN"), + SND_SOC_DAPM_SPK("SPKR", wsa883x_spkr_event), +}; + +static const struct snd_kcontrol_new wsa883x_snd_controls[] = { + SOC_SINGLE_RANGE_TLV("PA Volume", WSA883X_DRE_CTL_1, 1, + 0x0, 0x1f, 1, pa_gain), + SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum, + wsa_dev_mode_get, wsa_dev_mode_put), + SOC_SINGLE_EXT("COMP Offset", SND_SOC_NOPM, 0, 4, 0, + wsa883x_get_comp_offset, wsa883x_set_comp_offset), + SOC_SINGLE_EXT("DAC Switch", WSA883X_PORT_DAC, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), + SOC_SINGLE_EXT("COMP Switch", WSA883X_PORT_COMP, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), + SOC_SINGLE_EXT("BOOST Switch", WSA883X_PORT_BOOST, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), + SOC_SINGLE_EXT("VISENSE Switch", WSA883X_PORT_VISENSE, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), +}; + +static const struct snd_soc_dapm_route wsa883x_audio_map[] = { + {"SPKR", NULL, "IN"}, +}; + +static const struct snd_soc_component_driver wsa883x_component_drv = { + .name = "WSA883x", + .probe = wsa883x_codec_probe, + .controls = wsa883x_snd_controls, + .num_controls = ARRAY_SIZE(wsa883x_snd_controls), + .dapm_widgets = wsa883x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets), + .dapm_routes = wsa883x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map), +}; + +static int wsa883x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev); + int i; + + wsa883x->active_ports = 0; + for (i = 0; i < WSA883X_MAX_SWR_PORTS; i++) { + if (!wsa883x->port_enable[i]) + continue; + + wsa883x->port_config[wsa883x->active_ports] = wsa883x_pconfig[i]; + wsa883x->active_ports++; + } + + wsa883x->sconfig.frame_rate = params_rate(params); + + return sdw_stream_add_slave(wsa883x->slave, &wsa883x->sconfig, + wsa883x->port_config, wsa883x->active_ports, + wsa883x->sruntime); +} + +static int wsa883x_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev); + + sdw_stream_remove_slave(wsa883x->slave, wsa883x->sruntime); + + return 0; +} + +static int wsa883x_set_sdw_stream(struct snd_soc_dai *dai, + void *stream, int direction) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev); + + wsa883x->sruntime = stream; + + return 0; +} + +static int wsa883x_digital_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + + if (mute) { + snd_soc_component_write_field(component, WSA883X_DRE_CTL_1, + WSA883X_DRE_GAIN_EN_MASK, 0); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, 0); + + } else { + snd_soc_component_write_field(component, WSA883X_DRE_CTL_1, + WSA883X_DRE_GAIN_EN_MASK, + WSA883X_DRE_GAIN_FROM_CSR); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, 1); + + } + + return 0; +} + +static const struct snd_soc_dai_ops wsa883x_dai_ops = { + .hw_params = wsa883x_hw_params, + .hw_free = wsa883x_hw_free, + .mute_stream = wsa883x_digital_mute, + .set_stream = wsa883x_set_sdw_stream, +}; + +static struct snd_soc_dai_driver wsa883x_dais[] = { + { + .name = "SPKR", + .playback = { + .stream_name = "SPKR Playback", + .rates = WSA883X_RATES | WSA883X_FRAC_RATES, + .formats = WSA883X_FORMATS, + .rate_max = 8000, + .rate_min = 352800, + .channels_min = 1, + .channels_max = 1, + }, + .ops = &wsa883x_dai_ops, + }, +}; + +static int wsa883x_probe(struct sdw_slave *pdev, + const struct sdw_device_id *id) +{ + struct wsa883x_priv *wsa883x; + struct device *dev = &pdev->dev; + int ret; + + wsa883x = devm_kzalloc(&pdev->dev, sizeof(*wsa883x), GFP_KERNEL); + if (!wsa883x) + return -ENOMEM; + + wsa883x->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(wsa883x->vdd)) { + dev_err(dev, "No vdd regulator found\n"); + return PTR_ERR(wsa883x->vdd); + } + + ret = regulator_enable(wsa883x->vdd); + if (ret) { + dev_err(dev, "Failed to enable vdd regulator (%d)\n", ret); + return ret; + } + + wsa883x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown", + GPIOD_FLAGS_BIT_NONEXCLUSIVE); + if (IS_ERR(wsa883x->sd_n)) { + dev_err(&pdev->dev, "Shutdown Control GPIO not found\n"); + ret = PTR_ERR(wsa883x->sd_n); + goto err; + } + + dev_set_drvdata(&pdev->dev, wsa883x); + wsa883x->slave = pdev; + wsa883x->dev = &pdev->dev; + wsa883x->sconfig.ch_count = 1; + wsa883x->sconfig.bps = 1; + wsa883x->sconfig.direction = SDW_DATA_DIR_RX; + wsa883x->sconfig.type = SDW_STREAM_PDM; + + pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0); + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; + gpiod_direction_output(wsa883x->sd_n, 1); + + wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config); + if (IS_ERR(wsa883x->regmap)) { + dev_err(&pdev->dev, "regmap_init failed\n"); + ret = PTR_ERR(wsa883x->regmap); + goto err; + } + pm_runtime_set_autosuspend_delay(dev, 3000); + pm_runtime_use_autosuspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + ret = devm_snd_soc_register_component(&pdev->dev, + &wsa883x_component_drv, + wsa883x_dais, + ARRAY_SIZE(wsa883x_dais)); +err: + if (ret) + regulator_disable(wsa883x->vdd); + + return ret; + +} + +static int __maybe_unused wsa883x_runtime_suspend(struct device *dev) +{ + struct regmap *regmap = dev_get_regmap(dev, NULL); + struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); + + gpiod_direction_output(wsa883x->sd_n, 0); + + regcache_cache_only(regmap, true); + regcache_mark_dirty(regmap); + + regulator_disable(wsa883x->vdd); + return 0; +} + +static int __maybe_unused wsa883x_runtime_resume(struct device *dev) +{ + struct sdw_slave *slave = dev_to_sdw_dev(dev); + struct regmap *regmap = dev_get_regmap(dev, NULL); + struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); + unsigned long time; + int ret; + + ret = regulator_enable(wsa883x->vdd); + if (ret) { + dev_err(dev, "Failed to enable vdd regulator (%d)\n", ret); + return ret; + } + + gpiod_direction_output(wsa883x->sd_n, 1); + + time = wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA883X_PROBE_TIMEOUT)); + if (!time) { + dev_err(dev, "Initialization not complete, timed out\n"); + gpiod_direction_output(wsa883x->sd_n, 0); + regulator_disable(wsa883x->vdd); + return -ETIMEDOUT; + } + + usleep_range(20000, 20010); + regcache_cache_only(regmap, false); + regcache_sync(regmap); + + return 0; +} + +static const struct dev_pm_ops wsa883x_pm_ops = { + SET_RUNTIME_PM_OPS(wsa883x_runtime_suspend, wsa883x_runtime_resume, NULL) +}; + +static const struct sdw_device_id wsa883x_swr_id[] = { + SDW_SLAVE_ENTRY(0x0217, 0x0202, 0), + {}, +}; + +MODULE_DEVICE_TABLE(sdw, wsa883x_swr_id); + +static struct sdw_driver wsa883x_codec_driver = { + .driver = { + .name = "wsa883x-codec", + .pm = &wsa883x_pm_ops, + .suppress_bind_attrs = true, + }, + .probe = wsa883x_probe, + .ops = &wsa883x_slave_ops, + .id_table = wsa883x_swr_id, +}; + +module_sdw_driver(wsa883x_codec_driver); + +MODULE_DESCRIPTION("WSA883x codec driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/zl38060.c b/sound/soc/codecs/zl38060.c index 6cae0fb08093..c3d0a2a7c36f 100644 --- a/sound/soc/codecs/zl38060.c +++ b/sound/soc/codecs/zl38060.c @@ -385,7 +385,6 @@ static const struct snd_soc_component_driver zl38_component_dev = { .dapm_routes = zl38_dapm_routes, .num_dapm_routes = ARRAY_SIZE(zl38_dapm_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static void chip_gpio_set(struct gpio_chip *c, unsigned int offset, int val) |