summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/armada-370db-audio.txt24
-rw-r--r--Documentation/devicetree/bindings/sound/mvebu-audio.txt1
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic31xx.txt61
-rw-r--r--MAINTAINERS7
-rw-r--r--include/dt-bindings/sound/tlv320aic31xx-micbias.h8
-rw-r--r--include/sound/soc.h13
-rw-r--r--sound/soc/cirrus/snappercl15.c18
-rw-r--r--sound/soc/codecs/88pm860x-codec.c3
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ad193x.c10
-rw-r--r--sound/soc/codecs/adau1373.c7
-rw-r--r--sound/soc/codecs/adav80x.c7
-rw-r--r--sound/soc/codecs/ak4535.c9
-rw-r--r--sound/soc/codecs/ak4641.c8
-rw-r--r--sound/soc/codecs/ak4642.c8
-rw-r--r--sound/soc/codecs/ak4671.c12
-rw-r--r--sound/soc/codecs/alc5623.c7
-rw-r--r--sound/soc/codecs/alc5632.c8
-rw-r--r--sound/soc/codecs/cq93vc.c3
-rw-r--r--sound/soc/codecs/cs4270.c9
-rw-r--r--sound/soc/codecs/cs42l51.c6
-rw-r--r--sound/soc/codecs/cs42l52.c9
-rw-r--r--sound/soc/codecs/cs42l73.c11
-rw-r--r--sound/soc/codecs/da7210.c8
-rw-r--r--sound/soc/codecs/da7213.c8
-rw-r--r--sound/soc/codecs/da732x.c29
-rw-r--r--sound/soc/codecs/da9055.c8
-rw-r--r--sound/soc/codecs/isabelle.c16
-rw-r--r--sound/soc/codecs/lm4857.c3
-rw-r--r--sound/soc/codecs/lm49453.c31
-rw-r--r--sound/soc/codecs/max9768.c5
-rw-r--r--sound/soc/codecs/max98088.c45
-rw-r--r--sound/soc/codecs/max98090.c8
-rw-r--r--sound/soc/codecs/max98095.c56
-rw-r--r--sound/soc/codecs/max9850.c8
-rw-r--r--sound/soc/codecs/mc13783.c4
-rw-r--r--sound/soc/codecs/ml26124.c10
-rw-r--r--sound/soc/codecs/rt5631.c9
-rw-r--r--sound/soc/codecs/rt5640.c8
-rw-r--r--sound/soc/codecs/sgtl5000.c8
-rw-r--r--sound/soc/codecs/si476x.c6
-rw-r--r--sound/soc/codecs/sn95031.c2
-rw-r--r--sound/soc/codecs/ssm2518.c10
-rw-r--r--sound/soc/codecs/ssm2602.c7
-rw-r--r--sound/soc/codecs/sta32x.c14
-rw-r--r--sound/soc/codecs/sta529.c10
-rw-r--r--sound/soc/codecs/tlv320aic23.c8
-rw-r--r--sound/soc/codecs/tlv320aic26.c2
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c1295
-rw-r--r--sound/soc/codecs/tlv320aic31xx.h258
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c2
-rw-r--r--sound/soc/codecs/tlv320aic3x.c6
-rw-r--r--sound/soc/codecs/tlv320dac33.c1
-rw-r--r--sound/soc/codecs/wm2000.c2
-rw-r--r--sound/soc/codecs/wm2200.c7
-rw-r--r--sound/soc/codecs/wm5100.c7
-rw-r--r--sound/soc/codecs/wm5102.c4
-rw-r--r--sound/soc/codecs/wm5110.c3
-rw-r--r--sound/soc/codecs/wm8350.c4
-rw-r--r--sound/soc/codecs/wm8400.c3
-rw-r--r--sound/soc/codecs/wm8510.c10
-rw-r--r--sound/soc/codecs/wm8523.c7
-rw-r--r--sound/soc/codecs/wm8580.c6
-rw-r--r--sound/soc/codecs/wm8711.c6
-rw-r--r--sound/soc/codecs/wm8728.c11
-rw-r--r--sound/soc/codecs/wm8731.c7
-rw-r--r--sound/soc/codecs/wm8737.c6
-rw-r--r--sound/soc/codecs/wm8741.c6
-rw-r--r--sound/soc/codecs/wm8750.c6
-rw-r--r--sound/soc/codecs/wm8753.c7
-rw-r--r--sound/soc/codecs/wm8770.c6
-rw-r--r--sound/soc/codecs/wm8776.c6
-rw-r--r--sound/soc/codecs/wm8804.c8
-rw-r--r--sound/soc/codecs/wm8900.c8
-rw-r--r--sound/soc/codecs/wm8903.c10
-rw-r--r--sound/soc/codecs/wm8904.c9
-rw-r--r--sound/soc/codecs/wm8940.c6
-rw-r--r--sound/soc/codecs/wm8955.c8
-rw-r--r--sound/soc/codecs/wm8960.c6
-rw-r--r--sound/soc/codecs/wm8961.c7
-rw-r--r--sound/soc/codecs/wm8962.c7
-rw-r--r--sound/soc/codecs/wm8971.c6
-rw-r--r--sound/soc/codecs/wm8974.c6
-rw-r--r--sound/soc/codecs/wm8978.c8
-rw-r--r--sound/soc/codecs/wm8983.c6
-rw-r--r--sound/soc/codecs/wm8985.c7
-rw-r--r--sound/soc/codecs/wm8988.c8
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8991.c8
-rw-r--r--sound/soc/codecs/wm8993.c7
-rw-r--r--sound/soc/codecs/wm8994.c3
-rw-r--r--sound/soc/codecs/wm8995.c7
-rw-r--r--sound/soc/codecs/wm8996.c12
-rw-r--r--sound/soc/codecs/wm8997.c4
-rw-r--r--sound/soc/codecs/wm9081.c11
-rw-r--r--sound/soc/codecs/wm9090.c10
-rw-r--r--sound/soc/intel/Kconfig4
-rw-r--r--sound/soc/kirkwood/Kconfig10
-rw-r--r--sound/soc/kirkwood/Makefile2
-rw-r--r--sound/soc/kirkwood/armada-370-db.c120
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c1
-rw-r--r--sound/soc/omap/ams-delta.c2
-rw-r--r--sound/soc/pxa/magician.c34
-rw-r--r--sound/soc/pxa/tosa.c35
-rw-r--r--sound/soc/s6000/s6105-ipcam.c28
-rw-r--r--sound/soc/soc-core.c14
-rw-r--r--sound/soc/soc-io.c64
-rw-r--r--sound/soc/soc-jack.c5
109 files changed, 1958 insertions, 795 deletions
diff --git a/Documentation/devicetree/bindings/sound/armada-370db-audio.txt b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt
new file mode 100644
index 000000000000..3893b4d15a20
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt
@@ -0,0 +1,24 @@
+Device Tree bindings for the Armada 370 DB audio
+================================================
+
+These Device Tree bindings are used to describe the audio complex
+found on the Armada 370 DB platform.
+
+Mandatory properties:
+
+ * compatible: must be "marvell,a370db-audio"
+
+ * marvell,audio-controller: a phandle that points to the audio
+ controller of the Armada 370 SoC.
+
+ * marvell,audio-codec: a phandle that points to the analog audio
+ codec connected to the Armada 370 SoC.
+
+Example:
+
+ sound {
+ compatible = "marvell,a370db-audio";
+ marvell,audio-controller = <&audio_controller>;
+ marvell,audio-codec = <&audio_codec>;
+ status = "okay";
+ };
diff --git a/Documentation/devicetree/bindings/sound/mvebu-audio.txt b/Documentation/devicetree/bindings/sound/mvebu-audio.txt
index f0062c5871b4..cb8c07c81ce4 100644
--- a/Documentation/devicetree/bindings/sound/mvebu-audio.txt
+++ b/Documentation/devicetree/bindings/sound/mvebu-audio.txt
@@ -5,6 +5,7 @@ Required properties:
- compatible:
"marvell,kirkwood-audio" for Kirkwood platforms
"marvell,dove-audio" for Dove platforms
+ "marvell,armada370-audio" for Armada 370 platforms
- reg: physical base address of the controller and length of memory mapped
region.
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
new file mode 100644
index 000000000000..74c66dee3e14
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
@@ -0,0 +1,61 @@
+Texas Instruments - tlv320aic31xx Codec module
+
+The tlv320aic31xx serial control bus communicates through I2C protocols
+
+Required properties:
+
+- compatible - "string" - One of:
+ "ti,tlv320aic310x" - Generic TLV320AIC31xx with mono speaker amp
+ "ti,tlv320aic311x" - Generic TLV320AIC31xx with stereo speaker amp
+ "ti,tlv320aic3100" - TLV320AIC3100 (mono speaker amp, no MiniDSP)
+ "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP)
+ "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP)
+ "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP)
+
+- reg - <int> - I2C slave address
+
+
+Optional properties:
+
+- gpio-reset - gpio pin number used for codec reset
+- ai31xx-micbias-vg - MicBias Voltage setting
+ 1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V
+ 2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V
+ 3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD
+ If this node is not mentioned or if the value is unknown, then
+ micbias is set to 2.0V.
+- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
+ DVDD-supply : power supplies for the device as covered in
+ Documentation/devicetree/bindings/regulator/regulator.txt
+
+CODEC output pins:
+ * HPL
+ * HPR
+ * SPL, devices with stereo speaker amp
+ * SPR, devices with stereo speaker amp
+ * SPK, devices with mono speaker amp
+ * MICBIAS
+
+CODEC input pins:
+ * MIC1LP
+ * MIC1RP
+ * MIC1LM
+
+The pins can be used in referring sound node's audio-routing property.
+
+Example:
+#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+
+tlv320aic31xx: tlv320aic31xx@18 {
+ compatible = "ti,tlv320aic311x";
+ reg = <0x18>;
+
+ ai31xx-micbias-vg = <MICBIAS_OFF>;
+
+ HPVDD-supply = <&regulator>;
+ SPRVDD-supply = <&regulator>;
+ SPLVDD-supply = <&regulator>;
+ AVDD-supply = <&regulator>;
+ IOVDD-supply = <&regulator>;
+ DVDD-supply = <&regulator>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 82640e640f36..ec01455c7afe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2203,6 +2203,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Odd Fixes
F: sound/soc/codecs/cs4270*
+CIRRUS LOGIC AUDIO CODEC DRIVERS
+M: Brian Austin <brian.austin@cirrus.com>
+M: Paul Handrigan <Paul.Handrigan@cirrus.com>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+S: Maintained
+F: sound/soc/codecs/cs*
+
CLEANCACHE API
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: linux-kernel@vger.kernel.org
diff --git a/include/dt-bindings/sound/tlv320aic31xx-micbias.h b/include/dt-bindings/sound/tlv320aic31xx-micbias.h
new file mode 100644
index 000000000000..f5cb772ab9c8
--- /dev/null
+++ b/include/dt-bindings/sound/tlv320aic31xx-micbias.h
@@ -0,0 +1,8 @@
+#ifndef __DT_TLV320AIC31XX_MICBIAS_H
+#define __DT_TLV320AIC31XX_MICBIAS_H
+
+#define MICBIAS_2_0V 1
+#define MICBIAS_2_5V 2
+#define MICBIAS_AVDDV 3
+
+#endif /* __DT_TLV320AIC31XX_MICBIAS_H */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 959f38949967..f7de629728bf 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -354,12 +354,6 @@ typedef int (*hw_write_t)(void *,const char* ,int);
extern struct snd_ac97_bus_ops *soc_ac97_ops;
-enum snd_soc_control_type {
- SND_SOC_I2C = 1,
- SND_SOC_SPI,
- SND_SOC_REGMAP,
-};
-
enum snd_soc_pcm_subclass {
SND_SOC_PCM_CLASS_PCM = 0,
SND_SOC_PCM_CLASS_BE = 1,
@@ -406,8 +400,7 @@ int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
unsigned int reg);
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control);
+ struct regmap *regmap);
int snd_soc_cache_sync(struct snd_soc_codec *codec);
int snd_soc_cache_init(struct snd_soc_codec *codec);
int snd_soc_cache_exit(struct snd_soc_codec *codec);
@@ -614,7 +607,8 @@ struct snd_soc_jack_gpio {
struct snd_soc_jack *jack;
struct delayed_work work;
- int (*jack_status_check)(void);
+ void *data;
+ int (*jack_status_check)(void *data);
};
struct snd_soc_jack {
@@ -717,7 +711,6 @@ struct snd_soc_codec {
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
hw_write_t hw_write;
- unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
void *reg_cache;
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index 29238a7476dd..5b68b106cfc2 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -65,18 +65,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"MICIN", NULL, "Mic Jack"},
};
-static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
- ARRAY_SIZE(tlv320aic23_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- return 0;
-}
-
static struct snd_soc_dai_link snappercl15_dai = {
.name = "tlv320aic23",
.stream_name = "AIC23",
@@ -84,7 +72,6 @@ static struct snd_soc_dai_link snappercl15_dai = {
.codec_dai_name = "tlv320aic23-hifi",
.codec_name = "tlv320aic23-codec.0-001a",
.platform_name = "ep93xx-i2s",
- .init = snappercl15_tlv320aic23_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &snappercl15_ops,
@@ -95,6 +82,11 @@ static struct snd_soc_card snd_soc_snappercl15 = {
.owner = THIS_MODULE,
.dai_link = &snappercl15_dai,
.num_links = 1,
+
+ .dapm_widgets = tlv320aic23_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
};
static int snappercl15_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 8703244ee9fb..b07e17160f94 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1327,8 +1327,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
pm860x->codec = codec;
- codec->control_data = pm860x->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+ ret = snd_soc_codec_set_cache_io(codec, pm860x->regmap);
if (ret)
return ret;
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 32d7a6f04b7d..1a8ff1e541ef 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -85,6 +85,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TLV320AIC23_I2C if I2C
select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
select SND_SOC_TLV320AIC26 if SPI_MASTER
+ select SND_SOC_TLV320AIC31XX if I2C
select SND_SOC_TLV320AIC32X4 if I2C
select SND_SOC_TLV320AIC3X if I2C
select SND_SOC_TPA6130A2 if I2C
@@ -449,6 +450,9 @@ config SND_SOC_TLV320AIC26
tristate
depends on SPI
+config SND_SOC_TLV320AIC31XX
+ tristate
+
config SND_SOC_TLV320AIC32X4
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index cb46c4c78dc2..73df822885de 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -79,6 +79,7 @@ snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
snd-soc-tlv320aic26-objs := tlv320aic26.o
+snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o
snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
snd-soc-tlv320dac33-objs := tlv320dac33.o
@@ -223,6 +224,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
+obj-$(CONFIG_SND_SOC_TLV320AIC31XX) += snd-soc-tlv320aic31xx.o
obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 9381a767e75f..6844d0b2af68 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -322,14 +322,6 @@ static struct snd_soc_dai_driver ad193x_dai = {
static int ad193x_codec_probe(struct snd_soc_codec *codec)
{
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = ad193x->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
- return ret;
- }
/* default setting for ad193x */
@@ -347,7 +339,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
- return ret;
+ return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 5223800775ad..877f5737bb6b 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1376,15 +1376,8 @@ static int adau1373_probe(struct snd_soc_codec *codec)
struct adau1373_platform_data *pdata = codec->dev->platform_data;
bool lineout_differential = false;
unsigned int val;
- int ret;
int i;
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
- if (ret) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
if (pdata) {
if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
return -EINVAL;
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 7470831ba756..5062e34ee8dc 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -801,15 +801,8 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
static int adav80x_probe(struct snd_soc_codec *codec)
{
- int ret;
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
- if (ret) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Force PLLs on for SYSCLK output */
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 684fe910669f..30e297890fec 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -388,15 +388,6 @@ static int ak4535_resume(struct snd_soc_codec *codec)
static int ak4535_probe(struct snd_soc_codec *codec)
{
- struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = ak4535->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
/* power on device */
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 684b56f2856a..868c0e2da1ec 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -519,14 +519,6 @@ static int ak4641_resume(struct snd_soc_codec *codec)
static int ak4641_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* power on device */
ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 1f646c6e90c6..92655cc189ae 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -465,14 +465,6 @@ static int ak4642_resume(struct snd_soc_codec *codec)
static int ak4642_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index deb2b44669de..998fa0c5a0b9 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -613,17 +613,7 @@ static struct snd_soc_dai_driver ak4671_dai = {
static int ak4671_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return ret;
+ return ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
}
static int ak4671_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index ed506253a914..09f7e773bafb 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -904,13 +904,6 @@ static int alc5623_probe(struct snd_soc_codec *codec)
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- codec->control_data = alc5623->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
alc5623_reset(codec);
/* power on device */
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index d885056ad8f2..ec071a6306ef 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -1063,14 +1063,6 @@ static int alc5632_probe(struct snd_soc_codec *codec)
struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = alc5632->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* power on device */
alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 43737a27d79c..1e25c7af853b 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -138,9 +138,8 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
struct davinci_vc *davinci_vc = codec->dev->platform_data;
davinci_vc->cq93vc.codec = codec;
- codec->control_data = davinci_vc->regmap;
- snd_soc_codec_set_cache_io(codec, 32, 32, SND_SOC_REGMAP);
+ snd_soc_codec_set_cache_io(codec, davinci_vc->regmap);
/* Off, with power on */
cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 83c835d9fd88..3920e6264948 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -506,15 +506,6 @@ static int cs4270_probe(struct snd_soc_codec *codec)
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int ret;
- /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
- * then do the I2C transactions itself.
- */
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
- return ret;
- }
-
/* Disable auto-mute. This feature appears to be buggy. In some
* situations, auto-mute will not deactivate when it should, so we want
* this feature disabled by default. An application (e.g. alsactl) can
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 828157779057..6c0da2baa154 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -487,12 +487,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
{
int ret, reg;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/*
* DAC configuration
* - Use signal processor
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index ea7938d9e13a..f0ca6bee6771 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -1109,14 +1109,7 @@ static void cs42l52_free_beep(struct snd_soc_codec *codec)
static int cs42l52_probe(struct snd_soc_codec *codec)
{
struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
- int ret;
- codec->control_data = cs42l52->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
regcache_cache_only(cs42l52->regmap, true);
cs42l52_add_mic_controls(codec);
@@ -1128,7 +1121,7 @@ static int cs42l52_probe(struct snd_soc_codec *codec)
cs42l52->sysclk = CS42L52_DEFAULT_CLK;
cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
- return ret;
+ return 0;
}
static int cs42l52_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index e5778c015c8d..0ee60a19a263 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1345,17 +1345,8 @@ static int cs42l73_resume(struct snd_soc_codec *codec)
static int cs42l73_probe(struct snd_soc_codec *codec)
{
- int ret;
struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
- codec->control_data = cs42l73->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Set Charge Pump Frequency */
@@ -1368,7 +1359,7 @@ static int cs42l73_probe(struct snd_soc_codec *codec)
cs42l73->mclksel = CS42L73_CLKID_MCLK1;
cs42l73->mclk = 0;
- return ret;
+ return 0;
}
static int cs42l73_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 01e55fc72307..137e8ebc092c 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -1071,17 +1071,9 @@ static struct snd_soc_dai_driver da7210_dai = {
static int da7210_probe(struct snd_soc_codec *codec)
{
struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
- int ret;
dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
- codec->control_data = da7210->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
da7210->mclk_rate = 0; /* This will be set from set_sysclk() */
da7210->master = 0; /* This will be set from set_fmt() */
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 439d10387f10..738fa18a50d2 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1393,17 +1393,9 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
static int da7213_probe(struct snd_soc_codec *codec)
{
- int ret;
struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
struct da7213_platform_data *pdata = da7213->pdata;
- codec->control_data = da7213->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Default to using ALC auto offset calibration mode. */
snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
DA7213_ALC_CALIB_MODE_MAN, 0);
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index 4d1c302f5a76..7d168ec71cd7 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -1297,9 +1297,9 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
msleep(DA732X_WAIT_FOR_STABILIZATION);
/* Check DAC offset sign */
- sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+ sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
DA732X_HP_DAC_OFF_CNTL_COMPO);
- sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+ sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
DA732X_HP_DAC_OFF_CNTL_COMPO);
/* Binary search DAC offset values (both channels at once) */
@@ -1316,10 +1316,10 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
msleep(DA732X_WAIT_FOR_STABILIZATION);
- if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+ if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
offset[DA732X_HPL_DAC] &= ~step;
- if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+ if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
offset[DA732X_HPR_DAC] &= ~step;
@@ -1360,9 +1360,9 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
msleep(DA732X_WAIT_FOR_STABILIZATION);
/* Check output offset sign */
- sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) &
+ sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) &
DA732X_HP_OUT_COMPO;
- sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) &
+ sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) &
DA732X_HP_OUT_COMPO;
snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
@@ -1383,10 +1383,10 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
msleep(DA732X_WAIT_FOR_STABILIZATION);
- if ((codec->hw_read(codec, DA732X_REG_HPL) &
+ if ((snd_soc_read(codec, DA732X_REG_HPL) &
DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
offset[DA732X_HPL_AMP] &= ~step;
- if ((codec->hw_read(codec, DA732X_REG_HPR) &
+ if ((snd_soc_read(codec, DA732X_REG_HPR) &
DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
offset[DA732X_HPR_AMP] &= ~step;
@@ -1512,23 +1512,14 @@ static int da732x_probe(struct snd_soc_codec *codec)
{
struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret = 0;
da732x->codec = codec;
dapm->idle_bias_off = false;
- codec->control_data = da732x->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec.\n");
- goto err;
- }
-
da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-err:
- return ret;
+
+ return 0;
}
static int da732x_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index f118daa91234..4ff06b50fbba 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -1383,16 +1383,8 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
static int da9055_probe(struct snd_soc_codec *codec)
{
- int ret;
struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
- codec->control_data = da9055->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Enable all Gain Ramps */
snd_soc_update_bits(codec, DA9055_AUX_L_CTRL,
DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index cb736ddc446d..3e264a78017a 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -1090,23 +1090,7 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
},
};
-static int isabelle_probe(struct snd_soc_codec *codec)
-{
- int ret = 0;
-
- codec->control_data = dev_get_regmap(codec->dev, NULL);
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
- .probe = isabelle_probe,
.set_bias_level = isabelle_set_bias_level,
.controls = isabelle_snd_controls,
.num_controls = ARRAY_SIZE(isabelle_snd_controls),
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 0e5743ea79df..4f048db9f55f 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -101,8 +101,7 @@ static const char *lm4857_mode[] = {
"Headphone",
};
-static const struct soc_enum lm4857_mode_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
+static SOC_ENUM_SINGLE_EXT_DECL(lm4857_mode_enum, lm4857_mode);
static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("IN"),
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 6b7fe5e54881..275b3f72f3f4 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -213,15 +213,13 @@ static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" };
static const char *lm49453_adcr_mux_text[] = { "MIC2", "Aux_R" };
-static const struct soc_enum lm49453_adcl_enum =
- SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 0,
- ARRAY_SIZE(lm49453_adcl_mux_text),
- lm49453_adcl_mux_text);
+static SOC_ENUM_SINGLE_DECL(lm49453_adcl_enum,
+ LM49453_P0_ANALOG_MIXER_ADC_REG, 0,
+ lm49453_adcl_mux_text);
-static const struct soc_enum lm49453_adcr_enum =
- SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 1,
- ARRAY_SIZE(lm49453_adcr_mux_text),
- lm49453_adcr_mux_text);
+static SOC_ENUM_SINGLE_DECL(lm49453_adcr_enum,
+ LM49453_P0_ANALOG_MIXER_ADC_REG, 1,
+ lm49453_adcr_mux_text);
static const struct snd_kcontrol_new lm49453_adcl_mux_control =
SOC_DAPM_ENUM("ADC Left Mux", lm49453_adcl_enum);
@@ -1409,22 +1407,6 @@ static int lm49453_resume(struct snd_soc_codec *codec)
return 0;
}
-static int lm49453_probe(struct snd_soc_codec *codec)
-{
- struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- codec->control_data = lm49453->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
/* power down chip */
static int lm49453_remove(struct snd_soc_codec *codec)
{
@@ -1433,7 +1415,6 @@ static int lm49453_remove(struct snd_soc_codec *codec)
}
static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
- .probe = lm49453_probe,
.remove = lm49453_remove,
.suspend = lm49453_suspend,
.resume = lm49453_resume,
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
index 31f91560e9f6..ec481fc428c7 100644
--- a/sound/soc/codecs/max9768.c
+++ b/sound/soc/codecs/max9768.c
@@ -135,11 +135,6 @@ static int max9768_probe(struct snd_soc_codec *codec)
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = max9768->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
- if (ret)
- return ret;
-
if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
if (ret)
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index bb1ecfc4459b..ef7cf89f5623 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -597,28 +597,27 @@ static const unsigned int max98088_exmode_values[] = {
0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32
};
-static const struct soc_enum max98088_exmode_enum =
- SOC_VALUE_ENUM_SINGLE(M98088_REG_41_SPKDHP, 0, 127,
- ARRAY_SIZE(max98088_exmode_texts),
- max98088_exmode_texts,
- max98088_exmode_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(max98088_exmode_enum,
+ M98088_REG_41_SPKDHP, 0, 127,
+ max98088_exmode_texts,
+ max98088_exmode_values);
static const char *max98088_ex_thresh[] = { /* volts PP */
"0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};
-static const struct soc_enum max98088_ex_thresh_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_42_SPKDHP_THRESH, 0, 8,
- max98088_ex_thresh),
-};
+static SOC_ENUM_SINGLE_DECL(max98088_ex_thresh_enum,
+ M98088_REG_42_SPKDHP_THRESH, 0,
+ max98088_ex_thresh);
static const char *max98088_fltr_mode[] = {"Voice", "Music" };
-static const struct soc_enum max98088_filter_mode_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 7, 2, max98088_fltr_mode),
-};
+static SOC_ENUM_SINGLE_DECL(max98088_filter_mode_enum,
+ M98088_REG_18_DAI1_FILTERS, 7,
+ max98088_fltr_mode);
static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" };
-static const struct soc_enum max98088_extmic_enum =
- SOC_ENUM_SINGLE(M98088_REG_48_CFG_MIC, 0, 3, max98088_extmic_text);
+static SOC_ENUM_SINGLE_DECL(max98088_extmic_enum,
+ M98088_REG_48_CFG_MIC, 0,
+ max98088_extmic_text);
static const struct snd_kcontrol_new max98088_extmic_mux =
SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum);
@@ -626,12 +625,12 @@ static const struct snd_kcontrol_new max98088_extmic_mux =
static const char *max98088_dai1_fltr[] = {
"Off", "fc=258/fs=16k", "fc=500/fs=16k",
"fc=258/fs=8k", "fc=500/fs=8k", "fc=200"};
-static const struct soc_enum max98088_dai1_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 0, 6, max98088_dai1_fltr),
-};
-static const struct soc_enum max98088_dai1_adc_filter_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 4, 6, max98088_dai1_fltr),
-};
+static SOC_ENUM_SINGLE_DECL(max98088_dai1_dac_filter_enum,
+ M98088_REG_18_DAI1_FILTERS, 0,
+ max98088_dai1_fltr);
+static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum,
+ M98088_REG_18_DAI1_FILTERS, 4,
+ max98088_dai1_fltr);
static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1915,12 +1914,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
regcache_mark_dirty(max98088->regmap);
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* initialize private data */
max98088->sysclk = (unsigned)-1;
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index f363de19be07..96a47459b3d7 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2218,14 +2218,6 @@ static int max98090_probe(struct snd_soc_codec *codec)
max98090->codec = codec;
- codec->control_data = max98090->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Reset the codec, the DSP core, and disable all interrupts */
max98090_reset(max98090);
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 5bce9cde4a6d..03f0536e6f61 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -560,25 +560,27 @@ static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
}
static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
-static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
- SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
-};
-static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
- SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
-};
+static SOC_ENUM_SINGLE_DECL(max98095_dai1_filter_mode_enum,
+ M98095_02E_DAI1_FILTERS, 7,
+ max98095_fltr_mode);
+static SOC_ENUM_SINGLE_DECL(max98095_dai2_filter_mode_enum,
+ M98095_038_DAI2_FILTERS, 7,
+ max98095_fltr_mode);
static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
-static const struct soc_enum max98095_extmic_enum =
- SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
+static SOC_ENUM_SINGLE_DECL(max98095_extmic_enum,
+ M98095_087_CFG_MIC, 0,
+ max98095_extmic_text);
static const struct snd_kcontrol_new max98095_extmic_mux =
SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
static const char * const max98095_linein_text[] = { "INA", "INB" };
-static const struct soc_enum max98095_linein_enum =
- SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
+static SOC_ENUM_SINGLE_DECL(max98095_linein_enum,
+ M98095_086_CFG_LINE, 6,
+ max98095_linein_text);
static const struct snd_kcontrol_new max98095_linein_mux =
SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
@@ -586,24 +588,26 @@ static const struct snd_kcontrol_new max98095_linein_mux =
static const char * const max98095_line_mode_text[] = {
"Stereo", "Differential"};
-static const struct soc_enum max98095_linein_mode_enum =
- SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
+static SOC_ENUM_SINGLE_DECL(max98095_linein_mode_enum,
+ M98095_086_CFG_LINE, 7,
+ max98095_line_mode_text);
-static const struct soc_enum max98095_lineout_mode_enum =
- SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
+static SOC_ENUM_SINGLE_DECL(max98095_lineout_mode_enum,
+ M98095_086_CFG_LINE, 4,
+ max98095_line_mode_text);
static const char * const max98095_dai_fltr[] = {
"Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
"Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
-static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
-};
-static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
-};
-static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
-};
+static SOC_ENUM_SINGLE_DECL(max98095_dai1_dac_filter_enum,
+ M98095_02E_DAI1_FILTERS, 0,
+ max98095_dai_fltr);
+static SOC_ENUM_SINGLE_DECL(max98095_dai2_dac_filter_enum,
+ M98095_038_DAI2_FILTERS, 0,
+ max98095_dai_fltr);
+static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum,
+ M98095_042_DAI3_FILTERS, 0,
+ max98095_dai_fltr);
static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2234,12 +2238,6 @@ static int max98095_probe(struct snd_soc_codec *codec)
struct i2c_client *client;
int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* reset the codec, the DSP core, and disable all interrupts */
max98095_reset(codec);
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index 82757ebf0301..4fdf5aaa236f 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -312,14 +312,6 @@ static int max9850_resume(struct snd_soc_codec *codec)
static int max9850_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* enable zero-detect */
snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
/* enable slew-rate control */
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index ec89b8f90a64..37d737e567a1 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -612,8 +612,8 @@ static int mc13783_probe(struct snd_soc_codec *codec)
struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
- ret = snd_soc_codec_set_cache_io(codec, 8, 24, SND_SOC_REGMAP);
+ ret = snd_soc_codec_set_cache_io(codec,
+ dev_get_regmap(codec->dev->parent, NULL));
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 577fb8776ce7..e661e8420e3d 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -586,16 +586,6 @@ static int ml26124_resume(struct snd_soc_codec *codec)
static int ml26124_probe(struct snd_soc_codec *codec)
{
- int ret;
- struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
- codec->control_data = priv->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Software Reset */
snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index ce199d375209..d4c229f0233f 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -1570,15 +1570,6 @@ static int rt5631_probe(struct snd_soc_codec *codec)
{
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
unsigned int val;
- int ret;
-
- codec->control_data = rt5631->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
if (val & 0x0002)
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 1a1e1150237d..13ccee43cfc5 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -1936,16 +1936,8 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
static int rt5640_probe(struct snd_soc_codec *codec)
{
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
- int ret;
rt5640->codec = codec;
- codec->control_data = rt5640->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
codec->dapm.idle_bias_off = 1;
rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index ab4754a7a88c..d3ed1be5a186 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1352,14 +1352,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
int ret;
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
- /* setup i2c data ops */
- codec->control_data = sgtl5000->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = sgtl5000_enable_regulators(codec);
if (ret)
return ret;
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index fa2b8e07f420..244c097cd905 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <linux/regmap.h>
#include <sound/soc.h>
#include <sound/initval.h>
@@ -209,8 +210,9 @@ out:
static int si476x_codec_probe(struct snd_soc_codec *codec)
{
- codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
- return snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+ struct regmap *regmap = dev_get_regmap(codec->dev->parent, NULL);
+
+ return snd_soc_codec_set_cache_io(codec, regmap);
}
static struct snd_soc_dai_ops si476x_dai_ops = {
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index bca7d02b362a..42dff26b3a2a 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -825,8 +825,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
{
pr_debug("codec_probe called\n");
- snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
-
/* PCM interface config
* This sets the pcm rx slot conguration to max 6 slots
* for max 4 dais (2 stereo and 2 mono)
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index 806f3d826ffb..56adb3e2def9 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -648,16 +648,6 @@ static struct snd_soc_dai_driver ssm2518_dai = {
static int ssm2518_probe(struct snd_soc_codec *codec)
{
- struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = ssm2518->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 12947096897c..97b0454eb346 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -562,13 +562,6 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec)
struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = ssm2602->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 2735361a4c3c..12577749b17b 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -872,16 +872,6 @@ static int sta32x_probe(struct snd_soc_codec *codec)
return ret;
}
- /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
- * then do the I2C transactions itself.
- */
- codec->control_data = sta32x->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
- goto err;
- }
-
/* Chip documentation explicitly requires that the reset values
* of reserved register bits are left untouched.
* Write the register default value to cache for reserved registers,
@@ -946,10 +936,6 @@ static int sta32x_probe(struct snd_soc_codec *codec)
regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
return 0;
-
-err:
- regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
- return ret;
}
static int sta32x_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index f15b0e37274c..a3c61d308bb0 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -322,16 +322,6 @@ static struct snd_soc_dai_driver sta529_dai = {
static int sta529_probe(struct snd_soc_codec *codec)
{
- struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = sta529->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index dc9a52fcb39a..20864ee8793b 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -559,14 +559,6 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Reset codec */
snd_soc_write(codec, TLV320AIC23_RESET, 0);
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index ff5f23d482b7..43069de3d56a 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -296,8 +296,6 @@ static int aic26_probe(struct snd_soc_codec *codec)
struct aic26 *aic26 = dev_get_drvdata(codec->dev);
int ret, reg;
- snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
-
aic26->codec = codec;
/* Reset the codec to power on defaults */
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
new file mode 100644
index 000000000000..e60e37b43a1b
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -0,0 +1,1295 @@
+/*
+ * ALSA SoC TLV320AIC31XX codec driver
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Jyri Sarha <jsarha@ti.com>
+ *
+ * Based on ground work by: Ajit Kulkarni <x0175765@ti.com>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * The TLV320AIC31xx series of audio codec is a low-power, highly integrated
+ * high performance codec which provides a stereo DAC, a mono ADC,
+ * and mono/stereo Class-D speaker driver.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+
+#include "tlv320aic31xx.h"
+
+static const struct reg_default aic31xx_reg_defaults[] = {
+ { AIC31XX_CLKMUX, 0x00 },
+ { AIC31XX_PLLPR, 0x11 },
+ { AIC31XX_PLLJ, 0x04 },
+ { AIC31XX_PLLDMSB, 0x00 },
+ { AIC31XX_PLLDLSB, 0x00 },
+ { AIC31XX_NDAC, 0x01 },
+ { AIC31XX_MDAC, 0x01 },
+ { AIC31XX_DOSRMSB, 0x00 },
+ { AIC31XX_DOSRLSB, 0x80 },
+ { AIC31XX_NADC, 0x01 },
+ { AIC31XX_MADC, 0x01 },
+ { AIC31XX_AOSR, 0x80 },
+ { AIC31XX_IFACE1, 0x00 },
+ { AIC31XX_DATA_OFFSET, 0x00 },
+ { AIC31XX_IFACE2, 0x00 },
+ { AIC31XX_BCLKN, 0x01 },
+ { AIC31XX_DACSETUP, 0x14 },
+ { AIC31XX_DACMUTE, 0x0c },
+ { AIC31XX_LDACVOL, 0x00 },
+ { AIC31XX_RDACVOL, 0x00 },
+ { AIC31XX_ADCSETUP, 0x00 },
+ { AIC31XX_ADCFGA, 0x80 },
+ { AIC31XX_ADCVOL, 0x00 },
+ { AIC31XX_HPDRIVER, 0x04 },
+ { AIC31XX_SPKAMP, 0x06 },
+ { AIC31XX_DACMIXERROUTE, 0x00 },
+ { AIC31XX_LANALOGHPL, 0x7f },
+ { AIC31XX_RANALOGHPR, 0x7f },
+ { AIC31XX_LANALOGSPL, 0x7f },
+ { AIC31XX_RANALOGSPR, 0x7f },
+ { AIC31XX_HPLGAIN, 0x02 },
+ { AIC31XX_HPRGAIN, 0x02 },
+ { AIC31XX_SPLGAIN, 0x00 },
+ { AIC31XX_SPRGAIN, 0x00 },
+ { AIC31XX_MICBIAS, 0x00 },
+ { AIC31XX_MICPGA, 0x80 },
+ { AIC31XX_MICPGAPI, 0x00 },
+ { AIC31XX_MICPGAMI, 0x00 },
+};
+
+static bool aic31xx_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case AIC31XX_PAGECTL: /* regmap implementation requires this */
+ case AIC31XX_RESET: /* always clears after write */
+ case AIC31XX_OT_FLAG:
+ case AIC31XX_ADCFLAG:
+ case AIC31XX_DACFLAG1:
+ case AIC31XX_DACFLAG2:
+ case AIC31XX_OFFLAG: /* Sticky interrupt flags */
+ case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */
+ case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */
+ case AIC31XX_INTRDACFLAG2:
+ case AIC31XX_INTRADCFLAG2:
+ return true;
+ }
+ return false;
+}
+
+static bool aic31xx_writeable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case AIC31XX_OT_FLAG:
+ case AIC31XX_ADCFLAG:
+ case AIC31XX_DACFLAG1:
+ case AIC31XX_DACFLAG2:
+ case AIC31XX_OFFLAG: /* Sticky interrupt flags */
+ case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */
+ case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */
+ case AIC31XX_INTRDACFLAG2:
+ case AIC31XX_INTRADCFLAG2:
+ return false;
+ }
+ return true;
+}
+
+static const struct regmap_range_cfg aic31xx_ranges[] = {
+ {
+ .range_min = 0,
+ .range_max = 12 * 128,
+ .selector_reg = AIC31XX_PAGECTL,
+ .selector_mask = 0xff,
+ .selector_shift = 0,
+ .window_start = 0,
+ .window_len = 128,
+ },
+};
+
+struct regmap_config aic31xx_i2c_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .writeable_reg = aic31xx_writeable,
+ .volatile_reg = aic31xx_volatile,
+ .reg_defaults = aic31xx_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(aic31xx_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+ .ranges = aic31xx_ranges,
+ .num_ranges = ARRAY_SIZE(aic31xx_ranges),
+ .max_register = 12 * 128,
+};
+
+#define AIC31XX_NUM_SUPPLIES 6
+static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = {
+ "HPVDD",
+ "SPRVDD",
+ "SPLVDD",
+ "AVDD",
+ "IOVDD",
+ "DVDD",
+};
+
+struct aic31xx_disable_nb {
+ struct notifier_block nb;
+ struct aic31xx_priv *aic31xx;
+};
+
+struct aic31xx_priv {
+ struct snd_soc_codec *codec;
+ u8 i2c_regs_status;
+ struct device *dev;
+ struct regmap *regmap;
+ struct aic31xx_pdata pdata;
+ struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
+ struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
+ unsigned int sysclk;
+ int rate_div_line;
+};
+
+struct aic31xx_rate_divs {
+ u32 mclk;
+ u32 rate;
+ u8 p_val;
+ u8 pll_j;
+ u16 pll_d;
+ u16 dosr;
+ u8 ndac;
+ u8 mdac;
+ u8 aosr;
+ u8 nadc;
+ u8 madc;
+};
+
+/* ADC dividers can be disabled by cofiguring them to 0 */
+static const struct aic31xx_rate_divs aic31xx_divs[] = {
+ /* mclk rate pll: p j d dosr ndac mdac aors nadc madc */
+ /* 8k rate */
+ {12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2},
+ {24000000, 8000, 2, 8, 1920, 128, 48, 2, 128, 48, 2},
+ {25000000, 8000, 2, 7, 8643, 128, 48, 2, 128, 48, 2},
+ /* 11.025k rate */
+ {12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2},
+ {24000000, 11025, 2, 7, 5264, 128, 32, 2, 128, 32, 2},
+ {25000000, 11025, 2, 7, 2253, 128, 32, 2, 128, 32, 2},
+ /* 16k rate */
+ {12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2},
+ {24000000, 16000, 2, 8, 1920, 128, 24, 2, 128, 24, 2},
+ {25000000, 16000, 2, 7, 8643, 128, 24, 2, 128, 24, 2},
+ /* 22.05k rate */
+ {12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2},
+ {24000000, 22050, 2, 7, 5264, 128, 16, 2, 128, 16, 2},
+ {25000000, 22050, 2, 7, 2253, 128, 16, 2, 128, 16, 2},
+ /* 32k rate */
+ {12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2},
+ {24000000, 32000, 2, 8, 1920, 128, 12, 2, 128, 12, 2},
+ {25000000, 32000, 2, 7, 8643, 128, 12, 2, 128, 12, 2},
+ /* 44.1k rate */
+ {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2},
+ {24000000, 44100, 2, 7, 5264, 128, 8, 2, 128, 8, 2},
+ {25000000, 44100, 2, 7, 2253, 128, 8, 2, 128, 8, 2},
+ /* 48k rate */
+ {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2},
+ {24000000, 48000, 2, 8, 1920, 128, 8, 2, 128, 8, 2},
+ {25000000, 48000, 2, 7, 8643, 128, 8, 2, 128, 8, 2},
+ /* 88.2k rate */
+ {12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2},
+ {24000000, 88200, 2, 7, 5264, 64, 8, 2, 64, 8, 2},
+ {25000000, 88200, 2, 7, 2253, 64, 8, 2, 64, 8, 2},
+ /* 96k rate */
+ {12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2},
+ {24000000, 96000, 2, 8, 1920, 64, 8, 2, 64, 8, 2},
+ {25000000, 96000, 2, 7, 8643, 64, 8, 2, 64, 8, 2},
+ /* 176.4k rate */
+ {12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2},
+ {24000000, 176400, 2, 7, 5264, 32, 8, 2, 32, 8, 2},
+ {25000000, 176400, 2, 7, 2253, 32, 8, 2, 32, 8, 2},
+ /* 192k rate */
+ {12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2},
+ {24000000, 192000, 2, 8, 1920, 32, 8, 2, 32, 8, 2},
+ {25000000, 192000, 2, 7, 8643, 32, 8, 2, 32, 8, 2},
+};
+
+static const char * const ldac_in_text[] = {
+ "Off", "Left Data", "Right Data", "Mono"
+};
+
+static const char * const rdac_in_text[] = {
+ "Off", "Right Data", "Left Data", "Mono"
+};
+
+static SOC_ENUM_SINGLE_DECL(ldac_in_enum, AIC31XX_DACSETUP, 4, ldac_in_text);
+
+static SOC_ENUM_SINGLE_DECL(rdac_in_enum, AIC31XX_DACSETUP, 2, rdac_in_text);
+
+static const char * const mic_select_text[] = {
+ "Off", "FFR 10 Ohm", "FFR 20 Ohm", "FFR 40 Ohm"
+};
+
+static const
+SOC_ENUM_SINGLE_DECL(mic1lp_p_enum, AIC31XX_MICPGAPI, 6, mic_select_text);
+static const
+SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4, mic_select_text);
+static const
+SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, mic_select_text);
+
+static const
+SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text);
+static const
+SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, mic_select_text);
+
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
+static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0);
+static const DECLARE_TLV_DB_SCALE(adc_cgain_tlv, -2000, 50, 0);
+static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, 0, 50, 0);
+static const DECLARE_TLV_DB_SCALE(hp_drv_tlv, 0, 100, 0);
+static const DECLARE_TLV_DB_SCALE(class_D_drv_tlv, 600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -6350, 50, 0);
+static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0);
+
+/*
+ * controls to be exported to the user space
+ */
+static const struct snd_kcontrol_new aic31xx_snd_controls[] = {
+ SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL,
+ AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv),
+
+ SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1,
+ adc_fgain_tlv),
+
+ SOC_SINGLE("ADC Capture Switch", AIC31XX_ADCFGA, 7, 1, 1),
+ SOC_DOUBLE_R_S_TLV("ADC Capture Volume", AIC31XX_ADCVOL, AIC31XX_ADCVOL,
+ 0, -24, 40, 6, 0, adc_cgain_tlv),
+
+ SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0,
+ 119, 0, mic_pga_tlv),
+
+ SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN,
+ AIC31XX_HPRGAIN, 2, 1, 0),
+ SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN,
+ AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv),
+
+ SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL,
+ AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv),
+};
+
+static const struct snd_kcontrol_new aic311x_snd_controls[] = {
+ SOC_DOUBLE_R("Speaker Driver Playback Switch", AIC31XX_SPLGAIN,
+ AIC31XX_SPRGAIN, 2, 1, 0),
+ SOC_DOUBLE_R_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN,
+ AIC31XX_SPRGAIN, 3, 3, 0, class_D_drv_tlv),
+
+ SOC_DOUBLE_R_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL,
+ AIC31XX_RANALOGSPR, 0, 0x7F, 1, sp_vol_tlv),
+};
+
+static const struct snd_kcontrol_new aic310x_snd_controls[] = {
+ SOC_SINGLE("Speaker Driver Playback Switch", AIC31XX_SPLGAIN,
+ 2, 1, 0),
+ SOC_SINGLE_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN,
+ 3, 3, 0, class_D_drv_tlv),
+
+ SOC_SINGLE_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL,
+ 0, 0x7F, 1, sp_vol_tlv),
+};
+
+static const struct snd_kcontrol_new ldac_in_control =
+ SOC_DAPM_ENUM("DAC Left Input", ldac_in_enum);
+
+static const struct snd_kcontrol_new rdac_in_control =
+ SOC_DAPM_ENUM("DAC Right Input", rdac_in_enum);
+
+int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
+ unsigned int mask, unsigned int wbits, int sleep,
+ int count)
+{
+ unsigned int bits;
+ int counter = count;
+ int ret = regmap_read(aic31xx->regmap, reg, &bits);
+ while ((bits & mask) != wbits && counter && !ret) {
+ usleep_range(sleep, sleep * 2);
+ ret = regmap_read(aic31xx->regmap, reg, &bits);
+ counter--;
+ }
+ if ((bits & mask) != wbits) {
+ dev_err(aic31xx->dev,
+ "%s: Failed! 0x%x was 0x%x expected 0x%x (%d, 0x%x, %d us)\n",
+ __func__, reg, bits, wbits, ret, mask,
+ (count - counter) * sleep);
+ ret = -1;
+ }
+ return ret;
+}
+
+#define WIDGET_BIT(reg, shift) (((shift) << 8) | (reg))
+
+static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(w->codec);
+ unsigned int reg = AIC31XX_DACFLAG1;
+ unsigned int mask;
+
+ switch (WIDGET_BIT(w->reg, w->shift)) {
+ case WIDGET_BIT(AIC31XX_DACSETUP, 7):
+ mask = AIC31XX_LDACPWRSTATUS_MASK;
+ break;
+ case WIDGET_BIT(AIC31XX_DACSETUP, 6):
+ mask = AIC31XX_RDACPWRSTATUS_MASK;
+ break;
+ case WIDGET_BIT(AIC31XX_HPDRIVER, 7):
+ mask = AIC31XX_HPLDRVPWRSTATUS_MASK;
+ break;
+ case WIDGET_BIT(AIC31XX_HPDRIVER, 6):
+ mask = AIC31XX_HPRDRVPWRSTATUS_MASK;
+ break;
+ case WIDGET_BIT(AIC31XX_SPKAMP, 7):
+ mask = AIC31XX_SPLDRVPWRSTATUS_MASK;
+ break;
+ case WIDGET_BIT(AIC31XX_SPKAMP, 6):
+ mask = AIC31XX_SPRDRVPWRSTATUS_MASK;
+ break;
+ case WIDGET_BIT(AIC31XX_ADCSETUP, 7):
+ mask = AIC31XX_ADCPWRSTATUS_MASK;
+ reg = AIC31XX_ADCFLAG;
+ break;
+ default:
+ dev_err(w->codec->dev, "Unknown widget '%s' calling %s/n",
+ w->name, __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100);
+ case SND_SOC_DAPM_POST_PMD:
+ return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
+ default:
+ dev_dbg(w->codec->dev,
+ "Unhandled dapm widget event %d from %s\n",
+ event, w->name);
+ }
+ return 0;
+}
+
+static const struct snd_kcontrol_new left_output_switches[] = {
+ SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0),
+ SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0),
+ SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0),
+};
+
+static const struct snd_kcontrol_new right_output_switches[] = {
+ SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0),
+ SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0),
+};
+
+static const struct snd_kcontrol_new p_term_mic1lp =
+ SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum);
+
+static const struct snd_kcontrol_new p_term_mic1rp =
+ SOC_DAPM_ENUM("MIC1RP P-Terminal", mic1rp_p_enum);
+
+static const struct snd_kcontrol_new p_term_mic1lm =
+ SOC_DAPM_ENUM("MIC1LM P-Terminal", mic1lm_p_enum);
+
+static const struct snd_kcontrol_new m_term_mic1lm =
+ SOC_DAPM_ENUM("MIC1LM M-Terminal", mic1lm_m_enum);
+
+static const struct snd_kcontrol_new aic31xx_dapm_hpl_switch =
+ SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGHPL, 7, 1, 0);
+
+static const struct snd_kcontrol_new aic31xx_dapm_hpr_switch =
+ SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGHPR, 7, 1, 0);
+
+static const struct snd_kcontrol_new aic31xx_dapm_spl_switch =
+ SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGSPL, 7, 1, 0);
+
+static const struct snd_kcontrol_new aic31xx_dapm_spr_switch =
+ SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGSPR, 7, 1, 0);
+
+static int mic_bias_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ /* change mic bias voltage to user defined */
+ snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+ AIC31XX_MICBIAS_MASK,
+ aic31xx->pdata.micbias_vg <<
+ AIC31XX_MICBIAS_SHIFT);
+ dev_dbg(codec->dev, "%s: turned on\n", __func__);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ /* turn mic bias off */
+ snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+ AIC31XX_MICBIAS_MASK, 0);
+ dev_dbg(codec->dev, "%s: turned off\n", __func__);
+ break;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_MUX("DAC Left Input",
+ SND_SOC_NOPM, 0, 0, &ldac_in_control),
+ SND_SOC_DAPM_MUX("DAC Right Input",
+ SND_SOC_NOPM, 0, 0, &rdac_in_control),
+ /* DACs */
+ SND_SOC_DAPM_DAC_E("DAC Left", "Left Playback",
+ AIC31XX_DACSETUP, 7, 0, aic31xx_dapm_power_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("DAC Right", "Right Playback",
+ AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* Output Mixers */
+ SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0,
+ left_output_switches,
+ ARRAY_SIZE(left_output_switches)),
+ SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
+ right_output_switches,
+ ARRAY_SIZE(right_output_switches)),
+
+ SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0,
+ &aic31xx_dapm_hpl_switch),
+ SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0,
+ &aic31xx_dapm_hpr_switch),
+
+ /* Output drivers */
+ SND_SOC_DAPM_OUT_DRV_E("HPL Driver", AIC31XX_HPDRIVER, 7, 0,
+ NULL, 0, aic31xx_dapm_power_event,
+ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_OUT_DRV_E("HPR Driver", AIC31XX_HPDRIVER, 6, 0,
+ NULL, 0, aic31xx_dapm_power_event,
+ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+
+ /* ADC */
+ SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0,
+ aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ /* Input Selection to MIC_PGA */
+ SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0,
+ &p_term_mic1lp),
+ SND_SOC_DAPM_MUX("MIC1RP P-Terminal", SND_SOC_NOPM, 0, 0,
+ &p_term_mic1rp),
+ SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0,
+ &p_term_mic1lm),
+
+ SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0,
+ &m_term_mic1lm),
+ /* Enabling & Disabling MIC Gain Ctl */
+ SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA,
+ 7, 1, NULL, 0),
+
+ /* Mic Bias */
+ SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ /* Outputs */
+ SND_SOC_DAPM_OUTPUT("HPL"),
+ SND_SOC_DAPM_OUTPUT("HPR"),
+
+ /* Inputs */
+ SND_SOC_DAPM_INPUT("MIC1LP"),
+ SND_SOC_DAPM_INPUT("MIC1RP"),
+ SND_SOC_DAPM_INPUT("MIC1LM"),
+};
+
+static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = {
+ /* AIC3111 and AIC3110 have stereo class-D amplifier */
+ SND_SOC_DAPM_OUT_DRV_E("SPL ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0,
+ aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_OUT_DRV_E("SPR ClassD", AIC31XX_SPKAMP, 6, 0, NULL, 0,
+ aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SWITCH("Speaker Left", SND_SOC_NOPM, 0, 0,
+ &aic31xx_dapm_spl_switch),
+ SND_SOC_DAPM_SWITCH("Speaker Right", SND_SOC_NOPM, 0, 0,
+ &aic31xx_dapm_spr_switch),
+ SND_SOC_DAPM_OUTPUT("SPL"),
+ SND_SOC_DAPM_OUTPUT("SPR"),
+};
+
+/* AIC3100 and AIC3120 have only mono class-D amplifier */
+static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = {
+ SND_SOC_DAPM_OUT_DRV_E("SPK ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0,
+ aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SWITCH("Speaker", SND_SOC_NOPM, 0, 0,
+ &aic31xx_dapm_spl_switch),
+ SND_SOC_DAPM_OUTPUT("SPK"),
+};
+
+static const struct snd_soc_dapm_route
+aic31xx_audio_map[] = {
+ /* DAC Input Routing */
+ {"DAC Left Input", "Left Data", "DAC IN"},
+ {"DAC Left Input", "Right Data", "DAC IN"},
+ {"DAC Left Input", "Mono", "DAC IN"},
+ {"DAC Right Input", "Left Data", "DAC IN"},
+ {"DAC Right Input", "Right Data", "DAC IN"},
+ {"DAC Right Input", "Mono", "DAC IN"},
+ {"DAC Left", NULL, "DAC Left Input"},
+ {"DAC Right", NULL, "DAC Right Input"},
+
+ /* Mic input */
+ {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
+ {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
+ {"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
+ {"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
+ {"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
+ {"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
+ {"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
+ {"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
+ {"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
+
+ {"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
+ {"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
+ {"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
+
+ {"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
+ {"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
+ {"MIC_GAIN_CTL", NULL, "MIC1LM P-Terminal"},
+ {"MIC_GAIN_CTL", NULL, "MIC1LM M-Terminal"},
+
+ {"ADC", NULL, "MIC_GAIN_CTL"},
+
+ /* Left Output */
+ {"Output Left", "From Left DAC", "DAC Left"},
+ {"Output Left", "From MIC1LP", "MIC1LP"},
+ {"Output Left", "From MIC1RP", "MIC1RP"},
+
+ /* Right Output */
+ {"Output Right", "From Right DAC", "DAC Right"},
+ {"Output Right", "From MIC1RP", "MIC1RP"},
+
+ /* HPL path */
+ {"HP Left", "Switch", "Output Left"},
+ {"HPL Driver", NULL, "HP Left"},
+ {"HPL", NULL, "HPL Driver"},
+
+ /* HPR path */
+ {"HP Right", "Switch", "Output Right"},
+ {"HPR Driver", NULL, "HP Right"},
+ {"HPR", NULL, "HPR Driver"},
+};
+
+static const struct snd_soc_dapm_route
+aic311x_audio_map[] = {
+ /* SP L path */
+ {"Speaker Left", "Switch", "Output Left"},
+ {"SPL ClassD", NULL, "Speaker Left"},
+ {"SPL", NULL, "SPL ClassD"},
+
+ /* SP R path */
+ {"Speaker Right", "Switch", "Output Right"},
+ {"SPR ClassD", NULL, "Speaker Right"},
+ {"SPR", NULL, "SPR ClassD"},
+};
+
+static const struct snd_soc_dapm_route
+aic310x_audio_map[] = {
+ /* SP L path */
+ {"Speaker", "Switch", "Output Left"},
+ {"SPK ClassD", NULL, "Speaker"},
+ {"SPK", NULL, "SPK ClassD"},
+};
+
+static int aic31xx_add_controls(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+
+ if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT)
+ ret = snd_soc_add_codec_controls(
+ codec, aic311x_snd_controls,
+ ARRAY_SIZE(aic311x_snd_controls));
+ else
+ ret = snd_soc_add_codec_controls(
+ codec, aic310x_snd_controls,
+ ARRAY_SIZE(aic310x_snd_controls));
+
+ return ret;
+}
+
+static int aic31xx_add_widgets(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) {
+ ret = snd_soc_dapm_new_controls(
+ dapm, aic311x_dapm_widgets,
+ ARRAY_SIZE(aic311x_dapm_widgets));
+ if (ret)
+ return ret;
+
+ ret = snd_soc_dapm_add_routes(dapm, aic311x_audio_map,
+ ARRAY_SIZE(aic311x_audio_map));
+ if (ret)
+ return ret;
+ } else {
+ ret = snd_soc_dapm_new_controls(
+ dapm, aic310x_dapm_widgets,
+ ARRAY_SIZE(aic310x_dapm_widgets));
+ if (ret)
+ return ret;
+
+ ret = snd_soc_dapm_add_routes(dapm, aic310x_audio_map,
+ ARRAY_SIZE(aic310x_audio_map));
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int aic31xx_setup_pll(struct snd_soc_codec *codec,
+ struct snd_pcm_hw_params *params)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int bclk_n = 0;
+ int i;
+
+ /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
+ snd_soc_update_bits(codec, AIC31XX_CLKMUX,
+ AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL);
+ snd_soc_update_bits(codec, AIC31XX_IFACE2,
+ AIC31XX_BDIVCLK_MASK, AIC31XX_DAC2BCLK);
+
+ for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
+ if (aic31xx_divs[i].rate == params_rate(params) &&
+ aic31xx_divs[i].mclk == aic31xx->sysclk)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(aic31xx_divs)) {
+ dev_err(codec->dev, "%s: Sampling rate %u not supported\n",
+ __func__, params_rate(params));
+ return -EINVAL;
+ }
+
+ /* PLL configuration */
+ snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
+ (aic31xx_divs[i].p_val << 4) | 0x01);
+ snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
+
+ snd_soc_write(codec, AIC31XX_PLLDMSB,
+ aic31xx_divs[i].pll_d >> 8);
+ snd_soc_write(codec, AIC31XX_PLLDLSB,
+ aic31xx_divs[i].pll_d & 0xff);
+
+ /* DAC dividers configuration */
+ snd_soc_update_bits(codec, AIC31XX_NDAC, AIC31XX_PLL_MASK,
+ aic31xx_divs[i].ndac);
+ snd_soc_update_bits(codec, AIC31XX_MDAC, AIC31XX_PLL_MASK,
+ aic31xx_divs[i].mdac);
+
+ snd_soc_write(codec, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8);
+ snd_soc_write(codec, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff);
+
+ /* ADC dividers configuration. Write reset value 1 if not used. */
+ snd_soc_update_bits(codec, AIC31XX_NADC, AIC31XX_PLL_MASK,
+ aic31xx_divs[i].nadc ? aic31xx_divs[i].nadc : 1);
+ snd_soc_update_bits(codec, AIC31XX_MADC, AIC31XX_PLL_MASK,
+ aic31xx_divs[i].madc ? aic31xx_divs[i].madc : 1);
+
+ snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr);
+
+ /* Bit clock divider configuration. */
+ bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac)
+ / snd_soc_params_to_frame_size(params);
+ if (bclk_n == 0) {
+ dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, AIC31XX_BCLKN,
+ AIC31XX_PLL_MASK, bclk_n);
+
+ aic31xx->rate_div_line = i;
+
+ dev_dbg(codec->dev,
+ "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n",
+ aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d,
+ aic31xx_divs[i].p_val, aic31xx_divs[i].dosr,
+ aic31xx_divs[i].ndac, aic31xx_divs[i].mdac,
+ aic31xx_divs[i].aosr, aic31xx_divs[i].nadc,
+ aic31xx_divs[i].madc, bclk_n);
+
+ return 0;
+}
+
+static int aic31xx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *tmp)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ u8 data = 0;
+
+ dev_dbg(codec->dev, "## %s: format %d width %d rate %d\n",
+ __func__, params_format(params), params_width(params),
+ params_rate(params));
+
+ switch (params_width(params)) {
+ case 16:
+ break;
+ case 20:
+ data = (AIC31XX_WORD_LEN_20BITS <<
+ AIC31XX_IFACE1_DATALEN_SHIFT);
+ break;
+ case 24:
+ data = (AIC31XX_WORD_LEN_24BITS <<
+ AIC31XX_IFACE1_DATALEN_SHIFT);
+ break;
+ case 32:
+ data = (AIC31XX_WORD_LEN_32BITS <<
+ AIC31XX_IFACE1_DATALEN_SHIFT);
+ break;
+ default:
+ dev_err(codec->dev, "%s: Unsupported format %d\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, AIC31XX_IFACE1,
+ AIC31XX_IFACE1_DATALEN_MASK,
+ data);
+
+ return aic31xx_setup_pll(codec, params);
+}
+
+static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+
+ if (mute) {
+ snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+ AIC31XX_DACMUTE_MASK,
+ AIC31XX_DACMUTE_MASK);
+ } else {
+ snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+ AIC31XX_DACMUTE_MASK, 0x0);
+ }
+
+ return 0;
+}
+
+static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 iface_reg1 = 0;
+ u8 iface_reg3 = 0;
+ u8 dsp_a_val = 0;
+
+ dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER;
+ break;
+ default:
+ dev_alert(codec->dev, "Invalid DAI master/slave interface\n");
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ dsp_a_val = 0x1;
+ case SND_SOC_DAIFMT_DSP_B:
+ /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ iface_reg3 |= AIC31XX_BCLKINV_MASK;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ break;
+ default:
+ return -EINVAL;
+ }
+ iface_reg1 |= (AIC31XX_DSP_MODE <<
+ AIC31XX_IFACE1_DATATYPE_SHIFT);
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ iface_reg1 |= (AIC31XX_RIGHT_JUSTIFIED_MODE <<
+ AIC31XX_IFACE1_DATATYPE_SHIFT);
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface_reg1 |= (AIC31XX_LEFT_JUSTIFIED_MODE <<
+ AIC31XX_IFACE1_DATATYPE_SHIFT);
+ break;
+ default:
+ dev_err(codec->dev, "Invalid DAI interface format\n");
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, AIC31XX_IFACE1,
+ AIC31XX_IFACE1_DATATYPE_MASK |
+ AIC31XX_IFACE1_MASTER_MASK,
+ iface_reg1);
+ snd_soc_update_bits(codec, AIC31XX_DATA_OFFSET,
+ AIC31XX_DATA_OFFSET_MASK,
+ dsp_a_val);
+ snd_soc_update_bits(codec, AIC31XX_IFACE2,
+ AIC31XX_BCLKINV_MASK,
+ iface_reg3);
+
+ return 0;
+}
+
+static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
+ __func__, clk_id, freq, dir);
+
+ for (i = 0; aic31xx_divs[i].mclk != freq; i++) {
+ if (i == ARRAY_SIZE(aic31xx_divs)) {
+ dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n",
+ __func__, freq);
+ return -EINVAL;
+ }
+ }
+
+ /* set clock on MCLK, BCLK, or GPIO1 as PLL input */
+ snd_soc_update_bits(codec, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
+ clk_id << AIC31XX_PLL_CLKIN_SHIFT);
+
+ aic31xx->sysclk = freq;
+ return 0;
+}
+
+static int aic31xx_regulator_event(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct aic31xx_disable_nb *disable_nb =
+ container_of(nb, struct aic31xx_disable_nb, nb);
+ struct aic31xx_priv *aic31xx = disable_nb->aic31xx;
+
+ if (event & REGULATOR_EVENT_DISABLE) {
+ /*
+ * Put codec to reset and as at least one of the
+ * supplies was disabled.
+ */
+ if (gpio_is_valid(aic31xx->pdata.gpio_reset))
+ gpio_set_value(aic31xx->pdata.gpio_reset, 0);
+
+ regcache_mark_dirty(aic31xx->regmap);
+ dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__);
+ }
+
+ return 0;
+}
+
+static void aic31xx_clk_on(struct snd_soc_codec *codec)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ u8 mask = AIC31XX_PM_MASK;
+ u8 on = AIC31XX_PM_MASK;
+
+ dev_dbg(codec->dev, "codec clock -> on (rate %d)\n",
+ aic31xx_divs[aic31xx->rate_div_line].rate);
+ snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, on);
+ mdelay(10);
+ snd_soc_update_bits(codec, AIC31XX_NDAC, mask, on);
+ snd_soc_update_bits(codec, AIC31XX_MDAC, mask, on);
+ if (aic31xx_divs[aic31xx->rate_div_line].nadc)
+ snd_soc_update_bits(codec, AIC31XX_NADC, mask, on);
+ if (aic31xx_divs[aic31xx->rate_div_line].madc)
+ snd_soc_update_bits(codec, AIC31XX_MADC, mask, on);
+ snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, on);
+}
+
+static void aic31xx_clk_off(struct snd_soc_codec *codec)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ u8 mask = AIC31XX_PM_MASK;
+ u8 off = 0;
+
+ dev_dbg(codec->dev, "codec clock -> off\n");
+ snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, off);
+ snd_soc_update_bits(codec, AIC31XX_MADC, mask, off);
+ snd_soc_update_bits(codec, AIC31XX_NADC, mask, off);
+ snd_soc_update_bits(codec, AIC31XX_MDAC, mask, off);
+ snd_soc_update_bits(codec, AIC31XX_NDAC, mask, off);
+ snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, off);
+}
+
+static int aic31xx_power_on(struct snd_soc_codec *codec)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies),
+ aic31xx->supplies);
+ if (ret)
+ return ret;
+
+ if (gpio_is_valid(aic31xx->pdata.gpio_reset)) {
+ gpio_set_value(aic31xx->pdata.gpio_reset, 1);
+ udelay(100);
+ }
+ regcache_cache_only(aic31xx->regmap, false);
+ ret = regcache_sync(aic31xx->regmap);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to restore cache: %d\n", ret);
+ regcache_cache_only(aic31xx->regmap, true);
+ regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
+ aic31xx->supplies);
+ return ret;
+ }
+ return 0;
+}
+
+static int aic31xx_power_off(struct snd_soc_codec *codec)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ regcache_cache_only(aic31xx->regmap, true);
+ ret = regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
+ aic31xx->supplies);
+
+ return ret;
+}
+
+static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
+ codec->dapm.bias_level, level);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+ aic31xx_clk_on(codec);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ switch (codec->dapm.bias_level) {
+ case SND_SOC_BIAS_OFF:
+ aic31xx_power_on(codec);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ aic31xx_clk_off(codec);
+ break;
+ default:
+ BUG();
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ aic31xx_power_off(codec);
+ break;
+ }
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int aic31xx_suspend(struct snd_soc_codec *codec)
+{
+ aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int aic31xx_resume(struct snd_soc_codec *codec)
+{
+ aic31xx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+
+static int aic31xx_codec_probe(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ dev_dbg(aic31xx->dev, "## %s\n", __func__);
+
+ aic31xx = snd_soc_codec_get_drvdata(codec);
+ codec->control_data = aic31xx->regmap;
+
+ aic31xx->codec = codec;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+
+ if (ret != 0) {
+ dev_err(codec->dev, "snd_soc_codec_set_cache_io failed %d\n",
+ ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
+ aic31xx->disable_nb[i].nb.notifier_call =
+ aic31xx_regulator_event;
+ aic31xx->disable_nb[i].aic31xx = aic31xx;
+ ret = regulator_register_notifier(aic31xx->supplies[i].consumer,
+ &aic31xx->disable_nb[i].nb);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to request regulator notifier: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ regcache_cache_only(aic31xx->regmap, true);
+ regcache_mark_dirty(aic31xx->regmap);
+
+ ret = aic31xx_add_controls(codec);
+ if (ret)
+ return ret;
+
+ ret = aic31xx_add_widgets(codec);
+
+ return ret;
+}
+
+static int aic31xx_codec_remove(struct snd_soc_codec *codec)
+{
+ struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int i;
+ /* power down chip */
+ aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
+ regulator_unregister_notifier(aic31xx->supplies[i].consumer,
+ &aic31xx->disable_nb[i].nb);
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_driver_aic31xx = {
+ .probe = aic31xx_codec_probe,
+ .remove = aic31xx_codec_remove,
+ .suspend = aic31xx_suspend,
+ .resume = aic31xx_resume,
+ .set_bias_level = aic31xx_set_bias_level,
+ .controls = aic31xx_snd_controls,
+ .num_controls = ARRAY_SIZE(aic31xx_snd_controls),
+ .dapm_widgets = aic31xx_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(aic31xx_dapm_widgets),
+ .dapm_routes = aic31xx_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(aic31xx_audio_map),
+};
+
+static struct snd_soc_dai_ops aic31xx_dai_ops = {
+ .hw_params = aic31xx_hw_params,
+ .set_sysclk = aic31xx_set_dai_sysclk,
+ .set_fmt = aic31xx_set_dai_fmt,
+ .digital_mute = aic31xx_dac_mute,
+};
+
+static struct snd_soc_dai_driver aic31xx_dai_driver[] = {
+ {
+ .name = "tlv320aic31xx-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AIC31XX_RATES,
+ .formats = AIC31XX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AIC31XX_RATES,
+ .formats = AIC31XX_FORMATS,
+ },
+ .ops = &aic31xx_dai_ops,
+ .symmetric_rates = 1,
+ }
+};
+
+#if defined(CONFIG_OF)
+static const struct of_device_id tlv320aic31xx_of_match[] = {
+ { .compatible = "ti,tlv320aic310x" },
+ { .compatible = "ti,tlv320aic311x" },
+ { .compatible = "ti,tlv320aic3100" },
+ { .compatible = "ti,tlv320aic3110" },
+ { .compatible = "ti,tlv320aic3120" },
+ { .compatible = "ti,tlv320aic3111" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match);
+
+static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
+{
+ struct device_node *np = aic31xx->dev->of_node;
+ unsigned int value = MICBIAS_2_0V;
+ int ret;
+
+ of_property_read_u32(np, "ai31xx-micbias-vg", &value);
+ switch (value) {
+ case MICBIAS_2_0V:
+ case MICBIAS_2_5V:
+ case MICBIAS_AVDDV:
+ aic31xx->pdata.micbias_vg = value;
+ break;
+ default:
+ dev_err(aic31xx->dev,
+ "Bad ai31xx-micbias-vg value %d DT\n",
+ value);
+ aic31xx->pdata.micbias_vg = MICBIAS_2_0V;
+ }
+
+ ret = of_get_named_gpio(np, "gpio-reset", 0);
+ if (ret > 0)
+ aic31xx->pdata.gpio_reset = ret;
+}
+#else /* CONFIG_OF */
+static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
+{
+}
+#endif /* CONFIG_OF */
+
+void aic31xx_device_init(struct aic31xx_priv *aic31xx)
+{
+ int ret, i;
+
+ dev_set_drvdata(aic31xx->dev, aic31xx);
+
+ if (dev_get_platdata(aic31xx->dev))
+ memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev),
+ sizeof(aic31xx->pdata));
+ else if (aic31xx->dev->of_node)
+ aic31xx_pdata_from_of(aic31xx);
+
+ if (aic31xx->pdata.gpio_reset) {
+ ret = devm_gpio_request_one(aic31xx->dev,
+ aic31xx->pdata.gpio_reset,
+ GPIOF_OUT_INIT_HIGH,
+ "aic31xx-reset-pin");
+ if (ret < 0) {
+ dev_err(aic31xx->dev, "not able to acquire gpio\n");
+ return;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
+ aic31xx->supplies[i].supply = aic31xx_supply_names[i];
+
+ ret = devm_regulator_bulk_get(aic31xx->dev,
+ ARRAY_SIZE(aic31xx->supplies),
+ aic31xx->supplies);
+ if (ret != 0)
+ dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret);
+
+}
+
+static int aic31xx_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct aic31xx_priv *aic31xx;
+ int ret;
+ const struct regmap_config *regmap_config;
+
+ dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__,
+ id->name, (int) id->driver_data);
+
+ regmap_config = &aic31xx_i2c_regmap;
+
+ aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL);
+ if (aic31xx == NULL)
+ return -ENOMEM;
+
+ aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config);
+
+ if (IS_ERR(aic31xx->regmap)) {
+ ret = PTR_ERR(aic31xx->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+ aic31xx->dev = &i2c->dev;
+
+ aic31xx->pdata.codec_type = id->driver_data;
+
+ aic31xx_device_init(aic31xx);
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx,
+ aic31xx_dai_driver,
+ ARRAY_SIZE(aic31xx_dai_driver));
+
+ return ret;
+}
+
+static int aic31xx_i2c_remove(struct i2c_client *i2c)
+{
+ struct aic31xx_priv *aic31xx = dev_get_drvdata(&i2c->dev);
+
+ kfree(aic31xx);
+ return 0;
+}
+
+static const struct i2c_device_id aic31xx_i2c_id[] = {
+ { "tlv320aic310x", AIC3100 },
+ { "tlv320aic311x", AIC3110 },
+ { "tlv320aic3100", AIC3100 },
+ { "tlv320aic3110", AIC3110 },
+ { "tlv320aic3120", AIC3120 },
+ { "tlv320aic3111", AIC3111 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id);
+
+static struct i2c_driver aic31xx_i2c_driver = {
+ .driver = {
+ .name = "tlv320aic31xx-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(tlv320aic31xx_of_match),
+ },
+ .probe = aic31xx_i2c_probe,
+ .remove = (aic31xx_i2c_remove),
+ .id_table = aic31xx_i2c_id,
+};
+
+module_i2c_driver(aic31xx_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC TLV320AIC3111 codec driver");
+MODULE_AUTHOR("Jyri Sarha");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h
new file mode 100644
index 000000000000..52ed57c69dfa
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic31xx.h
@@ -0,0 +1,258 @@
+/*
+ * ALSA SoC TLV320AIC31XX codec driver
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#ifndef _TLV320AIC31XX_H
+#define _TLV320AIC31XX_H
+
+#define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000
+
+#define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
+ | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+
+#define AIC31XX_STEREO_CLASS_D_BIT 0x1
+#define AIC31XX_MINIDSP_BIT 0x2
+
+enum aic31xx_type {
+ AIC3100 = 0,
+ AIC3110 = AIC31XX_STEREO_CLASS_D_BIT,
+ AIC3120 = AIC31XX_MINIDSP_BIT,
+ AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT),
+};
+
+struct aic31xx_pdata {
+ enum aic31xx_type codec_type;
+ unsigned int gpio_reset;
+ int micbias_vg;
+};
+
+/* Page Control Register */
+#define AIC31XX_PAGECTL 0x00
+
+/* Page 0 Registers */
+/* Software reset register */
+#define AIC31XX_RESET 0x01
+/* OT FLAG register */
+#define AIC31XX_OT_FLAG 0x03
+/* Clock clock Gen muxing, Multiplexers*/
+#define AIC31XX_CLKMUX 0x04
+/* PLL P and R-VAL register */
+#define AIC31XX_PLLPR 0x05
+/* PLL J-VAL register */
+#define AIC31XX_PLLJ 0x06
+/* PLL D-VAL MSB register */
+#define AIC31XX_PLLDMSB 0x07
+/* PLL D-VAL LSB register */
+#define AIC31XX_PLLDLSB 0x08
+/* DAC NDAC_VAL register*/
+#define AIC31XX_NDAC 0x0B
+/* DAC MDAC_VAL register */
+#define AIC31XX_MDAC 0x0C
+/* DAC OSR setting register 1, MSB value */
+#define AIC31XX_DOSRMSB 0x0D
+/* DAC OSR setting register 2, LSB value */
+#define AIC31XX_DOSRLSB 0x0E
+#define AIC31XX_MINI_DSP_INPOL 0x10
+/* Clock setting register 8, PLL */
+#define AIC31XX_NADC 0x12
+/* Clock setting register 9, PLL */
+#define AIC31XX_MADC 0x13
+/* ADC Oversampling (AOSR) Register */
+#define AIC31XX_AOSR 0x14
+/* Clock setting register 9, Multiplexers */
+#define AIC31XX_CLKOUTMUX 0x19
+/* Clock setting register 10, CLOCKOUT M divider value */
+#define AIC31XX_CLKOUTMVAL 0x1A
+/* Audio Interface Setting Register 1 */
+#define AIC31XX_IFACE1 0x1B
+/* Audio Data Slot Offset Programming */
+#define AIC31XX_DATA_OFFSET 0x1C
+/* Audio Interface Setting Register 2 */
+#define AIC31XX_IFACE2 0x1D
+/* Clock setting register 11, BCLK N Divider */
+#define AIC31XX_BCLKN 0x1E
+/* Audio Interface Setting Register 3, Secondary Audio Interface */
+#define AIC31XX_IFACESEC1 0x1F
+/* Audio Interface Setting Register 4 */
+#define AIC31XX_IFACESEC2 0x20
+/* Audio Interface Setting Register 5 */
+#define AIC31XX_IFACESEC3 0x21
+/* I2C Bus Condition */
+#define AIC31XX_I2C 0x22
+/* ADC FLAG */
+#define AIC31XX_ADCFLAG 0x24
+/* DAC Flag Registers */
+#define AIC31XX_DACFLAG1 0x25
+#define AIC31XX_DACFLAG2 0x26
+/* Sticky Interrupt flag (overflow) */
+#define AIC31XX_OFFLAG 0x27
+/* Sticy DAC Interrupt flags */
+#define AIC31XX_INTRDACFLAG 0x2C
+/* Sticy ADC Interrupt flags */
+#define AIC31XX_INTRADCFLAG 0x2D
+/* DAC Interrupt flags 2 */
+#define AIC31XX_INTRDACFLAG2 0x2E
+/* ADC Interrupt flags 2 */
+#define AIC31XX_INTRADCFLAG2 0x2F
+/* INT1 interrupt control */
+#define AIC31XX_INT1CTRL 0x30
+/* INT2 interrupt control */
+#define AIC31XX_INT2CTRL 0x31
+/* GPIO1 control */
+#define AIC31XX_GPIO1 0x33
+
+#define AIC31XX_DACPRB 0x3C
+/* ADC Instruction Set Register */
+#define AIC31XX_ADCPRB 0x3D
+/* DAC channel setup register */
+#define AIC31XX_DACSETUP 0x3F
+/* DAC Mute and volume control register */
+#define AIC31XX_DACMUTE 0x40
+/* Left DAC channel digital volume control */
+#define AIC31XX_LDACVOL 0x41
+/* Right DAC channel digital volume control */
+#define AIC31XX_RDACVOL 0x42
+/* Headset detection */
+#define AIC31XX_HSDETECT 0x43
+/* ADC Digital Mic */
+#define AIC31XX_ADCSETUP 0x51
+/* ADC Digital Volume Control Fine Adjust */
+#define AIC31XX_ADCFGA 0x52
+/* ADC Digital Volume Control Coarse Adjust */
+#define AIC31XX_ADCVOL 0x53
+
+
+/* Page 1 Registers */
+/* Headphone drivers */
+#define AIC31XX_HPDRIVER 0x9F
+/* Class-D Speakear Amplifier */
+#define AIC31XX_SPKAMP 0xA0
+/* HP Output Drivers POP Removal Settings */
+#define AIC31XX_HPPOP 0xA1
+/* Output Driver PGA Ramp-Down Period Control */
+#define AIC31XX_SPPGARAMP 0xA2
+/* DAC_L and DAC_R Output Mixer Routing */
+#define AIC31XX_DACMIXERROUTE 0xA3
+/* Left Analog Vol to HPL */
+#define AIC31XX_LANALOGHPL 0xA4
+/* Right Analog Vol to HPR */
+#define AIC31XX_RANALOGHPR 0xA5
+/* Left Analog Vol to SPL */
+#define AIC31XX_LANALOGSPL 0xA6
+/* Right Analog Vol to SPR */
+#define AIC31XX_RANALOGSPR 0xA7
+/* HPL Driver */
+#define AIC31XX_HPLGAIN 0xA8
+/* HPR Driver */
+#define AIC31XX_HPRGAIN 0xA9
+/* SPL Driver */
+#define AIC31XX_SPLGAIN 0xAA
+/* SPR Driver */
+#define AIC31XX_SPRGAIN 0xAB
+/* HP Driver Control */
+#define AIC31XX_HPCONTROL 0xAC
+/* MIC Bias Control */
+#define AIC31XX_MICBIAS 0xAE
+/* MIC PGA*/
+#define AIC31XX_MICPGA 0xAF
+/* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */
+#define AIC31XX_MICPGAPI 0xB0
+/* ADC Input Selection for M-Terminal */
+#define AIC31XX_MICPGAMI 0xB1
+/* Input CM Settings */
+#define AIC31XX_MICPGACM 0xB2
+
+/* Bits, masks and shifts */
+
+/* AIC31XX_CLKMUX */
+#define AIC31XX_PLL_CLKIN_MASK 0x0c
+#define AIC31XX_PLL_CLKIN_SHIFT 2
+#define AIC31XX_PLL_CLKIN_MCLK 0
+#define AIC31XX_CODEC_CLKIN_MASK 0x03
+#define AIC31XX_CODEC_CLKIN_SHIFT 0
+#define AIC31XX_CODEC_CLKIN_PLL 3
+#define AIC31XX_CODEC_CLKIN_BCLK 1
+
+/* AIC31XX_PLLPR, AIC31XX_NDAC, AIC31XX_MDAC, AIC31XX_NADC, AIC31XX_MADC,
+ AIC31XX_BCLKN */
+#define AIC31XX_PLL_MASK 0x7f
+#define AIC31XX_PM_MASK 0x80
+
+/* AIC31XX_IFACE1 */
+#define AIC31XX_WORD_LEN_16BITS 0x00
+#define AIC31XX_WORD_LEN_20BITS 0x01
+#define AIC31XX_WORD_LEN_24BITS 0x02
+#define AIC31XX_WORD_LEN_32BITS 0x03
+#define AIC31XX_IFACE1_DATALEN_MASK 0x30
+#define AIC31XX_IFACE1_DATALEN_SHIFT (4)
+#define AIC31XX_IFACE1_DATATYPE_MASK 0xC0
+#define AIC31XX_IFACE1_DATATYPE_SHIFT (6)
+#define AIC31XX_I2S_MODE 0x00
+#define AIC31XX_DSP_MODE 0x01
+#define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02
+#define AIC31XX_LEFT_JUSTIFIED_MODE 0x03
+#define AIC31XX_IFACE1_MASTER_MASK 0x0C
+#define AIC31XX_BCLK_MASTER 0x08
+#define AIC31XX_WCLK_MASTER 0x04
+
+/* AIC31XX_DATA_OFFSET */
+#define AIC31XX_DATA_OFFSET_MASK 0xFF
+
+/* AIC31XX_IFACE2 */
+#define AIC31XX_BCLKINV_MASK 0x08
+#define AIC31XX_BDIVCLK_MASK 0x03
+#define AIC31XX_DAC2BCLK 0x00
+#define AIC31XX_DACMOD2BCLK 0x01
+#define AIC31XX_ADC2BCLK 0x02
+#define AIC31XX_ADCMOD2BCLK 0x03
+
+/* AIC31XX_ADCFLAG */
+#define AIC31XX_ADCPWRSTATUS_MASK 0x40
+
+/* AIC31XX_DACFLAG1 */
+#define AIC31XX_LDACPWRSTATUS_MASK 0x80
+#define AIC31XX_RDACPWRSTATUS_MASK 0x08
+#define AIC31XX_HPLDRVPWRSTATUS_MASK 0x20
+#define AIC31XX_HPRDRVPWRSTATUS_MASK 0x02
+#define AIC31XX_SPLDRVPWRSTATUS_MASK 0x10
+#define AIC31XX_SPRDRVPWRSTATUS_MASK 0x01
+
+/* AIC31XX_INTRDACFLAG */
+#define AIC31XX_HPSCDETECT_MASK 0x80
+#define AIC31XX_BUTTONPRESS_MASK 0x20
+#define AIC31XX_HSPLUG_MASK 0x10
+#define AIC31XX_LDRCTHRES_MASK 0x08
+#define AIC31XX_RDRCTHRES_MASK 0x04
+#define AIC31XX_DACSINT_MASK 0x02
+#define AIC31XX_DACAINT_MASK 0x01
+
+/* AIC31XX_INT1CTRL */
+#define AIC31XX_HSPLUGDET_MASK 0x80
+#define AIC31XX_BUTTONPRESSDET_MASK 0x40
+#define AIC31XX_DRCTHRES_MASK 0x20
+#define AIC31XX_AGCNOISE_MASK 0x10
+#define AIC31XX_OC_MASK 0x08
+#define AIC31XX_ENGINE_MASK 0x04
+
+/* AIC31XX_DACSETUP */
+#define AIC31XX_SOFTSTEP_MASK 0x03
+
+/* AIC31XX_DACMUTE */
+#define AIC31XX_DACMUTE_MASK 0x0C
+
+/* AIC31XX_MICBIAS */
+#define AIC31XX_MICBIAS_MASK 0x03
+#define AIC31XX_MICBIAS_SHIFT 0
+
+#endif /* _TLV320AIC31XX_H */
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index c6bd7e75352d..1d9b117345a3 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -614,8 +614,6 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
u32 tmp_reg;
- snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-
if (gpio_is_valid(aic32x4->rstn_gpio)) {
ndelay(10);
gpio_set_value(aic32x4->rstn_gpio, 1);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 470fbfb4b386..b1835103e9b4 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1344,12 +1344,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
INIT_LIST_HEAD(&aic3x->list);
aic3x->codec = codec;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
aic3x->disable_nb[i].aic3x = aic3x;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 793516146670..6bfc8a17331b 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -122,7 +122,6 @@ struct tlv320dac33_priv {
unsigned int uthr;
enum dac33_state state;
- enum snd_soc_control_type control_type;
void *control_data;
};
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 8ae50274ea8f..83a2c872925c 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -786,8 +786,6 @@ static int wm2000_probe(struct snd_soc_codec *codec)
{
struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
- snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_REGMAP);
-
/* This will trigger a transition to standby mode by default */
wm2000_anc_set_mode(wm2000);
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 1e0a083d8345..2e721e06671b 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1554,15 +1554,8 @@ static int wm2200_probe(struct snd_soc_codec *codec)
int ret;
wm2200->codec = codec;
- codec->control_data = wm2200->regmap;
codec->dapm.bias_level = SND_SOC_BIAS_OFF;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
if (ret != 0)
return ret;
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index d3fa65fd9e85..eca983fad891 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2343,13 +2343,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
int ret, i;
wm5100->codec = codec;
- codec->control_data = wm5100->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 34109050ceed..dcf1d12cfef8 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1760,9 +1760,7 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = priv->core.arizona->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+ ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap);
if (ret != 0)
return ret;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index d7bf8848174a..df5a38dd8328 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1587,10 +1587,9 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = priv->core.arizona->regmap;
priv->core.arizona->dapm = &codec->dapm;
- ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+ ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap);
if (ret != 0)
return ret;
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index a183dcf3d5c1..757256bf7672 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1505,9 +1505,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
if (ret != 0)
return ret;
- codec->control_data = wm8350->regmap;
-
- snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+ snd_soc_codec_set_cache_io(codec, wm8350->regmap);
/* Put the codec into reset if it wasn't already */
wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 6d684d934f4d..146564feaea0 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1316,10 +1316,9 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec)
snd_soc_codec_set_drvdata(codec, priv);
priv->wm8400 = wm8400;
- codec->control_data = wm8400->regmap;
priv->codec = codec;
- snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+ snd_soc_codec_set_cache_io(codec, wm8400->regmap);
ret = devm_regulator_bulk_get(wm8400->dev,
ARRAY_SIZE(power), &power[0]);
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 7df7d4572755..1c1e328feeb8 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -589,20 +589,12 @@ static int wm8510_resume(struct snd_soc_codec *codec)
static int wm8510_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
wm8510_reset(codec);
/* power on device */
wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return ret;
+ return 0;
}
/* power down chip */
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 5dfd571b1a03..601ee8178af1 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -392,18 +392,11 @@ static int wm8523_resume(struct snd_soc_codec *codec)
static int wm8523_probe(struct snd_soc_codec *codec)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- int ret;
wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
wm8523->rate_constraint.count =
ARRAY_SIZE(wm8523->rate_constraint_list);
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Change some default settings - latch VU and enable ZC */
snd_soc_update_bits(codec, WM8523_DAC_GAINR,
WM8523_DACR_VU, WM8523_DACR_VU);
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 318989acbbe5..7558c838193d 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -869,12 +869,6 @@ static int wm8580_probe(struct snd_soc_codec *codec)
struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
wm8580->supplies);
if (ret != 0) {
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 6efcc40a7cb3..b0fbcb377baf 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -367,12 +367,6 @@ static int wm8711_probe(struct snd_soc_codec *codec)
{
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8711_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index cd89033e84c0..bac7fc28fe71 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -228,19 +228,10 @@ static int wm8728_resume(struct snd_soc_codec *codec)
static int wm8728_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
- ret);
- return ret;
- }
-
/* power on device */
wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return ret;
+ return 0;
}
static int wm8728_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d9655f981df1..d74f43975b90 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -583,13 +583,6 @@ static int wm8731_probe(struct snd_soc_codec *codec)
struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
int ret = 0, i;
- codec->control_data = wm8731->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
wm8731->supplies[i].supply = wm8731_supply_names[i];
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index ecc4e8725d5b..b27f26cdc049 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -570,12 +570,6 @@ static int wm8737_probe(struct snd_soc_codec *codec)
struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
wm8737->supplies);
if (ret != 0) {
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index dd02ebf88015..b33542a04607 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -429,12 +429,6 @@ static int wm8741_probe(struct snd_soc_codec *codec)
goto err_get;
}
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err_enable;
- }
-
ret = wm8741_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 78616a638a55..33990b63d214 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -702,12 +702,6 @@ static int wm8750_probe(struct snd_soc_codec *codec)
{
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8750_reset(codec);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 6a6855d8b8ea..cbb8d55052a4 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1470,13 +1470,6 @@ static int wm8753_probe(struct snd_soc_codec *codec)
INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
- codec->control_data = wm8753->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8753_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 5bce21013485..c61aeb38efb8 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -580,12 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec)
wm8770 = snd_soc_codec_get_drvdata(codec);
wm8770->codec = codec;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
wm8770->supplies);
if (ret) {
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index ef8246725232..70952ceb278b 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -430,12 +430,6 @@ static int wm8776_probe(struct snd_soc_codec *codec)
{
int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8776_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 72d12bbe1a56..ee76f0fb4299 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -546,14 +546,6 @@ static int wm8804_probe(struct snd_soc_codec *codec)
wm8804 = snd_soc_codec_get_drvdata(codec);
- codec->control_data = wm8804->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
wm8804->supplies[i].supply = wm8804_supply_names[i];
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 43c2201cb901..d09fdce57f5a 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -1178,13 +1178,7 @@ static int wm8900_resume(struct snd_soc_codec *codec)
static int wm8900_probe(struct snd_soc_codec *codec)
{
- int ret = 0, reg;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
+ int reg;
reg = snd_soc_read(codec, WM8900_REG_ID);
if (reg != 0x8900) {
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index b82b70a3b3d3..b0084a127d18 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1897,21 +1897,13 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903)
static int wm8903_probe(struct snd_soc_codec *codec)
{
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int ret;
wm8903->codec = codec;
- codec->control_data = wm8903->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
/* power on device */
wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return ret;
+ return 0;
}
/* power down chip */
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 27299cda0e99..49c35c36935e 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2048,9 +2048,6 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
static int wm8904_probe(struct snd_soc_codec *codec)
{
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = wm8904->regmap;
switch (wm8904->devtype) {
case WM8904:
@@ -2064,12 +2061,6 @@ static int wm8904_probe(struct snd_soc_codec *codec)
return -EINVAL;
}
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
wm8904_handle_pdata(codec);
wm8904_add_widgets(codec);
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 87f032d0d19f..fc6eec9ad66b 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -712,12 +712,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
int ret;
u16 reg;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8940_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index d4dcaecc8a5f..fecd4e4f4c57 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -895,14 +895,6 @@ static int wm8955_probe(struct snd_soc_codec *codec)
struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
int ret, i;
- codec->control_data = wm8955->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
wm8955->supplies[i].supply = wm8955_supply_names[i];
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f156010e52bc..d04e9cad445c 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -976,12 +976,6 @@ static int wm8960_probe(struct snd_soc_codec *codec)
wm8960->set_bias_level = wm8960_set_bias_level_capless;
}
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8960_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index ce8fa6e01cb4..9c88f04442b3 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -836,15 +836,8 @@ static struct snd_soc_dai_driver wm8961_dai = {
static int wm8961_probe(struct snd_soc_codec *codec)
{
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret = 0;
u16 reg;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Enable class W */
reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
reg |= WM8961_CP_DYN_PWR_MASK;
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 62af9dc59fc5..5522d2566c67 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3424,13 +3424,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
bool dmicclk, dmicdat;
wm8962->codec = codec;
- codec->control_data = wm8962->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1;
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 67aba78a7ca5..09b7b4200221 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -648,12 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec)
int ret = 0;
u16 reg;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
wm8971_workq = create_workqueue("wm8971");
if (wm8971_workq == NULL)
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 6e16c4306461..0627c56fa44e 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -593,12 +593,6 @@ static int wm8974_probe(struct snd_soc_codec *codec)
{
int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8974_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index a9e2f465c331..28ef46c91f62 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -975,19 +975,13 @@ static const int update_reg[] = {
static int wm8978_probe(struct snd_soc_codec *codec)
{
struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
- int ret = 0, i;
+ int i;
/*
* Set default system clock to PLL, it is more precise, this is also the
* default hardware setting
*/
wm8978->sysclk = WM8978_PLL;
- codec->control_data = wm8978->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
/*
* Set the update bit in all registers, that have one. This way all
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 58f0551eed2d..2b9bfa53efbf 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -995,12 +995,6 @@ static int wm8983_probe(struct snd_soc_codec *codec)
int ret;
int i;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index d786f2b39764..5473dc969585 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -995,13 +995,6 @@ static int wm8985_probe(struct snd_soc_codec *codec)
int ret;
wm8985 = snd_soc_codec_get_drvdata(codec);
- codec->control_data = wm8985->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++)
wm8985->supplies[i].supply = wm8985_supply_names[i];
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 0277a76c6bef..3a1ae4f5164d 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -810,16 +810,8 @@ static int wm8988_resume(struct snd_soc_codec *codec)
static int wm8988_probe(struct snd_soc_codec *codec)
{
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- codec->control_data = wm8988->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
ret = wm8988_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 33f53ab1e7b0..c413c1991453 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1289,14 +1289,6 @@ static int wm8990_resume(struct snd_soc_codec *codec)
*/
static int wm8990_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
wm8990_reset(codec);
/* charge output caps */
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 32d219570cca..844cc4a60d66 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1248,14 +1248,6 @@ static int wm8991_remove(struct snd_soc_codec *codec)
static int wm8991_probe(struct snd_soc_codec *codec)
{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 7b0630a076fa..f825dc04ebe1 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1493,13 +1493,6 @@ static int wm8993_probe(struct snd_soc_codec *codec)
wm8993->hubs_data.dcs_codes_r = -2;
wm8993->hubs_data.series_startup = 1;
- codec->control_data = wm8993->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Latch volume update bits and default ZC on */
snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
WM8993_DAC_VU, WM8993_DAC_VU);
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 79854cb7feb6..6303537f54c6 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3998,9 +3998,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
int ret, i;
wm8994->hubs.codec = codec;
- codec->control_data = control->regmap;
- snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
+ snd_soc_codec_set_cache_io(codec, control->regmap);
mutex_init(&wm8994->accdet_lock);
INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index ddb197dc1d53..d3152cf5bd56 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -2042,13 +2042,6 @@ static int wm8995_probe(struct snd_soc_codec *codec)
wm8995 = snd_soc_codec_get_drvdata(codec);
wm8995->codec = codec;
- codec->control_data = wm8995->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
wm8995->supplies[i].supply = wm8995_supply_names[i];
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index c8244af7d56a..c6cbb3b8ace9 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2633,14 +2633,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
init_completion(&wm8996->dcs_done);
init_completion(&wm8996->fll_lock);
- codec->control_data = wm8996->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
if (wm8996->pdata.num_retune_mobile_cfgs)
wm8996_retune_mobile_pdata(codec);
else
@@ -2679,13 +2671,11 @@ static int wm8996_probe(struct snd_soc_codec *codec)
} else {
dev_err(codec->dev, "Failed to request IRQ: %d\n",
ret);
+ return ret;
}
}
return 0;
-
-err:
- return ret;
}
static int wm8996_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index e10f44d7fdb7..004186b6bd48 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -1053,9 +1053,7 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret;
- codec->control_data = priv->core.arizona->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+ ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap);
if (ret != 0)
return ret;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 721cee71d5fc..d18eff31fbbc 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1260,15 +1260,6 @@ static struct snd_soc_dai_driver wm9081_dai = {
static int wm9081_probe(struct snd_soc_codec *codec)
{
struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = wm9081->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
/* Enable zero cross by default */
snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
@@ -1283,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(wm9081_eq_controls));
}
- return ret;
+ return 0;
}
static int wm9081_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index a07fe1618eec..87934171f063 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -522,16 +522,6 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
static int wm9090_probe(struct snd_soc_codec *codec)
{
- struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev);
- int ret;
-
- codec->control_data = wm9090->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
/* Configure some defaults; they will be written out when we
* bring the bias up.
*/
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 4577b69fcf2c..3c81b3891209 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -32,7 +32,7 @@ config SND_SOC_INTEL_BAYTRAIL
config SND_SOC_INTEL_HASWELL_MACH
tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
- depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS
+ depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C
select SND_SOC_INTEL_HASWELL
select SND_SOC_RT5640
help
@@ -43,7 +43,7 @@ config SND_SOC_INTEL_HASWELL_MACH
config SND_SOC_INTEL_BYT_RT5640_MACH
tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
- depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS
+ depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C
select SND_SOC_INTEL_BAYTRAIL
select SND_SOC_RT5640
help
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index 78ed4a42ad21..2dc3ecf34801 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -1,11 +1,19 @@
config SND_KIRKWOOD_SOC
tristate "SoC Audio for the Marvell Kirkwood and Dove chips"
- depends on ARCH_KIRKWOOD || ARCH_DOVE || COMPILE_TEST
+ depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST
help
Say Y or M if you want to add support for codecs attached to
the Kirkwood I2S interface. You will also need to select the
audio interfaces to support below.
+config SND_KIRKWOOD_SOC_ARMADA370_DB
+ tristate "SoC Audio support for Armada 370 DB"
+ depends on SND_KIRKWOOD_SOC && (ARCH_MVEBU || COMPILE_TEST) && I2C
+ select SND_SOC_CS42L51
+ help
+ Say Y if you want to add support for SoC audio on
+ the Armada 370 Development Board.
+
config SND_KIRKWOOD_SOC_OPENRD
tristate "SoC Audio support for Kirkwood Openrd Client"
depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE || COMPILE_TEST)
diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile
index 9e781385cb88..7c1d8fe09e6b 100644
--- a/sound/soc/kirkwood/Makefile
+++ b/sound/soc/kirkwood/Makefile
@@ -4,6 +4,8 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
snd-soc-openrd-objs := kirkwood-openrd.o
snd-soc-t5325-objs := kirkwood-t5325.o
+snd-soc-armada-370-db-objs := armada-370-db.o
+obj-$(CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB) += snd-soc-armada-370-db.o
obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c
new file mode 100644
index 000000000000..977639b3ffde
--- /dev/null
+++ b/sound/soc/kirkwood/armada-370-db.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <linux/of.h>
+#include <linux/platform_data/asoc-kirkwood.h>
+#include "../codecs/cs42l51.h"
+
+static int a370db_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ unsigned int freq;
+
+ switch (params_rate(params)) {
+ default:
+ case 44100:
+ freq = 11289600;
+ break;
+ case 48000:
+ freq = 12288000;
+ break;
+ case 96000:
+ freq = 24576000;
+ break;
+ }
+
+ return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
+}
+
+static struct snd_soc_ops a370db_ops = {
+ .hw_params = a370db_hw_params,
+};
+
+static const struct snd_soc_dapm_widget a370db_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Out Jack", NULL),
+ SND_SOC_DAPM_LINE("In Jack", NULL),
+};
+
+static const struct snd_soc_dapm_route a370db_route[] = {
+ { "Out Jack", NULL, "HPL" },
+ { "Out Jack", NULL, "HPR" },
+ { "AIN1L", NULL, "In Jack" },
+ { "AIN1L", NULL, "In Jack" },
+};
+
+static struct snd_soc_dai_link a370db_dai[] = {
+{
+ .name = "CS42L51",
+ .stream_name = "analog",
+ .cpu_dai_name = "i2s",
+ .codec_dai_name = "cs42l51-hifi",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
+ .ops = &a370db_ops,
+},
+};
+
+static struct snd_soc_card a370db = {
+ .name = "a370db",
+ .owner = THIS_MODULE,
+ .dai_link = a370db_dai,
+ .num_links = ARRAY_SIZE(a370db_dai),
+ .dapm_widgets = a370db_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(a370db_dapm_widgets),
+ .dapm_routes = a370db_route,
+ .num_dapm_routes = ARRAY_SIZE(a370db_route),
+};
+
+static int a370db_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &a370db;
+
+ card->dev = &pdev->dev;
+
+ a370db_dai[0].cpu_of_node =
+ of_parse_phandle(pdev->dev.of_node,
+ "marvell,audio-controller", 0);
+ a370db_dai[0].platform_of_node = a370db_dai[0].cpu_of_node;
+
+ a370db_dai[0].codec_of_node =
+ of_parse_phandle(pdev->dev.of_node,
+ "marvell,audio-codec", 0);
+
+ return devm_snd_soc_register_card(card->dev, card);
+}
+
+static const struct of_device_id a370db_dt_ids[] = {
+ { .compatible = "marvell,a370db-audio" },
+ { },
+};
+
+static struct platform_driver a370db_driver = {
+ .driver = {
+ .name = "a370db-audio",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(a370db_dt_ids),
+ },
+ .probe = a370db_probe,
+};
+
+module_platform_driver(a370db_driver);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("ALSA SoC a370db audio client");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:a370db-audio");
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 3920a5e8125f..9f842222e798 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -633,6 +633,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
static struct of_device_id mvebu_audio_of_match[] = {
{ .compatible = "marvell,kirkwood-audio" },
{ .compatible = "marvell,dove-audio" },
+ { .compatible = "marvell,armada370-audio" },
{ }
};
MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index f141435b0b4a..56a5219c0a00 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -325,7 +325,7 @@ static void cx81801_close(struct tty_struct *tty)
snd_soc_dapm_sync_unlocked(dapm);
- snd_soc_dapm_mutex_unlock(codec);
+ snd_soc_dapm_mutex_unlock(dapm);
}
/* Line discipline .hangup() */
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 41ab6678b65d..259e048681c0 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -41,9 +41,8 @@ static int magician_hp_switch;
static int magician_spk_switch = 1;
static int magician_in_sel = MAGICIAN_MIC;
-static void magician_ext_control(struct snd_soc_codec *codec)
+static void magician_ext_control(struct snd_soc_dapm_context *dapm)
{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
snd_soc_dapm_mutex_lock(dapm);
@@ -75,10 +74,9 @@ static void magician_ext_control(struct snd_soc_codec *codec)
static int magician_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
/* check the jack status at stream startup */
- magician_ext_control(codec);
+ magician_ext_control(&rtd->card->dapm);
return 0;
}
@@ -277,13 +275,13 @@ static int magician_get_hp(struct snd_kcontrol *kcontrol,
static int magician_set_hp(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
if (magician_hp_switch == ucontrol->value.integer.value[0])
return 0;
magician_hp_switch = ucontrol->value.integer.value[0];
- magician_ext_control(codec);
+ magician_ext_control(&card->dapm);
return 1;
}
@@ -297,13 +295,13 @@ static int magician_get_spk(struct snd_kcontrol *kcontrol,
static int magician_set_spk(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
if (magician_spk_switch == ucontrol->value.integer.value[0])
return 0;
magician_spk_switch = ucontrol->value.integer.value[0];
- magician_ext_control(codec);
+ magician_ext_control(&card->dapm);
return 1;
}
@@ -400,7 +398,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
/* NC codec pins */
snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
@@ -410,19 +407,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_nc_pin(dapm, "VINL");
snd_soc_dapm_nc_pin(dapm, "VINR");
- /* Add magician specific controls */
- err = snd_soc_add_codec_controls(codec, uda1380_magician_controls,
- ARRAY_SIZE(uda1380_magician_controls));
- if (err < 0)
- return err;
-
- /* Add magician specific widgets */
- snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
- ARRAY_SIZE(uda1380_dapm_widgets));
-
- /* Set up magician specific audio path interconnects */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
return 0;
}
@@ -456,6 +440,12 @@ static struct snd_soc_card snd_soc_card_magician = {
.dai_link = magician_dai,
.num_links = ARRAY_SIZE(magician_dai),
+ .controls = uda1380_magician_controls,
+ .num_controls = ARRAY_SIZE(uda1380_magician_controls),
+ .dapm_widgets = uda1380_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
};
static struct platform_device *magician_snd_device;
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index cead1658d10a..4a956d1cb269 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -44,9 +44,8 @@
static int tosa_jack_func;
static int tosa_spk_func;
-static void tosa_ext_control(struct snd_soc_codec *codec)
+static void tosa_ext_control(struct snd_soc_dapm_context *dapm)
{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
snd_soc_dapm_mutex_lock(dapm);
@@ -82,10 +81,9 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
static int tosa_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
/* check the jack status at stream startup */
- tosa_ext_control(codec);
+ tosa_ext_control(&rtd->card->dapm);
return 0;
}
@@ -104,13 +102,13 @@ static int tosa_get_jack(struct snd_kcontrol *kcontrol,
static int tosa_set_jack(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
if (tosa_jack_func == ucontrol->value.integer.value[0])
return 0;
tosa_jack_func = ucontrol->value.integer.value[0];
- tosa_ext_control(codec);
+ tosa_ext_control(&card->dapm);
return 1;
}
@@ -124,13 +122,13 @@ static int tosa_get_spk(struct snd_kcontrol *kcontrol,
static int tosa_set_spk(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
if (tosa_spk_func == ucontrol->value.integer.value[0])
return 0;
tosa_spk_func = ucontrol->value.integer.value[0];
- tosa_ext_control(codec);
+ tosa_ext_control(&card->dapm);
return 1;
}
@@ -191,24 +189,10 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
snd_soc_dapm_nc_pin(dapm, "OUT3");
snd_soc_dapm_nc_pin(dapm, "MONOOUT");
- /* add tosa specific controls */
- err = snd_soc_add_codec_controls(codec, tosa_controls,
- ARRAY_SIZE(tosa_controls));
- if (err < 0)
- return err;
-
- /* add tosa specific widgets */
- snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
- ARRAY_SIZE(tosa_dapm_widgets));
-
- /* set up tosa specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
return 0;
}
@@ -239,6 +223,13 @@ static struct snd_soc_card tosa = {
.owner = THIS_MODULE,
.dai_link = tosa_dai,
.num_links = ARRAY_SIZE(tosa_dai),
+
+ .controls = tosa_controls,
+ .num_controls = ARRAY_SIZE(tosa_controls),
+ .dapm_widgets = tosa_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tosa_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
};
static int tosa_probe(struct platform_device *pdev)
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index 945e8abdc10f..0b21d1dc80c1 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -104,8 +104,8 @@ static int output_type_get(struct snd_kcontrol *kcontrol,
static int output_type_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = kcontrol->private_data;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_card *card = kcontrol->private_data;
+ struct snd_soc_dapm_context *dapm = &card->dapm;
unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
char *differential = "Audio Out Differential";
char *stereo = "Audio Out Stereo";
@@ -137,13 +137,7 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* Add s6105 specific widgets */
- snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
- ARRAY_SIZE(aic3x_dapm_widgets));
-
- /* Set up s6105 specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ struct snd_soc_card *card = rtd->card;
/* not present */
snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
@@ -157,17 +151,10 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_nc_pin(dapm, "RLOUT");
snd_soc_dapm_nc_pin(dapm, "HPRCOM");
- /* always connected */
- snd_soc_dapm_enable_pin(dapm, "Audio In");
-
/* must correspond to audio_out_mux.private_value initializer */
- snd_soc_dapm_disable_pin(dapm, "Audio Out Differential");
- snd_soc_dapm_sync(dapm);
- snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo");
-
- snd_soc_dapm_sync(dapm);
+ snd_soc_dapm_disable_pin(&card->dapm, "Audio Out Differential");
- snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
+ snd_ctl_add(card->snd_card, snd_ctl_new1(&audio_out_mux, card));
return 0;
}
@@ -190,6 +177,11 @@ static struct snd_soc_card snd_soc_card_s6105 = {
.owner = THIS_MODULE,
.dai_link = &s6105_dai,
.num_links = 1,
+
+ .dapm_widgets = aic3x_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
};
static struct s6000_snd_platform_data s6105_snd_data __initdata = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 359c2849b364..b322cf294d06 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1137,6 +1137,16 @@ static int soc_probe_codec(struct snd_soc_card *card,
codec->dapm.idle_bias_off = driver->idle_bias_off;
+ if (!codec->write && dev_get_regmap(codec->dev, NULL)) {
+ /* Set the default I/O up try regmap */
+ ret = snd_soc_codec_set_cache_io(codec, NULL);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "Failed to set cache I/O: %d\n", ret);
+ goto err_probe;
+ }
+ }
+
if (driver->probe) {
ret = driver->probe(codec);
if (ret < 0) {
@@ -1150,10 +1160,6 @@ static int soc_probe_codec(struct snd_soc_card *card,
codec->name);
}
- /* If the driver didn't set I/O up try regmap */
- if (!codec->write && dev_get_regmap(codec->dev, NULL))
- snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
-
if (driver->controls)
snd_soc_add_codec_controls(codec, driver->controls,
driver->num_controls);
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index aa886cca3ecf..8aa086996866 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -69,9 +69,7 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
* snd_soc_codec_set_cache_io: Set up standard I/O functions.
*
* @codec: CODEC to configure.
- * @addr_bits: Number of bits of register address data.
- * @data_bits: Number of bits of data per register.
- * @control: Control bus used.
+ * @map: Register map to write to
*
* Register formats are frequently shared between many I2C and SPI
* devices. In order to promote code reuse the ASoC core provides
@@ -85,60 +83,36 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
* volatile registers.
*/
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control)
+ struct regmap *regmap)
{
- struct regmap_config config;
int ret;
- memset(&config, 0, sizeof(config));
- codec->write = hw_write;
- codec->read = hw_read;
+ /* Device has made its own regmap arrangements */
+ if (!regmap)
+ codec->control_data = dev_get_regmap(codec->dev, NULL);
+ else
+ codec->control_data = regmap;
- config.reg_bits = addr_bits;
- config.val_bits = data_bits;
+ if (IS_ERR(codec->control_data))
+ return PTR_ERR(codec->control_data);
- switch (control) {
-#if IS_ENABLED(CONFIG_REGMAP_I2C)
- case SND_SOC_I2C:
- codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
- &config);
- break;
-#endif
+ codec->write = hw_write;
+ codec->read = hw_read;
-#if IS_ENABLED(CONFIG_REGMAP_SPI)
- case SND_SOC_SPI:
- codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
- &config);
- break;
-#endif
+ ret = regmap_get_val_bytes(codec->control_data);
+ /* Errors are legitimate for non-integer byte
+ * multiples */
+ if (ret > 0)
+ codec->val_bytes = ret;
- case SND_SOC_REGMAP:
- /* Device has made its own regmap arrangements */
- codec->using_regmap = true;
- if (!codec->control_data)
- codec->control_data = dev_get_regmap(codec->dev, NULL);
-
- if (codec->control_data) {
- ret = regmap_get_val_bytes(codec->control_data);
- /* Errors are legitimate for non-integer byte
- * multiples */
- if (ret > 0)
- codec->val_bytes = ret;
- }
- break;
-
- default:
- return -EINVAL;
- }
+ codec->using_regmap = true;
- return PTR_ERR_OR_ZERO(codec->control_data);
+ return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
#else
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control)
+ struct regmap *regmap)
{
return -ENOTSUPP;
}
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 23d43dac91da..b903f822d1b2 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -250,7 +250,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
report = 0;
if (gpio->jack_status_check)
- report = gpio->jack_status_check();
+ report = gpio->jack_status_check(gpio->data);
snd_soc_jack_report(jack, report, gpio->report);
}
@@ -342,7 +342,8 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
gpio_export(gpios[i].gpio, false);
/* Update initial jack status */
- snd_soc_jack_gpio_detect(&gpios[i]);
+ schedule_delayed_work(&gpios[i].work,
+ msecs_to_jiffies(gpios[i].debounce_time));
}
return 0;