diff options
Diffstat (limited to 'sound/soc')
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 | |||
182 | config SND_SOC_AD193X | 184 | config SND_SOC_AD193X |
183 | tristate | 185 | tristate |
184 | 186 | ||
187 | config SND_SOC_AD193X_SPI | ||
188 | tristate | ||
189 | select SND_SOC_AD193X | ||
190 | |||
191 | config SND_SOC_AD193X_I2C | ||
192 | tristate | ||
193 | select SND_SOC_AD193X | ||
194 | |||
185 | config SND_SOC_AD1980 | 195 | config SND_SOC_AD1980 |
186 | tristate | 196 | tristate |
187 | 197 | ||
@@ -357,6 +367,14 @@ config SND_SOC_TAS5086 | |||
357 | config SND_SOC_TLV320AIC23 | 367 | config SND_SOC_TLV320AIC23 |
358 | tristate | 368 | tristate |
359 | 369 | ||
370 | config SND_SOC_TLV320AIC23_I2C | ||
371 | tristate | ||
372 | select SND_SOC_TLV320AIC23 | ||
373 | |||
374 | config SND_SOC_TLV320AIC23_SPI | ||
375 | tristate | ||
376 | select SND_SOC_TLV320AIC23 | ||
377 | |||
360 | config SND_SOC_TLV320AIC26 | 378 | config 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 | |||
3 | snd-soc-ac97-objs := ac97.o | 3 | snd-soc-ac97-objs := ac97.o |
4 | snd-soc-ad1836-objs := ad1836.o | 4 | snd-soc-ad1836-objs := ad1836.o |
5 | snd-soc-ad193x-objs := ad193x.o | 5 | snd-soc-ad193x-objs := ad193x.o |
6 | snd-soc-ad193x-spi-objs := ad193x-spi.o | ||
7 | snd-soc-ad193x-i2c-objs := ad193x-i2c.o | ||
6 | snd-soc-ad1980-objs := ad1980.o | 8 | snd-soc-ad1980-objs := ad1980.o |
7 | snd-soc-ad73311-objs := ad73311.o | 9 | snd-soc-ad73311-objs := ad73311.o |
8 | snd-soc-adau1701-objs := adau1701.o | 10 | snd-soc-adau1701-objs := adau1701.o |
@@ -63,9 +65,11 @@ snd-soc-sta529-objs := sta529.o | |||
63 | snd-soc-stac9766-objs := stac9766.o | 65 | snd-soc-stac9766-objs := stac9766.o |
64 | snd-soc-tas5086-objs := tas5086.o | 66 | snd-soc-tas5086-objs := tas5086.o |
65 | snd-soc-tlv320aic23-objs := tlv320aic23.o | 67 | snd-soc-tlv320aic23-objs := tlv320aic23.o |
68 | snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o | ||
69 | snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o | ||
66 | snd-soc-tlv320aic26-objs := tlv320aic26.o | 70 | snd-soc-tlv320aic26-objs := tlv320aic26.o |
67 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o | ||
68 | snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o | 71 | snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o |
72 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o | ||
69 | snd-soc-tlv320dac33-objs := tlv320dac33.o | 73 | snd-soc-tlv320dac33-objs := tlv320dac33.o |
70 | snd-soc-twl4030-objs := twl4030.o | 74 | snd-soc-twl4030-objs := twl4030.o |
71 | snd-soc-twl6040-objs := twl6040.o | 75 | snd-soc-twl6040-objs := twl6040.o |
@@ -134,6 +138,8 @@ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o | |||
134 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o | 138 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o |
135 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o | 139 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o |
136 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o | 140 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o |
141 | obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o | ||
142 | obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o | ||
137 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o | 143 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o |
138 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o | 144 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o |
139 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o | 145 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o |
@@ -193,9 +199,11 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o | |||
193 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o | 199 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o |
194 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o | 200 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o |
195 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o | 201 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o |
202 | obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o | ||
203 | obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o | ||
196 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o | 204 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o |
197 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | ||
198 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o | 205 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o |
206 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | ||
199 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o | 207 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o |
200 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o | 208 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o |
201 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o | 209 | obj-$(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 | |||
17 | static const struct i2c_device_id ad193x_id[] = { | ||
18 | { "ad1936", 0 }, | ||
19 | { "ad1937", 0 }, | ||
20 | { } | ||
21 | }; | ||
22 | MODULE_DEVICE_TABLE(i2c, ad193x_id); | ||
23 | |||
24 | static 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 | |||
36 | static int ad193x_i2c_remove(struct i2c_client *client) | ||
37 | { | ||
38 | snd_soc_unregister_codec(&client->dev); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static 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 | }; | ||
50 | module_i2c_driver(ad193x_i2c_driver); | ||
51 | |||
52 | MODULE_DESCRIPTION("ASoC AD1936/AD1937 audio CODEC driver"); | ||
53 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
54 | MODULE_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 | |||
17 | static 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 | |||
30 | static int ad193x_spi_remove(struct spi_device *spi) | ||
31 | { | ||
32 | snd_soc_unregister_codec(&spi->dev); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static 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 | }; | ||
44 | module_spi_driver(ad193x_spi_driver); | ||
45 | |||
46 | MODULE_DESCRIPTION("ASoC AD1938/AD1939 audio CODEC driver"); | ||
47 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
48 | MODULE_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 | */ |
33 | static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; | 32 | static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; |
34 | 33 | ||
35 | static const struct soc_enum ad193x_deemp_enum = | 34 | static 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 | ||
38 | static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); | 37 | static 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 | ||
323 | static int ad193x_probe(struct snd_soc_codec *codec) | 322 | static 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 | ||
354 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { | 353 | static 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) | 368 | const struct regmap_config ad193x_regmap_config = { |
370 | |||
371 | static 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 | }; |
372 | EXPORT_SYMBOL_GPL(ad193x_regmap_config); | ||
380 | 373 | ||
381 | static int ad193x_spi_probe(struct spi_device *spi) | 374 | int 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 | |||
400 | static int ad193x_spi_remove(struct spi_device *spi) | ||
401 | { | ||
402 | snd_soc_unregister_codec(&spi->dev); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static 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 | |||
418 | static 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 | |||
426 | static const struct i2c_device_id ad193x_id[] = { | ||
427 | { "ad1936", 0 }, | ||
428 | { "ad1937", 0 }, | ||
429 | { } | ||
430 | }; | ||
431 | MODULE_DEVICE_TABLE(i2c, ad193x_id); | ||
432 | 380 | ||
433 | static 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 | |||
453 | static int ad193x_i2c_remove(struct i2c_client *client) | ||
454 | { | ||
455 | snd_soc_unregister_codec(&client->dev); | ||
456 | return 0; | ||
457 | } | ||
458 | 386 | ||
459 | static 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 | |||
469 | static 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 | } | ||
490 | module_init(ad193x_modinit); | ||
491 | |||
492 | static 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 | } |
502 | module_exit(ad193x_modexit); | 392 | EXPORT_SYMBOL_GPL(ad193x_probe); |
503 | 393 | ||
504 | MODULE_DESCRIPTION("ASoC ad193x driver"); | 394 | MODULE_DESCRIPTION("ASoC ad193x driver"); |
505 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | 395 | MODULE_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 | |||
14 | struct device; | ||
15 | |||
16 | extern const struct regmap_config ad193x_regmap_config; | ||
17 | int 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 */ | ||
27 | struct 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 */ |
32 | static const u8 ak4671_reg[AK4671_CACHEREGNUM] = { | 28 | static 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 */ |
242 | static const char *ak4671_lin_mux_texts[] = | 238 | static const char *ak4671_lin_mux_texts[] = |
243 | {"LIN1", "LIN2", "LIN3", "LIN4"}; | 239 | {"LIN1", "LIN2", "LIN3", "LIN4"}; |
244 | static const struct soc_enum ak4671_lin_mux_enum = | 240 | static 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); | ||
248 | static const struct snd_kcontrol_new ak4671_lin_mux_control = | 243 | static 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 | ||
251 | static const char *ak4671_rin_mux_texts[] = | 246 | static const char *ak4671_rin_mux_texts[] = |
252 | {"RIN1", "RIN2", "RIN3", "RIN4"}; | 247 | {"RIN1", "RIN2", "RIN3", "RIN4"}; |
253 | static const struct soc_enum ak4671_rin_mux_enum = | 248 | static 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); | ||
257 | static const struct snd_kcontrol_new ak4671_rin_mux_control = | 251 | static 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 | ||
620 | static int ak4671_probe(struct snd_soc_codec *codec) | 614 | static 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 | ||
647 | static 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 | |||
658 | static int ak4671_i2c_probe(struct i2c_client *client, | 657 | static 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 */ |
40 | struct alc5623_priv { | 41 | struct 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 | ||
49 | static 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 | |||
61 | static inline int alc5623_reset(struct snd_soc_codec *codec) | 49 | static 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 */ |
231 | static const struct soc_enum alc5623_aux_out_input_enum = | 219 | static SOC_ENUM_SINGLE_DECL(alc5623_aux_out_input_enum, |
232 | SOC_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); | ||
233 | static const struct snd_kcontrol_new alc5623_auxout_mux_controls = | 222 | static const struct snd_kcontrol_new alc5623_auxout_mux_controls = |
234 | SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); | 223 | SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); |
235 | 224 | ||
236 | /* speaker output mux */ | 225 | /* speaker output mux */ |
237 | static const struct soc_enum alc5623_spkout_input_enum = | 226 | static SOC_ENUM_SINGLE_DECL(alc5623_spkout_input_enum, |
238 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); | 227 | ALC5623_OUTPUT_MIXER_CTRL, 10, |
228 | alc5623_spkout_input_sel); | ||
239 | static const struct snd_kcontrol_new alc5623_spkout_mux_controls = | 229 | static const struct snd_kcontrol_new alc5623_spkout_mux_controls = |
240 | SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); | 230 | SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); |
241 | 231 | ||
242 | /* headphone left output mux */ | 232 | /* headphone left output mux */ |
243 | static const struct soc_enum alc5623_hpl_out_input_enum = | 233 | static SOC_ENUM_SINGLE_DECL(alc5623_hpl_out_input_enum, |
244 | SOC_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); | ||
245 | static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = | 236 | static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = |
246 | SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); | 237 | SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); |
247 | 238 | ||
248 | /* headphone right output mux */ | 239 | /* headphone right output mux */ |
249 | static const struct soc_enum alc5623_hpr_out_input_enum = | 240 | static SOC_ENUM_SINGLE_DECL(alc5623_hpr_out_input_enum, |
250 | SOC_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); | ||
251 | static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = | 243 | static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = |
252 | SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); | 244 | SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); |
253 | 245 | ||
254 | /* speaker output N select */ | 246 | /* speaker output N select */ |
255 | static const struct soc_enum alc5623_spk_n_sour_enum = | 247 | static SOC_ENUM_SINGLE_DECL(alc5623_spk_n_sour_enum, |
256 | SOC_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); | ||
257 | static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = | 250 | static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = |
258 | SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); | 251 | SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); |
259 | 252 | ||
@@ -338,8 +331,9 @@ SND_SOC_DAPM_VMID("Vmid"), | |||
338 | }; | 331 | }; |
339 | 332 | ||
340 | static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; | 333 | static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; |
341 | static const struct soc_enum alc5623_amp_enum = | 334 | static 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); | ||
343 | static const struct snd_kcontrol_new alc5623_amp_mux_controls = | 337 | static 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 | ||
870 | static int alc5623_suspend(struct snd_soc_codec *codec) | 864 | static 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 | ||
876 | static int alc5623_resume(struct snd_soc_codec *codec) | 874 | static 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, | 989 | static 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 */ |
296 | static const struct soc_enum alc5632_aux_out_input_enum = | 296 | static SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum, |
297 | SOC_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); | ||
298 | static const struct snd_kcontrol_new alc5632_auxout_mux_controls = | 299 | static const struct snd_kcontrol_new alc5632_auxout_mux_controls = |
299 | SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); | 300 | SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); |
300 | 301 | ||
301 | /* speaker output mux */ | 302 | /* speaker output mux */ |
302 | static const struct soc_enum alc5632_spkout_input_enum = | 303 | static SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum, |
303 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel); | 304 | ALC5632_OUTPUT_MIXER_CTRL, 10, |
305 | alc5632_spkout_input_sel); | ||
304 | static const struct snd_kcontrol_new alc5632_spkout_mux_controls = | 306 | static const struct snd_kcontrol_new alc5632_spkout_mux_controls = |
305 | SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); | 307 | SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); |
306 | 308 | ||
307 | /* headphone left output mux */ | 309 | /* headphone left output mux */ |
308 | static const struct soc_enum alc5632_hpl_out_input_enum = | 310 | static SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum, |
309 | SOC_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); | ||
310 | static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = | 313 | static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = |
311 | SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); | 314 | SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); |
312 | 315 | ||
313 | /* headphone right output mux */ | 316 | /* headphone right output mux */ |
314 | static const struct soc_enum alc5632_hpr_out_input_enum = | 317 | static SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum, |
315 | SOC_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); | ||
316 | static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = | 320 | static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = |
317 | SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); | 321 | SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); |
318 | 322 | ||
319 | /* speaker output N select */ | 323 | /* speaker output N select */ |
320 | static const struct soc_enum alc5632_spk_n_sour_enum = | 324 | static SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum, |
321 | SOC_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); | ||
322 | static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = | 327 | static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = |
323 | SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); | 328 | SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); |
324 | 329 | ||
325 | /* speaker amplifier */ | 330 | /* speaker amplifier */ |
326 | static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; | 331 | static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; |
327 | static const struct soc_enum alc5632_amp_enum = | 332 | static 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); | ||
329 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = | 335 | static 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 */ |
333 | static const struct soc_enum alc5632_adcr_func_enum = | 339 | static 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); | ||
335 | static const struct snd_kcontrol_new alc5632_adcr_func_controls = | 342 | static 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 */ |
339 | static const struct soc_enum alc5632_i2s_out_enum = | 346 | static 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); | ||
341 | static const struct snd_kcontrol_new alc5632_i2s_out_controls = | 349 | static 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 | ||
42 | struct cs42l51_private { | 43 | struct 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 | ||
55 | static 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 | |||
73 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, | 55 | static 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 | ||
506 | static int cs42l51_probe(struct snd_soc_codec *codec) | 488 | static 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 | ||
539 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 514 | static 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 | ||
525 | static 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 | |||
552 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, | 533 | static 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 | }; |
601 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); | 589 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); |
602 | 590 | ||
591 | static const struct of_device_id cs42l51_of_match[] = { | ||
592 | { .compatible = "cirrus,cs42l51", }, | ||
593 | { } | ||
594 | }; | ||
595 | MODULE_DEVICE_TABLE(of, cs42l51_of_match); | ||
596 | |||
603 | static struct i2c_driver cs42l51_i2c_driver = { | 597 | static 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: | |||
210 | static int si476x_codec_probe(struct snd_soc_codec *codec) | 210 | static 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 | ||
216 | static struct snd_soc_dai_ops si476x_dai_ops = { | 216 | static 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 | |||
21 | static 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 | |||
33 | static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) | ||
34 | { | ||
35 | snd_soc_unregister_codec(&i2c->dev); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static const struct i2c_device_id tlv320aic23_id[] = { | ||
40 | {"tlv320aic23", 0}, | ||
41 | {} | ||
42 | }; | ||
43 | |||
44 | MODULE_DEVICE_TABLE(i2c, tlv320aic23_id); | ||
45 | |||
46 | static 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 | |||
55 | module_i2c_driver(tlv320aic23_i2c_driver); | ||
56 | |||
57 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver I2C"); | ||
58 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | ||
59 | MODULE_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 | |||
21 | static 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 | |||
38 | static int aic23_spi_remove(struct spi_device *spi) | ||
39 | { | ||
40 | snd_soc_unregister_codec(&spi->dev); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static 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 | |||
53 | module_spi_driver(aic23_spi); | ||
54 | |||
55 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver SPI"); | ||
56 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | ||
57 | MODULE_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 | ||
54 | static const struct regmap_config tlv320aic23_regmap = { | 53 | const 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 | }; |
62 | EXPORT_SYMBOL(tlv320aic23_regmap); | ||
63 | 63 | ||
64 | static const char *rec_src_text[] = { "Line", "Mic" }; | 64 | static const char *rec_src_text[] = { "Line", "Mic" }; |
65 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | 65 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; |
66 | 66 | ||
67 | static const struct soc_enum rec_src_enum = | 67 | static 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 | ||
70 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = | 70 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = |
71 | SOC_DAPM_ENUM("Input Select", rec_src_enum); | 71 | SOC_DAPM_ENUM("Input Select", rec_src_enum); |
72 | 72 | ||
73 | static const struct soc_enum tlv320aic23_rec_src = | 73 | static 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); |
75 | static const struct soc_enum tlv320aic23_deemph = | 75 | static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph, |
76 | SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); | 76 | TLV320AIC23_DIGT, 1, deemph_text); |
77 | 77 | ||
78 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); | 78 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); |
79 | static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); | 79 | static 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 | ||
560 | static int tlv320aic23_probe(struct snd_soc_codec *codec) | 560 | static 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 | ||
606 | static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { | 606 | static 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 | /* | 620 | int 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 | */ | ||
624 | static 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 | } | ||
647 | static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) | ||
648 | { | ||
649 | snd_soc_unregister_codec(&i2c->dev); | ||
650 | return 0; | ||
651 | } | 637 | } |
652 | 638 | EXPORT_SYMBOL(tlv320aic23_probe); | |
653 | static const struct i2c_device_id tlv320aic23_id[] = { | ||
654 | {"tlv320aic23", 0}, | ||
655 | {} | ||
656 | }; | ||
657 | |||
658 | MODULE_DEVICE_TABLE(i2c, tlv320aic23_id); | ||
659 | |||
660 | static 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 | |||
669 | module_i2c_driver(tlv320aic23_i2c_driver); | ||
670 | 639 | ||
671 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); | 640 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); |
672 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | 641 | MODULE_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 | ||
15 | struct device; | ||
16 | struct regmap_config; | ||
17 | |||
18 | extern const struct regmap_config tlv320aic23_regmap; | ||
19 | int 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 */ | ||
72 | static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0); | ||
73 | /* 0dB min, 0.5dB steps */ | 80 | /* 0dB min, 0.5dB steps */ |
74 | static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0); | 81 | static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0); |
82 | /* -63.5dB min, 0.5dB steps */ | ||
83 | static DECLARE_TLV_DB_SCALE(tlv_pcm, -6350, 50, 0); | ||
84 | /* -6dB min, 1dB steps */ | ||
85 | static DECLARE_TLV_DB_SCALE(tlv_driver_gain, -600, 100, 0); | ||
86 | /* -12dB min, 0.5dB steps */ | ||
87 | static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0); | ||
75 | 88 | ||
76 | static const struct snd_kcontrol_new aic32x4_snd_controls[] = { | 89 | static 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) | |||
480 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | 495 | static 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 | ||
694 | static 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 | |||
704 | static 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 | |||
718 | static 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 | |||
791 | error_av: | ||
792 | if (!IS_ERR(aic32x4->supply_dv)) | ||
793 | regulator_disable(aic32x4->supply_dv); | ||
794 | |||
795 | error_dv: | ||
796 | if (!IS_ERR(aic32x4->supply_ldo)) | ||
797 | regulator_disable(aic32x4->supply_ldo); | ||
798 | |||
799 | error_ldo: | ||
800 | regulator_disable(aic32x4->supply_iov); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
666 | static int aic32x4_i2c_probe(struct i2c_client *i2c, | 804 | static 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 | ||
708 | static int aic32x4_i2c_remove(struct i2c_client *client) | 873 | static 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 | }; |
718 | MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); | 887 | MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); |
719 | 888 | ||
889 | static const struct of_device_id aic32x4_of_id[] = { | ||
890 | { .compatible = "ti,tlv320aic32x4", }, | ||
891 | { /* senitel */ } | ||
892 | }; | ||
893 | MODULE_DEVICE_TABLE(of, aic32x4_of_id); | ||
894 | |||
720 | static struct i2c_driver aic32x4_i2c_driver = { | 895 | static 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, | |||
171 | static const char *wm8991_digital_sidetone[] = | 171 | static const char *wm8991_digital_sidetone[] = |
172 | {"None", "Left ADC", "Right ADC", "Reserved"}; | 172 | {"None", "Left ADC", "Right ADC", "Reserved"}; |
173 | 173 | ||
174 | static const struct soc_enum wm8991_left_digital_sidetone_enum = | 174 | static 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 | 179 | static SOC_ENUM_SINGLE_DECL(wm8991_right_digital_sidetone_enum, | |
180 | static 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 | ||
186 | static const char *wm8991_adcmode[] = | 184 | static 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 | ||
189 | static const struct soc_enum wm8991_right_adcmode_enum = | 187 | static 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 | ||
195 | static const struct snd_kcontrol_new wm8991_snd_controls[] = { | 192 | static 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[] = { | |||
486 | static const char *wm8991_ainlmux[] = | 483 | static const char *wm8991_ainlmux[] = |
487 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; | 484 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; |
488 | 485 | ||
489 | static const struct soc_enum wm8991_ainlmux_enum = | 486 | static 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 | ||
493 | static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls = | 490 | static 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 = | |||
499 | static const char *wm8991_ainrmux[] = | 496 | static const char *wm8991_ainrmux[] = |
500 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; | 497 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; |
501 | 498 | ||
502 | static const struct soc_enum wm8991_ainrmux_enum = | 499 | static 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 | ||
506 | static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls = | 503 | static 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 | ||
1252 | static int wm8991_probe(struct snd_soc_codec *codec) | 1249 | static 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 | ||
123 | config SND_SOC_SAMSUNG_SIMTEC_HERMES | 123 | config 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, | |||
2716 | EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); | 2716 | EXPORT_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 | */ | ||
2732 | static 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 | } |
2749 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | 2791 | EXPORT_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. |