summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig67
-rw-r--r--sound/soc/codecs/Makefile16
-rw-r--r--sound/soc/codecs/ad193x-i2c.c6
-rw-r--r--sound/soc/codecs/adau1372-i2c.c4
-rw-r--r--sound/soc/codecs/adau1372.c1
-rw-r--r--sound/soc/codecs/adau1373.c5
-rw-r--r--sound/soc/codecs/adau1701.c5
-rw-r--r--sound/soc/codecs/adau1761-i2c.c8
-rw-r--r--sound/soc/codecs/adau1761.c86
-rw-r--r--sound/soc/codecs/adau1781-i2c.c8
-rw-r--r--sound/soc/codecs/adau17x1.c20
-rw-r--r--sound/soc/codecs/adau17x1.h1
-rw-r--r--sound/soc/codecs/adau1977-i2c.c8
-rw-r--r--sound/soc/codecs/adau7118-i2c.c5
-rw-r--r--sound/soc/codecs/adav803.c5
-rw-r--r--sound/soc/codecs/ak4118.c5
-rw-r--r--sound/soc/codecs/ak4535.c5
-rw-r--r--sound/soc/codecs/ak4613.c377
-rw-r--r--sound/soc/codecs/ak4641.c5
-rw-r--r--sound/soc/codecs/ak4642.c8
-rw-r--r--sound/soc/codecs/ak4671.c5
-rw-r--r--sound/soc/codecs/alc5623.c24
-rw-r--r--sound/soc/codecs/alc5632.c20
-rw-r--r--sound/soc/codecs/cros_ec_codec.c7
-rw-r--r--sound/soc/codecs/cs35l32.c5
-rw-r--r--sound/soc/codecs/cs35l33.c5
-rw-r--r--sound/soc/codecs/cs35l34.c5
-rw-r--r--sound/soc/codecs/cs35l35.c5
-rw-r--r--sound/soc/codecs/cs35l36.c7
-rw-r--r--sound/soc/codecs/cs35l41-i2c.c5
-rw-r--r--sound/soc/codecs/cs35l41-lib.c16
-rw-r--r--sound/soc/codecs/cs35l41.c2
-rw-r--r--sound/soc/codecs/cs35l45-i2c.c74
-rw-r--r--sound/soc/codecs/cs35l45-spi.c74
-rw-r--r--sound/soc/codecs/cs35l45-tables.c202
-rw-r--r--sound/soc/codecs/cs35l45.c690
-rw-r--r--sound/soc/codecs/cs35l45.h217
-rw-r--r--sound/soc/codecs/cs4234.c5
-rw-r--r--sound/soc/codecs/cs4265.c5
-rw-r--r--sound/soc/codecs/cs4270.c20
-rw-r--r--sound/soc/codecs/cs4271-i2c.c5
-rw-r--r--sound/soc/codecs/cs42l42.c5
-rw-r--r--sound/soc/codecs/cs42l51-i2c.c5
-rw-r--r--sound/soc/codecs/cs42l51.c7
-rw-r--r--sound/soc/codecs/cs42l52.c5
-rw-r--r--sound/soc/codecs/cs42l56.c7
-rw-r--r--sound/soc/codecs/cs42l73.c5
-rw-r--r--sound/soc/codecs/cs42xx8-i2c.c5
-rw-r--r--sound/soc/codecs/cs43130.c23
-rw-r--r--sound/soc/codecs/cs43130.h151
-rw-r--r--sound/soc/codecs/cs4341.c5
-rw-r--r--sound/soc/codecs/cs4349.c14
-rw-r--r--sound/soc/codecs/cs53l30.c5
-rw-r--r--sound/soc/codecs/cx2072x.c6
-rw-r--r--sound/soc/codecs/da7210.c5
-rw-r--r--sound/soc/codecs/da7213.c5
-rw-r--r--sound/soc/codecs/da7218.c19
-rw-r--r--sound/soc/codecs/da7219.c5
-rw-r--r--sound/soc/codecs/da732x.c5
-rw-r--r--sound/soc/codecs/da9055.c5
-rw-r--r--sound/soc/codecs/dmic.c5
-rw-r--r--sound/soc/codecs/es8316.c5
-rw-r--r--sound/soc/codecs/es8328-i2c.c5
-rw-r--r--sound/soc/codecs/hdac_hda.c15
-rw-r--r--sound/soc/codecs/hdmi-codec.c15
-rw-r--r--sound/soc/codecs/isabelle.c5
-rw-r--r--sound/soc/codecs/lm4857.c5
-rw-r--r--sound/soc/codecs/lm49453.c5
-rw-r--r--sound/soc/codecs/lochnagar-sc.c5
-rw-r--r--sound/soc/codecs/lpass-macro-common.c35
-rw-r--r--sound/soc/codecs/max9768.c5
-rw-r--r--sound/soc/codecs/max98088.c21
-rw-r--r--sound/soc/codecs/max98090.c33
-rw-r--r--sound/soc/codecs/max98095.c19
-rw-r--r--sound/soc/codecs/max98371.c5
-rw-r--r--sound/soc/codecs/max98373-i2c.c5
-rw-r--r--sound/soc/codecs/max98390.c17
-rw-r--r--sound/soc/codecs/max98396.c1637
-rw-r--r--sound/soc/codecs/max98396.h305
-rw-r--r--sound/soc/codecs/max9850.c5
-rw-r--r--sound/soc/codecs/max98504.c6
-rw-r--r--sound/soc/codecs/max98520.c4
-rw-r--r--sound/soc/codecs/max9867.c5
-rw-r--r--sound/soc/codecs/max9877.c5
-rw-r--r--sound/soc/codecs/max98925.c5
-rw-r--r--sound/soc/codecs/max98926.c5
-rw-r--r--sound/soc/codecs/max98927.c5
-rw-r--r--sound/soc/codecs/ml26124.c5
-rw-r--r--sound/soc/codecs/mt6351.c10
-rw-r--r--sound/soc/codecs/mt6358.c10
-rw-r--r--sound/soc/codecs/mt6359.c10
-rw-r--r--sound/soc/codecs/mt6660.c6
-rw-r--r--sound/soc/codecs/nau8540.c5
-rw-r--r--sound/soc/codecs/nau8810.c5
-rw-r--r--sound/soc/codecs/nau8821.c5
-rw-r--r--sound/soc/codecs/nau8822.c5
-rw-r--r--sound/soc/codecs/nau8824.c5
-rw-r--r--sound/soc/codecs/nau8825.c5
-rw-r--r--sound/soc/codecs/pcm1681.c5
-rw-r--r--sound/soc/codecs/pcm1789-i2c.c9
-rw-r--r--sound/soc/codecs/pcm1789.c4
-rw-r--r--sound/soc/codecs/pcm1789.h2
-rw-r--r--sound/soc/codecs/pcm179x-i2c.c5
-rw-r--r--sound/soc/codecs/pcm186x-i2c.c24
-rw-r--r--sound/soc/codecs/pcm186x.c7
-rw-r--r--sound/soc/codecs/pcm3060-i2c.c5
-rw-r--r--sound/soc/codecs/pcm3060.c1
-rw-r--r--sound/soc/codecs/pcm3168a-i2c.c5
-rw-r--r--sound/soc/codecs/pcm512x-i2c.c5
-rw-r--r--sound/soc/codecs/rk3328_codec.c2
-rw-r--r--sound/soc/codecs/rt1011.c5
-rw-r--r--sound/soc/codecs/rt1015.c5
-rw-r--r--sound/soc/codecs/rt1016.c5
-rw-r--r--sound/soc/codecs/rt1019.c8
-rw-r--r--sound/soc/codecs/rt1305.c5
-rw-r--r--sound/soc/codecs/rt1308-sdw.c1
-rw-r--r--sound/soc/codecs/rt1308-sdw.h1
-rw-r--r--sound/soc/codecs/rt1308.c5
-rw-r--r--sound/soc/codecs/rt1316-sdw.c1
-rw-r--r--sound/soc/codecs/rt274.c5
-rw-r--r--sound/soc/codecs/rt286.c5
-rw-r--r--sound/soc/codecs/rt298.c5
-rw-r--r--sound/soc/codecs/rt5514.c7
-rw-r--r--sound/soc/codecs/rt5616.c5
-rw-r--r--sound/soc/codecs/rt5631.c5
-rw-r--r--sound/soc/codecs/rt5640.c5
-rw-r--r--sound/soc/codecs/rt5645.c16
-rw-r--r--sound/soc/codecs/rt5651.c5
-rw-r--r--sound/soc/codecs/rt5659.c5
-rw-r--r--sound/soc/codecs/rt5660.c5
-rw-r--r--sound/soc/codecs/rt5663.c5
-rw-r--r--sound/soc/codecs/rt5665.c5
-rw-r--r--sound/soc/codecs/rt5668.c5
-rw-r--r--sound/soc/codecs/rt5670.c5
-rw-r--r--sound/soc/codecs/rt5682-i2c.c5
-rw-r--r--sound/soc/codecs/rt5682s.c32
-rw-r--r--sound/soc/codecs/rt5682s.h6
-rw-r--r--sound/soc/codecs/rt700.c1
-rw-r--r--sound/soc/codecs/rt711-sdca.c1
-rw-r--r--sound/soc/codecs/rt711.c1
-rw-r--r--sound/soc/codecs/rt715-sdca-sdw.c2
-rw-r--r--sound/soc/codecs/rt715-sdca.c1
-rw-r--r--sound/soc/codecs/rt715.c1
-rw-r--r--sound/soc/codecs/rt9120.c114
-rw-r--r--sound/soc/codecs/sdw-mockup.c1
-rw-r--r--sound/soc/codecs/sgtl5000.c5
-rw-r--r--sound/soc/codecs/ssm2518.c5
-rw-r--r--sound/soc/codecs/ssm2602-i2c.c8
-rw-r--r--sound/soc/codecs/ssm4567.c5
-rw-r--r--sound/soc/codecs/sta32x.c14
-rw-r--r--sound/soc/codecs/sta350.c14
-rw-r--r--sound/soc/codecs/sta529.c5
-rw-r--r--sound/soc/codecs/tas2552.c5
-rw-r--r--sound/soc/codecs/tas2562.c25
-rw-r--r--sound/soc/codecs/tas2764.c5
-rw-r--r--sound/soc/codecs/tas2770.c5
-rw-r--r--sound/soc/codecs/tas5086.c5
-rw-r--r--sound/soc/codecs/tas571x.c17
-rw-r--r--sound/soc/codecs/tas5720.c21
-rw-r--r--sound/soc/codecs/tas6424.c17
-rw-r--r--sound/soc/codecs/tda7419.c5
-rw-r--r--sound/soc/codecs/tlv320adc3xxx.c32
-rw-r--r--sound/soc/codecs/tlv320adcx140.c16
-rw-r--r--sound/soc/codecs/tlv320aic23-i2c.c5
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c32
-rw-r--r--sound/soc/codecs/tlv320aic32x4-i2c.c11
-rw-r--r--sound/soc/codecs/tlv320aic3x-i2c.c25
-rw-r--r--sound/soc/codecs/tlv320dac33.c5
-rw-r--r--sound/soc/codecs/tpa6130a2.c21
-rw-r--r--sound/soc/codecs/ts3a227e.c5
-rw-r--r--sound/soc/codecs/tscs42xx.c5
-rw-r--r--sound/soc/codecs/tscs454.c17
-rw-r--r--sound/soc/codecs/uda1380.c5
-rw-r--r--sound/soc/codecs/wcd9335.c1
-rw-r--r--sound/soc/codecs/wcd934x.c1
-rw-r--r--sound/soc/codecs/wcd938x.c1
-rw-r--r--sound/soc/codecs/wm1250-ev1.c5
-rw-r--r--sound/soc/codecs/wm2000.c12
-rw-r--r--sound/soc/codecs/wm2200.c5
-rw-r--r--sound/soc/codecs/wm5100.c5
-rw-r--r--sound/soc/codecs/wm8510.c5
-rw-r--r--sound/soc/codecs/wm8523.c5
-rw-r--r--sound/soc/codecs/wm8580.c5
-rw-r--r--sound/soc/codecs/wm8711.c5
-rw-r--r--sound/soc/codecs/wm8728.c5
-rw-r--r--sound/soc/codecs/wm8731-i2c.c68
-rw-r--r--sound/soc/codecs/wm8731-spi.c59
-rw-r--r--sound/soc/codecs/wm8731.c267
-rw-r--r--sound/soc/codecs/wm8731.h27
-rw-r--r--sound/soc/codecs/wm8737.c5
-rw-r--r--sound/soc/codecs/wm8741.c5
-rw-r--r--sound/soc/codecs/wm8750.c5
-rw-r--r--sound/soc/codecs/wm8753.c5
-rw-r--r--sound/soc/codecs/wm8776.c5
-rw-r--r--sound/soc/codecs/wm8804-i2c.c5
-rw-r--r--sound/soc/codecs/wm8900.c5
-rw-r--r--sound/soc/codecs/wm8903.c7
-rw-r--r--sound/soc/codecs/wm8904.c9
-rw-r--r--sound/soc/codecs/wm8940.c12
-rw-r--r--sound/soc/codecs/wm8955.c5
-rw-r--r--sound/soc/codecs/wm8960.c20
-rw-r--r--sound/soc/codecs/wm8961.c5
-rw-r--r--sound/soc/codecs/wm8962.c11
-rw-r--r--sound/soc/codecs/wm8971.c5
-rw-r--r--sound/soc/codecs/wm8974.c5
-rw-r--r--sound/soc/codecs/wm8978.c5
-rw-r--r--sound/soc/codecs/wm8983.c5
-rw-r--r--sound/soc/codecs/wm8985.c8
-rw-r--r--sound/soc/codecs/wm8988.c5
-rw-r--r--sound/soc/codecs/wm8990.c5
-rw-r--r--sound/soc/codecs/wm8991.c5
-rw-r--r--sound/soc/codecs/wm8993.c5
-rw-r--r--sound/soc/codecs/wm8995.c5
-rw-r--r--sound/soc/codecs/wm8996.c5
-rw-r--r--sound/soc/codecs/wm9081.c5
-rw-r--r--sound/soc/codecs/wm9090.c6
-rw-r--r--sound/soc/codecs/wsa881x.c1
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, &reg);
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, &reg);
@@ -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, &reg);
+ 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, &reg);
+ 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, &reg);
+ 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, &reg);
+ 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, &reg);
+ 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, &reg);
+ 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), &reg);
+ 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), &reg);
+ 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,