diff options
author | Takashi Iwai <tiwai@suse.de> | 2022-05-23 16:03:04 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-05-23 16:03:04 +0200 |
commit | 0163717ed5dec4fc3aaf937baa9f66f21ca11c1d (patch) | |
tree | b0618a944385d1d35bd829c9aa09eddb5c9633fa /sound/soc/codecs | |
parent | 1693e265e0a5dbe11fba21b48272dd15dbb71ec0 (diff) | |
parent | e5cd20e0d6713138444cc3f3f982712cf9a36143 (diff) |
Merge tag 'asoc-v5.19' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v5.19
This is quite a big update, partly due to the addition of some larger
drivers (more of which is to follow since at least the AVS driver is
still a work in progress) and partly due to Charles' work sorting out
our handling of endianness. As has been the case recently it's much
more about drivers than the core.
- Overhaul of endianness specification for data formats, avoiding
needless restrictions due to CODECs.
- Initial stages of Intel AVS driver merge.
- Introduction of v4 IPC mechanism for SOF.
- TDM mode support for AK4613.
- Support for Analog Devices ADAU1361, Cirrus Logic CS35L45, Maxim
MAX98396, MediaTek MT8186, NXP i.MX8 micfil and SAI interfaces,
nVidia Tegra186 ASRC, and Texas Instruments TAS2764 and TAS2780
Diffstat (limited to 'sound/soc/codecs')
217 files changed, 4792 insertions, 1149 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f46a22660103..6165db92a629 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -65,6 +65,8 @@ config SND_SOC_ALL_CODECS imply SND_SOC_CS35L36 imply SND_SOC_CS35L41_SPI imply SND_SOC_CS35L41_I2C + imply SND_SOC_CS35L45_I2C + imply SND_SOC_CS35L45_SPI imply SND_SOC_CS42L42 imply SND_SOC_CS42L51_I2C imply SND_SOC_CS42L52 @@ -127,6 +129,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_MAX98373_I2C imply SND_SOC_MAX98373_SDW imply SND_SOC_MAX98390 + imply SND_SOC_MAX98396 imply SND_SOC_MAX9850 imply SND_SOC_MAX9860 imply SND_SOC_MAX9759 @@ -168,6 +171,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_RT1011 imply SND_SOC_RT1015 imply SND_SOC_RT1015P + imply SND_SOC_RT1016 imply SND_SOC_RT1019 imply SND_SOC_RT1305 imply SND_SOC_RT1308 @@ -265,7 +269,8 @@ config SND_SOC_ALL_CODECS imply SND_SOC_WM8711 imply SND_SOC_WM8727 imply SND_SOC_WM8728 - imply SND_SOC_WM8731 + imply SND_SOC_WM8731_I2C + imply SND_SOC_WM8731_SPI imply SND_SOC_WM8737 imply SND_SOC_WM8741 imply SND_SOC_WM8750 @@ -655,6 +660,34 @@ config SND_SOC_CS35L41_I2C select SND_SOC_CS35L41 select REGMAP_I2C +config SND_SOC_CS35L45_TABLES + tristate + +config SND_SOC_CS35L45 + tristate + +config SND_SOC_CS35L45_SPI + tristate "Cirrus Logic CS35L45 CODEC (SPI)" + depends on SPI_MASTER + select REGMAP + select REGMAP_SPI + select SND_SOC_CS35L45_TABLES + select SND_SOC_CS35L45 + help + Enable support for Cirrus Logic CS35L45 smart speaker amplifier + with SPI control. + +config SND_SOC_CS35L45_I2C + tristate "Cirrus Logic CS35L45 CODEC (I2C)" + depends on I2C + select REGMAP + select REGMAP_I2C + select SND_SOC_CS35L45_TABLES + select SND_SOC_CS35L45 + help + Enable support for Cirrus Logic CS35L45 smart speaker amplifier + with I2C control. + config SND_SOC_CS42L42 tristate "Cirrus Logic CS42L42 CODEC" depends on I2C @@ -953,7 +986,6 @@ config SND_SOC_MAX98095 config SND_SOC_MAX98357A tristate "Maxim MAX98357A CODEC" - depends on GPIOLIB config SND_SOC_MAX98371 tristate @@ -1015,6 +1047,15 @@ config SND_SOC_MAX98390 tristate "Maxim Integrated MAX98390 Speaker Amplifier" depends on I2C +config SND_SOC_MAX98396 + tristate "Analog Devices MAX98396 Speaker Amplifier" + depends on I2C + help + Enable support for Analog Devices MAX98396 audio + amplifier. The device provides a PCM interface for + audio data and a standard I2C interface for control + data communication. + config SND_SOC_MAX9850 tristate depends on I2C @@ -1213,7 +1254,10 @@ config SND_SOC_RT1015 config SND_SOC_RT1015P tristate - depends on GPIOLIB + +config SND_SOC_RT1016 + tristate + depends on I2C config SND_SOC_RT1019 tristate @@ -1753,8 +1797,19 @@ config SND_SOC_WM8728 depends on SND_SOC_I2C_AND_SPI config SND_SOC_WM8731 - tristate "Wolfson Microelectronics WM8731 CODEC" - depends on SND_SOC_I2C_AND_SPI + tristate + +config SND_SOC_WM8731_I2C + tristate "Wolfson Microelectronics WM8731 CODEC with I2C" + depends on I2C + select REGMAP + select SND_SOC_WM8731 + +config SND_SOC_WM8731_SPI + tristate "Wolfson Microelectronics WM8731 CODEC with SPI" + depends on SPI + select REGMAP + select SND_SOC_WM8731 config SND_SOC_WM8737 tristate "Wolfson Microelectronics WM8737 ADC" @@ -1811,7 +1866,7 @@ config SND_SOC_WM8904 depends on I2C config SND_SOC_WM8940 - tristate + tristate "Wolfson Microelectronics WM8940 codec" depends on I2C config SND_SOC_WM8955 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 8637e9e869e3..28dc4edfd01f 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -60,6 +60,10 @@ snd-soc-cs35l41-lib-objs := cs35l41-lib.o snd-soc-cs35l41-objs := cs35l41.o snd-soc-cs35l41-spi-objs := cs35l41-spi.o snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o +snd-soc-cs35l45-tables-objs := cs35l45-tables.o +snd-soc-cs35l45-objs := cs35l45.o +snd-soc-cs35l45-spi-objs := cs35l45-spi.o +snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o snd-soc-cs42l42-objs := cs42l42.o snd-soc-cs42l51-objs := cs42l51.o snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o @@ -135,6 +139,7 @@ snd-soc-max98373-objs := max98373.o snd-soc-max98373-i2c-objs := max98373-i2c.o snd-soc-max98373-sdw-objs := max98373-sdw.o snd-soc-max98390-objs := max98390.o +snd-soc-max98396-objs := max98396.o snd-soc-max9850-objs := max9850.o snd-soc-max9860-objs := max9860.o snd-soc-mc13783-objs := mc13783.o @@ -181,6 +186,7 @@ snd-soc-rl6347a-objs := rl6347a.o snd-soc-rt1011-objs := rt1011.o snd-soc-rt1015-objs := rt1015.o snd-soc-rt1015p-objs := rt1015p.o +snd-soc-rt1016-objs := rt1016.o snd-soc-rt1019-objs := rt1019.o snd-soc-rt1305-objs := rt1305.o snd-soc-rt1308-objs := rt1308.o @@ -290,6 +296,8 @@ snd-soc-wm8711-objs := wm8711.o snd-soc-wm8727-objs := wm8727.o snd-soc-wm8728-objs := wm8728.o snd-soc-wm8731-objs := wm8731.o +snd-soc-wm8731-i2c-objs := wm8731-i2c.o +snd-soc-wm8731-spi-objs := wm8731-spi.o snd-soc-wm8737-objs := wm8737.o snd-soc-wm8741-objs := wm8741.o snd-soc-wm8750-objs := wm8750.o @@ -404,6 +412,10 @@ obj-$(CONFIG_SND_SOC_CS35L41) += snd-soc-cs35l41.o obj-$(CONFIG_SND_SOC_CS35L41_LIB) += snd-soc-cs35l41-lib.o obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o +obj-$(CONFIG_SND_SOC_CS35L45_TABLES) += snd-soc-cs35l45-tables.o +obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o +obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o +obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o @@ -474,6 +486,7 @@ obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o obj-$(CONFIG_SND_SOC_MAX98373_I2C) += snd-soc-max98373-i2c.o obj-$(CONFIG_SND_SOC_MAX98373_SDW) += snd-soc-max98373-sdw.o obj-$(CONFIG_SND_SOC_MAX98390) += snd-soc-max98390.o +obj-$(CONFIG_SND_SOC_MAX98396) += snd-soc-max98396.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o @@ -520,6 +533,7 @@ obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o obj-$(CONFIG_SND_SOC_RT1011) += snd-soc-rt1011.o obj-$(CONFIG_SND_SOC_RT1015) += snd-soc-rt1015.o obj-$(CONFIG_SND_SOC_RT1015P) += snd-soc-rt1015p.o +obj-$(CONFIG_SND_SOC_RT1016) += snd-soc-rt1016.o obj-$(CONFIG_SND_SOC_RT1019) += snd-soc-rt1019.o obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o obj-$(CONFIG_SND_SOC_RT1308) += snd-soc-rt1308.o @@ -632,6 +646,8 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o +obj-$(CONFIG_SND_SOC_WM8731_I2C) += snd-soc-wm8731-i2c.o +obj-$(CONFIG_SND_SOC_WM8731_SPI) += snd-soc-wm8731-spi.o obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c index 3d509a65e4ca..4cb8d87f9011 100644 --- a/sound/soc/codecs/ad193x-i2c.c +++ b/sound/soc/codecs/ad193x-i2c.c @@ -20,10 +20,10 @@ static const struct i2c_device_id ad193x_id[] = { }; MODULE_DEVICE_TABLE(i2c, ad193x_id); -static int ad193x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad193x_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(ad193x_id, client); config = ad193x_regmap_config; config.val_bits = 8; @@ -38,7 +38,7 @@ static struct i2c_driver ad193x_i2c_driver = { .driver = { .name = "ad193x", }, - .probe = ad193x_i2c_probe, + .probe_new = ad193x_i2c_probe, .id_table = ad193x_id, }; module_i2c_driver(ad193x_i2c_driver); diff --git a/sound/soc/codecs/adau1372-i2c.c b/sound/soc/codecs/adau1372-i2c.c index fc87a76ff1ee..8ed0ffdedbc9 100644 --- a/sound/soc/codecs/adau1372-i2c.c +++ b/sound/soc/codecs/adau1372-i2c.c @@ -14,7 +14,7 @@ #include "adau1372.h" -static int adau1372_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int adau1372_i2c_probe(struct i2c_client *client) { return adau1372_probe(&client->dev, devm_regmap_init_i2c(client, &adau1372_regmap_config), NULL); @@ -30,7 +30,7 @@ static struct i2c_driver adau1372_i2c_driver = { .driver = { .name = "adau1372", }, - .probe = adau1372_i2c_probe, + .probe_new = adau1372_i2c_probe, .id_table = adau1372_i2c_ids, }; module_i2c_driver(adau1372_i2c_driver); diff --git a/sound/soc/codecs/adau1372.c b/sound/soc/codecs/adau1372.c index 1faa4c426365..a9f89e8565ec 100644 --- a/sound/soc/codecs/adau1372.c +++ b/sound/soc/codecs/adau1372.c @@ -859,6 +859,7 @@ static const struct snd_soc_component_driver adau1372_driver = { .num_dapm_widgets = ARRAY_SIZE(adau1372_dapm_widgets), .dapm_routes = adau1372_dapm_routes, .num_dapm_routes = ARRAY_SIZE(adau1372_dapm_routes), + .endianness = 1, }; static const struct snd_soc_dai_ops adau1372_dai_ops = { diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 46128aaceae9..a9032b5c8d78 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1473,8 +1473,7 @@ static const struct snd_soc_component_driver adau1373_component_driver = { .non_legacy_dai_naming = 1, }; -static int adau1373_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adau1373_i2c_probe(struct i2c_client *client) { struct adau1373 *adau1373; int ret; @@ -1508,7 +1507,7 @@ static struct i2c_driver adau1373_i2c_driver = { .driver = { .name = "adau1373", }, - .probe = adau1373_i2c_probe, + .probe_new = adau1373_i2c_probe, .id_table = adau1373_i2c_id, }; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index dba9af753188..98768e5300f0 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -785,8 +785,7 @@ static const struct regmap_config adau1701_regmap = { .reg_read = adau1701_reg_read, }; -static int adau1701_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adau1701_i2c_probe(struct i2c_client *client) { struct adau1701 *adau1701; struct device *dev = &client->dev; @@ -878,7 +877,7 @@ static struct i2c_driver adau1701_i2c_driver = { .name = "adau1701", .of_match_table = of_match_ptr(adau1701_dt_ids), }, - .probe = adau1701_i2c_probe, + .probe_new = adau1701_i2c_probe, .id_table = adau1701_i2c_id, }; diff --git a/sound/soc/codecs/adau1761-i2c.c b/sound/soc/codecs/adau1761-i2c.c index c8fce37e5cfa..0683caf86aea 100644 --- a/sound/soc/codecs/adau1761-i2c.c +++ b/sound/soc/codecs/adau1761-i2c.c @@ -14,10 +14,12 @@ #include "adau1761.h" -static int adau1761_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id adau1761_i2c_ids[]; + +static int adau1761_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(adau1761_i2c_ids, client); config = adau1761_regmap_config; config.val_bits = 8; @@ -59,7 +61,7 @@ static struct i2c_driver adau1761_i2c_driver = { .name = "adau1761", .of_match_table = of_match_ptr(adau1761_i2c_dt_ids), }, - .probe = adau1761_i2c_probe, + .probe_new = adau1761_i2c_probe, .remove = adau1761_i2c_remove, .id_table = adau1761_i2c_ids, }; diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index fb006fc81653..8f887227981f 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -556,8 +556,6 @@ static const struct snd_soc_dapm_route adau1761_dapm_routes[] = { { "Left DAC", NULL, "Interpolator Resync Clock" }, { "Right DAC", NULL, "Interpolator Resync Clock" }, - { "DSP", NULL, "Digital Clock 0" }, - { "Slew Clock", NULL, "Digital Clock 0" }, { "Right Playback Mixer", NULL, "Slew Clock" }, { "Left Playback Mixer", NULL, "Slew Clock" }, @@ -569,6 +567,56 @@ static const struct snd_soc_dapm_route adau1761_dapm_routes[] = { { "Digital Clock 1", NULL, "SYSCLK" }, }; +static const struct snd_soc_dapm_route adau1761_dapm_dsp_routes[] = { + { "DSP", NULL, "Digital Clock 0" }, +}; + +static int adau1761_compatibility_probe(struct device *dev) +{ + struct adau *adau = dev_get_drvdata(dev); + struct regmap *regmap = adau->regmap; + int val, ret = 0; + + /* Only consider compatibility mode when ADAU1361 was specified. */ + if (adau->type != ADAU1361) + return 0; + + regcache_cache_bypass(regmap, true); + + /* + * This will enable the core clock and bypass the PLL, + * so that we can access the registers for probing purposes + * (without having to set up the PLL). + */ + regmap_write(regmap, ADAU17X1_CLOCK_CONTROL, + ADAU17X1_CLOCK_CONTROL_SYSCLK_EN); + + /* + * ADAU17X1_SERIAL_SAMPLING_RATE doesn't exist in non-DSP chips; + * reading it results in zero at all times, and write is a no-op. + * Use this register to probe for ADAU1761. + */ + regmap_write(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, 1); + ret = regmap_read(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, &val); + if (ret) + goto exit; + if (val != 1) + goto exit; + regmap_write(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, 0); + ret = regmap_read(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, &val); + if (ret) + goto exit; + if (val != 0) + goto exit; + + adau->type = ADAU1761_AS_1361; +exit: + /* Disable core clock after probing. */ + regmap_write(regmap, ADAU17X1_CLOCK_CONTROL, 0); + regcache_cache_bypass(regmap, false); + return ret; +} + static int adau1761_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { @@ -823,7 +871,11 @@ static int adau1761_component_probe(struct snd_soc_component *component) if (ret) return ret; - if (adau->type == ADAU1761) { + /* + * If we've got an ADAU1761, or an ADAU1761 operating as an + * ADAU1361, we need these non-DSP related DAPM widgets and routes. + */ + if (adau->type == ADAU1761 || adau->type == ADAU1761_AS_1361) { ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets, ARRAY_SIZE(adau1761_dapm_widgets)); if (ret) @@ -834,7 +886,29 @@ static int adau1761_component_probe(struct snd_soc_component *component) if (ret) return ret; } - + /* + * These routes are DSP related and only used when we have a + * bona fide ADAU1761. + */ + if (adau->type == ADAU1761) { + ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_dsp_routes, + ARRAY_SIZE(adau1761_dapm_dsp_routes)); + if (ret) + return ret; + } + /* + * In the ADAU1761, by default, the AIF is routed to the DSP, whereas + * for the ADAU1361, the AIF is permanently routed to the ADC and DAC. + * Thus, if we have an ADAU1761 masquerading as an ADAU1361, + * we need to explicitly route the AIF to the ADC and DAC. + * For the ADAU1761, this is normally done by set_tdm_slot, but this + * function is not necessarily called during stream setup, so set up + * the compatible AIF routings here from the start. + */ + if (adau->type == ADAU1761_AS_1361) { + regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE, 0x01); + regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x01); + } ret = adau17x1_add_routes(component); if (ret < 0) return ret; @@ -919,6 +993,10 @@ int adau1761_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = adau1761_compatibility_probe(dev); + if (ret) + return ret; + /* Enable cache only mode as we could miss writes before bias level * reaches standby and the core clock is enabled */ regcache_cache_only(regmap, true); diff --git a/sound/soc/codecs/adau1781-i2c.c b/sound/soc/codecs/adau1781-i2c.c index 1c476429ad99..e046de0ebcc7 100644 --- a/sound/soc/codecs/adau1781-i2c.c +++ b/sound/soc/codecs/adau1781-i2c.c @@ -14,10 +14,12 @@ #include "adau1781.h" -static int adau1781_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id adau1781_i2c_ids[]; + +static int adau1781_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(adau1781_i2c_ids, client); config = adau1781_regmap_config; config.val_bits = 8; @@ -55,7 +57,7 @@ static struct i2c_driver adau1781_i2c_driver = { .name = "adau1781", .of_match_table = of_match_ptr(adau1781_i2c_dt_ids), }, - .probe = adau1781_i2c_probe, + .probe_new = adau1781_i2c_probe, .remove = adau1781_i2c_remove, .id_table = adau1781_i2c_ids, }; diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index af05463af4ac..c0f44ecef606 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -334,6 +334,17 @@ static bool adau17x1_has_dsp(struct adau *adau) } } +/* Chip has a DSP but we're pretending it doesn't. */ +static bool adau17x1_has_disused_dsp(struct adau *adau) +{ + switch (adau->type) { + case ADAU1761_AS_1361: + return true; + default: + return false; + } +} + static bool adau17x1_has_safeload(struct adau *adau) { switch (adau->type) { @@ -516,10 +527,11 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, ADAU17X1_CONVERTER0_CONVSR_MASK, div); - if (adau17x1_has_dsp(adau)) { + + if (adau17x1_has_dsp(adau) || adau17x1_has_disused_dsp(adau)) regmap_write(adau->regmap, ADAU17X1_SERIAL_SAMPLING_RATE, div); + if (adau17x1_has_dsp(adau)) regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dsp_div); - } if (adau->sigmadsp) { ret = adau17x1_setup_firmware(component, params_rate(params)); @@ -663,7 +675,7 @@ static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai, switch (slot_width * slots) { case 32: - if (adau->type == ADAU1761) + if (adau->type == ADAU1761 || adau->type == ADAU1761_AS_1361) return -EINVAL; ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK32; @@ -738,7 +750,7 @@ static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai, regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1, ADAU17X1_SERIAL_PORT1_BCLK_MASK, ser_ctrl1); - if (!adau17x1_has_dsp(adau)) + if (!adau17x1_has_dsp(adau) && !adau17x1_has_disused_dsp(adau)) return 0; if (adau->dsp_bypass[SNDRV_PCM_STREAM_PLAYBACK]) { diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index 98a3b6f5bc96..5e58abfffc3d 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h @@ -10,6 +10,7 @@ enum adau17x1_type { ADAU1361, ADAU1761, + ADAU1761_AS_1361, ADAU1381, ADAU1781, }; diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c index 82a49c85d536..9f137a0634d5 100644 --- a/sound/soc/codecs/adau1977-i2c.c +++ b/sound/soc/codecs/adau1977-i2c.c @@ -14,10 +14,12 @@ #include "adau1977.h" -static int adau1977_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id adau1977_i2c_ids[]; + +static int adau1977_i2c_probe(struct i2c_client *client) { struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(adau1977_i2c_ids, client); config = adau1977_regmap_config; config.val_bits = 8; @@ -40,7 +42,7 @@ static struct i2c_driver adau1977_i2c_driver = { .driver = { .name = "adau1977", }, - .probe = adau1977_i2c_probe, + .probe_new = adau1977_i2c_probe, .id_table = adau1977_i2c_ids, }; module_i2c_driver(adau1977_i2c_driver); diff --git a/sound/soc/codecs/adau7118-i2c.c b/sound/soc/codecs/adau7118-i2c.c index aa7afb3b826d..afed48401b25 100644 --- a/sound/soc/codecs/adau7118-i2c.c +++ b/sound/soc/codecs/adau7118-i2c.c @@ -48,8 +48,7 @@ static const struct regmap_config adau7118_regmap_config = { .volatile_reg = adau7118_volatile, }; -static int adau7118_probe_i2c(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int adau7118_probe_i2c(struct i2c_client *i2c) { struct regmap *map; @@ -79,7 +78,7 @@ static struct i2c_driver adau7118_driver = { .name = "adau7118", .of_match_table = adau7118_of_match, }, - .probe = adau7118_probe_i2c, + .probe_new = adau7118_probe_i2c, .id_table = adau7118_id, }; module_i2c_driver(adau7118_driver); diff --git a/sound/soc/codecs/adav803.c b/sound/soc/codecs/adav803.c index 0f565b851ea5..bf181bbaabed 100644 --- a/sound/soc/codecs/adav803.c +++ b/sound/soc/codecs/adav803.c @@ -19,8 +19,7 @@ static const struct i2c_device_id adav803_id[] = { }; MODULE_DEVICE_TABLE(i2c, adav803_id); -static int adav803_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adav803_probe(struct i2c_client *client) { return adav80x_bus_probe(&client->dev, devm_regmap_init_i2c(client, &adav80x_regmap_config)); @@ -30,7 +29,7 @@ static struct i2c_driver adav803_driver = { .driver = { .name = "adav803", }, - .probe = adav803_probe, + .probe_new = adav803_probe, .id_table = adav803_id, }; module_i2c_driver(adav803_driver); diff --git a/sound/soc/codecs/ak4118.c b/sound/soc/codecs/ak4118.c index 2e6bafd2a821..5c4a78c16733 100644 --- a/sound/soc/codecs/ak4118.c +++ b/sound/soc/codecs/ak4118.c @@ -356,8 +356,7 @@ static const struct regmap_config ak4118_regmap = { .max_register = AK4118_REG_MAX - 1, }; -static int ak4118_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4118_i2c_probe(struct i2c_client *i2c) { struct ak4118_priv *ak4118; int ret; @@ -416,7 +415,7 @@ static struct i2c_driver ak4118_i2c_driver = { .of_match_table = of_match_ptr(ak4118_of_match), }, .id_table = ak4118_id_table, - .probe = ak4118_i2c_probe, + .probe_new = ak4118_i2c_probe, }; module_i2c_driver(ak4118_i2c_driver); diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 91e7a57c43da..cc803e730c6e 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -405,8 +405,7 @@ static const struct snd_soc_component_driver soc_component_dev_ak4535 = { .non_legacy_dai_naming = 1, }; -static int ak4535_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4535_i2c_probe(struct i2c_client *i2c) { struct ak4535_priv *ak4535; int ret; @@ -441,7 +440,7 @@ static struct i2c_driver ak4535_i2c_driver = { .driver = { .name = "ak4535", }, - .probe = ak4535_i2c_probe, + .probe_new = ak4535_i2c_probe, .id_table = ak4535_i2c_id, }; diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 034195c83bd7..55e773f92122 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -10,11 +10,97 @@ // Based on ak4535.c by Richard Purdie // Based on wm8753.c by Liam Girdwood +/* + * +-------+ + * |AK4613 | + * SDTO1 <-| | + * | | + * SDTI1 ->| | + * SDTI2 ->| | + * SDTI3 ->| | + * +-------+ + * + * +---+ + * clk | |___________________________________________... + * + * [TDM512] + * SDTO1 [L1][R1][L2][R2] + * SDTI1 [L1][R1][L2][R2][L3][R3][L4][R4][L5][R5][L6][R6] + * + * [TDM256] + * SDTO1 [L1][R1][L2][R2] + * SDTI1 [L1][R1][L2][R2][L3][R3][L4][R4] + * SDTI2 [L5][R5][L6][R6] + * + * [TDM128] + * SDTO1 [L1][R1][L2][R2] + * SDTI1 [L1][R1][L2][R2] + * SDTI2 [L3][R3][L4][R4] + * SDTI3 [L5][R5][L6][R6] + * + * [STEREO] + * Playback 2ch : SDTI1 + * Capture 2ch : SDTO1 + * + * [TDM512] + * Playback 12ch : SDTI1 + * Capture 4ch : SDTO1 + * + * [TDM256] + * Playback 12ch : SDTI1 + SDTI2 + * Playback 8ch : SDTI1 + * Capture 4ch : SDTO1 + * + * [TDM128] + * Playback 12ch : SDTI1 + SDTI2 + SDTI3 + * Playback 8ch : SDTI1 + SDTI2 + * Playback 4ch : SDTI1 + * Capture 4ch : SDTO1 + * + * + * !!! NOTE !!! + * + * Renesas is the only user of ak4613 on upstream so far, + * but the chip connection is like below. + * Thus, Renesas can't test all connection case. + * Tested TDM is very limited. + * + * +-----+ +-----------+ + * | SoC | | AK4613 | + * | |<-----|SDTO1 IN1|<-- Mic + * | | | IN2| + * | | | | + * | |----->|SDTI1 OUT1|--> Headphone + * +-----+ |SDTI2 OUT2| + * |SDTI3 OUT3| + * | OUT4| + * | OUT5| + * | OUT6| + * +-----------+ + * + * Renesas SoC can handle [2, 6,8] channels. + * Ak4613 can handle [2,4, 8,12] channels. + * + * Because of above HW connection and available channels number, + * Renesas could test are ... + * + * [STEREO] Playback 2ch : SDTI1 + * Capture 2ch : SDTO1 + * [TDM256] Playback 8ch : SDTI1 (*) + * + * (*) it used 8ch data between SoC <-> AK4613 on TDM256 mode, + * but could confirm is only first 2ch because only 1 + * Headphone is connected. + * + * see + * AK4613_ENABLE_TDM_TEST + */ #include <linux/clk.h> #include <linux/delay.h> #include <linux/i2c.h> #include <linux/slab.h> #include <linux/of_device.h> +#include <linux/of_graph.h> #include <linux/module.h> #include <linux/regmap.h> #include <sound/soc.h> @@ -78,29 +164,74 @@ /* OCTRL */ #define OCTRL_MASK (0x3F) -struct ak4613_formats { - unsigned int width; - unsigned int fmt; -}; +/* + * configs + * + * 0x000000BA + * + * B : AK4613_CONFIG_SDTI_x + * A : AK4613_CONFIG_MODE_x + */ +#define AK4613_CONFIG_SET(priv, x) priv->configs |= AK4613_CONFIG_##x +#define AK4613_CONFIG_GET(priv, x) (priv->configs & AK4613_CONFIG_##x##_MASK) + +/* + * AK4613_CONFIG_SDTI_x + * + * It indicates how many SDTIx is connected. + */ +#define AK4613_CONFIG_SDTI_MASK (0xF << 4) +#define AK4613_CONFIG_SDTI(x) (((x) & 0xF) << 4) +#define AK4613_CONFIG_SDTI_set(priv, x) AK4613_CONFIG_SET(priv, SDTI(x)) +#define AK4613_CONFIG_SDTI_get(priv) ((AK4613_CONFIG_GET(priv, SDTI) >> 4) & 0xF) + +/* + * AK4613_CONFIG_MODE_x + * + * Same as Ctrl1 :: TDM1/TDM0 + * No shift is requested + * see + * AK4613_CTRL1_TO_MODE() + * Table 11/12/13/14 + */ +#define AK4613_CONFIG_MODE_MASK (0xF) +#define AK4613_CONFIG_MODE_STEREO (0x0) +#define AK4613_CONFIG_MODE_TDM512 (0x1) +#define AK4613_CONFIG_MODE_TDM256 (0x2) +#define AK4613_CONFIG_MODE_TDM128 (0x3) + +/* + * !!!! FIXME !!!! + * + * Because of testable HW limitation, TDM256 8ch TDM was only tested. + * This driver uses AK4613_ENABLE_TDM_TEST instead of new DT property so far. + * Don't hesitate to update driver, you don't need to care compatible + * with Renesas. + * + * #define AK4613_ENABLE_TDM_TEST + */ struct ak4613_interface { - struct ak4613_formats capture; - struct ak4613_formats playback; + unsigned int width; + unsigned int fmt; + u8 dif; }; struct ak4613_priv { struct mutex lock; - const struct ak4613_interface *iface; - struct snd_pcm_hw_constraint_list constraint; + struct snd_pcm_hw_constraint_list constraint_rates; + struct snd_pcm_hw_constraint_list constraint_channels; struct work_struct dummy_write_work; struct snd_soc_component *component; unsigned int rate; unsigned int sysclk; unsigned int fmt; + unsigned int configs; + int cnt; + u8 ctrl1; u8 oc; u8 ic; - int cnt; }; /* @@ -137,14 +268,24 @@ static const struct reg_default ak4613_reg[] = { { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 }, }; -#define AUDIO_IFACE_TO_VAL(fmts) ((fmts - ak4613_iface) << 3) -#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt } +/* + * CTRL1 register + * see + * Table 11/12/13/14 + */ +#define AUDIO_IFACE(_dif, _width, _fmt) \ + { \ + .dif = _dif, \ + .width = _width, \ + .fmt = SND_SOC_DAIFMT_##_fmt,\ + } static const struct ak4613_interface ak4613_iface[] = { - /* capture */ /* playback */ - /* [0] - [2] are not supported */ - [3] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(24, LEFT_J) }, - [4] = { AUDIO_IFACE(24, I2S), AUDIO_IFACE(24, I2S) }, + /* It doesn't support asymmetric format */ + + AUDIO_IFACE(0x03, 24, LEFT_J), + AUDIO_IFACE(0x04, 24, I2S), }; +#define AK4613_CTRL1_TO_MODE(priv) ((priv)->ctrl1 >> 6) /* AK4613_CONFIG_MODE_x */ static const struct regmap_config ak4613_regmap_cfg = { .reg_bits = 8, @@ -250,13 +391,14 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream, priv->cnt = 0; } if (!priv->cnt) - priv->iface = NULL; + priv->ctrl1 = 0; mutex_unlock(&priv->lock); } static void ak4613_hw_constraints(struct ak4613_priv *priv, - struct snd_pcm_runtime *runtime) + struct snd_pcm_substream *substream) { + struct snd_pcm_runtime *runtime = substream->runtime; static const unsigned int ak4613_rates[] = { 32000, 44100, @@ -267,10 +409,36 @@ static void ak4613_hw_constraints(struct ak4613_priv *priv, 176400, 192000, }; - struct snd_pcm_hw_constraint_list *constraint = &priv->constraint; +#define AK4613_CHANNEL_2 0 +#define AK4613_CHANNEL_4 1 +#define AK4613_CHANNEL_8 2 +#define AK4613_CHANNEL_12 3 +#define AK4613_CHANNEL_NONE -1 + static const unsigned int ak4613_channels[] = { + [AK4613_CHANNEL_2] = 2, + [AK4613_CHANNEL_4] = 4, + [AK4613_CHANNEL_8] = 8, + [AK4613_CHANNEL_12] = 12, + }; +#define MODE_MAX 4 +#define SDTx_MAX 4 +#define MASK(x) (1 << AK4613_CHANNEL_##x) + static const int mask_list[MODE_MAX][SDTx_MAX] = { + /* SDTO SDTIx1 SDTIx2 SDTIx3 */ + [AK4613_CONFIG_MODE_STEREO] = { MASK(2), MASK(2), MASK(2), MASK(2)}, + [AK4613_CONFIG_MODE_TDM512] = { MASK(4), MASK(12), MASK(12), MASK(12)}, + [AK4613_CONFIG_MODE_TDM256] = { MASK(4), MASK(8), MASK(8)|MASK(12), MASK(8)|MASK(12)}, + [AK4613_CONFIG_MODE_TDM128] = { MASK(4), MASK(4), MASK(4)|MASK(8), MASK(4)|MASK(8)|MASK(12)}, + }; + struct snd_pcm_hw_constraint_list *constraint; + unsigned int mask; + unsigned int mode; unsigned int fs; + int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + int sdti_num; int i; + constraint = &priv->constraint_rates; constraint->list = ak4613_rates; constraint->mask = 0; constraint->count = 0; @@ -296,6 +464,41 @@ static void ak4613_hw_constraints(struct ak4613_priv *priv, snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, constraint); + + + sdti_num = AK4613_CONFIG_SDTI_get(priv); + if (WARN_ON(sdti_num >= SDTx_MAX)) + return; + + if (priv->cnt) { + /* + * If it was already working, + * the constraint is same as working mode. + */ + mode = AK4613_CTRL1_TO_MODE(priv); + mask = 0; /* no default */ + } else { + /* + * It is not yet working, + * the constraint is based on board configs. + * STEREO mask is default + */ + mode = AK4613_CONFIG_GET(priv, MODE); + mask = mask_list[AK4613_CONFIG_MODE_STEREO][is_play * sdti_num]; + } + + if (WARN_ON(mode >= MODE_MAX)) + return; + + /* add each mode mask */ + mask |= mask_list[mode][is_play * sdti_num]; + + constraint = &priv->constraint_channels; + constraint->list = ak4613_channels; + constraint->mask = mask; + constraint->count = sizeof(ak4613_channels); + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, constraint); } static int ak4613_dai_startup(struct snd_pcm_substream *substream, @@ -304,9 +507,10 @@ static int ak4613_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct ak4613_priv *priv = snd_soc_component_get_drvdata(component); + mutex_lock(&priv->lock); + ak4613_hw_constraints(priv, substream); priv->cnt++; - - ak4613_hw_constraints(priv, substream->runtime); + mutex_unlock(&priv->lock); return 0; } @@ -322,13 +526,13 @@ static int ak4613_dai_set_sysclk(struct snd_soc_dai *codec_dai, return 0; } -static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int format) { struct snd_soc_component *component = dai->component; struct ak4613_priv *priv = snd_soc_component_get_drvdata(component); + unsigned int fmt; - fmt &= SND_SOC_DAIFMT_FORMAT_MASK; - + fmt = format & SND_SOC_DAIFMT_FORMAT_MASK; switch (fmt) { case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_I2S: @@ -338,24 +542,20 @@ static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - return 0; -} - -static bool ak4613_dai_fmt_matching(const struct ak4613_interface *iface, - int is_play, - unsigned int fmt, unsigned int width) -{ - const struct ak4613_formats *fmts; - - fmts = (is_play) ? &iface->playback : &iface->capture; - - if (fmts->fmt != fmt) - return false; - - if (fmts->width != width) - return false; + fmt = format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; + switch (fmt) { + case SND_SOC_DAIFMT_CBC_CFC: + break; + default: + /* + * SUPPORTME + * + * "clock provider" is not yet supperted + */ + return -EINVAL; + } - return true; + return 0; } static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, @@ -364,14 +564,12 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct ak4613_priv *priv = snd_soc_component_get_drvdata(component); - const struct ak4613_interface *iface; struct device *dev = component->dev; unsigned int width = params_width(params); unsigned int fmt = priv->fmt; unsigned int rate; - int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int i, ret; - u8 fmt_ctrl, ctrl2; + u8 ctrl2; rate = params_rate(params); switch (rate) { @@ -397,40 +595,51 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, /* * FIXME * - * It doesn't support TDM at this point + * It doesn't have full TDM suppert yet */ - fmt_ctrl = NO_FMT; ret = -EINVAL; - iface = NULL; mutex_lock(&priv->lock); - if (priv->iface) { - if (ak4613_dai_fmt_matching(priv->iface, is_play, fmt, width)) - iface = priv->iface; + if (priv->cnt > 1) { + /* + * If it was already working, use current priv->ctrl1 + */ + ret = 0; } else { + /* + * It is not yet working, + */ + unsigned int channel = params_channels(params); + u8 tdm; + + /* STEREO or TDM */ + if (channel == 2) + tdm = AK4613_CONFIG_MODE_STEREO; + else + tdm = AK4613_CONFIG_GET(priv, MODE); + for (i = ARRAY_SIZE(ak4613_iface) - 1; i >= 0; i--) { - if (!ak4613_dai_fmt_matching(ak4613_iface + i, - is_play, - fmt, width)) - continue; - iface = ak4613_iface + i; - break; + const struct ak4613_interface *iface = ak4613_iface + i; + + if ((iface->fmt == fmt) && (iface->width == width)) { + /* + * Ctrl1 + * | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | + * |TDM1|TDM0|DIF2|DIF1|DIF0|ATS1|ATS0|SMUTE| + * < tdm > < iface->dif > + */ + priv->ctrl1 = (tdm << 6) | (iface->dif << 3); + ret = 0; + break; + } } } - - if ((priv->iface == NULL) || - (priv->iface == iface)) { - priv->iface = iface; - ret = 0; - } mutex_unlock(&priv->lock); if (ret < 0) goto hw_params_end; - fmt_ctrl = AUDIO_IFACE_TO_VAL(iface); - - snd_soc_component_update_bits(component, CTRL1, FMT_MASK, fmt_ctrl); + snd_soc_component_update_bits(component, CTRL1, FMT_MASK, priv->ctrl1); snd_soc_component_update_bits(component, CTRL2, DFS_MASK, ctrl2); snd_soc_component_update_bits(component, ICTRL, ICTRL_MASK, priv->ic); @@ -574,14 +783,14 @@ static struct snd_soc_dai_driver ak4613_dai = { .playback = { .stream_name = "Playback", .channels_min = 2, - .channels_max = 2, + .channels_max = 12, .rates = AK4613_PCM_RATE, .formats = AK4613_PCM_FMTBIT, }, .capture = { .stream_name = "Capture", .channels_min = 2, - .channels_max = 2, + .channels_max = 4, .rates = AK4613_PCM_RATE, .formats = AK4613_PCM_FMTBIT, }, @@ -626,6 +835,7 @@ static void ak4613_parse_of(struct ak4613_priv *priv, { struct device_node *np = dev->of_node; char prop[32]; + int sdti_num; int i; /* Input 1 - 2 */ @@ -641,10 +851,32 @@ static void ak4613_parse_of(struct ak4613_priv *priv, if (!of_get_property(np, prop, NULL)) priv->oc |= 1 << i; } + + /* + * enable TDM256 test + * + * !!! FIXME !!! + * + * It should be configured by DT or other way + * if it was full supported. + * But it is using ifdef style for now for test + * purpose. + */ +#if defined(AK4613_ENABLE_TDM_TEST) + AK4613_CONFIG_SET(priv, MODE_TDM256); +#endif + + /* + * connected STDI + */ + sdti_num = of_graph_get_endpoint_count(np); + if (WARN_ON((sdti_num > 3) || (sdti_num < 1))) + return; + + AK4613_CONFIG_SDTI_set(priv, sdti_num); } -static int ak4613_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4613_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct device_node *np = dev->of_node; @@ -655,8 +887,11 @@ static int ak4613_i2c_probe(struct i2c_client *i2c, regmap_cfg = NULL; if (np) regmap_cfg = of_device_get_match_data(dev); - else + else { + const struct i2c_device_id *id = + i2c_match_id(ak4613_i2c_id, i2c); regmap_cfg = (const struct regmap_config *)id->driver_data; + } if (!regmap_cfg) return -EINVAL; @@ -667,7 +902,7 @@ static int ak4613_i2c_probe(struct i2c_client *i2c, ak4613_parse_of(priv, dev); - priv->iface = NULL; + priv->ctrl1 = 0; priv->cnt = 0; priv->sysclk = 0; INIT_WORK(&priv->dummy_write_work, ak4613_dummy_write); @@ -694,7 +929,7 @@ static struct i2c_driver ak4613_i2c_driver = { .name = "ak4613-codec", .of_match_table = ak4613_of_match, }, - .probe = ak4613_i2c_probe, + .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 04aef0e72aa5..d8d9cc712d67 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -548,8 +548,7 @@ static const struct regmap_config ak4641_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int ak4641_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak4641_i2c_probe(struct i2c_client *i2c) { struct ak4641_platform_data *pdata = i2c->dev.platform_data; struct ak4641_priv *ak4641; @@ -632,7 +631,7 @@ static struct i2c_driver ak4641_i2c_driver = { .driver = { .name = "ak4641", }, - .probe = ak4641_i2c_probe, + .probe_new = ak4641_i2c_probe, .remove = ak4641_i2c_remove, .id_table = ak4641_i2c_id, }; diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index c284dcc5af76..3c20ff5595eb 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -630,8 +630,8 @@ static struct clk *ak4642_of_parse_mcko(struct device *dev) #endif static const struct of_device_id ak4642_of_match[]; -static int ak4642_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id ak4642_i2c_id[]; +static int ak4642_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct device_node *np = dev->of_node; @@ -651,6 +651,8 @@ static int ak4642_i2c_probe(struct i2c_client *i2c, if (of_id) drvdata = of_id->data; } else { + const struct i2c_device_id *id = + i2c_match_id(ak4642_i2c_id, i2c); drvdata = (const struct ak4642_drvdata *)id->driver_data; } @@ -697,7 +699,7 @@ static struct i2c_driver ak4642_i2c_driver = { .name = "ak4642-codec", .of_match_table = ak4642_of_match, }, - .probe = ak4642_i2c_probe, + .probe_new = ak4642_i2c_probe, .id_table = ak4642_i2c_id, }; diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index e9d1251c4265..60edcbe56014 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -629,8 +629,7 @@ static const struct regmap_config ak4671_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int ak4671_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ak4671_i2c_probe(struct i2c_client *client) { struct regmap *regmap; int ret; @@ -657,7 +656,7 @@ static struct i2c_driver ak4671_i2c_driver = { .driver = { .name = "ak4671-codec", }, - .probe = ak4671_i2c_probe, + .probe_new = ak4671_i2c_probe, .id_table = ak4671_i2c_id, }; diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index b10357a6d655..8e6235d2c544 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -968,14 +968,21 @@ static const struct regmap_config alc5623_regmap = { .cache_type = REGCACHE_RBTREE, }; +static const struct i2c_device_id alc5623_i2c_table[] = { + {"alc5621", 0x21}, + {"alc5622", 0x22}, + {"alc5623", 0x23}, + {} +}; +MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); + /* * ALC5623 2 wire address is determined by A1 pin * state during powerup. * low = 0x1a * high = 0x1b */ -static int alc5623_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int alc5623_i2c_probe(struct i2c_client *client) { struct alc5623_platform_data *pdata; struct alc5623_priv *alc5623; @@ -983,6 +990,7 @@ static int alc5623_i2c_probe(struct i2c_client *client, unsigned int vid1, vid2; int ret; u32 val32; + const struct i2c_device_id *id; alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), GFP_KERNEL); @@ -1009,6 +1017,8 @@ static int alc5623_i2c_probe(struct i2c_client *client, } vid2 >>= 8; + id = i2c_match_id(alc5623_i2c_table, client); + if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { dev_err(&client->dev, "unknown or wrong codec\n"); dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n", @@ -1060,14 +1070,6 @@ static int alc5623_i2c_probe(struct i2c_client *client, return ret; } -static const struct i2c_device_id alc5623_i2c_table[] = { - {"alc5621", 0x21}, - {"alc5622", 0x22}, - {"alc5623", 0x23}, - {} -}; -MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); - #ifdef CONFIG_OF static const struct of_device_id alc5623_of_match[] = { { .compatible = "realtek,alc5623", }, @@ -1082,7 +1084,7 @@ static struct i2c_driver alc5623_i2c_driver = { .name = "alc562x-codec", .of_match_table = of_match_ptr(alc5623_of_match), }, - .probe = alc5623_i2c_probe, + .probe_new = alc5623_i2c_probe, .id_table = alc5623_i2c_table, }; diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 6d7af3736a91..641bdfddae16 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1092,18 +1092,24 @@ static const struct regmap_config alc5632_regmap = { .cache_type = REGCACHE_RBTREE, }; +static const struct i2c_device_id alc5632_i2c_table[] = { + {"alc5632", 0x5c}, + {} +}; +MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table); + /* * alc5632 2 wire address is determined by A1 pin * state during powerup. * low = 0x1a * high = 0x1b */ -static int alc5632_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int alc5632_i2c_probe(struct i2c_client *client) { struct alc5632_priv *alc5632; int ret, ret1, ret2; unsigned int vid1, vid2; + const struct i2c_device_id *id; alc5632 = devm_kzalloc(&client->dev, sizeof(struct alc5632_priv), GFP_KERNEL); @@ -1129,6 +1135,8 @@ static int alc5632_i2c_probe(struct i2c_client *client, vid2 >>= 8; + id = i2c_match_id(alc5632_i2c_table, client); + if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) { dev_err(&client->dev, "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2); @@ -1161,12 +1169,6 @@ static int alc5632_i2c_probe(struct i2c_client *client, return ret; } -static const struct i2c_device_id alc5632_i2c_table[] = { - {"alc5632", 0x5c}, - {} -}; -MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table); - #ifdef CONFIG_OF static const struct of_device_id alc5632_of_match[] = { { .compatible = "realtek,alc5632", }, @@ -1181,7 +1183,7 @@ static struct i2c_driver alc5632_i2c_driver = { .name = "alc5632", .of_match_table = of_match_ptr(alc5632_of_match), }, - .probe = alc5632_i2c_probe, + .probe_new = alc5632_i2c_probe, .id_table = alc5632_i2c_table, }; diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 9b92e1a0d1a3..8b0a9c788a26 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -232,11 +232,11 @@ static int i2s_rx_hw_params(struct snd_pcm_substream *substream, if (params_rate(params) != 48000) return -EINVAL; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_16; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_24; break; default: @@ -387,6 +387,7 @@ static const struct snd_soc_component_driver i2s_rx_component_driver = { .num_dapm_widgets = ARRAY_SIZE(i2s_rx_dapm_widgets), .dapm_routes = i2s_rx_dapm_routes, .num_dapm_routes = ARRAY_SIZE(i2s_rx_dapm_routes), + .endianness = 1, }; static void *wov_map_shm(struct cros_ec_codec_priv *priv, diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 933e3d627e5f..badfc55bc5fa 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -346,8 +346,7 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, return 0; } -static int cs35l32_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l32_i2c_probe(struct i2c_client *i2c_client) { struct cs35l32_private *cs35l32; struct cs35l32_platform_data *pdata = @@ -576,7 +575,7 @@ static struct i2c_driver cs35l32_i2c_driver = { .of_match_table = cs35l32_of_match, }, .id_table = cs35l32_id, - .probe = cs35l32_i2c_probe, + .probe_new = cs35l32_i2c_probe, .remove = cs35l32_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 2a6f5e46d031..47dc0f6d90a2 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -1116,8 +1116,7 @@ static int cs35l33_of_get_pdata(struct device *dev, return 0; } -static int cs35l33_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l33_i2c_probe(struct i2c_client *i2c_client) { struct cs35l33_private *cs35l33; struct cs35l33_pdata *pdata = dev_get_platdata(&i2c_client->dev); @@ -1286,7 +1285,7 @@ static struct i2c_driver cs35l33_i2c_driver = { }, .id_table = cs35l33_id, - .probe = cs35l33_i2c_probe, + .probe_new = cs35l33_i2c_probe, .remove = cs35l33_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index ed678241c22b..50d509a06071 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -994,8 +994,7 @@ static const char * const cs35l34_core_supplies[] = { "VP", }; -static int cs35l34_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l34_i2c_probe(struct i2c_client *i2c_client) { struct cs35l34_private *cs35l34; struct cs35l34_platform_data *pdata = @@ -1217,7 +1216,7 @@ static struct i2c_driver cs35l34_i2c_driver = { }, .id_table = cs35l34_id, - .probe = cs35l34_i2c_probe, + .probe_new = cs35l34_i2c_probe, .remove = cs35l34_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 961a3e07e70f..6b70afb70a67 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1466,8 +1466,7 @@ static const struct reg_sequence cs35l35_errata_patch[] = { { 0x7F, 0x00 }, }; -static int cs35l35_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l35_i2c_probe(struct i2c_client *i2c_client) { struct cs35l35_private *cs35l35; struct device *dev = &i2c_client->dev; @@ -1658,7 +1657,7 @@ static struct i2c_driver cs35l35_i2c_driver = { .of_match_table = cs35l35_of_match, }, .id_table = cs35l35_id, - .probe = cs35l35_i2c_probe, + .probe_new = cs35l35_i2c_probe, .remove = cs35l35_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index d83c1b318c1c..920190daa4d1 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -1700,8 +1700,7 @@ static const struct reg_sequence cs35l36_revb0_errata_patch[] = { { CS35L36_TESTKEY_CTRL, CS35L36_TEST_LOCK2 }, }; -static int cs35l36_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs35l36_i2c_probe(struct i2c_client *i2c_client) { struct cs35l36_private *cs35l36; struct device *dev = &i2c_client->dev; @@ -1804,7 +1803,7 @@ static int cs35l36_i2c_probe(struct i2c_client *i2c_client, if (ret < 0) { dev_err(&i2c_client->dev, "Failed to read otp_id Register %d\n", ret); - return ret; + goto err; } if ((l37_id_reg & CS35L36_OTP_REV_MASK) == CS35L36_OTP_REV_L37) @@ -1947,7 +1946,7 @@ static struct i2c_driver cs35l36_i2c_driver = { .of_match_table = cs35l36_of_match, }, .id_table = cs35l36_id, - .probe = cs35l36_i2c_probe, + .probe_new = cs35l36_i2c_probe, .remove = cs35l36_i2c_remove, }; module_i2c_driver(cs35l36_i2c_driver); diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c index 5ff0f00a2de4..37c703c08fd5 100644 --- a/sound/soc/codecs/cs35l41-i2c.c +++ b/sound/soc/codecs/cs35l41-i2c.c @@ -29,8 +29,7 @@ static const struct i2c_device_id cs35l41_id_i2c[] = { MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); -static int cs35l41_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs35l41_i2c_probe(struct i2c_client *client) { struct cs35l41_private *cs35l41; struct device *dev = &client->dev; @@ -91,7 +90,7 @@ static struct i2c_driver cs35l41_i2c_driver = { .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), }, .id_table = cs35l41_id_i2c, - .probe = cs35l41_i2c_probe, + .probe_new = cs35l41_i2c_probe, .remove = cs35l41_i2c_remove, }; diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 3edb09000efa..6d3070ea9e06 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -423,7 +423,7 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) } } -static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { +static const struct cs35l41_otp_packed_element_t otp_map_1[] = { /* addr shift size */ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ @@ -526,7 +526,7 @@ static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ }; -static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { +static const struct cs35l41_otp_packed_element_t otp_map_2[] = { /* addr shift size */ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ @@ -691,35 +691,35 @@ static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { { .id = 0x01, .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_1), .bit_offset = 16, .word_offset = 2, }, { .id = 0x02, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x03, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x06, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x08, .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_1), .bit_offset = 16, .word_offset = 2, }, @@ -842,7 +842,7 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) word_offset = otp_map_match->word_offset; for (i = 0; i < otp_map_match->num_elements; i++) { - dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d otp_map[i].size = %d\n", + dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d, otp_map[i].size = %u\n", bit_offset, word_offset, bit_sum % 32, otp_map[i].size); if (bit_offset + otp_map[i].size - 1 >= 32) { otp_val = (otp_mem[word_offset] & diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 5f0eca229dd3..3e68a07a3c8e 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -1025,6 +1025,8 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { .controls = cs35l41_aud_controls, .num_controls = ARRAY_SIZE(cs35l41_aud_controls), .set_sysclk = cs35l41_component_set_sysclk, + + .endianness = 1, }; static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cfg) diff --git a/sound/soc/codecs/cs35l45-i2c.c b/sound/soc/codecs/cs35l45-i2c.c new file mode 100644 index 000000000000..38a4dbc9e9fe --- /dev/null +++ b/sound/soc/codecs/cs35l45-i2c.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +// +// cs35l45-i2c.c -- CS35L45 I2C driver +// +// Copyright 2019-2022 Cirrus Logic, Inc. +// +// Author: James Schulman <james.schulman@cirrus.com> + +#include <linux/device.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/regmap.h> + +#include "cs35l45.h" + +static int cs35l45_i2c_probe(struct i2c_client *client) +{ + struct cs35l45_private *cs35l45; + struct device *dev = &client->dev; + int ret; + + cs35l45 = devm_kzalloc(dev, sizeof(struct cs35l45_private), GFP_KERNEL); + if (!cs35l45) + return -ENOMEM; + + i2c_set_clientdata(client, cs35l45); + cs35l45->regmap = devm_regmap_init_i2c(client, &cs35l45_i2c_regmap); + if (IS_ERR(cs35l45->regmap)) { + ret = PTR_ERR(cs35l45->regmap); + dev_err(dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + + cs35l45->dev = dev; + + return cs35l45_probe(cs35l45); +} + +static int cs35l45_i2c_remove(struct i2c_client *client) +{ + struct cs35l45_private *cs35l45 = i2c_get_clientdata(client); + + return cs35l45_remove(cs35l45); +} + +static const struct of_device_id cs35l45_of_match[] = { + { .compatible = "cirrus,cs35l45" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l45_of_match); + +static const struct i2c_device_id cs35l45_id_i2c[] = { + { "cs35l45", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs35l45_id_i2c); + +static struct i2c_driver cs35l45_i2c_driver = { + .driver = { + .name = "cs35l45", + .of_match_table = cs35l45_of_match, + .pm = &cs35l45_pm_ops, + }, + .id_table = cs35l45_id_i2c, + .probe_new = cs35l45_i2c_probe, + .remove = cs35l45_i2c_remove, +}; +module_i2c_driver(cs35l45_i2c_driver); + +MODULE_DESCRIPTION("I2C CS35L45 driver"); +MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_IMPORT_NS(SND_SOC_CS35L45); +MODULE_IMPORT_NS(SND_SOC_CS35L45_TABLES); diff --git a/sound/soc/codecs/cs35l45-spi.c b/sound/soc/codecs/cs35l45-spi.c new file mode 100644 index 000000000000..baaf6e0f4fb9 --- /dev/null +++ b/sound/soc/codecs/cs35l45-spi.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +// +// cs35l45-spi.c -- CS35L45 SPI driver +// +// Copyright 2019-2022 Cirrus Logic, Inc. +// +// Author: James Schulman <james.schulman@cirrus.com> + +#include <linux/device.h> +#include <linux/module.h> +#include <linux/regmap.h> +#include <linux/spi/spi.h> + +#include "cs35l45.h" + +static int cs35l45_spi_probe(struct spi_device *spi) +{ + struct cs35l45_private *cs35l45; + struct device *dev = &spi->dev; + int ret; + + cs35l45 = devm_kzalloc(dev, sizeof(struct cs35l45_private), GFP_KERNEL); + if (cs35l45 == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, cs35l45); + cs35l45->regmap = devm_regmap_init_spi(spi, &cs35l45_spi_regmap); + if (IS_ERR(cs35l45->regmap)) { + ret = PTR_ERR(cs35l45->regmap); + dev_err(dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + + cs35l45->dev = dev; + + return cs35l45_probe(cs35l45); +} + +static void cs35l45_spi_remove(struct spi_device *spi) +{ + struct cs35l45_private *cs35l45 = spi_get_drvdata(spi); + + cs35l45_remove(cs35l45); +} + +static const struct of_device_id cs35l45_of_match[] = { + { .compatible = "cirrus,cs35l45" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l45_of_match); + +static const struct spi_device_id cs35l45_id_spi[] = { + { "cs35l45", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, cs35l45_id_spi); + +static struct spi_driver cs35l45_spi_driver = { + .driver = { + .name = "cs35l45", + .of_match_table = cs35l45_of_match, + .pm = &cs35l45_pm_ops, + }, + .id_table = cs35l45_id_spi, + .probe = cs35l45_spi_probe, + .remove = cs35l45_spi_remove, +}; +module_spi_driver(cs35l45_spi_driver); + +MODULE_DESCRIPTION("SPI CS35L45 driver"); +MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_IMPORT_NS(SND_SOC_CS35L45); +MODULE_IMPORT_NS(SND_SOC_CS35L45_TABLES); diff --git a/sound/soc/codecs/cs35l45-tables.c b/sound/soc/codecs/cs35l45-tables.c new file mode 100644 index 000000000000..5a2c2e684ef9 --- /dev/null +++ b/sound/soc/codecs/cs35l45-tables.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +// +// cs35l45-tables.c -- CS35L45 ALSA SoC audio driver +// +// Copyright 2019-2022 Cirrus Logic, Inc. +// +// Author: James Schulman <james.schulman@cirrus.com> + +#include <linux/module.h> +#include <linux/regmap.h> + +#include "cs35l45.h" + +static const struct reg_sequence cs35l45_patch[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, + { 0x00000044, 0x00000055 }, + { 0x00000044, 0x000000AA }, + { 0x00006480, 0x0830500A }, + { 0x00007C60, 0x1000850B }, + { CS35L45_BOOST_OV_CFG, 0x007000D0 }, + { CS35L45_LDPM_CONFIG, 0x0001B636 }, + { 0x00002C08, 0x00000009 }, + { 0x00006850, 0x0A30FFC4 }, + { 0x00003820, 0x00040100 }, + { 0x00003824, 0x00000000 }, + { 0x00007CFC, 0x62870004 }, + { 0x00007C60, 0x1001850B }, + { 0x00000040, 0x00000000 }, + { 0x00000044, 0x00000000 }, + { CS35L45_BOOST_CCM_CFG, 0xF0000003 }, + { CS35L45_BOOST_DCM_CFG, 0x08710220 }, + { CS35L45_ERROR_RELEASE, 0x00200000 }, +}; + +int cs35l45_apply_patch(struct cs35l45_private *cs35l45) +{ + return regmap_register_patch(cs35l45->regmap, cs35l45_patch, + ARRAY_SIZE(cs35l45_patch)); +} +EXPORT_SYMBOL_NS_GPL(cs35l45_apply_patch, SND_SOC_CS35L45_TABLES); + +static const struct reg_default cs35l45_defaults[] = { + { CS35L45_BLOCK_ENABLES, 0x00003323 }, + { CS35L45_BLOCK_ENABLES2, 0x00000010 }, + { CS35L45_REFCLK_INPUT, 0x00000510 }, + { CS35L45_GLOBAL_SAMPLE_RATE, 0x00000003 }, + { CS35L45_ASP_ENABLES1, 0x00000000 }, + { CS35L45_ASP_CONTROL1, 0x00000028 }, + { CS35L45_ASP_CONTROL2, 0x18180200 }, + { CS35L45_ASP_CONTROL3, 0x00000002 }, + { CS35L45_ASP_FRAME_CONTROL1, 0x03020100 }, + { CS35L45_ASP_FRAME_CONTROL2, 0x00000004 }, + { CS35L45_ASP_FRAME_CONTROL5, 0x00000100 }, + { CS35L45_ASP_DATA_CONTROL1, 0x00000018 }, + { CS35L45_ASP_DATA_CONTROL5, 0x00000018 }, + { CS35L45_DACPCM1_INPUT, 0x00000008 }, + { CS35L45_ASPTX1_INPUT, 0x00000018 }, + { CS35L45_ASPTX2_INPUT, 0x00000019 }, + { CS35L45_ASPTX3_INPUT, 0x00000020 }, + { CS35L45_ASPTX4_INPUT, 0x00000028 }, + { CS35L45_ASPTX5_INPUT, 0x00000048 }, + { CS35L45_AMP_PCM_CONTROL, 0x00100000 }, +}; + +static bool cs35l45_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L45_DEVID ... CS35L45_OTPID: + case CS35L45_SFT_RESET: + case CS35L45_GLOBAL_ENABLES: + case CS35L45_BLOCK_ENABLES: + case CS35L45_BLOCK_ENABLES2: + case CS35L45_ERROR_RELEASE: + case CS35L45_REFCLK_INPUT: + case CS35L45_GLOBAL_SAMPLE_RATE: + case CS35L45_ASP_ENABLES1: + case CS35L45_ASP_CONTROL1: + case CS35L45_ASP_CONTROL2: + case CS35L45_ASP_CONTROL3: + case CS35L45_ASP_FRAME_CONTROL1: + case CS35L45_ASP_FRAME_CONTROL2: + case CS35L45_ASP_FRAME_CONTROL5: + case CS35L45_ASP_DATA_CONTROL1: + case CS35L45_ASP_DATA_CONTROL5: + case CS35L45_DACPCM1_INPUT: + case CS35L45_ASPTX1_INPUT: + case CS35L45_ASPTX2_INPUT: + case CS35L45_ASPTX3_INPUT: + case CS35L45_ASPTX4_INPUT: + case CS35L45_ASPTX5_INPUT: + case CS35L45_AMP_PCM_CONTROL: + case CS35L45_AMP_PCM_HPF_TST: + case CS35L45_IRQ1_EINT_4: + return true; + default: + return false; + } +} + +static bool cs35l45_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L45_DEVID ... CS35L45_OTPID: + case CS35L45_SFT_RESET: + case CS35L45_GLOBAL_ENABLES: + case CS35L45_ERROR_RELEASE: + case CS35L45_AMP_PCM_HPF_TST: /* not cachable */ + case CS35L45_IRQ1_EINT_4: + return true; + default: + return false; + } +} + +const struct regmap_config cs35l45_i2c_regmap = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L45_LASTREG, + .reg_defaults = cs35l45_defaults, + .num_reg_defaults = ARRAY_SIZE(cs35l45_defaults), + .volatile_reg = cs35l45_volatile_reg, + .readable_reg = cs35l45_readable_reg, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_NS_GPL(cs35l45_i2c_regmap, SND_SOC_CS35L45_TABLES); + +const struct regmap_config cs35l45_spi_regmap = { + .reg_bits = 32, + .val_bits = 32, + .pad_bits = 16, + .reg_stride = 4, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L45_LASTREG, + .reg_defaults = cs35l45_defaults, + .num_reg_defaults = ARRAY_SIZE(cs35l45_defaults), + .volatile_reg = cs35l45_volatile_reg, + .readable_reg = cs35l45_readable_reg, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_NS_GPL(cs35l45_spi_regmap, SND_SOC_CS35L45_TABLES); + +static const struct { + u8 cfg_id; + u32 freq; +} cs35l45_pll_refclk_freq[] = { + { 0x0C, 128000 }, + { 0x0F, 256000 }, + { 0x11, 384000 }, + { 0x12, 512000 }, + { 0x15, 768000 }, + { 0x17, 1024000 }, + { 0x19, 1411200 }, + { 0x1B, 1536000 }, + { 0x1C, 2116800 }, + { 0x1D, 2048000 }, + { 0x1E, 2304000 }, + { 0x1F, 2822400 }, + { 0x21, 3072000 }, + { 0x23, 4233600 }, + { 0x24, 4096000 }, + { 0x25, 4608000 }, + { 0x26, 5644800 }, + { 0x27, 6000000 }, + { 0x28, 6144000 }, + { 0x29, 6350400 }, + { 0x2A, 6912000 }, + { 0x2D, 7526400 }, + { 0x2E, 8467200 }, + { 0x2F, 8192000 }, + { 0x30, 9216000 }, + { 0x31, 11289600 }, + { 0x33, 12288000 }, + { 0x37, 16934400 }, + { 0x38, 18432000 }, + { 0x39, 22579200 }, + { 0x3B, 24576000 }, +}; + +unsigned int cs35l45_get_clk_freq_id(unsigned int freq) +{ + int i; + + if (freq == 0) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(cs35l45_pll_refclk_freq); ++i) { + if (cs35l45_pll_refclk_freq[i].freq == freq) + return cs35l45_pll_refclk_freq[i].cfg_id; + } + + return -EINVAL; +} +EXPORT_SYMBOL_NS_GPL(cs35l45_get_clk_freq_id, SND_SOC_CS35L45_TABLES); + +MODULE_DESCRIPTION("ASoC CS35L45 driver tables"); +MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c new file mode 100644 index 000000000000..2367c1a4c10e --- /dev/null +++ b/sound/soc/codecs/cs35l45.c @@ -0,0 +1,690 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +// +// cs35l45.c - CS35L45 ALSA SoC audio driver +// +// Copyright 2019-2022 Cirrus Logic, Inc. +// +// Author: James Schulman <james.schulman@cirrus.com> + +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/tlv.h> + +#include "cs35l45.h" + +static int cs35l45_global_en_ev(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 cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component); + + dev_dbg(cs35l45->dev, "%s event : %x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_write(cs35l45->regmap, CS35L45_GLOBAL_ENABLES, + CS35L45_GLOBAL_EN_MASK); + + usleep_range(CS35L45_POST_GLOBAL_EN_US, CS35L45_POST_GLOBAL_EN_US + 100); + break; + case SND_SOC_DAPM_PRE_PMD: + usleep_range(CS35L45_PRE_GLOBAL_DIS_US, CS35L45_PRE_GLOBAL_DIS_US + 100); + + regmap_write(cs35l45->regmap, CS35L45_GLOBAL_ENABLES, 0); + break; + default: + break; + } + + return 0; +} + +static const char * const cs35l45_asp_tx_txt[] = { + "Zero", "ASP_RX1", "ASP_RX2", + "VMON", "IMON", "ERR_VOL", + "VDD_BATTMON", "VDD_BSTMON", + "Interpolator", "IL_TARGET", +}; + +static const unsigned int cs35l45_asp_tx_val[] = { + CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2, + CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL, + CS35L45_PCM_SRC_VDD_BATTMON, CS35L45_PCM_SRC_VDD_BSTMON, + CS35L45_PCM_SRC_INTERPOLATOR, CS35L45_PCM_SRC_IL_TARGET, +}; + +static const struct soc_enum cs35l45_asp_tx_enums[] = { + SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX1_INPUT, 0, CS35L45_PCM_SRC_MASK, + ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt, + cs35l45_asp_tx_val), + SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX2_INPUT, 0, CS35L45_PCM_SRC_MASK, + ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt, + cs35l45_asp_tx_val), + SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX3_INPUT, 0, CS35L45_PCM_SRC_MASK, + ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt, + cs35l45_asp_tx_val), + SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX4_INPUT, 0, CS35L45_PCM_SRC_MASK, + ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt, + cs35l45_asp_tx_val), + SOC_VALUE_ENUM_SINGLE(CS35L45_ASPTX5_INPUT, 0, CS35L45_PCM_SRC_MASK, + ARRAY_SIZE(cs35l45_asp_tx_txt), cs35l45_asp_tx_txt, + cs35l45_asp_tx_val), +}; + +static const char * const cs35l45_dac_txt[] = { + "Zero", "ASP_RX1", "ASP_RX2" +}; + +static const unsigned int cs35l45_dac_val[] = { + CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2 +}; + +static const struct soc_enum cs35l45_dacpcm_enums[] = { + SOC_VALUE_ENUM_SINGLE(CS35L45_DACPCM1_INPUT, 0, CS35L45_PCM_SRC_MASK, + ARRAY_SIZE(cs35l45_dac_txt), cs35l45_dac_txt, + cs35l45_dac_val), +}; + +static const struct snd_kcontrol_new cs35l45_asp_muxes[] = { + SOC_DAPM_ENUM("ASP_TX1 Source", cs35l45_asp_tx_enums[0]), + SOC_DAPM_ENUM("ASP_TX2 Source", cs35l45_asp_tx_enums[1]), + SOC_DAPM_ENUM("ASP_TX3 Source", cs35l45_asp_tx_enums[2]), + SOC_DAPM_ENUM("ASP_TX4 Source", cs35l45_asp_tx_enums[3]), + SOC_DAPM_ENUM("ASP_TX5 Source", cs35l45_asp_tx_enums[4]), +}; + +static const struct snd_kcontrol_new cs35l45_dac_muxes[] = { + SOC_DAPM_ENUM("DACPCM1 Source", cs35l45_dacpcm_enums[0]), +}; + +static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("GLOBAL_EN", SND_SOC_NOPM, 0, 0, + cs35l45_global_en_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("ASP_EN", CS35L45_BLOCK_ENABLES2, CS35L45_ASP_EN_SHIFT, 0, NULL, 0), + + SND_SOC_DAPM_SIGGEN("VMON_SRC"), + SND_SOC_DAPM_SIGGEN("IMON_SRC"), + SND_SOC_DAPM_SIGGEN("VDD_BATTMON_SRC"), + SND_SOC_DAPM_SIGGEN("VDD_BSTMON_SRC"), + SND_SOC_DAPM_SIGGEN("ERR_VOL"), + SND_SOC_DAPM_SIGGEN("AMP_INTP"), + SND_SOC_DAPM_SIGGEN("IL_TARGET"), + SND_SOC_DAPM_ADC("VMON", NULL, CS35L45_BLOCK_ENABLES, CS35L45_VMON_EN_SHIFT, 0), + SND_SOC_DAPM_ADC("IMON", NULL, CS35L45_BLOCK_ENABLES, CS35L45_IMON_EN_SHIFT, 0), + SND_SOC_DAPM_ADC("VDD_BATTMON", NULL, CS35L45_BLOCK_ENABLES, + CS35L45_VDD_BATTMON_EN_SHIFT, 0), + SND_SOC_DAPM_ADC("VDD_BSTMON", NULL, CS35L45_BLOCK_ENABLES, + CS35L45_VDD_BSTMON_EN_SHIFT, 0), + + SND_SOC_DAPM_AIF_IN("ASP_RX1", NULL, 0, CS35L45_ASP_ENABLES1, CS35L45_ASP_RX1_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_IN("ASP_RX2", NULL, 1, CS35L45_ASP_ENABLES1, CS35L45_ASP_RX2_EN_SHIFT, 0), + + SND_SOC_DAPM_AIF_OUT("ASP_TX1", NULL, 0, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX1_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_OUT("ASP_TX2", NULL, 1, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX2_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_OUT("ASP_TX3", NULL, 2, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX3_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_OUT("ASP_TX4", NULL, 3, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX4_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_OUT("ASP_TX5", NULL, 3, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX5_EN_SHIFT, 0), + + SND_SOC_DAPM_MUX("ASP_TX1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[0]), + SND_SOC_DAPM_MUX("ASP_TX2 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[1]), + SND_SOC_DAPM_MUX("ASP_TX3 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[2]), + SND_SOC_DAPM_MUX("ASP_TX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[3]), + SND_SOC_DAPM_MUX("ASP_TX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[4]), + + SND_SOC_DAPM_MUX("DACPCM1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dac_muxes[0]), + + SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("SPK"), +}; + +#define CS35L45_ASP_MUX_ROUTE(name) \ + { name" Source", "ASP_RX1", "ASP_RX1" }, \ + { name" Source", "ASP_RX2", "ASP_RX2" }, \ + { name" Source", "VMON", "VMON" }, \ + { name" Source", "IMON", "IMON" }, \ + { name" Source", "ERR_VOL", "ERR_VOL" }, \ + { name" Source", "VDD_BATTMON", "VDD_BATTMON" }, \ + { name" Source", "VDD_BSTMON", "VDD_BSTMON" }, \ + { name" Source", "Interpolator", "AMP_INTP" }, \ + { name" Source", "IL_TARGET", "IL_TARGET" } + +#define CS35L45_DAC_MUX_ROUTE(name) \ + { name" Source", "ASP_RX1", "ASP_RX1" }, \ + { name" Source", "ASP_RX2", "ASP_RX2" } + +static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = { + /* Feedback */ + { "VMON", NULL, "VMON_SRC" }, + { "IMON", NULL, "IMON_SRC" }, + { "VDD_BATTMON", NULL, "VDD_BATTMON_SRC" }, + { "VDD_BSTMON", NULL, "VDD_BSTMON_SRC" }, + + { "Capture", NULL, "ASP_TX1"}, + { "Capture", NULL, "ASP_TX2"}, + { "Capture", NULL, "ASP_TX3"}, + { "Capture", NULL, "ASP_TX4"}, + { "Capture", NULL, "ASP_TX5"}, + { "ASP_TX1", NULL, "ASP_TX1 Source"}, + { "ASP_TX2", NULL, "ASP_TX2 Source"}, + { "ASP_TX3", NULL, "ASP_TX3 Source"}, + { "ASP_TX4", NULL, "ASP_TX4 Source"}, + { "ASP_TX5", NULL, "ASP_TX5 Source"}, + + { "ASP_TX1", NULL, "ASP_EN" }, + { "ASP_TX2", NULL, "ASP_EN" }, + { "ASP_TX3", NULL, "ASP_EN" }, + { "ASP_TX4", NULL, "ASP_EN" }, + { "ASP_TX1", NULL, "GLOBAL_EN" }, + { "ASP_TX2", NULL, "GLOBAL_EN" }, + { "ASP_TX3", NULL, "GLOBAL_EN" }, + { "ASP_TX4", NULL, "GLOBAL_EN" }, + { "ASP_TX5", NULL, "GLOBAL_EN" }, + + CS35L45_ASP_MUX_ROUTE("ASP_TX1"), + CS35L45_ASP_MUX_ROUTE("ASP_TX2"), + CS35L45_ASP_MUX_ROUTE("ASP_TX3"), + CS35L45_ASP_MUX_ROUTE("ASP_TX4"), + CS35L45_ASP_MUX_ROUTE("ASP_TX5"), + + /* Playback */ + { "ASP_RX1", NULL, "Playback" }, + { "ASP_RX2", NULL, "Playback" }, + { "ASP_RX1", NULL, "ASP_EN" }, + { "ASP_RX2", NULL, "ASP_EN" }, + + { "AMP", NULL, "DACPCM1 Source"}, + { "AMP", NULL, "GLOBAL_EN"}, + + CS35L45_DAC_MUX_ROUTE("DACPCM1"), + + { "SPK", NULL, "AMP"}, +}; + +static const DECLARE_TLV_DB_SCALE(cs35l45_dig_pcm_vol_tlv, -10225, 25, true); + +static const struct snd_kcontrol_new cs35l45_controls[] = { + /* Ignore bit 0: it is beyond the resolution of TLV_DB_SCALE */ + SOC_SINGLE_S_TLV("Digital PCM Volume", + CS35L45_AMP_PCM_CONTROL, + CS35L45_AMP_VOL_PCM_SHIFT + 1, + -409, 48, + (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1, + 0, cs35l45_dig_pcm_vol_tlv), +}; + +static int cs35l45_set_pll(struct cs35l45_private *cs35l45, unsigned int freq) +{ + unsigned int val; + int freq_id; + + freq_id = cs35l45_get_clk_freq_id(freq); + if (freq_id < 0) { + dev_err(cs35l45->dev, "Invalid freq: %u\n", freq); + return -EINVAL; + } + + regmap_read(cs35l45->regmap, CS35L45_REFCLK_INPUT, &val); + val = (val & CS35L45_PLL_REFCLK_FREQ_MASK) >> CS35L45_PLL_REFCLK_FREQ_SHIFT; + if (val == freq_id) + return 0; + + regmap_set_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_OPEN_LOOP_MASK); + regmap_update_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, + CS35L45_PLL_REFCLK_FREQ_MASK, + freq_id << CS35L45_PLL_REFCLK_FREQ_SHIFT); + regmap_clear_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_REFCLK_EN_MASK); + regmap_clear_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_OPEN_LOOP_MASK); + regmap_set_bits(cs35l45->regmap, CS35L45_REFCLK_INPUT, CS35L45_PLL_REFCLK_EN_MASK); + + return 0; +} + +static int cs35l45_asp_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(codec_dai->component); + unsigned int asp_fmt, fsync_inv, bclk_inv; + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: + break; + default: + dev_err(cs35l45->dev, "Invalid DAI clocking\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + asp_fmt = CS35l45_ASP_FMT_DSP_A; + break; + case SND_SOC_DAIFMT_I2S: + asp_fmt = CS35L45_ASP_FMT_I2S; + break; + default: + dev_err(cs35l45->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_IF: + fsync_inv = 1; + bclk_inv = 0; + break; + case SND_SOC_DAIFMT_IB_NF: + fsync_inv = 0; + bclk_inv = 1; + break; + case SND_SOC_DAIFMT_IB_IF: + fsync_inv = 1; + bclk_inv = 1; + break; + case SND_SOC_DAIFMT_NB_NF: + fsync_inv = 0; + bclk_inv = 0; + break; + default: + dev_warn(cs35l45->dev, "Invalid DAI clock polarity\n"); + return -EINVAL; + } + + regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL2, + CS35L45_ASP_FMT_MASK | + CS35L45_ASP_FSYNC_INV_MASK | + CS35L45_ASP_BCLK_INV_MASK, + (asp_fmt << CS35L45_ASP_FMT_SHIFT) | + (fsync_inv << CS35L45_ASP_FSYNC_INV_SHIFT) | + (bclk_inv << CS35L45_ASP_BCLK_INV_SHIFT)); + + return 0; +} + +static int cs35l45_asp_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component); + unsigned int asp_width, asp_wl, global_fs, slot_multiple, asp_fmt; + int bclk; + + switch (params_rate(params)) { + case 44100: + global_fs = CS35L45_44P100_KHZ; + break; + case 48000: + global_fs = CS35L45_48P0_KHZ; + break; + case 88200: + global_fs = CS35L45_88P200_KHZ; + break; + case 96000: + global_fs = CS35L45_96P0_KHZ; + break; + default: + dev_warn(cs35l45->dev, "Unsupported sample rate (%d)\n", + params_rate(params)); + return -EINVAL; + } + + regmap_update_bits(cs35l45->regmap, CS35L45_GLOBAL_SAMPLE_RATE, + CS35L45_GLOBAL_FS_MASK, + global_fs << CS35L45_GLOBAL_FS_SHIFT); + + asp_wl = params_width(params); + + if (cs35l45->slot_width) + asp_width = cs35l45->slot_width; + else + asp_width = params_width(params); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL2, + CS35L45_ASP_WIDTH_RX_MASK, + asp_width << CS35L45_ASP_WIDTH_RX_SHIFT); + + regmap_update_bits(cs35l45->regmap, CS35L45_ASP_DATA_CONTROL5, + CS35L45_ASP_WL_MASK, + asp_wl << CS35L45_ASP_WL_SHIFT); + } else { + regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL2, + CS35L45_ASP_WIDTH_TX_MASK, + asp_width << CS35L45_ASP_WIDTH_TX_SHIFT); + + regmap_update_bits(cs35l45->regmap, CS35L45_ASP_DATA_CONTROL1, + CS35L45_ASP_WL_MASK, + asp_wl << CS35L45_ASP_WL_SHIFT); + } + + if (cs35l45->sysclk_set) + return 0; + + /* I2S always has an even number of channels */ + regmap_read(cs35l45->regmap, CS35L45_ASP_CONTROL2, &asp_fmt); + asp_fmt = (asp_fmt & CS35L45_ASP_FMT_MASK) >> CS35L45_ASP_FMT_SHIFT; + if (asp_fmt == CS35L45_ASP_FMT_I2S) + slot_multiple = 2; + else + slot_multiple = 1; + + bclk = snd_soc_tdm_params_to_bclk(params, asp_width, + cs35l45->slot_count, slot_multiple); + + return cs35l45_set_pll(cs35l45, bclk); +} + +static int cs35l45_asp_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component); + + if (slot_width && ((slot_width < 16) || (slot_width > 128))) + return -EINVAL; + + cs35l45->slot_width = slot_width; + cs35l45->slot_count = slots; + + return 0; +} + +static int cs35l45_asp_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component); + int ret; + + if (clk_id != 0) { + dev_err(cs35l45->dev, "Invalid clk_id %d\n", clk_id); + return -EINVAL; + } + + cs35l45->sysclk_set = false; + if (freq == 0) + return 0; + + ret = cs35l45_set_pll(cs35l45, freq); + if (ret < 0) + return -EINVAL; + + cs35l45->sysclk_set = true; + + return 0; +} + +static int cs35l45_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(dai->component); + unsigned int global_fs, val, hpf_tune; + + if (mute) + return 0; + + regmap_read(cs35l45->regmap, CS35L45_GLOBAL_SAMPLE_RATE, &global_fs); + global_fs = (global_fs & CS35L45_GLOBAL_FS_MASK) >> CS35L45_GLOBAL_FS_SHIFT; + switch (global_fs) { + case CS35L45_44P100_KHZ: + hpf_tune = CS35L45_HPF_44P1; + break; + case CS35L45_88P200_KHZ: + hpf_tune = CS35L45_HPF_88P2; + break; + default: + hpf_tune = CS35l45_HPF_DEFAULT; + break; + } + + regmap_read(cs35l45->regmap, CS35L45_AMP_PCM_HPF_TST, &val); + if (val != hpf_tune) { + struct reg_sequence hpf_override_seq[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, + { 0x00000044, 0x00000055 }, + { 0x00000044, 0x000000AA }, + { CS35L45_AMP_PCM_HPF_TST, hpf_tune }, + { 0x00000040, 0x00000000 }, + { 0x00000044, 0x00000000 }, + }; + regmap_multi_reg_write(cs35l45->regmap, hpf_override_seq, + ARRAY_SIZE(hpf_override_seq)); + } + + return 0; +} + +static const struct snd_soc_dai_ops cs35l45_asp_dai_ops = { + .set_fmt = cs35l45_asp_set_fmt, + .hw_params = cs35l45_asp_hw_params, + .set_tdm_slot = cs35l45_asp_set_tdm_slot, + .set_sysclk = cs35l45_asp_set_sysclk, + .mute_stream = cs35l45_mute_stream, +}; + +static struct snd_soc_dai_driver cs35l45_dai[] = { + { + .name = "cs35l45", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = CS35L45_RATES, + .formats = CS35L45_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 5, + .rates = CS35L45_RATES, + .formats = CS35L45_FORMATS, + }, + .symmetric_rate = true, + .symmetric_sample_bits = true, + .ops = &cs35l45_asp_dai_ops, + }, +}; + +static const struct snd_soc_component_driver cs35l45_component = { + .dapm_widgets = cs35l45_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs35l45_dapm_widgets), + + .dapm_routes = cs35l45_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(cs35l45_dapm_routes), + + .controls = cs35l45_controls, + .num_controls = ARRAY_SIZE(cs35l45_controls), + + .name = "cs35l45", +}; + +static int __maybe_unused cs35l45_runtime_suspend(struct device *dev) +{ + struct cs35l45_private *cs35l45 = dev_get_drvdata(dev); + + regcache_cache_only(cs35l45->regmap, true); + + dev_dbg(cs35l45->dev, "Runtime suspended\n"); + + return 0; +} + +static int __maybe_unused cs35l45_runtime_resume(struct device *dev) +{ + struct cs35l45_private *cs35l45 = dev_get_drvdata(dev); + int ret; + + dev_dbg(cs35l45->dev, "Runtime resume\n"); + + regcache_cache_only(cs35l45->regmap, false); + ret = regcache_sync(cs35l45->regmap); + if (ret != 0) + dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret); + + /* Clear global error status */ + regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); + regmap_set_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); + regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); + return ret; +} + +static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45) +{ + unsigned int val; + + if (device_property_read_u32(cs35l45->dev, + "cirrus,asp-sdout-hiz-ctrl", &val) == 0) { + regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL3, + CS35L45_ASP_DOUT_HIZ_CTRL_MASK, + val << CS35L45_ASP_DOUT_HIZ_CTRL_SHIFT); + } + + return 0; +} + +static int cs35l45_initialize(struct cs35l45_private *cs35l45) +{ + struct device *dev = cs35l45->dev; + unsigned int dev_id[5]; + unsigned int sts; + int ret; + + ret = regmap_read_poll_timeout(cs35l45->regmap, CS35L45_IRQ1_EINT_4, sts, + (sts & CS35L45_OTP_BOOT_DONE_STS_MASK), + 1000, 5000); + if (ret < 0) { + dev_err(cs35l45->dev, "Timeout waiting for OTP boot\n"); + return ret; + } + + ret = regmap_bulk_read(cs35l45->regmap, CS35L45_DEVID, dev_id, ARRAY_SIZE(dev_id)); + if (ret) { + dev_err(cs35l45->dev, "Get Device ID failed: %d\n", ret); + return ret; + } + + switch (dev_id[0]) { + case 0x35A450: + break; + default: + dev_err(cs35l45->dev, "Bad DEVID 0x%x\n", dev_id[0]); + return -ENODEV; + } + + dev_info(cs35l45->dev, "Cirrus Logic CS35L45: REVID %02X OTPID %02X\n", + dev_id[1], dev_id[4]); + + regmap_write(cs35l45->regmap, CS35L45_IRQ1_EINT_4, + CS35L45_OTP_BOOT_DONE_STS_MASK | CS35L45_OTP_BUSY_MASK); + + ret = cs35l45_apply_patch(cs35l45); + if (ret < 0) { + dev_err(dev, "Failed to apply init patch %d\n", ret); + return ret; + } + + ret = cs35l45_apply_property_config(cs35l45); + if (ret < 0) + return ret; + + pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000); + pm_runtime_use_autosuspend(cs35l45->dev); + pm_runtime_set_active(cs35l45->dev); + pm_runtime_enable(cs35l45->dev); + + return 0; +} + +int cs35l45_probe(struct cs35l45_private *cs35l45) +{ + struct device *dev = cs35l45->dev; + int ret; + + cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt"); + if (IS_ERR(cs35l45->vdd_batt)) + return dev_err_probe(dev, PTR_ERR(cs35l45->vdd_batt), + "Failed to request vdd-batt\n"); + + cs35l45->vdd_a = devm_regulator_get(dev, "vdd-a"); + if (IS_ERR(cs35l45->vdd_a)) + return dev_err_probe(dev, PTR_ERR(cs35l45->vdd_a), + "Failed to request vdd-a\n"); + + /* VDD_BATT must always be enabled before other supplies */ + ret = regulator_enable(cs35l45->vdd_batt); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to enable vdd-batt\n"); + + ret = regulator_enable(cs35l45->vdd_a); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to enable vdd-a\n"); + + /* If reset is shared only one instance can claim it */ + cs35l45->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(cs35l45->reset_gpio)) { + ret = PTR_ERR(cs35l45->reset_gpio); + cs35l45->reset_gpio = NULL; + if (ret == -EBUSY) { + dev_dbg(dev, "Reset line busy, assuming shared reset\n"); + } else { + dev_err_probe(dev, ret, "Failed to get reset GPIO\n"); + goto err; + } + } + + if (cs35l45->reset_gpio) { + usleep_range(CS35L45_RESET_HOLD_US, CS35L45_RESET_HOLD_US + 100); + gpiod_set_value_cansleep(cs35l45->reset_gpio, 1); + } + + usleep_range(CS35L45_RESET_US, CS35L45_RESET_US + 100); + + ret = cs35l45_initialize(cs35l45); + if (ret < 0) + goto err_reset; + + ret = devm_snd_soc_register_component(dev, &cs35l45_component, + cs35l45_dai, + ARRAY_SIZE(cs35l45_dai)); + if (ret < 0) + goto err_reset; + + return 0; + +err_reset: + gpiod_set_value_cansleep(cs35l45->reset_gpio, 0); +err: + regulator_disable(cs35l45->vdd_a); + regulator_disable(cs35l45->vdd_batt); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45); + +int cs35l45_remove(struct cs35l45_private *cs35l45) +{ + pm_runtime_disable(cs35l45->dev); + + gpiod_set_value_cansleep(cs35l45->reset_gpio, 0); + 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); + +const struct dev_pm_ops cs35l45_pm_ops = { + SET_RUNTIME_PM_OPS(cs35l45_runtime_suspend, cs35l45_runtime_resume, NULL) +}; +EXPORT_SYMBOL_NS_GPL(cs35l45_pm_ops, SND_SOC_CS35L45); + +MODULE_DESCRIPTION("ASoC CS35L45 driver"); +MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>"); +MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_IMPORT_NS(SND_SOC_CS35L45_TABLES); diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h new file mode 100644 index 000000000000..4e266d19cd1c --- /dev/null +++ b/sound/soc/codecs/cs35l45.h @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * cs35l45.h - CS35L45 ALSA SoC audio driver + * + * Copyright 2019-2022 Cirrus Logic, Inc. + * + * Author: James Schulman <james.schulman@cirrus.com> + * + */ + +#ifndef CS35L45_H +#define CS35L45_H + +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> + +#define CS35L45_DEVID 0x00000000 +#define CS35L45_REVID 0x00000004 +#define CS35L45_RELID 0x0000000C +#define CS35L45_OTPID 0x00000010 +#define CS35L45_SFT_RESET 0x00000020 +#define CS35L45_GLOBAL_ENABLES 0x00002014 +#define CS35L45_BLOCK_ENABLES 0x00002018 +#define CS35L45_BLOCK_ENABLES2 0x0000201C +#define CS35L45_ERROR_RELEASE 0x00002034 +#define CS35L45_REFCLK_INPUT 0x00002C04 +#define CS35L45_GLOBAL_SAMPLE_RATE 0x00002C0C +#define CS35L45_BOOST_CCM_CFG 0x00003808 +#define CS35L45_BOOST_DCM_CFG 0x0000380C +#define CS35L45_BOOST_OV_CFG 0x0000382C +#define CS35L45_ASP_ENABLES1 0x00004800 +#define CS35L45_ASP_CONTROL1 0x00004804 +#define CS35L45_ASP_CONTROL2 0x00004808 +#define CS35L45_ASP_CONTROL3 0x0000480C +#define CS35L45_ASP_FRAME_CONTROL1 0x00004810 +#define CS35L45_ASP_FRAME_CONTROL2 0x00004814 +#define CS35L45_ASP_FRAME_CONTROL5 0x00004820 +#define CS35L45_ASP_DATA_CONTROL1 0x00004830 +#define CS35L45_ASP_DATA_CONTROL5 0x00004840 +#define CS35L45_DACPCM1_INPUT 0x00004C00 +#define CS35L45_ASPTX1_INPUT 0x00004C20 +#define CS35L45_ASPTX2_INPUT 0x00004C24 +#define CS35L45_ASPTX3_INPUT 0x00004C28 +#define CS35L45_ASPTX4_INPUT 0x00004C2C +#define CS35L45_ASPTX5_INPUT 0x00004C30 +#define CS35L45_LDPM_CONFIG 0x00006404 +#define CS35L45_AMP_PCM_CONTROL 0x00007000 +#define CS35L45_AMP_PCM_HPF_TST 0x00007004 +#define CS35L45_IRQ1_EINT_4 0x0000E01C +#define CS35L45_LASTREG 0x0000E01C + +/* SFT_RESET */ +#define CS35L45_SOFT_RESET_TRIGGER 0x5A000000 + +/* GLOBAL_ENABLES */ +#define CS35L45_GLOBAL_EN_SHIFT 0 +#define CS35L45_GLOBAL_EN_MASK BIT(0) + +/* BLOCK_ENABLES */ +#define CS35L45_IMON_EN_SHIFT 13 +#define CS35L45_VMON_EN_SHIFT 12 +#define CS35L45_VDD_BSTMON_EN_SHIFT 9 +#define CS35L45_VDD_BATTMON_EN_SHIFT 8 +#define CS35L45_BST_EN_SHIFT 4 +#define CS35L45_BST_EN_MASK GENMASK(5, 4) + +#define CS35L45_BST_DISABLE_FET_ON 0x01 + +/* BLOCK_ENABLES2 */ +#define CS35L45_ASP_EN_SHIFT 27 + +/* ERROR_RELEASE */ +#define CS35L45_GLOBAL_ERR_RLS_MASK BIT(11) + +/* REFCLK_INPUT */ +#define CS35L45_PLL_FORCE_EN_SHIFT 16 +#define CS35L45_PLL_FORCE_EN_MASK BIT(16) +#define CS35L45_PLL_OPEN_LOOP_SHIFT 11 +#define CS35L45_PLL_OPEN_LOOP_MASK BIT(11) +#define CS35L45_PLL_REFCLK_FREQ_SHIFT 5 +#define CS35L45_PLL_REFCLK_FREQ_MASK GENMASK(10, 5) +#define CS35L45_PLL_REFCLK_EN_SHIFT 4 +#define CS35L45_PLL_REFCLK_EN_MASK BIT(4) +#define CS35L45_PLL_REFCLK_SEL_SHIFT 0 +#define CS35L45_PLL_REFCLK_SEL_MASK GENMASK(2, 0) + +#define CS35L45_PLL_REFCLK_SEL_BCLK 0x0 + +/* GLOBAL_SAMPLE_RATE */ +#define CS35L45_GLOBAL_FS_SHIFT 0 +#define CS35L45_GLOBAL_FS_MASK GENMASK(4, 0) + +#define CS35L45_48P0_KHZ 0x03 +#define CS35L45_96P0_KHZ 0x04 +#define CS35L45_44P100_KHZ 0x0B +#define CS35L45_88P200_KHZ 0x0C + +/* ASP_ENABLES_1 */ +#define CS35L45_ASP_RX2_EN_SHIFT 17 +#define CS35L45_ASP_RX1_EN_SHIFT 16 +#define CS35L45_ASP_TX5_EN_SHIFT 4 +#define CS35L45_ASP_TX4_EN_SHIFT 3 +#define CS35L45_ASP_TX3_EN_SHIFT 2 +#define CS35L45_ASP_TX2_EN_SHIFT 1 +#define CS35L45_ASP_TX1_EN_SHIFT 0 + +/* ASP_CONTROL2 */ +#define CS35L45_ASP_WIDTH_RX_SHIFT 24 +#define CS35L45_ASP_WIDTH_RX_MASK GENMASK(31, 24) +#define CS35L45_ASP_WIDTH_TX_SHIFT 16 +#define CS35L45_ASP_WIDTH_TX_MASK GENMASK(23, 16) +#define CS35L45_ASP_FMT_SHIFT 8 +#define CS35L45_ASP_FMT_MASK GENMASK(10, 8) +#define CS35L45_ASP_BCLK_INV_SHIFT 6 +#define CS35L45_ASP_BCLK_INV_MASK BIT(6) +#define CS35L45_ASP_FSYNC_INV_SHIFT 2 +#define CS35L45_ASP_FSYNC_INV_MASK BIT(2) + +#define CS35l45_ASP_FMT_DSP_A 0 +#define CS35L45_ASP_FMT_I2S 2 + +/* ASP_CONTROL3 */ +#define CS35L45_ASP_DOUT_HIZ_CTRL_SHIFT 0 +#define CS35L45_ASP_DOUT_HIZ_CTRL_MASK GENMASK(1, 0) + +/* ASP_FRAME_CONTROL1 */ +#define CS35L45_ASP_TX4_SLOT_SHIFT 24 +#define CS35L45_ASP_TX4_SLOT_MASK GENMASK(29, 24) +#define CS35L45_ASP_TX3_SLOT_SHIFT 16 +#define CS35L45_ASP_TX3_SLOT_MASK GENMASK(21, 16) +#define CS35L45_ASP_TX2_SLOT_SHIFT 8 +#define CS35L45_ASP_TX2_SLOT_MASK GENMASK(13, 8) +#define CS35L45_ASP_TX1_SLOT_SHIFT 0 +#define CS35L45_ASP_TX1_SLOT_MASK GENMASK(5, 0) + +#define CS35L45_ASP_TX_ALL_SLOTS (CS35L45_ASP_TX4_SLOT_MASK | \ + CS35L45_ASP_TX3_SLOT_MASK | \ + CS35L45_ASP_TX2_SLOT_MASK | \ + CS35L45_ASP_TX1_SLOT_MASK) +/* ASP_FRAME_CONTROL5 */ +#define CS35L45_ASP_RX2_SLOT_SHIFT 8 +#define CS35L45_ASP_RX2_SLOT_MASK GENMASK(13, 8) +#define CS35L45_ASP_RX1_SLOT_SHIFT 0 +#define CS35L45_ASP_RX1_SLOT_MASK GENMASK(5, 0) + +#define CS35L45_ASP_RX_ALL_SLOTS (CS35L45_ASP_RX2_SLOT_MASK | \ + CS35L45_ASP_RX1_SLOT_MASK) + +/* ASP_DATA_CONTROL1 */ +/* ASP_DATA_CONTROL5 */ +#define CS35L45_ASP_WL_SHIFT 0 +#define CS35L45_ASP_WL_MASK GENMASK(5, 0) + +/* AMP_PCM_CONTROL */ +#define CS35L45_AMP_VOL_PCM_SHIFT 0 +#define CS35L45_AMP_VOL_PCM_WIDTH 11 + +/* AMP_PCM_HPF_TST */ +#define CS35l45_HPF_DEFAULT 0x00000000 +#define CS35L45_HPF_44P1 0x000108BD +#define CS35L45_HPF_88P2 0x0001045F + +/* IRQ1_EINT_4 */ +#define CS35L45_OTP_BOOT_DONE_STS_MASK BIT(1) +#define CS35L45_OTP_BUSY_MASK BIT(0) + +/* Mixer sources */ +#define CS35L45_PCM_SRC_MASK 0x7F +#define CS35L45_PCM_SRC_ZERO 0x00 +#define CS35L45_PCM_SRC_ASP_RX1 0x08 +#define CS35L45_PCM_SRC_ASP_RX2 0x09 +#define CS35L45_PCM_SRC_VMON 0x18 +#define CS35L45_PCM_SRC_IMON 0x19 +#define CS35L45_PCM_SRC_ERR_VOL 0x20 +#define CS35L45_PCM_SRC_CLASSH_TGT 0x21 +#define CS35L45_PCM_SRC_VDD_BATTMON 0x28 +#define CS35L45_PCM_SRC_VDD_BSTMON 0x29 +#define CS35L45_PCM_SRC_TEMPMON 0x3A +#define CS35L45_PCM_SRC_INTERPOLATOR 0x40 +#define CS35L45_PCM_SRC_IL_TARGET 0x48 + +#define CS35L45_RESET_HOLD_US 2000 +#define CS35L45_RESET_US 2000 +#define CS35L45_POST_GLOBAL_EN_US 5000 +#define CS35L45_PRE_GLOBAL_DIS_US 3000 + +#define CS35L45_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_3LE| \ + SNDRV_PCM_FMTBIT_S24_LE) + +#define CS35L45_RATES (SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000) + +struct cs35l45_private { + struct device *dev; + struct regmap *regmap; + struct gpio_desc *reset_gpio; + struct regulator *vdd_batt; + struct regulator *vdd_a; + bool initialized; + bool sysclk_set; + u8 slot_width; + u8 slot_count; +}; + +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); +unsigned int cs35l45_get_clk_freq_id(unsigned int freq); +int cs35l45_probe(struct cs35l45_private *cs35l45); +int cs35l45_remove(struct cs35l45_private *cs35l45); + +#endif /* CS35L45_H */ diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index 20126cc675b1..881c5ba70c0e 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -663,6 +663,7 @@ static const struct snd_soc_component_driver soc_component_cs4234 = { .non_legacy_dai_naming = 1, .idle_bias_on = 1, .suspend_bias_off = 1, + .endianness = 1, }; static const struct regmap_config cs4234_regmap = { @@ -731,7 +732,7 @@ static int cs4234_powerup(struct cs4234 *cs4234) return 0; } -static int cs4234_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) +static int cs4234_i2c_probe(struct i2c_client *i2c_client) { struct cs4234 *cs4234; struct device *dev = &i2c_client->dev; @@ -908,7 +909,7 @@ static struct i2c_driver cs4234_i2c_driver = { .pm = &cs4234_pm, .of_match_table = cs4234_of_match, }, - .probe = cs4234_i2c_probe, + .probe_new = cs4234_i2c_probe, .remove = cs4234_i2c_remove, }; module_i2c_driver(cs4234_i2c_driver); diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 4415fb364d4d..86bfa8d5ec78 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -568,8 +568,7 @@ static const struct regmap_config cs4265_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int cs4265_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs4265_i2c_probe(struct i2c_client *i2c_client) { struct cs4265_private *cs4265; int ret; @@ -653,7 +652,7 @@ static struct i2c_driver cs4265_i2c_driver = { .of_match_table = cs4265_of_match, }, .id_table = cs4265_id, - .probe = cs4265_i2c_probe, + .probe_new = cs4265_i2c_probe, .remove = cs4265_i2c_remove, }; diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 2d239e983a83..531f63b01554 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -32,18 +32,9 @@ #include <linux/gpio/consumer.h> #include <linux/of_device.h> -/* - * The codec isn't really big-endian or little-endian, since the I2S - * interface requires data to be sent serially with the MSbit first. - * However, to support BE and LE I2S devices, we specify both here. That - * way, ALSA will always match the bit patterns. - */ -#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) +#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) /* CS4270 registers addresses */ #define CS4270_CHIPID 0x01 /* Chip ID */ @@ -677,8 +668,7 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client) * This function is called whenever the I2C subsystem finds a device that * matches the device ID given via a prior call to i2c_add_driver(). */ -static int cs4270_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs4270_i2c_probe(struct i2c_client *i2c_client) { struct cs4270_private *cs4270; unsigned int val; @@ -765,7 +755,7 @@ static struct i2c_driver cs4270_i2c_driver = { .of_match_table = cs4270_of_match, }, .id_table = cs4270_id, - .probe = cs4270_i2c_probe, + .probe_new = cs4270_i2c_probe, .remove = cs4270_i2c_remove, }; diff --git a/sound/soc/codecs/cs4271-i2c.c b/sound/soc/codecs/cs4271-i2c.c index 0a174236f573..0e8a7cf0da50 100644 --- a/sound/soc/codecs/cs4271-i2c.c +++ b/sound/soc/codecs/cs4271-i2c.c @@ -11,8 +11,7 @@ #include <sound/soc.h> #include "cs4271.h" -static int cs4271_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs4271_i2c_probe(struct i2c_client *client) { struct regmap_config config; @@ -35,7 +34,7 @@ static struct i2c_driver cs4271_i2c_driver = { .name = "cs4271", .of_match_table = of_match_ptr(cs4271_dt_ids), }, - .probe = cs4271_i2c_probe, + .probe_new = cs4271_i2c_probe, .id_table = cs4271_i2c_id, }; module_i2c_driver(cs4271_i2c_driver); diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index c8409d50e934..4fade2388797 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -2194,8 +2194,7 @@ static int __maybe_unused cs42l42_resume(struct device *dev) return 0; } -static int cs42l42_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l42_i2c_probe(struct i2c_client *i2c_client) { struct cs42l42_private *cs42l42; int ret, i, devid; @@ -2399,7 +2398,7 @@ static struct i2c_driver cs42l42_i2c_driver = { .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), }, .id_table = cs42l42_id, - .probe = cs42l42_i2c_probe, + .probe_new = cs42l42_i2c_probe, .remove = cs42l42_i2c_remove, }; diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c index 3cb21a2ba29f..3613fb12d623 100644 --- a/sound/soc/codecs/cs42l51-i2c.c +++ b/sound/soc/codecs/cs42l51-i2c.c @@ -19,8 +19,7 @@ static struct i2c_device_id cs42l51_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); -static int cs42l51_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cs42l51_i2c_probe(struct i2c_client *i2c) { struct regmap_config config; @@ -46,7 +45,7 @@ static struct i2c_driver cs42l51_i2c_driver = { .of_match_table = cs42l51_of_match, .pm = &cs42l51_pm_ops, }, - .probe = cs42l51_i2c_probe, + .probe_new = cs42l51_i2c_probe, .remove = cs42l51_i2c_remove, .id_table = cs42l51_i2c_id, }; diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index e9c3cb4e2bfc..aff618513c75 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -51,11 +51,8 @@ struct cs42l51_private { struct regmap *regmap; }; -#define CS42L51_FORMATS ( \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) +#define CS42L51_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 80161151b3f2..9b182b585be4 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1086,8 +1086,7 @@ static const struct regmap_config cs42l52_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int cs42l52_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l52_i2c_probe(struct i2c_client *i2c_client) { struct cs42l52_private *cs42l52; struct cs42l52_platform_data *pdata = dev_get_platdata(&i2c_client->dev); @@ -1226,7 +1225,7 @@ static struct i2c_driver cs42l52_i2c_driver = { .of_match_table = cs42l52_of_match, }, .id_table = cs42l52_id, - .probe = cs42l52_i2c_probe, + .probe_new = cs42l52_i2c_probe, }; module_i2c_driver(cs42l52_i2c_driver); diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 3cf8a0b4478c..dc23007336c5 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1167,8 +1167,7 @@ static int cs42l56_handle_of_data(struct i2c_client *i2c_client, return 0; } -static int cs42l56_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l56_i2c_probe(struct i2c_client *i2c_client) { struct cs42l56_private *cs42l56; struct cs42l56_platform_data *pdata = @@ -1246,7 +1245,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, ®); if (ret) { dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret); - return ret; + goto err_enable; } devid = reg & CS42L56_CHIP_ID_MASK; @@ -1350,7 +1349,7 @@ static struct i2c_driver cs42l56_i2c_driver = { .of_match_table = cs42l56_of_match, }, .id_table = cs42l56_id, - .probe = cs42l56_i2c_probe, + .probe_new = cs42l56_i2c_probe, .remove = cs42l56_i2c_remove, }; diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 018463f34e12..5a9166289f36 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1274,8 +1274,7 @@ static const struct regmap_config cs42l73_regmap = { .use_single_write = true, }; -static int cs42l73_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int cs42l73_i2c_probe(struct i2c_client *i2c_client) { struct cs42l73_private *cs42l73; struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev); @@ -1386,7 +1385,7 @@ static struct i2c_driver cs42l73_i2c_driver = { .of_match_table = cs42l73_of_match, }, .id_table = cs42l73_id, - .probe = cs42l73_i2c_probe, + .probe_new = cs42l73_i2c_probe, }; diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c index 0214e3ab9da0..cb06a06d48b0 100644 --- a/sound/soc/codecs/cs42xx8-i2c.c +++ b/sound/soc/codecs/cs42xx8-i2c.c @@ -17,8 +17,7 @@ #include "cs42xx8.h" -static int cs42xx8_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cs42xx8_i2c_probe(struct i2c_client *i2c) { int ret = cs42xx8_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &cs42xx8_regmap_config)); @@ -51,7 +50,7 @@ static struct i2c_driver cs42xx8_i2c_driver = { .pm = &cs42xx8_pm, .of_match_table = cs42xx8_of_match, }, - .probe = cs42xx8_i2c_probe, + .probe_new = cs42xx8_i2c_probe, .remove = cs42xx8_i2c_remove, .id_table = cs42xx8_i2c_id, }; diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index 44b20c1ef851..a2bce0f9f247 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -712,30 +712,30 @@ static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk, case CS43130_ASP_PCM_DAI: case CS43130_ASP_DOP_DAI: regmap_write(cs43130->regmap, CS43130_ASP_DEN_1, - (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> + (clk_gen->v.denominator & CS43130_SP_M_LSB_DATA_MASK) >> CS43130_SP_M_LSB_DATA_SHIFT); regmap_write(cs43130->regmap, CS43130_ASP_DEN_2, - (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> + (clk_gen->v.denominator & CS43130_SP_M_MSB_DATA_MASK) >> CS43130_SP_M_MSB_DATA_SHIFT); regmap_write(cs43130->regmap, CS43130_ASP_NUM_1, - (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> + (clk_gen->v.numerator & CS43130_SP_N_LSB_DATA_MASK) >> CS43130_SP_N_LSB_DATA_SHIFT); regmap_write(cs43130->regmap, CS43130_ASP_NUM_2, - (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> + (clk_gen->v.numerator & CS43130_SP_N_MSB_DATA_MASK) >> CS43130_SP_N_MSB_DATA_SHIFT); break; case CS43130_XSP_DOP_DAI: regmap_write(cs43130->regmap, CS43130_XSP_DEN_1, - (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> + (clk_gen->v.denominator & CS43130_SP_M_LSB_DATA_MASK) >> CS43130_SP_M_LSB_DATA_SHIFT); regmap_write(cs43130->regmap, CS43130_XSP_DEN_2, - (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> + (clk_gen->v.denominator & CS43130_SP_M_MSB_DATA_MASK) >> CS43130_SP_M_MSB_DATA_SHIFT); regmap_write(cs43130->regmap, CS43130_XSP_NUM_1, - (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> + (clk_gen->v.numerator & CS43130_SP_N_LSB_DATA_MASK) >> CS43130_SP_N_LSB_DATA_SHIFT); regmap_write(cs43130->regmap, CS43130_XSP_NUM_2, - (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> + (clk_gen->v.numerator & CS43130_SP_N_MSB_DATA_MASK) >> CS43130_SP_N_MSB_DATA_SHIFT); break; default: @@ -2303,7 +2303,7 @@ static int cs43130_probe(struct snd_soc_component *component) } ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK, - &cs43130->jack, NULL, 0); + &cs43130->jack); if (ret < 0) { dev_err(component->dev, "Cannot create jack\n"); return ret; @@ -2418,8 +2418,7 @@ static int cs43130_handle_device_data(struct i2c_client *i2c_client, return 0; } -static int cs43130_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs43130_i2c_probe(struct i2c_client *client) { struct cs43130_private *cs43130; int ret; @@ -2702,7 +2701,7 @@ static struct i2c_driver cs43130_i2c_driver = { .pm = &cs43130_runtime_pm, }, .id_table = cs43130_i2c_id, - .probe = cs43130_i2c_probe, + .probe_new = cs43130_i2c_probe, .remove = cs43130_i2c_remove, }; diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h index e62d671e95bb..1dd893674313 100644 --- a/sound/soc/codecs/cs43130.h +++ b/sound/soc/codecs/cs43130.h @@ -10,6 +10,8 @@ #ifndef __CS43130_H__ #define __CS43130_H__ +#include <linux/math.h> + /* CS43130 registers addresses */ /* all reg address is shifted by a byte for control byte to be LSB */ #define CS43130_FIRSTREG 0x010000 @@ -372,97 +374,96 @@ enum cs43130_dai_id { }; struct cs43130_clk_gen { - unsigned int mclk_int; - int fs; - u16 den; - u16 num; + unsigned int mclk_int; + int fs; + struct u16_fract v; }; /* frm_size = 16 */ static const struct cs43130_clk_gen cs43130_16_clk_gen[] = { - {22579200, 32000, 441, 10,}, - {22579200, 44100, 32, 1,}, - {22579200, 48000, 147, 5,}, - {22579200, 88200, 16, 1,}, - {22579200, 96000, 147, 10,}, - {22579200, 176400, 8, 1,}, - {22579200, 192000, 147, 20,}, - {22579200, 352800, 4, 1,}, - {22579200, 384000, 147, 40,}, - {24576000, 32000, 48, 1,}, - {24576000, 44100, 5120, 147,}, - {24576000, 48000, 32, 1,}, - {24576000, 88200, 2560, 147,}, - {24576000, 96000, 16, 1,}, - {24576000, 176400, 1280, 147,}, - {24576000, 192000, 8, 1,}, - {24576000, 352800, 640, 147,}, - {24576000, 384000, 4, 1,}, + { 22579200, 32000, .v = { 441, 10, }, }, + { 22579200, 44100, .v = { 32, 1, }, }, + { 22579200, 48000, .v = { 147, 5, }, }, + { 22579200, 88200, .v = { 16, 1, }, }, + { 22579200, 96000, .v = { 147, 10, }, }, + { 22579200, 176400, .v = { 8, 1, }, }, + { 22579200, 192000, .v = { 147, 20, }, }, + { 22579200, 352800, .v = { 4, 1, }, }, + { 22579200, 384000, .v = { 147, 40, }, }, + { 24576000, 32000, .v = { 48, 1, }, }, + { 24576000, 44100, .v = { 5120, 147, }, }, + { 24576000, 48000, .v = { 32, 1, }, }, + { 24576000, 88200, .v = { 2560, 147, }, }, + { 24576000, 96000, .v = { 16, 1, }, }, + { 24576000, 176400, .v = { 1280, 147, }, }, + { 24576000, 192000, .v = { 8, 1, }, }, + { 24576000, 352800, .v = { 640, 147, }, }, + { 24576000, 384000, .v = { 4, 1, }, }, }; /* frm_size = 32 */ static const struct cs43130_clk_gen cs43130_32_clk_gen[] = { - {22579200, 32000, 441, 20,}, - {22579200, 44100, 16, 1,}, - {22579200, 48000, 147, 10,}, - {22579200, 88200, 8, 1,}, - {22579200, 96000, 147, 20,}, - {22579200, 176400, 4, 1,}, - {22579200, 192000, 147, 40,}, - {22579200, 352800, 2, 1,}, - {22579200, 384000, 147, 80,}, - {24576000, 32000, 24, 1,}, - {24576000, 44100, 2560, 147,}, - {24576000, 48000, 16, 1,}, - {24576000, 88200, 1280, 147,}, - {24576000, 96000, 8, 1,}, - {24576000, 176400, 640, 147,}, - {24576000, 192000, 4, 1,}, - {24576000, 352800, 320, 147,}, - {24576000, 384000, 2, 1,}, + { 22579200, 32000, .v = { 441, 20, }, }, + { 22579200, 44100, .v = { 16, 1, }, }, + { 22579200, 48000, .v = { 147, 10, }, }, + { 22579200, 88200, .v = { 8, 1, }, }, + { 22579200, 96000, .v = { 147, 20, }, }, + { 22579200, 176400, .v = { 4, 1, }, }, + { 22579200, 192000, .v = { 147, 40, }, }, + { 22579200, 352800, .v = { 2, 1, }, }, + { 22579200, 384000, .v = { 147, 80, }, }, + { 24576000, 32000, .v = { 24, 1, }, }, + { 24576000, 44100, .v = { 2560, 147, }, }, + { 24576000, 48000, .v = { 16, 1, }, }, + { 24576000, 88200, .v = { 1280, 147, }, }, + { 24576000, 96000, .v = { 8, 1, }, }, + { 24576000, 176400, .v = { 640, 147, }, }, + { 24576000, 192000, .v = { 4, 1, }, }, + { 24576000, 352800, .v = { 320, 147, }, }, + { 24576000, 384000, .v = { 2, 1, }, }, }; /* frm_size = 48 */ static const struct cs43130_clk_gen cs43130_48_clk_gen[] = { - {22579200, 32000, 147, 100,}, - {22579200, 44100, 32, 3,}, - {22579200, 48000, 49, 5,}, - {22579200, 88200, 16, 3,}, - {22579200, 96000, 49, 10,}, - {22579200, 176400, 8, 3,}, - {22579200, 192000, 49, 20,}, - {22579200, 352800, 4, 3,}, - {22579200, 384000, 49, 40,}, - {24576000, 32000, 16, 1,}, - {24576000, 44100, 5120, 441,}, - {24576000, 48000, 32, 3,}, - {24576000, 88200, 2560, 441,}, - {24576000, 96000, 16, 3,}, - {24576000, 176400, 1280, 441,}, - {24576000, 192000, 8, 3,}, - {24576000, 352800, 640, 441,}, - {24576000, 384000, 4, 3,}, + { 22579200, 32000, .v = { 147, 100, }, }, + { 22579200, 44100, .v = { 32, 3, }, }, + { 22579200, 48000, .v = { 49, 5, }, }, + { 22579200, 88200, .v = { 16, 3, }, }, + { 22579200, 96000, .v = { 49, 10, }, }, + { 22579200, 176400, .v = { 8, 3, }, }, + { 22579200, 192000, .v = { 49, 20, }, }, + { 22579200, 352800, .v = { 4, 3, }, }, + { 22579200, 384000, .v = { 49, 40, }, }, + { 24576000, 32000, .v = { 16, 1, }, }, + { 24576000, 44100, .v = { 5120, 441, }, }, + { 24576000, 48000, .v = { 32, 3, }, }, + { 24576000, 88200, .v = { 2560, 441, }, }, + { 24576000, 96000, .v = { 16, 3, }, }, + { 24576000, 176400, .v = { 1280, 441, }, }, + { 24576000, 192000, .v = { 8, 3, }, }, + { 24576000, 352800, .v = { 640, 441, }, }, + { 24576000, 384000, .v = { 4, 3, }, }, }; /* frm_size = 64 */ static const struct cs43130_clk_gen cs43130_64_clk_gen[] = { - {22579200, 32000, 441, 40,}, - {22579200, 44100, 8, 1,}, - {22579200, 48000, 147, 20,}, - {22579200, 88200, 4, 1,}, - {22579200, 96000, 147, 40,}, - {22579200, 176400, 2, 1,}, - {22579200, 192000, 147, 80,}, - {22579200, 352800, 1, 1,}, - {24576000, 32000, 12, 1,}, - {24576000, 44100, 1280, 147,}, - {24576000, 48000, 8, 1,}, - {24576000, 88200, 640, 147,}, - {24576000, 96000, 4, 1,}, - {24576000, 176400, 320, 147,}, - {24576000, 192000, 2, 1,}, - {24576000, 352800, 160, 147,}, - {24576000, 384000, 1, 1,}, + { 22579200, 32000, .v = { 441, 40, }, }, + { 22579200, 44100, .v = { 8, 1, }, }, + { 22579200, 48000, .v = { 147, 20, }, }, + { 22579200, 88200, .v = { 4, 1, }, }, + { 22579200, 96000, .v = { 147, 40, }, }, + { 22579200, 176400, .v = { 2, 1, }, }, + { 22579200, 192000, .v = { 147, 80, }, }, + { 22579200, 352800, .v = { 1, 1, }, }, + { 24576000, 32000, .v = { 12, 1, }, }, + { 24576000, 44100, .v = { 1280, 147, }, }, + { 24576000, 48000, .v = { 8, 1, }, }, + { 24576000, 88200, .v = { 640, 147, }, }, + { 24576000, 96000, .v = { 4, 1, }, }, + { 24576000, 176400, .v = { 320, 147, }, }, + { 24576000, 192000, .v = { 2, 1, }, }, + { 24576000, 352800, .v = { 160, 147, }, }, + { 24576000, 384000, .v = { 1, 1, }, }, }; struct cs43130_bitwidth_map { diff --git a/sound/soc/codecs/cs4341.c b/sound/soc/codecs/cs4341.c index 29d05e32d341..8ac043f1aae0 100644 --- a/sound/soc/codecs/cs4341.c +++ b/sound/soc/codecs/cs4341.c @@ -225,8 +225,7 @@ static int cs4341_probe(struct device *dev) } #if IS_ENABLED(CONFIG_I2C) -static int cs4341_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cs4341_i2c_probe(struct i2c_client *i2c) { struct cs4341_priv *cs4341; @@ -260,7 +259,7 @@ static struct i2c_driver cs4341_i2c_driver = { .name = "cs4341-i2c", .of_match_table = of_match_ptr(cs4341_dt_ids), }, - .probe = cs4341_i2c_probe, + .probe_new = cs4341_i2c_probe, .id_table = cs4341_i2c_id, }; #endif diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 786c69a8ec4a..7069e9b54857 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -223,12 +223,9 @@ static const struct snd_soc_dapm_route cs4349_routes[] = { {"OutputB", NULL, "HiFi DAC"}, }; -#define CS4349_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ +#define CS4349_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) #define CS4349_PCM_RATES SNDRV_PCM_RATE_8000_192000 @@ -278,8 +275,7 @@ static const struct regmap_config cs4349_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int cs4349_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs4349_i2c_probe(struct i2c_client *client) { struct cs4349_private *cs4349; int ret; @@ -382,7 +378,7 @@ static struct i2c_driver cs4349_i2c_driver = { .pm = &cs4349_runtime_pm, }, .id_table = cs4349_i2c_id, - .probe = cs4349_i2c_probe, + .probe_new = cs4349_i2c_probe, .remove = cs4349_i2c_remove, }; diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index f2087bd38dbc..703545273900 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -918,8 +918,7 @@ static struct regmap_config cs53l30_regmap = { .use_single_write = true, }; -static int cs53l30_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cs53l30_i2c_probe(struct i2c_client *client) { const struct device_node *np = client->dev.of_node; struct device *dev = &client->dev; @@ -1125,7 +1124,7 @@ static struct i2c_driver cs53l30_i2c_driver = { .pm = &cs53l30_runtime_pm, }, .id_table = cs53l30_id, - .probe = cs53l30_i2c_probe, + .probe_new = cs53l30_i2c_probe, .remove = cs53l30_i2c_remove, }; diff --git a/sound/soc/codecs/cx2072x.c b/sound/soc/codecs/cx2072x.c index 1f5c57fab1d8..b35debb5818d 100644 --- a/sound/soc/codecs/cx2072x.c +++ b/sound/soc/codecs/cx2072x.c @@ -1527,6 +1527,7 @@ static const struct snd_soc_component_driver soc_codec_driver_cx2072x = { .num_dapm_widgets = ARRAY_SIZE(cx2072x_dapm_widgets), .dapm_routes = cx2072x_intercon, .num_dapm_routes = ARRAY_SIZE(cx2072x_intercon), + .endianness = 1, }; /* @@ -1626,8 +1627,7 @@ static int __maybe_unused cx2072x_runtime_resume(struct device *dev) return clk_prepare_enable(cx2072x->mclk); } -static int cx2072x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int cx2072x_i2c_probe(struct i2c_client *i2c) { struct cx2072x_priv *cx2072x; unsigned int ven_id, rev_id; @@ -1710,7 +1710,7 @@ static struct i2c_driver cx2072x_i2c_driver = { .acpi_match_table = ACPI_PTR(cx2072x_acpi_match), .pm = &cx2072x_runtime_pm, }, - .probe = cx2072x_i2c_probe, + .probe_new = cx2072x_i2c_probe, .remove = cx2072x_i2c_remove, .id_table = cx2072x_i2c_id, }; diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 8af344b2fdbf..3fa3042e4424 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1206,8 +1206,7 @@ static const struct regmap_config da7210_regmap_config_i2c = { .cache_type = REGCACHE_RBTREE, }; -static int da7210_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7210_i2c_probe(struct i2c_client *i2c) { struct da7210_priv *da7210; int ret; @@ -1250,7 +1249,7 @@ static struct i2c_driver da7210_i2c_driver = { .driver = { .name = "da7210", }, - .probe = da7210_i2c_probe, + .probe_new = da7210_i2c_probe, .id_table = da7210_i2c_id, }; #endif diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 3ab89387b4e6..2e645dc60eda 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1946,8 +1946,7 @@ static const char *da7213_supply_names[DA7213_NUM_SUPPLIES] = { [DA7213_SUPPLY_VDDIO] = "VDDIO", }; -static int da7213_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7213_i2c_probe(struct i2c_client *i2c) { struct da7213_priv *da7213; int i, ret; @@ -2040,7 +2039,7 @@ static struct i2c_driver da7213_i2c_driver = { .acpi_match_table = ACPI_PTR(da7213_acpi_match), .pm = &da7213_pm, }, - .probe = da7213_i2c_probe, + .probe_new = da7213_i2c_probe, .id_table = da7213_i2c_id, }; diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index ea426d986d4c..a5d7c350a3de 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3258,8 +3258,19 @@ static const struct regmap_config da7218_regmap_config = { * I2C layer */ -static int da7218_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id da7218_i2c_id[]; + +static inline int da7218_i2c_get_id(struct i2c_client *i2c) +{ + const struct i2c_device_id *id = i2c_match_id(da7218_i2c_id, i2c); + + if (id) + return (uintptr_t)id->driver_data; + else + return -EINVAL; +} + +static int da7218_i2c_probe(struct i2c_client *i2c) { struct da7218_priv *da7218; int ret; @@ -3273,7 +3284,7 @@ static int da7218_i2c_probe(struct i2c_client *i2c, if (i2c->dev.of_node) da7218->dev_id = da7218_of_get_id(&i2c->dev); else - da7218->dev_id = id->driver_data; + da7218->dev_id = da7218_i2c_get_id(i2c); if ((da7218->dev_id != DA7217_DEV_ID) && (da7218->dev_id != DA7218_DEV_ID)) { @@ -3311,7 +3322,7 @@ static struct i2c_driver da7218_i2c_driver = { .name = "da7218", .of_match_table = da7218_of_match, }, - .probe = da7218_i2c_probe, + .probe_new = da7218_i2c_probe, .id_table = da7218_i2c_id, }; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index c7493549a9a5..7fdef38ed8cd 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2655,8 +2655,7 @@ static const struct snd_soc_component_driver soc_component_dev_da7219 = { * I2C layer */ -static int da7219_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da7219_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct da7219_priv *da7219; @@ -2711,7 +2710,7 @@ static struct i2c_driver da7219_i2c_driver = { .of_match_table = of_match_ptr(da7219_of_match), .acpi_match_table = ACPI_PTR(da7219_acpi_match), }, - .probe = da7219_i2c_probe, + .probe_new = da7219_i2c_probe, .remove = da7219_i2c_remove, .id_table = da7219_i2c_id, }; diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 42d6a3fc3af5..f14cddf23f42 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1506,8 +1506,7 @@ static const struct snd_soc_component_driver soc_component_dev_da732x = { .non_legacy_dai_naming = 1, }; -static int da732x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da732x_i2c_probe(struct i2c_client *i2c) { struct da732x_priv *da732x; unsigned int reg; @@ -1562,7 +1561,7 @@ static struct i2c_driver da732x_i2c_driver = { .driver = { .name = "da7320", }, - .probe = da732x_i2c_probe, + .probe_new = da732x_i2c_probe, .remove = da732x_i2c_remove, .id_table = da732x_i2c_id, }; diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index a9676b261129..9d8c8adc5d76 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1473,8 +1473,7 @@ static const struct regmap_config da9055_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int da9055_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int da9055_i2c_probe(struct i2c_client *i2c) { struct da9055_priv *da9055; struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev); @@ -1533,7 +1532,7 @@ static struct i2c_driver da9055_i2c_driver = { .name = "da9055-codec", .of_match_table = of_match_ptr(da9055_of_match), }, - .probe = da9055_i2c_probe, + .probe_new = da9055_i2c_probe, .id_table = da9055_i2c_id, }; diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 5d079d90fd3b..d1a30ca4571a 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -82,7 +82,10 @@ static struct snd_soc_dai_driver dmic_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE - | SNDRV_PCM_FMTBIT_S16_LE, + | SNDRV_PCM_FMTBIT_S16_LE + | SNDRV_PCM_FMTBIT_DSD_U8 + | SNDRV_PCM_FMTBIT_DSD_U16_LE + | SNDRV_PCM_FMTBIT_DSD_U32_LE, }, .ops = &dmic_dai_ops, }; diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index ff33eab6f9de..4407166bb338 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -789,8 +789,7 @@ static const struct regmap_config es8316_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int es8316_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +static int es8316_i2c_probe(struct i2c_client *i2c_client) { struct device *dev = &i2c_client->dev; struct es8316_priv *es8316; @@ -852,7 +851,7 @@ static struct i2c_driver es8316_i2c_driver = { .acpi_match_table = ACPI_PTR(es8316_acpi_match), .of_match_table = of_match_ptr(es8316_of_match), }, - .probe = es8316_i2c_probe, + .probe_new = es8316_i2c_probe, .id_table = es8316_i2c_id, }; module_i2c_driver(es8316_i2c_driver); diff --git a/sound/soc/codecs/es8328-i2c.c b/sound/soc/codecs/es8328-i2c.c index 6b0df0d750dc..68072e99fcc7 100644 --- a/sound/soc/codecs/es8328-i2c.c +++ b/sound/soc/codecs/es8328-i2c.c @@ -29,8 +29,7 @@ static const struct of_device_id es8328_of_match[] = { }; MODULE_DEVICE_TABLE(of, es8328_of_match); -static int es8328_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int es8328_i2c_probe(struct i2c_client *i2c) { return es8328_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &es8328_regmap_config)); @@ -41,7 +40,7 @@ static struct i2c_driver es8328_i2c_driver = { .name = "es8328", .of_match_table = es8328_of_match, }, - .probe = es8328_i2c_probe, + .probe_new = es8328_i2c_probe, .id_table = es8328_id, }; diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index a9f61c7e44ee..8debcee59224 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -571,13 +571,14 @@ static const struct snd_soc_dapm_widget hdac_hda_dapm_widgets[] = { }; static const struct snd_soc_component_driver hdac_hda_codec = { - .probe = hdac_hda_codec_probe, - .remove = hdac_hda_codec_remove, - .idle_bias_on = false, - .dapm_widgets = hdac_hda_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(hdac_hda_dapm_widgets), - .dapm_routes = hdac_hda_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(hdac_hda_dapm_routes), + .probe = hdac_hda_codec_probe, + .remove = hdac_hda_codec_remove, + .dapm_widgets = hdac_hda_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(hdac_hda_dapm_widgets), + .dapm_routes = hdac_hda_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(hdac_hda_dapm_routes), + .idle_bias_on = false, + .endianness = 1, }; static int hdac_hda_dev_probe(struct hdac_device *hdev) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index b07607a9ecea..b773466619b2 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -727,10 +727,8 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\ SNDRV_PCM_RATE_192000) -#define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) +#define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) /* * This list is only for formats allowed on the I2S bus. So there is @@ -740,12 +738,9 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { * problems, we should add the video side driver an option to disable * them. */ -#define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ - SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) +#define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) static struct snd_kcontrol_new hdmi_codec_controls[] = { { diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 1d86b6a0eb9d..39be31e1282e 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1108,8 +1108,7 @@ static const struct regmap_config isabelle_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int isabelle_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int isabelle_i2c_probe(struct i2c_client *i2c) { struct regmap *isabelle_regmap; int ret = 0; @@ -1144,7 +1143,7 @@ static struct i2c_driver isabelle_i2c_driver = { .driver = { .name = "isabelle", }, - .probe = isabelle_i2c_probe, + .probe_new = isabelle_i2c_probe, .id_table = isabelle_i2c_id, }; diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 300b325e2fdd..dba161305de8 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -115,8 +115,7 @@ static const struct regmap_config lm4857_regmap_config = { .num_reg_defaults = ARRAY_SIZE(lm4857_default_regs), }; -static int lm4857_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int lm4857_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; @@ -138,7 +137,7 @@ static struct i2c_driver lm4857_i2c_driver = { .driver = { .name = "lm4857", }, - .probe = lm4857_i2c_probe, + .probe_new = lm4857_i2c_probe, .id_table = lm4857_i2c_id, }; diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 973d781b4b6a..bd0078e4499b 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1412,8 +1412,7 @@ static const struct regmap_config lm49453_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int lm49453_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int lm49453_i2c_probe(struct i2c_client *i2c) { struct lm49453_priv *lm49453; int ret = 0; @@ -1458,7 +1457,7 @@ static struct i2c_driver lm49453_i2c_driver = { .driver = { .name = "lm49453", }, - .probe = lm49453_i2c_probe, + .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 54426a90bc0b..54a8ba7ed3c2 100644 --- a/sound/soc/codecs/lochnagar-sc.c +++ b/sound/soc/codecs/lochnagar-sc.c @@ -212,12 +212,13 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { }; static const struct snd_soc_component_driver lochnagar_sc_driver = { - .non_legacy_dai_naming = 1, - .dapm_widgets = lochnagar_sc_widgets, .num_dapm_widgets = ARRAY_SIZE(lochnagar_sc_widgets), .dapm_routes = lochnagar_sc_routes, .num_dapm_routes = ARRAY_SIZE(lochnagar_sc_routes), + + .non_legacy_dai_naming = 1, + .endianness = 1, }; static int lochnagar_sc_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/lpass-macro-common.c b/sound/soc/codecs/lpass-macro-common.c index 6cede75ed3b5..1b9082d237c1 100644 --- a/sound/soc/codecs/lpass-macro-common.c +++ b/sound/soc/codecs/lpass-macro-common.c @@ -24,42 +24,45 @@ struct lpass_macro *lpass_macro_pds_init(struct device *dev) return ERR_PTR(-ENOMEM); l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro"); - if (IS_ERR_OR_NULL(l_pds->macro_pd)) - return NULL; - - ret = pm_runtime_get_sync(l_pds->macro_pd); - if (ret < 0) { - pm_runtime_put_noidle(l_pds->macro_pd); + if (IS_ERR_OR_NULL(l_pds->macro_pd)) { + ret = l_pds->macro_pd ? PTR_ERR(l_pds->macro_pd) : -ENODATA; goto macro_err; } + ret = pm_runtime_resume_and_get(l_pds->macro_pd); + if (ret < 0) + goto macro_sync_err; + l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec"); - if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) + if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) { + ret = l_pds->dcodec_pd ? PTR_ERR(l_pds->dcodec_pd) : -ENODATA; goto dcodec_err; + } - ret = pm_runtime_get_sync(l_pds->dcodec_pd); - if (ret < 0) { - pm_runtime_put_noidle(l_pds->dcodec_pd); + ret = pm_runtime_resume_and_get(l_pds->dcodec_pd); + if (ret < 0) goto dcodec_sync_err; - } return l_pds; dcodec_sync_err: dev_pm_domain_detach(l_pds->dcodec_pd, false); dcodec_err: pm_runtime_put(l_pds->macro_pd); -macro_err: +macro_sync_err: dev_pm_domain_detach(l_pds->macro_pd, false); +macro_err: return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(lpass_macro_pds_init); void lpass_macro_pds_exit(struct lpass_macro *pds) { - pm_runtime_put(pds->macro_pd); - dev_pm_domain_detach(pds->macro_pd, false); - pm_runtime_put(pds->dcodec_pd); - dev_pm_domain_detach(pds->dcodec_pd, false); + if (pds) { + pm_runtime_put(pds->macro_pd); + dev_pm_domain_detach(pds->macro_pd, false); + pm_runtime_put(pds->dcodec_pd); + dev_pm_domain_detach(pds->dcodec_pd, false); + } } EXPORT_SYMBOL_GPL(lpass_macro_pds_exit); diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 39dda1b03b3d..d711eb1da0a8 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -167,8 +167,7 @@ static const struct regmap_config max9768_i2c_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int max9768_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max9768_i2c_probe(struct i2c_client *client) { struct max9768 *max9768; struct max9768_pdata *pdata = client->dev.platform_data; @@ -215,7 +214,7 @@ static struct i2c_driver max9768_i2c_driver = { .driver = { .name = "max9768", }, - .probe = max9768_i2c_probe, + .probe_new = max9768_i2c_probe, .id_table = max9768_i2c_id, }; module_i2c_driver(max9768_i2c_driver); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 429717d4ac5a..5ef2e1279ee7 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1737,11 +1737,18 @@ static const struct snd_soc_component_driver soc_component_dev_max98088 = { .non_legacy_dai_naming = 1, }; -static int max98088_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id max98088_i2c_id[] = { + { "max98088", MAX98088 }, + { "max98089", MAX98089 }, + { } +}; +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; max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), GFP_KERNEL); @@ -1757,6 +1764,7 @@ static int max98088_i2c_probe(struct i2c_client *i2c, if (PTR_ERR(max98088->mclk) == -EPROBE_DEFER) return PTR_ERR(max98088->mclk); + id = i2c_match_id(max98088_i2c_id, i2c); max98088->devtype = id->driver_data; i2c_set_clientdata(i2c, max98088); @@ -1767,13 +1775,6 @@ static int max98088_i2c_probe(struct i2c_client *i2c, return ret; } -static const struct i2c_device_id max98088_i2c_id[] = { - { "max98088", MAX98088 }, - { "max98089", MAX98089 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); - #if defined(CONFIG_OF) static const struct of_device_id max98088_of_match[] = { { .compatible = "maxim,max98088" }, @@ -1788,7 +1789,7 @@ static struct i2c_driver max98088_i2c_driver = { .name = "max98088", .of_match_table = of_match_ptr(max98088_of_match), }, - .probe = max98088_i2c_probe, + .probe_new = max98088_i2c_probe, .id_table = max98088_i2c_id, }; diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 62b41ca050a2..576277a82d41 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -393,9 +393,11 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int sel = ucontrol->value.integer.value[0]; + int sel_unchecked = ucontrol->value.integer.value[0]; + unsigned int sel; unsigned int val = snd_soc_component_read(component, mc->reg); unsigned int *select; + int change; switch (mc->reg) { case M98090_REG_MIC1_INPUT_LEVEL: @@ -413,9 +415,11 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, val = (val >> mc->shift) & mask; - if (sel < 0 || sel > mc->max) + if (sel_unchecked < 0 || sel_unchecked > mc->max) return -EINVAL; + sel = sel_unchecked; + change = *select != sel; *select = sel; /* Setting a volume is only valid if it is already On */ @@ -430,7 +434,7 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, mask << mc->shift, sel << mc->shift); - return *select != val; + return change; } static const char *max98090_perf_pwr_text[] = @@ -2532,8 +2536,14 @@ static const struct regmap_config max98090_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max98090_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static const struct i2c_device_id max98090_i2c_id[] = { + { "max98090", MAX98090 }, + { "max98091", MAX98091 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max98090_i2c_id); + +static int max98090_i2c_probe(struct i2c_client *i2c) { struct max98090_priv *max98090; const struct acpi_device_id *acpi_id; @@ -2555,7 +2565,9 @@ static int max98090_i2c_probe(struct i2c_client *i2c, return -EINVAL; } driver_data = acpi_id->driver_data; - } else if (i2c_id) { + } else { + const struct i2c_device_id *i2c_id = + i2c_match_id(max98090_i2c_id, i2c); driver_data = i2c_id->driver_data; } @@ -2662,13 +2674,6 @@ static const struct dev_pm_ops max98090_pm = { SET_SYSTEM_SLEEP_PM_OPS(NULL, max98090_resume) }; -static const struct i2c_device_id max98090_i2c_id[] = { - { "max98090", MAX98090 }, - { "max98091", MAX98091 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max98090_i2c_id); - #ifdef CONFIG_OF static const struct of_device_id max98090_of_match[] = { { .compatible = "maxim,max98090", }, @@ -2693,7 +2698,7 @@ static struct i2c_driver max98090_i2c_driver = { .of_match_table = of_match_ptr(max98090_of_match), .acpi_match_table = ACPI_PTR(max98090_acpi_match), }, - .probe = max98090_i2c_probe, + .probe_new = max98090_i2c_probe, .shutdown = max98090_i2c_shutdown, .remove = max98090_i2c_remove, .id_table = max98090_i2c_id, diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 4977b00ddf5f..7bca99fa61b5 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2106,11 +2106,17 @@ static const struct snd_soc_component_driver soc_component_dev_max98095 = { .non_legacy_dai_naming = 1, }; -static int max98095_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id max98095_i2c_id[] = { + { "max98095", MAX98095 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max98095_i2c_id); + +static int max98095_i2c_probe(struct i2c_client *i2c) { struct max98095_priv *max98095; int ret; + const struct i2c_device_id *id; max98095 = devm_kzalloc(&i2c->dev, sizeof(struct max98095_priv), GFP_KERNEL); @@ -2126,6 +2132,7 @@ static int max98095_i2c_probe(struct i2c_client *i2c, return ret; } + id = i2c_match_id(max98095_i2c_id, i2c); max98095->devtype = id->driver_data; i2c_set_clientdata(i2c, max98095); max98095->pdata = i2c->dev.platform_data; @@ -2136,12 +2143,6 @@ static int max98095_i2c_probe(struct i2c_client *i2c, return ret; } -static const struct i2c_device_id max98095_i2c_id[] = { - { "max98095", MAX98095 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max98095_i2c_id); - #ifdef CONFIG_OF static const struct of_device_id max98095_of_match[] = { { .compatible = "maxim,max98095", }, @@ -2155,7 +2156,7 @@ static struct i2c_driver max98095_i2c_driver = { .name = "max98095", .of_match_table = of_match_ptr(max98095_of_match), }, - .probe = max98095_i2c_probe, + .probe_new = max98095_i2c_probe, .id_table = max98095_i2c_id, }; diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 8d42f523e420..800f2bca6a0f 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c @@ -365,8 +365,7 @@ static const struct regmap_config max98371_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max98371_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max98371_i2c_probe(struct i2c_client *i2c) { struct max98371_priv *max98371; int ret, reg; @@ -421,7 +420,7 @@ static struct i2c_driver max98371_i2c_driver = { .name = "max98371", .of_match_table = of_match_ptr(max98371_of_match), }, - .probe = max98371_i2c_probe, + .probe_new = max98371_i2c_probe, .id_table = max98371_i2c_id, }; diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c index ddb6436835d7..4fe065ece17c 100644 --- a/sound/soc/codecs/max98373-i2c.c +++ b/sound/soc/codecs/max98373-i2c.c @@ -516,8 +516,7 @@ static const struct regmap_config max98373_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max98373_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max98373_i2c_probe(struct i2c_client *i2c) { int ret = 0; int reg = 0; @@ -622,7 +621,7 @@ static struct i2c_driver max98373_i2c_driver = { .acpi_match_table = ACPI_PTR(max98373_acpi_match), .pm = &max98373_pm, }, - .probe = max98373_i2c_probe, + .probe_new = max98373_i2c_probe, .id_table = max98373_i2c_id, }; diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 40fd6f363f35..2a6b1648c884 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -1014,14 +1014,14 @@ static void max98390_slot_config(struct i2c_client *i2c, max98390->i_l_slot = 1; } -static int max98390_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max98390_i2c_probe(struct i2c_client *i2c) { int ret = 0; int reg = 0; struct max98390_priv *max98390 = NULL; struct i2c_adapter *adapter = i2c->adapter; + struct gpio_desc *reset_gpio; ret = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE @@ -1073,6 +1073,17 @@ static int max98390_i2c_probe(struct i2c_client *i2c, return ret; } + reset_gpio = devm_gpiod_get_optional(&i2c->dev, + "reset", GPIOD_OUT_HIGH); + + /* Power on device */ + if (reset_gpio) { + usleep_range(1000, 2000); + /* bring out of reset */ + gpiod_set_value_cansleep(reset_gpio, 0); + usleep_range(1000, 2000); + } + /* Check Revision ID */ ret = regmap_read(max98390->regmap, MAX98390_R24FF_REV_ID, ®); @@ -1121,7 +1132,7 @@ static struct i2c_driver max98390_i2c_driver = { .acpi_match_table = ACPI_PTR(max98390_acpi_match), .pm = &max98390_pm, }, - .probe = max98390_i2c_probe, + .probe_new = max98390_i2c_probe, .id_table = max98390_i2c_id, }; diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c new file mode 100644 index 000000000000..56eb62bb041f --- /dev/null +++ b/sound/soc/codecs/max98396.c @@ -0,0 +1,1637 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2022, Analog Devices Inc. + +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <linux/gpio.h> +#include <sound/tlv.h> +#include "max98396.h" + +static struct reg_default max98396_reg[] = { + {MAX98396_R2000_SW_RESET, 0x00}, + {MAX98396_R2001_INT_RAW1, 0x00}, + {MAX98396_R2002_INT_RAW2, 0x00}, + {MAX98396_R2003_INT_RAW3, 0x00}, + {MAX98396_R2004_INT_RAW4, 0x00}, + {MAX98396_R2006_INT_STATE1, 0x00}, + {MAX98396_R2007_INT_STATE2, 0x00}, + {MAX98396_R2008_INT_STATE3, 0x00}, + {MAX98396_R2009_INT_STATE4, 0x00}, + {MAX98396_R200B_INT_FLAG1, 0x00}, + {MAX98396_R200C_INT_FLAG2, 0x00}, + {MAX98396_R200D_INT_FLAG3, 0x00}, + {MAX98396_R200E_INT_FLAG4, 0x00}, + {MAX98396_R2010_INT_EN1, 0x02}, + {MAX98396_R2011_INT_EN2, 0x00}, + {MAX98396_R2012_INT_EN3, 0x00}, + {MAX98396_R2013_INT_EN4, 0x00}, + {MAX98396_R2015_INT_FLAG_CLR1, 0x00}, + {MAX98396_R2016_INT_FLAG_CLR2, 0x00}, + {MAX98396_R2017_INT_FLAG_CLR3, 0x00}, + {MAX98396_R2018_INT_FLAG_CLR4, 0x00}, + {MAX98396_R201F_IRQ_CTRL, 0x00}, + {MAX98396_R2020_THERM_WARN_THRESH, 0x46}, + {MAX98396_R2021_THERM_WARN_THRESH2, 0x46}, + {MAX98396_R2022_THERM_SHDN_THRESH, 0x64}, + {MAX98396_R2023_THERM_HYSTERESIS, 0x02}, + {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5}, + {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01}, + {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32}, + {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00}, + {MAX98396_R2038_CLK_MON_CTRL, 0x00}, + {MAX98396_R2039_DATA_MON_CTRL, 0x00}, + {MAX98396_R203F_ENABLE_CTRLS, 0x0F}, + {MAX98396_R2040_PIN_CFG, 0x55}, + {MAX98396_R2041_PCM_MODE_CFG, 0xC0}, + {MAX98396_R2042_PCM_CLK_SETUP, 0x04}, + {MAX98396_R2043_PCM_SR_SETUP, 0x88}, + {MAX98396_R2044_PCM_TX_CTRL_1, 0x00}, + {MAX98396_R2045_PCM_TX_CTRL_2, 0x00}, + {MAX98396_R2046_PCM_TX_CTRL_3, 0x00}, + {MAX98396_R2047_PCM_TX_CTRL_4, 0x00}, + {MAX98396_R2048_PCM_TX_CTRL_5, 0x00}, + {MAX98396_R2049_PCM_TX_CTRL_6, 0x00}, + {MAX98396_R204A_PCM_TX_CTRL_7, 0x00}, + {MAX98396_R204B_PCM_TX_CTRL_8, 0x00}, + {MAX98396_R204C_PCM_TX_HIZ_CTRL_1, 0xFF}, + {MAX98396_R204D_PCM_TX_HIZ_CTRL_2, 0xFF}, + {MAX98396_R204E_PCM_TX_HIZ_CTRL_3, 0xFF}, + {MAX98396_R204F_PCM_TX_HIZ_CTRL_4, 0xFF}, + {MAX98396_R2050_PCM_TX_HIZ_CTRL_5, 0xFF}, + {MAX98396_R2051_PCM_TX_HIZ_CTRL_6, 0xFF}, + {MAX98396_R2052_PCM_TX_HIZ_CTRL_7, 0xFF}, + {MAX98396_R2053_PCM_TX_HIZ_CTRL_8, 0xFF}, + {MAX98396_R2055_PCM_RX_SRC1, 0x00}, + {MAX98396_R2056_PCM_RX_SRC2, 0x00}, + {MAX98396_R2058_PCM_BYPASS_SRC, 0x00}, + {MAX98396_R205D_PCM_TX_SRC_EN, 0x00}, + {MAX98396_R205E_PCM_RX_EN, 0x00}, + {MAX98396_R205F_PCM_TX_EN, 0x00}, + {MAX98396_R2070_ICC_RX_EN_A, 0x00}, + {MAX98396_R2071_ICC_RX_EN_B, 0x00}, + {MAX98396_R2072_ICC_TX_CTRL, 0x00}, + {MAX98396_R207F_ICC_EN, 0x00}, + {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04}, + {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00}, + {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00}, + {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00}, + {MAX98396_R208F_TONE_GEN_EN, 0x00}, + {MAX98396_R2090_AMP_VOL_CTRL, 0x00}, + {MAX98396_R2091_AMP_PATH_GAIN, 0x0B}, + {MAX98396_R2092_AMP_DSP_CFG, 0x23}, + {MAX98396_R2093_SSM_CFG, 0x0D}, + {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12}, + {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17}, + {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17}, + {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00}, + {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00}, + {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03}, + {MAX98396_R209A_SPK_EDGE_CTRL, 0x00}, + {MAX98396_R209C_SPK_EDGE_CTRL1, 0x0A}, + {MAX98396_R209D_SPK_EDGE_CTRL2, 0xAA}, + {MAX98396_R209E_AMP_CLIP_GAIN, 0x00}, + {MAX98396_R209F_BYPASS_PATH_CFG, 0x00}, + {MAX98396_R20A0_AMP_SUPPLY_CTL, 0x00}, + {MAX98396_R20AF_AMP_EN, 0x00}, + {MAX98396_R20B0_ADC_SR, 0x30}, + {MAX98396_R20B1_ADC_PVDD_CFG, 0x00}, + {MAX98396_R20B2_ADC_VBAT_CFG, 0x00}, + {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00}, + {MAX98396_R20B4_ADC_READBACK_CTRL1, 0x00}, + {MAX98396_R20B5_ADC_READBACK_CTRL2, 0x00}, + {MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0x00}, + {MAX98396_R20B7_ADC_PVDD_READBACK_LSB, 0x00}, + {MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0x00}, + {MAX98396_R20B9_ADC_VBAT_READBACK_LSB, 0x00}, + {MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0x00}, + {MAX98396_R20BB_ADC_TEMP_READBACK_LSB, 0x00}, + {MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB, 0x00}, + {MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB, 0x00}, + {MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB, 0x00}, + {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00}, + {MAX98396_R20C7_ADC_CFG, 0x00}, + {MAX98396_R20D0_DHT_CFG1, 0x00}, + {MAX98396_R20D1_LIMITER_CFG1, 0x08}, + {MAX98396_R20D2_LIMITER_CFG2, 0x00}, + {MAX98396_R20D3_DHT_CFG2, 0x14}, + {MAX98396_R20D4_DHT_CFG3, 0x02}, + {MAX98396_R20D5_DHT_CFG4, 0x04}, + {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07}, + {MAX98396_R20DF_DHT_EN, 0x00}, + {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04}, + {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00}, + {MAX98396_R20E5_BPE_STATE, 0x00}, + {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00}, + {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00}, + {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00}, + {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00}, + {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00}, + {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00}, + {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00}, + {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00}, + {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00}, + {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00}, + {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00}, + {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00}, + {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00}, + {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00}, + {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00}, + {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00}, + {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00}, + {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00}, + {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00}, + {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00}, + {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00}, + {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00}, + {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00}, + {MAX98396_R2109_BPE_LOW_STATE, 0x00}, + {MAX98396_R210A_BPE_LOW_GAIN, 0x00}, + {MAX98396_R210B_BPE_LOW_LIMITER, 0x00}, + {MAX98396_R210D_BPE_EN, 0x00}, + {MAX98396_R210E_AUTO_RESTART, 0x00}, + {MAX98396_R210F_GLOBAL_EN, 0x00}, + {MAX98396_R21FF_REVISION_ID, 0x00}, +}; + +static struct reg_default max98397_reg[] = { + {MAX98396_R2000_SW_RESET, 0x00}, + {MAX98396_R2001_INT_RAW1, 0x00}, + {MAX98396_R2002_INT_RAW2, 0x00}, + {MAX98396_R2003_INT_RAW3, 0x00}, + {MAX98396_R2004_INT_RAW4, 0x00}, + {MAX98396_R2006_INT_STATE1, 0x00}, + {MAX98396_R2007_INT_STATE2, 0x00}, + {MAX98396_R2008_INT_STATE3, 0x00}, + {MAX98396_R2009_INT_STATE4, 0x00}, + {MAX98396_R200B_INT_FLAG1, 0x00}, + {MAX98396_R200C_INT_FLAG2, 0x00}, + {MAX98396_R200D_INT_FLAG3, 0x00}, + {MAX98396_R200E_INT_FLAG4, 0x00}, + {MAX98396_R2010_INT_EN1, 0x02}, + {MAX98396_R2011_INT_EN2, 0x00}, + {MAX98396_R2012_INT_EN3, 0x00}, + {MAX98396_R2013_INT_EN4, 0x00}, + {MAX98396_R2015_INT_FLAG_CLR1, 0x00}, + {MAX98396_R2016_INT_FLAG_CLR2, 0x00}, + {MAX98396_R2017_INT_FLAG_CLR3, 0x00}, + {MAX98396_R2018_INT_FLAG_CLR4, 0x00}, + {MAX98396_R201F_IRQ_CTRL, 0x00}, + {MAX98396_R2020_THERM_WARN_THRESH, 0x46}, + {MAX98396_R2021_THERM_WARN_THRESH2, 0x46}, + {MAX98396_R2022_THERM_SHDN_THRESH, 0x64}, + {MAX98396_R2023_THERM_HYSTERESIS, 0x02}, + {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5}, + {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01}, + {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32}, + {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00}, + {MAX98396_R2038_CLK_MON_CTRL, 0x00}, + {MAX98396_R2039_DATA_MON_CTRL, 0x00}, + {MAX98397_R203A_SPK_MON_THRESH, 0x03}, + {MAX98396_R203F_ENABLE_CTRLS, 0x0F}, + {MAX98396_R2040_PIN_CFG, 0x55}, + {MAX98396_R2041_PCM_MODE_CFG, 0xC0}, + {MAX98396_R2042_PCM_CLK_SETUP, 0x04}, + {MAX98396_R2043_PCM_SR_SETUP, 0x88}, + {MAX98396_R2044_PCM_TX_CTRL_1, 0x00}, + {MAX98396_R2045_PCM_TX_CTRL_2, 0x00}, + {MAX98396_R2046_PCM_TX_CTRL_3, 0x00}, + {MAX98396_R2047_PCM_TX_CTRL_4, 0x00}, + {MAX98396_R2048_PCM_TX_CTRL_5, 0x00}, + {MAX98396_R2049_PCM_TX_CTRL_6, 0x00}, + {MAX98396_R204A_PCM_TX_CTRL_7, 0x00}, + {MAX98396_R204B_PCM_TX_CTRL_8, 0x00}, + {MAX98397_R204C_PCM_TX_CTRL_9, 0x00}, + {MAX98397_R204D_PCM_TX_HIZ_CTRL_1, 0xFF}, + {MAX98397_R204E_PCM_TX_HIZ_CTRL_2, 0xFF}, + {MAX98397_R204F_PCM_TX_HIZ_CTRL_3, 0xFF}, + {MAX98397_R2050_PCM_TX_HIZ_CTRL_4, 0xFF}, + {MAX98397_R2051_PCM_TX_HIZ_CTRL_5, 0xFF}, + {MAX98397_R2052_PCM_TX_HIZ_CTRL_6, 0xFF}, + {MAX98397_R2053_PCM_TX_HIZ_CTRL_7, 0xFF}, + {MAX98397_R2054_PCM_TX_HIZ_CTRL_8, 0xFF}, + {MAX98397_R2056_PCM_RX_SRC1, 0x00}, + {MAX98397_R2057_PCM_RX_SRC2, 0x00}, + {MAX98396_R2058_PCM_BYPASS_SRC, 0x00}, + {MAX98396_R205D_PCM_TX_SRC_EN, 0x00}, + {MAX98396_R205E_PCM_RX_EN, 0x00}, + {MAX98396_R205F_PCM_TX_EN, 0x00}, + {MAX98397_R2060_PCM_TX_SUPPLY_SEL, 0x00}, + {MAX98396_R2070_ICC_RX_EN_A, 0x00}, + {MAX98396_R2071_ICC_RX_EN_B, 0x00}, + {MAX98396_R2072_ICC_TX_CTRL, 0x00}, + {MAX98396_R207F_ICC_EN, 0x00}, + {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04}, + {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00}, + {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00}, + {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00}, + {MAX98396_R208F_TONE_GEN_EN, 0x00}, + {MAX98396_R2090_AMP_VOL_CTRL, 0x00}, + {MAX98396_R2091_AMP_PATH_GAIN, 0x12}, + {MAX98396_R2092_AMP_DSP_CFG, 0x22}, + {MAX98396_R2093_SSM_CFG, 0x08}, + {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12}, + {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17}, + {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17}, + {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00}, + {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00}, + {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03}, + {MAX98396_R209A_SPK_EDGE_CTRL, 0x00}, + {MAX98397_R209B_SPK_PATH_WB_ONLY, 0x00}, + {MAX98396_R209C_SPK_EDGE_CTRL1, 0x03}, + {MAX98396_R209D_SPK_EDGE_CTRL2, 0xFC}, + {MAX98396_R209E_AMP_CLIP_GAIN, 0x00}, + {MAX98396_R209F_BYPASS_PATH_CFG, 0x00}, + {MAX98396_R20AF_AMP_EN, 0x00}, + {MAX98396_R20B0_ADC_SR, 0x30}, + {MAX98396_R20B1_ADC_PVDD_CFG, 0x00}, + {MAX98396_R20B2_ADC_VBAT_CFG, 0x00}, + {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00}, + {MAX98397_R20B4_ADC_VDDH_CFG, 0x00}, + {MAX98397_R20B5_ADC_READBACK_CTRL1, 0x00}, + {MAX98397_R20B6_ADC_READBACK_CTRL2, 0x00}, + {MAX98397_R20B7_ADC_PVDD_READBACK_MSB, 0x00}, + {MAX98397_R20B8_ADC_PVDD_READBACK_LSB, 0x00}, + {MAX98397_R20B9_ADC_VBAT_READBACK_MSB, 0x00}, + {MAX98397_R20BA_ADC_VBAT_READBACK_LSB, 0x00}, + {MAX98397_R20BB_ADC_TEMP_READBACK_MSB, 0x00}, + {MAX98397_R20BC_ADC_TEMP_READBACK_LSB, 0x00}, + {MAX98397_R20BD_ADC_VDDH__READBACK_MSB, 0x00}, + {MAX98397_R20BE_ADC_VDDH_READBACK_LSB, 0x00}, + {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00}, + {MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB, 0x00}, + {MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB, 0x00}, + {MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE, 0x04}, + {MAX98396_R20C7_ADC_CFG, 0x00}, + {MAX98396_R20D0_DHT_CFG1, 0x00}, + {MAX98396_R20D1_LIMITER_CFG1, 0x08}, + {MAX98396_R20D2_LIMITER_CFG2, 0x00}, + {MAX98396_R20D3_DHT_CFG2, 0x14}, + {MAX98396_R20D4_DHT_CFG3, 0x02}, + {MAX98396_R20D5_DHT_CFG4, 0x04}, + {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07}, + {MAX98396_R20DF_DHT_EN, 0x00}, + {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04}, + {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00}, + {MAX98396_R20E5_BPE_STATE, 0x00}, + {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00}, + {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00}, + {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00}, + {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00}, + {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00}, + {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00}, + {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00}, + {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00}, + {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00}, + {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00}, + {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00}, + {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00}, + {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00}, + {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00}, + {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00}, + {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00}, + {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00}, + {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00}, + {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00}, + {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00}, + {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00}, + {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00}, + {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00}, + {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00}, + {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00}, + {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00}, + {MAX98396_R2109_BPE_LOW_STATE, 0x00}, + {MAX98396_R210A_BPE_LOW_GAIN, 0x00}, + {MAX98396_R210B_BPE_LOW_LIMITER, 0x00}, + {MAX98396_R210D_BPE_EN, 0x00}, + {MAX98396_R210E_AUTO_RESTART, 0x00}, + {MAX98396_R210F_GLOBAL_EN, 0x00}, + {MAX98397_R22FF_REVISION_ID, 0x00}, +}; + +static void max98396_global_enable_onoff(struct regmap *regmap, bool onoff) +{ + regmap_write(regmap, MAX98396_R210F_GLOBAL_EN, onoff ? 1 : 0); + usleep_range(11000, 12000); +} + +static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_component *component = codec_dai->component; + struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); + unsigned int format = 0; + unsigned int bclk_pol = 0; + int ret, status; + int reg; + bool update = false; + + dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt); + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + format = MAX98396_PCM_MODE_CFG_LRCLKEDGE; + break; + case SND_SOC_DAIFMT_IB_NF: + bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE; + break; + case SND_SOC_DAIFMT_IB_IF: + bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE; + format = MAX98396_PCM_MODE_CFG_LRCLKEDGE; + break; + + default: + dev_err(component->dev, "DAI invert mode unsupported\n"); + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + format |= MAX98396_PCM_FORMAT_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + format |= MAX98396_PCM_FORMAT_LJ; + break; + case SND_SOC_DAIFMT_DSP_A: + format |= MAX98396_PCM_FORMAT_TDM_MODE1; + break; + case SND_SOC_DAIFMT_DSP_B: + format |= MAX98396_PCM_FORMAT_TDM_MODE0; + break; + default: + return -EINVAL; + } + + ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status); + if (ret < 0) + return -EINVAL; + + if (status) { + ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®); + if (ret < 0) + return -EINVAL; + if (format != (reg & MAX98396_PCM_BCLKEDGE_BSEL_MASK)) { + update = true; + } else { + ret = regmap_read(max98396->regmap, + MAX98396_R2042_PCM_CLK_SETUP, ®); + if (ret < 0) + return -EINVAL; + if (bclk_pol != (reg & MAX98396_PCM_MODE_CFG_BCLKEDGE)) + update = true; + } + /* GLOBAL_EN OFF prior to pcm mode, clock configuration change */ + if (update) + max98396_global_enable_onoff(max98396->regmap, false); + } + + regmap_update_bits(max98396->regmap, + MAX98396_R2041_PCM_MODE_CFG, + MAX98396_PCM_BCLKEDGE_BSEL_MASK, + format); + + regmap_update_bits(max98396->regmap, + MAX98396_R2042_PCM_CLK_SETUP, + MAX98396_PCM_MODE_CFG_BCLKEDGE, + bclk_pol); + + if (status && update) + max98396_global_enable_onoff(max98396->regmap, true); + + return 0; +} + +/* BCLKs per LRCLK */ +static const int bclk_sel_table[] = { + 32, 48, 64, 96, 128, 192, 256, 384, 512, 320, +}; + +static int max98396_get_bclk_sel(int bclk) +{ + 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; + + 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); + } + + return 0; +} + +static int max98396_dai_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 max98396_priv *max98396 = snd_soc_component_get_drvdata(component); + unsigned int sampling_rate = 0; + unsigned int chan_sz = 0; + int ret, reg; + int status; + bool update = false; + + /* pcm mode configuration */ + switch (snd_pcm_format_width(params_format(params))) { + case 16: + chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16; + break; + case 24: + chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24; + break; + case 32: + chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32; + break; + default: + dev_err(component->dev, "format unsupported %d\n", + params_format(params)); + goto err; + } + + max98396->ch_size = snd_pcm_format_width(params_format(params)); + + dev_dbg(component->dev, "format supported %d", + params_format(params)); + + /* sampling rate configuration */ + switch (params_rate(params)) { + case 8000: + sampling_rate = MAX98396_PCM_SR_8000; + break; + case 11025: + sampling_rate = MAX98396_PCM_SR_11025; + break; + case 12000: + sampling_rate = MAX98396_PCM_SR_12000; + break; + case 16000: + sampling_rate = MAX98396_PCM_SR_16000; + break; + case 22050: + sampling_rate = MAX98396_PCM_SR_22050; + break; + case 24000: + sampling_rate = MAX98396_PCM_SR_24000; + break; + case 32000: + sampling_rate = MAX98396_PCM_SR_32000; + break; + case 44100: + sampling_rate = MAX98396_PCM_SR_44100; + break; + case 48000: + sampling_rate = MAX98396_PCM_SR_48000; + break; + case 88200: + sampling_rate = MAX98396_PCM_SR_88200; + break; + case 96000: + sampling_rate = MAX98396_PCM_SR_96000; + break; + case 192000: + sampling_rate = MAX98396_PCM_SR_192000; + break; + default: + dev_err(component->dev, "rate %d not supported\n", + params_rate(params)); + goto err; + } + + ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status); + if (ret < 0) + goto err; + + if (status) { + ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®); + if (ret < 0) + goto err; + if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) { + update = true; + } else { + ret = regmap_read(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, ®); + if (ret < 0) + goto err; + if (sampling_rate != (reg & MAX98396_PCM_SR_MASK)) + update = true; + } + + /* GLOBAL_EN OFF prior to channel size and sampling rate change */ + if (update) + max98396_global_enable_onoff(max98396->regmap, false); + } + + /* set channel size */ + regmap_update_bits(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, + MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz); + + /* set DAI_SR to correct LRCLK frequency */ + regmap_update_bits(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, + MAX98396_PCM_SR_MASK, sampling_rate); + + /* set sampling rate of IV */ + if (max98396->interleave_mode && + sampling_rate > MAX98396_PCM_SR_16000) + regmap_update_bits(max98396->regmap, + MAX98396_R2043_PCM_SR_SETUP, + MAX98396_IVADC_SR_MASK, + (sampling_rate - 3) + << MAX98396_IVADC_SR_SHIFT); + else + regmap_update_bits(max98396->regmap, + MAX98396_R2043_PCM_SR_SETUP, + MAX98396_IVADC_SR_MASK, + sampling_rate << MAX98396_IVADC_SR_SHIFT); + + ret = max98396_set_clock(component, params); + + if (status && update) + max98396_global_enable_onoff(max98396->regmap, true); + + return ret; + +err: + return -EINVAL; +} + +static int max98396_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 max98396_priv *max98396 = + snd_soc_component_get_drvdata(component); + int bsel; + unsigned int chan_sz = 0; + int ret, status; + int reg; + bool update = false; + + if (!tx_mask && !rx_mask && !slots && !slot_width) + max98396->tdm_mode = false; + else + 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); + return -EINVAL; + } + + /* Channel size configuration */ + switch (slot_width) { + case 16: + chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16; + break; + case 24: + chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24; + break; + case 32: + chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32; + break; + default: + dev_err(component->dev, "format unsupported %d\n", + slot_width); + return -EINVAL; + } + + ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status); + if (ret < 0) + return -EINVAL; + + if (status) { + ret = regmap_read(max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, ®); + if (ret < 0) + return -EINVAL; + if (bsel != (reg & MAX98396_PCM_CLK_SETUP_BSEL_MASK)) { + update = true; + } else { + ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®); + if (ret < 0) + return -EINVAL; + if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) + update = true; + } + + /* GLOBAL_EN OFF prior to channel size and BCLK per LRCLK change */ + if (update) + max98396_global_enable_onoff(max98396->regmap, false); + } + + regmap_update_bits(max98396->regmap, + MAX98396_R2042_PCM_CLK_SETUP, + MAX98396_PCM_CLK_SETUP_BSEL_MASK, + bsel); + + regmap_update_bits(max98396->regmap, + MAX98396_R2041_PCM_MODE_CFG, + MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz); + + /* Rx slot configuration */ + if (max98396->device_id == CODEC_TYPE_MAX98396) { + regmap_update_bits(max98396->regmap, + MAX98396_R2056_PCM_RX_SRC2, + MAX98396_PCM_DMIX_CH0_SRC_MASK, + rx_mask); + regmap_update_bits(max98396->regmap, + MAX98396_R2056_PCM_RX_SRC2, + MAX98396_PCM_DMIX_CH1_SRC_MASK, + rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT); + } else { + regmap_update_bits(max98396->regmap, + MAX98397_R2057_PCM_RX_SRC2, + MAX98396_PCM_DMIX_CH0_SRC_MASK, + rx_mask); + regmap_update_bits(max98396->regmap, + MAX98397_R2057_PCM_RX_SRC2, + MAX98396_PCM_DMIX_CH1_SRC_MASK, + rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT); + } + + /* Tx slot Hi-Z configuration */ + if (max98396->device_id == CODEC_TYPE_MAX98396) { + regmap_write(max98396->regmap, + MAX98396_R2053_PCM_TX_HIZ_CTRL_8, + ~tx_mask & 0xFF); + regmap_write(max98396->regmap, + MAX98396_R2052_PCM_TX_HIZ_CTRL_7, + (~tx_mask & 0xFF00) >> 8); + } else { + regmap_write(max98396->regmap, + MAX98397_R2054_PCM_TX_HIZ_CTRL_8, + ~tx_mask & 0xFF); + regmap_write(max98396->regmap, + MAX98397_R2053_PCM_TX_HIZ_CTRL_7, + (~tx_mask & 0xFF00) >> 8); + } + + if (status && update) + max98396_global_enable_onoff(max98396->regmap, true); + + return 0; +} + +#define MAX98396_RATES SNDRV_PCM_RATE_8000_192000 + +#define MAX98396_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static const struct snd_soc_dai_ops max98396_dai_ops = { + .set_fmt = max98396_dai_set_fmt, + .hw_params = max98396_dai_hw_params, + .set_tdm_slot = max98396_dai_tdm_slot, +}; + +static int max98396_dac_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 max98396_priv *max98396 = + snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + max98396_global_enable_onoff(max98396->regmap, true); + break; + case SND_SOC_DAPM_PRE_PMD: + max98396_global_enable_onoff(max98396->regmap, false); + + max98396->tdm_mode = false; + break; + default: + return 0; + } + return 0; +} + +static bool max98396_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4: + case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4: + case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4: + case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4: + case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4: + case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET: + case MAX98396_R2027_THERM_FOLDBACK_EN: + case MAX98396_R2030_NOISEGATE_MODE_CTRL: + case MAX98396_R2033_NOISEGATE_MODE_EN: + case MAX98396_R2038_CLK_MON_CTRL ... MAX98396_R2039_DATA_MON_CTRL: + case MAX98396_R203F_ENABLE_CTRLS ... MAX98396_R2053_PCM_TX_HIZ_CTRL_8: + case MAX98396_R2055_PCM_RX_SRC1 ... MAX98396_R2056_PCM_RX_SRC2: + case MAX98396_R2058_PCM_BYPASS_SRC: + case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98396_R205F_PCM_TX_EN: + case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL: + case MAX98396_R207F_ICC_EN: + case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3: + case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209A_SPK_EDGE_CTRL: + case MAX98396_R209C_SPK_EDGE_CTRL1 ... MAX98396_R20A0_AMP_SUPPLY_CTL: + case MAX98396_R20AF_AMP_EN ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB: + case MAX98396_R20C7_ADC_CFG: + case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG: + case MAX98396_R20DF_DHT_EN: + case MAX98396_R20E0_IV_SENSE_PATH_CFG: + case MAX98396_R20E4_IV_SENSE_PATH_EN + ... MAX98396_R2106_BPE_THRESH_HYSTERESIS: + case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER: + case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN: + case MAX98396_R21FF_REVISION_ID: + return true; + default: + return false; + } +}; + +static bool max98396_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX98396_R2000_SW_RESET: + case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4: + case MAX98396_R2041_PCM_MODE_CFG: + case MAX98396_R20B6_ADC_PVDD_READBACK_MSB + ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB: + case MAX98396_R20E5_BPE_STATE: + case MAX98396_R2109_BPE_LOW_STATE + ... MAX98396_R210B_BPE_LOW_LIMITER: + case MAX98396_R210F_GLOBAL_EN: + case MAX98396_R21FF_REVISION_ID: + return true; + default: + return false; + } +} + +static bool max98397_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4: + case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4: + case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4: + case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4: + case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4: + case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET: + case MAX98396_R2027_THERM_FOLDBACK_EN: + case MAX98396_R2030_NOISEGATE_MODE_CTRL: + case MAX98396_R2033_NOISEGATE_MODE_EN: + case MAX98396_R2038_CLK_MON_CTRL ... MAX98397_R203A_SPK_MON_THRESH: + case MAX98396_R203F_ENABLE_CTRLS ... MAX98397_R2054_PCM_TX_HIZ_CTRL_8: + case MAX98397_R2056_PCM_RX_SRC1... MAX98396_R2058_PCM_BYPASS_SRC: + case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98397_R2060_PCM_TX_SUPPLY_SEL: + case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL: + case MAX98396_R207F_ICC_EN: + case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3: + case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209F_BYPASS_PATH_CFG: + case MAX98396_R20AF_AMP_EN ... MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE: + case MAX98396_R20C7_ADC_CFG: + case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG: + case MAX98396_R20DF_DHT_EN: + case MAX98396_R20E0_IV_SENSE_PATH_CFG: + case MAX98396_R20E4_IV_SENSE_PATH_EN + ... MAX98396_R2106_BPE_THRESH_HYSTERESIS: + case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER: + case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN: + case MAX98397_R22FF_REVISION_ID: + return true; + default: + return false; + } +}; + +static bool max98397_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4: + case MAX98396_R2041_PCM_MODE_CFG: + case MAX98397_R20B7_ADC_PVDD_READBACK_MSB + ... MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB: + case MAX98396_R20E5_BPE_STATE: + case MAX98396_R2109_BPE_LOW_STATE + ... MAX98396_R210B_BPE_LOW_LIMITER: + case MAX98396_R210F_GLOBAL_EN: + case MAX98397_R22FF_REVISION_ID: + return true; + default: + return false; + } +} + +static const char * const max98396_op_mod_text[] = { + "DG", "PVDD", "VBAT", +}; + +static SOC_ENUM_SINGLE_DECL(max98396_op_mod_enum, + MAX98396_R2098_SPK_CLS_DG_MODE, + 0, max98396_op_mod_text); + +static DECLARE_TLV_DB_SCALE(max98396_digital_tlv, -6350, 50, 1); +static const DECLARE_TLV_DB_RANGE(max98396_spk_tlv, + 0, 0x11, TLV_DB_SCALE_ITEM(400, 100, 0), +); +static DECLARE_TLV_DB_RANGE(max98397_digital_tlv, + 0, 0x4A, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), + 0x4B, 0xFF, TLV_DB_SCALE_ITEM(-9000, 50, 0), +); +static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv, + 0, 0x15, TLV_DB_SCALE_ITEM(600, 100, 0), +); + +static int max98396_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_dapm_kcontrol_component(kcontrol); + struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); + int reg, val; + + if (max98396->device_id == CODEC_TYPE_MAX98396) + reg = MAX98396_R2055_PCM_RX_SRC1; + else + reg = MAX98397_R2056_PCM_RX_SRC1; + + regmap_read(max98396->regmap, reg, &val); + + ucontrol->value.enumerated.item[0] = val; + + return 0; +} + +static int max98396_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int *item = ucontrol->value.enumerated.item; + int reg, val; + int change; + + if (item[0] >= e->items) + return -EINVAL; + + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; + + if (max98396->device_id == CODEC_TYPE_MAX98396) + reg = MAX98396_R2055_PCM_RX_SRC1; + else + reg = MAX98397_R2056_PCM_RX_SRC1; + + change = snd_soc_component_test_bits(component, reg, + MAX98396_PCM_RX_MASK, val); + + if (change) + regmap_update_bits(max98396->regmap, reg, + MAX98396_PCM_RX_MASK, val); + + snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL); + + return change; +} + +static const char * const max98396_switch_text[] = { + "Left", "Right", "LeftRight"}; + +static SOC_ENUM_SINGLE_DECL(dai_sel_enum, SND_SOC_NOPM, 0, + max98396_switch_text); + +static const struct snd_kcontrol_new max98396_dai_mux = + SOC_DAPM_ENUM_EXT("DAI Sel Mux", dai_sel_enum, + max98396_mux_get, max98396_mux_put); + +static const struct snd_kcontrol_new max98396_vi_control = + SOC_DAPM_SINGLE("Switch", MAX98396_R205F_PCM_TX_EN, 0, 1, 0); + +static const struct snd_soc_dapm_widget max98396_dapm_widgets[] = { + SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", + MAX98396_R20AF_AMP_EN, 0, 0, max98396_dac_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0, + &max98396_dai_mux), + SND_SOC_DAPM_OUTPUT("BE_OUT"), + SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0, + MAX98396_R20E4_IV_SENSE_PATH_EN, 0, 0), + SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0, + MAX98396_R20E4_IV_SENSE_PATH_EN, 1, 0), + SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0, + &max98396_vi_control), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON"), + SND_SOC_DAPM_SIGGEN("FBMON"), +}; + +static const char * const max98396_thermal_thresh_text[] = { + "50C", "51C", "52C", "53C", "54C", "55C", "56C", "57C", + "58C", "59C", "60C", "61C", "62C", "63C", "64C", "65C", + "66C", "67C", "68C", "69C", "70C", "71C", "72C", "73C", + "74C", "75C", "76C", "77C", "78C", "79C", "80C", "81C", + "82C", "83C", "84C", "85C", "86C", "87C", "88C", "89C", + "90C", "91C", "92C", "93C", "94C", "95C", "96C", "97C", + "98C", "99C", "100C", "101C", "102C", "103C", "104C", "105C", + "106C", "107C", "108C", "109C", "110C", "111C", "112C", "113C", + "114C", "115C", "116C", "117C", "118C", "119C", "120C", "121C", + "122C", "123C", "124C", "125C", "126C", "127C", "128C", "129C", + "130C", "131C", "132C", "133C", "134C", "135C", "136C", "137C", + "138C", "139C", "140C", "141C", "142C", "143C", "144C", "145C", + "146C", "147C", "148C", "149C", "150C" +}; + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh1_enum, + MAX98396_R2020_THERM_WARN_THRESH, 0, + max98396_thermal_thresh_text); + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh2_enum, + MAX98396_R2021_THERM_WARN_THRESH2, 0, + max98396_thermal_thresh_text); + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_shdn_thresh_enum, + MAX98396_R2022_THERM_SHDN_THRESH, 0, + max98396_thermal_thresh_text); + +static const char * const max98396_thermal_hyteresis_text[] = { + "2C", "5C", "7C", "10C" +}; + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_hysteresis_enum, + MAX98396_R2023_THERM_HYSTERESIS, 0, + max98396_thermal_hyteresis_text); + +static const char * const max98396_foldback_slope_text[] = { + "0.25", "0.5", "1.0", "2.0" +}; + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope1_enum, + MAX98396_R2024_THERM_FOLDBACK_SET, + MAX98396_THERM_FB_SLOPE1_SHIFT, + max98396_foldback_slope_text); + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope2_enum, + MAX98396_R2024_THERM_FOLDBACK_SET, + MAX98396_THERM_FB_SLOPE2_SHIFT, + max98396_foldback_slope_text); + +static const char * const max98396_foldback_reltime_text[] = { + "3ms", "10ms", "100ms", "300ms" +}; + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_reltime_enum, + MAX98396_R2024_THERM_FOLDBACK_SET, + MAX98396_THERM_FB_REL_SHIFT, + max98396_foldback_reltime_text); + +static const char * const max98396_foldback_holdtime_text[] = { + "0ms", "20ms", "40ms", "80ms" +}; + +static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_holdtime_enum, + MAX98396_R2024_THERM_FOLDBACK_SET, + MAX98396_THERM_FB_HOLD_SHIFT, + max98396_foldback_holdtime_text); + +static int max98396_adc_value_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); + int ret; + u8 val[2]; + int reg = mc->reg; + + /* ADC value is not available if the device is powered down */ + if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + goto exit; + + if (max98396->device_id == CODEC_TYPE_MAX98397) { + switch (mc->reg) { + case MAX98396_R20B6_ADC_PVDD_READBACK_MSB: + reg = MAX98397_R20B7_ADC_PVDD_READBACK_MSB; + break; + case MAX98396_R20B8_ADC_VBAT_READBACK_MSB: + reg = MAX98397_R20B9_ADC_VBAT_READBACK_MSB; + break; + case MAX98396_R20BA_ADC_TEMP_READBACK_MSB: + reg = MAX98397_R20BB_ADC_TEMP_READBACK_MSB; + break; + default: + goto exit; + } + } + + ret = regmap_raw_read(max98396->regmap, reg, &val, 2); + if (ret) + goto exit; + + /* ADC readback bits[8:0] rearrangement */ + ucontrol->value.integer.value[0] = (val[0] << 1) | (val[1] & 1); + return 0; + +exit: + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static const struct snd_kcontrol_new max98396_snd_controls[] = { + /* Volume */ + SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL, + 0, 0x7F, 1, max98396_digital_tlv), + SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN, + 0, 0x11, 0, max98396_spk_tlv), + /* Volume Ramp Up/Down Enable*/ + SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0), + SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0), + /* Clock Monitor Enable */ + SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS, + MAX98396_CTRL_CMON_EN_SHIFT, 1, 0), + /* Dither Enable */ + SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0), + SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0), + /* DC Blocker Enable */ + SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0), + SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0), + /* Speaker Safe Mode Enable */ + SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0), + /* Wideband Filter Enable */ + SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0), + SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0), + /* Dynamic Headroom Tracking */ + SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0), + /* Brownout Protection Engine */ + SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0), + SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0), + /* Bypass Path Enable */ + SOC_SINGLE("Bypass Path Switch", + MAX98396_R205E_PCM_RX_EN, 1, 1, 0), + /* Speaker Operation Mode */ + SOC_ENUM("OP Mode", max98396_op_mod_enum), + /* Auto Restart functions */ + SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL, + MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0), + SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0), + SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0), + SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0), + SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_OVC_RESTART_SHFT, 1, 0), + /* Thermal Threshold */ + SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum), + SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum), + SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum), + SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum), + SOC_SINGLE("THERM Foldback Switch", + MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0), + SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum), + SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum), + SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum), + SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum), + /* ADC */ + SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0, + max98396_adc_value_get, NULL), + SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0, + max98396_adc_value_get, NULL), + SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0, + max98396_adc_value_get, NULL), +}; + +static const struct snd_kcontrol_new max98397_snd_controls[] = { + /* Volume */ + SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL, + 0, 0xFF, 1, max98397_digital_tlv), + SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN, + 0, 0x15, 0, max98397_spk_tlv), + /* Volume Ramp Up/Down Enable*/ + SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0), + SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0), + /* Clock Monitor Enable */ + SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS, + MAX98396_CTRL_CMON_EN_SHIFT, 1, 0), + /* Dither Enable */ + SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0), + SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0), + /* DC Blocker Enable */ + SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0), + SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0), + /* Speaker Safe Mode Enable */ + SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0), + /* Wideband Filter Enable */ + SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG, + MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0), + SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0), + /* Dynamic Headroom Tracking */ + SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0), + /* Brownout Protection Engine */ + SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0), + SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0), + /* Bypass Path Enable */ + SOC_SINGLE("Bypass Path Switch", + MAX98396_R205E_PCM_RX_EN, 1, 1, 0), + /* Speaker Operation Mode */ + SOC_ENUM("OP Mode", max98396_op_mod_enum), + /* Auto Restart functions */ + SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL, + MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0), + SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0), + SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0), + SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0), + SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART, + MAX98396_OVC_RESTART_SHFT, 1, 0), + /* Thermal Threshold */ + SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum), + SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum), + SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum), + SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum), + SOC_SINGLE("THERM Foldback Switch", + MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0), + SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum), + SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum), + SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum), + SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum), + /* ADC */ + SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0, + max98396_adc_value_get, NULL), + SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0, + max98396_adc_value_get, NULL), + SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0, + max98396_adc_value_get, NULL), +}; + +static const struct snd_soc_dapm_route max98396_audio_map[] = { + /* Plabyack */ + {"DAI Sel Mux", "Left", "Amp Enable"}, + {"DAI Sel Mux", "Right", "Amp Enable"}, + {"DAI Sel Mux", "LeftRight", "Amp Enable"}, + {"BE_OUT", NULL, "DAI Sel Mux"}, + /* Capture */ + { "VI Sense", "Switch", "VMON" }, + { "VI Sense", "Switch", "IMON" }, + { "Voltage Sense", NULL, "VI Sense" }, + { "Current Sense", NULL, "VI Sense" }, +}; + +static struct snd_soc_dai_driver max98396_dai[] = { + { + .name = "max98396-aif1", + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98396_RATES, + .formats = MAX98396_FORMATS, + }, + .capture = { + .stream_name = "HiFi Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98396_RATES, + .formats = MAX98396_FORMATS, + }, + .ops = &max98396_dai_ops, + } +}; + +static struct snd_soc_dai_driver max98397_dai[] = { + { + .name = "max98397-aif1", + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98396_RATES, + .formats = MAX98396_FORMATS, + }, + .capture = { + .stream_name = "HiFi Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98396_RATES, + .formats = MAX98396_FORMATS, + }, + .ops = &max98396_dai_ops, + } +}; + +static void max98396_reset(struct max98396_priv *max98396, struct device *dev) +{ + int ret, reg, count; + + /* Software Reset */ + ret = regmap_write(max98396->regmap, + MAX98396_R2000_SW_RESET, 1); + if (ret) + dev_err(dev, "Reset command failed. (ret:%d)\n", ret); + + count = 0; + while (count < 3) { + usleep_range(5000, 6000); + /* Software Reset Verification */ + ret = regmap_read(max98396->regmap, + GET_REG_ADDR_REV_ID(max98396->device_id), ®); + if (!ret) { + dev_info(dev, "Reset completed (retry:%d)\n", count); + return; + } + count++; + } + dev_err(dev, "Reset failed. (ret:%d)\n", ret); +} + +static int max98396_probe(struct snd_soc_component *component) +{ + struct max98396_priv *max98396 = + snd_soc_component_get_drvdata(component); + + /* Software Reset */ + max98396_reset(max98396, component->dev); + + /* L/R mix configuration */ + if (max98396->device_id == CODEC_TYPE_MAX98396) { + regmap_write(max98396->regmap, + MAX98396_R2055_PCM_RX_SRC1, 0x02); + regmap_write(max98396->regmap, + MAX98396_R2056_PCM_RX_SRC2, 0x10); + } else { + regmap_write(max98396->regmap, + MAX98397_R2056_PCM_RX_SRC1, 0x02); + regmap_write(max98396->regmap, + MAX98397_R2057_PCM_RX_SRC2, 0x10); + } + /* Enable DC blocker */ + regmap_update_bits(max98396->regmap, + MAX98396_R2092_AMP_DSP_CFG, 1, 1); + /* Enable IV Monitor DC blocker */ + regmap_update_bits(max98396->regmap, + MAX98396_R20E0_IV_SENSE_PATH_CFG, + MAX98396_IV_SENSE_DCBLK_EN_MASK, + MAX98396_IV_SENSE_DCBLK_EN_MASK); + /* Configure default data output sources */ + regmap_write(max98396->regmap, + MAX98396_R205D_PCM_TX_SRC_EN, 3); + /* Enable Wideband Filter */ + regmap_update_bits(max98396->regmap, + MAX98396_R2092_AMP_DSP_CFG, 0x40, 0x40); + /* Enable IV Wideband Filter */ + regmap_update_bits(max98396->regmap, + MAX98396_R20E0_IV_SENSE_PATH_CFG, 8, 8); + + /* Enable Bypass Source */ + regmap_write(max98396->regmap, + MAX98396_R2058_PCM_BYPASS_SRC, + max98396->bypass_slot); + /* Voltage, current slot configuration */ + regmap_write(max98396->regmap, + MAX98396_R2044_PCM_TX_CTRL_1, + max98396->v_slot); + regmap_write(max98396->regmap, + MAX98396_R2045_PCM_TX_CTRL_2, + max98396->i_slot); + + if (max98396->v_slot < 8) + if (max98396->device_id == CODEC_TYPE_MAX98396) + regmap_update_bits(max98396->regmap, + MAX98396_R2053_PCM_TX_HIZ_CTRL_8, + 1 << max98396->v_slot, 0); + else + regmap_update_bits(max98396->regmap, + MAX98397_R2054_PCM_TX_HIZ_CTRL_8, + 1 << max98396->v_slot, 0); + else + if (max98396->device_id == CODEC_TYPE_MAX98396) + regmap_update_bits(max98396->regmap, + MAX98396_R2052_PCM_TX_HIZ_CTRL_7, + 1 << (max98396->v_slot - 8), 0); + else + regmap_update_bits(max98396->regmap, + MAX98397_R2053_PCM_TX_HIZ_CTRL_7, + 1 << (max98396->v_slot - 8), 0); + + if (max98396->i_slot < 8) + if (max98396->device_id == CODEC_TYPE_MAX98396) + regmap_update_bits(max98396->regmap, + MAX98396_R2053_PCM_TX_HIZ_CTRL_8, + 1 << max98396->i_slot, 0); + else + regmap_update_bits(max98396->regmap, + MAX98397_R2054_PCM_TX_HIZ_CTRL_8, + 1 << max98396->i_slot, 0); + else + if (max98396->device_id == CODEC_TYPE_MAX98396) + regmap_update_bits(max98396->regmap, + MAX98396_R2052_PCM_TX_HIZ_CTRL_7, + 1 << (max98396->i_slot - 8), 0); + else + regmap_update_bits(max98396->regmap, + MAX98397_R2053_PCM_TX_HIZ_CTRL_7, + 1 << (max98396->i_slot - 8), 0); + + /* Set interleave mode */ + if (max98396->interleave_mode) + regmap_update_bits(max98396->regmap, + MAX98396_R2041_PCM_MODE_CFG, + MAX98396_PCM_TX_CH_INTERLEAVE_MASK, + MAX98396_PCM_TX_CH_INTERLEAVE_MASK); + + regmap_update_bits(max98396->regmap, + MAX98396_R2038_CLK_MON_CTRL, + MAX98396_CLK_MON_AUTO_RESTART_MASK, + MAX98396_CLK_MON_AUTO_RESTART_MASK); + + /* Speaker Amplifier PCM RX Enable by default */ + regmap_update_bits(max98396->regmap, + MAX98396_R205E_PCM_RX_EN, + MAX98396_PCM_RX_EN_MASK, 1); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int max98396_suspend(struct device *dev) +{ + struct max98396_priv *max98396 = dev_get_drvdata(dev); + + regcache_cache_only(max98396->regmap, true); + regcache_mark_dirty(max98396->regmap); + return 0; +} + +static int max98396_resume(struct device *dev) +{ + struct max98396_priv *max98396 = dev_get_drvdata(dev); + + regcache_cache_only(max98396->regmap, false); + max98396_reset(max98396, dev); + regcache_sync(max98396->regmap); + return 0; +} +#endif + +static const struct dev_pm_ops max98396_pm = { + SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume) +}; + +static const struct snd_soc_component_driver soc_codec_dev_max98396 = { + .probe = max98396_probe, + .controls = max98396_snd_controls, + .num_controls = ARRAY_SIZE(max98396_snd_controls), + .dapm_widgets = max98396_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets), + .dapm_routes = max98396_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98396_audio_map), + .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 = { + .probe = max98396_probe, + .controls = max98397_snd_controls, + .num_controls = ARRAY_SIZE(max98397_snd_controls), + .dapm_widgets = max98396_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets), + .dapm_routes = max98396_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98396_audio_map), + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, + .non_legacy_dai_naming = 1, +}; + +static const struct regmap_config max98396_regmap = { + .reg_bits = 16, + .val_bits = 8, + .max_register = MAX98396_R21FF_REVISION_ID, + .reg_defaults = max98396_reg, + .num_reg_defaults = ARRAY_SIZE(max98396_reg), + .readable_reg = max98396_readable_register, + .volatile_reg = max98396_volatile_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static const struct regmap_config max98397_regmap = { + .reg_bits = 16, + .val_bits = 8, + .max_register = MAX98397_R22FF_REVISION_ID, + .reg_defaults = max98397_reg, + .num_reg_defaults = ARRAY_SIZE(max98397_reg), + .readable_reg = max98397_readable_register, + .volatile_reg = max98397_volatile_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static void max98396_read_device_property(struct device *dev, + struct max98396_priv *max98396) +{ + int value; + + if (!device_property_read_u32(dev, "adi,vmon-slot-no", &value)) + max98396->v_slot = value & 0xF; + else + max98396->v_slot = 0; + + if (!device_property_read_u32(dev, "adi,imon-slot-no", &value)) + max98396->i_slot = value & 0xF; + else + max98396->i_slot = 1; + + if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value)) + max98396->bypass_slot = value & 0xF; + else + max98396->bypass_slot = 0; +} + +static int max98396_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct max98396_priv *max98396 = NULL; + int ret, reg; + + max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL); + + if (!max98396) { + ret = -ENOMEM; + return ret; + } + i2c_set_clientdata(i2c, max98396); + + max98396->device_id = id->driver_data; + + /* regmap initialization */ + if (max98396->device_id == CODEC_TYPE_MAX98396) + max98396->regmap = devm_regmap_init_i2c(i2c, &max98396_regmap); + + else + max98396->regmap = devm_regmap_init_i2c(i2c, &max98397_regmap); + + if (IS_ERR(max98396->regmap)) { + ret = PTR_ERR(max98396->regmap); + dev_err(&i2c->dev, + "Failed to allocate regmap: %d\n", ret); + return ret; + } + + /* update interleave mode info */ + if (device_property_read_bool(&i2c->dev, "adi,interleave_mode")) + max98396->interleave_mode = true; + else + max98396->interleave_mode = false; + + /* voltage/current slot & gpio configuration */ + max98396_read_device_property(&i2c->dev, max98396); + + /* Reset the Device */ + max98396->reset_gpio = devm_gpiod_get_optional(&i2c->dev, + "reset", GPIOD_OUT_HIGH); + if (IS_ERR(max98396->reset_gpio)) { + ret = PTR_ERR(max98396->reset_gpio); + dev_err(&i2c->dev, "Unable to request GPIO pin: %d.\n", ret); + return ret; + } + + if (max98396->reset_gpio) { + usleep_range(5000, 6000); + gpiod_set_value_cansleep(max98396->reset_gpio, 0); + /* Wait for the hw reset done */ + usleep_range(5000, 6000); + } + + ret = regmap_read(max98396->regmap, + GET_REG_ADDR_REV_ID(max98396->device_id), ®); + if (ret < 0) { + dev_err(&i2c->dev, "%s: failed to read revision of the device.\n", id->name); + return ret; + } + dev_info(&i2c->dev, "%s revision ID: 0x%02X\n", id->name, reg); + + /* codec registration */ + if (max98396->device_id == CODEC_TYPE_MAX98396) + ret = devm_snd_soc_register_component(&i2c->dev, + &soc_codec_dev_max98396, + max98396_dai, + ARRAY_SIZE(max98396_dai)); + else + ret = devm_snd_soc_register_component(&i2c->dev, + &soc_codec_dev_max98397, + max98397_dai, + ARRAY_SIZE(max98397_dai)); + if (ret < 0) + dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); + + return ret; +} + +static const struct i2c_device_id max98396_i2c_id[] = { + { "max98396", CODEC_TYPE_MAX98396}, + { "max98397", CODEC_TYPE_MAX98397}, + { }, +}; + +MODULE_DEVICE_TABLE(i2c, max98396_i2c_id); + +#if defined(CONFIG_OF) +static const struct of_device_id max98396_of_match[] = { + { .compatible = "adi,max98396", }, + { .compatible = "adi,max98397", }, + { } +}; +MODULE_DEVICE_TABLE(of, max98396_of_match); +#endif + +#ifdef CONFIG_ACPI +static const struct acpi_device_id max98396_acpi_match[] = { + { "ADS8396", 0 }, + { "ADS8397", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, max98396_acpi_match); +#endif + +static struct i2c_driver max98396_i2c_driver = { + .driver = { + .name = "max98396", + .of_match_table = of_match_ptr(max98396_of_match), + .acpi_match_table = ACPI_PTR(max98396_acpi_match), + .pm = &max98396_pm, + }, + .probe = max98396_i2c_probe, + .id_table = max98396_i2c_id, +}; + +module_i2c_driver(max98396_i2c_driver) + +MODULE_DESCRIPTION("ALSA SoC MAX98396 driver"); +MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/max98396.h b/sound/soc/codecs/max98396.h new file mode 100644 index 000000000000..694411038597 --- /dev/null +++ b/sound/soc/codecs/max98396.h @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * max98396.h -- MAX98396 ALSA SoC audio driver header + * + * Copyright(c) 2022, Analog Devices Inc. + */ + +#ifndef _MAX98396_H +#define _MAX98396_H + +#define MAX98396_R2000_SW_RESET 0x2000 +#define MAX98396_R2001_INT_RAW1 0x2001 +#define MAX98396_R2002_INT_RAW2 0x2002 +#define MAX98396_R2003_INT_RAW3 0x2003 +#define MAX98396_R2004_INT_RAW4 0x2004 +#define MAX98396_R2006_INT_STATE1 0x2006 +#define MAX98396_R2007_INT_STATE2 0x2007 +#define MAX98396_R2008_INT_STATE3 0x2008 +#define MAX98396_R2009_INT_STATE4 0x2009 +#define MAX98396_R200B_INT_FLAG1 0x200B +#define MAX98396_R200C_INT_FLAG2 0x200C +#define MAX98396_R200D_INT_FLAG3 0x200D +#define MAX98396_R200E_INT_FLAG4 0x200E +#define MAX98396_R2010_INT_EN1 0x2010 +#define MAX98396_R2011_INT_EN2 0x2011 +#define MAX98396_R2012_INT_EN3 0x2012 +#define MAX98396_R2013_INT_EN4 0x2013 +#define MAX98396_R2015_INT_FLAG_CLR1 0x2015 +#define MAX98396_R2016_INT_FLAG_CLR2 0x2016 +#define MAX98396_R2017_INT_FLAG_CLR3 0x2017 +#define MAX98396_R2018_INT_FLAG_CLR4 0x2018 +#define MAX98396_R201F_IRQ_CTRL 0x201F +#define MAX98396_R2020_THERM_WARN_THRESH 0x2020 +#define MAX98396_R2021_THERM_WARN_THRESH2 0x2021 +#define MAX98396_R2022_THERM_SHDN_THRESH 0x2022 +#define MAX98396_R2023_THERM_HYSTERESIS 0x2023 +#define MAX98396_R2024_THERM_FOLDBACK_SET 0x2024 +#define MAX98396_R2027_THERM_FOLDBACK_EN 0x2027 +#define MAX98396_R2030_NOISEGATE_MODE_CTRL 0x2030 +#define MAX98396_R2033_NOISEGATE_MODE_EN 0x2033 +#define MAX98396_R2038_CLK_MON_CTRL 0x2038 +#define MAX98396_R2039_DATA_MON_CTRL 0x2039 +#define MAX98396_R203F_ENABLE_CTRLS 0x203F +#define MAX98396_R2040_PIN_CFG 0x2040 +#define MAX98396_R2041_PCM_MODE_CFG 0x2041 +#define MAX98396_R2042_PCM_CLK_SETUP 0x2042 +#define MAX98396_R2043_PCM_SR_SETUP 0x2043 +#define MAX98396_R2044_PCM_TX_CTRL_1 0x2044 +#define MAX98396_R2045_PCM_TX_CTRL_2 0x2045 +#define MAX98396_R2046_PCM_TX_CTRL_3 0x2046 +#define MAX98396_R2047_PCM_TX_CTRL_4 0x2047 +#define MAX98396_R2048_PCM_TX_CTRL_5 0x2048 +#define MAX98396_R2049_PCM_TX_CTRL_6 0x2049 +#define MAX98396_R204A_PCM_TX_CTRL_7 0x204A +#define MAX98396_R204B_PCM_TX_CTRL_8 0x204B +#define MAX98396_R204C_PCM_TX_HIZ_CTRL_1 0x204C +#define MAX98396_R204D_PCM_TX_HIZ_CTRL_2 0x204D +#define MAX98396_R204E_PCM_TX_HIZ_CTRL_3 0x204E +#define MAX98396_R204F_PCM_TX_HIZ_CTRL_4 0x204F +#define MAX98396_R2050_PCM_TX_HIZ_CTRL_5 0x2050 +#define MAX98396_R2051_PCM_TX_HIZ_CTRL_6 0x2051 +#define MAX98396_R2052_PCM_TX_HIZ_CTRL_7 0x2052 +#define MAX98396_R2053_PCM_TX_HIZ_CTRL_8 0x2053 +#define MAX98396_R2055_PCM_RX_SRC1 0x2055 +#define MAX98396_R2056_PCM_RX_SRC2 0x2056 +#define MAX98396_R2058_PCM_BYPASS_SRC 0x2058 +#define MAX98396_R205D_PCM_TX_SRC_EN 0x205D +#define MAX98396_R205E_PCM_RX_EN 0x205E +#define MAX98396_R205F_PCM_TX_EN 0x205F +#define MAX98396_R2070_ICC_RX_EN_A 0x2070 +#define MAX98396_R2071_ICC_RX_EN_B 0x2071 +#define MAX98396_R2072_ICC_TX_CTRL 0x2072 +#define MAX98396_R207F_ICC_EN 0x207F +#define MAX98396_R2083_TONE_GEN_DC_CFG 0x2083 +#define MAX98396_R2084_TONE_GEN_DC_LVL1 0x2084 +#define MAX98396_R2085_TONE_GEN_DC_LVL2 0x2085 +#define MAX98396_R2086_TONE_GEN_DC_LVL3 0x2086 +#define MAX98396_R208F_TONE_GEN_EN 0x208F +#define MAX98396_R2090_AMP_VOL_CTRL 0x2090 +#define MAX98396_R2091_AMP_PATH_GAIN 0x2091 +#define MAX98396_R2092_AMP_DSP_CFG 0x2092 +#define MAX98396_R2093_SSM_CFG 0x2093 +#define MAX98396_R2094_SPK_CLS_DG_THRESH 0x2094 +#define MAX98396_R2095_SPK_CLS_DG_HDR 0x2095 +#define MAX98396_R2096_SPK_CLS_DG_HOLD_TIME 0x2096 +#define MAX98396_R2097_SPK_CLS_DG_DELAY 0x2097 +#define MAX98396_R2098_SPK_CLS_DG_MODE 0x2098 +#define MAX98396_R2099_SPK_CLS_DG_VBAT_LVL 0x2099 +#define MAX98396_R209A_SPK_EDGE_CTRL 0x209A +#define MAX98396_R209C_SPK_EDGE_CTRL1 0x209C +#define MAX98396_R209D_SPK_EDGE_CTRL2 0x209D +#define MAX98396_R209E_AMP_CLIP_GAIN 0x209E +#define MAX98396_R209F_BYPASS_PATH_CFG 0x209F +#define MAX98396_R20A0_AMP_SUPPLY_CTL 0x20A0 +#define MAX98396_R20AF_AMP_EN 0x20AF +#define MAX98396_R20B0_ADC_SR 0x20B0 +#define MAX98396_R20B1_ADC_PVDD_CFG 0x20B1 +#define MAX98396_R20B2_ADC_VBAT_CFG 0x20B2 +#define MAX98396_R20B3_ADC_THERMAL_CFG 0x20B3 +#define MAX98396_R20B4_ADC_READBACK_CTRL1 0x20B4 +#define MAX98396_R20B5_ADC_READBACK_CTRL2 0x20B5 +#define MAX98396_R20B6_ADC_PVDD_READBACK_MSB 0x20B6 +#define MAX98396_R20B7_ADC_PVDD_READBACK_LSB 0x20B7 +#define MAX98396_R20B8_ADC_VBAT_READBACK_MSB 0x20B8 +#define MAX98396_R20B9_ADC_VBAT_READBACK_LSB 0x20B9 +#define MAX98396_R20BA_ADC_TEMP_READBACK_MSB 0x20BA +#define MAX98396_R20BB_ADC_TEMP_READBACK_LSB 0x20BB +#define MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB 0x20BC +#define MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB 0x20BD +#define MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB 0x20BE +#define MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB 0x20BF +#define MAX98396_R20C7_ADC_CFG 0x20C7 +#define MAX98396_R20D0_DHT_CFG1 0x20D0 +#define MAX98396_R20D1_LIMITER_CFG1 0x20D1 +#define MAX98396_R20D2_LIMITER_CFG2 0x20D2 +#define MAX98396_R20D3_DHT_CFG2 0x20D3 +#define MAX98396_R20D4_DHT_CFG3 0x20D4 +#define MAX98396_R20D5_DHT_CFG4 0x20D5 +#define MAX98396_R20D6_DHT_HYSTERESIS_CFG 0x20D6 +#define MAX98396_R20DF_DHT_EN 0x20DF +#define MAX98396_R20E0_IV_SENSE_PATH_CFG 0x20E0 +#define MAX98396_R20E4_IV_SENSE_PATH_EN 0x20E4 +#define MAX98396_R20E5_BPE_STATE 0x20E5 +#define MAX98396_R20E6_BPE_L3_THRESH_MSB 0x20E6 +#define MAX98396_R20E7_BPE_L3_THRESH_LSB 0x20E7 +#define MAX98396_R20E8_BPE_L2_THRESH_MSB 0x20E8 +#define MAX98396_R20E9_BPE_L2_THRESH_LSB 0x20E9 +#define MAX98396_R20EA_BPE_L1_THRESH_MSB 0x20EA +#define MAX98396_R20EB_BPE_L1_THRESH_LSB 0x20EB +#define MAX98396_R20EC_BPE_L0_THRESH_MSB 0x20EC +#define MAX98396_R20ED_BPE_L0_THRESH_LSB 0x20ED +#define MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME 0x20EE +#define MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME 0x20EF +#define MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME 0x20F0 +#define MAX98396_R20F1_BPE_L0_HOLD_TIME 0x20F1 +#define MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP 0x20F2 +#define MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP 0x20F3 +#define MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP 0x20F4 +#define MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP 0x20F5 +#define MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN 0x20F6 +#define MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN 0x20F7 +#define MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN 0x20F8 +#define MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN 0x20F9 +#define MAX98396_R20FA_BPE_L3_ATT_REL_RATE 0x20FA +#define MAX98396_R20FB_BPE_L2_ATT_REL_RATE 0x20FB +#define MAX98396_R20FC_BPE_L1_ATT_REL_RATE 0x20FC +#define MAX98396_R20FD_BPE_L0_ATT_REL_RATE 0x20FD +#define MAX98396_R20FE_BPE_L3_LIMITER_CFG 0x20FE +#define MAX98396_R20FF_BPE_L2_LIMITER_CFG 0x20FF +#define MAX98396_R2100_BPE_L1_LIMITER_CFG 0x2100 +#define MAX98396_R2101_BPE_L0_LIMITER_CFG 0x2101 +#define MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE 0x2102 +#define MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE 0x2103 +#define MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE 0x2104 +#define MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE 0x2105 +#define MAX98396_R2106_BPE_THRESH_HYSTERESIS 0x2106 +#define MAX98396_R2107_BPE_INFINITE_HOLD_CLR 0x2107 +#define MAX98396_R2108_BPE_SUPPLY_SRC 0x2108 +#define MAX98396_R2109_BPE_LOW_STATE 0x2109 +#define MAX98396_R210A_BPE_LOW_GAIN 0x210A +#define MAX98396_R210B_BPE_LOW_LIMITER 0x210B +#define MAX98396_R210D_BPE_EN 0x210D +#define MAX98396_R210E_AUTO_RESTART 0x210E +#define MAX98396_R210F_GLOBAL_EN 0x210F +#define MAX98396_R21FF_REVISION_ID 0x21FF + +/* MAX98927 Registers */ +#define MAX98397_R203A_SPK_MON_THRESH 0x203A +#define MAX98397_R204C_PCM_TX_CTRL_9 0x204C +#define MAX98397_R204D_PCM_TX_HIZ_CTRL_1 0x204D +#define MAX98397_R204E_PCM_TX_HIZ_CTRL_2 0x204E +#define MAX98397_R204F_PCM_TX_HIZ_CTRL_3 0x204F +#define MAX98397_R2050_PCM_TX_HIZ_CTRL_4 0x2050 +#define MAX98397_R2051_PCM_TX_HIZ_CTRL_5 0x2051 +#define MAX98397_R2052_PCM_TX_HIZ_CTRL_6 0x2052 +#define MAX98397_R2053_PCM_TX_HIZ_CTRL_7 0x2053 +#define MAX98397_R2054_PCM_TX_HIZ_CTRL_8 0x2054 +#define MAX98397_R2056_PCM_RX_SRC1 0x2056 +#define MAX98397_R2057_PCM_RX_SRC2 0x2057 +#define MAX98397_R2060_PCM_TX_SUPPLY_SEL 0x2060 +#define MAX98397_R209B_SPK_PATH_WB_ONLY 0x209B +#define MAX98397_R20B4_ADC_VDDH_CFG 0x20B4 +#define MAX98397_R20B5_ADC_READBACK_CTRL1 0x20B5 +#define MAX98397_R20B6_ADC_READBACK_CTRL2 0x20B6 +#define MAX98397_R20B7_ADC_PVDD_READBACK_MSB 0x20B7 +#define MAX98397_R20B8_ADC_PVDD_READBACK_LSB 0x20B8 +#define MAX98397_R20B9_ADC_VBAT_READBACK_MSB 0x20B9 +#define MAX98397_R20BA_ADC_VBAT_READBACK_LSB 0x20BA +#define MAX98397_R20BB_ADC_TEMP_READBACK_MSB 0x20BB +#define MAX98397_R20BC_ADC_TEMP_READBACK_LSB 0x20BC +#define MAX98397_R20BD_ADC_VDDH__READBACK_MSB 0x20BD +#define MAX98397_R20BE_ADC_VDDH_READBACK_LSB 0x20BE +#define MAX98397_R20BF_ADC_LO_PVDD_READBACK_MSB 0x20BF +#define MAX98397_R20C0_ADC_LO_PVDD_READBACK_LSB 0x20C0 +#define MAX98397_R20C1_ADC_LO_VBAT_READBACK_MSB 0x20C1 +#define MAX98397_R20C2_ADC_LO_VBAT_READBACK_LSB 0x20C2 +#define MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB 0x20C3 +#define MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB 0x20C4 +#define MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE 0x20C5 +#define MAX98397_R22FF_REVISION_ID 0x22FF + +#define GET_REG_ADDR_REV_ID(x)\ + ((x) > 0 ? MAX98397_R22FF_REVISION_ID : MAX98396_R21FF_REVISION_ID) + +/* MAX98396_R2024_THERM_FOLDBACK_SET */ +#define MAX98396_THERM_FB_SLOPE1_SHIFT (0) +#define MAX98396_THERM_FB_SLOPE2_SHIFT (2) +#define MAX98396_THERM_FB_REL_SHIFT (4) +#define MAX98396_THERM_FB_HOLD_SHIFT (6) + +/* MAX98396_R2038_CLK_MON_CTRL */ +#define MAX98396_CLK_MON_AUTO_RESTART_MASK (0x1 << 0) +#define MAX98396_CLK_MON_AUTO_RESTART_SHIFT (0) + +/* MAX98396_R203F_ENABLE_CTRLS */ +#define MAX98396_CTRL_CMON_EN_SHIFT (0) + +/* MAX98396_R2041_PCM_MODE_CFG */ +#define MAX98396_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3) +#define MAX98396_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 2) +#define MAX98396_PCM_FORMAT_I2S (0x0 << 3) +#define MAX98396_PCM_FORMAT_LJ (0x1 << 3) +#define MAX98396_PCM_FORMAT_TDM_MODE0 (0x3 << 3) +#define MAX98396_PCM_FORMAT_TDM_MODE1 (0x4 << 3) +#define MAX98396_PCM_FORMAT_TDM_MODE2 (0x5 << 3) +#define MAX98396_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6) +#define MAX98396_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6) +#define MAX98396_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6) +#define MAX98396_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6) +#define MAX98396_PCM_MODE_CFG_LRCLKEDGE (0x1 << 1) + +/* MAX98396_R2042_PCM_CLK_SETUP */ +#define MAX98396_PCM_MODE_CFG_BCLKEDGE (0x1 << 4) +#define MAX98396_PCM_CLK_SETUP_BSEL_MASK (0xF << 0) +#define MAX98396_PCM_BCLKEDGE_BSEL_MASK (0x1F) + +/* MAX98396_R2043_PCM_SR_SETUP */ +#define MAX98396_PCM_SR_SHIFT (0) +#define MAX98396_IVADC_SR_SHIFT (4) +#define MAX98396_PCM_SR_MASK (0xF << MAX98396_PCM_SR_SHIFT) +#define MAX98396_IVADC_SR_MASK (0xF << MAX98396_IVADC_SR_SHIFT) +#define MAX98396_PCM_SR_8000 (0) +#define MAX98396_PCM_SR_11025 (1) +#define MAX98396_PCM_SR_12000 (2) +#define MAX98396_PCM_SR_16000 (3) +#define MAX98396_PCM_SR_22050 (4) +#define MAX98396_PCM_SR_24000 (5) +#define MAX98396_PCM_SR_32000 (6) +#define MAX98396_PCM_SR_44100 (7) +#define MAX98396_PCM_SR_48000 (8) +#define MAX98396_PCM_SR_88200 (9) +#define MAX98396_PCM_SR_96000 (10) +#define MAX98396_PCM_SR_176400 (11) +#define MAX98396_PCM_SR_192000 (12) + +/* MAX98396_R2055_PCM_RX_SRC1 */ +#define MAX98396_PCM_RX_MASK (0x3 << 0) + +/* MAX98396_R2056_PCM_RX_SRC2 */ +#define MAX98396_PCM_DMIX_CH1_SHIFT (0xF << 0) +#define MAX98396_PCM_DMIX_CH0_SRC_MASK (0xF << 0) +#define MAX98396_PCM_DMIX_CH1_SRC_MASK (0xF << MAX98396_PCM_DMIX_CH1_SHIFT) + +/* MAX98396_R205E_PCM_RX_EN */ +#define MAX98396_PCM_RX_EN_MASK (0x1 << 0) +#define MAX98396_PCM_RX_BYP_EN_MASK (0x1 << 1) + +/* MAX98396_R2092_AMP_DSP_CFG */ +#define MAX98396_DSP_SPK_DCBLK_EN_SHIFT (0) +#define MAX98396_DSP_SPK_DITH_EN_SHIFT (1) +#define MAX98396_DSP_SPK_INVERT_SHIFT (2) +#define MAX98396_DSP_SPK_VOL_RMPUP_SHIFT (3) +#define MAX98396_DSP_SPK_VOL_RMPDN_SHIFT (4) +#define MAX98396_DSP_SPK_SAFE_EN_SHIFT (5) +#define MAX98396_DSP_SPK_WB_FLT_EN_SHIFT (6) + +/* MAX98396_R20E0_IV_SENSE_PATH_CFG */ +#define MAX98396_IV_SENSE_DCBLK_EN_MASK (0x3 << 0) +#define MAX98396_IV_SENSE_DCBLK_EN_SHIFT (0) +#define MAX98396_IV_SENSE_DITH_EN_SHIFT (2) +#define MAX98396_IV_SENSE_WB_FLT_EN_SHIFT (3) + +/* MAX98396_R210E_AUTO_RESTART_BEHAVIOR */ +#define MAX98396_PVDD_UVLO_RESTART_SHFT (0) +#define MAX98396_VBAT_UVLO_RESTART_SHFT (1) +#define MAX98396_THEM_SHDN_RESTART_SHFT (2) +#define MAX98396_OVC_RESTART_SHFT (3) + +enum { + CODEC_TYPE_MAX98396, + CODEC_TYPE_MAX98397, +}; + +struct max98396_priv { + struct regmap *regmap; + struct gpio_desc *reset_gpio; + unsigned int v_slot; + unsigned int i_slot; + unsigned int bypass_slot; + bool interleave_mode; + unsigned int ch_size; + bool tdm_mode; + int device_id; +}; +#endif diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index e073f0e029be..9ca6fc254883 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -299,8 +299,7 @@ static const struct snd_soc_component_driver soc_component_dev_max9850 = { .non_legacy_dai_naming = 1, }; -static int max9850_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max9850_i2c_probe(struct i2c_client *i2c) { struct max9850_priv *max9850; int ret; @@ -331,7 +330,7 @@ static struct i2c_driver max9850_i2c_driver = { .driver = { .name = "max9850", }, - .probe = max9850_i2c_probe, + .probe_new = max9850_i2c_probe, .id_table = max9850_i2c_id, }; diff --git a/sound/soc/codecs/max98504.c b/sound/soc/codecs/max98504.c index a5aa124c4a2e..0daa2a3dd621 100644 --- a/sound/soc/codecs/max98504.c +++ b/sound/soc/codecs/max98504.c @@ -291,6 +291,7 @@ static const struct snd_soc_component_driver max98504_component_driver = { .num_dapm_widgets = ARRAY_SIZE(max98504_dapm_widgets), .dapm_routes = max98504_dapm_routes, .num_dapm_routes = ARRAY_SIZE(max98504_dapm_routes), + .endianness = 1, }; static const struct regmap_config max98504_regmap = { @@ -304,8 +305,7 @@ static const struct regmap_config max98504_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max98504_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max98504_i2c_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct device_node *node = dev->of_node; @@ -371,7 +371,7 @@ static struct i2c_driver max98504_i2c_driver = { .name = "max98504", .of_match_table = of_match_ptr(max98504_of_match), }, - .probe = max98504_i2c_probe, + .probe_new = max98504_i2c_probe, .id_table = max98504_i2c_id, }; module_i2c_driver(max98504_i2c_driver); diff --git a/sound/soc/codecs/max98520.c b/sound/soc/codecs/max98520.c index bb8649cd421c..f0f085ecab55 100644 --- a/sound/soc/codecs/max98520.c +++ b/sound/soc/codecs/max98520.c @@ -677,7 +677,7 @@ static void max98520_power_on(struct max98520_priv *max98520, bool poweron) gpiod_set_value_cansleep(max98520->reset_gpio, !poweron); } -static int max98520_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +static int max98520_i2c_probe(struct i2c_client *i2c) { int ret; int reg = 0; @@ -757,7 +757,7 @@ static struct i2c_driver max98520_i2c_driver = { .of_match_table = of_match_ptr(max98520_of_match), .pm = &max98520_pm, }, - .probe = max98520_i2c_probe, + .probe_new = max98520_i2c_probe, .id_table = max98520_i2c_id, }; diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index c2b1151c75cc..eb628b7e84f5 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -613,8 +613,7 @@ static const struct regmap_config max9867_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max9867_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max9867_i2c_probe(struct i2c_client *i2c) { struct max9867_priv *max9867; int ret, reg; @@ -662,7 +661,7 @@ static struct i2c_driver max9867_i2c_driver = { .name = "max9867", .of_match_table = of_match_ptr(max9867_of_match), }, - .probe = max9867_i2c_probe, + .probe_new = max9867_i2c_probe, .id_table = max9867_i2c_id, }; diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 71fede9224c4..3bf86328d5cd 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c @@ -133,8 +133,7 @@ static const struct regmap_config max9877_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max9877_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max9877_i2c_probe(struct i2c_client *client) { struct regmap *regmap; int i; @@ -161,7 +160,7 @@ static struct i2c_driver max9877_i2c_driver = { .driver = { .name = "max9877", }, - .probe = max9877_i2c_probe, + .probe_new = max9877_i2c_probe, .id_table = max9877_i2c_id, }; diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c index f34fa274ae4f..63849ebcfd35 100644 --- a/sound/soc/codecs/max98925.c +++ b/sound/soc/codecs/max98925.c @@ -558,8 +558,7 @@ static const struct regmap_config max98925_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max98925_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max98925_i2c_probe(struct i2c_client *i2c) { int ret, reg; u32 value; @@ -637,7 +636,7 @@ static struct i2c_driver max98925_i2c_driver = { .name = "max98925", .of_match_table = of_match_ptr(max98925_of_match), }, - .probe = max98925_i2c_probe, + .probe_new = max98925_i2c_probe, .id_table = max98925_i2c_id, }; diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 1fbbc62bb0a2..56e0a87c7112 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c @@ -510,8 +510,7 @@ static const struct regmap_config max98926_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int max98926_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max98926_i2c_probe(struct i2c_client *i2c) { int ret, reg; u32 value; @@ -584,7 +583,7 @@ static struct i2c_driver max98926_i2c_driver = { .name = "max98926", .of_match_table = of_match_ptr(max98926_of_match), }, - .probe = max98926_i2c_probe, + .probe_new = max98926_i2c_probe, .id_table = max98926_i2c_id, }; diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index bf78d3c98514..b7cff76d7b5b 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -863,8 +863,7 @@ static void max98927_slot_config(struct i2c_client *i2c, max98927->i_l_slot = 1; } -static int max98927_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int max98927_i2c_probe(struct i2c_client *i2c) { int ret = 0, value; @@ -977,7 +976,7 @@ static struct i2c_driver max98927_i2c_driver = { .acpi_match_table = ACPI_PTR(max98927_acpi_match), .pm = &max98927_pm, }, - .probe = max98927_i2c_probe, + .probe_new = max98927_i2c_probe, .remove = max98927_i2c_remove, .id_table = max98927_i2c_id, }; diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 0823527e4a75..de8fcbdd85be 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -550,8 +550,7 @@ static const struct regmap_config ml26124_i2c_regmap = { .write_flag_mask = 0x01, }; -static int ml26124_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ml26124_i2c_probe(struct i2c_client *i2c) { struct ml26124_priv *priv; int ret; @@ -583,7 +582,7 @@ static struct i2c_driver ml26124_i2c_driver = { .driver = { .name = "ml26124", }, - .probe = ml26124_i2c_probe, + .probe_new = ml26124_i2c_probe, .id_table = ml26124_i2c_id, }; diff --git a/sound/soc/codecs/mt6351.c b/sound/soc/codecs/mt6351.c index 5c0536eb1044..d2cf4847eead 100644 --- a/sound/soc/codecs/mt6351.c +++ b/sound/soc/codecs/mt6351.c @@ -282,12 +282,9 @@ static const struct snd_soc_dai_ops mt6351_codec_dai_ops = { .hw_params = mt6351_codec_dai_hw_params, }; -#define MT6351_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |\ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ - SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE |\ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE) +#define MT6351_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) static struct snd_soc_dai_driver mt6351_dai_driver[] = { { @@ -1448,6 +1445,7 @@ static const struct snd_soc_component_driver mt6351_soc_component_driver = { .num_dapm_widgets = ARRAY_SIZE(mt6351_dapm_widgets), .dapm_routes = mt6351_dapm_routes, .num_dapm_routes = ARRAY_SIZE(mt6351_dapm_routes), + .endianness = 1, }; static int mt6351_codec_driver_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index 4c7b5d940799..60b209efe52d 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -2340,12 +2340,9 @@ static const struct snd_soc_dai_ops mt6358_codec_dai_ops = { .hw_params = mt6358_codec_dai_hw_params, }; -#define MT6358_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |\ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ - SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE |\ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE) +#define MT6358_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) static struct snd_soc_dai_driver mt6358_dai_driver[] = { { @@ -2433,6 +2430,7 @@ static const struct snd_soc_component_driver mt6358_soc_component_driver = { .num_dapm_widgets = ARRAY_SIZE(mt6358_dapm_widgets), .dapm_routes = mt6358_dapm_routes, .num_dapm_routes = ARRAY_SIZE(mt6358_dapm_routes), + .endianness = 1, }; static void mt6358_parse_dt(struct mt6358_priv *priv) diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index f8532aa7e4aa..23709b180409 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -2576,12 +2576,9 @@ static const struct snd_soc_dai_ops mt6359_codec_dai_ops = { .shutdown = mt6359_codec_dai_shutdown, }; -#define MT6359_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |\ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ - SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE |\ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE) +#define MT6359_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) static struct snd_soc_dai_driver mt6359_dai_driver[] = { { @@ -2739,6 +2736,7 @@ static const struct snd_soc_component_driver mt6359_soc_component_driver = { .num_dapm_widgets = ARRAY_SIZE(mt6359_dapm_widgets), .dapm_routes = mt6359_dapm_routes, .num_dapm_routes = ARRAY_SIZE(mt6359_dapm_routes), + .endianness = 1, }; static int mt6359_parse_dt(struct mt6359_priv *priv) diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c index 3a881523c30f..ba11555796ad 100644 --- a/sound/soc/codecs/mt6660.c +++ b/sound/soc/codecs/mt6660.c @@ -323,6 +323,7 @@ static const struct snd_soc_component_driver mt6660_component_driver = { .num_dapm_routes = ARRAY_SIZE(mt6660_component_dapm_routes), .idle_bias_on = false, /* idle_bias_off = true */ + .endianness = 1, }; static int mt6660_component_aif_hw_params(struct snd_pcm_substream *substream, @@ -456,8 +457,7 @@ static int _mt6660_read_chip_revision(struct mt6660_chip *chip) return 0; } -static int mt6660_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mt6660_i2c_probe(struct i2c_client *client) { struct mt6660_chip *chip = NULL; int ret; @@ -567,7 +567,7 @@ static struct i2c_driver mt6660_i2c_driver = { .of_match_table = of_match_ptr(mt6660_of_id), .pm = &mt6660_dev_pm_ops, }, - .probe = mt6660_i2c_probe, + .probe_new = mt6660_i2c_probe, .remove = mt6660_i2c_remove, .id_table = mt6660_i2c_id, }; diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index ace96995fedc..347c715e22a4 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -823,8 +823,7 @@ static const struct regmap_config nau8540_regmap_config = { .num_reg_defaults = ARRAY_SIZE(nau8540_reg_defaults), }; -static int nau8540_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8540_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8540 *nau8540 = dev_get_platdata(dev); @@ -874,7 +873,7 @@ static struct i2c_driver nau8540_i2c_driver = { .name = "nau8540", .of_match_table = of_match_ptr(nau8540_of_ids), }, - .probe = nau8540_i2c_probe, + .probe_new = nau8540_i2c_probe, .id_table = nau8540_i2c_ids, }; module_i2c_driver(nau8540_i2c_driver); diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index 13676b544f58..7b3b1e4ac246 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -869,8 +869,7 @@ static const struct snd_soc_component_driver nau8810_component_driver = { .non_legacy_dai_naming = 1, }; -static int nau8810_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8810_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8810 *nau8810 = dev_get_platdata(dev); @@ -916,7 +915,7 @@ static struct i2c_driver nau8810_i2c_driver = { .name = "nau8810", .of_match_table = of_match_ptr(nau8810_of_match), }, - .probe = nau8810_i2c_probe, + .probe_new = nau8810_i2c_probe, .id_table = nau8810_i2c_id, }; diff --git a/sound/soc/codecs/nau8821.c b/sound/soc/codecs/nau8821.c index d67dc27890a9..ce4e7f46bb06 100644 --- a/sound/soc/codecs/nau8821.c +++ b/sound/soc/codecs/nau8821.c @@ -1626,8 +1626,7 @@ static int nau8821_setup_irq(struct nau8821 *nau8821) return 0; } -static int nau8821_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8821_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8821 *nau8821 = dev_get_platdata(&i2c->dev); @@ -1703,7 +1702,7 @@ static struct i2c_driver nau8821_driver = { .of_match_table = of_match_ptr(nau8821_of_ids), .acpi_match_table = ACPI_PTR(nau8821_acpi_match), }, - .probe = nau8821_i2c_probe, + .probe_new = nau8821_i2c_probe, .remove = nau8821_i2c_remove, .id_table = nau8821_i2c_ids, }; diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 58123390c7a3..66bbd8f4f1ad 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -1083,8 +1083,7 @@ static const struct regmap_config nau8822_regmap_config = { .num_reg_defaults = ARRAY_SIZE(nau8822_reg_defaults), }; -static int nau8822_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8822_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8822 *nau8822 = dev_get_platdata(dev); @@ -1141,7 +1140,7 @@ static struct i2c_driver nau8822_i2c_driver = { .name = "nau8822", .of_match_table = of_match_ptr(nau8822_of_match), }, - .probe = nau8822_i2c_probe, + .probe_new = nau8822_i2c_probe, .id_table = nau8822_i2c_id, }; module_i2c_driver(nau8822_i2c_driver); diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index d0dd1542f78a..2a7c93508535 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -1910,8 +1910,7 @@ const char *nau8824_components(void) } EXPORT_SYMBOL_GPL(nau8824_components); -static int nau8824_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8824_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8824 *nau8824 = dev_get_platdata(dev); @@ -1985,7 +1984,7 @@ static struct i2c_driver nau8824_i2c_driver = { .of_match_table = of_match_ptr(nau8824_of_ids), .acpi_match_table = ACPI_PTR(nau8824_acpi_match), }, - .probe = nau8824_i2c_probe, + .probe_new = nau8824_i2c_probe, .id_table = nau8824_i2c_ids, }; module_i2c_driver(nau8824_i2c_driver); diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 7734bc35ab21..20e45a337b8f 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -2613,8 +2613,7 @@ static int nau8825_setup_irq(struct nau8825 *nau8825) return 0; } -static int nau8825_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8825_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8825 *nau8825 = dev_get_platdata(&i2c->dev); @@ -2703,7 +2702,7 @@ static struct i2c_driver nau8825_driver = { .of_match_table = of_match_ptr(nau8825_of_ids), .acpi_match_table = ACPI_PTR(nau8825_acpi_match), }, - .probe = nau8825_i2c_probe, + .probe_new = nau8825_i2c_probe, .remove = nau8825_i2c_remove, .id_table = nau8825_i2c_ids, }; diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 9eb65f94fc4d..20eb04c8a41a 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -299,8 +299,7 @@ static const struct i2c_device_id pcm1681_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, pcm1681_i2c_id); -static int pcm1681_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pcm1681_i2c_probe(struct i2c_client *client) { int ret; struct pcm1681_private *priv; @@ -329,7 +328,7 @@ static struct i2c_driver pcm1681_i2c_driver = { .of_match_table = of_match_ptr(pcm1681_dt_ids), }, .id_table = pcm1681_i2c_id, - .probe = pcm1681_i2c_probe, + .probe_new = pcm1681_i2c_probe, }; module_i2c_driver(pcm1681_i2c_driver); diff --git a/sound/soc/codecs/pcm1789-i2c.c b/sound/soc/codecs/pcm1789-i2c.c index 7a6be45f8149..1d2f7480a6e4 100644 --- a/sound/soc/codecs/pcm1789-i2c.c +++ b/sound/soc/codecs/pcm1789-i2c.c @@ -12,8 +12,7 @@ #include "pcm1789.h" -static int pcm1789_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pcm1789_i2c_probe(struct i2c_client *client) { struct regmap *regmap; int ret; @@ -30,7 +29,9 @@ static int pcm1789_i2c_probe(struct i2c_client *client, static int pcm1789_i2c_remove(struct i2c_client *client) { - return pcm1789_common_exit(&client->dev); + pcm1789_common_exit(&client->dev); + + return 0; } #ifdef CONFIG_OF @@ -53,7 +54,7 @@ static struct i2c_driver pcm1789_i2c_driver = { .of_match_table = of_match_ptr(pcm1789_of_match), }, .id_table = pcm1789_i2c_ids, - .probe = pcm1789_i2c_probe, + .probe_new = pcm1789_i2c_probe, .remove = pcm1789_i2c_remove, }; diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c index 620dec172ce7..35788b57e11f 100644 --- a/sound/soc/codecs/pcm1789.c +++ b/sound/soc/codecs/pcm1789.c @@ -259,13 +259,11 @@ int pcm1789_common_init(struct device *dev, struct regmap *regmap) } EXPORT_SYMBOL_GPL(pcm1789_common_init); -int pcm1789_common_exit(struct device *dev) +void pcm1789_common_exit(struct device *dev) { struct pcm1789_private *priv = dev_get_drvdata(dev); flush_work(&priv->work); - - return 0; } EXPORT_SYMBOL_GPL(pcm1789_common_exit); diff --git a/sound/soc/codecs/pcm1789.h b/sound/soc/codecs/pcm1789.h index c446d789ed48..79439c8322b3 100644 --- a/sound/soc/codecs/pcm1789.h +++ b/sound/soc/codecs/pcm1789.h @@ -12,6 +12,6 @@ extern const struct regmap_config pcm1789_regmap_config; int pcm1789_common_init(struct device *dev, struct regmap *regmap); -int pcm1789_common_exit(struct device *dev); +void pcm1789_common_exit(struct device *dev); #endif diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 34a3d596f288..e20fe3a85af8 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -14,8 +14,7 @@ #include "pcm179x.h" -static int pcm179x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pcm179x_i2c_probe(struct i2c_client *client) { struct regmap *regmap; int ret; @@ -50,7 +49,7 @@ static struct i2c_driver pcm179x_i2c_driver = { .of_match_table = of_match_ptr(pcm179x_of_match), }, .id_table = pcm179x_i2c_ids, - .probe = pcm179x_i2c_probe, + .probe_new = pcm179x_i2c_probe, }; module_i2c_driver(pcm179x_i2c_driver); diff --git a/sound/soc/codecs/pcm186x-i2c.c b/sound/soc/codecs/pcm186x-i2c.c index f8382b74391d..932c8d41c3ea 100644 --- a/sound/soc/codecs/pcm186x-i2c.c +++ b/sound/soc/codecs/pcm186x-i2c.c @@ -22,9 +22,18 @@ static const struct of_device_id pcm186x_of_match[] = { }; MODULE_DEVICE_TABLE(of, pcm186x_of_match); -static int pcm186x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id pcm186x_i2c_id[] = { + { "pcm1862", PCM1862 }, + { "pcm1863", PCM1863 }, + { "pcm1864", PCM1864 }, + { "pcm1865", PCM1865 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id); + +static int pcm186x_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_match_id(pcm186x_i2c_id, i2c); const enum pcm186x_type type = (enum pcm186x_type)id->driver_data; int irq = i2c->irq; struct regmap *regmap; @@ -36,17 +45,8 @@ static int pcm186x_i2c_probe(struct i2c_client *i2c, return pcm186x_probe(&i2c->dev, type, irq, regmap); } -static const struct i2c_device_id pcm186x_i2c_id[] = { - { "pcm1862", PCM1862 }, - { "pcm1863", PCM1863 }, - { "pcm1864", PCM1864 }, - { "pcm1865", PCM1865 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id); - static struct i2c_driver pcm186x_i2c_driver = { - .probe = pcm186x_i2c_probe, + .probe_new = pcm186x_i2c_probe, .id_table = pcm186x_i2c_id, .driver = { .name = "pcm186x", diff --git a/sound/soc/codecs/pcm186x.c b/sound/soc/codecs/pcm186x.c index 2c78dccb3f62..fda9d7ee3fe6 100644 --- a/sound/soc/codecs/pcm186x.c +++ b/sound/soc/codecs/pcm186x.c @@ -534,19 +534,14 @@ static int pcm186x_power_on(struct snd_soc_component *component) static int pcm186x_power_off(struct snd_soc_component *component) { struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component); - int ret; snd_soc_component_update_bits(component, PCM186X_POWER_CTRL, PCM186X_PWR_CTRL_PWRDN, PCM186X_PWR_CTRL_PWRDN); regcache_cache_only(priv->regmap, true); - ret = regulator_bulk_disable(ARRAY_SIZE(priv->supplies), + return regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); - if (ret) - return ret; - - return 0; } static int pcm186x_set_bias_level(struct snd_soc_component *component, diff --git a/sound/soc/codecs/pcm3060-i2c.c b/sound/soc/codecs/pcm3060-i2c.c index abcdeb922201..2388098eeca3 100644 --- a/sound/soc/codecs/pcm3060-i2c.c +++ b/sound/soc/codecs/pcm3060-i2c.c @@ -10,8 +10,7 @@ #include "pcm3060.h" -static int pcm3060_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int pcm3060_i2c_probe(struct i2c_client *i2c) { struct pcm3060_priv *priv; @@ -50,7 +49,7 @@ static struct i2c_driver pcm3060_i2c_driver = { #endif /* CONFIG_OF */ }, .id_table = pcm3060_i2c_id, - .probe = pcm3060_i2c_probe, + .probe_new = pcm3060_i2c_probe, }; module_i2c_driver(pcm3060_i2c_driver); diff --git a/sound/soc/codecs/pcm3060.c b/sound/soc/codecs/pcm3060.c index 4e3bfb9fa444..586ec8c7246c 100644 --- a/sound/soc/codecs/pcm3060.c +++ b/sound/soc/codecs/pcm3060.c @@ -255,6 +255,7 @@ static const struct snd_soc_component_driver pcm3060_soc_comp_driver = { .num_dapm_widgets = ARRAY_SIZE(pcm3060_dapm_widgets), .dapm_routes = pcm3060_dapm_map, .num_dapm_routes = ARRAY_SIZE(pcm3060_dapm_map), + .endianness = 1, }; /* regmap */ diff --git a/sound/soc/codecs/pcm3168a-i2c.c b/sound/soc/codecs/pcm3168a-i2c.c index 1f75933e74fa..c0fa0dc80e8f 100644 --- a/sound/soc/codecs/pcm3168a-i2c.c +++ b/sound/soc/codecs/pcm3168a-i2c.c @@ -15,8 +15,7 @@ #include "pcm3168a.h" -static int pcm3168a_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int pcm3168a_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; @@ -47,7 +46,7 @@ static const struct of_device_id pcm3168a_of_match[] = { MODULE_DEVICE_TABLE(of, pcm3168a_of_match); static struct i2c_driver pcm3168a_i2c_driver = { - .probe = pcm3168a_i2c_probe, + .probe_new = pcm3168a_i2c_probe, .remove = pcm3168a_i2c_remove, .id_table = pcm3168a_i2c_id, .driver = { diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c index 633f7ebe29a3..81754e141a55 100644 --- a/sound/soc/codecs/pcm512x-i2c.c +++ b/sound/soc/codecs/pcm512x-i2c.c @@ -13,8 +13,7 @@ #include "pcm512x.h" -static int pcm512x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int pcm512x_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; struct regmap_config config = pcm512x_regmap; @@ -68,7 +67,7 @@ MODULE_DEVICE_TABLE(acpi, pcm512x_acpi_match); #endif static struct i2c_driver pcm512x_i2c_driver = { - .probe = pcm512x_i2c_probe, + .probe_new = pcm512x_i2c_probe, .remove = pcm512x_i2c_remove, .id_table = pcm512x_i2c_id, .driver = { diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c index 758d439e8c7a..86b679cf7aef 100644 --- a/sound/soc/codecs/rk3328_codec.c +++ b/sound/soc/codecs/rk3328_codec.c @@ -481,7 +481,7 @@ static int rk3328_platform_probe(struct platform_device *pdev) ret = clk_prepare_enable(rk3328->pclk); if (ret < 0) { dev_err(&pdev->dev, "failed to enable acodec pclk\n"); - return ret; + goto err_unprepare_mclk; } base = devm_platform_ioremap_resource(pdev, 0); diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index b62301a6281f..08dbaef84d4e 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -2433,8 +2433,7 @@ static int rt1011_parse_dp(struct rt1011_priv *rt1011, struct device *dev) return 0; } -static int rt1011_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt1011_i2c_probe(struct i2c_client *i2c) { struct rt1011_priv *rt1011; int ret; @@ -2485,7 +2484,7 @@ static struct i2c_driver rt1011_i2c_driver = { .of_match_table = of_match_ptr(rt1011_of_match), .acpi_match_table = ACPI_PTR(rt1011_acpi_match) }, - .probe = rt1011_i2c_probe, + .probe_new = rt1011_i2c_probe, .shutdown = rt1011_i2c_shutdown, .id_table = rt1011_i2c_id, }; diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 6a27dfacd81c..7a06f2654afb 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -1113,8 +1113,7 @@ static void rt1015_parse_dt(struct rt1015_priv *rt1015, struct device *dev) &rt1015->pdata.power_up_delay_ms); } -static int rt1015_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt1015_i2c_probe(struct i2c_client *i2c) { struct rt1015_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt1015_priv *rt1015; @@ -1172,7 +1171,7 @@ static struct i2c_driver rt1015_i2c_driver = { .of_match_table = of_match_ptr(rt1015_of_match), .acpi_match_table = ACPI_PTR(rt1015_acpi_match), }, - .probe = rt1015_i2c_probe, + .probe_new = rt1015_i2c_probe, .shutdown = rt1015_i2c_shutdown, .id_table = rt1015_i2c_id, }; diff --git a/sound/soc/codecs/rt1016.c b/sound/soc/codecs/rt1016.c index 9845cdddcb4c..e31c4736627f 100644 --- a/sound/soc/codecs/rt1016.c +++ b/sound/soc/codecs/rt1016.c @@ -631,8 +631,7 @@ static const struct acpi_device_id rt1016_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rt1016_acpi_match); #endif -static int rt1016_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt1016_i2c_probe(struct i2c_client *i2c) { struct rt1016_priv *rt1016; int ret; @@ -685,7 +684,7 @@ static struct i2c_driver rt1016_i2c_driver = { .of_match_table = of_match_ptr(rt1016_of_match), .acpi_match_table = ACPI_PTR(rt1016_acpi_match), }, - .probe = rt1016_i2c_probe, + .probe_new = rt1016_i2c_probe, .shutdown = rt1016_i2c_shutdown, .id_table = rt1016_i2c_id, }; diff --git a/sound/soc/codecs/rt1019.c b/sound/soc/codecs/rt1019.c index 80b7ca0e4e1e..f3f15fbe85d0 100644 --- a/sound/soc/codecs/rt1019.c +++ b/sound/soc/codecs/rt1019.c @@ -515,7 +515,7 @@ static struct snd_soc_dai_driver rt1019_dai[] = { }; static const struct snd_soc_component_driver soc_component_dev_rt1019 = { - .probe = rt1019_probe, + .probe = rt1019_probe, .controls = rt1019_snd_controls, .num_controls = ARRAY_SIZE(rt1019_snd_controls), .dapm_widgets = rt1019_dapm_widgets, @@ -523,6 +523,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt1019 = { .dapm_routes = rt1019_dapm_routes, .num_dapm_routes = ARRAY_SIZE(rt1019_dapm_routes), .non_legacy_dai_naming = 1, + .endianness = 1, }; static const struct regmap_config rt1019_regmap = { @@ -558,8 +559,7 @@ static const struct acpi_device_id rt1019_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rt1019_acpi_match); #endif -static int rt1019_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt1019_i2c_probe(struct i2c_client *i2c) { struct rt1019_priv *rt1019; int ret; @@ -599,7 +599,7 @@ static struct i2c_driver rt1019_i2c_driver = { .of_match_table = of_match_ptr(rt1019_of_match), .acpi_match_table = ACPI_PTR(rt1019_acpi_match), }, - .probe = rt1019_i2c_probe, + .probe_new = rt1019_i2c_probe, .id_table = rt1019_i2c_id, }; module_i2c_driver(rt1019_i2c_driver); diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c index a9c473537a91..58d97e3c5087 100644 --- a/sound/soc/codecs/rt1305.c +++ b/sound/soc/codecs/rt1305.c @@ -1117,8 +1117,7 @@ static void rt1305_calibrate(struct rt1305_priv *rt1305) regcache_cache_bypass(rt1305->regmap, false); } -static int rt1305_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt1305_i2c_probe(struct i2c_client *i2c) { struct rt1305_priv *rt1305; int ret; @@ -1172,7 +1171,7 @@ static struct i2c_driver rt1305_i2c_driver = { .acpi_match_table = ACPI_PTR(rt1305_acpi_match) #endif }, - .probe = rt1305_i2c_probe, + .probe_new = rt1305_i2c_probe, .shutdown = rt1305_i2c_shutdown, .id_table = rt1305_i2c_id, }; diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 1ef836a68a56..1c11b42dd76e 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -615,6 +615,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1308 = { .num_dapm_widgets = ARRAY_SIZE(rt1308_dapm_widgets), .dapm_routes = rt1308_dapm_routes, .num_dapm_routes = ARRAY_SIZE(rt1308_dapm_routes), + .endianness = 1, }; static const struct snd_soc_dai_ops rt1308_aif_dai_ops = { diff --git a/sound/soc/codecs/rt1308-sdw.h b/sound/soc/codecs/rt1308-sdw.h index c5ce75666dcc..6668e19d85d4 100644 --- a/sound/soc/codecs/rt1308-sdw.h +++ b/sound/soc/codecs/rt1308-sdw.h @@ -140,6 +140,7 @@ static const struct reg_default rt1308_reg_defaults[] = { { 0x3008, 0x02 }, { 0x300a, 0x00 }, { 0xc003 | (RT1308_DAC_SET << 4), 0x00 }, + { 0xc000 | (RT1308_POWER << 4), 0x00 }, { 0xc001 | (RT1308_POWER << 4), 0x00 }, { 0xc002 | (RT1308_POWER << 4), 0x00 }, }; diff --git a/sound/soc/codecs/rt1308.c b/sound/soc/codecs/rt1308.c index c555b77b3c5c..eec2b1760408 100644 --- a/sound/soc/codecs/rt1308.c +++ b/sound/soc/codecs/rt1308.c @@ -814,8 +814,7 @@ static void rt1308_efuse(struct rt1308_priv *rt1308) regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000); } -static int rt1308_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt1308_i2c_probe(struct i2c_client *i2c) { struct rt1308_priv *rt1308; int ret; @@ -864,7 +863,7 @@ static struct i2c_driver rt1308_i2c_driver = { .of_match_table = of_match_ptr(rt1308_of_match), .acpi_match_table = ACPI_PTR(rt1308_acpi_match), }, - .probe = rt1308_i2c_probe, + .probe_new = rt1308_i2c_probe, .shutdown = rt1308_i2c_shutdown, .id_table = rt1308_i2c_id, }; diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index c66d7b20cb4d..60baa9ff1907 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -597,6 +597,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1316 = { .num_dapm_widgets = ARRAY_SIZE(rt1316_dapm_widgets), .dapm_routes = rt1316_dapm_routes, .num_dapm_routes = ARRAY_SIZE(rt1316_dapm_routes), + .endianness = 1, }; static const struct snd_soc_dai_ops rt1316_aif_dai_ops = { diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index 0d3773c576f8..ab093bdb5552 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -1114,8 +1114,7 @@ static const struct acpi_device_id rt274_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rt274_acpi_match); #endif -static int rt274_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt274_i2c_probe(struct i2c_client *i2c) { struct rt274_priv *rt274; @@ -1227,7 +1226,7 @@ static struct i2c_driver rt274_i2c_driver = { .of_match_table = of_match_ptr(rt274_of_match), #endif }, - .probe = rt274_i2c_probe, + .probe_new = rt274_i2c_probe, .remove = rt274_i2c_remove, .id_table = rt274_i2c_id, }; diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index caa720884e3e..ad8ea1fa7c23 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1134,8 +1134,7 @@ static const struct dmi_system_id dmi_dell[] = { { } }; -static int rt286_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt286_i2c_probe(struct i2c_client *i2c) { struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt286_priv *rt286; @@ -1271,7 +1270,7 @@ static struct i2c_driver rt286_i2c_driver = { .name = "rt286", .acpi_match_table = ACPI_PTR(rt286_acpi_match), }, - .probe = rt286_i2c_probe, + .probe_new = rt286_i2c_probe, .remove = rt286_i2c_remove, .id_table = rt286_i2c_id, }; diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index c592c40a7ab3..c291786dc82d 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1176,8 +1176,7 @@ static const struct dmi_system_id force_combo_jack_table[] = { { } }; -static int rt298_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt298_i2c_probe(struct i2c_client *i2c) { struct rt298_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt298_priv *rt298; @@ -1314,7 +1313,7 @@ static struct i2c_driver rt298_i2c_driver = { .name = "rt298", .acpi_match_table = ACPI_PTR(rt298_acpi_match), }, - .probe = rt298_i2c_probe, + .probe_new = rt298_i2c_probe, .remove = rt298_i2c_remove, .id_table = rt298_i2c_id, }; diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 577680df7052..be8ece4630df 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -419,7 +419,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, } } - return 0; + return 1; } static const struct snd_kcontrol_new rt5514_snd_controls[] = { @@ -1252,8 +1252,7 @@ static __maybe_unused int rt5514_i2c_resume(struct device *dev) return 0; } -static int rt5514_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5514_i2c_probe(struct i2c_client *i2c) { struct rt5514_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5514_priv *rt5514; @@ -1330,7 +1329,7 @@ static struct i2c_driver rt5514_i2c_driver = { .of_match_table = of_match_ptr(rt5514_of_match), .pm = &rt5514_i2_pm_ops, }, - .probe = rt5514_i2c_probe, + .probe_new = rt5514_i2c_probe, .id_table = rt5514_i2c_id, }; module_i2c_driver(rt5514_i2c_driver); diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 8e6414468a87..37f1bf552eff 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -1337,8 +1337,7 @@ static const struct of_device_id rt5616_of_match[] = { MODULE_DEVICE_TABLE(of, rt5616_of_match); #endif -static int rt5616_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5616_i2c_probe(struct i2c_client *i2c) { struct rt5616_priv *rt5616; unsigned int val; @@ -1408,7 +1407,7 @@ static struct i2c_driver rt5616_i2c_driver = { .name = "rt5616", .of_match_table = of_match_ptr(rt5616_of_match), }, - .probe = rt5616_i2c_probe, + .probe_new = rt5616_i2c_probe, .remove = rt5616_i2c_remove, .shutdown = rt5616_i2c_shutdown, .id_table = rt5616_i2c_id, diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 38356ea2bd6e..c941e878471c 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1699,8 +1699,7 @@ static const struct regmap_config rt5631_regmap_config = { .use_single_write = true, }; -static int rt5631_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5631_i2c_probe(struct i2c_client *i2c) { struct rt5631_priv *rt5631; int ret; @@ -1732,7 +1731,7 @@ static struct i2c_driver rt5631_i2c_driver = { .name = "rt5631", .of_match_table = of_match_ptr(rt5631_i2c_dt_ids), }, - .probe = rt5631_i2c_probe, + .probe_new = rt5631_i2c_probe, .remove = rt5631_i2c_remove, .id_table = rt5631_i2c_id, }; diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 30c2e7cb7ed2..12da2bea1a7b 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2927,8 +2927,7 @@ static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np) return 0; } -static int rt5640_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5640_i2c_probe(struct i2c_client *i2c) { struct rt5640_priv *rt5640; int ret; @@ -3006,7 +3005,7 @@ static struct i2c_driver rt5640_i2c_driver = { .acpi_match_table = ACPI_PTR(rt5640_acpi_match), .of_match_table = of_match_ptr(rt5640_of_match), }, - .probe = rt5640_i2c_probe, + .probe_new = rt5640_i2c_probe, .id_table = rt5640_i2c_id, }; module_i2c_driver(rt5640_i2c_driver); diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 197c56047947..507aba8de3cc 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3855,8 +3855,7 @@ static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) return 0; } -static int rt5645_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5645_i2c_probe(struct i2c_client *i2c) { struct rt5645_platform_data *pdata = NULL; const struct dmi_system_id *dmi_data; @@ -3944,7 +3943,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ret = PTR_ERR(regmap); dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n", ret); - return ret; + goto err_enable; } /* @@ -3975,7 +3974,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ret = PTR_ERR(rt5645->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); - return ret; + goto err_enable; } regmap_write(rt5645->regmap, RT5645_RESET, 0); @@ -4154,9 +4153,14 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) if (i2c->irq) free_irq(i2c->irq, rt5645); + /* + * Since the rt5645_btn_check_callback() can queue jack_detect_work, + * the timer need to be delted first + */ + del_timer_sync(&rt5645->btn_check_timer); + cancel_delayed_work_sync(&rt5645->jack_detect_work); cancel_delayed_work_sync(&rt5645->rcclock_work); - del_timer_sync(&rt5645->btn_check_timer); regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); @@ -4183,7 +4187,7 @@ static struct i2c_driver rt5645_i2c_driver = { .of_match_table = of_match_ptr(rt5645_of_match), .acpi_match_table = ACPI_PTR(rt5645_acpi_match), }, - .probe = rt5645_i2c_probe, + .probe_new = rt5645_i2c_probe, .remove = rt5645_i2c_remove, .shutdown = rt5645_i2c_shutdown, .id_table = rt5645_i2c_id, diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index f302c25688d1..d11d201b1d03 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -2209,8 +2209,7 @@ MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id); * Note this function MUST not look at device-properties, see the comment * above rt5651_apply_properties(). */ -static int rt5651_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5651_i2c_probe(struct i2c_client *i2c) { struct rt5651_priv *rt5651; int ret; @@ -2281,7 +2280,7 @@ static struct i2c_driver rt5651_i2c_driver = { .acpi_match_table = ACPI_PTR(rt5651_acpi_match), .of_match_table = of_match_ptr(rt5651_of_match), }, - .probe = rt5651_i2c_probe, + .probe_new = rt5651_i2c_probe, .id_table = rt5651_i2c_id, }; module_i2c_driver(rt5651_i2c_driver); diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index e1503c2eee81..6efa90f46362 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -4093,8 +4093,7 @@ static void rt5659_intel_hd_header_probe_setup(struct rt5659_priv *rt5659) RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN); } -static int rt5659_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5659_i2c_probe(struct i2c_client *i2c) { struct rt5659_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5659_priv *rt5659; @@ -4342,7 +4341,7 @@ static struct i2c_driver rt5659_i2c_driver = { .of_match_table = of_match_ptr(rt5659_of_match), .acpi_match_table = ACPI_PTR(rt5659_acpi_match), }, - .probe = rt5659_i2c_probe, + .probe_new = rt5659_i2c_probe, .shutdown = rt5659_i2c_shutdown, .id_table = rt5659_i2c_id, }; diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 3b50fb29864e..d5f9926625d2 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1266,8 +1266,7 @@ static int rt5660_parse_dt(struct rt5660_priv *rt5660, struct device *dev) return 0; } -static int rt5660_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5660_i2c_probe(struct i2c_client *i2c) { struct rt5660_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5660_priv *rt5660; @@ -1343,7 +1342,7 @@ static struct i2c_driver rt5660_i2c_driver = { .acpi_match_table = ACPI_PTR(rt5660_acpi_match), .of_match_table = of_match_ptr(rt5660_of_match), }, - .probe = rt5660_i2c_probe, + .probe_new = rt5660_i2c_probe, .id_table = rt5660_i2c_id, }; module_i2c_driver(rt5660_i2c_driver); diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 3a8fba101b20..e51eed8a79ab 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -3490,8 +3490,7 @@ static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) return 0; } -static int rt5663_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5663_i2c_probe(struct i2c_client *i2c) { struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5663_priv *rt5663; @@ -3737,7 +3736,7 @@ static struct i2c_driver rt5663_i2c_driver = { .acpi_match_table = ACPI_PTR(rt5663_acpi_match), .of_match_table = of_match_ptr(rt5663_of_match), }, - .probe = rt5663_i2c_probe, + .probe_new = rt5663_i2c_probe, .remove = rt5663_i2c_remove, .shutdown = rt5663_i2c_shutdown, .id_table = rt5663_i2c_id, diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 33e889802ff8..4a8d62e1dd2b 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4757,8 +4757,7 @@ static void rt5665_calibrate_handler(struct work_struct *work) rt5665_calibrate(rt5665); } -static int rt5665_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5665_i2c_probe(struct i2c_client *i2c) { struct rt5665_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5665_priv *rt5665; @@ -4970,7 +4969,7 @@ static struct i2c_driver rt5665_i2c_driver = { .of_match_table = of_match_ptr(rt5665_of_match), .acpi_match_table = ACPI_PTR(rt5665_acpi_match), }, - .probe = rt5665_i2c_probe, + .probe_new = rt5665_i2c_probe, .shutdown = rt5665_i2c_shutdown, .id_table = rt5665_i2c_id, }; diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 5b12cbf2ba21..01566f036ca1 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -2453,8 +2453,7 @@ static void rt5668_calibrate(struct rt5668_priv *rt5668) } -static int rt5668_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5668_i2c_probe(struct i2c_client *i2c) { struct rt5668_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5668_priv *rt5668; @@ -2620,7 +2619,7 @@ static struct i2c_driver rt5668_i2c_driver = { .of_match_table = of_match_ptr(rt5668_of_match), .acpi_match_table = ACPI_PTR(rt5668_acpi_match), }, - .probe = rt5668_i2c_probe, + .probe_new = rt5668_i2c_probe, .shutdown = rt5668_i2c_shutdown, .id_table = rt5668_i2c_id, }; diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index ce7684752bb0..8a97f6db04d5 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -3046,8 +3046,7 @@ const char *rt5670_components(void) } EXPORT_SYMBOL_GPL(rt5670_components); -static int rt5670_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5670_i2c_probe(struct i2c_client *i2c) { struct rt5670_priv *rt5670; int ret; @@ -3334,7 +3333,7 @@ static struct i2c_driver rt5670_i2c_driver = { .name = "rt5670", .acpi_match_table = ACPI_PTR(rt5670_acpi_match), }, - .probe = rt5670_i2c_probe, + .probe_new = rt5670_i2c_probe, .remove = rt5670_i2c_remove, .id_table = rt5670_i2c_id, }; diff --git a/sound/soc/codecs/rt5682-i2c.c b/sound/soc/codecs/rt5682-i2c.c index 20fc0f3766de..3f72f6093436 100644 --- a/sound/soc/codecs/rt5682-i2c.c +++ b/sound/soc/codecs/rt5682-i2c.c @@ -118,8 +118,7 @@ static void rt5682_i2c_disable_regulators(void *data) regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies); } -static int rt5682_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5682_i2c_probe(struct i2c_client *i2c) { struct rt5682_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5682_priv *rt5682; @@ -335,7 +334,7 @@ static struct i2c_driver rt5682_i2c_driver = { .acpi_match_table = rt5682_acpi_match, .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, - .probe = rt5682_i2c_probe, + .probe_new = rt5682_i2c_probe, .remove = rt5682_i2c_remove, .shutdown = rt5682_i2c_shutdown, .id_table = rt5682_i2c_id, diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index b55f3ac3a267..4d44eddee901 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -42,8 +42,8 @@ static const struct rt5682s_platform_data i2s_default_platform_data = { }; static const char *rt5682s_supply_names[RT5682S_NUM_SUPPLIES] = { - "AVDD", - "MICVDD", + [RT5682S_SUPPLY_AVDD] = "AVDD", + [RT5682S_SUPPLY_MICVDD] = "MICVDD", }; static const struct reg_sequence patch_list[] = { @@ -3022,12 +3022,21 @@ static struct snd_soc_dai_driver rt5682s_dai[] = { static void rt5682s_i2c_disable_regulators(void *data) { struct rt5682s_priv *rt5682s = data; + struct device *dev = regmap_get_device(rt5682s->regmap); + int ret; + + ret = regulator_disable(rt5682s->supplies[RT5682S_SUPPLY_AVDD].consumer); + if (ret) + dev_err(dev, "Failed to disable supply AVDD: %d\n", ret); - regulator_bulk_disable(ARRAY_SIZE(rt5682s->supplies), rt5682s->supplies); + usleep_range(1000, 1500); + + ret = regulator_disable(rt5682s->supplies[RT5682S_SUPPLY_MICVDD].consumer); + if (ret) + dev_err(dev, "Failed to disable supply MICVDD: %d\n", ret); } -static int rt5682s_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5682s_i2c_probe(struct i2c_client *i2c) { struct rt5682s_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5682s_priv *rt5682s; @@ -3068,9 +3077,16 @@ static int rt5682s_i2c_probe(struct i2c_client *i2c, if (ret) return ret; - ret = regulator_bulk_enable(ARRAY_SIZE(rt5682s->supplies), rt5682s->supplies); + ret = regulator_enable(rt5682s->supplies[RT5682S_SUPPLY_MICVDD].consumer); + if (ret) { + dev_err(&i2c->dev, "Failed to enable supply MICVDD: %d\n", ret); + return ret; + } + usleep_range(1000, 1500); + + ret = regulator_enable(rt5682s->supplies[RT5682S_SUPPLY_AVDD].consumer); if (ret) { - dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + dev_err(&i2c->dev, "Failed to enable supply AVDD: %d\n", ret); return ret; } @@ -3211,7 +3227,7 @@ static struct i2c_driver rt5682s_i2c_driver = { .acpi_match_table = rt5682s_acpi_match, .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, - .probe = rt5682s_i2c_probe, + .probe_new = rt5682s_i2c_probe, .remove = rt5682s_i2c_remove, .shutdown = rt5682s_i2c_shutdown, .id_table = rt5682s_i2c_id, diff --git a/sound/soc/codecs/rt5682s.h b/sound/soc/codecs/rt5682s.h index 397a2531b6f6..7353831c73dd 100644 --- a/sound/soc/codecs/rt5682s.h +++ b/sound/soc/codecs/rt5682s.h @@ -1434,7 +1434,11 @@ struct pll_calc_map { bool sel_ps; }; -#define RT5682S_NUM_SUPPLIES 2 +enum { + RT5682S_SUPPLY_AVDD, + RT5682S_SUPPLY_MICVDD, + RT5682S_NUM_SUPPLIES, +}; struct rt5682s_priv { struct snd_soc_component *component; diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index e61a8257bf64..af32295fa9b9 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -853,6 +853,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt700 = { .dapm_routes = rt700_audio_map, .num_dapm_routes = ARRAY_SIZE(rt700_audio_map), .set_jack = rt700_set_jack_detect, + .endianness = 1, }; static int rt700_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index bdb1375f0338..57629c18db38 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1208,6 +1208,7 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = { .num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map), .set_jack = rt711_sdca_set_jack_detect, .remove = rt711_sdca_remove, + .endianness = 1, }; static int rt711_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index ea25fd58d43a..9838fb4d5b9c 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -950,6 +950,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = { .num_dapm_routes = ARRAY_SIZE(rt711_audio_map), .set_jack = rt711_set_jack_detect, .remove = rt711_remove, + .endianness = 1, }; static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c index a5c673f43d82..0ecd2948f7aa 100644 --- a/sound/soc/codecs/rt715-sdca-sdw.c +++ b/sound/soc/codecs/rt715-sdca-sdw.c @@ -181,8 +181,6 @@ static int rt715_sdca_sdw_probe(struct sdw_slave *slave, { struct regmap *mbq_regmap, *regmap; - slave->ops = &rt715_sdca_slave_ops; - /* Regmap Initialization */ mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt715_sdca_mbq_regmap); if (IS_ERR(mbq_regmap)) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index bfa536bd7196..5857d0866307 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -765,6 +765,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = { .num_dapm_widgets = ARRAY_SIZE(rt715_sdca_dapm_widgets), .dapm_routes = rt715_sdca_audio_map, .num_dapm_routes = ARRAY_SIZE(rt715_sdca_audio_map), + .endianness = 1, }; static int rt715_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index a64d11a74751..418e006b19ef 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -745,6 +745,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt715 = { .num_dapm_widgets = ARRAY_SIZE(rt715_dapm_widgets), .dapm_routes = rt715_audio_map, .num_dapm_routes = ARRAY_SIZE(rt715_audio_map), + .endianness = 1, }; static int rt715_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, diff --git a/sound/soc/codecs/rt9120.c b/sound/soc/codecs/rt9120.c index 6e0d7cf0c8c9..da495bdc8415 100644 --- a/sound/soc/codecs/rt9120.c +++ b/sound/soc/codecs/rt9120.c @@ -7,6 +7,7 @@ #include <linux/i2c.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <sound/pcm.h> @@ -75,6 +76,7 @@ enum { struct rt9120_data { struct device *dev; struct regmap *regmap; + struct gpio_desc *pwdnn_gpio; int chip_idx; }; @@ -160,6 +162,8 @@ static int rt9120_codec_probe(struct snd_soc_component *comp) snd_soc_component_init_regmap(comp, data->regmap); + pm_runtime_get_sync(comp->dev); + /* Internal setting */ if (data->chip_idx == CHIP_IDX_RT9120S) { snd_soc_component_write(comp, RT9120_REG_INTERCFG, 0xde); @@ -167,6 +171,9 @@ static int rt9120_codec_probe(struct snd_soc_component *comp) } else snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x04); + pm_runtime_mark_last_busy(comp->dev); + pm_runtime_put(comp->dev); + return 0; } @@ -178,6 +185,7 @@ static const struct snd_soc_component_driver rt9120_component_driver = { .num_dapm_widgets = ARRAY_SIZE(rt9120_dapm_widgets), .dapm_routes = rt9120_dapm_routes, .num_dapm_routes = ARRAY_SIZE(rt9120_dapm_routes), + .endianness = 1, }; static int rt9120_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) @@ -337,6 +345,18 @@ static const struct regmap_access_table rt9120_wr_table = { .n_yes_ranges = ARRAY_SIZE(rt9120_wr_yes_ranges), }; +static bool rt9120_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0x00 ... 0x01: + case 0x10: + case 0x30 ... 0x40: + return true; + default: + return false; + } +} + static int rt9120_get_reg_size(unsigned int reg) { switch (reg) { @@ -371,7 +391,7 @@ static int rt9120_reg_read(void *context, unsigned int reg, unsigned int *val) *val = be32_to_cpup((__be32 *)raw); break; case 3: - *val = raw[0] << 16 | raw[1] << 8 | raw[0]; + *val = raw[0] << 16 | raw[1] << 8 | raw[2]; break; case 2: *val = be16_to_cpup((__be16 *)raw); @@ -396,14 +416,49 @@ static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val) return i2c_smbus_write_i2c_block_data(i2c, reg, size, rawp + offs); } +static const struct reg_default rt9120_reg_defaults[] = { + { .reg = 0x02, .def = 0x02 }, + { .reg = 0x03, .def = 0xf2 }, + { .reg = 0x04, .def = 0x01 }, + { .reg = 0x05, .def = 0xc0 }, + { .reg = 0x06, .def = 0x28 }, + { .reg = 0x07, .def = 0x04 }, + { .reg = 0x08, .def = 0xff }, + { .reg = 0x09, .def = 0x01 }, + { .reg = 0x0a, .def = 0x01 }, + { .reg = 0x0b, .def = 0x00 }, + { .reg = 0x0c, .def = 0x04 }, + { .reg = 0x11, .def = 0x30 }, + { .reg = 0x12, .def = 0x08 }, + { .reg = 0x13, .def = 0x12 }, + { .reg = 0x14, .def = 0x09 }, + { .reg = 0x15, .def = 0x00 }, + { .reg = 0x20, .def = 0x7ff }, + { .reg = 0x21, .def = 0x180 }, + { .reg = 0x22, .def = 0x180 }, + { .reg = 0x23, .def = 0x00 }, + { .reg = 0x24, .def = 0x80 }, + { .reg = 0x25, .def = 0x180 }, + { .reg = 0x26, .def = 0x640 }, + { .reg = 0x27, .def = 0x180 }, + { .reg = 0x63, .def = 0x5e }, + { .reg = 0x65, .def = 0x66 }, + { .reg = 0x6c, .def = 0xe0 }, + { .reg = 0xf8, .def = 0x44 }, +}; + static const struct regmap_config rt9120_regmap_config = { .reg_bits = 8, .val_bits = 32, .max_register = RT9120_REG_DIGCFG, + .reg_defaults = rt9120_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(rt9120_reg_defaults), + .cache_type = REGCACHE_RBTREE, .reg_read = rt9120_reg_read, .reg_write = rt9120_reg_write, + .volatile_reg = rt9120_volatile_reg, .wr_table = &rt9120_wr_table, .rd_table = &rt9120_rd_table, }; @@ -449,7 +504,6 @@ static int rt9120_do_register_reset(struct rt9120_data *data) static int rt9120_probe(struct i2c_client *i2c) { struct rt9120_data *data; - struct gpio_desc *pwdnn_gpio; struct regulator *dvdd_supply; int dvdd_supply_volt, ret; @@ -460,12 +514,12 @@ static int rt9120_probe(struct i2c_client *i2c) data->dev = &i2c->dev; i2c_set_clientdata(i2c, data); - pwdnn_gpio = devm_gpiod_get_optional(&i2c->dev, "pwdnn", - GPIOD_OUT_HIGH); - if (IS_ERR(pwdnn_gpio)) { + data->pwdnn_gpio = devm_gpiod_get_optional(&i2c->dev, "pwdnn", + GPIOD_OUT_HIGH); + if (IS_ERR(data->pwdnn_gpio)) { dev_err(&i2c->dev, "Failed to initialize 'pwdnn' gpio\n"); - return PTR_ERR(pwdnn_gpio); - } else if (pwdnn_gpio) { + return PTR_ERR(data->pwdnn_gpio); + } else if (data->pwdnn_gpio) { dev_dbg(&i2c->dev, "'pwdnn' from low to high, wait chip on\n"); msleep(RT9120_CHIPON_WAITMS); } @@ -507,11 +561,55 @@ static int rt9120_probe(struct i2c_client *i2c) } } + pm_runtime_set_autosuspend_delay(&i2c->dev, 1000); + pm_runtime_use_autosuspend(&i2c->dev); + pm_runtime_set_active(&i2c->dev); + pm_runtime_mark_last_busy(&i2c->dev); + pm_runtime_enable(&i2c->dev); + return devm_snd_soc_register_component(&i2c->dev, &rt9120_component_driver, &rt9120_dai, 1); } +static int rt9120_remove(struct i2c_client *i2c) +{ + pm_runtime_disable(&i2c->dev); + pm_runtime_set_suspended(&i2c->dev); + return 0; +} + +static int __maybe_unused rt9120_runtime_suspend(struct device *dev) +{ + struct rt9120_data *data = dev_get_drvdata(dev); + + if (data->pwdnn_gpio) { + regcache_cache_only(data->regmap, true); + regcache_mark_dirty(data->regmap); + gpiod_set_value(data->pwdnn_gpio, 0); + } + + return 0; +} + +static int __maybe_unused rt9120_runtime_resume(struct device *dev) +{ + struct rt9120_data *data = dev_get_drvdata(dev); + + if (data->pwdnn_gpio) { + gpiod_set_value(data->pwdnn_gpio, 1); + msleep(RT9120_CHIPON_WAITMS); + regcache_cache_only(data->regmap, false); + regcache_sync(data->regmap); + } + + return 0; +} + +static const struct dev_pm_ops rt9120_pm_ops = { + SET_RUNTIME_PM_OPS(rt9120_runtime_suspend, rt9120_runtime_resume, NULL) +}; + static const struct of_device_id __maybe_unused rt9120_device_table[] = { { .compatible = "richtek,rt9120", }, { } @@ -522,8 +620,10 @@ static struct i2c_driver rt9120_driver = { .driver = { .name = "rt9120", .of_match_table = rt9120_device_table, + .pm = &rt9120_pm_ops, }, .probe_new = rt9120_probe, + .remove = rt9120_remove, }; module_i2c_driver(rt9120_driver); diff --git a/sound/soc/codecs/sdw-mockup.c b/sound/soc/codecs/sdw-mockup.c index 7c612aaf31c7..288b55368d2a 100644 --- a/sound/soc/codecs/sdw-mockup.c +++ b/sound/soc/codecs/sdw-mockup.c @@ -38,6 +38,7 @@ static void sdw_mockup_component_remove(struct snd_soc_component *component) static const struct snd_soc_component_driver snd_soc_sdw_mockup_component = { .probe = sdw_mockup_component_probe, .remove = sdw_mockup_component_remove, + .endianness = 1, }; static int sdw_mockup_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 8eebf27d0ea2..2aa48aef6a97 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1579,8 +1579,7 @@ static void sgtl5000_fill_defaults(struct i2c_client *client) } } -static int sgtl5000_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sgtl5000_i2c_probe(struct i2c_client *client) { struct sgtl5000_priv *sgtl5000; int ret, reg, rev; @@ -1821,7 +1820,7 @@ static struct i2c_driver sgtl5000_i2c_driver = { .name = "sgtl5000", .of_match_table = sgtl5000_dt_ids, }, - .probe = sgtl5000_i2c_probe, + .probe_new = sgtl5000_i2c_probe, .remove = sgtl5000_i2c_remove, .id_table = sgtl5000_id, }; diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 09449c6c4024..83acbdbb8e0d 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -735,8 +735,7 @@ static const struct regmap_config ssm2518_regmap_config = { .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults), }; -static int ssm2518_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ssm2518_i2c_probe(struct i2c_client *i2c) { struct ssm2518_platform_data *pdata = i2c->dev.platform_data; struct ssm2518 *ssm2518; @@ -815,7 +814,7 @@ static struct i2c_driver ssm2518_driver = { .name = "ssm2518", .of_match_table = of_match_ptr(ssm2518_dt_ids), }, - .probe = ssm2518_i2c_probe, + .probe_new = ssm2518_i2c_probe, .id_table = ssm2518_i2c_ids, }; module_i2c_driver(ssm2518_driver); diff --git a/sound/soc/codecs/ssm2602-i2c.c b/sound/soc/codecs/ssm2602-i2c.c index afab81383d3a..3c85772901f5 100644 --- a/sound/soc/codecs/ssm2602-i2c.c +++ b/sound/soc/codecs/ssm2602-i2c.c @@ -13,15 +13,17 @@ #include "ssm2602.h" +static const struct i2c_device_id ssm2602_i2c_id[]; + /* * ssm2602 2 wire address is determined by GPIO5 * state during powerup. * low = 0x1a * high = 0x1b */ -static int ssm2602_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ssm2602_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_match_id(ssm2602_i2c_id, client); return ssm2602_probe(&client->dev, id->driver_data, devm_regmap_init_i2c(client, &ssm2602_regmap_config)); } @@ -47,7 +49,7 @@ static struct i2c_driver ssm2602_i2c_driver = { .name = "ssm2602", .of_match_table = ssm2602_of_match, }, - .probe = ssm2602_i2c_probe, + .probe_new = ssm2602_i2c_probe, .id_table = ssm2602_i2c_id, }; module_i2c_driver(ssm2602_i2c_driver); diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 811b1a2c404a..08ced09ef001 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -444,8 +444,7 @@ static const struct regmap_config ssm4567_regmap_config = { .num_reg_defaults = ARRAY_SIZE(ssm4567_reg_defaults), }; -static int ssm4567_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ssm4567_i2c_probe(struct i2c_client *i2c) { struct ssm4567 *ssm4567; int ret; @@ -502,7 +501,7 @@ static struct i2c_driver ssm4567_driver = { .of_match_table = of_match_ptr(ssm4567_of_match), .acpi_match_table = ACPI_PTR(ssm4567_acpi_match), }, - .probe = ssm4567_i2c_probe, + .probe_new = ssm4567_i2c_probe, .id_table = ssm4567_i2c_ids, }; module_i2c_driver(ssm4567_driver); diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 86528b930de8..8585cbef4c9b 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -48,12 +48,9 @@ SNDRV_PCM_RATE_192000) #define STA32X_FORMATS \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) /* Power-up register defaults */ static const struct reg_default sta32x_regs[] = { @@ -1094,8 +1091,7 @@ static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x) } #endif -static int sta32x_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int sta32x_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct sta32x_priv *sta32x; @@ -1175,7 +1171,7 @@ static struct i2c_driver sta32x_i2c_driver = { .name = "sta32x", .of_match_table = of_match_ptr(st32x_dt_ids), }, - .probe = sta32x_i2c_probe, + .probe_new = sta32x_i2c_probe, .id_table = sta32x_i2c_id, }; diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index 75d3b0618ab5..9189fb3648f7 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -48,12 +48,9 @@ SNDRV_PCM_RATE_192000) #define STA350_FORMATS \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) /* Power-up register defaults */ static const struct reg_default sta350_regs[] = { @@ -1187,8 +1184,7 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) } #endif -static int sta350_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int sta350_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct sta350_priv *sta350; @@ -1263,7 +1259,7 @@ static struct i2c_driver sta350_i2c_driver = { .name = "sta350", .of_match_table = of_match_ptr(st350_dt_ids), }, - .probe = sta350_i2c_probe, + .probe_new = sta350_i2c_probe, .remove = sta350_i2c_remove, .id_table = sta350_i2c_id, }; diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 97b5f34027c0..d90e5512a731 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -337,8 +337,7 @@ static const struct regmap_config sta529_regmap = { .num_reg_defaults = ARRAY_SIZE(sta529_reg_defaults), }; -static int sta529_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int sta529_i2c_probe(struct i2c_client *i2c) { struct sta529 *sta529; int ret; @@ -381,7 +380,7 @@ static struct i2c_driver sta529_i2c_driver = { .name = "sta529", .of_match_table = sta529_of_match, }, - .probe = sta529_i2c_probe, + .probe_new = sta529_i2c_probe, .id_table = sta529_i2c_id, }; diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 700baa6314aa..b5c9c61ff5a8 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -681,8 +681,7 @@ static const struct regmap_config tas2552_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int tas2552_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tas2552_probe(struct i2c_client *client) { struct device *dev; struct tas2552_data *data; @@ -764,7 +763,7 @@ static struct i2c_driver tas2552_i2c_driver = { .of_match_table = of_match_ptr(tas2552_of_match), .pm = &tas2552_pm, }, - .probe = tas2552_probe, + .probe_new = tas2552_probe, .remove = tas2552_i2c_remove, .id_table = tas2552_id, }; diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c index 10302552195e..e62a3da16aed 100644 --- a/sound/soc/codecs/tas2562.c +++ b/sound/soc/codecs/tas2562.c @@ -754,17 +754,27 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562) return ret; } -static int tas2562_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id tas2562_id[] = { + { "tas2562", TAS2562 }, + { "tas2563", TAS2563 }, + { "tas2564", TAS2564 }, + { "tas2110", TAS2110 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tas2562_id); + +static int tas2562_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct tas2562_data *data; int ret; + const struct i2c_device_id *id; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; + id = i2c_match_id(tas2562_id, client); data->client = client; data->dev = &client->dev; data->model_id = id->driver_data; @@ -792,15 +802,6 @@ static int tas2562_probe(struct i2c_client *client, } -static const struct i2c_device_id tas2562_id[] = { - { "tas2562", TAS2562 }, - { "tas2563", TAS2563 }, - { "tas2564", TAS2564 }, - { "tas2110", TAS2110 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tas2562_id); - #ifdef CONFIG_OF static const struct of_device_id tas2562_of_match[] = { { .compatible = "ti,tas2562", }, @@ -817,7 +818,7 @@ static struct i2c_driver tas2562_i2c_driver = { .name = "tas2562", .of_match_table = of_match_ptr(tas2562_of_match), }, - .probe = tas2562_probe, + .probe_new = tas2562_probe, .id_table = tas2562_id, }; diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index 9265af41c235..d395feffb30b 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -621,8 +621,7 @@ static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764) return 0; } -static int tas2764_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tas2764_i2c_probe(struct i2c_client *client) { struct tas2764_priv *tas2764; int result; @@ -678,7 +677,7 @@ static struct i2c_driver tas2764_i2c_driver = { .name = "tas2764", .of_match_table = of_match_ptr(tas2764_of_match), }, - .probe = tas2764_i2c_probe, + .probe_new = tas2764_i2c_probe, .id_table = tas2764_i2c_id, }; module_i2c_driver(tas2764_i2c_driver); diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index c5ea3b115966..c1dbd978d550 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -672,8 +672,7 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770) return 0; } -static int tas2770_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tas2770_i2c_probe(struct i2c_client *client) { struct tas2770_priv *tas2770; int result; @@ -739,7 +738,7 @@ static struct i2c_driver tas2770_i2c_driver = { .name = "tas2770", .of_match_table = of_match_ptr(tas2770_of_match), }, - .probe = tas2770_i2c_probe, + .probe_new = tas2770_i2c_probe, .id_table = tas2770_i2c_id, }; module_i2c_driver(tas2770_i2c_driver); diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 7831c96d0d83..5c0df3cd4832 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -911,8 +911,7 @@ static const struct regmap_config tas5086_regmap = { .reg_write = tas5086_reg_write, }; -static int tas5086_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int tas5086_i2c_probe(struct i2c_client *i2c) { struct tas5086_private *priv; struct device *dev = &i2c->dev; @@ -994,7 +993,7 @@ static struct i2c_driver tas5086_i2c_driver = { .of_match_table = of_match_ptr(tas5086_dt_ids), }, .id_table = tas5086_i2c_id, - .probe = tas5086_i2c_probe, + .probe_new = tas5086_i2c_probe, .remove = tas5086_i2c_remove, }; diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index a3e682376946..7b599664db20 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -774,9 +774,9 @@ static struct snd_soc_dai_driver tas571x_dai = { }; static const struct of_device_id tas571x_of_match[] __maybe_unused; +static const struct i2c_device_id tas571x_i2c_id[]; -static int tas571x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tas571x_i2c_probe(struct i2c_client *client) { struct tas571x_private *priv; struct device *dev = &client->dev; @@ -791,8 +791,11 @@ static int tas571x_i2c_probe(struct i2c_client *client, of_id = of_match_device(tas571x_of_match, dev); if (of_id) priv->chip = of_id->data; - else + else { + const struct i2c_device_id *id = + i2c_match_id(tas571x_i2c_id, client); priv->chip = (void *) id->driver_data; + } priv->mclk = devm_clk_get(dev, "mclk"); if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) { @@ -830,7 +833,8 @@ static int tas571x_i2c_probe(struct i2c_client *client, if (IS_ERR(priv->pdn_gpio)) { dev_err(dev, "error requesting pdn_gpio: %ld\n", PTR_ERR(priv->pdn_gpio)); - return PTR_ERR(priv->pdn_gpio); + ret = PTR_ERR(priv->pdn_gpio); + goto disable_regs; } priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", @@ -838,7 +842,8 @@ static int tas571x_i2c_probe(struct i2c_client *client, if (IS_ERR(priv->reset_gpio)) { dev_err(dev, "error requesting reset_gpio: %ld\n", PTR_ERR(priv->reset_gpio)); - return PTR_ERR(priv->reset_gpio); + ret = PTR_ERR(priv->reset_gpio); + goto disable_regs; } else if (priv->reset_gpio) { /* pulse the active low reset line for ~100us */ usleep_range(100, 200); @@ -914,7 +919,7 @@ static struct i2c_driver tas571x_i2c_driver = { .name = "tas571x", .of_match_table = of_match_ptr(tas571x_of_match), }, - .probe = tas571x_i2c_probe, + .probe_new = tas571x_i2c_probe, .remove = tas571x_i2c_remove, .id_table = tas571x_i2c_id, }; diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index 9ff644ddb470..17034abef568 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c @@ -633,12 +633,19 @@ static struct snd_soc_dai_driver tas5720_dai[] = { }, }; -static int tas5720_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id tas5720_id[] = { + { "tas5720", TAS5720 }, + { "tas5722", TAS5722 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tas5720_id); + +static int tas5720_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct tas5720_data *data; const struct regmap_config *regmap_config; + const struct i2c_device_id *id; int ret; int i; @@ -646,6 +653,7 @@ static int tas5720_probe(struct i2c_client *client, if (!data) return -ENOMEM; + id = i2c_match_id(tas5720_id, client); data->tas5720_client = client; data->devtype = id->driver_data; @@ -704,13 +712,6 @@ static int tas5720_probe(struct i2c_client *client, return 0; } -static const struct i2c_device_id tas5720_id[] = { - { "tas5720", TAS5720 }, - { "tas5722", TAS5722 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tas5720_id); - #if IS_ENABLED(CONFIG_OF) static const struct of_device_id tas5720_of_match[] = { { .compatible = "ti,tas5720", }, @@ -725,7 +726,7 @@ static struct i2c_driver tas5720_i2c_driver = { .name = "tas5720", .of_match_table = of_match_ptr(tas5720_of_match), }, - .probe = tas5720_probe, + .probe_new = tas5720_probe, .id_table = tas5720_id, }; diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c index 59543d392110..22b53856e691 100644 --- a/sound/soc/codecs/tas6424.c +++ b/sound/soc/codecs/tas6424.c @@ -682,8 +682,7 @@ static const struct of_device_id tas6424_of_ids[] = { MODULE_DEVICE_TABLE(of, tas6424_of_ids); #endif -static int tas6424_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tas6424_i2c_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct tas6424_data *tas6424; @@ -757,7 +756,7 @@ static int tas6424_i2c_probe(struct i2c_client *client, TAS6424_RESET, TAS6424_RESET); if (ret) { dev_err(dev, "unable to reset device: %d\n", ret); - return ret; + goto disable_regs; } INIT_DELAYED_WORK(&tas6424->fault_check_work, tas6424_fault_check_work); @@ -766,10 +765,14 @@ static int tas6424_i2c_probe(struct i2c_client *client, tas6424_dai, ARRAY_SIZE(tas6424_dai)); if (ret < 0) { dev_err(dev, "unable to register codec: %d\n", ret); - return ret; + goto disable_regs; } return 0; + +disable_regs: + regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies), tas6424->supplies); + return ret; } static int tas6424_i2c_remove(struct i2c_client *client) @@ -786,10 +789,8 @@ static int tas6424_i2c_remove(struct i2c_client *client) ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies), tas6424->supplies); - if (ret < 0) { + if (ret < 0) dev_err(dev, "unable to disable supplies: %d\n", ret); - return ret; - } return 0; } @@ -805,7 +806,7 @@ static struct i2c_driver tas6424_i2c_driver = { .name = "tas6424", .of_match_table = of_match_ptr(tas6424_of_ids), }, - .probe = tas6424_i2c_probe, + .probe_new = tas6424_i2c_probe, .remove = tas6424_i2c_remove, .id_table = tas6424_i2c_ids, }; diff --git a/sound/soc/codecs/tda7419.c b/sound/soc/codecs/tda7419.c index 83d220054c96..d964e5207569 100644 --- a/sound/soc/codecs/tda7419.c +++ b/sound/soc/codecs/tda7419.c @@ -571,8 +571,7 @@ static const struct snd_soc_component_driver tda7419_component_driver = { .num_dapm_routes = ARRAY_SIZE(tda7419_dapm_routes), }; -static int tda7419_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int tda7419_probe(struct i2c_client *i2c) { struct tda7419_data *tda7419; int i, ret; @@ -630,7 +629,7 @@ static struct i2c_driver tda7419_driver = { .name = "tda7419", .of_match_table = tda7419_of_match, }, - .probe = tda7419_probe, + .probe_new = tda7419_probe, .id_table = tda7419_i2c_id, }; diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c index ae18982ac310..82532ad00c3c 100644 --- a/sound/soc/codecs/tlv320adc3xxx.c +++ b/sound/soc/codecs/tlv320adc3xxx.c @@ -1152,20 +1152,20 @@ static int adc3xxx_hw_params(struct snd_pcm_substream *substream, return i; /* select data word length */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: iface_len = ADC3XXX_IFACE_16BITS; width = 16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: iface_len = ADC3XXX_IFACE_20BITS; width = 20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: iface_len = ADC3XXX_IFACE_24BITS; width = 24; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: iface_len = ADC3XXX_IFACE_32BITS; width = 32; break; @@ -1335,13 +1335,21 @@ static const struct snd_soc_component_driver soc_component_dev_adc3xxx = { .num_dapm_widgets = ARRAY_SIZE(adc3xxx_dapm_widgets), .dapm_routes = adc3xxx_intercon, .num_dapm_routes = ARRAY_SIZE(adc3xxx_intercon), + .endianness = 1, }; -static int adc3xxx_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id adc3xxx_i2c_id[] = { + { "tlv320adc3001", ADC3001 }, + { "tlv320adc3101", ADC3101 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id); + +static int adc3xxx_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct adc3xxx *adc3xxx = NULL; + const struct i2c_device_id *id; int ret; adc3xxx = devm_kzalloc(dev, sizeof(struct adc3xxx), GFP_KERNEL); @@ -1394,6 +1402,7 @@ static int adc3xxx_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, adc3xxx); + id = i2c_match_id(adc3xxx_i2c_id, i2c); adc3xxx->type = id->driver_data; /* Reset codec chip */ @@ -1436,19 +1445,12 @@ static const struct of_device_id tlv320adc3xxx_of_match[] = { }; MODULE_DEVICE_TABLE(of, tlv320adc3xxx_of_match); -static const struct i2c_device_id adc3xxx_i2c_id[] = { - { "tlv320adc3001", ADC3001 }, - { "tlv320adc3101", ADC3101 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id); - static struct i2c_driver adc3xxx_i2c_driver = { .driver = { .name = "tlv320adc3xxx-codec", .of_match_table = tlv320adc3xxx_of_match, }, - .probe = adc3xxx_i2c_probe, + .probe_new = adc3xxx_i2c_probe, .remove = adc3xxx_i2c_remove, .id_table = adc3xxx_i2c_id, }; diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 32b120d624b2..b55f0b836932 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -1083,8 +1083,14 @@ static const struct of_device_id tlv320adcx140_of_match[] = { MODULE_DEVICE_TABLE(of, tlv320adcx140_of_match); #endif -static int adcx140_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static void adcx140_disable_regulator(void *arg) +{ + struct adcx140_priv *adcx140 = arg; + + regulator_disable(adcx140->supply_areg); +} + +static int adcx140_i2c_probe(struct i2c_client *i2c) { struct adcx140_priv *adcx140; int ret; @@ -1113,6 +1119,10 @@ static int adcx140_i2c_probe(struct i2c_client *i2c, dev_err(adcx140->dev, "Failed to enable areg\n"); return ret; } + + ret = devm_add_action_or_reset(&i2c->dev, adcx140_disable_regulator, adcx140); + if (ret) + return ret; } adcx140->regmap = devm_regmap_init_i2c(i2c, &adcx140_i2c_regmap); @@ -1143,7 +1153,7 @@ static struct i2c_driver adcx140_i2c_driver = { .name = "tlv320adcx140-codec", .of_match_table = of_match_ptr(tlv320adcx140_of_match), }, - .probe = adcx140_i2c_probe, + .probe_new = adcx140_i2c_probe, .id_table = adcx140_i2c_id, }; module_i2c_driver(adcx140_i2c_driver); diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c index dbb8f969274c..1f97673a1cc0 100644 --- a/sound/soc/codecs/tlv320aic23-i2c.c +++ b/sound/soc/codecs/tlv320aic23-i2c.c @@ -16,8 +16,7 @@ #include "tlv320aic23.h" -static int tlv320aic23_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int tlv320aic23_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; @@ -48,7 +47,7 @@ static struct i2c_driver tlv320aic23_i2c_driver = { .name = "tlv320aic23-codec", .of_match_table = of_match_ptr(tlv320aic23_of_match), }, - .probe = tlv320aic23_i2c_probe, + .probe_new = tlv320aic23_i2c_probe, .id_table = tlv320aic23_id, }; diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 8331dc26bcd2..b2e59581c17a 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1628,11 +1628,24 @@ static void aic31xx_configure_ocmv(struct aic31xx_priv *priv) } } -static int aic31xx_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id aic31xx_i2c_id[] = { + { "tlv320aic310x", AIC3100 }, + { "tlv320aic311x", AIC3110 }, + { "tlv320aic3100", AIC3100 }, + { "tlv320aic3110", AIC3110 }, + { "tlv320aic3120", AIC3120 }, + { "tlv320aic3111", AIC3111 }, + { "tlv320dac3100", DAC3100 }, + { "tlv320dac3101", DAC3101 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); + +static int aic31xx_i2c_probe(struct i2c_client *i2c) { struct aic31xx_priv *aic31xx; unsigned int micbias_value = MICBIAS_2_0V; + const struct i2c_device_id *id = i2c_match_id(aic31xx_i2c_id, i2c); int i, ret; dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__, @@ -1729,26 +1742,13 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, ARRAY_SIZE(aic31xx_dai_driver)); } -static const struct i2c_device_id aic31xx_i2c_id[] = { - { "tlv320aic310x", AIC3100 }, - { "tlv320aic311x", AIC3110 }, - { "tlv320aic3100", AIC3100 }, - { "tlv320aic3110", AIC3110 }, - { "tlv320aic3120", AIC3120 }, - { "tlv320aic3111", AIC3111 }, - { "tlv320dac3100", DAC3100 }, - { "tlv320dac3101", DAC3101 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); - static struct i2c_driver aic31xx_i2c_driver = { .driver = { .name = "tlv320aic31xx-codec", .of_match_table = of_match_ptr(tlv320aic31xx_of_match), .acpi_match_table = ACPI_PTR(aic31xx_acpi_match), }, - .probe = aic31xx_i2c_probe, + .probe_new = aic31xx_i2c_probe, .id_table = aic31xx_i2c_id, }; module_i2c_driver(aic31xx_i2c_driver); diff --git a/sound/soc/codecs/tlv320aic32x4-i2c.c b/sound/soc/codecs/tlv320aic32x4-i2c.c index ed70e3d9baf2..0645239901b1 100644 --- a/sound/soc/codecs/tlv320aic32x4-i2c.c +++ b/sound/soc/codecs/tlv320aic32x4-i2c.c @@ -17,9 +17,9 @@ #include "tlv320aic32x4.h" static const struct of_device_id aic32x4_of_id[]; +static const struct i2c_device_id aic32x4_i2c_id[]; -static int aic32x4_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int aic32x4_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; struct regmap_config config; @@ -35,7 +35,10 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, oid = of_match_node(aic32x4_of_id, i2c->dev.of_node); dev_set_drvdata(&i2c->dev, (void *)oid->data); - } else if (id) { + } else { + const struct i2c_device_id *id; + + id = i2c_match_id(aic32x4_i2c_id, i2c); dev_set_drvdata(&i2c->dev, (void *)id->driver_data); } @@ -70,7 +73,7 @@ static struct i2c_driver aic32x4_i2c_driver = { .name = "tlv320aic32x4", .of_match_table = aic32x4_of_id, }, - .probe = aic32x4_i2c_probe, + .probe_new = aic32x4_i2c_probe, .remove = aic32x4_i2c_remove, .id_table = aic32x4_i2c_id, }; diff --git a/sound/soc/codecs/tlv320aic3x-i2c.c b/sound/soc/codecs/tlv320aic3x-i2c.c index 2f272bc3f5da..7bd9ce08bb7b 100644 --- a/sound/soc/codecs/tlv320aic3x-i2c.c +++ b/sound/soc/codecs/tlv320aic3x-i2c.c @@ -17,10 +17,21 @@ #include "tlv320aic3x.h" -static int aic3x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +static const struct i2c_device_id aic3x_i2c_id[] = { + { "tlv320aic3x", AIC3X_MODEL_3X }, + { "tlv320aic33", AIC3X_MODEL_33 }, + { "tlv320aic3007", AIC3X_MODEL_3007 }, + { "tlv320aic3104", AIC3X_MODEL_3104 }, + { "tlv320aic3106", AIC3X_MODEL_3106 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); + +static int aic3x_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; struct regmap_config config; + const struct i2c_device_id *id = i2c_match_id(aic3x_i2c_id, i2c); config = aic3x_regmap; config.reg_bits = 8; @@ -37,16 +48,6 @@ static int aic3x_i2c_remove(struct i2c_client *i2c) return 0; } -static const struct i2c_device_id aic3x_i2c_id[] = { - { "tlv320aic3x", AIC3X_MODEL_3X }, - { "tlv320aic33", AIC3X_MODEL_33 }, - { "tlv320aic3007", AIC3X_MODEL_3007 }, - { "tlv320aic3104", AIC3X_MODEL_3104 }, - { "tlv320aic3106", AIC3X_MODEL_3106 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); - static const struct of_device_id aic3x_of_id[] = { { .compatible = "ti,tlv320aic3x", }, { .compatible = "ti,tlv320aic33" }, @@ -62,7 +63,7 @@ static struct i2c_driver aic3x_i2c_driver = { .name = "tlv320aic3x", .of_match_table = aic3x_of_id, }, - .probe = aic3x_i2c_probe, + .probe_new = aic3x_i2c_probe, .remove = aic3x_i2c_remove, .id_table = aic3x_i2c_id, }; diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 48572d66cb3b..66f1d1cd6cf0 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1463,8 +1463,7 @@ static struct snd_soc_dai_driver dac33_dai = { .ops = &dac33_dai_ops, }; -static int dac33_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dac33_i2c_probe(struct i2c_client *client) { struct tlv320dac33_platform_data *pdata; struct tlv320dac33_priv *dac33; @@ -1566,7 +1565,7 @@ static struct i2c_driver tlv320dac33_i2c_driver = { .driver = { .name = "tlv320dac33-codec", }, - .probe = dac33_i2c_probe, + .probe_new = dac33_i2c_probe, .remove = dac33_i2c_remove, .id_table = tlv320dac33_i2c_id, }; diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index e2d7ae615c52..8c00db32996b 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -209,13 +209,20 @@ static const struct regmap_config tpa6130a2_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int tpa6130a2_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id tpa6130a2_id[] = { + { "tpa6130a2", TPA6130A2 }, + { "tpa6140a2", TPA6140A2 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tpa6130a2_id); + +static int tpa6130a2_probe(struct i2c_client *client) { struct device *dev; struct tpa6130a2_data *data; struct tpa6130a2_platform_data *pdata = client->dev.platform_data; struct device_node *np = client->dev.of_node; + const struct i2c_device_id *id; const char *regulator; unsigned int version; int ret; @@ -244,6 +251,7 @@ static int tpa6130a2_probe(struct i2c_client *client, i2c_set_clientdata(client, data); + id = i2c_match_id(tpa6130a2_id, client); data->id = id->driver_data; if (data->power_gpio >= 0) { @@ -297,13 +305,6 @@ static int tpa6130a2_probe(struct i2c_client *client, &tpa6130a2_component_driver, NULL, 0); } -static const struct i2c_device_id tpa6130a2_id[] = { - { "tpa6130a2", TPA6130A2 }, - { "tpa6140a2", TPA6140A2 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tpa6130a2_id); - #if IS_ENABLED(CONFIG_OF) static const struct of_device_id tpa6130a2_of_match[] = { { .compatible = "ti,tpa6130a2", }, @@ -318,7 +319,7 @@ static struct i2c_driver tpa6130a2_i2c_driver = { .name = "tpa6130a2", .of_match_table = of_match_ptr(tpa6130a2_of_match), }, - .probe = tpa6130a2_probe, + .probe_new = tpa6130a2_probe, .id_table = tpa6130a2_id, }; diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index 962f5d48378a..d8ab0810fceb 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c @@ -282,8 +282,7 @@ static int ts3a227e_parse_device_property(struct ts3a227e *ts3a227e, return 0; } -static int ts3a227e_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ts3a227e_i2c_probe(struct i2c_client *i2c) { struct ts3a227e *ts3a227e; struct device *dev = &i2c->dev; @@ -389,7 +388,7 @@ static struct i2c_driver ts3a227e_driver = { .of_match_table = of_match_ptr(ts3a227e_of_match), .acpi_match_table = ACPI_PTR(ts3a227e_acpi_match), }, - .probe = ts3a227e_i2c_probe, + .probe_new = ts3a227e_i2c_probe, .id_table = ts3a227e_i2c_ids, }; module_i2c_driver(ts3a227e_driver); diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c index 5b63e017a43b..4fb0bb01bcdc 100644 --- a/sound/soc/codecs/tscs42xx.c +++ b/sound/soc/codecs/tscs42xx.c @@ -1409,8 +1409,7 @@ static const struct reg_sequence tscs42xx_patch[] = { static char const * const src_names[TSCS42XX_PLL_SRC_CNT] = { "xtal", "mclk1", "mclk2"}; -static int tscs42xx_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int tscs42xx_i2c_probe(struct i2c_client *i2c) { struct tscs42xx *tscs42xx; int src; @@ -1505,7 +1504,7 @@ static struct i2c_driver tscs42xx_i2c_driver = { .name = "tscs42xx", .of_match_table = tscs42xx_of_match, }, - .probe = tscs42xx_i2c_probe, + .probe_new = tscs42xx_i2c_probe, .id_table = tscs42xx_i2c_id, }; diff --git a/sound/soc/codecs/tscs454.c b/sound/soc/codecs/tscs454.c index 7e1826d6f06f..38622bc247fc 100644 --- a/sound/soc/codecs/tscs454.c +++ b/sound/soc/codecs/tscs454.c @@ -3120,18 +3120,17 @@ static int set_aif_sample_format(struct snd_soc_component *component, unsigned int width; int ret; - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (snd_pcm_format_width(format)) { + case 16: width = FV_WL_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: width = FV_WL_20; break; - case SNDRV_PCM_FORMAT_S24_3LE: + case 24: width = FV_WL_24; break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S32_LE: + case 32: width = FV_WL_32; break; default: @@ -3326,6 +3325,7 @@ static const struct snd_soc_component_driver soc_component_dev_tscs454 = { .num_dapm_routes = ARRAY_SIZE(tscs454_intercon), .controls = tscs454_snd_controls, .num_controls = ARRAY_SIZE(tscs454_snd_controls), + .endianness = 1, }; #define TSCS454_RATES SNDRV_PCM_RATE_8000_96000 @@ -3400,8 +3400,7 @@ static struct snd_soc_dai_driver tscs454_dais[] = { static char const * const src_names[] = { "xtal", "mclk1", "mclk2", "bclk"}; -static int tscs454_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int tscs454_i2c_probe(struct i2c_client *i2c) { struct tscs454 *tscs454; int src; @@ -3474,7 +3473,7 @@ static struct i2c_driver tscs454_i2c_driver = { .name = "tscs454", .of_match_table = tscs454_of_match, }, - .probe = tscs454_i2c_probe, + .probe_new = tscs454_i2c_probe, .id_table = tscs454_i2c_id, }; diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 13060a9a2388..b5004842520b 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -739,8 +739,7 @@ static const struct snd_soc_component_driver soc_component_dev_uda1380 = { .non_legacy_dai_naming = 1, }; -static int uda1380_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int uda1380_i2c_probe(struct i2c_client *i2c) { struct uda1380_platform_data *pdata = i2c->dev.platform_data; struct uda1380_priv *uda1380; @@ -800,7 +799,7 @@ static struct i2c_driver uda1380_i2c_driver = { .name = "uda1380-codec", .of_match_table = uda1380_of_match, }, - .probe = uda1380_i2c_probe, + .probe_new = uda1380_i2c_probe, .id_table = uda1380_i2c_id, }; diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 1e60db4056ad..617a36a89dfe 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -4924,6 +4924,7 @@ static const struct snd_soc_component_driver wcd9335_component_drv = { .num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets), .dapm_routes = wcd9335_audio_map, .num_dapm_routes = ARRAY_SIZE(wcd9335_audio_map), + .endianness = 1, }; static int wcd9335_probe(struct wcd9335_codec *wcd) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index 6298ebe96e94..f56907d0942d 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -5847,6 +5847,7 @@ static const struct snd_soc_component_driver wcd934x_component_drv = { .dapm_routes = wcd934x_audio_map, .num_dapm_routes = ARRAY_SIZE(wcd934x_audio_map), .set_jack = wcd934x_codec_set_jack, + .endianness = 1, }; static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 898b2887fa63..c1b61b997f69 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -4168,6 +4168,7 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd938x = { .dapm_routes = wcd938x_audio_map, .num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map), .set_jack = wcd938x_codec_set_jack, + .endianness = 1, }; static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd) diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index d6ffe99550fe..b6366dea15a6 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c @@ -192,8 +192,7 @@ static void wm1250_ev1_free(struct i2c_client *i2c) gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios)); } -static int wm1250_ev1_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int wm1250_ev1_probe(struct i2c_client *i2c) { int id, board, rev, ret; @@ -247,7 +246,7 @@ static struct i2c_driver wm1250_ev1_i2c_driver = { .driver = { .name = "wm1250-ev1", }, - .probe = wm1250_ev1_probe, + .probe_new = wm1250_ev1_probe, .remove = wm1250_ev1_remove, .id_table = wm1250_ev1_i2c_id, }; diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 72e165cc6443..ede5f2a982a6 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -536,7 +536,7 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, { struct i2c_client *i2c = wm2000->i2c; int i, j; - int ret; + int ret = 0; if (wm2000->anc_mode == mode) return 0; @@ -566,13 +566,13 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, ret = anc_transitions[i].step[j](i2c, anc_transitions[i].analogue); if (ret != 0) - return ret; + break; } if (anc_transitions[i].dest == ANC_OFF) clk_disable_unprepare(wm2000->mclk); - return 0; + return ret; } static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) @@ -803,12 +803,10 @@ 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, - .endianness = 1, .non_legacy_dai_naming = 1, }; -static int wm2000_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int wm2000_i2c_probe(struct i2c_client *i2c) { struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; @@ -941,7 +939,7 @@ static struct i2c_driver wm2000_i2c_driver = { .driver = { .name = "wm2000", }, - .probe = wm2000_i2c_probe, + .probe_new = wm2000_i2c_probe, .id_table = wm2000_i2c_id, }; diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 8863b533f9c4..1cd544580c83 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -2176,8 +2176,7 @@ static const unsigned int wm2200_mic_ctrl_reg[] = { WM2200_IN3L_CONTROL, }; -static int wm2200_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm2200_i2c_probe(struct i2c_client *i2c) { struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm2200_priv *wm2200; @@ -2489,7 +2488,7 @@ static struct i2c_driver wm2200_i2c_driver = { .name = "wm2200", .pm = &wm2200_pm, }, - .probe = wm2200_i2c_probe, + .probe_new = wm2200_i2c_probe, .remove = wm2200_i2c_remove, .id_table = wm2200_i2c_id, }; diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 9cab01ee4ee9..a89870918174 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2411,8 +2411,7 @@ static const unsigned int wm5100_mic_ctrl_reg[] = { WM5100_IN4L_CONTROL, }; -static int wm5100_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm5100_i2c_probe(struct i2c_client *i2c) { struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm5100_priv *wm5100; @@ -2713,7 +2712,7 @@ static struct i2c_driver wm5100_i2c_driver = { .name = "wm5100", .pm = &wm5100_pm, }, - .probe = wm5100_i2c_probe, + .probe_new = wm5100_i2c_probe, .remove = wm5100_i2c_remove, .id_table = wm5100_i2c_id, }; diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index a18e2290b8c8..c6439d25006b 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -646,8 +646,7 @@ static struct spi_driver wm8510_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8510_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8510_i2c_probe(struct i2c_client *i2c) { struct wm8510_priv *wm8510; int ret; @@ -680,7 +679,7 @@ static struct i2c_driver wm8510_i2c_driver = { .name = "wm8510", .of_match_table = wm8510_of_match, }, - .probe = wm8510_i2c_probe, + .probe_new = wm8510_i2c_probe, .id_table = wm8510_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index c8b50aac6c18..ba35a0221dc8 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -443,8 +443,7 @@ static const struct regmap_config wm8523_regmap = { .volatile_reg = wm8523_volatile_register, }; -static int wm8523_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8523_i2c_probe(struct i2c_client *i2c) { struct wm8523_priv *wm8523; unsigned int val; @@ -529,7 +528,7 @@ static struct i2c_driver wm8523_i2c_driver = { .name = "wm8523", .of_match_table = wm8523_of_match, }, - .probe = wm8523_i2c_probe, + .probe_new = wm8523_i2c_probe, .id_table = wm8523_i2c_id, }; diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 85ad2f03cfd0..84020195314d 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -996,8 +996,7 @@ static const struct of_device_id wm8580_of_match[] = { }; MODULE_DEVICE_TABLE(of, wm8580_of_match); -static int wm8580_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8580_i2c_probe(struct i2c_client *i2c) { const struct of_device_id *of_id; struct wm8580_priv *wm8580; @@ -1051,7 +1050,7 @@ static struct i2c_driver wm8580_i2c_driver = { .name = "wm8580", .of_match_table = wm8580_of_match, }, - .probe = wm8580_i2c_probe, + .probe_new = wm8580_i2c_probe, .id_table = wm8580_i2c_id, }; diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index bc4d161c59e5..b68a1ebcd061 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -432,8 +432,7 @@ static struct spi_driver wm8711_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8711_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int wm8711_i2c_probe(struct i2c_client *client) { struct wm8711_priv *wm8711; int ret; @@ -466,7 +465,7 @@ static struct i2c_driver wm8711_i2c_driver = { .name = "wm8711", .of_match_table = wm8711_of_match, }, - .probe = wm8711_i2c_probe, + .probe_new = wm8711_i2c_probe, .id_table = wm8711_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 2cd58d133899..119ff0a1bb35 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -273,8 +273,7 @@ static struct spi_driver wm8728_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8728_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8728_i2c_probe(struct i2c_client *i2c) { struct wm8728_priv *wm8728; int ret; @@ -307,7 +306,7 @@ static struct i2c_driver wm8728_i2c_driver = { .name = "wm8728", .of_match_table = wm8728_of_match, }, - .probe = wm8728_i2c_probe, + .probe_new = wm8728_i2c_probe, .id_table = wm8728_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8731-i2c.c b/sound/soc/codecs/wm8731-i2c.c new file mode 100644 index 000000000000..fdf03bf91606 --- /dev/null +++ b/sound/soc/codecs/wm8731-i2c.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * wm8731-i2c.c -- WM8731 ALSA SoC Audio driver I2C code + * + * Copyright 2005 Openedhand Ltd. + * Copyright 2006-12 Wolfson Microelectronics, plc + * + * Author: Richard Purdie <richard@openedhand.com> + * + * Based on wm8753.c by Liam Girdwood + */ + +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of_device.h> + +#include "wm8731.h" + + +static const struct of_device_id wm8731_of_match[] = { + { .compatible = "wlf,wm8731", }, + { } +}; +MODULE_DEVICE_TABLE(of, wm8731_of_match); + +static int wm8731_i2c_probe(struct i2c_client *i2c) +{ + struct wm8731_priv *wm8731; + int ret; + + wm8731 = devm_kzalloc(&i2c->dev, sizeof(struct wm8731_priv), + GFP_KERNEL); + if (wm8731 == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, wm8731); + + wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); + if (IS_ERR(wm8731->regmap)) { + ret = PTR_ERR(wm8731->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + return wm8731_init(&i2c->dev, wm8731); +} + +static const struct i2c_device_id wm8731_i2c_id[] = { + { "wm8731", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); + +static struct i2c_driver wm8731_i2c_driver = { + .driver = { + .name = "wm8731", + .of_match_table = wm8731_of_match, + }, + .probe_new = wm8731_i2c_probe, + .id_table = wm8731_i2c_id, +}; + +module_i2c_driver(wm8731_i2c_driver); + +MODULE_DESCRIPTION("ASoC WM8731 driver - I2C"); +MODULE_AUTHOR("Richard Purdie"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8731-spi.c b/sound/soc/codecs/wm8731-spi.c new file mode 100644 index 000000000000..542ed097d89a --- /dev/null +++ b/sound/soc/codecs/wm8731-spi.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * wm8731.c -- WM8731 ALSA SoC Audio driver + * + * Copyright 2005 Openedhand Ltd. + * Copyright 2006-12 Wolfson Microelectronics, plc + * + * Author: Richard Purdie <richard@openedhand.com> + * + * Based on wm8753.c by Liam Girdwood + */ + +#include <linux/spi/spi.h> +#include <linux/module.h> +#include <linux/of_device.h> + +#include "wm8731.h" + +static const struct of_device_id wm8731_of_match[] = { + { .compatible = "wlf,wm8731", }, + { } +}; +MODULE_DEVICE_TABLE(of, wm8731_of_match); + +static int wm8731_spi_probe(struct spi_device *spi) +{ + struct wm8731_priv *wm8731; + int ret; + + wm8731 = devm_kzalloc(&spi->dev, sizeof(*wm8731), GFP_KERNEL); + if (wm8731 == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, wm8731); + + wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); + if (IS_ERR(wm8731->regmap)) { + ret = PTR_ERR(wm8731->regmap); + dev_err(&spi->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + return wm8731_init(&spi->dev, wm8731); +} + +static struct spi_driver wm8731_spi_driver = { + .driver = { + .name = "wm8731", + .of_match_table = wm8731_of_match, + }, + .probe = wm8731_spi_probe, +}; + +module_spi_driver(wm8731_spi_driver); + +MODULE_DESCRIPTION("ASoC WM8731 driver - SPI"); +MODULE_AUTHOR("Richard Purdie"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index b14c6d104e6d..2408c4a591d5 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -15,13 +15,9 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/pm.h> -#include <linux/i2c.h> #include <linux/slab.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> -#include <linux/spi/spi.h> -#include <linux/of_device.h> -#include <linux/mutex.h> #include <linux/clk.h> #include <sound/core.h> #include <sound/pcm.h> @@ -32,7 +28,6 @@ #include "wm8731.h" -#define WM8731_NUM_SUPPLIES 4 static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { "AVDD", "HPVDD", @@ -40,21 +35,6 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { "DBVDD", }; -/* codec private data */ -struct wm8731_priv { - struct regmap *regmap; - struct clk *mclk; - struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; - const struct snd_pcm_hw_constraint_list *constraints; - unsigned int sysclk; - int sysclk_type; - int playback_fs; - bool deemph; - - struct mutex lock; -}; - - /* * wm8731 register cache */ @@ -429,12 +409,11 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_component *component = codec_dai->component; u16 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; @@ -570,59 +549,6 @@ static struct snd_soc_dai_driver wm8731_dai = { .symmetric_rate = 1, }; -static int wm8731_request_supplies(struct device *dev, - struct wm8731_priv *wm8731) -{ - int ret = 0, i; - - for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) - wm8731->supplies[i].supply = wm8731_supply_names[i]; - - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8731->supplies), - wm8731->supplies); - if (ret != 0) { - dev_err(dev, "Failed to request supplies: %d\n", ret); - return ret; - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), - wm8731->supplies); - if (ret != 0) { - dev_err(dev, "Failed to enable supplies: %d\n", ret); - return ret; - } - - return 0; -} - -static int wm8731_hw_init(struct device *dev, struct wm8731_priv *wm8731) -{ - int ret = 0; - - ret = wm8731_reset(wm8731->regmap); - if (ret < 0) { - dev_err(dev, "Failed to issue reset: %d\n", ret); - goto err; - } - - /* Clear POWEROFF, keep everything else disabled */ - regmap_write(wm8731->regmap, WM8731_PWR, 0x7f); - - /* Latch the update bits */ - regmap_update_bits(wm8731->regmap, WM8731_LOUT1V, 0x100, 0); - regmap_update_bits(wm8731->regmap, WM8731_ROUT1V, 0x100, 0); - regmap_update_bits(wm8731->regmap, WM8731_LINVOL, 0x100, 0); - regmap_update_bits(wm8731->regmap, WM8731_RINVOL, 0x100, 0); - - /* Disable bypass path by default */ - regmap_update_bits(wm8731->regmap, WM8731_APANA, 0x8, 0); - - regcache_mark_dirty(wm8731->regmap); - -err: - return ret; -} - static const struct snd_soc_component_driver soc_component_dev_wm8731 = { .set_bias_level = wm8731_set_bias_level, .controls = wm8731_snd_controls, @@ -638,136 +564,65 @@ static const struct snd_soc_component_driver soc_component_dev_wm8731 = { .non_legacy_dai_naming = 1, }; -static const struct of_device_id wm8731_of_match[] = { - { .compatible = "wlf,wm8731", }, - { } -}; - -MODULE_DEVICE_TABLE(of, wm8731_of_match); - -static const struct regmap_config wm8731_regmap = { - .reg_bits = 7, - .val_bits = 9, - - .max_register = WM8731_RESET, - .volatile_reg = wm8731_volatile, - - .cache_type = REGCACHE_RBTREE, - .reg_defaults = wm8731_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults), -}; - -#if defined(CONFIG_SPI_MASTER) -static int wm8731_spi_probe(struct spi_device *spi) +int wm8731_init(struct device *dev, struct wm8731_priv *wm8731) { - struct wm8731_priv *wm8731; - int ret; - - wm8731 = devm_kzalloc(&spi->dev, sizeof(*wm8731), GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; + int ret = 0, i; - wm8731->mclk = devm_clk_get(&spi->dev, "mclk"); + wm8731->mclk = devm_clk_get(dev, "mclk"); if (IS_ERR(wm8731->mclk)) { ret = PTR_ERR(wm8731->mclk); if (ret == -ENOENT) { wm8731->mclk = NULL; - dev_warn(&spi->dev, "Assuming static MCLK\n"); + dev_warn(dev, "Assuming static MCLK\n"); } else { - dev_err(&spi->dev, "Failed to get MCLK: %d\n", - ret); + dev_err(dev, "Failed to get MCLK: %d\n", ret); return ret; } } mutex_init(&wm8731->lock); - spi_set_drvdata(spi, wm8731); - - ret = wm8731_request_supplies(&spi->dev, wm8731); - if (ret != 0) - return ret; + for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) + wm8731->supplies[i].supply = wm8731_supply_names[i]; - wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); - if (IS_ERR(wm8731->regmap)) { - ret = PTR_ERR(wm8731->regmap); - dev_err(&spi->dev, "Failed to allocate register map: %d\n", - ret); + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8731->supplies), + wm8731->supplies); + if (ret != 0) { + dev_err(dev, "Failed to request supplies: %d\n", ret); return ret; } - ret = wm8731_hw_init(&spi->dev, wm8731); - if (ret != 0) - return ret; - - ret = devm_snd_soc_register_component(&spi->dev, - &soc_component_dev_wm8731, &wm8731_dai, 1); + ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), + wm8731->supplies); if (ret != 0) { - dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); + dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } - return 0; -} - -static struct spi_driver wm8731_spi_driver = { - .driver = { - .name = "wm8731", - .of_match_table = wm8731_of_match, - }, - .probe = wm8731_spi_probe, -}; -#endif /* CONFIG_SPI_MASTER */ - -#if IS_ENABLED(CONFIG_I2C) -static int wm8731_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8731_priv *wm8731; - int ret; - - wm8731 = devm_kzalloc(&i2c->dev, sizeof(struct wm8731_priv), - GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; - - wm8731->mclk = devm_clk_get(&i2c->dev, "mclk"); - if (IS_ERR(wm8731->mclk)) { - ret = PTR_ERR(wm8731->mclk); - if (ret == -ENOENT) { - wm8731->mclk = NULL; - dev_warn(&i2c->dev, "Assuming static MCLK\n"); - } else { - dev_err(&i2c->dev, "Failed to get MCLK: %d\n", - ret); - return ret; - } + ret = wm8731_reset(wm8731->regmap); + if (ret < 0) { + dev_err(dev, "Failed to issue reset: %d\n", ret); + goto err_regulator_enable; } - mutex_init(&wm8731->lock); - - i2c_set_clientdata(i2c, wm8731); + /* Clear POWEROFF, keep everything else disabled */ + regmap_write(wm8731->regmap, WM8731_PWR, 0x7f); - ret = wm8731_request_supplies(&i2c->dev, wm8731); - if (ret != 0) - return ret; + /* Latch the update bits */ + regmap_update_bits(wm8731->regmap, WM8731_LOUT1V, 0x100, 0); + regmap_update_bits(wm8731->regmap, WM8731_ROUT1V, 0x100, 0); + regmap_update_bits(wm8731->regmap, WM8731_LINVOL, 0x100, 0); + regmap_update_bits(wm8731->regmap, WM8731_RINVOL, 0x100, 0); - wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); - if (IS_ERR(wm8731->regmap)) { - ret = PTR_ERR(wm8731->regmap); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", - ret); - goto err_regulator_enable; - } + /* Disable bypass path by default */ + regmap_update_bits(wm8731->regmap, WM8731_APANA, 0x8, 0); - ret = wm8731_hw_init(&i2c->dev, wm8731); - if (ret != 0) - goto err_regulator_enable; + regcache_mark_dirty(wm8731->regmap); - ret = devm_snd_soc_register_component(&i2c->dev, + ret = devm_snd_soc_register_component(dev, &soc_component_dev_wm8731, &wm8731_dai, 1); if (ret != 0) { - dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + dev_err(dev, "Failed to register CODEC: %d\n", ret); goto err_regulator_enable; } @@ -779,54 +634,20 @@ err_regulator_enable: return ret; } +EXPORT_SYMBOL_GPL(wm8731_init); -static const struct i2c_device_id wm8731_i2c_id[] = { - { "wm8731", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); - -static struct i2c_driver wm8731_i2c_driver = { - .driver = { - .name = "wm8731", - .of_match_table = wm8731_of_match, - }, - .probe = wm8731_i2c_probe, - .id_table = wm8731_i2c_id, -}; -#endif +const struct regmap_config wm8731_regmap = { + .reg_bits = 7, + .val_bits = 9, -static int __init wm8731_modinit(void) -{ - int ret = 0; -#if IS_ENABLED(CONFIG_I2C) - ret = i2c_add_driver(&wm8731_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n", - ret); - } -#endif -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8731_spi_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n", - ret); - } -#endif - return ret; -} -module_init(wm8731_modinit); + .max_register = WM8731_RESET, + .volatile_reg = wm8731_volatile, -static void __exit wm8731_exit(void) -{ -#if IS_ENABLED(CONFIG_I2C) - i2c_del_driver(&wm8731_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8731_spi_driver); -#endif -} -module_exit(wm8731_exit); + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8731_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults), +}; +EXPORT_SYMBOL_GPL(wm8731_regmap); MODULE_DESCRIPTION("ASoC WM8731 driver"); MODULE_AUTHOR("Richard Purdie"); diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h index 4fcf1226d7c2..8d5a7a9ca6b2 100644 --- a/sound/soc/codecs/wm8731.h +++ b/sound/soc/codecs/wm8731.h @@ -12,6 +12,13 @@ #ifndef _WM8731_H #define _WM8731_H +#include <linux/mutex.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> + +struct clk; +struct snd_pcm_hw_constraint_list; + /* WM8731 register space */ #define WM8731_LINVOL 0x00 @@ -33,4 +40,24 @@ #define WM8731_DAI 0 +#define WM8731_NUM_SUPPLIES 4 + +/* codec private data */ +struct wm8731_priv { + struct regmap *regmap; + struct clk *mclk; + struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; + const struct snd_pcm_hw_constraint_list *constraints; + unsigned int sysclk; + int sysclk_type; + int playback_fs; + bool deemph; + + struct mutex lock; +}; + +extern const struct regmap_config wm8731_regmap; + +int wm8731_init(struct device *dev, struct wm8731_priv *wm8731); + #endif diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 7a3f9fbe8d53..5778091d1c09 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -606,8 +606,7 @@ static const struct regmap_config wm8737_regmap = { }; #if IS_ENABLED(CONFIG_I2C) -static int wm8737_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8737_i2c_probe(struct i2c_client *i2c) { struct wm8737_priv *wm8737; int ret, i; @@ -651,7 +650,7 @@ static struct i2c_driver wm8737_i2c_driver = { .name = "wm8737", .of_match_table = wm8737_of_match, }, - .probe = wm8737_i2c_probe, + .probe_new = wm8737_i2c_probe, .id_table = wm8737_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 0e3994326936..871e2c5421b8 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -565,8 +565,7 @@ static int wm8741_set_pdata(struct device *dev, struct wm8741_priv *wm8741) } #if IS_ENABLED(CONFIG_I2C) -static int wm8741_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8741_i2c_probe(struct i2c_client *i2c) { struct wm8741_priv *wm8741; int ret, i; @@ -618,7 +617,7 @@ static struct i2c_driver wm8741_i2c_driver = { .name = "wm8741", .of_match_table = wm8741_of_match, }, - .probe = wm8741_i2c_probe, + .probe_new = wm8741_i2c_probe, .id_table = wm8741_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 9491817020d8..1426fc1f7c5a 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -780,8 +780,7 @@ static struct spi_driver wm8750_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8750_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8750_i2c_probe(struct i2c_client *i2c) { struct wm8750_priv *wm8750; struct regmap *regmap; @@ -815,7 +814,7 @@ static struct i2c_driver wm8750_i2c_driver = { .name = "wm8750", .of_match_table = wm8750_of_match, }, - .probe = wm8750_i2c_probe, + .probe_new = wm8750_i2c_probe, .id_table = wm8750_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index deaa54be6268..931134d334ec 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1552,8 +1552,7 @@ static struct spi_driver wm8753_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8753_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8753_i2c_probe(struct i2c_client *i2c) { struct wm8753_priv *wm8753; int ret; @@ -1592,7 +1591,7 @@ static struct i2c_driver wm8753_i2c_driver = { .name = "wm8753", .of_match_table = wm8753_of_match, }, - .probe = wm8753_i2c_probe, + .probe_new = wm8753_i2c_probe, .id_table = wm8753_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 554acf56130c..f164cb6744c4 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -490,8 +490,7 @@ static struct spi_driver wm8776_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8776_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8776_i2c_probe(struct i2c_client *i2c) { struct wm8776_priv *wm8776; int ret; @@ -525,7 +524,7 @@ static struct i2c_driver wm8776_i2c_driver = { .name = "wm8776", .of_match_table = wm8776_of_match, }, - .probe = wm8776_i2c_probe, + .probe_new = wm8776_i2c_probe, .id_table = wm8776_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8804-i2c.c b/sound/soc/codecs/wm8804-i2c.c index f97a75e64166..04dc9fb5afb4 100644 --- a/sound/soc/codecs/wm8804-i2c.c +++ b/sound/soc/codecs/wm8804-i2c.c @@ -14,8 +14,7 @@ #include "wm8804.h" -static int wm8804_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8804_i2c_probe(struct i2c_client *i2c) { struct regmap *regmap; @@ -62,7 +61,7 @@ static struct i2c_driver wm8804_i2c_driver = { .of_match_table = of_match_ptr(wm8804_of_match), .acpi_match_table = ACPI_PTR(wm8804_acpi_match), }, - .probe = wm8804_i2c_probe, + .probe_new = wm8804_i2c_probe, .remove = wm8804_i2c_remove, .id_table = wm8804_i2c_id }; diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index bf3a4415a85f..84a3daf0c11e 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1261,8 +1261,7 @@ static struct spi_driver wm8900_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8900_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8900_i2c_probe(struct i2c_client *i2c) { struct wm8900_priv *wm8900; int ret; @@ -1299,7 +1298,7 @@ static struct i2c_driver wm8900_i2c_driver = { .driver = { .name = "wm8900", }, - .probe = wm8900_i2c_probe, + .probe_new = wm8900_i2c_probe, .remove = wm8900_i2c_remove, .id_table = wm8900_i2c_id, }; diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 75f30154c809..3c95c2aea515 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1981,8 +1981,7 @@ static int wm8903_set_pdata_from_of(struct i2c_client *i2c, return 0; } -static int wm8903_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8903_i2c_probe(struct i2c_client *i2c) { struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); struct wm8903_priv *wm8903; @@ -2132,7 +2131,7 @@ static int wm8903_i2c_probe(struct i2c_client *i2c, if (ret != 0) { dev_err(wm8903->dev, "Failed to request IRQ: %d\n", ret); - return ret; + goto err; } /* Enable write sequencer interrupts */ @@ -2214,7 +2213,7 @@ static struct i2c_driver wm8903_i2c_driver = { .name = "wm8903", .of_match_table = wm8903_of_match, }, - .probe = wm8903_i2c_probe, + .probe_new = wm8903_i2c_probe, .remove = wm8903_i2c_remove, .id_table = wm8903_i2c_id, }; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index a02a77fef360..04bb8e392497 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2162,8 +2162,9 @@ static const struct of_device_id wm8904_of_match[] = { MODULE_DEVICE_TABLE(of, wm8904_of_match); #endif -static int wm8904_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id wm8904_i2c_id[]; + +static int wm8904_i2c_probe(struct i2c_client *i2c) { struct wm8904_priv *wm8904; unsigned int val; @@ -2197,6 +2198,8 @@ static int wm8904_i2c_probe(struct i2c_client *i2c, return -EINVAL; wm8904->devtype = (enum wm8904_type)match->data; } else { + const struct i2c_device_id *id = + i2c_match_id(wm8904_i2c_id, i2c); wm8904->devtype = id->driver_data; } @@ -2328,7 +2331,7 @@ static struct i2c_driver wm8904_i2c_driver = { .name = "wm8904", .of_match_table = of_match_ptr(wm8904_of_match), }, - .probe = wm8904_i2c_probe, + .probe_new = wm8904_i2c_probe, .id_table = wm8904_i2c_id, }; diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 440d048ef0c0..589394d420ce 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -750,8 +750,7 @@ static const struct regmap_config wm8940_regmap = { .volatile_reg = wm8940_volatile_register, }; -static int wm8940_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8940_i2c_probe(struct i2c_client *i2c) { struct wm8940_priv *wm8940; int ret; @@ -779,11 +778,18 @@ static const struct i2c_device_id wm8940_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id); +static const struct of_device_id wm8940_of_match[] = { + { .compatible = "wlf,wm8940", }, + { } +}; +MODULE_DEVICE_TABLE(of, wm8940_of_match); + static struct i2c_driver wm8940_i2c_driver = { .driver = { .name = "wm8940", + .of_match_table = wm8940_of_match, }, - .probe = wm8940_i2c_probe, + .probe_new = wm8940_i2c_probe, .id_table = wm8940_i2c_id, }; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 513df47bd87d..80e3cbd704ee 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -968,8 +968,7 @@ static const struct regmap_config wm8955_regmap = { .num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults), }; -static int wm8955_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8955_i2c_probe(struct i2c_client *i2c) { struct wm8955_priv *wm8955; int ret; @@ -1005,7 +1004,7 @@ static struct i2c_driver wm8955_i2c_driver = { .driver = { .name = "wm8955", }, - .probe = wm8955_i2c_probe, + .probe_new = wm8955_i2c_probe, .id_table = wm8955_i2c_id, }; diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index ca7660f4bb05..8c8f32b23083 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -14,6 +14,7 @@ #include <linux/pm.h> #include <linux/clk.h> #include <linux/i2c.h> +#include <linux/acpi.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -1410,8 +1411,7 @@ static void wm8960_set_pdata_from_of(struct i2c_client *i2c, ARRAY_SIZE(pdata->hp_cfg)); } -static int wm8960_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8960_i2c_probe(struct i2c_client *i2c) { struct wm8960_data *pdata = dev_get_platdata(&i2c->dev); struct wm8960_priv *wm8960; @@ -1498,18 +1498,30 @@ static const struct i2c_device_id wm8960_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id); +#if defined(CONFIG_OF) static const struct of_device_id wm8960_of_match[] = { { .compatible = "wlf,wm8960", }, { } }; MODULE_DEVICE_TABLE(of, wm8960_of_match); +#endif + +#if defined(CONFIG_ACPI) +static const struct acpi_device_id wm8960_acpi_match[] = { + { "1AEC8960", 0 }, /* Wolfson PCI ID + part ID */ + { "10138960", 0 }, /* Cirrus Logic PCI ID + part ID */ + { }, +}; +MODULE_DEVICE_TABLE(acpi, wm8960_acpi_match); +#endif static struct i2c_driver wm8960_i2c_driver = { .driver = { .name = "wm8960", - .of_match_table = wm8960_of_match, + .of_match_table = of_match_ptr(wm8960_of_match), + .acpi_match_table = ACPI_PTR(wm8960_acpi_match), }, - .probe = wm8960_i2c_probe, + .probe_new = wm8960_i2c_probe, .remove = wm8960_i2c_remove, .id_table = wm8960_i2c_id, }; diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index ef80d9fc1eec..69eb731dbf4b 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -911,8 +911,7 @@ static const struct regmap_config wm8961_regmap = { .readable_reg = wm8961_readable, }; -static int wm8961_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8961_i2c_probe(struct i2c_client *i2c) { struct wm8961_priv *wm8961; unsigned int val; @@ -977,7 +976,7 @@ static struct i2c_driver wm8961_i2c_driver = { .driver = { .name = "wm8961", }, - .probe = wm8961_i2c_probe, + .probe_new = wm8961_i2c_probe, .id_table = wm8961_i2c_id, }; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 2c41d31956aa..34cd5a2a997c 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2896,9 +2896,8 @@ static int wm8962_set_fll(struct snd_soc_component *component, int fll_id, int s reinit_completion(&wm8962->fll_lock); - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0) { - pm_runtime_put_noidle(component->dev); dev_err(component->dev, "Failed to resume device: %d\n", ret); return ret; } @@ -3030,9 +3029,8 @@ static irqreturn_t wm8962_irq(int irq, void *data) unsigned int active; int reg, ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { - pm_runtime_put_noidle(dev); dev_err(dev, "Failed to resume: %d\n", ret); return IRQ_NONE; } @@ -3555,8 +3553,7 @@ static int wm8962_set_pdata_from_of(struct i2c_client *i2c, return PTR_ERR_OR_ZERO(pdata->mclk); } -static int wm8962_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8962_i2c_probe(struct i2c_client *i2c) { struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm8962_priv *wm8962; @@ -3892,7 +3889,7 @@ static struct i2c_driver wm8962_i2c_driver = { .of_match_table = wm8962_of_match, .pm = &wm8962_pm, }, - .probe = wm8962_i2c_probe, + .probe_new = wm8962_i2c_probe, .remove = wm8962_i2c_remove, .id_table = wm8962_i2c_id, }; diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index ddf0e2f5e66a..8a289b048e66 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -672,8 +672,7 @@ static const struct regmap_config wm8971_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int wm8971_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8971_i2c_probe(struct i2c_client *i2c) { struct wm8971_priv *wm8971; @@ -702,7 +701,7 @@ static struct i2c_driver wm8971_i2c_driver = { .driver = { .name = "wm8971", }, - .probe = wm8971_i2c_probe, + .probe_new = wm8971_i2c_probe, .id_table = wm8971_i2c_id, }; diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index fdc68ab49742..a8d7809f3f64 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -685,8 +685,7 @@ static const struct snd_soc_component_driver soc_component_dev_wm8974 = { .non_legacy_dai_naming = 1, }; -static int wm8974_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8974_i2c_probe(struct i2c_client *i2c) { struct wm8974_priv *priv; struct regmap *regmap; @@ -725,7 +724,7 @@ static struct i2c_driver wm8974_i2c_driver = { .name = "wm8974", .of_match_table = wm8974_of_match, }, - .probe = wm8974_i2c_probe, + .probe_new = wm8974_i2c_probe, .id_table = wm8974_i2c_id, }; diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 7091e1a9d516..141f50bfec68 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -1020,8 +1020,7 @@ static const struct regmap_config wm8978_regmap_config = { .num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults), }; -static int wm8978_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8978_i2c_probe(struct i2c_client *i2c) { struct wm8978_priv *wm8978; int ret; @@ -1074,7 +1073,7 @@ static struct i2c_driver wm8978_i2c_driver = { .name = "wm8978", .of_match_table = wm8978_of_match, }, - .probe = wm8978_i2c_probe, + .probe_new = wm8978_i2c_probe, .id_table = wm8978_i2c_id, }; diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index d8ed22a9caac..ae89554d47bc 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -1035,8 +1035,7 @@ static struct spi_driver wm8983_spi_driver = { #endif #if IS_ENABLED(CONFIG_I2C) -static int wm8983_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8983_i2c_probe(struct i2c_client *i2c) { struct wm8983_priv *wm8983; int ret; @@ -1070,7 +1069,7 @@ static struct i2c_driver wm8983_i2c_driver = { .driver = { .name = "wm8983", }, - .probe = wm8983_i2c_probe, + .probe_new = wm8983_i2c_probe, .id_table = wm8983_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index a7e01106fbc0..cf2c32eac773 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1167,10 +1167,12 @@ static struct spi_driver wm8985_spi_driver = { #endif #if IS_ENABLED(CONFIG_I2C) -static int wm8985_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static const struct i2c_device_id wm8985_i2c_id[]; + +static int wm8985_i2c_probe(struct i2c_client *i2c) { struct wm8985_priv *wm8985; + const struct i2c_device_id *id = i2c_match_id(wm8985_i2c_id, i2c); int ret; wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL); @@ -1205,7 +1207,7 @@ static struct i2c_driver wm8985_i2c_driver = { .driver = { .name = "wm8985", }, - .probe = wm8985_i2c_probe, + .probe_new = wm8985_i2c_probe, .id_table = wm8985_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 1d2f881bbcae..27538d6598cf 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -872,8 +872,7 @@ static struct spi_driver wm8988_spi_driver = { #endif /* CONFIG_SPI_MASTER */ #if IS_ENABLED(CONFIG_I2C) -static int wm8988_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8988_i2c_probe(struct i2c_client *i2c) { struct wm8988_priv *wm8988; int ret; @@ -907,7 +906,7 @@ static struct i2c_driver wm8988_i2c_driver = { .driver = { .name = "wm8988", }, - .probe = wm8988_i2c_probe, + .probe_new = wm8988_i2c_probe, .id_table = wm8988_i2c_id, }; #endif diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 938940777e5d..c9448a59c872 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1220,8 +1220,7 @@ static const struct snd_soc_component_driver soc_component_dev_wm8990 = { .non_legacy_dai_naming = 1, }; -static int wm8990_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8990_i2c_probe(struct i2c_client *i2c) { struct wm8990_priv *wm8990; int ret; @@ -1249,7 +1248,7 @@ static struct i2c_driver wm8990_i2c_driver = { .driver = { .name = "wm8990", }, - .probe = wm8990_i2c_probe, + .probe_new = wm8990_i2c_probe, .id_table = wm8990_i2c_id, }; diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 16bc8609d0d2..998bc89bb7e1 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1257,8 +1257,7 @@ static const struct regmap_config wm8991_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int wm8991_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8991_i2c_probe(struct i2c_client *i2c) { struct wm8991_priv *wm8991; unsigned int val; @@ -1325,7 +1324,7 @@ static struct i2c_driver wm8991_i2c_driver = { .driver = { .name = "wm8991", }, - .probe = wm8991_i2c_probe, + .probe_new = wm8991_i2c_probe, .id_table = wm8991_i2c_id, }; diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index c4f41692b806..f4da77ec9d6c 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1624,8 +1624,7 @@ static const struct snd_soc_component_driver soc_component_dev_wm8993 = { .non_legacy_dai_naming = 1, }; -static int wm8993_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8993_i2c_probe(struct i2c_client *i2c) { struct wm8993_priv *wm8993; unsigned int reg; @@ -1745,7 +1744,7 @@ static struct i2c_driver wm8993_i2c_driver = { .driver = { .name = "wm8993", }, - .probe = wm8993_i2c_probe, + .probe_new = wm8993_i2c_probe, .remove = wm8993_i2c_remove, .id_table = wm8993_i2c_id, }; diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index b896d9c5bea0..ea9727446707 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2231,8 +2231,7 @@ static struct spi_driver wm8995_spi_driver = { #endif #if IS_ENABLED(CONFIG_I2C) -static int wm8995_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8995_i2c_probe(struct i2c_client *i2c) { struct wm8995_priv *wm8995; int ret; @@ -2270,7 +2269,7 @@ static struct i2c_driver wm8995_i2c_driver = { .driver = { .name = "wm8995", }, - .probe = wm8995_i2c_probe, + .probe_new = wm8995_i2c_probe, .id_table = wm8995_i2c_id }; #endif diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 197ae7d84a49..f7bb27d1c76d 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2755,8 +2755,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { }, }; -static int wm8996_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8996_i2c_probe(struct i2c_client *i2c) { struct wm8996_priv *wm8996; int ret, i; @@ -3091,7 +3090,7 @@ static struct i2c_driver wm8996_i2c_driver = { .driver = { .name = "wm8996", }, - .probe = wm8996_i2c_probe, + .probe_new = wm8996_i2c_probe, .remove = wm8996_i2c_remove, .id_table = wm8996_i2c_id, }; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 4a667ee82fe2..87b58448cea7 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1299,8 +1299,7 @@ static const struct regmap_config wm9081_regmap = { .cache_type = REGCACHE_RBTREE, }; -static int wm9081_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm9081_i2c_probe(struct i2c_client *i2c) { struct wm9081_priv *wm9081; unsigned int reg; @@ -1373,7 +1372,7 @@ static struct i2c_driver wm9081_i2c_driver = { .driver = { .name = "wm9081", }, - .probe = wm9081_i2c_probe, + .probe_new = wm9081_i2c_probe, .remove = wm9081_i2c_remove, .id_table = wm9081_i2c_id, }; diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index e0231a54609c..f7d80f1e37a8 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, - .endianness = 1, .non_legacy_dai_naming = 1, }; @@ -561,8 +560,7 @@ static const struct regmap_config wm9090_regmap = { }; -static int wm9090_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm9090_i2c_probe(struct i2c_client *i2c) { struct wm9090_priv *wm9090; unsigned int reg; @@ -619,7 +617,7 @@ static struct i2c_driver wm9090_i2c_driver = { .driver = { .name = "wm9090", }, - .probe = wm9090_i2c_probe, + .probe_new = wm9090_i2c_probe, .id_table = wm9090_id, }; diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 616b26c70c3b..f3a56f3ce487 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1066,6 +1066,7 @@ static const struct snd_soc_component_driver wsa881x_component_drv = { .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), .dapm_routes = wsa881x_audio_map, .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), + .endianness = 1, }; static int wsa881x_update_status(struct sdw_slave *slave, |