aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/atmel/Kconfig2
-rw-r--r--sound/soc/blackfin/Kconfig3
-rw-r--r--sound/soc/cirrus/Kconfig2
-rw-r--r--sound/soc/codecs/Kconfig22
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ad193x-i2c.c54
-rw-r--r--sound/soc/codecs/ad193x-spi.c48
-rw-r--r--sound/soc/codecs/ad193x.c144
-rw-r--r--sound/soc/codecs/ad193x.h7
-rw-r--r--sound/soc/codecs/ak4671.c240
-rw-r--r--sound/soc/codecs/ak4671.h2
-rw-r--r--sound/soc/codecs/alc5623.c117
-rw-r--r--sound/soc/codecs/alc5632.c40
-rw-r--r--sound/soc/codecs/cs42l51.c71
-rw-r--r--sound/soc/codecs/da732x.c16
-rw-r--r--sound/soc/codecs/sgtl5000.c8
-rw-r--r--sound/soc/codecs/si476x.c2
-rw-r--r--sound/soc/codecs/tlv320aic23-i2c.c59
-rw-r--r--sound/soc/codecs/tlv320aic23-spi.c57
-rw-r--r--sound/soc/codecs/tlv320aic23.c69
-rw-r--r--sound/soc/codecs/tlv320aic23.h6
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c232
-rw-r--r--sound/soc/codecs/wm8991.c44
-rw-r--r--sound/soc/fsl/Kconfig2
-rw-r--r--sound/soc/omap/Kconfig4
-rw-r--r--sound/soc/samsung/Kconfig2
-rw-r--r--sound/soc/soc-core.c76
-rw-r--r--sound/soc/soc-io.c19
-rw-r--r--sound/soc/tegra/Kconfig2
29 files changed, 846 insertions, 516 deletions
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index e634eb78ed03..4789619a52d8 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -58,6 +58,6 @@ config SND_AT91_SOC_AFEB9260
58 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC 58 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
59 select SND_ATMEL_SOC_PDC 59 select SND_ATMEL_SOC_PDC
60 select SND_ATMEL_SOC_SSC 60 select SND_ATMEL_SOC_SSC
61 select SND_SOC_TLV320AIC23 61 select SND_SOC_TLV320AIC23_I2C
62 help 62 help
63 Say Y here to support sound on AFEB9260 board. 63 Say Y here to support sound on AFEB9260 board.
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 54f74f8cbb75..359136777c4d 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -68,7 +68,8 @@ config SND_BF5XX_SOC_AD193X
68 tristate "SoC AD193X Audio support for Blackfin" 68 tristate "SoC AD193X Audio support for Blackfin"
69 depends on SND_BF5XX_I2S 69 depends on SND_BF5XX_I2S
70 select SND_BF5XX_SOC_I2S 70 select SND_BF5XX_SOC_I2S
71 select SND_SOC_AD193X 71 select SND_SOC_AD193X_I2C if I2C
72 select SND_SOC_AD193X_SPI if SPI_MASTER
72 help 73 help
73 Say Y if you want to add support for AD193X codec on Blackfin. 74 Say Y if you want to add support for AD193X codec on Blackfin.
74 This driver supports AD1936, AD1937, AD1938 and AD1939. 75 This driver supports AD1936, AD1937, AD1938 and AD1939.
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig
index 06f938deda15..a0bf4a610397 100644
--- a/sound/soc/cirrus/Kconfig
+++ b/sound/soc/cirrus/Kconfig
@@ -18,7 +18,7 @@ config SND_EP93XX_SOC_SNAPPERCL15
18 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module" 18 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module"
19 depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 19 depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
20 select SND_EP93XX_SOC_I2S 20 select SND_EP93XX_SOC_I2S
21 select SND_SOC_TLV320AIC23 21 select SND_SOC_TLV320AIC23_I2C
22 help 22 help
23 Say Y or M here if you want to add support for I2S audio on the 23 Say Y or M here if you want to add support for I2S audio on the
24 Bluewater Systems Snapper CL15 module. 24 Bluewater Systems Snapper CL15 module.
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 983d087aa92a..555f32f39f8a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -16,7 +16,8 @@ config SND_SOC_ALL_CODECS
16 select SND_SOC_AB8500_CODEC if ABX500_CORE 16 select SND_SOC_AB8500_CODEC if ABX500_CORE
17 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 17 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
18 select SND_SOC_AD1836 if SPI_MASTER 18 select SND_SOC_AD1836 if SPI_MASTER
19 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 19 select SND_SOC_AD193X_SPI if SPI_MASTER
20 select SND_SOC_AD193X_I2C if I2C
20 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 21 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
21 select SND_SOC_AD73311 22 select SND_SOC_AD73311
22 select SND_SOC_ADAU1373 if I2C 23 select SND_SOC_ADAU1373 if I2C
@@ -71,7 +72,8 @@ config SND_SOC_ALL_CODECS
71 select SND_SOC_STA529 if I2C 72 select SND_SOC_STA529 if I2C
72 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 73 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
73 select SND_SOC_TAS5086 if I2C 74 select SND_SOC_TAS5086 if I2C
74 select SND_SOC_TLV320AIC23 if I2C 75 select SND_SOC_TLV320AIC23_I2C if I2C
76 select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
75 select SND_SOC_TLV320AIC26 if SPI_MASTER 77 select SND_SOC_TLV320AIC26 if SPI_MASTER
76 select SND_SOC_TLV320AIC32X4 if I2C 78 select SND_SOC_TLV320AIC32X4 if I2C
77 select SND_SOC_TLV320AIC3X if I2C 79 select SND_SOC_TLV320AIC3X if I2C
@@ -182,6 +184,14 @@ config SND_SOC_AD1836
182config SND_SOC_AD193X 184config SND_SOC_AD193X
183 tristate 185 tristate
184 186
187config SND_SOC_AD193X_SPI
188 tristate
189 select SND_SOC_AD193X
190
191config SND_SOC_AD193X_I2C
192 tristate
193 select SND_SOC_AD193X
194
185config SND_SOC_AD1980 195config SND_SOC_AD1980
186 tristate 196 tristate
187 197
@@ -357,6 +367,14 @@ config SND_SOC_TAS5086
357config SND_SOC_TLV320AIC23 367config SND_SOC_TLV320AIC23
358 tristate 368 tristate
359 369
370config SND_SOC_TLV320AIC23_I2C
371 tristate
372 select SND_SOC_TLV320AIC23
373
374config SND_SOC_TLV320AIC23_SPI
375 tristate
376 select SND_SOC_TLV320AIC23
377
360config SND_SOC_TLV320AIC26 378config SND_SOC_TLV320AIC26
361 tristate 379 tristate
362 depends on SPI 380 depends on SPI
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index bc126764a44d..bfda5c60932a 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,6 +3,8 @@ snd-soc-ab8500-codec-objs := ab8500-codec.o
3snd-soc-ac97-objs := ac97.o 3snd-soc-ac97-objs := ac97.o
4snd-soc-ad1836-objs := ad1836.o 4snd-soc-ad1836-objs := ad1836.o
5snd-soc-ad193x-objs := ad193x.o 5snd-soc-ad193x-objs := ad193x.o
6snd-soc-ad193x-spi-objs := ad193x-spi.o
7snd-soc-ad193x-i2c-objs := ad193x-i2c.o
6snd-soc-ad1980-objs := ad1980.o 8snd-soc-ad1980-objs := ad1980.o
7snd-soc-ad73311-objs := ad73311.o 9snd-soc-ad73311-objs := ad73311.o
8snd-soc-adau1701-objs := adau1701.o 10snd-soc-adau1701-objs := adau1701.o
@@ -63,9 +65,11 @@ snd-soc-sta529-objs := sta529.o
63snd-soc-stac9766-objs := stac9766.o 65snd-soc-stac9766-objs := stac9766.o
64snd-soc-tas5086-objs := tas5086.o 66snd-soc-tas5086-objs := tas5086.o
65snd-soc-tlv320aic23-objs := tlv320aic23.o 67snd-soc-tlv320aic23-objs := tlv320aic23.o
68snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
69snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
66snd-soc-tlv320aic26-objs := tlv320aic26.o 70snd-soc-tlv320aic26-objs := tlv320aic26.o
67snd-soc-tlv320aic3x-objs := tlv320aic3x.o
68snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o 71snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
72snd-soc-tlv320aic3x-objs := tlv320aic3x.o
69snd-soc-tlv320dac33-objs := tlv320dac33.o 73snd-soc-tlv320dac33-objs := tlv320dac33.o
70snd-soc-twl4030-objs := twl4030.o 74snd-soc-twl4030-objs := twl4030.o
71snd-soc-twl6040-objs := twl6040.o 75snd-soc-twl6040-objs := twl6040.o
@@ -134,6 +138,8 @@ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
134obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 138obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
135obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 139obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
136obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 140obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
141obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o
142obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o
137obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 143obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
138obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 144obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
139obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o 145obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
@@ -193,9 +199,11 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
193obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 199obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
194obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o 200obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
195obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 201obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
202obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
203obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
196obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 204obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
197obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
198obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o 205obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
206obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
199obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 207obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
200obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 208obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
201obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 209obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c
new file mode 100644
index 000000000000..df3a1a415825
--- /dev/null
+++ b/sound/soc/codecs/ad193x-i2c.c
@@ -0,0 +1,54 @@
1/*
2 * AD1936/AD1937 audio driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/i2c.h>
11#include <linux/regmap.h>
12
13#include <sound/soc.h>
14
15#include "ad193x.h"
16
17static const struct i2c_device_id ad193x_id[] = {
18 { "ad1936", 0 },
19 { "ad1937", 0 },
20 { }
21};
22MODULE_DEVICE_TABLE(i2c, ad193x_id);
23
24static int ad193x_i2c_probe(struct i2c_client *client,
25 const struct i2c_device_id *id)
26{
27 struct regmap_config config;
28
29 config = ad193x_regmap_config;
30 config.val_bits = 8;
31 config.reg_bits = 8;
32
33 return ad193x_probe(&client->dev, devm_regmap_init_i2c(client, &config));
34}
35
36static int ad193x_i2c_remove(struct i2c_client *client)
37{
38 snd_soc_unregister_codec(&client->dev);
39 return 0;
40}
41
42static struct i2c_driver ad193x_i2c_driver = {
43 .driver = {
44 .name = "ad193x",
45 },
46 .probe = ad193x_i2c_probe,
47 .remove = ad193x_i2c_remove,
48 .id_table = ad193x_id,
49};
50module_i2c_driver(ad193x_i2c_driver);
51
52MODULE_DESCRIPTION("ASoC AD1936/AD1937 audio CODEC driver");
53MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
54MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c
new file mode 100644
index 000000000000..390cef9b9dc2
--- /dev/null
+++ b/sound/soc/codecs/ad193x-spi.c
@@ -0,0 +1,48 @@
1/*
2 * AD1938/AD1939 audio driver
3 *
4 * Copyright 2014 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/spi/spi.h>
11#include <linux/regmap.h>
12
13#include <sound/soc.h>
14
15#include "ad193x.h"
16
17static int ad193x_spi_probe(struct spi_device *spi)
18{
19 struct regmap_config config;
20
21 config = ad193x_regmap_config;
22 config.val_bits = 8;
23 config.reg_bits = 16;
24 config.read_flag_mask = 0x09;
25 config.write_flag_mask = 0x08;
26
27 return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
28}
29
30static int ad193x_spi_remove(struct spi_device *spi)
31{
32 snd_soc_unregister_codec(&spi->dev);
33 return 0;
34}
35
36static struct spi_driver ad193x_spi_driver = {
37 .driver = {
38 .name = "ad193x",
39 .owner = THIS_MODULE,
40 },
41 .probe = ad193x_spi_probe,
42 .remove = ad193x_spi_remove,
43};
44module_spi_driver(ad193x_spi_driver);
45
46MODULE_DESCRIPTION("ASoC AD1938/AD1939 audio CODEC driver");
47MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
48MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 5a42dca535b7..9381a767e75f 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -6,12 +6,10 @@
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
8 8
9#include <linux/init.h>
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12#include <linux/device.h> 11#include <linux/device.h>
13#include <linux/i2c.h> 12#include <linux/regmap.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h> 13#include <linux/slab.h>
16#include <sound/core.h> 14#include <sound/core.h>
17#include <sound/pcm.h> 15#include <sound/pcm.h>
@@ -19,6 +17,7 @@
19#include <sound/initval.h> 17#include <sound/initval.h>
20#include <sound/soc.h> 18#include <sound/soc.h>
21#include <sound/tlv.h> 19#include <sound/tlv.h>
20
22#include "ad193x.h" 21#include "ad193x.h"
23 22
24/* codec private data */ 23/* codec private data */
@@ -32,8 +31,8 @@ struct ad193x_priv {
32 */ 31 */
33static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; 32static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
34 33
35static const struct soc_enum ad193x_deemp_enum = 34static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
36 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); 35 ad193x_deemp);
37 36
38static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); 37static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
39 38
@@ -320,7 +319,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
320 .ops = &ad193x_dai_ops, 319 .ops = &ad193x_dai_ops,
321}; 320};
322 321
323static int ad193x_probe(struct snd_soc_codec *codec) 322static int ad193x_codec_probe(struct snd_soc_codec *codec)
324{ 323{
325 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 324 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
326 int ret; 325 int ret;
@@ -352,7 +351,7 @@ static int ad193x_probe(struct snd_soc_codec *codec)
352} 351}
353 352
354static struct snd_soc_codec_driver soc_codec_dev_ad193x = { 353static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
355 .probe = ad193x_probe, 354 .probe = ad193x_codec_probe,
356 .controls = ad193x_snd_controls, 355 .controls = ad193x_snd_controls,
357 .num_controls = ARRAY_SIZE(ad193x_snd_controls), 356 .num_controls = ARRAY_SIZE(ad193x_snd_controls),
358 .dapm_widgets = ad193x_dapm_widgets, 357 .dapm_widgets = ad193x_dapm_widgets,
@@ -366,140 +365,31 @@ static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
366 return false; 365 return false;
367} 366}
368 367
369#if defined(CONFIG_SPI_MASTER) 368const struct regmap_config ad193x_regmap_config = {
370
371static const struct regmap_config ad193x_spi_regmap_config = {
372 .val_bits = 8,
373 .reg_bits = 16,
374 .read_flag_mask = 0x09,
375 .write_flag_mask = 0x08,
376
377 .max_register = AD193X_NUM_REGS - 1, 369 .max_register = AD193X_NUM_REGS - 1,
378 .volatile_reg = adau193x_reg_volatile, 370 .volatile_reg = adau193x_reg_volatile,
379}; 371};
372EXPORT_SYMBOL_GPL(ad193x_regmap_config);
380 373
381static int ad193x_spi_probe(struct spi_device *spi) 374int ad193x_probe(struct device *dev, struct regmap *regmap)
382{ 375{
383 struct ad193x_priv *ad193x; 376 struct ad193x_priv *ad193x;
384 377
385 ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), 378 if (IS_ERR(regmap))
386 GFP_KERNEL); 379 return PTR_ERR(regmap);
387 if (ad193x == NULL)
388 return -ENOMEM;
389
390 ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config);
391 if (IS_ERR(ad193x->regmap))
392 return PTR_ERR(ad193x->regmap);
393
394 spi_set_drvdata(spi, ad193x);
395
396 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x,
397 &ad193x_dai, 1);
398}
399
400static int ad193x_spi_remove(struct spi_device *spi)
401{
402 snd_soc_unregister_codec(&spi->dev);
403 return 0;
404}
405
406static struct spi_driver ad193x_spi_driver = {
407 .driver = {
408 .name = "ad193x",
409 .owner = THIS_MODULE,
410 },
411 .probe = ad193x_spi_probe,
412 .remove = ad193x_spi_remove,
413};
414#endif
415
416#if IS_ENABLED(CONFIG_I2C)
417
418static const struct regmap_config ad193x_i2c_regmap_config = {
419 .val_bits = 8,
420 .reg_bits = 8,
421
422 .max_register = AD193X_NUM_REGS - 1,
423 .volatile_reg = adau193x_reg_volatile,
424};
425
426static const struct i2c_device_id ad193x_id[] = {
427 { "ad1936", 0 },
428 { "ad1937", 0 },
429 { }
430};
431MODULE_DEVICE_TABLE(i2c, ad193x_id);
432 380
433static int ad193x_i2c_probe(struct i2c_client *client, 381 ad193x = devm_kzalloc(dev, sizeof(*ad193x), GFP_KERNEL);
434 const struct i2c_device_id *id)
435{
436 struct ad193x_priv *ad193x;
437
438 ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
439 GFP_KERNEL);
440 if (ad193x == NULL) 382 if (ad193x == NULL)
441 return -ENOMEM; 383 return -ENOMEM;
442 384
443 ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config); 385 ad193x->regmap = regmap;
444 if (IS_ERR(ad193x->regmap))
445 return PTR_ERR(ad193x->regmap);
446
447 i2c_set_clientdata(client, ad193x);
448
449 return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x,
450 &ad193x_dai, 1);
451}
452
453static int ad193x_i2c_remove(struct i2c_client *client)
454{
455 snd_soc_unregister_codec(&client->dev);
456 return 0;
457}
458 386
459static struct i2c_driver ad193x_i2c_driver = { 387 dev_set_drvdata(dev, ad193x);
460 .driver = {
461 .name = "ad193x",
462 },
463 .probe = ad193x_i2c_probe,
464 .remove = ad193x_i2c_remove,
465 .id_table = ad193x_id,
466};
467#endif
468
469static int __init ad193x_modinit(void)
470{
471 int ret;
472
473#if IS_ENABLED(CONFIG_I2C)
474 ret = i2c_add_driver(&ad193x_i2c_driver);
475 if (ret != 0) {
476 printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
477 ret);
478 }
479#endif
480
481#if defined(CONFIG_SPI_MASTER)
482 ret = spi_register_driver(&ad193x_spi_driver);
483 if (ret != 0) {
484 printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n",
485 ret);
486 }
487#endif
488 return ret;
489}
490module_init(ad193x_modinit);
491
492static void __exit ad193x_modexit(void)
493{
494#if defined(CONFIG_SPI_MASTER)
495 spi_unregister_driver(&ad193x_spi_driver);
496#endif
497 388
498#if IS_ENABLED(CONFIG_I2C) 389 return snd_soc_register_codec(dev, &soc_codec_dev_ad193x,
499 i2c_del_driver(&ad193x_i2c_driver); 390 &ad193x_dai, 1);
500#endif
501} 391}
502module_exit(ad193x_modexit); 392EXPORT_SYMBOL_GPL(ad193x_probe);
503 393
504MODULE_DESCRIPTION("ASoC ad193x driver"); 394MODULE_DESCRIPTION("ASoC ad193x driver");
505MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 395MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 473388049992..ab9a998f15be 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -9,6 +9,13 @@
9#ifndef __AD193X_H__ 9#ifndef __AD193X_H__
10#define __AD193X_H__ 10#define __AD193X_H__
11 11
12#include <linux/regmap.h>
13
14struct device;
15
16extern const struct regmap_config ad193x_regmap_config;
17int ad193x_probe(struct device *dev, struct regmap *regmap);
18
12#define AD193X_PLL_CLK_CTRL0 0x00 19#define AD193X_PLL_CLK_CTRL0 0x00
13#define AD193X_PLL_POWERDOWN 0x01 20#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK 0x6 21#define AD193X_PLL_INPUT_MASK 0x6
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 25bdf6ad4a54..deb2b44669de 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/regmap.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
20#include <sound/initval.h> 21#include <sound/initval.h>
@@ -23,104 +24,99 @@
23#include "ak4671.h" 24#include "ak4671.h"
24 25
25 26
26/* codec private data */
27struct ak4671_priv {
28 enum snd_soc_control_type control_type;
29};
30
31/* ak4671 register cache & default register settings */ 27/* ak4671 register cache & default register settings */
32static const u8 ak4671_reg[AK4671_CACHEREGNUM] = { 28static const struct reg_default ak4671_reg_defaults[] = {
33 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */ 29 { 0x00, 0x00 }, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
34 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */ 30 { 0x01, 0xf6 }, /* AK4671_PLL_MODE_SELECT0 (0x01) */
35 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */ 31 { 0x02, 0x00 }, /* AK4671_PLL_MODE_SELECT1 (0x02) */
36 0x02, /* AK4671_FORMAT_SELECT (0x03) */ 32 { 0x03, 0x02 }, /* AK4671_FORMAT_SELECT (0x03) */
37 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */ 33 { 0x04, 0x00 }, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
38 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */ 34 { 0x05, 0x55 }, /* AK4671_MIC_AMP_GAIN (0x05) */
39 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */ 35 { 0x06, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
40 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */ 36 { 0x07, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
41 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */ 37 { 0x08, 0xb5 }, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
42 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */ 38 { 0x09, 0x00 }, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
43 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */ 39 { 0x0a, 0x00 }, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
44 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */ 40 { 0x0b, 0x00 }, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
45 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */ 41 { 0x0c, 0x00 }, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
46 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */ 42 { 0x0d, 0x00 }, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
47 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */ 43 { 0x0e, 0x00 }, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
48 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */ 44 { 0x0f, 0x00 }, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
49 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */ 45 { 0x10, 0x00 }, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
50 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */ 46 { 0x11, 0x80 }, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
51 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */ 47 { 0x12, 0x91 }, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
52 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */ 48 { 0x13, 0x91 }, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
53 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */ 49 { 0x14, 0xe1 }, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
54 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */ 50 { 0x15, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
55 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */ 51 { 0x16, 0x00 }, /* AK4671_ALC_TIMER_SELECT (0x16) */
56 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */ 52 { 0x17, 0x00 }, /* AK4671_ALC_MODE_CONTROL (0x17) */
57 0x02, /* AK4671_MODE_CONTROL1 (0x18) */ 53 { 0x18, 0x02 }, /* AK4671_MODE_CONTROL1 (0x18) */
58 0x01, /* AK4671_MODE_CONTROL2 (0x19) */ 54 { 0x19, 0x01 }, /* AK4671_MODE_CONTROL2 (0x19) */
59 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */ 55 { 0x1a, 0x18 }, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
60 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */ 56 { 0x1b, 0x18 }, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
61 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */ 57 { 0x1c, 0x00 }, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
62 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */ 58 { 0x1d, 0x02 }, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
63 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */ 59 { 0x1e, 0x00 }, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
64 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */ 60 { 0x1f, 0x00 }, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
65 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */ 61 { 0x20, 0x00 }, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
66 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */ 62 { 0x21, 0x00 }, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
67 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */ 63 { 0x22, 0x00 }, /* AK4671_EQ_COEFFICIENT0 (0x22) */
68 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */ 64 { 0x23, 0x00 }, /* AK4671_EQ_COEFFICIENT1 (0x23) */
69 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */ 65 { 0x24, 0x00 }, /* AK4671_EQ_COEFFICIENT2 (0x24) */
70 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */ 66 { 0x25, 0x00 }, /* AK4671_EQ_COEFFICIENT3 (0x25) */
71 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */ 67 { 0x26, 0x00 }, /* AK4671_EQ_COEFFICIENT4 (0x26) */
72 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */ 68 { 0x27, 0x00 }, /* AK4671_EQ_COEFFICIENT5 (0x27) */
73 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */ 69 { 0x28, 0xa9 }, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
74 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */ 70 { 0x29, 0x1f }, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
75 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */ 71 { 0x2a, 0xad }, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
76 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */ 72 { 0x2b, 0x20 }, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
77 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */ 73 { 0x2c, 0x00 }, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
78 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */ 74 { 0x2d, 0x00 }, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
79 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */ 75 { 0x2e, 0x00 }, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
80 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */ 76 { 0x2f, 0x00 }, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
81 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */ 77 { 0x30, 0x00 }, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
82 0x00, /* this register not used */ 78
83 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */ 79 { 0x32, 0x00 }, /* AK4671_E1_COEFFICIENT0 (0x32) */
84 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */ 80 { 0x33, 0x00 }, /* AK4671_E1_COEFFICIENT1 (0x33) */
85 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */ 81 { 0x34, 0x00 }, /* AK4671_E1_COEFFICIENT2 (0x34) */
86 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */ 82 { 0x35, 0x00 }, /* AK4671_E1_COEFFICIENT3 (0x35) */
87 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */ 83 { 0x36, 0x00 }, /* AK4671_E1_COEFFICIENT4 (0x36) */
88 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */ 84 { 0x37, 0x00 }, /* AK4671_E1_COEFFICIENT5 (0x37) */
89 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */ 85 { 0x38, 0x00 }, /* AK4671_E2_COEFFICIENT0 (0x38) */
90 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */ 86 { 0x39, 0x00 }, /* AK4671_E2_COEFFICIENT1 (0x39) */
91 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */ 87 { 0x3a, 0x00 }, /* AK4671_E2_COEFFICIENT2 (0x3a) */
92 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */ 88 { 0x3b, 0x00 }, /* AK4671_E2_COEFFICIENT3 (0x3b) */
93 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */ 89 { 0x3c, 0x00 }, /* AK4671_E2_COEFFICIENT4 (0x3c) */
94 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */ 90 { 0x3d, 0x00 }, /* AK4671_E2_COEFFICIENT5 (0x3d) */
95 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */ 91 { 0x3e, 0x00 }, /* AK4671_E3_COEFFICIENT0 (0x3e) */
96 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */ 92 { 0x3f, 0x00 }, /* AK4671_E3_COEFFICIENT1 (0x3f) */
97 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */ 93 { 0x40, 0x00 }, /* AK4671_E3_COEFFICIENT2 (0x40) */
98 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */ 94 { 0x41, 0x00 }, /* AK4671_E3_COEFFICIENT3 (0x41) */
99 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */ 95 { 0x42, 0x00 }, /* AK4671_E3_COEFFICIENT4 (0x42) */
100 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */ 96 { 0x43, 0x00 }, /* AK4671_E3_COEFFICIENT5 (0x43) */
101 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */ 97 { 0x44, 0x00 }, /* AK4671_E4_COEFFICIENT0 (0x44) */
102 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */ 98 { 0x45, 0x00 }, /* AK4671_E4_COEFFICIENT1 (0x45) */
103 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */ 99 { 0x46, 0x00 }, /* AK4671_E4_COEFFICIENT2 (0x46) */
104 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */ 100 { 0x47, 0x00 }, /* AK4671_E4_COEFFICIENT3 (0x47) */
105 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */ 101 { 0x48, 0x00 }, /* AK4671_E4_COEFFICIENT4 (0x48) */
106 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */ 102 { 0x49, 0x00 }, /* AK4671_E4_COEFFICIENT5 (0x49) */
107 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */ 103 { 0x4a, 0x00 }, /* AK4671_E5_COEFFICIENT0 (0x4a) */
108 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */ 104 { 0x4b, 0x00 }, /* AK4671_E5_COEFFICIENT1 (0x4b) */
109 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */ 105 { 0x4c, 0x00 }, /* AK4671_E5_COEFFICIENT2 (0x4c) */
110 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */ 106 { 0x4d, 0x00 }, /* AK4671_E5_COEFFICIENT3 (0x4d) */
111 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */ 107 { 0x4e, 0x00 }, /* AK4671_E5_COEFFICIENT4 (0x4e) */
112 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */ 108 { 0x4f, 0x00 }, /* AK4671_E5_COEFFICIENT5 (0x4f) */
113 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */ 109 { 0x50, 0x88 }, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
114 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */ 110 { 0x51, 0x88 }, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
115 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */ 111 { 0x52, 0x08 }, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
116 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */ 112 { 0x53, 0x00 }, /* AK4671_PCM_IF_CONTROL0 (0x53) */
117 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */ 113 { 0x54, 0x00 }, /* AK4671_PCM_IF_CONTROL1 (0x54) */
118 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */ 114 { 0x55, 0x00 }, /* AK4671_PCM_IF_CONTROL2 (0x55) */
119 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */ 115 { 0x56, 0x18 }, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
120 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */ 116 { 0x57, 0x18 }, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
121 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */ 117 { 0x58, 0x00 }, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
122 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */ 118 { 0x59, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
123 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */ 119 { 0x5a, 0x00 }, /* AK4671_SAR_ADC_CONTROL (0x5a) */
124}; 120};
125 121
126/* 122/*
@@ -241,19 +237,17 @@ static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
241/* Input MUXs */ 237/* Input MUXs */
242static const char *ak4671_lin_mux_texts[] = 238static const char *ak4671_lin_mux_texts[] =
243 {"LIN1", "LIN2", "LIN3", "LIN4"}; 239 {"LIN1", "LIN2", "LIN3", "LIN4"};
244static const struct soc_enum ak4671_lin_mux_enum = 240static SOC_ENUM_SINGLE_DECL(ak4671_lin_mux_enum,
245 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0, 241 AK4671_MIC_SIGNAL_SELECT, 0,
246 ARRAY_SIZE(ak4671_lin_mux_texts), 242 ak4671_lin_mux_texts);
247 ak4671_lin_mux_texts);
248static const struct snd_kcontrol_new ak4671_lin_mux_control = 243static const struct snd_kcontrol_new ak4671_lin_mux_control =
249 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum); 244 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
250 245
251static const char *ak4671_rin_mux_texts[] = 246static const char *ak4671_rin_mux_texts[] =
252 {"RIN1", "RIN2", "RIN3", "RIN4"}; 247 {"RIN1", "RIN2", "RIN3", "RIN4"};
253static const struct soc_enum ak4671_rin_mux_enum = 248static SOC_ENUM_SINGLE_DECL(ak4671_rin_mux_enum,
254 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2, 249 AK4671_MIC_SIGNAL_SELECT, 2,
255 ARRAY_SIZE(ak4671_rin_mux_texts), 250 ak4671_rin_mux_texts);
256 ak4671_rin_mux_texts);
257static const struct snd_kcontrol_new ak4671_rin_mux_control = 251static const struct snd_kcontrol_new ak4671_rin_mux_control =
258 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum); 252 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
259 253
@@ -619,18 +613,14 @@ static struct snd_soc_dai_driver ak4671_dai = {
619 613
620static int ak4671_probe(struct snd_soc_codec *codec) 614static int ak4671_probe(struct snd_soc_codec *codec)
621{ 615{
622 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
623 int ret; 616 int ret;
624 617
625 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); 618 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
626 if (ret < 0) { 619 if (ret < 0) {
627 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 620 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
628 return ret; 621 return ret;
629 } 622 }
630 623
631 snd_soc_add_codec_controls(codec, ak4671_snd_controls,
632 ARRAY_SIZE(ak4671_snd_controls));
633
634 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 624 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
635 625
636 return ret; 626 return ret;
@@ -646,28 +636,36 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
646 .probe = ak4671_probe, 636 .probe = ak4671_probe,
647 .remove = ak4671_remove, 637 .remove = ak4671_remove,
648 .set_bias_level = ak4671_set_bias_level, 638 .set_bias_level = ak4671_set_bias_level,
649 .reg_cache_size = AK4671_CACHEREGNUM, 639 .controls = ak4671_snd_controls,
650 .reg_word_size = sizeof(u8), 640 .num_controls = ARRAY_SIZE(ak4671_snd_controls),
651 .reg_cache_default = ak4671_reg,
652 .dapm_widgets = ak4671_dapm_widgets, 641 .dapm_widgets = ak4671_dapm_widgets,
653 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), 642 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
654 .dapm_routes = ak4671_intercon, 643 .dapm_routes = ak4671_intercon,
655 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), 644 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
656}; 645};
657 646
647static const struct regmap_config ak4671_regmap = {
648 .reg_bits = 8,
649 .val_bits = 8,
650
651 .max_register = AK4671_SAR_ADC_CONTROL,
652 .reg_defaults = ak4671_reg_defaults,
653 .num_reg_defaults = ARRAY_SIZE(ak4671_reg_defaults),
654 .cache_type = REGCACHE_RBTREE,
655};
656
658static int ak4671_i2c_probe(struct i2c_client *client, 657static int ak4671_i2c_probe(struct i2c_client *client,
659 const struct i2c_device_id *id) 658 const struct i2c_device_id *id)
660{ 659{
661 struct ak4671_priv *ak4671; 660 struct regmap *regmap;
662 int ret; 661 int ret;
663 662
664 ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv), 663 regmap = devm_regmap_init_i2c(client, &ak4671_regmap);
665 GFP_KERNEL); 664 if (IS_ERR(regmap)) {
666 if (ak4671 == NULL) 665 ret = PTR_ERR(regmap);
667 return -ENOMEM; 666 dev_err(&client->dev, "Failed to create regmap: %d\n", ret);
668 667 return ret;
669 i2c_set_clientdata(client, ak4671); 668 }
670 ak4671->control_type = SND_SOC_I2C;
671 669
672 ret = snd_soc_register_codec(&client->dev, 670 ret = snd_soc_register_codec(&client->dev,
673 &soc_codec_dev_ak4671, &ak4671_dai, 1); 671 &soc_codec_dev_ak4671, &ak4671_dai, 1);
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
index 61cb7ab7552c..394a34d3f50a 100644
--- a/sound/soc/codecs/ak4671.h
+++ b/sound/soc/codecs/ak4671.h
@@ -105,8 +105,6 @@
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59 105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a 106#define AK4671_SAR_ADC_CONTROL 0x5a
107 107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */ 108/* Bitfield Definitions */
111 109
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */ 110/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index d3036283482a..ed506253a914 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -21,6 +21,7 @@
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/regmap.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
@@ -38,26 +39,13 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
38 39
39/* codec private data */ 40/* codec private data */
40struct alc5623_priv { 41struct alc5623_priv {
41 enum snd_soc_control_type control_type; 42 struct regmap *regmap;
42 u8 id; 43 u8 id;
43 unsigned int sysclk; 44 unsigned int sysclk;
44 u16 reg_cache[ALC5623_VENDOR_ID2+2];
45 unsigned int add_ctrl; 45 unsigned int add_ctrl;
46 unsigned int jack_det_ctrl; 46 unsigned int jack_det_ctrl;
47}; 47};
48 48
49static void alc5623_fill_cache(struct snd_soc_codec *codec)
50{
51 int i, step = codec->driver->reg_cache_step;
52 u16 *cache = codec->reg_cache;
53
54 /* not really efficient ... */
55 codec->cache_bypass = 1;
56 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
57 cache[i] = snd_soc_read(codec, i);
58 codec->cache_bypass = 0;
59}
60
61static inline int alc5623_reset(struct snd_soc_codec *codec) 49static inline int alc5623_reset(struct snd_soc_codec *codec)
62{ 50{
63 return snd_soc_write(codec, ALC5623_RESET, 0); 51 return snd_soc_write(codec, ALC5623_RESET, 0);
@@ -228,32 +216,37 @@ static const char *alc5623_aux_out_input_sel[] = {
228 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 216 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
229 217
230/* auxout output mux */ 218/* auxout output mux */
231static const struct soc_enum alc5623_aux_out_input_enum = 219static SOC_ENUM_SINGLE_DECL(alc5623_aux_out_input_enum,
232SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); 220 ALC5623_OUTPUT_MIXER_CTRL, 6,
221 alc5623_aux_out_input_sel);
233static const struct snd_kcontrol_new alc5623_auxout_mux_controls = 222static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
234SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); 223SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
235 224
236/* speaker output mux */ 225/* speaker output mux */
237static const struct soc_enum alc5623_spkout_input_enum = 226static SOC_ENUM_SINGLE_DECL(alc5623_spkout_input_enum,
238SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); 227 ALC5623_OUTPUT_MIXER_CTRL, 10,
228 alc5623_spkout_input_sel);
239static const struct snd_kcontrol_new alc5623_spkout_mux_controls = 229static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
240SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); 230SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
241 231
242/* headphone left output mux */ 232/* headphone left output mux */
243static const struct soc_enum alc5623_hpl_out_input_enum = 233static SOC_ENUM_SINGLE_DECL(alc5623_hpl_out_input_enum,
244SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); 234 ALC5623_OUTPUT_MIXER_CTRL, 9,
235 alc5623_hpl_out_input_sel);
245static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = 236static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
246SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); 237SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
247 238
248/* headphone right output mux */ 239/* headphone right output mux */
249static const struct soc_enum alc5623_hpr_out_input_enum = 240static SOC_ENUM_SINGLE_DECL(alc5623_hpr_out_input_enum,
250SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); 241 ALC5623_OUTPUT_MIXER_CTRL, 8,
242 alc5623_hpr_out_input_sel);
251static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = 243static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
252SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); 244SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
253 245
254/* speaker output N select */ 246/* speaker output N select */
255static const struct soc_enum alc5623_spk_n_sour_enum = 247static SOC_ENUM_SINGLE_DECL(alc5623_spk_n_sour_enum,
256SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); 248 ALC5623_OUTPUT_MIXER_CTRL, 14,
249 alc5623_spk_n_sour_sel);
257static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = 250static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
258SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); 251SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
259 252
@@ -338,8 +331,9 @@ SND_SOC_DAPM_VMID("Vmid"),
338}; 331};
339 332
340static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; 333static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
341static const struct soc_enum alc5623_amp_enum = 334static SOC_ENUM_SINGLE_DECL(alc5623_amp_enum,
342 SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); 335 ALC5623_OUTPUT_MIXER_CTRL, 13,
336 alc5623_amp_names);
343static const struct snd_kcontrol_new alc5623_amp_mux_controls = 337static const struct snd_kcontrol_new alc5623_amp_mux_controls =
344 SOC_DAPM_ENUM("Route", alc5623_amp_enum); 338 SOC_DAPM_ENUM("Route", alc5623_amp_enum);
345 339
@@ -869,18 +863,28 @@ static struct snd_soc_dai_driver alc5623_dai = {
869 863
870static int alc5623_suspend(struct snd_soc_codec *codec) 864static int alc5623_suspend(struct snd_soc_codec *codec)
871{ 865{
866 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
867
872 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); 868 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
869 regcache_cache_only(alc5623->regmap, true);
870
873 return 0; 871 return 0;
874} 872}
875 873
876static int alc5623_resume(struct snd_soc_codec *codec) 874static int alc5623_resume(struct snd_soc_codec *codec)
877{ 875{
878 int i, step = codec->driver->reg_cache_step; 876 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
879 u16 *cache = codec->reg_cache; 877 int ret;
880 878
881 /* Sync reg_cache with the hardware */ 879 /* Sync reg_cache with the hardware */
882 for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) 880 regcache_cache_only(alc5623->regmap, false);
883 snd_soc_write(codec, i, cache[i]); 881 ret = regcache_sync(alc5623->regmap);
882 if (ret != 0) {
883 dev_err(codec->dev, "Failed to sync register cache: %d\n",
884 ret);
885 regcache_cache_only(alc5623->regmap, true);
886 return ret;
887 }
884 888
885 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 889 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
886 890
@@ -900,14 +904,14 @@ static int alc5623_probe(struct snd_soc_codec *codec)
900 struct snd_soc_dapm_context *dapm = &codec->dapm; 904 struct snd_soc_dapm_context *dapm = &codec->dapm;
901 int ret; 905 int ret;
902 906
903 ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); 907 codec->control_data = alc5623->regmap;
908 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
904 if (ret < 0) { 909 if (ret < 0) {
905 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 910 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
906 return ret; 911 return ret;
907 } 912 }
908 913
909 alc5623_reset(codec); 914 alc5623_reset(codec);
910 alc5623_fill_cache(codec);
911 915
912 /* power on device */ 916 /* power on device */
913 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 917 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -980,9 +984,15 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
980 .suspend = alc5623_suspend, 984 .suspend = alc5623_suspend,
981 .resume = alc5623_resume, 985 .resume = alc5623_resume,
982 .set_bias_level = alc5623_set_bias_level, 986 .set_bias_level = alc5623_set_bias_level,
983 .reg_cache_size = ALC5623_VENDOR_ID2+2, 987};
984 .reg_word_size = sizeof(u16), 988
985 .reg_cache_step = 2, 989static const struct regmap_config alc5623_regmap = {
990 .reg_bits = 8,
991 .val_bits = 16,
992 .reg_stride = 2,
993
994 .max_register = ALC5623_VENDOR_ID2,
995 .cache_type = REGCACHE_RBTREE,
986}; 996};
987 997
988/* 998/*
@@ -996,19 +1006,32 @@ static int alc5623_i2c_probe(struct i2c_client *client,
996{ 1006{
997 struct alc5623_platform_data *pdata; 1007 struct alc5623_platform_data *pdata;
998 struct alc5623_priv *alc5623; 1008 struct alc5623_priv *alc5623;
999 int ret, vid1, vid2; 1009 unsigned int vid1, vid2;
1010 int ret;
1000 1011
1001 vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); 1012 alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
1002 if (vid1 < 0) { 1013 GFP_KERNEL);
1003 dev_err(&client->dev, "failed to read I2C\n"); 1014 if (alc5623 == NULL)
1004 return -EIO; 1015 return -ENOMEM;
1016
1017 alc5623->regmap = devm_regmap_init_i2c(client, &alc5623_regmap);
1018 if (IS_ERR(alc5623->regmap)) {
1019 ret = PTR_ERR(alc5623->regmap);
1020 dev_err(&client->dev, "Failed to initialise I/O: %d\n", ret);
1021 return ret;
1022 }
1023
1024 ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID1, &vid1);
1025 if (ret < 0) {
1026 dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret);
1027 return ret;
1005 } 1028 }
1006 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); 1029 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
1007 1030
1008 vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); 1031 ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2);
1009 if (vid2 < 0) { 1032 if (ret < 0) {
1010 dev_err(&client->dev, "failed to read I2C\n"); 1033 dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret);
1011 return -EIO; 1034 return ret;
1012 } 1035 }
1013 1036
1014 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { 1037 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
@@ -1021,11 +1044,6 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1021 1044
1022 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); 1045 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
1023 1046
1024 alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
1025 GFP_KERNEL);
1026 if (alc5623 == NULL)
1027 return -ENOMEM;
1028
1029 pdata = client->dev.platform_data; 1047 pdata = client->dev.platform_data;
1030 if (pdata) { 1048 if (pdata) {
1031 alc5623->add_ctrl = pdata->add_ctrl; 1049 alc5623->add_ctrl = pdata->add_ctrl;
@@ -1048,7 +1066,6 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1048 } 1066 }
1049 1067
1050 i2c_set_clientdata(client, alc5623); 1068 i2c_set_clientdata(client, alc5623);
1051 alc5623->control_type = SND_SOC_I2C;
1052 1069
1053 ret = snd_soc_register_codec(&client->dev, 1070 ret = snd_soc_register_codec(&client->dev,
1054 &soc_codec_device_alc5623, &alc5623_dai, 1); 1071 &soc_codec_device_alc5623, &alc5623_dai, 1);
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index fb001c56cf8d..d885056ad8f2 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -293,51 +293,59 @@ static const char * const alc5632_i2s_out_sel[] = {
293 "ADC LR", "Voice Stereo Digital"}; 293 "ADC LR", "Voice Stereo Digital"};
294 294
295/* auxout output mux */ 295/* auxout output mux */
296static const struct soc_enum alc5632_aux_out_input_enum = 296static SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum,
297SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel); 297 ALC5632_OUTPUT_MIXER_CTRL, 6,
298 alc5632_aux_out_input_sel);
298static const struct snd_kcontrol_new alc5632_auxout_mux_controls = 299static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
299SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); 300SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
300 301
301/* speaker output mux */ 302/* speaker output mux */
302static const struct soc_enum alc5632_spkout_input_enum = 303static SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum,
303SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel); 304 ALC5632_OUTPUT_MIXER_CTRL, 10,
305 alc5632_spkout_input_sel);
304static const struct snd_kcontrol_new alc5632_spkout_mux_controls = 306static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
305SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); 307SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
306 308
307/* headphone left output mux */ 309/* headphone left output mux */
308static const struct soc_enum alc5632_hpl_out_input_enum = 310static SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum,
309SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel); 311 ALC5632_OUTPUT_MIXER_CTRL, 9,
312 alc5632_hpl_out_input_sel);
310static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = 313static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
311SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); 314SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
312 315
313/* headphone right output mux */ 316/* headphone right output mux */
314static const struct soc_enum alc5632_hpr_out_input_enum = 317static SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum,
315SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel); 318 ALC5632_OUTPUT_MIXER_CTRL, 8,
319 alc5632_hpr_out_input_sel);
316static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = 320static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
317SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); 321SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
318 322
319/* speaker output N select */ 323/* speaker output N select */
320static const struct soc_enum alc5632_spk_n_sour_enum = 324static SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum,
321SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel); 325 ALC5632_OUTPUT_MIXER_CTRL, 14,
326 alc5632_spk_n_sour_sel);
322static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = 327static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
323SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); 328SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
324 329
325/* speaker amplifier */ 330/* speaker amplifier */
326static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; 331static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
327static const struct soc_enum alc5632_amp_enum = 332static SOC_ENUM_SINGLE_DECL(alc5632_amp_enum,
328 SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names); 333 ALC5632_OUTPUT_MIXER_CTRL, 13,
334 alc5632_amp_names);
329static const struct snd_kcontrol_new alc5632_amp_mux_controls = 335static const struct snd_kcontrol_new alc5632_amp_mux_controls =
330 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); 336 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
331 337
332/* ADC output select */ 338/* ADC output select */
333static const struct soc_enum alc5632_adcr_func_enum = 339static SOC_ENUM_SINGLE_DECL(alc5632_adcr_func_enum,
334 SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel); 340 ALC5632_DAC_FUNC_SELECT, 5,
341 alc5632_adcr_func_sel);
335static const struct snd_kcontrol_new alc5632_adcr_func_controls = 342static const struct snd_kcontrol_new alc5632_adcr_func_controls =
336 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); 343 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
337 344
338/* I2S out select */ 345/* I2S out select */
339static const struct soc_enum alc5632_i2s_out_enum = 346static SOC_ENUM_SINGLE_DECL(alc5632_i2s_out_enum,
340 SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel); 347 ALC5632_I2S_OUT_CTL, 5,
348 alc5632_i2s_out_sel);
341static const struct snd_kcontrol_new alc5632_i2s_out_controls = 349static const struct snd_kcontrol_new alc5632_i2s_out_controls =
342 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); 350 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
343 351
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 6e9ea8379a91..3eab46020a30 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -30,6 +30,7 @@
30#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/regmap.h>
33 34
34#include "cs42l51.h" 35#include "cs42l51.h"
35 36
@@ -40,7 +41,6 @@ enum master_slave_mode {
40}; 41};
41 42
42struct cs42l51_private { 43struct cs42l51_private {
43 enum snd_soc_control_type control_type;
44 unsigned int mclk; 44 unsigned int mclk;
45 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 45 unsigned int audio_mode; /* The mode (I2S or left-justified) */
46 enum master_slave_mode func; 46 enum master_slave_mode func;
@@ -52,24 +52,6 @@ struct cs42l51_private {
52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ 52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) 53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
54 54
55static int cs42l51_fill_cache(struct snd_soc_codec *codec)
56{
57 u8 *cache = codec->reg_cache + 1;
58 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
59 s32 length;
60
61 length = i2c_smbus_read_i2c_block_data(i2c_client,
62 CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
63 if (length != CS42L51_NUMREGS) {
64 dev_err(&i2c_client->dev,
65 "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
66 i2c_client->addr, length, CS42L51_NUMREGS);
67 return -EIO;
68 }
69
70 return 0;
71}
72
73static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 55static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
74 struct snd_ctl_elem_value *ucontrol) 56 struct snd_ctl_elem_value *ucontrol)
75{ 57{
@@ -505,16 +487,9 @@ static struct snd_soc_dai_driver cs42l51_dai = {
505 487
506static int cs42l51_probe(struct snd_soc_codec *codec) 488static int cs42l51_probe(struct snd_soc_codec *codec)
507{ 489{
508 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
509 int ret, reg; 490 int ret, reg;
510 491
511 ret = cs42l51_fill_cache(codec); 492 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
512 if (ret < 0) {
513 dev_err(codec->dev, "failed to fill register cache\n");
514 return ret;
515 }
516
517 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
518 if (ret < 0) { 493 if (ret < 0) {
519 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 494 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
520 return ret; 495 return ret;
@@ -538,8 +513,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
538 513
539static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { 514static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
540 .probe = cs42l51_probe, 515 .probe = cs42l51_probe,
541 .reg_cache_size = CS42L51_NUMREGS + 1,
542 .reg_word_size = sizeof(u8),
543 516
544 .controls = cs42l51_snd_controls, 517 .controls = cs42l51_snd_controls,
545 .num_controls = ARRAY_SIZE(cs42l51_snd_controls), 518 .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
@@ -549,38 +522,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
549 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), 522 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
550}; 523};
551 524
525static const struct regmap_config cs42l51_regmap = {
526 .reg_bits = 8,
527 .val_bits = 8,
528
529 .max_register = CS42L51_CHARGE_FREQ,
530 .cache_type = REGCACHE_RBTREE,
531};
532
552static int cs42l51_i2c_probe(struct i2c_client *i2c_client, 533static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
553 const struct i2c_device_id *id) 534 const struct i2c_device_id *id)
554{ 535{
555 struct cs42l51_private *cs42l51; 536 struct cs42l51_private *cs42l51;
537 struct regmap *regmap;
538 unsigned int val;
556 int ret; 539 int ret;
557 540
541 regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap);
542 if (IS_ERR(regmap)) {
543 ret = PTR_ERR(regmap);
544 dev_err(&i2c_client->dev, "Failed to create regmap: %d\n",
545 ret);
546 return ret;
547 }
548
558 /* Verify that we have a CS42L51 */ 549 /* Verify that we have a CS42L51 */
559 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID); 550 ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
560 if (ret < 0) { 551 if (ret < 0) {
561 dev_err(&i2c_client->dev, "failed to read I2C\n"); 552 dev_err(&i2c_client->dev, "failed to read I2C\n");
562 goto error; 553 goto error;
563 } 554 }
564 555
565 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && 556 if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
566 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { 557 (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
567 dev_err(&i2c_client->dev, "Invalid chip id\n"); 558 dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val);
568 ret = -ENODEV; 559 ret = -ENODEV;
569 goto error; 560 goto error;
570 } 561 }
571 562
572 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", 563 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
573 ret & 7); 564 val & 7);
574 565
575 cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), 566 cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
576 GFP_KERNEL); 567 GFP_KERNEL);
577 if (!cs42l51) { 568 if (!cs42l51)
578 dev_err(&i2c_client->dev, "could not allocate codec\n");
579 return -ENOMEM; 569 return -ENOMEM;
580 }
581 570
582 i2c_set_clientdata(i2c_client, cs42l51); 571 i2c_set_clientdata(i2c_client, cs42l51);
583 cs42l51->control_type = SND_SOC_I2C;
584 572
585 ret = snd_soc_register_codec(&i2c_client->dev, 573 ret = snd_soc_register_codec(&i2c_client->dev,
586 &soc_codec_device_cs42l51, &cs42l51_dai, 1); 574 &soc_codec_device_cs42l51, &cs42l51_dai, 1);
@@ -600,10 +588,17 @@ static const struct i2c_device_id cs42l51_id[] = {
600}; 588};
601MODULE_DEVICE_TABLE(i2c, cs42l51_id); 589MODULE_DEVICE_TABLE(i2c, cs42l51_id);
602 590
591static const struct of_device_id cs42l51_of_match[] = {
592 { .compatible = "cirrus,cs42l51", },
593 { }
594};
595MODULE_DEVICE_TABLE(of, cs42l51_of_match);
596
603static struct i2c_driver cs42l51_i2c_driver = { 597static struct i2c_driver cs42l51_i2c_driver = {
604 .driver = { 598 .driver = {
605 .name = "cs42l51-codec", 599 .name = "cs42l51-codec",
606 .owner = THIS_MODULE, 600 .owner = THIS_MODULE,
601 .of_match_table = cs42l51_of_match,
607 }, 602 },
608 .id_table = cs42l51_id, 603 .id_table = cs42l51_id,
609 .probe = cs42l51_i2c_probe, 604 .probe = cs42l51_i2c_probe,
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index f295b6569910..8053e0e7f4a7 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -1301,9 +1301,9 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
1301 msleep(DA732X_WAIT_FOR_STABILIZATION); 1301 msleep(DA732X_WAIT_FOR_STABILIZATION);
1302 1302
1303 /* Check DAC offset sign */ 1303 /* Check DAC offset sign */
1304 sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 1304 sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1305 DA732X_HP_DAC_OFF_CNTL_COMPO); 1305 DA732X_HP_DAC_OFF_CNTL_COMPO);
1306 sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 1306 sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1307 DA732X_HP_DAC_OFF_CNTL_COMPO); 1307 DA732X_HP_DAC_OFF_CNTL_COMPO);
1308 1308
1309 /* Binary search DAC offset values (both channels at once) */ 1309 /* Binary search DAC offset values (both channels at once) */
@@ -1320,10 +1320,10 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
1320 1320
1321 msleep(DA732X_WAIT_FOR_STABILIZATION); 1321 msleep(DA732X_WAIT_FOR_STABILIZATION);
1322 1322
1323 if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & 1323 if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1324 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) 1324 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
1325 offset[DA732X_HPL_DAC] &= ~step; 1325 offset[DA732X_HPL_DAC] &= ~step;
1326 if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & 1326 if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1327 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) 1327 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
1328 offset[DA732X_HPR_DAC] &= ~step; 1328 offset[DA732X_HPR_DAC] &= ~step;
1329 1329
@@ -1364,9 +1364,9 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
1364 msleep(DA732X_WAIT_FOR_STABILIZATION); 1364 msleep(DA732X_WAIT_FOR_STABILIZATION);
1365 1365
1366 /* Check output offset sign */ 1366 /* Check output offset sign */
1367 sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) & 1367 sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) &
1368 DA732X_HP_OUT_COMPO; 1368 DA732X_HP_OUT_COMPO;
1369 sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) & 1369 sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) &
1370 DA732X_HP_OUT_COMPO; 1370 DA732X_HP_OUT_COMPO;
1371 1371
1372 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | 1372 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
@@ -1387,10 +1387,10 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
1387 1387
1388 msleep(DA732X_WAIT_FOR_STABILIZATION); 1388 msleep(DA732X_WAIT_FOR_STABILIZATION);
1389 1389
1390 if ((codec->hw_read(codec, DA732X_REG_HPL) & 1390 if ((snd_soc_read(codec, DA732X_REG_HPL) &
1391 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) 1391 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
1392 offset[DA732X_HPL_AMP] &= ~step; 1392 offset[DA732X_HPL_AMP] &= ~step;
1393 if ((codec->hw_read(codec, DA732X_REG_HPR) & 1393 if ((snd_soc_read(codec, DA732X_REG_HPR) &
1394 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) 1394 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
1395 offset[DA732X_HPR_AMP] &= ~step; 1395 offset[DA732X_HPR_AMP] &= ~step;
1396 1396
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 0fcbe90f3ef2..c8c37e431e7c 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1350,14 +1350,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1350 int ret; 1350 int ret;
1351 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 1351 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1352 1352
1353 /* setup i2c data ops */
1354 codec->control_data = sgtl5000->regmap;
1355 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
1356 if (ret < 0) {
1357 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1358 return ret;
1359 }
1360
1361 ret = sgtl5000_enable_regulators(codec); 1353 ret = sgtl5000_enable_regulators(codec);
1362 if (ret) 1354 if (ret)
1363 return ret; 1355 return ret;
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index 52e7cb08434b..fa2b8e07f420 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -210,7 +210,7 @@ out:
210static int si476x_codec_probe(struct snd_soc_codec *codec) 210static int si476x_codec_probe(struct snd_soc_codec *codec)
211{ 211{
212 codec->control_data = dev_get_regmap(codec->dev->parent, NULL); 212 codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
213 return 0; 213 return snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
214} 214}
215 215
216static struct snd_soc_dai_ops si476x_dai_ops = { 216static struct snd_soc_dai_ops si476x_dai_ops = {
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c
new file mode 100644
index 000000000000..20fc46092c2c
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23-i2c.c
@@ -0,0 +1,59 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver I2C interface
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/i2c.h>
15#include <linux/module.h>
16#include <linux/regmap.h>
17#include <sound/soc.h>
18
19#include "tlv320aic23.h"
20
21static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
22 const struct i2c_device_id *i2c_id)
23{
24 struct regmap *regmap;
25
26 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
27 return -EINVAL;
28
29 regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
30 return tlv320aic23_probe(&i2c->dev, regmap);
31}
32
33static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
34{
35 snd_soc_unregister_codec(&i2c->dev);
36 return 0;
37}
38
39static const struct i2c_device_id tlv320aic23_id[] = {
40 {"tlv320aic23", 0},
41 {}
42};
43
44MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
45
46static struct i2c_driver tlv320aic23_i2c_driver = {
47 .driver = {
48 .name = "tlv320aic23-codec",
49 },
50 .probe = tlv320aic23_i2c_probe,
51 .remove = __exit_p(tlv320aic23_i2c_remove),
52 .id_table = tlv320aic23_id,
53};
54
55module_i2c_driver(tlv320aic23_i2c_driver);
56
57MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver I2C");
58MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
59MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23-spi.c b/sound/soc/codecs/tlv320aic23-spi.c
new file mode 100644
index 000000000000..585aea436c6a
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23-spi.c
@@ -0,0 +1,57 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver SPI interface
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/regmap.h>
16#include <linux/spi/spi.h>
17#include <sound/soc.h>
18
19#include "tlv320aic23.h"
20
21static int aic23_spi_probe(struct spi_device *spi)
22{
23 int ret;
24 struct regmap *regmap;
25
26 dev_dbg(&spi->dev, "probing tlv320aic23 spi device\n");
27
28 spi->bits_per_word = 16;
29 spi->mode = SPI_MODE_0;
30 ret = spi_setup(spi);
31 if (ret < 0)
32 return ret;
33
34 regmap = devm_regmap_init_spi(spi, &tlv320aic23_regmap);
35 return tlv320aic23_probe(&spi->dev, regmap);
36}
37
38static int aic23_spi_remove(struct spi_device *spi)
39{
40 snd_soc_unregister_codec(&spi->dev);
41 return 0;
42}
43
44static struct spi_driver aic23_spi = {
45 .driver = {
46 .name = "tlv320aic23",
47 .owner = THIS_MODULE,
48 },
49 .probe = aic23_spi_probe,
50 .remove = aic23_spi_remove,
51};
52
53module_spi_driver(aic23_spi);
54
55MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver SPI");
56MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
57MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 5d430cc56f51..7b4cfef232ea 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -23,7 +23,6 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/regmap.h> 26#include <linux/regmap.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <sound/core.h> 28#include <sound/core.h>
@@ -51,7 +50,7 @@ static const struct reg_default tlv320aic23_reg[] = {
51 { 9, 0x0000 }, 50 { 9, 0x0000 },
52}; 51};
53 52
54static const struct regmap_config tlv320aic23_regmap = { 53const struct regmap_config tlv320aic23_regmap = {
55 .reg_bits = 7, 54 .reg_bits = 7,
56 .val_bits = 9, 55 .val_bits = 9,
57 56
@@ -60,20 +59,21 @@ static const struct regmap_config tlv320aic23_regmap = {
60 .num_reg_defaults = ARRAY_SIZE(tlv320aic23_reg), 59 .num_reg_defaults = ARRAY_SIZE(tlv320aic23_reg),
61 .cache_type = REGCACHE_RBTREE, 60 .cache_type = REGCACHE_RBTREE,
62}; 61};
62EXPORT_SYMBOL(tlv320aic23_regmap);
63 63
64static const char *rec_src_text[] = { "Line", "Mic" }; 64static const char *rec_src_text[] = { "Line", "Mic" };
65static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 65static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
66 66
67static const struct soc_enum rec_src_enum = 67static SOC_ENUM_SINGLE_DECL(rec_src_enum,
68 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); 68 TLV320AIC23_ANLG, 2, rec_src_text);
69 69
70static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = 70static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
71SOC_DAPM_ENUM("Input Select", rec_src_enum); 71SOC_DAPM_ENUM("Input Select", rec_src_enum);
72 72
73static const struct soc_enum tlv320aic23_rec_src = 73static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src,
74 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); 74 TLV320AIC23_ANLG, 2, rec_src_text);
75static const struct soc_enum tlv320aic23_deemph = 75static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph,
76 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); 76 TLV320AIC23_DIGT, 1, deemph_text);
77 77
78static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); 78static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
79static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); 79static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
@@ -557,7 +557,7 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
557 return 0; 557 return 0;
558} 558}
559 559
560static int tlv320aic23_probe(struct snd_soc_codec *codec) 560static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
561{ 561{
562 int ret; 562 int ret;
563 563
@@ -604,7 +604,7 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec)
604} 604}
605 605
606static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { 606static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
607 .probe = tlv320aic23_probe, 607 .probe = tlv320aic23_codec_probe,
608 .remove = tlv320aic23_remove, 608 .remove = tlv320aic23_remove,
609 .suspend = tlv320aic23_suspend, 609 .suspend = tlv320aic23_suspend,
610 .resume = tlv320aic23_resume, 610 .resume = tlv320aic23_resume,
@@ -617,56 +617,25 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
617 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), 617 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
618}; 618};
619 619
620/* 620int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
621 * If the i2c layer weren't so broken, we could pass this kind of data
622 * around
623 */
624static int tlv320aic23_codec_probe(struct i2c_client *i2c,
625 const struct i2c_device_id *i2c_id)
626{ 621{
627 struct aic23 *aic23; 622 struct aic23 *aic23;
628 int ret;
629 623
630 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 624 if (IS_ERR(regmap))
631 return -EINVAL; 625 return PTR_ERR(regmap);
632 626
633 aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL); 627 aic23 = devm_kzalloc(dev, sizeof(struct aic23), GFP_KERNEL);
634 if (aic23 == NULL) 628 if (aic23 == NULL)
635 return -ENOMEM; 629 return -ENOMEM;
636 630
637 aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap); 631 aic23->regmap = regmap;
638 if (IS_ERR(aic23->regmap))
639 return PTR_ERR(aic23->regmap);
640 632
641 i2c_set_clientdata(i2c, aic23); 633 dev_set_drvdata(dev, aic23);
642 634
643 ret = snd_soc_register_codec(&i2c->dev, 635 return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
644 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); 636 &tlv320aic23_dai, 1);
645 return ret;
646}
647static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
648{
649 snd_soc_unregister_codec(&i2c->dev);
650 return 0;
651} 637}
652 638EXPORT_SYMBOL(tlv320aic23_probe);
653static const struct i2c_device_id tlv320aic23_id[] = {
654 {"tlv320aic23", 0},
655 {}
656};
657
658MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
659
660static struct i2c_driver tlv320aic23_i2c_driver = {
661 .driver = {
662 .name = "tlv320aic23-codec",
663 },
664 .probe = tlv320aic23_codec_probe,
665 .remove = __exit_p(tlv320aic23_i2c_remove),
666 .id_table = tlv320aic23_id,
667};
668
669module_i2c_driver(tlv320aic23_i2c_driver);
670 639
671MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 640MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
672MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 641MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
index e804120bd3da..3a7235a04a89 100644
--- a/sound/soc/codecs/tlv320aic23.h
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -12,6 +12,12 @@
12#ifndef _TLV320AIC23_H 12#ifndef _TLV320AIC23_H
13#define _TLV320AIC23_H 13#define _TLV320AIC23_H
14 14
15struct device;
16struct regmap_config;
17
18extern const struct regmap_config tlv320aic23_regmap;
19int tlv320aic23_probe(struct device *dev, struct regmap *regmap);
20
15/* Codec TLV320AIC23 */ 21/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00 22#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01 23#define TLV320AIC23_RINVOL 0x01
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 688151ba309a..c6bd7e75352d 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -29,9 +29,12 @@
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/pm.h> 30#include <linux/pm.h>
31#include <linux/gpio.h> 31#include <linux/gpio.h>
32#include <linux/of_gpio.h>
32#include <linux/i2c.h> 33#include <linux/i2c.h>
33#include <linux/cdev.h> 34#include <linux/cdev.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/clk.h>
37#include <linux/regulator/consumer.h>
35 38
36#include <sound/tlv320aic32x4.h> 39#include <sound/tlv320aic32x4.h>
37#include <sound/core.h> 40#include <sound/core.h>
@@ -66,20 +69,32 @@ struct aic32x4_priv {
66 u32 micpga_routing; 69 u32 micpga_routing;
67 bool swapdacs; 70 bool swapdacs;
68 int rstn_gpio; 71 int rstn_gpio;
72 struct clk *mclk;
73
74 struct regulator *supply_ldo;
75 struct regulator *supply_iov;
76 struct regulator *supply_dv;
77 struct regulator *supply_av;
69}; 78};
70 79
71/* 0dB min, 1dB steps */
72static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0);
73/* 0dB min, 0.5dB steps */ 80/* 0dB min, 0.5dB steps */
74static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0); 81static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
82/* -63.5dB min, 0.5dB steps */
83static DECLARE_TLV_DB_SCALE(tlv_pcm, -6350, 50, 0);
84/* -6dB min, 1dB steps */
85static DECLARE_TLV_DB_SCALE(tlv_driver_gain, -600, 100, 0);
86/* -12dB min, 0.5dB steps */
87static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0);
75 88
76static const struct snd_kcontrol_new aic32x4_snd_controls[] = { 89static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
77 SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL, 90 SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
78 AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5), 91 AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm),
79 SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, 92 SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
80 AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1), 93 AIC32X4_HPRGAIN, 0, -0x6, 0x1d, 5, 0,
81 SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN, 94 tlv_driver_gain),
82 AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1), 95 SOC_DOUBLE_R_S_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
96 AIC32X4_LORGAIN, 0, -0x6, 0x1d, 5, 0,
97 tlv_driver_gain),
83 SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN, 98 SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
84 AIC32X4_HPRGAIN, 6, 0x01, 1), 99 AIC32X4_HPRGAIN, 6, 0x01, 1),
85 SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, 100 SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
@@ -90,8 +105,8 @@ static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
90 SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0), 105 SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
91 SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0), 106 SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
92 107
93 SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL, 108 SOC_DOUBLE_R_S_TLV("ADC Level Volume", AIC32X4_LADCVOL,
94 AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5), 109 AIC32X4_RADCVOL, 0, -0x18, 0x28, 6, 0, tlv_adc_vol),
95 SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL, 110 SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
96 AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5), 111 AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
97 112
@@ -480,8 +495,18 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
480static int aic32x4_set_bias_level(struct snd_soc_codec *codec, 495static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
481 enum snd_soc_bias_level level) 496 enum snd_soc_bias_level level)
482{ 497{
498 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
499 int ret;
500
483 switch (level) { 501 switch (level) {
484 case SND_SOC_BIAS_ON: 502 case SND_SOC_BIAS_ON:
503 /* Switch on master clock */
504 ret = clk_prepare_enable(aic32x4->mclk);
505 if (ret) {
506 dev_err(codec->dev, "Failed to enable master clock\n");
507 return ret;
508 }
509
485 /* Switch on PLL */ 510 /* Switch on PLL */
486 snd_soc_update_bits(codec, AIC32X4_PLLPR, 511 snd_soc_update_bits(codec, AIC32X4_PLLPR,
487 AIC32X4_PLLEN, AIC32X4_PLLEN); 512 AIC32X4_PLLEN, AIC32X4_PLLEN);
@@ -509,29 +534,32 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
509 case SND_SOC_BIAS_PREPARE: 534 case SND_SOC_BIAS_PREPARE:
510 break; 535 break;
511 case SND_SOC_BIAS_STANDBY: 536 case SND_SOC_BIAS_STANDBY:
512 /* Switch off PLL */ 537 /* Switch off BCLK_N Divider */
513 snd_soc_update_bits(codec, AIC32X4_PLLPR, 538 snd_soc_update_bits(codec, AIC32X4_BCLKN,
514 AIC32X4_PLLEN, 0); 539 AIC32X4_BCLKEN, 0);
515 540
516 /* Switch off NDAC Divider */ 541 /* Switch off MADC Divider */
517 snd_soc_update_bits(codec, AIC32X4_NDAC, 542 snd_soc_update_bits(codec, AIC32X4_MADC,
518 AIC32X4_NDACEN, 0); 543 AIC32X4_MADCEN, 0);
544
545 /* Switch off NADC Divider */
546 snd_soc_update_bits(codec, AIC32X4_NADC,
547 AIC32X4_NADCEN, 0);
519 548
520 /* Switch off MDAC Divider */ 549 /* Switch off MDAC Divider */
521 snd_soc_update_bits(codec, AIC32X4_MDAC, 550 snd_soc_update_bits(codec, AIC32X4_MDAC,
522 AIC32X4_MDACEN, 0); 551 AIC32X4_MDACEN, 0);
523 552
524 /* Switch off NADC Divider */ 553 /* Switch off NDAC Divider */
525 snd_soc_update_bits(codec, AIC32X4_NADC, 554 snd_soc_update_bits(codec, AIC32X4_NDAC,
526 AIC32X4_NADCEN, 0); 555 AIC32X4_NDACEN, 0);
527 556
528 /* Switch off MADC Divider */ 557 /* Switch off PLL */
529 snd_soc_update_bits(codec, AIC32X4_MADC, 558 snd_soc_update_bits(codec, AIC32X4_PLLPR,
530 AIC32X4_MADCEN, 0); 559 AIC32X4_PLLEN, 0);
531 560
532 /* Switch off BCLK_N Divider */ 561 /* Switch off master clock */
533 snd_soc_update_bits(codec, AIC32X4_BCLKN, 562 clk_disable_unprepare(aic32x4->mclk);
534 AIC32X4_BCLKEN, 0);
535 break; 563 break;
536 case SND_SOC_BIAS_OFF: 564 case SND_SOC_BIAS_OFF:
537 break; 565 break;
@@ -588,7 +616,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
588 616
589 snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); 617 snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
590 618
591 if (aic32x4->rstn_gpio >= 0) { 619 if (gpio_is_valid(aic32x4->rstn_gpio)) {
592 ndelay(10); 620 ndelay(10);
593 gpio_set_value(aic32x4->rstn_gpio, 1); 621 gpio_set_value(aic32x4->rstn_gpio, 1);
594 } 622 }
@@ -663,11 +691,122 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
663 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), 691 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
664}; 692};
665 693
694static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
695 struct device_node *np)
696{
697 aic32x4->swapdacs = false;
698 aic32x4->micpga_routing = 0;
699 aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0);
700
701 return 0;
702}
703
704static void aic32x4_disable_regulators(struct aic32x4_priv *aic32x4)
705{
706 regulator_disable(aic32x4->supply_iov);
707
708 if (!IS_ERR(aic32x4->supply_ldo))
709 regulator_disable(aic32x4->supply_ldo);
710
711 if (!IS_ERR(aic32x4->supply_dv))
712 regulator_disable(aic32x4->supply_dv);
713
714 if (!IS_ERR(aic32x4->supply_av))
715 regulator_disable(aic32x4->supply_av);
716}
717
718static int aic32x4_setup_regulators(struct device *dev,
719 struct aic32x4_priv *aic32x4)
720{
721 int ret = 0;
722
723 aic32x4->supply_ldo = devm_regulator_get_optional(dev, "ldoin");
724 aic32x4->supply_iov = devm_regulator_get(dev, "iov");
725 aic32x4->supply_dv = devm_regulator_get_optional(dev, "dv");
726 aic32x4->supply_av = devm_regulator_get_optional(dev, "av");
727
728 /* Check if the regulator requirements are fulfilled */
729
730 if (IS_ERR(aic32x4->supply_iov)) {
731 dev_err(dev, "Missing supply 'iov'\n");
732 return PTR_ERR(aic32x4->supply_iov);
733 }
734
735 if (IS_ERR(aic32x4->supply_ldo)) {
736 if (PTR_ERR(aic32x4->supply_ldo) == -EPROBE_DEFER)
737 return -EPROBE_DEFER;
738
739 if (IS_ERR(aic32x4->supply_dv)) {
740 dev_err(dev, "Missing supply 'dv' or 'ldoin'\n");
741 return PTR_ERR(aic32x4->supply_dv);
742 }
743 if (IS_ERR(aic32x4->supply_av)) {
744 dev_err(dev, "Missing supply 'av' or 'ldoin'\n");
745 return PTR_ERR(aic32x4->supply_av);
746 }
747 } else {
748 if (IS_ERR(aic32x4->supply_dv) &&
749 PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER)
750 return -EPROBE_DEFER;
751 if (IS_ERR(aic32x4->supply_av) &&
752 PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER)
753 return -EPROBE_DEFER;
754 }
755
756 ret = regulator_enable(aic32x4->supply_iov);
757 if (ret) {
758 dev_err(dev, "Failed to enable regulator iov\n");
759 return ret;
760 }
761
762 if (!IS_ERR(aic32x4->supply_ldo)) {
763 ret = regulator_enable(aic32x4->supply_ldo);
764 if (ret) {
765 dev_err(dev, "Failed to enable regulator ldo\n");
766 goto error_ldo;
767 }
768 }
769
770 if (!IS_ERR(aic32x4->supply_dv)) {
771 ret = regulator_enable(aic32x4->supply_dv);
772 if (ret) {
773 dev_err(dev, "Failed to enable regulator dv\n");
774 goto error_dv;
775 }
776 }
777
778 if (!IS_ERR(aic32x4->supply_av)) {
779 ret = regulator_enable(aic32x4->supply_av);
780 if (ret) {
781 dev_err(dev, "Failed to enable regulator av\n");
782 goto error_av;
783 }
784 }
785
786 if (!IS_ERR(aic32x4->supply_ldo) && IS_ERR(aic32x4->supply_av))
787 aic32x4->power_cfg |= AIC32X4_PWR_AIC32X4_LDO_ENABLE;
788
789 return 0;
790
791error_av:
792 if (!IS_ERR(aic32x4->supply_dv))
793 regulator_disable(aic32x4->supply_dv);
794
795error_dv:
796 if (!IS_ERR(aic32x4->supply_ldo))
797 regulator_disable(aic32x4->supply_ldo);
798
799error_ldo:
800 regulator_disable(aic32x4->supply_iov);
801 return ret;
802}
803
666static int aic32x4_i2c_probe(struct i2c_client *i2c, 804static int aic32x4_i2c_probe(struct i2c_client *i2c,
667 const struct i2c_device_id *id) 805 const struct i2c_device_id *id)
668{ 806{
669 struct aic32x4_pdata *pdata = i2c->dev.platform_data; 807 struct aic32x4_pdata *pdata = i2c->dev.platform_data;
670 struct aic32x4_priv *aic32x4; 808 struct aic32x4_priv *aic32x4;
809 struct device_node *np = i2c->dev.of_node;
671 int ret; 810 int ret;
672 811
673 aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv), 812 aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv),
@@ -686,6 +825,12 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c,
686 aic32x4->swapdacs = pdata->swapdacs; 825 aic32x4->swapdacs = pdata->swapdacs;
687 aic32x4->micpga_routing = pdata->micpga_routing; 826 aic32x4->micpga_routing = pdata->micpga_routing;
688 aic32x4->rstn_gpio = pdata->rstn_gpio; 827 aic32x4->rstn_gpio = pdata->rstn_gpio;
828 } else if (np) {
829 ret = aic32x4_parse_dt(aic32x4, np);
830 if (ret) {
831 dev_err(&i2c->dev, "Failed to parse DT node\n");
832 return ret;
833 }
689 } else { 834 } else {
690 aic32x4->power_cfg = 0; 835 aic32x4->power_cfg = 0;
691 aic32x4->swapdacs = false; 836 aic32x4->swapdacs = false;
@@ -693,20 +838,44 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c,
693 aic32x4->rstn_gpio = -1; 838 aic32x4->rstn_gpio = -1;
694 } 839 }
695 840
696 if (aic32x4->rstn_gpio >= 0) { 841 aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk");
842 if (IS_ERR(aic32x4->mclk)) {
843 dev_err(&i2c->dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n");
844 return PTR_ERR(aic32x4->mclk);
845 }
846
847 if (gpio_is_valid(aic32x4->rstn_gpio)) {
697 ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, 848 ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio,
698 GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); 849 GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn");
699 if (ret != 0) 850 if (ret != 0)
700 return ret; 851 return ret;
701 } 852 }
702 853
854 ret = aic32x4_setup_regulators(&i2c->dev, aic32x4);
855 if (ret) {
856 dev_err(&i2c->dev, "Failed to setup regulators\n");
857 return ret;
858 }
859
703 ret = snd_soc_register_codec(&i2c->dev, 860 ret = snd_soc_register_codec(&i2c->dev,
704 &soc_codec_dev_aic32x4, &aic32x4_dai, 1); 861 &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
705 return ret; 862 if (ret) {
863 dev_err(&i2c->dev, "Failed to register codec\n");
864 aic32x4_disable_regulators(aic32x4);
865 return ret;
866 }
867
868 i2c_set_clientdata(i2c, aic32x4);
869
870 return 0;
706} 871}
707 872
708static int aic32x4_i2c_remove(struct i2c_client *client) 873static int aic32x4_i2c_remove(struct i2c_client *client)
709{ 874{
875 struct aic32x4_priv *aic32x4 = i2c_get_clientdata(client);
876
877 aic32x4_disable_regulators(aic32x4);
878
710 snd_soc_unregister_codec(&client->dev); 879 snd_soc_unregister_codec(&client->dev);
711 return 0; 880 return 0;
712} 881}
@@ -717,10 +886,17 @@ static const struct i2c_device_id aic32x4_i2c_id[] = {
717}; 886};
718MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); 887MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
719 888
889static const struct of_device_id aic32x4_of_id[] = {
890 { .compatible = "ti,tlv320aic32x4", },
891 { /* senitel */ }
892};
893MODULE_DEVICE_TABLE(of, aic32x4_of_id);
894
720static struct i2c_driver aic32x4_i2c_driver = { 895static struct i2c_driver aic32x4_i2c_driver = {
721 .driver = { 896 .driver = {
722 .name = "tlv320aic32x4", 897 .name = "tlv320aic32x4",
723 .owner = THIS_MODULE, 898 .owner = THIS_MODULE,
899 .of_match_table = aic32x4_of_id,
724 }, 900 },
725 .probe = aic32x4_i2c_probe, 901 .probe = aic32x4_i2c_probe,
726 .remove = aic32x4_i2c_remove, 902 .remove = aic32x4_i2c_remove,
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index dba0306c42a5..32d219570cca 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -171,26 +171,23 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
171static const char *wm8991_digital_sidetone[] = 171static const char *wm8991_digital_sidetone[] =
172{"None", "Left ADC", "Right ADC", "Reserved"}; 172{"None", "Left ADC", "Right ADC", "Reserved"};
173 173
174static const struct soc_enum wm8991_left_digital_sidetone_enum = 174static SOC_ENUM_SINGLE_DECL(wm8991_left_digital_sidetone_enum,
175 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE, 175 WM8991_DIGITAL_SIDE_TONE,
176 WM8991_ADC_TO_DACL_SHIFT, 176 WM8991_ADC_TO_DACL_SHIFT,
177 WM8991_ADC_TO_DACL_MASK, 177 wm8991_digital_sidetone);
178 wm8991_digital_sidetone); 178
179 179static SOC_ENUM_SINGLE_DECL(wm8991_right_digital_sidetone_enum,
180static const struct soc_enum wm8991_right_digital_sidetone_enum = 180 WM8991_DIGITAL_SIDE_TONE,
181 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE, 181 WM8991_ADC_TO_DACR_SHIFT,
182 WM8991_ADC_TO_DACR_SHIFT, 182 wm8991_digital_sidetone);
183 WM8991_ADC_TO_DACR_MASK,
184 wm8991_digital_sidetone);
185 183
186static const char *wm8991_adcmode[] = 184static const char *wm8991_adcmode[] =
187{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; 185{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
188 186
189static const struct soc_enum wm8991_right_adcmode_enum = 187static SOC_ENUM_SINGLE_DECL(wm8991_right_adcmode_enum,
190 SOC_ENUM_SINGLE(WM8991_ADC_CTRL, 188 WM8991_ADC_CTRL,
191 WM8991_ADC_HPF_CUT_SHIFT, 189 WM8991_ADC_HPF_CUT_SHIFT,
192 WM8991_ADC_HPF_CUT_MASK, 190 wm8991_adcmode);
193 wm8991_adcmode);
194 191
195static const struct snd_kcontrol_new wm8991_snd_controls[] = { 192static const struct snd_kcontrol_new wm8991_snd_controls[] = {
196 /* INMIXL */ 193 /* INMIXL */
@@ -486,9 +483,9 @@ static const struct snd_kcontrol_new wm8991_dapm_inmixr_controls[] = {
486static const char *wm8991_ainlmux[] = 483static const char *wm8991_ainlmux[] =
487{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; 484{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
488 485
489static const struct soc_enum wm8991_ainlmux_enum = 486static SOC_ENUM_SINGLE_DECL(wm8991_ainlmux_enum,
490 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT, 487 WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT,
491 ARRAY_SIZE(wm8991_ainlmux), wm8991_ainlmux); 488 wm8991_ainlmux);
492 489
493static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls = 490static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls =
494 SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum); 491 SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum);
@@ -499,9 +496,9 @@ static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls =
499static const char *wm8991_ainrmux[] = 496static const char *wm8991_ainrmux[] =
500{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; 497{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
501 498
502static const struct soc_enum wm8991_ainrmux_enum = 499static SOC_ENUM_SINGLE_DECL(wm8991_ainrmux_enum,
503 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT, 500 WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT,
504 ARRAY_SIZE(wm8991_ainrmux), wm8991_ainrmux); 501 wm8991_ainrmux);
505 502
506static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls = 503static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls =
507 SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum); 504 SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum);
@@ -1251,11 +1248,8 @@ static int wm8991_remove(struct snd_soc_codec *codec)
1251 1248
1252static int wm8991_probe(struct snd_soc_codec *codec) 1249static int wm8991_probe(struct snd_soc_codec *codec)
1253{ 1250{
1254 struct wm8991_priv *wm8991;
1255 int ret; 1251 int ret;
1256 1252
1257 wm8991 = snd_soc_codec_get_drvdata(codec);
1258
1259 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); 1253 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1260 if (ret < 0) { 1254 if (ret < 0) {
1261 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); 1255 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 07f8f141727d..19a18a4f133a 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -170,7 +170,7 @@ config SND_SOC_EUKREA_TLV320
170 || MACH_EUKREA_MBIMXSD35_BASEBOARD \ 170 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
171 || MACH_EUKREA_MBIMXSD51_BASEBOARD 171 || MACH_EUKREA_MBIMXSD51_BASEBOARD
172 depends on I2C 172 depends on I2C
173 select SND_SOC_TLV320AIC23 173 select SND_SOC_TLV320AIC23_I2C
174 select SND_SOC_IMX_PCM_FIQ 174 select SND_SOC_IMX_PCM_FIQ
175 select SND_SOC_IMX_AUDMUX 175 select SND_SOC_IMX_AUDMUX
176 select SND_SOC_IMX_SSI 176 select SND_SOC_IMX_SSI
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 22ad9c5654b5..e00659351a4e 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -58,7 +58,7 @@ config SND_OMAP_SOC_OSK5912
58 tristate "SoC Audio support for omap osk5912" 58 tristate "SoC Audio support for omap osk5912"
59 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C 59 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
60 select SND_OMAP_SOC_MCBSP 60 select SND_OMAP_SOC_MCBSP
61 select SND_SOC_TLV320AIC23 61 select SND_SOC_TLV320AIC23_I2C
62 help 62 help
63 Say Y if you want to add support for SoC audio on osk5912. 63 Say Y if you want to add support for SoC audio on osk5912.
64 64
@@ -66,7 +66,7 @@ config SND_OMAP_SOC_AM3517EVM
66 tristate "SoC Audio support for OMAP3517 / AM3517 EVM" 66 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
67 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C 67 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
68 select SND_OMAP_SOC_MCBSP 68 select SND_OMAP_SOC_MCBSP
69 select SND_SOC_TLV320AIC23 69 select SND_SOC_TLV320AIC23_I2C
70 help 70 help
71 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517 71 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
72 EVM. 72 EVM.
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 454f41cfc828..47a7a1b633ae 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -117,7 +117,7 @@ config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
117 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" 117 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
118 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX 118 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
119 select SND_S3C24XX_I2S 119 select SND_S3C24XX_I2S
120 select SND_SOC_TLV320AIC23 120 select SND_SOC_TLV320AIC23_I2C
121 select SND_SOC_SAMSUNG_SIMTEC 121 select SND_SOC_SAMSUNG_SIMTEC
122 122
123config SND_SOC_SAMSUNG_SIMTEC_HERMES 123config SND_SOC_SAMSUNG_SIMTEC_HERMES
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index fe1df50805a3..ad2dd14f0e3e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1137,6 +1137,10 @@ static int soc_probe_codec(struct snd_soc_card *card,
1137 1137
1138 codec->dapm.idle_bias_off = driver->idle_bias_off; 1138 codec->dapm.idle_bias_off = driver->idle_bias_off;
1139 1139
1140 /* Set the default I/O up try regmap */
1141 if (dev_get_regmap(codec->dev, NULL))
1142 snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1143
1140 if (driver->probe) { 1144 if (driver->probe) {
1141 ret = driver->probe(codec); 1145 ret = driver->probe(codec);
1142 if (ret < 0) { 1146 if (ret < 0) {
@@ -1150,10 +1154,6 @@ static int soc_probe_codec(struct snd_soc_card *card,
1150 codec->name); 1154 codec->name);
1151 } 1155 }
1152 1156
1153 /* If the driver didn't set I/O up try regmap */
1154 if (!codec->write && dev_get_regmap(codec->dev, NULL))
1155 snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1156
1157 if (driver->controls) 1157 if (driver->controls)
1158 snd_soc_add_codec_controls(codec, driver->controls, 1158 snd_soc_add_codec_controls(codec, driver->controls,
1159 driver->num_controls); 1159 driver->num_controls);
@@ -2716,6 +2716,48 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
2716EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); 2716EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
2717 2717
2718/** 2718/**
2719 * snd_soc_read_signed - Read a codec register and interprete as signed value
2720 * @codec: codec
2721 * @reg: Register to read
2722 * @mask: Mask to use after shifting the register value
2723 * @shift: Right shift of register value
2724 * @sign_bit: Bit that describes if a number is negative or not.
2725 *
2726 * This functions reads a codec register. The register value is shifted right
2727 * by 'shift' bits and masked with the given 'mask'. Afterwards it translates
2728 * the given registervalue into a signed integer if sign_bit is non-zero.
2729 *
2730 * Returns the register value as signed int.
2731 */
2732static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg,
2733 unsigned int mask, unsigned int shift, unsigned int sign_bit)
2734{
2735 int ret;
2736 unsigned int val;
2737
2738 val = (snd_soc_read(codec, reg) >> shift) & mask;
2739
2740 if (!sign_bit)
2741 return val;
2742
2743 /* non-negative number */
2744 if (!(val & BIT(sign_bit)))
2745 return val;
2746
2747 ret = val;
2748
2749 /*
2750 * The register most probably does not contain a full-sized int.
2751 * Instead we have an arbitrary number of bits in a signed
2752 * representation which has to be translated into a full-sized int.
2753 * This is done by filling up all bits above the sign-bit.
2754 */
2755 ret |= ~((int)(BIT(sign_bit) - 1));
2756
2757 return ret;
2758}
2759
2760/**
2719 * snd_soc_info_volsw - single mixer info callback 2761 * snd_soc_info_volsw - single mixer info callback
2720 * @kcontrol: mixer control 2762 * @kcontrol: mixer control
2721 * @uinfo: control element information 2763 * @uinfo: control element information
@@ -2743,7 +2785,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2743 2785
2744 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; 2786 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
2745 uinfo->value.integer.min = 0; 2787 uinfo->value.integer.min = 0;
2746 uinfo->value.integer.max = platform_max; 2788 uinfo->value.integer.max = platform_max - mc->min;
2747 return 0; 2789 return 0;
2748} 2790}
2749EXPORT_SYMBOL_GPL(snd_soc_info_volsw); 2791EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
@@ -2769,11 +2811,16 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2769 unsigned int shift = mc->shift; 2811 unsigned int shift = mc->shift;
2770 unsigned int rshift = mc->rshift; 2812 unsigned int rshift = mc->rshift;
2771 int max = mc->max; 2813 int max = mc->max;
2814 int min = mc->min;
2815 int sign_bit = mc->sign_bit;
2772 unsigned int mask = (1 << fls(max)) - 1; 2816 unsigned int mask = (1 << fls(max)) - 1;
2773 unsigned int invert = mc->invert; 2817 unsigned int invert = mc->invert;
2774 2818
2775 ucontrol->value.integer.value[0] = 2819 if (sign_bit)
2776 (snd_soc_read(codec, reg) >> shift) & mask; 2820 mask = BIT(sign_bit + 1) - 1;
2821
2822 ucontrol->value.integer.value[0] = snd_soc_read_signed(codec, reg, mask,
2823 shift, sign_bit) - min;
2777 if (invert) 2824 if (invert)
2778 ucontrol->value.integer.value[0] = 2825 ucontrol->value.integer.value[0] =
2779 max - ucontrol->value.integer.value[0]; 2826 max - ucontrol->value.integer.value[0];
@@ -2781,10 +2828,12 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2781 if (snd_soc_volsw_is_stereo(mc)) { 2828 if (snd_soc_volsw_is_stereo(mc)) {
2782 if (reg == reg2) 2829 if (reg == reg2)
2783 ucontrol->value.integer.value[1] = 2830 ucontrol->value.integer.value[1] =
2784 (snd_soc_read(codec, reg) >> rshift) & mask; 2831 snd_soc_read_signed(codec, reg, mask, rshift,
2832 sign_bit) - min;
2785 else 2833 else
2786 ucontrol->value.integer.value[1] = 2834 ucontrol->value.integer.value[1] =
2787 (snd_soc_read(codec, reg2) >> shift) & mask; 2835 snd_soc_read_signed(codec, reg2, mask, shift,
2836 sign_bit) - min;
2788 if (invert) 2837 if (invert)
2789 ucontrol->value.integer.value[1] = 2838 ucontrol->value.integer.value[1] =
2790 max - ucontrol->value.integer.value[1]; 2839 max - ucontrol->value.integer.value[1];
@@ -2815,6 +2864,8 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2815 unsigned int shift = mc->shift; 2864 unsigned int shift = mc->shift;
2816 unsigned int rshift = mc->rshift; 2865 unsigned int rshift = mc->rshift;
2817 int max = mc->max; 2866 int max = mc->max;
2867 int min = mc->min;
2868 unsigned int sign_bit = mc->sign_bit;
2818 unsigned int mask = (1 << fls(max)) - 1; 2869 unsigned int mask = (1 << fls(max)) - 1;
2819 unsigned int invert = mc->invert; 2870 unsigned int invert = mc->invert;
2820 int err; 2871 int err;
@@ -2822,13 +2873,16 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2822 unsigned int val2 = 0; 2873 unsigned int val2 = 0;
2823 unsigned int val, val_mask; 2874 unsigned int val, val_mask;
2824 2875
2825 val = (ucontrol->value.integer.value[0] & mask); 2876 if (sign_bit)
2877 mask = BIT(sign_bit + 1) - 1;
2878
2879 val = ((ucontrol->value.integer.value[0] + min) & mask);
2826 if (invert) 2880 if (invert)
2827 val = max - val; 2881 val = max - val;
2828 val_mask = mask << shift; 2882 val_mask = mask << shift;
2829 val = val << shift; 2883 val = val << shift;
2830 if (snd_soc_volsw_is_stereo(mc)) { 2884 if (snd_soc_volsw_is_stereo(mc)) {
2831 val2 = (ucontrol->value.integer.value[1] & mask); 2885 val2 = ((ucontrol->value.integer.value[1] + min) & mask);
2832 if (invert) 2886 if (invert)
2833 val2 = max - val2; 2887 val2 = max - val2;
2834 if (reg == reg2) { 2888 if (reg == reg2) {
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index aa886cca3ecf..18353f111b6a 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -88,31 +88,12 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
88 int addr_bits, int data_bits, 88 int addr_bits, int data_bits,
89 enum snd_soc_control_type control) 89 enum snd_soc_control_type control)
90{ 90{
91 struct regmap_config config;
92 int ret; 91 int ret;
93 92
94 memset(&config, 0, sizeof(config));
95 codec->write = hw_write; 93 codec->write = hw_write;
96 codec->read = hw_read; 94 codec->read = hw_read;
97 95
98 config.reg_bits = addr_bits;
99 config.val_bits = data_bits;
100
101 switch (control) { 96 switch (control) {
102#if IS_ENABLED(CONFIG_REGMAP_I2C)
103 case SND_SOC_I2C:
104 codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
105 &config);
106 break;
107#endif
108
109#if IS_ENABLED(CONFIG_REGMAP_SPI)
110 case SND_SOC_SPI:
111 codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
112 &config);
113 break;
114#endif
115
116 case SND_SOC_REGMAP: 97 case SND_SOC_REGMAP:
117 /* Device has made its own regmap arrangements */ 98 /* Device has made its own regmap arrangements */
118 codec->using_regmap = true; 99 codec->using_regmap = true;
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 9f9c1856f822..31198cf7f88d 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -105,7 +105,7 @@ config SND_SOC_TEGRA_TRIMSLICE
105 tristate "SoC Audio support for TrimSlice board" 105 tristate "SoC Audio support for TrimSlice board"
106 depends on SND_SOC_TEGRA && I2C 106 depends on SND_SOC_TEGRA && I2C
107 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 107 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
108 select SND_SOC_TLV320AIC23 108 select SND_SOC_TLV320AIC23_I2C
109 help 109 help
110 Say Y or M here if you want to add support for SoC audio on the 110 Say Y or M here if you want to add support for SoC audio on the
111 TrimSlice platform. 111 TrimSlice platform.