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/88pm860x-codec.c3
-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/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.c68
-rw-r--r--sound/soc/tegra/Kconfig2
22 files changed, 594 insertions, 250 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/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 75d0ad5d2dcb..647a72cda005 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1328,6 +1328,9 @@ static int pm860x_probe(struct snd_soc_codec *codec)
1328 pm860x->codec = codec; 1328 pm860x->codec = codec;
1329 1329
1330 codec->control_data = pm860x->regmap; 1330 codec->control_data = pm860x->regmap;
1331 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1332 if (ret)
1333 return ret;
1331 1334
1332 for (i = 0; i < 4; i++) { 1335 for (i = 0; i < 4; i++) {
1333 ret = request_threaded_irq(pm860x->irq[i], NULL, 1336 ret = request_threaded_irq(pm860x->irq[i], NULL,
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/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 93854f031523..ad2dd14f0e3e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -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/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.