diff options
Diffstat (limited to 'sound/soc/codecs')
56 files changed, 3291 insertions, 586 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 922006dd0583..4c3b0af39fd8 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -1337,8 +1337,6 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1337 | } | 1337 | } |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1341 | |||
1342 | return 0; | 1340 | return 0; |
1343 | 1341 | ||
1344 | out: | 1342 | out: |
@@ -1354,7 +1352,6 @@ static int pm860x_remove(struct snd_soc_codec *codec) | |||
1354 | 1352 | ||
1355 | for (i = 3; i >= 0; i--) | 1353 | for (i = 3; i >= 0; i--) |
1356 | free_irq(pm860x->irq[i], pm860x); | 1354 | free_irq(pm860x->irq[i], pm860x); |
1357 | pm860x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1358 | return 0; | 1355 | return 0; |
1359 | } | 1356 | } |
1360 | 1357 | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8838838e25ed..a68d1731a8fd 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -43,6 +43,7 @@ config SND_SOC_ALL_CODECS | |||
43 | select SND_SOC_ALC5623 if I2C | 43 | select SND_SOC_ALC5623 if I2C |
44 | select SND_SOC_ALC5632 if I2C | 44 | select SND_SOC_ALC5632 if I2C |
45 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC | 45 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC |
46 | select SND_SOC_CS35L32 if I2C | ||
46 | select SND_SOC_CS42L51_I2C if I2C | 47 | select SND_SOC_CS42L51_I2C if I2C |
47 | select SND_SOC_CS42L52 if I2C && INPUT | 48 | select SND_SOC_CS42L52 if I2C && INPUT |
48 | select SND_SOC_CS42L56 if I2C && INPUT | 49 | select SND_SOC_CS42L56 if I2C && INPUT |
@@ -56,7 +57,10 @@ config SND_SOC_ALL_CODECS | |||
56 | select SND_SOC_DA7213 if I2C | 57 | select SND_SOC_DA7213 if I2C |
57 | select SND_SOC_DA732X if I2C | 58 | select SND_SOC_DA732X if I2C |
58 | select SND_SOC_DA9055 if I2C | 59 | select SND_SOC_DA9055 if I2C |
60 | select SND_SOC_DMIC | ||
59 | select SND_SOC_BT_SCO | 61 | select SND_SOC_BT_SCO |
62 | select SND_SOC_ES8328_SPI if SPI_MASTER | ||
63 | select SND_SOC_ES8328_I2C if I2C | ||
60 | select SND_SOC_ISABELLE if I2C | 64 | select SND_SOC_ISABELLE if I2C |
61 | select SND_SOC_JZ4740_CODEC | 65 | select SND_SOC_JZ4740_CODEC |
62 | select SND_SOC_LM4857 if I2C | 66 | select SND_SOC_LM4857 if I2C |
@@ -90,6 +94,7 @@ config SND_SOC_ALL_CODECS | |||
90 | select SND_SOC_SSM2518 if I2C | 94 | select SND_SOC_SSM2518 if I2C |
91 | select SND_SOC_SSM2602_SPI if SPI_MASTER | 95 | select SND_SOC_SSM2602_SPI if SPI_MASTER |
92 | select SND_SOC_SSM2602_I2C if I2C | 96 | select SND_SOC_SSM2602_I2C if I2C |
97 | select SND_SOC_SSM4567 if I2C | ||
93 | select SND_SOC_STA32X if I2C | 98 | select SND_SOC_STA32X if I2C |
94 | select SND_SOC_STA350 if I2C | 99 | select SND_SOC_STA350 if I2C |
95 | select SND_SOC_STA529 if I2C | 100 | select SND_SOC_STA529 if I2C |
@@ -323,6 +328,10 @@ config SND_SOC_ALC5632 | |||
323 | config SND_SOC_CQ0093VC | 328 | config SND_SOC_CQ0093VC |
324 | tristate | 329 | tristate |
325 | 330 | ||
331 | config SND_SOC_CS35L32 | ||
332 | tristate "Cirrus Logic CS35L32 CODEC" | ||
333 | depends on I2C | ||
334 | |||
326 | config SND_SOC_CS42L51 | 335 | config SND_SOC_CS42L51 |
327 | tristate | 336 | tristate |
328 | 337 | ||
@@ -405,6 +414,17 @@ config SND_SOC_DMIC | |||
405 | config SND_SOC_HDMI_CODEC | 414 | config SND_SOC_HDMI_CODEC |
406 | tristate "HDMI stub CODEC" | 415 | tristate "HDMI stub CODEC" |
407 | 416 | ||
417 | config SND_SOC_ES8328 | ||
418 | tristate "Everest Semi ES8328 CODEC" | ||
419 | |||
420 | config SND_SOC_ES8328_I2C | ||
421 | tristate | ||
422 | select SND_SOC_ES8328 | ||
423 | |||
424 | config SND_SOC_ES8328_SPI | ||
425 | tristate | ||
426 | select SND_SOC_ES8328 | ||
427 | |||
408 | config SND_SOC_ISABELLE | 428 | config SND_SOC_ISABELLE |
409 | tristate | 429 | tristate |
410 | 430 | ||
@@ -464,6 +484,7 @@ config SND_SOC_RL6231 | |||
464 | 484 | ||
465 | config SND_SOC_RT286 | 485 | config SND_SOC_RT286 |
466 | tristate | 486 | tristate |
487 | depends on I2C | ||
467 | 488 | ||
468 | config SND_SOC_RT5631 | 489 | config SND_SOC_RT5631 |
469 | tristate | 490 | tristate |
@@ -520,12 +541,20 @@ config SND_SOC_SSM2602 | |||
520 | tristate | 541 | tristate |
521 | 542 | ||
522 | config SND_SOC_SSM2602_SPI | 543 | config SND_SOC_SSM2602_SPI |
544 | tristate "Analog Devices SSM2602 CODEC - SPI" | ||
545 | depends on SPI_MASTER | ||
523 | select SND_SOC_SSM2602 | 546 | select SND_SOC_SSM2602 |
524 | tristate | 547 | select REGMAP_SPI |
525 | 548 | ||
526 | config SND_SOC_SSM2602_I2C | 549 | config SND_SOC_SSM2602_I2C |
550 | tristate "Analog Devices SSM2602 CODEC - I2C" | ||
551 | depends on I2C | ||
527 | select SND_SOC_SSM2602 | 552 | select SND_SOC_SSM2602 |
528 | tristate | 553 | select REGMAP_I2C |
554 | |||
555 | config SND_SOC_SSM4567 | ||
556 | tristate "Analog Devices ssm4567 amplifier driver support" | ||
557 | depends on I2C | ||
529 | 558 | ||
530 | config SND_SOC_STA32X | 559 | config SND_SOC_STA32X |
531 | tristate | 560 | tristate |
@@ -712,7 +741,8 @@ config SND_SOC_WM8974 | |||
712 | tristate | 741 | tristate |
713 | 742 | ||
714 | config SND_SOC_WM8978 | 743 | config SND_SOC_WM8978 |
715 | tristate | 744 | tristate "Wolfson Microelectronics WM8978 codec" |
745 | depends on I2C | ||
716 | 746 | ||
717 | config SND_SOC_WM8983 | 747 | config SND_SOC_WM8983 |
718 | tristate | 748 | tristate |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 20afe0f0c5be..5dce451661e4 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -32,6 +32,7 @@ snd-soc-ak4671-objs := ak4671.o | |||
32 | snd-soc-ak5386-objs := ak5386.o | 32 | snd-soc-ak5386-objs := ak5386.o |
33 | snd-soc-arizona-objs := arizona.o | 33 | snd-soc-arizona-objs := arizona.o |
34 | snd-soc-cq93vc-objs := cq93vc.o | 34 | snd-soc-cq93vc-objs := cq93vc.o |
35 | snd-soc-cs35l32-objs := cs35l32.o | ||
35 | snd-soc-cs42l51-objs := cs42l51.o | 36 | snd-soc-cs42l51-objs := cs42l51.o |
36 | snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o | 37 | snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o |
37 | snd-soc-cs42l52-objs := cs42l52.o | 38 | snd-soc-cs42l52-objs := cs42l52.o |
@@ -49,6 +50,9 @@ snd-soc-da732x-objs := da732x.o | |||
49 | snd-soc-da9055-objs := da9055.o | 50 | snd-soc-da9055-objs := da9055.o |
50 | snd-soc-bt-sco-objs := bt-sco.o | 51 | snd-soc-bt-sco-objs := bt-sco.o |
51 | snd-soc-dmic-objs := dmic.o | 52 | snd-soc-dmic-objs := dmic.o |
53 | snd-soc-es8328-objs := es8328.o | ||
54 | snd-soc-es8328-i2c-objs := es8328-i2c.o | ||
55 | snd-soc-es8328-spi-objs := es8328-spi.o | ||
52 | snd-soc-isabelle-objs := isabelle.o | 56 | snd-soc-isabelle-objs := isabelle.o |
53 | snd-soc-jz4740-codec-objs := jz4740.o | 57 | snd-soc-jz4740-codec-objs := jz4740.o |
54 | snd-soc-l3-objs := l3.o | 58 | snd-soc-l3-objs := l3.o |
@@ -91,6 +95,7 @@ snd-soc-ssm2518-objs := ssm2518.o | |||
91 | snd-soc-ssm2602-objs := ssm2602.o | 95 | snd-soc-ssm2602-objs := ssm2602.o |
92 | snd-soc-ssm2602-spi-objs := ssm2602-spi.o | 96 | snd-soc-ssm2602-spi-objs := ssm2602-spi.o |
93 | snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o | 97 | snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o |
98 | snd-soc-ssm4567-objs := ssm4567.o | ||
94 | snd-soc-sta32x-objs := sta32x.o | 99 | snd-soc-sta32x-objs := sta32x.o |
95 | snd-soc-sta350-objs := sta350.o | 100 | snd-soc-sta350-objs := sta350.o |
96 | snd-soc-sta529-objs := sta529.o | 101 | snd-soc-sta529-objs := sta529.o |
@@ -203,6 +208,7 @@ obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o | |||
203 | obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o | 208 | obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o |
204 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o | 209 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o |
205 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o | 210 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o |
211 | obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o | ||
206 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o | 212 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o |
207 | obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o | 213 | obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o |
208 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o | 214 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o |
@@ -220,6 +226,9 @@ obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o | |||
220 | obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o | 226 | obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o |
221 | obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o | 227 | obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o |
222 | obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o | 228 | obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o |
229 | obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o | ||
230 | obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o | ||
231 | obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o | ||
223 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o | 232 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o |
224 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o | 233 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o |
225 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o | 234 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o |
@@ -258,6 +267,7 @@ obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o | |||
258 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | 267 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o |
259 | obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o | 268 | obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o |
260 | obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o | 269 | obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o |
270 | obj-$(CONFIG_SND_SOC_SSM4567) += snd-soc-ssm4567.o | ||
261 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o | 271 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o |
262 | obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o | 272 | obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o |
263 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o | 273 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 1fb4402bf72d..fd43827bb856 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -56,8 +56,7 @@ | |||
56 | #define GPIO31_DIR_OUTPUT 0x40 | 56 | #define GPIO31_DIR_OUTPUT 0x40 |
57 | 57 | ||
58 | /* Macrocell register definitions */ | 58 | /* Macrocell register definitions */ |
59 | #define AB8500_CTRL3_REG 0x0200 | 59 | #define AB8500_GPIO_DIR4_REG 0x13 /* Bank AB8500_MISC */ |
60 | #define AB8500_GPIO_DIR4_REG 0x1013 | ||
61 | 60 | ||
62 | /* Nr of FIR/IIR-coeff banks in ANC-block */ | 61 | /* Nr of FIR/IIR-coeff banks in ANC-block */ |
63 | #define AB8500_NR_OF_ANC_COEFF_BANKS 2 | 62 | #define AB8500_NR_OF_ANC_COEFF_BANKS 2 |
@@ -126,6 +125,8 @@ struct ab8500_codec_drvdata_dbg { | |||
126 | 125 | ||
127 | /* Private data for AB8500 device-driver */ | 126 | /* Private data for AB8500 device-driver */ |
128 | struct ab8500_codec_drvdata { | 127 | struct ab8500_codec_drvdata { |
128 | struct regmap *regmap; | ||
129 | |||
129 | /* Sidetone */ | 130 | /* Sidetone */ |
130 | long *sid_fir_values; | 131 | long *sid_fir_values; |
131 | enum sid_state sid_status; | 132 | enum sid_state sid_status; |
@@ -166,49 +167,35 @@ static inline const char *amic_type_str(enum amic_type type) | |||
166 | */ | 167 | */ |
167 | 168 | ||
168 | /* Read a register from the audio-bank of AB8500 */ | 169 | /* Read a register from the audio-bank of AB8500 */ |
169 | static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec, | 170 | static int ab8500_codec_read_reg(void *context, unsigned int reg, |
170 | unsigned int reg) | 171 | unsigned int *value) |
171 | { | 172 | { |
173 | struct device *dev = context; | ||
172 | int status; | 174 | int status; |
173 | unsigned int value = 0; | ||
174 | 175 | ||
175 | u8 value8; | 176 | u8 value8; |
176 | status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO, | 177 | status = abx500_get_register_interruptible(dev, AB8500_AUDIO, |
177 | reg, &value8); | 178 | reg, &value8); |
178 | if (status < 0) { | 179 | *value = (unsigned int)value8; |
179 | dev_err(codec->dev, | ||
180 | "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n", | ||
181 | __func__, (u8)AB8500_AUDIO, (u8)reg, status); | ||
182 | } else { | ||
183 | dev_dbg(codec->dev, | ||
184 | "%s: Read 0x%02x from register 0x%02x:0x%02x\n", | ||
185 | __func__, value8, (u8)AB8500_AUDIO, (u8)reg); | ||
186 | value = (unsigned int)value8; | ||
187 | } | ||
188 | 180 | ||
189 | return value; | 181 | return status; |
190 | } | 182 | } |
191 | 183 | ||
192 | /* Write to a register in the audio-bank of AB8500 */ | 184 | /* Write to a register in the audio-bank of AB8500 */ |
193 | static int ab8500_codec_write_reg(struct snd_soc_codec *codec, | 185 | static int ab8500_codec_write_reg(void *context, unsigned int reg, |
194 | unsigned int reg, unsigned int value) | 186 | unsigned int value) |
195 | { | 187 | { |
196 | int status; | 188 | struct device *dev = context; |
197 | |||
198 | status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO, | ||
199 | reg, value); | ||
200 | if (status < 0) | ||
201 | dev_err(codec->dev, | ||
202 | "%s: ERROR: Register (%02x:%02x) write failed (%d).\n", | ||
203 | __func__, (u8)AB8500_AUDIO, (u8)reg, status); | ||
204 | else | ||
205 | dev_dbg(codec->dev, | ||
206 | "%s: Wrote 0x%02x into register %02x:%02x\n", | ||
207 | __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg); | ||
208 | 189 | ||
209 | return status; | 190 | return abx500_set_register_interruptible(dev, AB8500_AUDIO, |
191 | reg, value); | ||
210 | } | 192 | } |
211 | 193 | ||
194 | static const struct regmap_config ab8500_codec_regmap = { | ||
195 | .reg_read = ab8500_codec_read_reg, | ||
196 | .reg_write = ab8500_codec_write_reg, | ||
197 | }; | ||
198 | |||
212 | /* | 199 | /* |
213 | * Controls - DAPM | 200 | * Controls - DAPM |
214 | */ | 201 | */ |
@@ -1968,16 +1955,16 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, | |||
1968 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | 1955 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); |
1969 | 1956 | ||
1970 | /* Set DMic-clocks to outputs */ | 1957 | /* Set DMic-clocks to outputs */ |
1971 | status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC, | 1958 | status = abx500_get_register_interruptible(codec->dev, AB8500_MISC, |
1972 | (u8)AB8500_GPIO_DIR4_REG, | 1959 | AB8500_GPIO_DIR4_REG, |
1973 | &value8); | 1960 | &value8); |
1974 | if (status < 0) | 1961 | if (status < 0) |
1975 | return status; | 1962 | return status; |
1976 | value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | | 1963 | value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | |
1977 | GPIO31_DIR_OUTPUT; | 1964 | GPIO31_DIR_OUTPUT; |
1978 | status = abx500_set_register_interruptible(codec->dev, | 1965 | status = abx500_set_register_interruptible(codec->dev, |
1979 | (u8)AB8500_MISC, | 1966 | AB8500_MISC, |
1980 | (u8)AB8500_GPIO_DIR4_REG, | 1967 | AB8500_GPIO_DIR4_REG, |
1981 | value); | 1968 | value); |
1982 | if (status < 0) | 1969 | if (status < 0) |
1983 | return status; | 1970 | return status; |
@@ -2565,9 +2552,6 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2565 | 2552 | ||
2566 | static struct snd_soc_codec_driver ab8500_codec_driver = { | 2553 | static struct snd_soc_codec_driver ab8500_codec_driver = { |
2567 | .probe = ab8500_codec_probe, | 2554 | .probe = ab8500_codec_probe, |
2568 | .read = ab8500_codec_read_reg, | ||
2569 | .write = ab8500_codec_write_reg, | ||
2570 | .reg_word_size = sizeof(u8), | ||
2571 | .controls = ab8500_ctrls, | 2555 | .controls = ab8500_ctrls, |
2572 | .num_controls = ARRAY_SIZE(ab8500_ctrls), | 2556 | .num_controls = ARRAY_SIZE(ab8500_ctrls), |
2573 | .dapm_widgets = ab8500_dapm_widgets, | 2557 | .dapm_widgets = ab8500_dapm_widgets, |
@@ -2592,6 +2576,15 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev) | |||
2592 | drvdata->anc_status = ANC_UNCONFIGURED; | 2576 | drvdata->anc_status = ANC_UNCONFIGURED; |
2593 | dev_set_drvdata(&pdev->dev, drvdata); | 2577 | dev_set_drvdata(&pdev->dev, drvdata); |
2594 | 2578 | ||
2579 | drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev, | ||
2580 | &ab8500_codec_regmap); | ||
2581 | if (IS_ERR(drvdata->regmap)) { | ||
2582 | status = PTR_ERR(drvdata->regmap); | ||
2583 | dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n", | ||
2584 | __func__, status); | ||
2585 | return status; | ||
2586 | } | ||
2587 | |||
2595 | dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__); | 2588 | dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__); |
2596 | status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver, | 2589 | status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver, |
2597 | ab8500_codec_dai, | 2590 | ab8500_codec_dai, |
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index e889e1b84192..bd9b1839c8b0 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -69,19 +69,6 @@ static struct snd_soc_dai_driver ac97_dai = { | |||
69 | .ops = &ac97_dai_ops, | 69 | .ops = &ac97_dai_ops, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static unsigned int ac97_read(struct snd_soc_codec *codec, | ||
73 | unsigned int reg) | ||
74 | { | ||
75 | return soc_ac97_ops->read(codec->ac97, reg); | ||
76 | } | ||
77 | |||
78 | static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | ||
79 | unsigned int val) | ||
80 | { | ||
81 | soc_ac97_ops->write(codec->ac97, reg, val); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int ac97_soc_probe(struct snd_soc_codec *codec) | 72 | static int ac97_soc_probe(struct snd_soc_codec *codec) |
86 | { | 73 | { |
87 | struct snd_ac97_bus *ac97_bus; | 74 | struct snd_ac97_bus *ac97_bus; |
@@ -122,8 +109,6 @@ static int ac97_soc_resume(struct snd_soc_codec *codec) | |||
122 | #endif | 109 | #endif |
123 | 110 | ||
124 | static struct snd_soc_codec_driver soc_codec_dev_ac97 = { | 111 | static struct snd_soc_codec_driver soc_codec_dev_ac97 = { |
125 | .write = ac97_write, | ||
126 | .read = ac97_read, | ||
127 | .probe = ac97_soc_probe, | 112 | .probe = ac97_soc_probe, |
128 | .suspend = ac97_soc_suspend, | 113 | .suspend = ac97_soc_suspend, |
129 | .resume = ac97_soc_resume, | 114 | .resume = ac97_soc_resume, |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 1ff7d4d027e9..7c784ad3e8b2 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -1448,29 +1448,10 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec, | |||
1448 | return 0; | 1448 | return 0; |
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | static int adau1373_remove(struct snd_soc_codec *codec) | ||
1452 | { | ||
1453 | adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1454 | return 0; | ||
1455 | } | ||
1456 | |||
1457 | static int adau1373_suspend(struct snd_soc_codec *codec) | ||
1458 | { | ||
1459 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); | ||
1460 | int ret; | ||
1461 | |||
1462 | ret = adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1463 | regcache_cache_only(adau1373->regmap, true); | ||
1464 | |||
1465 | return ret; | ||
1466 | } | ||
1467 | |||
1468 | static int adau1373_resume(struct snd_soc_codec *codec) | 1451 | static int adau1373_resume(struct snd_soc_codec *codec) |
1469 | { | 1452 | { |
1470 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); | 1453 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); |
1471 | 1454 | ||
1472 | regcache_cache_only(adau1373->regmap, false); | ||
1473 | adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1474 | regcache_sync(adau1373->regmap); | 1455 | regcache_sync(adau1373->regmap); |
1475 | 1456 | ||
1476 | return 0; | 1457 | return 0; |
@@ -1501,8 +1482,6 @@ static const struct regmap_config adau1373_regmap_config = { | |||
1501 | 1482 | ||
1502 | static struct snd_soc_codec_driver adau1373_codec_driver = { | 1483 | static struct snd_soc_codec_driver adau1373_codec_driver = { |
1503 | .probe = adau1373_probe, | 1484 | .probe = adau1373_probe, |
1504 | .remove = adau1373_remove, | ||
1505 | .suspend = adau1373_suspend, | ||
1506 | .resume = adau1373_resume, | 1485 | .resume = adau1373_resume, |
1507 | .set_bias_level = adau1373_set_bias_level, | 1486 | .set_bias_level = adau1373_set_bias_level, |
1508 | .idle_bias_off = true, | 1487 | .idle_bias_off = true, |
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 848cab839553..5518ebd6947c 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c | |||
@@ -714,9 +714,9 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec) | |||
714 | 714 | ||
715 | static const struct snd_soc_codec_driver adau1761_codec_driver = { | 715 | static const struct snd_soc_codec_driver adau1761_codec_driver = { |
716 | .probe = adau1761_codec_probe, | 716 | .probe = adau1761_codec_probe, |
717 | .suspend = adau17x1_suspend, | ||
718 | .resume = adau17x1_resume, | 717 | .resume = adau17x1_resume, |
719 | .set_bias_level = adau1761_set_bias_level, | 718 | .set_bias_level = adau1761_set_bias_level, |
719 | .suspend_bias_off = true, | ||
720 | 720 | ||
721 | .controls = adau1761_controls, | 721 | .controls = adau1761_controls, |
722 | .num_controls = ARRAY_SIZE(adau1761_controls), | 722 | .num_controls = ARRAY_SIZE(adau1761_controls), |
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index 045a61413840..e9fc00fb13dd 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c | |||
@@ -446,9 +446,9 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec) | |||
446 | 446 | ||
447 | static const struct snd_soc_codec_driver adau1781_codec_driver = { | 447 | static const struct snd_soc_codec_driver adau1781_codec_driver = { |
448 | .probe = adau1781_codec_probe, | 448 | .probe = adau1781_codec_probe, |
449 | .suspend = adau17x1_suspend, | ||
450 | .resume = adau17x1_resume, | 449 | .resume = adau17x1_resume, |
451 | .set_bias_level = adau1781_set_bias_level, | 450 | .set_bias_level = adau1781_set_bias_level, |
451 | .suspend_bias_off = true, | ||
452 | 452 | ||
453 | .controls = adau1781_controls, | 453 | .controls = adau1781_controls, |
454 | .num_controls = ARRAY_SIZE(adau1781_controls), | 454 | .num_controls = ARRAY_SIZE(adau1781_controls), |
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 0b659704e60c..3e16c1c64115 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c | |||
@@ -815,13 +815,6 @@ int adau17x1_add_routes(struct snd_soc_codec *codec) | |||
815 | } | 815 | } |
816 | EXPORT_SYMBOL_GPL(adau17x1_add_routes); | 816 | EXPORT_SYMBOL_GPL(adau17x1_add_routes); |
817 | 817 | ||
818 | int adau17x1_suspend(struct snd_soc_codec *codec) | ||
819 | { | ||
820 | codec->driver->set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
821 | return 0; | ||
822 | } | ||
823 | EXPORT_SYMBOL_GPL(adau17x1_suspend); | ||
824 | |||
825 | int adau17x1_resume(struct snd_soc_codec *codec) | 818 | int adau17x1_resume(struct snd_soc_codec *codec) |
826 | { | 819 | { |
827 | struct adau *adau = snd_soc_codec_get_drvdata(codec); | 820 | struct adau *adau = snd_soc_codec_get_drvdata(codec); |
@@ -829,7 +822,6 @@ int adau17x1_resume(struct snd_soc_codec *codec) | |||
829 | if (adau->switch_mode) | 822 | if (adau->switch_mode) |
830 | adau->switch_mode(codec->dev); | 823 | adau->switch_mode(codec->dev); |
831 | 824 | ||
832 | codec->driver->set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
833 | regcache_sync(adau->regmap); | 825 | regcache_sync(adau->regmap); |
834 | 826 | ||
835 | return 0; | 827 | return 0; |
diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index 3ffabaf4c7a8..e4a557fd7155 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h | |||
@@ -52,7 +52,6 @@ int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, | |||
52 | enum adau17x1_micbias_voltage micbias); | 52 | enum adau17x1_micbias_voltage micbias); |
53 | bool adau17x1_readable_register(struct device *dev, unsigned int reg); | 53 | bool adau17x1_readable_register(struct device *dev, unsigned int reg); |
54 | bool adau17x1_volatile_register(struct device *dev, unsigned int reg); | 54 | bool adau17x1_volatile_register(struct device *dev, unsigned int reg); |
55 | int adau17x1_suspend(struct snd_soc_codec *codec); | ||
56 | int adau17x1_resume(struct snd_soc_codec *codec); | 55 | int adau17x1_resume(struct snd_soc_codec *codec); |
57 | 56 | ||
58 | extern const struct snd_soc_dai_ops adau17x1_dai_ops; | 57 | extern const struct snd_soc_dai_ops adau17x1_dai_ops; |
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index c43b93fdf0df..ce3cdca9fc62 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
@@ -812,42 +812,23 @@ static int adav80x_probe(struct snd_soc_codec *codec) | |||
812 | /* Disable DAC zero flag */ | 812 | /* Disable DAC zero flag */ |
813 | regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6); | 813 | regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6); |
814 | 814 | ||
815 | return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 815 | return 0; |
816 | } | ||
817 | |||
818 | static int adav80x_suspend(struct snd_soc_codec *codec) | ||
819 | { | ||
820 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | ||
821 | int ret; | ||
822 | |||
823 | ret = adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
824 | regcache_cache_only(adav80x->regmap, true); | ||
825 | |||
826 | return ret; | ||
827 | } | 816 | } |
828 | 817 | ||
829 | static int adav80x_resume(struct snd_soc_codec *codec) | 818 | static int adav80x_resume(struct snd_soc_codec *codec) |
830 | { | 819 | { |
831 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 820 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
832 | 821 | ||
833 | regcache_cache_only(adav80x->regmap, false); | ||
834 | adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
835 | regcache_sync(adav80x->regmap); | 822 | regcache_sync(adav80x->regmap); |
836 | 823 | ||
837 | return 0; | 824 | return 0; |
838 | } | 825 | } |
839 | 826 | ||
840 | static int adav80x_remove(struct snd_soc_codec *codec) | ||
841 | { | ||
842 | return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
843 | } | ||
844 | |||
845 | static struct snd_soc_codec_driver adav80x_codec_driver = { | 827 | static struct snd_soc_codec_driver adav80x_codec_driver = { |
846 | .probe = adav80x_probe, | 828 | .probe = adav80x_probe, |
847 | .remove = adav80x_remove, | ||
848 | .suspend = adav80x_suspend, | ||
849 | .resume = adav80x_resume, | 829 | .resume = adav80x_resume, |
850 | .set_bias_level = adav80x_set_bias_level, | 830 | .set_bias_level = adav80x_set_bias_level, |
831 | .suspend_bias_off = true, | ||
851 | 832 | ||
852 | .set_pll = adav80x_set_pll, | 833 | .set_pll = adav80x_set_pll, |
853 | .set_sysclk = adav80x_set_sysclk, | 834 | .set_sysclk = adav80x_set_sysclk, |
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c new file mode 100644 index 000000000000..c125925da92e --- /dev/null +++ b/sound/soc/codecs/cs35l32.c | |||
@@ -0,0 +1,631 @@ | |||
1 | /* | ||
2 | * cs35l32.c -- CS35L32 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2014 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | #include <linux/version.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/regulator/consumer.h> | ||
26 | #include <linux/gpio/consumer.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #include <sound/core.h> | ||
29 | #include <sound/pcm.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #include <sound/soc.h> | ||
32 | #include <sound/soc-dapm.h> | ||
33 | #include <sound/initval.h> | ||
34 | #include <sound/tlv.h> | ||
35 | #include <dt-bindings/sound/cs35l32.h> | ||
36 | |||
37 | #include "cs35l32.h" | ||
38 | |||
39 | #define CS35L32_NUM_SUPPLIES 2 | ||
40 | static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = { | ||
41 | "VA", | ||
42 | "VP", | ||
43 | }; | ||
44 | |||
45 | struct cs35l32_private { | ||
46 | struct regmap *regmap; | ||
47 | struct snd_soc_codec *codec; | ||
48 | struct regulator_bulk_data supplies[CS35L32_NUM_SUPPLIES]; | ||
49 | struct cs35l32_platform_data pdata; | ||
50 | struct gpio_desc *reset_gpio; | ||
51 | }; | ||
52 | |||
53 | static const struct reg_default cs35l32_reg_defaults[] = { | ||
54 | |||
55 | { 0x06, 0x04 }, /* Power Ctl 1 */ | ||
56 | { 0x07, 0xE8 }, /* Power Ctl 2 */ | ||
57 | { 0x08, 0x40 }, /* Clock Ctl */ | ||
58 | { 0x09, 0x20 }, /* Low Battery Threshold */ | ||
59 | { 0x0A, 0x00 }, /* Voltage Monitor [RO] */ | ||
60 | { 0x0B, 0x40 }, /* Conv Peak Curr Protection CTL */ | ||
61 | { 0x0C, 0x07 }, /* IMON Scaling */ | ||
62 | { 0x0D, 0x03 }, /* Audio/LED Pwr Manager */ | ||
63 | { 0x0F, 0x20 }, /* Serial Port Control */ | ||
64 | { 0x10, 0x14 }, /* Class D Amp CTL */ | ||
65 | { 0x11, 0x00 }, /* Protection Release CTL */ | ||
66 | { 0x12, 0xFF }, /* Interrupt Mask 1 */ | ||
67 | { 0x13, 0xFF }, /* Interrupt Mask 2 */ | ||
68 | { 0x14, 0xFF }, /* Interrupt Mask 3 */ | ||
69 | { 0x19, 0x00 }, /* LED Flash Mode Current */ | ||
70 | { 0x1A, 0x00 }, /* LED Movie Mode Current */ | ||
71 | { 0x1B, 0x20 }, /* LED Flash Timer */ | ||
72 | { 0x1C, 0x00 }, /* LED Flash Inhibit Current */ | ||
73 | }; | ||
74 | |||
75 | static bool cs35l32_readable_register(struct device *dev, unsigned int reg) | ||
76 | { | ||
77 | switch (reg) { | ||
78 | case CS35L32_DEVID_AB: | ||
79 | case CS35L32_DEVID_CD: | ||
80 | case CS35L32_DEVID_E: | ||
81 | case CS35L32_FAB_ID: | ||
82 | case CS35L32_REV_ID: | ||
83 | case CS35L32_PWRCTL1: | ||
84 | case CS35L32_PWRCTL2: | ||
85 | case CS35L32_CLK_CTL: | ||
86 | case CS35L32_BATT_THRESHOLD: | ||
87 | case CS35L32_VMON: | ||
88 | case CS35L32_BST_CPCP_CTL: | ||
89 | case CS35L32_IMON_SCALING: | ||
90 | case CS35L32_AUDIO_LED_MNGR: | ||
91 | case CS35L32_ADSP_CTL: | ||
92 | case CS35L32_CLASSD_CTL: | ||
93 | case CS35L32_PROTECT_CTL: | ||
94 | case CS35L32_INT_MASK_1: | ||
95 | case CS35L32_INT_MASK_2: | ||
96 | case CS35L32_INT_MASK_3: | ||
97 | case CS35L32_INT_STATUS_1: | ||
98 | case CS35L32_INT_STATUS_2: | ||
99 | case CS35L32_INT_STATUS_3: | ||
100 | case CS35L32_LED_STATUS: | ||
101 | case CS35L32_FLASH_MODE: | ||
102 | case CS35L32_MOVIE_MODE: | ||
103 | case CS35L32_FLASH_TIMER: | ||
104 | case CS35L32_FLASH_INHIBIT: | ||
105 | return true; | ||
106 | default: | ||
107 | return false; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static bool cs35l32_volatile_register(struct device *dev, unsigned int reg) | ||
112 | { | ||
113 | switch (reg) { | ||
114 | case CS35L32_DEVID_AB: | ||
115 | case CS35L32_DEVID_CD: | ||
116 | case CS35L32_DEVID_E: | ||
117 | case CS35L32_FAB_ID: | ||
118 | case CS35L32_REV_ID: | ||
119 | case CS35L32_INT_STATUS_1: | ||
120 | case CS35L32_INT_STATUS_2: | ||
121 | case CS35L32_INT_STATUS_3: | ||
122 | case CS35L32_LED_STATUS: | ||
123 | return true; | ||
124 | default: | ||
125 | return false; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | static bool cs35l32_precious_register(struct device *dev, unsigned int reg) | ||
130 | { | ||
131 | switch (reg) { | ||
132 | case CS35L32_INT_STATUS_1: | ||
133 | case CS35L32_INT_STATUS_2: | ||
134 | case CS35L32_INT_STATUS_3: | ||
135 | case CS35L32_LED_STATUS: | ||
136 | return true; | ||
137 | default: | ||
138 | return false; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static DECLARE_TLV_DB_SCALE(classd_ctl_tlv, 900, 300, 0); | ||
143 | |||
144 | static const struct snd_kcontrol_new imon_ctl = | ||
145 | SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 6, 1, 1); | ||
146 | |||
147 | static const struct snd_kcontrol_new vmon_ctl = | ||
148 | SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 7, 1, 1); | ||
149 | |||
150 | static const struct snd_kcontrol_new vpmon_ctl = | ||
151 | SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 5, 1, 1); | ||
152 | |||
153 | static const struct snd_kcontrol_new cs35l32_snd_controls[] = { | ||
154 | SOC_SINGLE_TLV("Speaker Volume", CS35L32_CLASSD_CTL, | ||
155 | 3, 0x04, 1, classd_ctl_tlv), | ||
156 | SOC_SINGLE("Zero Cross Switch", CS35L32_CLASSD_CTL, 2, 1, 0), | ||
157 | SOC_SINGLE("Gain Manager Switch", CS35L32_AUDIO_LED_MNGR, 3, 1, 0), | ||
158 | }; | ||
159 | |||
160 | static const struct snd_soc_dapm_widget cs35l32_dapm_widgets[] = { | ||
161 | |||
162 | SND_SOC_DAPM_SUPPLY("BOOST", CS35L32_PWRCTL1, 2, 1, NULL, 0), | ||
163 | SND_SOC_DAPM_OUT_DRV("Speaker", CS35L32_PWRCTL1, 7, 1, NULL, 0), | ||
164 | |||
165 | SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L32_PWRCTL2, 3, 1), | ||
166 | |||
167 | SND_SOC_DAPM_INPUT("VP"), | ||
168 | SND_SOC_DAPM_INPUT("ISENSE"), | ||
169 | SND_SOC_DAPM_INPUT("VSENSE"), | ||
170 | |||
171 | SND_SOC_DAPM_SWITCH("VMON ADC", CS35L32_PWRCTL2, 7, 1, &vmon_ctl), | ||
172 | SND_SOC_DAPM_SWITCH("IMON ADC", CS35L32_PWRCTL2, 6, 1, &imon_ctl), | ||
173 | SND_SOC_DAPM_SWITCH("VPMON ADC", CS35L32_PWRCTL2, 5, 1, &vpmon_ctl), | ||
174 | }; | ||
175 | |||
176 | static const struct snd_soc_dapm_route cs35l32_audio_map[] = { | ||
177 | |||
178 | {"Speaker", NULL, "BOOST"}, | ||
179 | |||
180 | {"VMON ADC", NULL, "VSENSE"}, | ||
181 | {"IMON ADC", NULL, "ISENSE"}, | ||
182 | {"VPMON ADC", NULL, "VP"}, | ||
183 | |||
184 | {"SDOUT", "Switch", "VMON ADC"}, | ||
185 | {"SDOUT", "Switch", "IMON ADC"}, | ||
186 | {"SDOUT", "Switch", "VPMON ADC"}, | ||
187 | |||
188 | {"Capture", NULL, "SDOUT"}, | ||
189 | }; | ||
190 | |||
191 | static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | ||
192 | { | ||
193 | struct snd_soc_codec *codec = codec_dai->codec; | ||
194 | |||
195 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
196 | case SND_SOC_DAIFMT_CBM_CFM: | ||
197 | snd_soc_update_bits(codec, CS35L32_ADSP_CTL, | ||
198 | CS35L32_ADSP_MASTER_MASK, | ||
199 | CS35L32_ADSP_MASTER_MASK); | ||
200 | break; | ||
201 | case SND_SOC_DAIFMT_CBS_CFS: | ||
202 | snd_soc_update_bits(codec, CS35L32_ADSP_CTL, | ||
203 | CS35L32_ADSP_MASTER_MASK, 0); | ||
204 | break; | ||
205 | default: | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int cs35l32_set_tristate(struct snd_soc_dai *dai, int tristate) | ||
213 | { | ||
214 | struct snd_soc_codec *codec = dai->codec; | ||
215 | |||
216 | return snd_soc_update_bits(codec, CS35L32_PWRCTL2, | ||
217 | CS35L32_SDOUT_3ST, tristate << 3); | ||
218 | } | ||
219 | |||
220 | static const struct snd_soc_dai_ops cs35l32_ops = { | ||
221 | .set_fmt = cs35l32_set_dai_fmt, | ||
222 | .set_tristate = cs35l32_set_tristate, | ||
223 | }; | ||
224 | |||
225 | static struct snd_soc_dai_driver cs35l32_dai[] = { | ||
226 | { | ||
227 | .name = "cs35l32-monitor", | ||
228 | .id = 0, | ||
229 | .capture = { | ||
230 | .stream_name = "Capture", | ||
231 | .channels_min = 2, | ||
232 | .channels_max = 2, | ||
233 | .rates = CS35L32_RATES, | ||
234 | .formats = CS35L32_FORMATS, | ||
235 | }, | ||
236 | .ops = &cs35l32_ops, | ||
237 | .symmetric_rates = 1, | ||
238 | } | ||
239 | }; | ||
240 | |||
241 | static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec, | ||
242 | int clk_id, int source, unsigned int freq, int dir) | ||
243 | { | ||
244 | unsigned int val; | ||
245 | |||
246 | switch (freq) { | ||
247 | case 6000000: | ||
248 | val = CS35L32_MCLK_RATIO; | ||
249 | break; | ||
250 | case 12000000: | ||
251 | val = CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO; | ||
252 | break; | ||
253 | case 6144000: | ||
254 | val = 0; | ||
255 | break; | ||
256 | case 12288000: | ||
257 | val = CS35L32_MCLK_DIV2_MASK; | ||
258 | break; | ||
259 | default: | ||
260 | return -EINVAL; | ||
261 | } | ||
262 | |||
263 | return snd_soc_update_bits(codec, CS35L32_CLK_CTL, | ||
264 | CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val); | ||
265 | } | ||
266 | |||
267 | static struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { | ||
268 | .set_sysclk = cs35l32_codec_set_sysclk, | ||
269 | |||
270 | .dapm_widgets = cs35l32_dapm_widgets, | ||
271 | .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), | ||
272 | .dapm_routes = cs35l32_audio_map, | ||
273 | .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), | ||
274 | |||
275 | .controls = cs35l32_snd_controls, | ||
276 | .num_controls = ARRAY_SIZE(cs35l32_snd_controls), | ||
277 | }; | ||
278 | |||
279 | /* Current and threshold powerup sequence Pg37 in datasheet */ | ||
280 | static const struct reg_default cs35l32_monitor_patch[] = { | ||
281 | |||
282 | { 0x00, 0x99 }, | ||
283 | { 0x48, 0x17 }, | ||
284 | { 0x49, 0x56 }, | ||
285 | { 0x43, 0x01 }, | ||
286 | { 0x3B, 0x62 }, | ||
287 | { 0x3C, 0x80 }, | ||
288 | { 0x00, 0x00 }, | ||
289 | }; | ||
290 | |||
291 | static struct regmap_config cs35l32_regmap = { | ||
292 | .reg_bits = 8, | ||
293 | .val_bits = 8, | ||
294 | |||
295 | .max_register = CS35L32_MAX_REGISTER, | ||
296 | .reg_defaults = cs35l32_reg_defaults, | ||
297 | .num_reg_defaults = ARRAY_SIZE(cs35l32_reg_defaults), | ||
298 | .volatile_reg = cs35l32_volatile_register, | ||
299 | .readable_reg = cs35l32_readable_register, | ||
300 | .precious_reg = cs35l32_precious_register, | ||
301 | .cache_type = REGCACHE_RBTREE, | ||
302 | }; | ||
303 | |||
304 | static int cs35l32_handle_of_data(struct i2c_client *i2c_client, | ||
305 | struct cs35l32_platform_data *pdata) | ||
306 | { | ||
307 | struct device_node *np = i2c_client->dev.of_node; | ||
308 | unsigned int val; | ||
309 | |||
310 | if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0) | ||
311 | pdata->sdout_share = val; | ||
312 | |||
313 | of_property_read_u32(np, "cirrus,boost-manager", &val); | ||
314 | switch (val) { | ||
315 | case CS35L32_BOOST_MGR_AUTO: | ||
316 | case CS35L32_BOOST_MGR_AUTO_AUDIO: | ||
317 | case CS35L32_BOOST_MGR_BYPASS: | ||
318 | case CS35L32_BOOST_MGR_FIXED: | ||
319 | pdata->boost_mng = val; | ||
320 | break; | ||
321 | default: | ||
322 | dev_err(&i2c_client->dev, | ||
323 | "Wrong cirrus,boost-manager DT value %d\n", val); | ||
324 | pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS; | ||
325 | } | ||
326 | |||
327 | of_property_read_u32(np, "cirrus,sdout-datacfg", &val); | ||
328 | switch (val) { | ||
329 | case CS35L32_DATA_CFG_LR_VP: | ||
330 | case CS35L32_DATA_CFG_LR_STAT: | ||
331 | case CS35L32_DATA_CFG_LR: | ||
332 | case CS35L32_DATA_CFG_LR_VPSTAT: | ||
333 | pdata->sdout_datacfg = val; | ||
334 | break; | ||
335 | default: | ||
336 | dev_err(&i2c_client->dev, | ||
337 | "Wrong cirrus,sdout-datacfg DT value %d\n", val); | ||
338 | pdata->sdout_datacfg = CS35L32_DATA_CFG_LR; | ||
339 | } | ||
340 | |||
341 | of_property_read_u32(np, "cirrus,battery-threshold", &val); | ||
342 | switch (val) { | ||
343 | case CS35L32_BATT_THRESH_3_1V: | ||
344 | case CS35L32_BATT_THRESH_3_2V: | ||
345 | case CS35L32_BATT_THRESH_3_3V: | ||
346 | case CS35L32_BATT_THRESH_3_4V: | ||
347 | pdata->batt_thresh = val; | ||
348 | break; | ||
349 | default: | ||
350 | dev_err(&i2c_client->dev, | ||
351 | "Wrong cirrus,battery-threshold DT value %d\n", val); | ||
352 | pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V; | ||
353 | } | ||
354 | |||
355 | of_property_read_u32(np, "cirrus,battery-recovery", &val); | ||
356 | switch (val) { | ||
357 | case CS35L32_BATT_RECOV_3_1V: | ||
358 | case CS35L32_BATT_RECOV_3_2V: | ||
359 | case CS35L32_BATT_RECOV_3_3V: | ||
360 | case CS35L32_BATT_RECOV_3_4V: | ||
361 | case CS35L32_BATT_RECOV_3_5V: | ||
362 | case CS35L32_BATT_RECOV_3_6V: | ||
363 | pdata->batt_recov = val; | ||
364 | break; | ||
365 | default: | ||
366 | dev_err(&i2c_client->dev, | ||
367 | "Wrong cirrus,battery-recovery DT value %d\n", val); | ||
368 | pdata->batt_recov = CS35L32_BATT_RECOV_3_4V; | ||
369 | } | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int cs35l32_i2c_probe(struct i2c_client *i2c_client, | ||
375 | const struct i2c_device_id *id) | ||
376 | { | ||
377 | struct cs35l32_private *cs35l32; | ||
378 | struct cs35l32_platform_data *pdata = | ||
379 | dev_get_platdata(&i2c_client->dev); | ||
380 | int ret, i; | ||
381 | unsigned int devid = 0; | ||
382 | unsigned int reg; | ||
383 | |||
384 | |||
385 | cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private), | ||
386 | GFP_KERNEL); | ||
387 | if (!cs35l32) { | ||
388 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
389 | return -ENOMEM; | ||
390 | } | ||
391 | |||
392 | i2c_set_clientdata(i2c_client, cs35l32); | ||
393 | |||
394 | cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap); | ||
395 | if (IS_ERR(cs35l32->regmap)) { | ||
396 | ret = PTR_ERR(cs35l32->regmap); | ||
397 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); | ||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | if (pdata) { | ||
402 | cs35l32->pdata = *pdata; | ||
403 | } else { | ||
404 | pdata = devm_kzalloc(&i2c_client->dev, | ||
405 | sizeof(struct cs35l32_platform_data), | ||
406 | GFP_KERNEL); | ||
407 | if (!pdata) { | ||
408 | dev_err(&i2c_client->dev, "could not allocate pdata\n"); | ||
409 | return -ENOMEM; | ||
410 | } | ||
411 | if (i2c_client->dev.of_node) { | ||
412 | ret = cs35l32_handle_of_data(i2c_client, | ||
413 | &cs35l32->pdata); | ||
414 | if (ret != 0) | ||
415 | return ret; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | for (i = 0; i < ARRAY_SIZE(cs35l32->supplies); i++) | ||
420 | cs35l32->supplies[i].supply = cs35l32_supply_names[i]; | ||
421 | |||
422 | ret = devm_regulator_bulk_get(&i2c_client->dev, | ||
423 | ARRAY_SIZE(cs35l32->supplies), | ||
424 | cs35l32->supplies); | ||
425 | if (ret != 0) { | ||
426 | dev_err(&i2c_client->dev, | ||
427 | "Failed to request supplies: %d\n", ret); | ||
428 | return ret; | ||
429 | } | ||
430 | |||
431 | ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies), | ||
432 | cs35l32->supplies); | ||
433 | if (ret != 0) { | ||
434 | dev_err(&i2c_client->dev, | ||
435 | "Failed to enable supplies: %d\n", ret); | ||
436 | return ret; | ||
437 | } | ||
438 | |||
439 | /* Reset the Device */ | ||
440 | cs35l32->reset_gpio = devm_gpiod_get(&i2c_client->dev, | ||
441 | "reset-gpios"); | ||
442 | if (IS_ERR(cs35l32->reset_gpio)) { | ||
443 | ret = PTR_ERR(cs35l32->reset_gpio); | ||
444 | if (ret != -ENOENT && ret != -ENOSYS) | ||
445 | return ret; | ||
446 | |||
447 | cs35l32->reset_gpio = NULL; | ||
448 | } else { | ||
449 | ret = gpiod_direction_output(cs35l32->reset_gpio, 0); | ||
450 | if (ret) | ||
451 | return ret; | ||
452 | gpiod_set_value_cansleep(cs35l32->reset_gpio, 1); | ||
453 | } | ||
454 | |||
455 | /* initialize codec */ | ||
456 | ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, ®); | ||
457 | devid = (reg & 0xFF) << 12; | ||
458 | |||
459 | ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, ®); | ||
460 | devid |= (reg & 0xFF) << 4; | ||
461 | |||
462 | ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, ®); | ||
463 | devid |= (reg & 0xF0) >> 4; | ||
464 | |||
465 | if (devid != CS35L32_CHIP_ID) { | ||
466 | ret = -ENODEV; | ||
467 | dev_err(&i2c_client->dev, | ||
468 | "CS35L32 Device ID (%X). Expected %X\n", | ||
469 | devid, CS35L32_CHIP_ID); | ||
470 | return ret; | ||
471 | } | ||
472 | |||
473 | ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, ®); | ||
474 | if (ret < 0) { | ||
475 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); | ||
476 | return ret; | ||
477 | } | ||
478 | |||
479 | ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch, | ||
480 | ARRAY_SIZE(cs35l32_monitor_patch)); | ||
481 | if (ret < 0) { | ||
482 | dev_err(&i2c_client->dev, "Failed to apply errata patch\n"); | ||
483 | return ret; | ||
484 | } | ||
485 | |||
486 | dev_info(&i2c_client->dev, | ||
487 | "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF); | ||
488 | |||
489 | /* Setup VBOOST Management */ | ||
490 | if (cs35l32->pdata.boost_mng) | ||
491 | regmap_update_bits(cs35l32->regmap, CS35L32_AUDIO_LED_MNGR, | ||
492 | CS35L32_BOOST_MASK, | ||
493 | cs35l32->pdata.boost_mng); | ||
494 | |||
495 | /* Setup ADSP Format Config */ | ||
496 | if (cs35l32->pdata.sdout_share) | ||
497 | regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL, | ||
498 | CS35L32_ADSP_SHARE_MASK, | ||
499 | cs35l32->pdata.sdout_share << 3); | ||
500 | |||
501 | /* Setup ADSP Data Configuration */ | ||
502 | if (cs35l32->pdata.sdout_datacfg) | ||
503 | regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL, | ||
504 | CS35L32_ADSP_DATACFG_MASK, | ||
505 | cs35l32->pdata.sdout_datacfg << 4); | ||
506 | |||
507 | /* Setup Low Battery Recovery */ | ||
508 | if (cs35l32->pdata.batt_recov) | ||
509 | regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD, | ||
510 | CS35L32_BATT_REC_MASK, | ||
511 | cs35l32->pdata.batt_recov << 1); | ||
512 | |||
513 | /* Setup Low Battery Threshold */ | ||
514 | if (cs35l32->pdata.batt_thresh) | ||
515 | regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD, | ||
516 | CS35L32_BATT_THRESH_MASK, | ||
517 | cs35l32->pdata.batt_thresh << 4); | ||
518 | |||
519 | /* Power down the AMP */ | ||
520 | regmap_update_bits(cs35l32->regmap, CS35L32_PWRCTL1, CS35L32_PDN_AMP, | ||
521 | CS35L32_PDN_AMP); | ||
522 | |||
523 | /* Clear MCLK Error Bit since we don't have the clock yet */ | ||
524 | ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, ®); | ||
525 | |||
526 | ret = snd_soc_register_codec(&i2c_client->dev, | ||
527 | &soc_codec_dev_cs35l32, cs35l32_dai, | ||
528 | ARRAY_SIZE(cs35l32_dai)); | ||
529 | if (ret < 0) | ||
530 | goto err_disable; | ||
531 | |||
532 | return 0; | ||
533 | |||
534 | err_disable: | ||
535 | regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies), | ||
536 | cs35l32->supplies); | ||
537 | return ret; | ||
538 | } | ||
539 | |||
540 | static int cs35l32_i2c_remove(struct i2c_client *i2c_client) | ||
541 | { | ||
542 | struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client); | ||
543 | |||
544 | snd_soc_unregister_codec(&i2c_client->dev); | ||
545 | |||
546 | /* Hold down reset */ | ||
547 | if (cs35l32->reset_gpio) | ||
548 | gpiod_set_value_cansleep(cs35l32->reset_gpio, 0); | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | #ifdef CONFIG_PM_RUNTIME | ||
554 | static int cs35l32_runtime_suspend(struct device *dev) | ||
555 | { | ||
556 | struct cs35l32_private *cs35l32 = dev_get_drvdata(dev); | ||
557 | |||
558 | regcache_cache_only(cs35l32->regmap, true); | ||
559 | regcache_mark_dirty(cs35l32->regmap); | ||
560 | |||
561 | /* Hold down reset */ | ||
562 | if (cs35l32->reset_gpio) | ||
563 | gpiod_set_value_cansleep(cs35l32->reset_gpio, 0); | ||
564 | |||
565 | /* remove power */ | ||
566 | regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies), | ||
567 | cs35l32->supplies); | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static int cs35l32_runtime_resume(struct device *dev) | ||
573 | { | ||
574 | struct cs35l32_private *cs35l32 = dev_get_drvdata(dev); | ||
575 | int ret; | ||
576 | |||
577 | /* Enable power */ | ||
578 | ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies), | ||
579 | cs35l32->supplies); | ||
580 | if (ret != 0) { | ||
581 | dev_err(dev, "Failed to enable supplies: %d\n", | ||
582 | ret); | ||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | if (cs35l32->reset_gpio) | ||
587 | gpiod_set_value_cansleep(cs35l32->reset_gpio, 1); | ||
588 | |||
589 | regcache_cache_only(cs35l32->regmap, false); | ||
590 | regcache_sync(cs35l32->regmap); | ||
591 | |||
592 | return 0; | ||
593 | } | ||
594 | #endif | ||
595 | |||
596 | static const struct dev_pm_ops cs35l32_runtime_pm = { | ||
597 | SET_RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume, | ||
598 | NULL) | ||
599 | }; | ||
600 | |||
601 | static const struct of_device_id cs35l32_of_match[] = { | ||
602 | { .compatible = "cirrus,cs35l32", }, | ||
603 | {}, | ||
604 | }; | ||
605 | MODULE_DEVICE_TABLE(of, cs35l32_of_match); | ||
606 | |||
607 | |||
608 | static const struct i2c_device_id cs35l32_id[] = { | ||
609 | {"cs35l32", 0}, | ||
610 | {} | ||
611 | }; | ||
612 | |||
613 | MODULE_DEVICE_TABLE(i2c, cs35l32_id); | ||
614 | |||
615 | static struct i2c_driver cs35l32_i2c_driver = { | ||
616 | .driver = { | ||
617 | .name = "cs35l32", | ||
618 | .owner = THIS_MODULE, | ||
619 | .pm = &cs35l32_runtime_pm, | ||
620 | .of_match_table = cs35l32_of_match, | ||
621 | }, | ||
622 | .id_table = cs35l32_id, | ||
623 | .probe = cs35l32_i2c_probe, | ||
624 | .remove = cs35l32_i2c_remove, | ||
625 | }; | ||
626 | |||
627 | module_i2c_driver(cs35l32_i2c_driver); | ||
628 | |||
629 | MODULE_DESCRIPTION("ASoC CS35L32 driver"); | ||
630 | MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); | ||
631 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs35l32.h b/sound/soc/codecs/cs35l32.h new file mode 100644 index 000000000000..31ab804a22bc --- /dev/null +++ b/sound/soc/codecs/cs35l32.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * cs35l32.h -- CS35L32 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2014 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __CS35L32_H__ | ||
15 | #define __CS35L32_H__ | ||
16 | |||
17 | struct cs35l32_platform_data { | ||
18 | /* Low Battery Threshold */ | ||
19 | unsigned int batt_thresh; | ||
20 | /* Low Battery Recovery */ | ||
21 | unsigned int batt_recov; | ||
22 | /* LED Current Management*/ | ||
23 | unsigned int led_mng; | ||
24 | /* Audio Gain w/ LED */ | ||
25 | unsigned int audiogain_mng; | ||
26 | /* Boost Management */ | ||
27 | unsigned int boost_mng; | ||
28 | /* Data CFG for DUAL device */ | ||
29 | unsigned int sdout_datacfg; | ||
30 | /* SDOUT Sharing */ | ||
31 | unsigned int sdout_share; | ||
32 | }; | ||
33 | |||
34 | #define CS35L32_CHIP_ID 0x00035A32 | ||
35 | #define CS35L32_DEVID_AB 0x01 /* Device ID A & B [RO] */ | ||
36 | #define CS35L32_DEVID_CD 0x02 /* Device ID C & D [RO] */ | ||
37 | #define CS35L32_DEVID_E 0x03 /* Device ID E [RO] */ | ||
38 | #define CS35L32_FAB_ID 0x04 /* Fab ID [RO] */ | ||
39 | #define CS35L32_REV_ID 0x05 /* Revision ID [RO] */ | ||
40 | #define CS35L32_PWRCTL1 0x06 /* Power Ctl 1 */ | ||
41 | #define CS35L32_PWRCTL2 0x07 /* Power Ctl 2 */ | ||
42 | #define CS35L32_CLK_CTL 0x08 /* Clock Ctl */ | ||
43 | #define CS35L32_BATT_THRESHOLD 0x09 /* Low Battery Threshold */ | ||
44 | #define CS35L32_VMON 0x0A /* Voltage Monitor [RO] */ | ||
45 | #define CS35L32_BST_CPCP_CTL 0x0B /* Conv Peak Curr Protection CTL */ | ||
46 | #define CS35L32_IMON_SCALING 0x0C /* IMON Scaling */ | ||
47 | #define CS35L32_AUDIO_LED_MNGR 0x0D /* Audio/LED Pwr Manager */ | ||
48 | #define CS35L32_ADSP_CTL 0x0F /* Serial Port Control */ | ||
49 | #define CS35L32_CLASSD_CTL 0x10 /* Class D Amp CTL */ | ||
50 | #define CS35L32_PROTECT_CTL 0x11 /* Protection Release CTL */ | ||
51 | #define CS35L32_INT_MASK_1 0x12 /* Interrupt Mask 1 */ | ||
52 | #define CS35L32_INT_MASK_2 0x13 /* Interrupt Mask 2 */ | ||
53 | #define CS35L32_INT_MASK_3 0x14 /* Interrupt Mask 3 */ | ||
54 | #define CS35L32_INT_STATUS_1 0x15 /* Interrupt Status 1 [RO] */ | ||
55 | #define CS35L32_INT_STATUS_2 0x16 /* Interrupt Status 2 [RO] */ | ||
56 | #define CS35L32_INT_STATUS_3 0x17 /* Interrupt Status 3 [RO] */ | ||
57 | #define CS35L32_LED_STATUS 0x18 /* LED Lighting Status [RO] */ | ||
58 | #define CS35L32_FLASH_MODE 0x19 /* LED Flash Mode Current */ | ||
59 | #define CS35L32_MOVIE_MODE 0x1A /* LED Movie Mode Current */ | ||
60 | #define CS35L32_FLASH_TIMER 0x1B /* LED Flash Timer */ | ||
61 | #define CS35L32_FLASH_INHIBIT 0x1C /* LED Flash Inhibit Current */ | ||
62 | #define CS35L32_MAX_REGISTER 0x1C | ||
63 | |||
64 | #define CS35L32_MCLK_DIV2 0x01 | ||
65 | #define CS35L32_MCLK_RATIO 0x01 | ||
66 | #define CS35L32_MCLKDIS 0x80 | ||
67 | #define CS35L32_PDN_ALL 0x01 | ||
68 | #define CS35L32_PDN_AMP 0x80 | ||
69 | #define CS35L32_PDN_BOOST 0x04 | ||
70 | #define CS35L32_PDN_IMON 0x40 | ||
71 | #define CS35L32_PDN_VMON 0x80 | ||
72 | #define CS35L32_PDN_VPMON 0x20 | ||
73 | #define CS35L32_PDN_ADSP 0x08 | ||
74 | |||
75 | #define CS35L32_MCLK_DIV2_MASK 0x40 | ||
76 | #define CS35L32_MCLK_RATIO_MASK 0x01 | ||
77 | #define CS35L32_MCLK_MASK 0x41 | ||
78 | #define CS35L32_ADSP_MASTER_MASK 0x40 | ||
79 | #define CS35L32_BOOST_MASK 0x03 | ||
80 | #define CS35L32_GAIN_MGR_MASK 0x08 | ||
81 | #define CS35L32_ADSP_SHARE_MASK 0x08 | ||
82 | #define CS35L32_ADSP_DATACFG_MASK 0x30 | ||
83 | #define CS35L32_SDOUT_3ST 0x80 | ||
84 | #define CS35L32_BATT_REC_MASK 0x0E | ||
85 | #define CS35L32_BATT_THRESH_MASK 0x30 | ||
86 | |||
87 | #define CS35L32_RATES (SNDRV_PCM_RATE_48000) | ||
88 | #define CS35L32_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
89 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
90 | SNDRV_PCM_FMTBIT_S32_LE) | ||
91 | |||
92 | |||
93 | #endif | ||
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 98523209f739..4fdd47d700e3 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c | |||
@@ -77,6 +77,7 @@ static bool cs4265_readable_register(struct device *dev, unsigned int reg) | |||
77 | case CS4265_INT_MASK: | 77 | case CS4265_INT_MASK: |
78 | case CS4265_STATUS_MODE_MSB: | 78 | case CS4265_STATUS_MODE_MSB: |
79 | case CS4265_STATUS_MODE_LSB: | 79 | case CS4265_STATUS_MODE_LSB: |
80 | case CS4265_CHIP_ID: | ||
80 | return true; | 81 | return true; |
81 | default: | 82 | default: |
82 | return false; | 83 | return false; |
@@ -458,12 +459,12 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, | |||
458 | if (params_width(params) == 16) { | 459 | if (params_width(params) == 16) { |
459 | snd_soc_update_bits(codec, CS4265_DAC_CTL, | 460 | snd_soc_update_bits(codec, CS4265_DAC_CTL, |
460 | CS4265_DAC_CTL_DIF, (1 << 5)); | 461 | CS4265_DAC_CTL_DIF, (1 << 5)); |
461 | snd_soc_update_bits(codec, CS4265_ADC_CTL, | 462 | snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, |
462 | CS4265_SPDIF_CTL2_DIF, (1 << 7)); | 463 | CS4265_SPDIF_CTL2_DIF, (1 << 7)); |
463 | } else { | 464 | } else { |
464 | snd_soc_update_bits(codec, CS4265_DAC_CTL, | 465 | snd_soc_update_bits(codec, CS4265_DAC_CTL, |
465 | CS4265_DAC_CTL_DIF, (3 << 5)); | 466 | CS4265_DAC_CTL_DIF, (3 << 5)); |
466 | snd_soc_update_bits(codec, CS4265_ADC_CTL, | 467 | snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, |
467 | CS4265_SPDIF_CTL2_DIF, (1 << 7)); | 468 | CS4265_SPDIF_CTL2_DIF, (1 << 7)); |
468 | } | 469 | } |
469 | break; | 470 | break; |
@@ -472,7 +473,7 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, | |||
472 | CS4265_DAC_CTL_DIF, 0); | 473 | CS4265_DAC_CTL_DIF, 0); |
473 | snd_soc_update_bits(codec, CS4265_ADC_CTL, | 474 | snd_soc_update_bits(codec, CS4265_ADC_CTL, |
474 | CS4265_ADC_DIF, 0); | 475 | CS4265_ADC_DIF, 0); |
475 | snd_soc_update_bits(codec, CS4265_ADC_CTL, | 476 | snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, |
476 | CS4265_SPDIF_CTL2_DIF, (1 << 6)); | 477 | CS4265_SPDIF_CTL2_DIF, (1 << 6)); |
477 | 478 | ||
478 | break; | 479 | break; |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 969167d8b71e..35fbef743fbe 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -176,9 +176,9 @@ static bool cs42l52_volatile_register(struct device *dev, unsigned int reg) | |||
176 | case CS42L52_BATT_LEVEL: | 176 | case CS42L52_BATT_LEVEL: |
177 | case CS42L52_SPK_STATUS: | 177 | case CS42L52_SPK_STATUS: |
178 | case CS42L52_CHARGE_PUMP: | 178 | case CS42L52_CHARGE_PUMP: |
179 | return 1; | 179 | return true; |
180 | default: | 180 | default: |
181 | return 0; | 181 | return false; |
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
@@ -946,20 +946,6 @@ static struct snd_soc_dai_driver cs42l52_dai = { | |||
946 | .ops = &cs42l52_ops, | 946 | .ops = &cs42l52_ops, |
947 | }; | 947 | }; |
948 | 948 | ||
949 | static int cs42l52_suspend(struct snd_soc_codec *codec) | ||
950 | { | ||
951 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int cs42l52_resume(struct snd_soc_codec *codec) | ||
957 | { | ||
958 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
959 | |||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | static int beep_rates[] = { | 949 | static int beep_rates[] = { |
964 | 261, 522, 585, 667, 706, 774, 889, 1000, | 950 | 261, 522, 585, 667, 706, 774, 889, 1000, |
965 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 | 951 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 |
@@ -1104,8 +1090,6 @@ static int cs42l52_probe(struct snd_soc_codec *codec) | |||
1104 | 1090 | ||
1105 | cs42l52_init_beep(codec); | 1091 | cs42l52_init_beep(codec); |
1106 | 1092 | ||
1107 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1108 | |||
1109 | cs42l52->sysclk = CS42L52_DEFAULT_CLK; | 1093 | cs42l52->sysclk = CS42L52_DEFAULT_CLK; |
1110 | cs42l52->config.format = CS42L52_DEFAULT_FORMAT; | 1094 | cs42l52->config.format = CS42L52_DEFAULT_FORMAT; |
1111 | 1095 | ||
@@ -1115,7 +1099,6 @@ static int cs42l52_probe(struct snd_soc_codec *codec) | |||
1115 | static int cs42l52_remove(struct snd_soc_codec *codec) | 1099 | static int cs42l52_remove(struct snd_soc_codec *codec) |
1116 | { | 1100 | { |
1117 | cs42l52_free_beep(codec); | 1101 | cs42l52_free_beep(codec); |
1118 | cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1119 | 1102 | ||
1120 | return 0; | 1103 | return 0; |
1121 | } | 1104 | } |
@@ -1123,9 +1106,8 @@ static int cs42l52_remove(struct snd_soc_codec *codec) | |||
1123 | static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { | 1106 | static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { |
1124 | .probe = cs42l52_probe, | 1107 | .probe = cs42l52_probe, |
1125 | .remove = cs42l52_remove, | 1108 | .remove = cs42l52_remove, |
1126 | .suspend = cs42l52_suspend, | ||
1127 | .resume = cs42l52_resume, | ||
1128 | .set_bias_level = cs42l52_set_bias_level, | 1109 | .set_bias_level = cs42l52_set_bias_level, |
1110 | .suspend_bias_off = true, | ||
1129 | 1111 | ||
1130 | .dapm_widgets = cs42l52_dapm_widgets, | 1112 | .dapm_widgets = cs42l52_dapm_widgets, |
1131 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), | 1113 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), |
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index c766a5a9ce80..2ddc7ac10ad7 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c | |||
@@ -171,9 +171,9 @@ static bool cs42l56_volatile_register(struct device *dev, unsigned int reg) | |||
171 | { | 171 | { |
172 | switch (reg) { | 172 | switch (reg) { |
173 | case CS42L56_INT_STATUS: | 173 | case CS42L56_INT_STATUS: |
174 | return 1; | 174 | return true; |
175 | default: | 175 | default: |
176 | return 0; | 176 | return false; |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
@@ -1016,20 +1016,6 @@ static struct snd_soc_dai_driver cs42l56_dai = { | |||
1016 | .ops = &cs42l56_ops, | 1016 | .ops = &cs42l56_ops, |
1017 | }; | 1017 | }; |
1018 | 1018 | ||
1019 | static int cs42l56_suspend(struct snd_soc_codec *codec) | ||
1020 | { | ||
1021 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static int cs42l56_resume(struct snd_soc_codec *codec) | ||
1027 | { | ||
1028 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1029 | |||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | static int beep_freq[] = { | 1019 | static int beep_freq[] = { |
1034 | 261, 522, 585, 667, 706, 774, 889, 1000, | 1020 | 261, 522, 585, 667, 706, 774, 889, 1000, |
1035 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 | 1021 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 |
@@ -1168,18 +1154,12 @@ static int cs42l56_probe(struct snd_soc_codec *codec) | |||
1168 | { | 1154 | { |
1169 | cs42l56_init_beep(codec); | 1155 | cs42l56_init_beep(codec); |
1170 | 1156 | ||
1171 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1172 | |||
1173 | return 0; | 1157 | return 0; |
1174 | } | 1158 | } |
1175 | 1159 | ||
1176 | static int cs42l56_remove(struct snd_soc_codec *codec) | 1160 | static int cs42l56_remove(struct snd_soc_codec *codec) |
1177 | { | 1161 | { |
1178 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
1179 | |||
1180 | cs42l56_free_beep(codec); | 1162 | cs42l56_free_beep(codec); |
1181 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1182 | regulator_bulk_free(ARRAY_SIZE(cs42l56->supplies), cs42l56->supplies); | ||
1183 | 1163 | ||
1184 | return 0; | 1164 | return 0; |
1185 | } | 1165 | } |
@@ -1187,9 +1167,8 @@ static int cs42l56_remove(struct snd_soc_codec *codec) | |||
1187 | static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { | 1167 | static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { |
1188 | .probe = cs42l56_probe, | 1168 | .probe = cs42l56_probe, |
1189 | .remove = cs42l56_remove, | 1169 | .remove = cs42l56_remove, |
1190 | .suspend = cs42l56_suspend, | ||
1191 | .resume = cs42l56_resume, | ||
1192 | .set_bias_level = cs42l56_set_bias_level, | 1170 | .set_bias_level = cs42l56_set_bias_level, |
1171 | .suspend_bias_off = true, | ||
1193 | 1172 | ||
1194 | .dapm_widgets = cs42l56_dapm_widgets, | 1173 | .dapm_widgets = cs42l56_dapm_widgets, |
1195 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), | 1174 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 0e7b9eb2ba61..2f8b94683e83 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1330,25 +1330,10 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1330 | } | 1330 | } |
1331 | }; | 1331 | }; |
1332 | 1332 | ||
1333 | static int cs42l73_suspend(struct snd_soc_codec *codec) | ||
1334 | { | ||
1335 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1336 | |||
1337 | return 0; | ||
1338 | } | ||
1339 | |||
1340 | static int cs42l73_resume(struct snd_soc_codec *codec) | ||
1341 | { | ||
1342 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1343 | return 0; | ||
1344 | } | ||
1345 | |||
1346 | static int cs42l73_probe(struct snd_soc_codec *codec) | 1333 | static int cs42l73_probe(struct snd_soc_codec *codec) |
1347 | { | 1334 | { |
1348 | struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); | 1335 | struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); |
1349 | 1336 | ||
1350 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1351 | |||
1352 | /* Set Charge Pump Frequency */ | 1337 | /* Set Charge Pump Frequency */ |
1353 | if (cs42l73->pdata.chgfreq) | 1338 | if (cs42l73->pdata.chgfreq) |
1354 | snd_soc_update_bits(codec, CS42L73_CPFCHC, | 1339 | snd_soc_update_bits(codec, CS42L73_CPFCHC, |
@@ -1362,18 +1347,10 @@ static int cs42l73_probe(struct snd_soc_codec *codec) | |||
1362 | return 0; | 1347 | return 0; |
1363 | } | 1348 | } |
1364 | 1349 | ||
1365 | static int cs42l73_remove(struct snd_soc_codec *codec) | ||
1366 | { | ||
1367 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1368 | return 0; | ||
1369 | } | ||
1370 | |||
1371 | static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { | 1350 | static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { |
1372 | .probe = cs42l73_probe, | 1351 | .probe = cs42l73_probe, |
1373 | .remove = cs42l73_remove, | ||
1374 | .suspend = cs42l73_suspend, | ||
1375 | .resume = cs42l73_resume, | ||
1376 | .set_bias_level = cs42l73_set_bias_level, | 1352 | .set_bias_level = cs42l73_set_bias_level, |
1353 | .suspend_bias_off = true, | ||
1377 | 1354 | ||
1378 | .dapm_widgets = cs42l73_dapm_widgets, | 1355 | .dapm_widgets = cs42l73_dapm_widgets, |
1379 | .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), | 1356 | .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 2fae31cb0067..61b2f9a2eef1 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | struct da732x_priv { | 36 | struct da732x_priv { |
37 | struct regmap *regmap; | 37 | struct regmap *regmap; |
38 | struct snd_soc_codec *codec; | ||
39 | 38 | ||
40 | unsigned int sysclk; | 39 | unsigned int sysclk; |
41 | bool pll_en; | 40 | bool pll_en; |
@@ -217,7 +216,7 @@ static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state) | |||
217 | snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS); | 216 | snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS); |
218 | break; | 217 | break; |
219 | default: | 218 | default: |
220 | pr_err(KERN_ERR "Wrong charge pump state\n"); | 219 | pr_err("Wrong charge pump state\n"); |
221 | break; | 220 | break; |
222 | } | 221 | } |
223 | } | 222 | } |
@@ -1508,31 +1507,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, | |||
1508 | return 0; | 1507 | return 0; |
1509 | } | 1508 | } |
1510 | 1509 | ||
1511 | static int da732x_probe(struct snd_soc_codec *codec) | ||
1512 | { | ||
1513 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); | ||
1514 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
1515 | |||
1516 | da732x->codec = codec; | ||
1517 | |||
1518 | dapm->idle_bias_off = false; | ||
1519 | |||
1520 | da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1521 | |||
1522 | return 0; | ||
1523 | } | ||
1524 | |||
1525 | static int da732x_remove(struct snd_soc_codec *codec) | ||
1526 | { | ||
1527 | |||
1528 | da732x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1529 | |||
1530 | return 0; | ||
1531 | } | ||
1532 | |||
1533 | static struct snd_soc_codec_driver soc_codec_dev_da732x = { | 1510 | static struct snd_soc_codec_driver soc_codec_dev_da732x = { |
1534 | .probe = da732x_probe, | ||
1535 | .remove = da732x_remove, | ||
1536 | .set_bias_level = da732x_set_bias_level, | 1511 | .set_bias_level = da732x_set_bias_level, |
1537 | .controls = da732x_snd_controls, | 1512 | .controls = da732x_snd_controls, |
1538 | .num_controls = ARRAY_SIZE(da732x_snd_controls), | 1513 | .num_controls = ARRAY_SIZE(da732x_snd_controls), |
diff --git a/sound/soc/codecs/es8328-i2c.c b/sound/soc/codecs/es8328-i2c.c new file mode 100644 index 000000000000..aae410d122ee --- /dev/null +++ b/sound/soc/codecs/es8328-i2c.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * es8328-i2c.c -- ES8328 ALSA SoC I2C Audio driver | ||
3 | * | ||
4 | * Copyright 2014 Sutajio Ko-Usagi PTE LTD | ||
5 | * | ||
6 | * Author: Sean Cross <xobs@kosagi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/regmap.h> | ||
16 | |||
17 | #include <sound/soc.h> | ||
18 | |||
19 | #include "es8328.h" | ||
20 | |||
21 | static const struct i2c_device_id es8328_id[] = { | ||
22 | { "everest,es8328", 0 }, | ||
23 | { } | ||
24 | }; | ||
25 | MODULE_DEVICE_TABLE(i2c, es8328_id); | ||
26 | |||
27 | static const struct of_device_id es8328_of_match[] = { | ||
28 | { .compatible = "everest,es8328", }, | ||
29 | { } | ||
30 | }; | ||
31 | MODULE_DEVICE_TABLE(of, es8328_of_match); | ||
32 | |||
33 | static int es8328_i2c_probe(struct i2c_client *i2c, | ||
34 | const struct i2c_device_id *id) | ||
35 | { | ||
36 | return es8328_probe(&i2c->dev, | ||
37 | devm_regmap_init_i2c(i2c, &es8328_regmap_config)); | ||
38 | } | ||
39 | |||
40 | static int es8328_i2c_remove(struct i2c_client *i2c) | ||
41 | { | ||
42 | snd_soc_unregister_codec(&i2c->dev); | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static struct i2c_driver es8328_i2c_driver = { | ||
47 | .driver = { | ||
48 | .name = "es8328", | ||
49 | .of_match_table = es8328_of_match, | ||
50 | }, | ||
51 | .probe = es8328_i2c_probe, | ||
52 | .remove = es8328_i2c_remove, | ||
53 | .id_table = es8328_id, | ||
54 | }; | ||
55 | |||
56 | module_i2c_driver(es8328_i2c_driver); | ||
57 | |||
58 | MODULE_DESCRIPTION("ASoC ES8328 audio CODEC I2C driver"); | ||
59 | MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); | ||
60 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/es8328-spi.c b/sound/soc/codecs/es8328-spi.c new file mode 100644 index 000000000000..8fbd935e1c76 --- /dev/null +++ b/sound/soc/codecs/es8328-spi.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * es8328.c -- ES8328 ALSA SoC SPI Audio driver | ||
3 | * | ||
4 | * Copyright 2014 Sutajio Ko-Usagi PTE LTD | ||
5 | * | ||
6 | * Author: Sean Cross <xobs@kosagi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/regmap.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | #include <sound/soc.h> | ||
17 | #include "es8328.h" | ||
18 | |||
19 | static const struct of_device_id es8328_of_match[] = { | ||
20 | { .compatible = "everest,es8328", }, | ||
21 | { } | ||
22 | }; | ||
23 | MODULE_DEVICE_TABLE(of, es8328_of_match); | ||
24 | |||
25 | static int es8328_spi_probe(struct spi_device *spi) | ||
26 | { | ||
27 | return es8328_probe(&spi->dev, | ||
28 | devm_regmap_init_spi(spi, &es8328_regmap_config)); | ||
29 | } | ||
30 | |||
31 | static int es8328_spi_remove(struct spi_device *spi) | ||
32 | { | ||
33 | snd_soc_unregister_codec(&spi->dev); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static struct spi_driver es8328_spi_driver = { | ||
38 | .driver = { | ||
39 | .name = "es8328", | ||
40 | .of_match_table = es8328_of_match, | ||
41 | }, | ||
42 | .probe = es8328_spi_probe, | ||
43 | .remove = es8328_spi_remove, | ||
44 | }; | ||
45 | |||
46 | module_spi_driver(es8328_spi_driver); | ||
47 | MODULE_DESCRIPTION("ASoC ES8328 audio CODEC SPI driver"); | ||
48 | MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); | ||
49 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c new file mode 100644 index 000000000000..f27325155ace --- /dev/null +++ b/sound/soc/codecs/es8328.c | |||
@@ -0,0 +1,756 @@ | |||
1 | /* | ||
2 | * es8328.c -- ES8328 ALSA SoC Audio driver | ||
3 | * | ||
4 | * Copyright 2014 Sutajio Ko-Usagi PTE LTD | ||
5 | * | ||
6 | * Author: Sean Cross <xobs@kosagi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/of_device.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/regulator/consumer.h> | ||
21 | #include <sound/core.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/tlv.h> | ||
27 | #include "es8328.h" | ||
28 | |||
29 | #define ES8328_SYSCLK_RATE_1X 11289600 | ||
30 | #define ES8328_SYSCLK_RATE_2X 22579200 | ||
31 | |||
32 | /* Run the codec at 22.5792 or 11.2896 MHz to support these rates */ | ||
33 | static struct { | ||
34 | int rate; | ||
35 | u8 ratio; | ||
36 | } mclk_ratios[] = { | ||
37 | { 8000, 9 }, | ||
38 | {11025, 7 }, | ||
39 | {22050, 4 }, | ||
40 | {44100, 2 }, | ||
41 | }; | ||
42 | |||
43 | /* regulator supplies for sgtl5000, VDDD is an optional external supply */ | ||
44 | enum sgtl5000_regulator_supplies { | ||
45 | DVDD, | ||
46 | AVDD, | ||
47 | PVDD, | ||
48 | HPVDD, | ||
49 | ES8328_SUPPLY_NUM | ||
50 | }; | ||
51 | |||
52 | /* vddd is optional supply */ | ||
53 | static const char * const supply_names[ES8328_SUPPLY_NUM] = { | ||
54 | "DVDD", | ||
55 | "AVDD", | ||
56 | "PVDD", | ||
57 | "HPVDD", | ||
58 | }; | ||
59 | |||
60 | #define ES8328_RATES (SNDRV_PCM_RATE_44100 | \ | ||
61 | SNDRV_PCM_RATE_22050 | \ | ||
62 | SNDRV_PCM_RATE_11025) | ||
63 | #define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) | ||
64 | |||
65 | struct es8328_priv { | ||
66 | struct regmap *regmap; | ||
67 | struct clk *clk; | ||
68 | int playback_fs; | ||
69 | bool deemph; | ||
70 | struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; | ||
71 | }; | ||
72 | |||
73 | /* | ||
74 | * ES8328 Controls | ||
75 | */ | ||
76 | |||
77 | static const char * const adcpol_txt[] = {"Normal", "L Invert", "R Invert", | ||
78 | "L + R Invert"}; | ||
79 | static SOC_ENUM_SINGLE_DECL(adcpol, | ||
80 | ES8328_ADCCONTROL6, 6, adcpol_txt); | ||
81 | |||
82 | static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); | ||
83 | static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0); | ||
84 | static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); | ||
85 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | ||
86 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); | ||
87 | |||
88 | static const int deemph_settings[] = { 0, 32000, 44100, 48000 }; | ||
89 | |||
90 | static int es8328_set_deemph(struct snd_soc_codec *codec) | ||
91 | { | ||
92 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | ||
93 | int val, i, best; | ||
94 | |||
95 | /* | ||
96 | * If we're using deemphasis select the nearest available sample | ||
97 | * rate. | ||
98 | */ | ||
99 | if (es8328->deemph) { | ||
100 | best = 1; | ||
101 | for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) { | ||
102 | if (abs(deemph_settings[i] - es8328->playback_fs) < | ||
103 | abs(deemph_settings[best] - es8328->playback_fs)) | ||
104 | best = i; | ||
105 | } | ||
106 | |||
107 | val = best << 1; | ||
108 | } else { | ||
109 | val = 0; | ||
110 | } | ||
111 | |||
112 | dev_dbg(codec->dev, "Set deemphasis %d\n", val); | ||
113 | |||
114 | return snd_soc_update_bits(codec, ES8328_DACCONTROL6, 0x6, val); | ||
115 | } | ||
116 | |||
117 | static int es8328_get_deemph(struct snd_kcontrol *kcontrol, | ||
118 | struct snd_ctl_elem_value *ucontrol) | ||
119 | { | ||
120 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
121 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | ||
122 | |||
123 | ucontrol->value.enumerated.item[0] = es8328->deemph; | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int es8328_put_deemph(struct snd_kcontrol *kcontrol, | ||
128 | struct snd_ctl_elem_value *ucontrol) | ||
129 | { | ||
130 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
131 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | ||
132 | int deemph = ucontrol->value.enumerated.item[0]; | ||
133 | int ret; | ||
134 | |||
135 | if (deemph > 1) | ||
136 | return -EINVAL; | ||
137 | |||
138 | ret = es8328_set_deemph(codec); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | |||
142 | es8328->deemph = deemph; | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | |||
148 | |||
149 | static const struct snd_kcontrol_new es8328_snd_controls[] = { | ||
150 | SOC_DOUBLE_R_TLV("Capture Digital Volume", | ||
151 | ES8328_ADCCONTROL8, ES8328_ADCCONTROL9, | ||
152 | 0, 0xc0, 1, dac_adc_tlv), | ||
153 | SOC_SINGLE("Capture ZC Switch", ES8328_ADCCONTROL7, 6, 1, 0), | ||
154 | |||
155 | SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, | ||
156 | es8328_get_deemph, es8328_put_deemph), | ||
157 | |||
158 | SOC_ENUM("Capture Polarity", adcpol), | ||
159 | |||
160 | SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", | ||
161 | ES8328_DACCONTROL17, 3, 7, 1, bypass_tlv), | ||
162 | SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", | ||
163 | ES8328_DACCONTROL19, 3, 7, 1, bypass_tlv), | ||
164 | SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", | ||
165 | ES8328_DACCONTROL18, 3, 7, 1, bypass_tlv), | ||
166 | SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", | ||
167 | ES8328_DACCONTROL20, 3, 7, 1, bypass_tlv), | ||
168 | |||
169 | SOC_DOUBLE_R_TLV("PCM Volume", | ||
170 | ES8328_LDACVOL, ES8328_RDACVOL, | ||
171 | 0, ES8328_DACVOL_MAX, 1, dac_adc_tlv), | ||
172 | |||
173 | SOC_DOUBLE_R_TLV("Output 1 Playback Volume", | ||
174 | ES8328_LOUT1VOL, ES8328_ROUT1VOL, | ||
175 | 0, ES8328_OUT1VOL_MAX, 0, play_tlv), | ||
176 | |||
177 | SOC_DOUBLE_R_TLV("Output 2 Playback Volume", | ||
178 | ES8328_LOUT2VOL, ES8328_ROUT2VOL, | ||
179 | 0, ES8328_OUT2VOL_MAX, 0, play_tlv), | ||
180 | |||
181 | SOC_DOUBLE_TLV("Mic PGA Volume", ES8328_ADCCONTROL1, | ||
182 | 4, 0, 8, 0, mic_tlv), | ||
183 | }; | ||
184 | |||
185 | /* | ||
186 | * DAPM Controls | ||
187 | */ | ||
188 | |||
189 | static const char * const es8328_line_texts[] = { | ||
190 | "Line 1", "Line 2", "PGA", "Differential"}; | ||
191 | |||
192 | static const struct soc_enum es8328_lline_enum = | ||
193 | SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 3, | ||
194 | ARRAY_SIZE(es8328_line_texts), | ||
195 | es8328_line_texts); | ||
196 | static const struct snd_kcontrol_new es8328_left_line_controls = | ||
197 | SOC_DAPM_ENUM("Route", es8328_lline_enum); | ||
198 | |||
199 | static const struct soc_enum es8328_rline_enum = | ||
200 | SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 0, | ||
201 | ARRAY_SIZE(es8328_line_texts), | ||
202 | es8328_line_texts); | ||
203 | static const struct snd_kcontrol_new es8328_right_line_controls = | ||
204 | SOC_DAPM_ENUM("Route", es8328_lline_enum); | ||
205 | |||
206 | /* Left Mixer */ | ||
207 | static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { | ||
208 | SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 8, 1, 0), | ||
209 | SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 7, 1, 0), | ||
210 | SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 8, 1, 0), | ||
211 | SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 7, 1, 0), | ||
212 | }; | ||
213 | |||
214 | /* Right Mixer */ | ||
215 | static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { | ||
216 | SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 8, 1, 0), | ||
217 | SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 7, 1, 0), | ||
218 | SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 8, 1, 0), | ||
219 | SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 7, 1, 0), | ||
220 | }; | ||
221 | |||
222 | static const char * const es8328_pga_sel[] = { | ||
223 | "Line 1", "Line 2", "Line 3", "Differential"}; | ||
224 | |||
225 | /* Left PGA Mux */ | ||
226 | static const struct soc_enum es8328_lpga_enum = | ||
227 | SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 6, | ||
228 | ARRAY_SIZE(es8328_pga_sel), | ||
229 | es8328_pga_sel); | ||
230 | static const struct snd_kcontrol_new es8328_left_pga_controls = | ||
231 | SOC_DAPM_ENUM("Route", es8328_lpga_enum); | ||
232 | |||
233 | /* Right PGA Mux */ | ||
234 | static const struct soc_enum es8328_rpga_enum = | ||
235 | SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 4, | ||
236 | ARRAY_SIZE(es8328_pga_sel), | ||
237 | es8328_pga_sel); | ||
238 | static const struct snd_kcontrol_new es8328_right_pga_controls = | ||
239 | SOC_DAPM_ENUM("Route", es8328_rpga_enum); | ||
240 | |||
241 | /* Differential Mux */ | ||
242 | static const char * const es8328_diff_sel[] = {"Line 1", "Line 2"}; | ||
243 | static SOC_ENUM_SINGLE_DECL(diffmux, | ||
244 | ES8328_ADCCONTROL3, 7, es8328_diff_sel); | ||
245 | static const struct snd_kcontrol_new es8328_diffmux_controls = | ||
246 | SOC_DAPM_ENUM("Route", diffmux); | ||
247 | |||
248 | /* Mono ADC Mux */ | ||
249 | static const char * const es8328_mono_mux[] = {"Stereo", "Mono (Left)", | ||
250 | "Mono (Right)", "Digital Mono"}; | ||
251 | static SOC_ENUM_SINGLE_DECL(monomux, | ||
252 | ES8328_ADCCONTROL3, 3, es8328_mono_mux); | ||
253 | static const struct snd_kcontrol_new es8328_monomux_controls = | ||
254 | SOC_DAPM_ENUM("Route", monomux); | ||
255 | |||
256 | static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { | ||
257 | SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, | ||
258 | &es8328_diffmux_controls), | ||
259 | SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, | ||
260 | &es8328_monomux_controls), | ||
261 | SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, | ||
262 | &es8328_monomux_controls), | ||
263 | |||
264 | SND_SOC_DAPM_MUX("Left PGA Mux", ES8328_ADCPOWER, | ||
265 | ES8328_ADCPOWER_AINL_OFF, 1, | ||
266 | &es8328_left_pga_controls), | ||
267 | SND_SOC_DAPM_MUX("Right PGA Mux", ES8328_ADCPOWER, | ||
268 | ES8328_ADCPOWER_AINR_OFF, 1, | ||
269 | &es8328_right_pga_controls), | ||
270 | |||
271 | SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, | ||
272 | &es8328_left_line_controls), | ||
273 | SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, | ||
274 | &es8328_right_line_controls), | ||
275 | |||
276 | SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8328_ADCPOWER, | ||
277 | ES8328_ADCPOWER_ADCR_OFF, 1), | ||
278 | SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ES8328_ADCPOWER, | ||
279 | ES8328_ADCPOWER_ADCL_OFF, 1), | ||
280 | |||
281 | SND_SOC_DAPM_SUPPLY("Mic Bias", ES8328_ADCPOWER, | ||
282 | ES8328_ADCPOWER_MIC_BIAS_OFF, 1, NULL, 0), | ||
283 | SND_SOC_DAPM_SUPPLY("Mic Bias Gen", ES8328_ADCPOWER, | ||
284 | ES8328_ADCPOWER_ADC_BIAS_GEN_OFF, 1, NULL, 0), | ||
285 | |||
286 | SND_SOC_DAPM_SUPPLY("DAC STM", ES8328_CHIPPOWER, | ||
287 | ES8328_CHIPPOWER_DACSTM_RESET, 1, NULL, 0), | ||
288 | SND_SOC_DAPM_SUPPLY("ADC STM", ES8328_CHIPPOWER, | ||
289 | ES8328_CHIPPOWER_ADCSTM_RESET, 1, NULL, 0), | ||
290 | |||
291 | SND_SOC_DAPM_SUPPLY("DAC DIG", ES8328_CHIPPOWER, | ||
292 | ES8328_CHIPPOWER_DACDIG_OFF, 1, NULL, 0), | ||
293 | SND_SOC_DAPM_SUPPLY("ADC DIG", ES8328_CHIPPOWER, | ||
294 | ES8328_CHIPPOWER_ADCDIG_OFF, 1, NULL, 0), | ||
295 | |||
296 | SND_SOC_DAPM_SUPPLY("DAC DLL", ES8328_CHIPPOWER, | ||
297 | ES8328_CHIPPOWER_DACDLL_OFF, 1, NULL, 0), | ||
298 | SND_SOC_DAPM_SUPPLY("ADC DLL", ES8328_CHIPPOWER, | ||
299 | ES8328_CHIPPOWER_ADCDLL_OFF, 1, NULL, 0), | ||
300 | |||
301 | SND_SOC_DAPM_SUPPLY("ADC Vref", ES8328_CHIPPOWER, | ||
302 | ES8328_CHIPPOWER_ADCVREF_OFF, 1, NULL, 0), | ||
303 | SND_SOC_DAPM_SUPPLY("DAC Vref", ES8328_CHIPPOWER, | ||
304 | ES8328_CHIPPOWER_DACVREF_OFF, 1, NULL, 0), | ||
305 | |||
306 | SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ES8328_DACPOWER, | ||
307 | ES8328_DACPOWER_RDAC_OFF, 1), | ||
308 | SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, | ||
309 | ES8328_DACPOWER_LDAC_OFF, 1), | ||
310 | |||
311 | SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, | ||
312 | &es8328_left_mixer_controls[0], | ||
313 | ARRAY_SIZE(es8328_left_mixer_controls)), | ||
314 | SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, | ||
315 | &es8328_right_mixer_controls[0], | ||
316 | ARRAY_SIZE(es8328_right_mixer_controls)), | ||
317 | |||
318 | SND_SOC_DAPM_PGA("Right Out 2", ES8328_DACPOWER, | ||
319 | ES8328_DACPOWER_ROUT2_ON, 0, NULL, 0), | ||
320 | SND_SOC_DAPM_PGA("Left Out 2", ES8328_DACPOWER, | ||
321 | ES8328_DACPOWER_LOUT2_ON, 0, NULL, 0), | ||
322 | SND_SOC_DAPM_PGA("Right Out 1", ES8328_DACPOWER, | ||
323 | ES8328_DACPOWER_ROUT1_ON, 0, NULL, 0), | ||
324 | SND_SOC_DAPM_PGA("Left Out 1", ES8328_DACPOWER, | ||
325 | ES8328_DACPOWER_LOUT1_ON, 0, NULL, 0), | ||
326 | |||
327 | SND_SOC_DAPM_OUTPUT("LOUT1"), | ||
328 | SND_SOC_DAPM_OUTPUT("ROUT1"), | ||
329 | SND_SOC_DAPM_OUTPUT("LOUT2"), | ||
330 | SND_SOC_DAPM_OUTPUT("ROUT2"), | ||
331 | |||
332 | SND_SOC_DAPM_INPUT("LINPUT1"), | ||
333 | SND_SOC_DAPM_INPUT("LINPUT2"), | ||
334 | SND_SOC_DAPM_INPUT("RINPUT1"), | ||
335 | SND_SOC_DAPM_INPUT("RINPUT2"), | ||
336 | }; | ||
337 | |||
338 | static const struct snd_soc_dapm_route es8328_dapm_routes[] = { | ||
339 | |||
340 | { "Left Line Mux", "Line 1", "LINPUT1" }, | ||
341 | { "Left Line Mux", "Line 2", "LINPUT2" }, | ||
342 | { "Left Line Mux", "PGA", "Left PGA Mux" }, | ||
343 | { "Left Line Mux", "Differential", "Differential Mux" }, | ||
344 | |||
345 | { "Right Line Mux", "Line 1", "RINPUT1" }, | ||
346 | { "Right Line Mux", "Line 2", "RINPUT2" }, | ||
347 | { "Right Line Mux", "PGA", "Right PGA Mux" }, | ||
348 | { "Right Line Mux", "Differential", "Differential Mux" }, | ||
349 | |||
350 | { "Left PGA Mux", "Line 1", "LINPUT1" }, | ||
351 | { "Left PGA Mux", "Line 2", "LINPUT2" }, | ||
352 | { "Left PGA Mux", "Differential", "Differential Mux" }, | ||
353 | |||
354 | { "Right PGA Mux", "Line 1", "RINPUT1" }, | ||
355 | { "Right PGA Mux", "Line 2", "RINPUT2" }, | ||
356 | { "Right PGA Mux", "Differential", "Differential Mux" }, | ||
357 | |||
358 | { "Differential Mux", "Line 1", "LINPUT1" }, | ||
359 | { "Differential Mux", "Line 1", "RINPUT1" }, | ||
360 | { "Differential Mux", "Line 2", "LINPUT2" }, | ||
361 | { "Differential Mux", "Line 2", "RINPUT2" }, | ||
362 | |||
363 | { "Left ADC Mux", "Stereo", "Left PGA Mux" }, | ||
364 | { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, | ||
365 | { "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, | ||
366 | |||
367 | { "Right ADC Mux", "Stereo", "Right PGA Mux" }, | ||
368 | { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, | ||
369 | { "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, | ||
370 | |||
371 | { "Left ADC", NULL, "Left ADC Mux" }, | ||
372 | { "Right ADC", NULL, "Right ADC Mux" }, | ||
373 | |||
374 | { "ADC DIG", NULL, "ADC STM" }, | ||
375 | { "ADC DIG", NULL, "ADC Vref" }, | ||
376 | { "ADC DIG", NULL, "ADC DLL" }, | ||
377 | |||
378 | { "Left ADC", NULL, "ADC DIG" }, | ||
379 | { "Right ADC", NULL, "ADC DIG" }, | ||
380 | |||
381 | { "Mic Bias", NULL, "Mic Bias Gen" }, | ||
382 | |||
383 | { "Left Line Mux", "Line 1", "LINPUT1" }, | ||
384 | { "Left Line Mux", "Line 2", "LINPUT2" }, | ||
385 | { "Left Line Mux", "PGA", "Left PGA Mux" }, | ||
386 | { "Left Line Mux", "Differential", "Differential Mux" }, | ||
387 | |||
388 | { "Right Line Mux", "Line 1", "RINPUT1" }, | ||
389 | { "Right Line Mux", "Line 2", "RINPUT2" }, | ||
390 | { "Right Line Mux", "PGA", "Right PGA Mux" }, | ||
391 | { "Right Line Mux", "Differential", "Differential Mux" }, | ||
392 | |||
393 | { "Left Out 1", NULL, "Left DAC" }, | ||
394 | { "Right Out 1", NULL, "Right DAC" }, | ||
395 | { "Left Out 2", NULL, "Left DAC" }, | ||
396 | { "Right Out 2", NULL, "Right DAC" }, | ||
397 | |||
398 | { "Left Mixer", "Playback Switch", "Left DAC" }, | ||
399 | { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, | ||
400 | { "Left Mixer", "Right Playback Switch", "Right DAC" }, | ||
401 | { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, | ||
402 | |||
403 | { "Right Mixer", "Left Playback Switch", "Left DAC" }, | ||
404 | { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, | ||
405 | { "Right Mixer", "Playback Switch", "Right DAC" }, | ||
406 | { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, | ||
407 | |||
408 | { "DAC DIG", NULL, "DAC STM" }, | ||
409 | { "DAC DIG", NULL, "DAC Vref" }, | ||
410 | { "DAC DIG", NULL, "DAC DLL" }, | ||
411 | |||
412 | { "Left DAC", NULL, "DAC DIG" }, | ||
413 | { "Right DAC", NULL, "DAC DIG" }, | ||
414 | |||
415 | { "Left Out 1", NULL, "Left Mixer" }, | ||
416 | { "LOUT1", NULL, "Left Out 1" }, | ||
417 | { "Right Out 1", NULL, "Right Mixer" }, | ||
418 | { "ROUT1", NULL, "Right Out 1" }, | ||
419 | |||
420 | { "Left Out 2", NULL, "Left Mixer" }, | ||
421 | { "LOUT2", NULL, "Left Out 2" }, | ||
422 | { "Right Out 2", NULL, "Right Mixer" }, | ||
423 | { "ROUT2", NULL, "Right Out 2" }, | ||
424 | }; | ||
425 | |||
426 | static int es8328_mute(struct snd_soc_dai *dai, int mute) | ||
427 | { | ||
428 | return snd_soc_update_bits(dai->codec, ES8328_DACCONTROL3, | ||
429 | ES8328_DACCONTROL3_DACMUTE, | ||
430 | mute ? ES8328_DACCONTROL3_DACMUTE : 0); | ||
431 | } | ||
432 | |||
433 | static int es8328_hw_params(struct snd_pcm_substream *substream, | ||
434 | struct snd_pcm_hw_params *params, | ||
435 | struct snd_soc_dai *dai) | ||
436 | { | ||
437 | struct snd_soc_codec *codec = dai->codec; | ||
438 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | ||
439 | int clk_rate; | ||
440 | int i; | ||
441 | int reg; | ||
442 | u8 ratio; | ||
443 | |||
444 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
445 | reg = ES8328_DACCONTROL2; | ||
446 | else | ||
447 | reg = ES8328_ADCCONTROL5; | ||
448 | |||
449 | clk_rate = clk_get_rate(es8328->clk); | ||
450 | |||
451 | if ((clk_rate != ES8328_SYSCLK_RATE_1X) && | ||
452 | (clk_rate != ES8328_SYSCLK_RATE_2X)) { | ||
453 | dev_err(codec->dev, | ||
454 | "%s: clock is running at %d Hz, not %d or %d Hz\n", | ||
455 | __func__, clk_rate, | ||
456 | ES8328_SYSCLK_RATE_1X, ES8328_SYSCLK_RATE_2X); | ||
457 | return -EINVAL; | ||
458 | } | ||
459 | |||
460 | /* find master mode MCLK to sampling frequency ratio */ | ||
461 | ratio = mclk_ratios[0].rate; | ||
462 | for (i = 1; i < ARRAY_SIZE(mclk_ratios); i++) | ||
463 | if (params_rate(params) <= mclk_ratios[i].rate) | ||
464 | ratio = mclk_ratios[i].ratio; | ||
465 | |||
466 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
467 | es8328->playback_fs = params_rate(params); | ||
468 | es8328_set_deemph(codec); | ||
469 | } | ||
470 | |||
471 | return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio); | ||
472 | } | ||
473 | |||
474 | static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
475 | unsigned int fmt) | ||
476 | { | ||
477 | struct snd_soc_codec *codec = codec_dai->codec; | ||
478 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | ||
479 | int clk_rate; | ||
480 | u8 mode = ES8328_DACCONTROL1_DACWL_16; | ||
481 | |||
482 | /* set master/slave audio interface */ | ||
483 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM) | ||
484 | return -EINVAL; | ||
485 | |||
486 | /* interface format */ | ||
487 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
488 | case SND_SOC_DAIFMT_I2S: | ||
489 | mode |= ES8328_DACCONTROL1_DACFORMAT_I2S; | ||
490 | break; | ||
491 | case SND_SOC_DAIFMT_RIGHT_J: | ||
492 | mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST; | ||
493 | break; | ||
494 | case SND_SOC_DAIFMT_LEFT_J: | ||
495 | mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST; | ||
496 | break; | ||
497 | default: | ||
498 | return -EINVAL; | ||
499 | } | ||
500 | |||
501 | /* clock inversion */ | ||
502 | if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) | ||
503 | return -EINVAL; | ||
504 | |||
505 | snd_soc_write(codec, ES8328_DACCONTROL1, mode); | ||
506 | snd_soc_write(codec, ES8328_ADCCONTROL4, mode); | ||
507 | |||
508 | /* Master serial port mode, with BCLK generated automatically */ | ||
509 | clk_rate = clk_get_rate(es8328->clk); | ||
510 | if (clk_rate == ES8328_SYSCLK_RATE_1X) | ||
511 | snd_soc_write(codec, ES8328_MASTERMODE, | ||
512 | ES8328_MASTERMODE_MSC); | ||
513 | else | ||
514 | snd_soc_write(codec, ES8328_MASTERMODE, | ||
515 | ES8328_MASTERMODE_MCLKDIV2 | | ||
516 | ES8328_MASTERMODE_MSC); | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static int es8328_set_bias_level(struct snd_soc_codec *codec, | ||
522 | enum snd_soc_bias_level level) | ||
523 | { | ||
524 | switch (level) { | ||
525 | case SND_SOC_BIAS_ON: | ||
526 | break; | ||
527 | |||
528 | case SND_SOC_BIAS_PREPARE: | ||
529 | /* VREF, VMID=2x50k, digital enabled */ | ||
530 | snd_soc_write(codec, ES8328_CHIPPOWER, 0); | ||
531 | snd_soc_update_bits(codec, ES8328_CONTROL1, | ||
532 | ES8328_CONTROL1_VMIDSEL_MASK | | ||
533 | ES8328_CONTROL1_ENREF, | ||
534 | ES8328_CONTROL1_VMIDSEL_50k | | ||
535 | ES8328_CONTROL1_ENREF); | ||
536 | break; | ||
537 | |||
538 | case SND_SOC_BIAS_STANDBY: | ||
539 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
540 | snd_soc_update_bits(codec, ES8328_CONTROL1, | ||
541 | ES8328_CONTROL1_VMIDSEL_MASK | | ||
542 | ES8328_CONTROL1_ENREF, | ||
543 | ES8328_CONTROL1_VMIDSEL_5k | | ||
544 | ES8328_CONTROL1_ENREF); | ||
545 | |||
546 | /* Charge caps */ | ||
547 | msleep(100); | ||
548 | } | ||
549 | |||
550 | snd_soc_write(codec, ES8328_CONTROL2, | ||
551 | ES8328_CONTROL2_OVERCURRENT_ON | | ||
552 | ES8328_CONTROL2_THERMAL_SHUTDOWN_ON); | ||
553 | |||
554 | /* VREF, VMID=2*500k, digital stopped */ | ||
555 | snd_soc_update_bits(codec, ES8328_CONTROL1, | ||
556 | ES8328_CONTROL1_VMIDSEL_MASK | | ||
557 | ES8328_CONTROL1_ENREF, | ||
558 | ES8328_CONTROL1_VMIDSEL_500k | | ||
559 | ES8328_CONTROL1_ENREF); | ||
560 | break; | ||
561 | |||
562 | case SND_SOC_BIAS_OFF: | ||
563 | snd_soc_update_bits(codec, ES8328_CONTROL1, | ||
564 | ES8328_CONTROL1_VMIDSEL_MASK | | ||
565 | ES8328_CONTROL1_ENREF, | ||
566 | 0); | ||
567 | break; | ||
568 | } | ||
569 | codec->dapm.bias_level = level; | ||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static const struct snd_soc_dai_ops es8328_dai_ops = { | ||
574 | .hw_params = es8328_hw_params, | ||
575 | .digital_mute = es8328_mute, | ||
576 | .set_fmt = es8328_set_dai_fmt, | ||
577 | }; | ||
578 | |||
579 | static struct snd_soc_dai_driver es8328_dai = { | ||
580 | .name = "es8328-hifi-analog", | ||
581 | .playback = { | ||
582 | .stream_name = "Playback", | ||
583 | .channels_min = 2, | ||
584 | .channels_max = 2, | ||
585 | .rates = ES8328_RATES, | ||
586 | .formats = ES8328_FORMATS, | ||
587 | }, | ||
588 | .capture = { | ||
589 | .stream_name = "Capture", | ||
590 | .channels_min = 2, | ||
591 | .channels_max = 2, | ||
592 | .rates = ES8328_RATES, | ||
593 | .formats = ES8328_FORMATS, | ||
594 | }, | ||
595 | .ops = &es8328_dai_ops, | ||
596 | }; | ||
597 | |||
598 | static int es8328_suspend(struct snd_soc_codec *codec) | ||
599 | { | ||
600 | struct es8328_priv *es8328; | ||
601 | int ret; | ||
602 | |||
603 | es8328 = snd_soc_codec_get_drvdata(codec); | ||
604 | |||
605 | clk_disable_unprepare(es8328->clk); | ||
606 | |||
607 | ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), | ||
608 | es8328->supplies); | ||
609 | if (ret) { | ||
610 | dev_err(codec->dev, "unable to disable regulators\n"); | ||
611 | return ret; | ||
612 | } | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int es8328_resume(struct snd_soc_codec *codec) | ||
617 | { | ||
618 | struct regmap *regmap = dev_get_regmap(codec->dev, NULL); | ||
619 | struct es8328_priv *es8328; | ||
620 | int ret; | ||
621 | |||
622 | es8328 = snd_soc_codec_get_drvdata(codec); | ||
623 | |||
624 | ret = clk_prepare_enable(es8328->clk); | ||
625 | if (ret) { | ||
626 | dev_err(codec->dev, "unable to enable clock\n"); | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies), | ||
631 | es8328->supplies); | ||
632 | if (ret) { | ||
633 | dev_err(codec->dev, "unable to enable regulators\n"); | ||
634 | return ret; | ||
635 | } | ||
636 | |||
637 | regcache_mark_dirty(regmap); | ||
638 | ret = regcache_sync(regmap); | ||
639 | if (ret) { | ||
640 | dev_err(codec->dev, "unable to sync regcache\n"); | ||
641 | return ret; | ||
642 | } | ||
643 | |||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static int es8328_codec_probe(struct snd_soc_codec *codec) | ||
648 | { | ||
649 | struct es8328_priv *es8328; | ||
650 | int ret; | ||
651 | |||
652 | es8328 = snd_soc_codec_get_drvdata(codec); | ||
653 | |||
654 | ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies), | ||
655 | es8328->supplies); | ||
656 | if (ret) { | ||
657 | dev_err(codec->dev, "unable to enable regulators\n"); | ||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | /* Setup clocks */ | ||
662 | es8328->clk = devm_clk_get(codec->dev, NULL); | ||
663 | if (IS_ERR(es8328->clk)) { | ||
664 | dev_err(codec->dev, "codec clock missing or invalid\n"); | ||
665 | ret = PTR_ERR(es8328->clk); | ||
666 | goto clk_fail; | ||
667 | } | ||
668 | |||
669 | ret = clk_prepare_enable(es8328->clk); | ||
670 | if (ret) { | ||
671 | dev_err(codec->dev, "unable to prepare codec clk\n"); | ||
672 | goto clk_fail; | ||
673 | } | ||
674 | |||
675 | return 0; | ||
676 | |||
677 | clk_fail: | ||
678 | regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), | ||
679 | es8328->supplies); | ||
680 | return ret; | ||
681 | } | ||
682 | |||
683 | static int es8328_remove(struct snd_soc_codec *codec) | ||
684 | { | ||
685 | struct es8328_priv *es8328; | ||
686 | |||
687 | es8328 = snd_soc_codec_get_drvdata(codec); | ||
688 | |||
689 | if (es8328->clk) | ||
690 | clk_disable_unprepare(es8328->clk); | ||
691 | |||
692 | regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), | ||
693 | es8328->supplies); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | const struct regmap_config es8328_regmap_config = { | ||
699 | .reg_bits = 8, | ||
700 | .val_bits = 8, | ||
701 | .max_register = ES8328_REG_MAX, | ||
702 | .cache_type = REGCACHE_RBTREE, | ||
703 | }; | ||
704 | EXPORT_SYMBOL_GPL(es8328_regmap_config); | ||
705 | |||
706 | static struct snd_soc_codec_driver es8328_codec_driver = { | ||
707 | .probe = es8328_codec_probe, | ||
708 | .suspend = es8328_suspend, | ||
709 | .resume = es8328_resume, | ||
710 | .remove = es8328_remove, | ||
711 | .set_bias_level = es8328_set_bias_level, | ||
712 | .suspend_bias_off = true, | ||
713 | |||
714 | .controls = es8328_snd_controls, | ||
715 | .num_controls = ARRAY_SIZE(es8328_snd_controls), | ||
716 | .dapm_widgets = es8328_dapm_widgets, | ||
717 | .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), | ||
718 | .dapm_routes = es8328_dapm_routes, | ||
719 | .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), | ||
720 | }; | ||
721 | |||
722 | int es8328_probe(struct device *dev, struct regmap *regmap) | ||
723 | { | ||
724 | struct es8328_priv *es8328; | ||
725 | int ret; | ||
726 | int i; | ||
727 | |||
728 | if (IS_ERR(regmap)) | ||
729 | return PTR_ERR(regmap); | ||
730 | |||
731 | es8328 = devm_kzalloc(dev, sizeof(*es8328), GFP_KERNEL); | ||
732 | if (es8328 == NULL) | ||
733 | return -ENOMEM; | ||
734 | |||
735 | es8328->regmap = regmap; | ||
736 | |||
737 | for (i = 0; i < ARRAY_SIZE(es8328->supplies); i++) | ||
738 | es8328->supplies[i].supply = supply_names[i]; | ||
739 | |||
740 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(es8328->supplies), | ||
741 | es8328->supplies); | ||
742 | if (ret) { | ||
743 | dev_err(dev, "unable to get regulators\n"); | ||
744 | return ret; | ||
745 | } | ||
746 | |||
747 | dev_set_drvdata(dev, es8328); | ||
748 | |||
749 | return snd_soc_register_codec(dev, | ||
750 | &es8328_codec_driver, &es8328_dai, 1); | ||
751 | } | ||
752 | EXPORT_SYMBOL_GPL(es8328_probe); | ||
753 | |||
754 | MODULE_DESCRIPTION("ASoC ES8328 driver"); | ||
755 | MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); | ||
756 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/es8328.h b/sound/soc/codecs/es8328.h new file mode 100644 index 000000000000..cb36afe10c0e --- /dev/null +++ b/sound/soc/codecs/es8328.h | |||
@@ -0,0 +1,314 @@ | |||
1 | /* | ||
2 | * es8328.h -- ES8328 ALSA SoC Audio driver | ||
3 | */ | ||
4 | |||
5 | #ifndef _ES8328_H | ||
6 | #define _ES8328_H | ||
7 | |||
8 | #include <linux/regmap.h> | ||
9 | |||
10 | struct device; | ||
11 | |||
12 | extern const struct regmap_config es8328_regmap_config; | ||
13 | int es8328_probe(struct device *dev, struct regmap *regmap); | ||
14 | |||
15 | #define ES8328_DACLVOL 46 | ||
16 | #define ES8328_DACRVOL 47 | ||
17 | #define ES8328_DACCTL 28 | ||
18 | #define ES8328_RATEMASK (0x1f << 0) | ||
19 | |||
20 | #define ES8328_CONTROL1 0x00 | ||
21 | #define ES8328_CONTROL1_VMIDSEL_OFF (0 << 0) | ||
22 | #define ES8328_CONTROL1_VMIDSEL_50k (1 << 0) | ||
23 | #define ES8328_CONTROL1_VMIDSEL_500k (2 << 0) | ||
24 | #define ES8328_CONTROL1_VMIDSEL_5k (3 << 0) | ||
25 | #define ES8328_CONTROL1_VMIDSEL_MASK (7 << 0) | ||
26 | #define ES8328_CONTROL1_ENREF (1 << 2) | ||
27 | #define ES8328_CONTROL1_SEQEN (1 << 3) | ||
28 | #define ES8328_CONTROL1_SAMEFS (1 << 4) | ||
29 | #define ES8328_CONTROL1_DACMCLK_ADC (0 << 5) | ||
30 | #define ES8328_CONTROL1_DACMCLK_DAC (1 << 5) | ||
31 | #define ES8328_CONTROL1_LRCM (1 << 6) | ||
32 | #define ES8328_CONTROL1_SCP_RESET (1 << 7) | ||
33 | |||
34 | #define ES8328_CONTROL2 0x01 | ||
35 | #define ES8328_CONTROL2_VREF_BUF_OFF (1 << 0) | ||
36 | #define ES8328_CONTROL2_VREF_LOWPOWER (1 << 1) | ||
37 | #define ES8328_CONTROL2_IBIASGEN_OFF (1 << 2) | ||
38 | #define ES8328_CONTROL2_ANALOG_OFF (1 << 3) | ||
39 | #define ES8328_CONTROL2_VREF_BUF_LOWPOWER (1 << 4) | ||
40 | #define ES8328_CONTROL2_VCM_MOD_LOWPOWER (1 << 5) | ||
41 | #define ES8328_CONTROL2_OVERCURRENT_ON (1 << 6) | ||
42 | #define ES8328_CONTROL2_THERMAL_SHUTDOWN_ON (1 << 7) | ||
43 | |||
44 | #define ES8328_CHIPPOWER 0x02 | ||
45 | #define ES8328_CHIPPOWER_DACVREF_OFF 0 | ||
46 | #define ES8328_CHIPPOWER_ADCVREF_OFF 1 | ||
47 | #define ES8328_CHIPPOWER_DACDLL_OFF 2 | ||
48 | #define ES8328_CHIPPOWER_ADCDLL_OFF 3 | ||
49 | #define ES8328_CHIPPOWER_DACSTM_RESET 4 | ||
50 | #define ES8328_CHIPPOWER_ADCSTM_RESET 5 | ||
51 | #define ES8328_CHIPPOWER_DACDIG_OFF 6 | ||
52 | #define ES8328_CHIPPOWER_ADCDIG_OFF 7 | ||
53 | |||
54 | #define ES8328_ADCPOWER 0x03 | ||
55 | #define ES8328_ADCPOWER_INT1_LOWPOWER 0 | ||
56 | #define ES8328_ADCPOWER_FLASH_ADC_LOWPOWER 1 | ||
57 | #define ES8328_ADCPOWER_ADC_BIAS_GEN_OFF 2 | ||
58 | #define ES8328_ADCPOWER_MIC_BIAS_OFF 3 | ||
59 | #define ES8328_ADCPOWER_ADCR_OFF 4 | ||
60 | #define ES8328_ADCPOWER_ADCL_OFF 5 | ||
61 | #define ES8328_ADCPOWER_AINR_OFF 6 | ||
62 | #define ES8328_ADCPOWER_AINL_OFF 7 | ||
63 | |||
64 | #define ES8328_DACPOWER 0x04 | ||
65 | #define ES8328_DACPOWER_OUT3_ON 0 | ||
66 | #define ES8328_DACPOWER_MONO_ON 1 | ||
67 | #define ES8328_DACPOWER_ROUT2_ON 2 | ||
68 | #define ES8328_DACPOWER_LOUT2_ON 3 | ||
69 | #define ES8328_DACPOWER_ROUT1_ON 4 | ||
70 | #define ES8328_DACPOWER_LOUT1_ON 5 | ||
71 | #define ES8328_DACPOWER_RDAC_OFF 6 | ||
72 | #define ES8328_DACPOWER_LDAC_OFF 7 | ||
73 | |||
74 | #define ES8328_CHIPLOPOW1 0x05 | ||
75 | #define ES8328_CHIPLOPOW2 0x06 | ||
76 | #define ES8328_ANAVOLMANAG 0x07 | ||
77 | |||
78 | #define ES8328_MASTERMODE 0x08 | ||
79 | #define ES8328_MASTERMODE_BCLKDIV (0 << 0) | ||
80 | #define ES8328_MASTERMODE_BCLK_INV (1 << 5) | ||
81 | #define ES8328_MASTERMODE_MCLKDIV2 (1 << 6) | ||
82 | #define ES8328_MASTERMODE_MSC (1 << 7) | ||
83 | |||
84 | #define ES8328_ADCCONTROL1 0x09 | ||
85 | #define ES8328_ADCCONTROL2 0x0a | ||
86 | #define ES8328_ADCCONTROL3 0x0b | ||
87 | #define ES8328_ADCCONTROL4 0x0c | ||
88 | #define ES8328_ADCCONTROL5 0x0d | ||
89 | #define ES8328_ADCCONTROL5_RATEMASK (0x1f << 0) | ||
90 | |||
91 | #define ES8328_ADCCONTROL6 0x0e | ||
92 | |||
93 | #define ES8328_ADCCONTROL7 0x0f | ||
94 | #define ES8328_ADCCONTROL7_ADC_MUTE (1 << 2) | ||
95 | #define ES8328_ADCCONTROL7_ADC_LER (1 << 3) | ||
96 | #define ES8328_ADCCONTROL7_ADC_ZERO_CROSS (1 << 4) | ||
97 | #define ES8328_ADCCONTROL7_ADC_SOFT_RAMP (1 << 5) | ||
98 | #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_4 (0 << 6) | ||
99 | #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_8 (1 << 6) | ||
100 | #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_16 (2 << 6) | ||
101 | #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_32 (3 << 6) | ||
102 | |||
103 | #define ES8328_ADCCONTROL8 0x10 | ||
104 | #define ES8328_ADCCONTROL9 0x11 | ||
105 | #define ES8328_ADCCONTROL10 0x12 | ||
106 | #define ES8328_ADCCONTROL11 0x13 | ||
107 | #define ES8328_ADCCONTROL12 0x14 | ||
108 | #define ES8328_ADCCONTROL13 0x15 | ||
109 | #define ES8328_ADCCONTROL14 0x16 | ||
110 | |||
111 | #define ES8328_DACCONTROL1 0x17 | ||
112 | #define ES8328_DACCONTROL1_DACFORMAT_I2S (0 << 1) | ||
113 | #define ES8328_DACCONTROL1_DACFORMAT_LJUST (1 << 1) | ||
114 | #define ES8328_DACCONTROL1_DACFORMAT_RJUST (2 << 1) | ||
115 | #define ES8328_DACCONTROL1_DACFORMAT_PCM (3 << 1) | ||
116 | #define ES8328_DACCONTROL1_DACWL_24 (0 << 3) | ||
117 | #define ES8328_DACCONTROL1_DACWL_20 (1 << 3) | ||
118 | #define ES8328_DACCONTROL1_DACWL_18 (2 << 3) | ||
119 | #define ES8328_DACCONTROL1_DACWL_16 (3 << 3) | ||
120 | #define ES8328_DACCONTROL1_DACWL_32 (4 << 3) | ||
121 | #define ES8328_DACCONTROL1_DACLRP_I2S_POL_NORMAL (0 << 6) | ||
122 | #define ES8328_DACCONTROL1_DACLRP_I2S_POL_INV (1 << 6) | ||
123 | #define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK2 (0 << 6) | ||
124 | #define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK1 (1 << 6) | ||
125 | #define ES8328_DACCONTROL1_LRSWAP (1 << 7) | ||
126 | |||
127 | #define ES8328_DACCONTROL2 0x18 | ||
128 | #define ES8328_DACCONTROL2_RATEMASK (0x1f << 0) | ||
129 | #define ES8328_DACCONTROL2_DOUBLESPEED (1 << 5) | ||
130 | |||
131 | #define ES8328_DACCONTROL3 0x19 | ||
132 | #define ES8328_DACCONTROL3_AUTOMUTE (1 << 2) | ||
133 | #define ES8328_DACCONTROL3_DACMUTE (1 << 2) | ||
134 | #define ES8328_DACCONTROL3_LEFTGAINVOL (1 << 3) | ||
135 | #define ES8328_DACCONTROL3_DACZEROCROSS (1 << 4) | ||
136 | #define ES8328_DACCONTROL3_DACSOFTRAMP (1 << 5) | ||
137 | #define ES8328_DACCONTROL3_DACRAMPRATE (3 << 6) | ||
138 | |||
139 | #define ES8328_LDACVOL 0x1a | ||
140 | #define ES8328_LDACVOL_MASK (0 << 0) | ||
141 | #define ES8328_LDACVOL_MAX (0xc0) | ||
142 | |||
143 | #define ES8328_RDACVOL 0x1b | ||
144 | #define ES8328_RDACVOL_MASK (0 << 0) | ||
145 | #define ES8328_RDACVOL_MAX (0xc0) | ||
146 | |||
147 | #define ES8328_DACVOL_MAX (0xc0) | ||
148 | |||
149 | #define ES8328_DACCONTROL4 0x1a | ||
150 | #define ES8328_DACCONTROL5 0x1b | ||
151 | |||
152 | #define ES8328_DACCONTROL6 0x1c | ||
153 | #define ES8328_DACCONTROL6_CLICKFREE (1 << 3) | ||
154 | #define ES8328_DACCONTROL6_DAC_INVR (1 << 4) | ||
155 | #define ES8328_DACCONTROL6_DAC_INVL (1 << 5) | ||
156 | #define ES8328_DACCONTROL6_DEEMPH_OFF (0 << 6) | ||
157 | #define ES8328_DACCONTROL6_DEEMPH_32k (1 << 6) | ||
158 | #define ES8328_DACCONTROL6_DEEMPH_44_1k (2 << 6) | ||
159 | #define ES8328_DACCONTROL6_DEEMPH_48k (3 << 6) | ||
160 | |||
161 | #define ES8328_DACCONTROL7 0x1d | ||
162 | #define ES8328_DACCONTROL7_VPP_SCALE_3p5 (0 << 0) | ||
163 | #define ES8328_DACCONTROL7_VPP_SCALE_4p0 (1 << 0) | ||
164 | #define ES8328_DACCONTROL7_VPP_SCALE_3p0 (2 << 0) | ||
165 | #define ES8328_DACCONTROL7_VPP_SCALE_2p5 (3 << 0) | ||
166 | #define ES8328_DACCONTROL7_SHELVING_STRENGTH (1 << 2) /* In eights */ | ||
167 | #define ES8328_DACCONTROL7_MONO (1 << 5) | ||
168 | #define ES8328_DACCONTROL7_ZEROR (1 << 6) | ||
169 | #define ES8328_DACCONTROL7_ZEROL (1 << 7) | ||
170 | |||
171 | /* Shelving filter */ | ||
172 | #define ES8328_DACCONTROL8 0x1e | ||
173 | #define ES8328_DACCONTROL9 0x1f | ||
174 | #define ES8328_DACCONTROL10 0x20 | ||
175 | #define ES8328_DACCONTROL11 0x21 | ||
176 | #define ES8328_DACCONTROL12 0x22 | ||
177 | #define ES8328_DACCONTROL13 0x23 | ||
178 | #define ES8328_DACCONTROL14 0x24 | ||
179 | #define ES8328_DACCONTROL15 0x25 | ||
180 | |||
181 | #define ES8328_DACCONTROL16 0x26 | ||
182 | #define ES8328_DACCONTROL16_RMIXSEL_RIN1 (0 << 0) | ||
183 | #define ES8328_DACCONTROL16_RMIXSEL_RIN2 (1 << 0) | ||
184 | #define ES8328_DACCONTROL16_RMIXSEL_RIN3 (2 << 0) | ||
185 | #define ES8328_DACCONTROL16_RMIXSEL_RADC (3 << 0) | ||
186 | #define ES8328_DACCONTROL16_LMIXSEL_LIN1 (0 << 3) | ||
187 | #define ES8328_DACCONTROL16_LMIXSEL_LIN2 (1 << 3) | ||
188 | #define ES8328_DACCONTROL16_LMIXSEL_LIN3 (2 << 3) | ||
189 | #define ES8328_DACCONTROL16_LMIXSEL_LADC (3 << 3) | ||
190 | |||
191 | #define ES8328_DACCONTROL17 0x27 | ||
192 | #define ES8328_DACCONTROL17_LI2LOVOL (7 << 3) | ||
193 | #define ES8328_DACCONTROL17_LI2LO (1 << 6) | ||
194 | #define ES8328_DACCONTROL17_LD2LO (1 << 7) | ||
195 | |||
196 | #define ES8328_DACCONTROL18 0x28 | ||
197 | #define ES8328_DACCONTROL18_RI2LOVOL (7 << 3) | ||
198 | #define ES8328_DACCONTROL18_RI2LO (1 << 6) | ||
199 | #define ES8328_DACCONTROL18_RD2LO (1 << 7) | ||
200 | |||
201 | #define ES8328_DACCONTROL19 0x29 | ||
202 | #define ES8328_DACCONTROL19_LI2ROVOL (7 << 3) | ||
203 | #define ES8328_DACCONTROL19_LI2RO (1 << 6) | ||
204 | #define ES8328_DACCONTROL19_LD2RO (1 << 7) | ||
205 | |||
206 | #define ES8328_DACCONTROL20 0x2a | ||
207 | #define ES8328_DACCONTROL20_RI2ROVOL (7 << 3) | ||
208 | #define ES8328_DACCONTROL20_RI2RO (1 << 6) | ||
209 | #define ES8328_DACCONTROL20_RD2RO (1 << 7) | ||
210 | |||
211 | #define ES8328_DACCONTROL21 0x2b | ||
212 | #define ES8328_DACCONTROL21_LI2MOVOL (7 << 3) | ||
213 | #define ES8328_DACCONTROL21_LI2MO (1 << 6) | ||
214 | #define ES8328_DACCONTROL21_LD2MO (1 << 7) | ||
215 | |||
216 | #define ES8328_DACCONTROL22 0x2c | ||
217 | #define ES8328_DACCONTROL22_RI2MOVOL (7 << 3) | ||
218 | #define ES8328_DACCONTROL22_RI2MO (1 << 6) | ||
219 | #define ES8328_DACCONTROL22_RD2MO (1 << 7) | ||
220 | |||
221 | #define ES8328_DACCONTROL23 0x2d | ||
222 | #define ES8328_DACCONTROL23_MOUTINV (1 << 1) | ||
223 | #define ES8328_DACCONTROL23_HPSWPOL (1 << 2) | ||
224 | #define ES8328_DACCONTROL23_HPSWEN (1 << 3) | ||
225 | #define ES8328_DACCONTROL23_VROI_1p5k (0 << 4) | ||
226 | #define ES8328_DACCONTROL23_VROI_40k (1 << 4) | ||
227 | #define ES8328_DACCONTROL23_OUT3_VREF (0 << 5) | ||
228 | #define ES8328_DACCONTROL23_OUT3_ROUT1 (1 << 5) | ||
229 | #define ES8328_DACCONTROL23_OUT3_MONOOUT (2 << 5) | ||
230 | #define ES8328_DACCONTROL23_OUT3_RIGHT_MIXER (3 << 5) | ||
231 | #define ES8328_DACCONTROL23_ROUT2INV (1 << 7) | ||
232 | |||
233 | /* LOUT1 Amplifier */ | ||
234 | #define ES8328_LOUT1VOL 0x2e | ||
235 | #define ES8328_LOUT1VOL_MASK (0 << 5) | ||
236 | #define ES8328_LOUT1VOL_MAX (0x24) | ||
237 | |||
238 | /* ROUT1 Amplifier */ | ||
239 | #define ES8328_ROUT1VOL 0x2f | ||
240 | #define ES8328_ROUT1VOL_MASK (0 << 5) | ||
241 | #define ES8328_ROUT1VOL_MAX (0x24) | ||
242 | |||
243 | #define ES8328_OUT1VOL_MAX (0x24) | ||
244 | |||
245 | /* LOUT2 Amplifier */ | ||
246 | #define ES8328_LOUT2VOL 0x30 | ||
247 | #define ES8328_LOUT2VOL_MASK (0 << 5) | ||
248 | #define ES8328_LOUT2VOL_MAX (0x24) | ||
249 | |||
250 | /* ROUT2 Amplifier */ | ||
251 | #define ES8328_ROUT2VOL 0x31 | ||
252 | #define ES8328_ROUT2VOL_MASK (0 << 5) | ||
253 | #define ES8328_ROUT2VOL_MAX (0x24) | ||
254 | |||
255 | #define ES8328_OUT2VOL_MAX (0x24) | ||
256 | |||
257 | /* Mono Out Amplifier */ | ||
258 | #define ES8328_MONOOUTVOL 0x32 | ||
259 | #define ES8328_MONOOUTVOL_MASK (0 << 5) | ||
260 | #define ES8328_MONOOUTVOL_MAX (0x24) | ||
261 | |||
262 | #define ES8328_DACCONTROL29 0x33 | ||
263 | #define ES8328_DACCONTROL30 0x34 | ||
264 | |||
265 | #define ES8328_SYSCLK 0 | ||
266 | |||
267 | #define ES8328_REG_MAX 0x35 | ||
268 | |||
269 | #define ES8328_PLL1 0 | ||
270 | #define ES8328_PLL2 1 | ||
271 | |||
272 | /* clock inputs */ | ||
273 | #define ES8328_MCLK 0 | ||
274 | #define ES8328_PCMCLK 1 | ||
275 | |||
276 | /* clock divider id's */ | ||
277 | #define ES8328_PCMDIV 0 | ||
278 | #define ES8328_BCLKDIV 1 | ||
279 | #define ES8328_VXCLKDIV 2 | ||
280 | |||
281 | /* PCM clock dividers */ | ||
282 | #define ES8328_PCM_DIV_1 (0 << 6) | ||
283 | #define ES8328_PCM_DIV_3 (2 << 6) | ||
284 | #define ES8328_PCM_DIV_5_5 (3 << 6) | ||
285 | #define ES8328_PCM_DIV_2 (4 << 6) | ||
286 | #define ES8328_PCM_DIV_4 (5 << 6) | ||
287 | #define ES8328_PCM_DIV_6 (6 << 6) | ||
288 | #define ES8328_PCM_DIV_8 (7 << 6) | ||
289 | |||
290 | /* BCLK clock dividers */ | ||
291 | #define ES8328_BCLK_DIV_1 (0 << 7) | ||
292 | #define ES8328_BCLK_DIV_2 (1 << 7) | ||
293 | #define ES8328_BCLK_DIV_4 (2 << 7) | ||
294 | #define ES8328_BCLK_DIV_8 (3 << 7) | ||
295 | |||
296 | /* VXCLK clock dividers */ | ||
297 | #define ES8328_VXCLK_DIV_1 (0 << 6) | ||
298 | #define ES8328_VXCLK_DIV_2 (1 << 6) | ||
299 | #define ES8328_VXCLK_DIV_4 (2 << 6) | ||
300 | #define ES8328_VXCLK_DIV_8 (3 << 6) | ||
301 | #define ES8328_VXCLK_DIV_16 (4 << 6) | ||
302 | |||
303 | #define ES8328_DAI_HIFI 0 | ||
304 | #define ES8328_DAI_VOICE 1 | ||
305 | |||
306 | #define ES8328_1536FS 1536 | ||
307 | #define ES8328_1024FS 1024 | ||
308 | #define ES8328_768FS 768 | ||
309 | #define ES8328_512FS 512 | ||
310 | #define ES8328_384FS 384 | ||
311 | #define ES8328_256FS 256 | ||
312 | #define ES8328_128FS 128 | ||
313 | |||
314 | #endif | ||
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index bcebd1a9ce31..df7c01cf7072 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c | |||
@@ -293,41 +293,13 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) | |||
293 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1, | 293 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1, |
294 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); | 294 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); |
295 | 295 | ||
296 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
297 | |||
298 | return 0; | 296 | return 0; |
299 | } | 297 | } |
300 | 298 | ||
301 | static int jz4740_codec_dev_remove(struct snd_soc_codec *codec) | ||
302 | { | ||
303 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | #ifdef CONFIG_PM_SLEEP | ||
309 | |||
310 | static int jz4740_codec_suspend(struct snd_soc_codec *codec) | ||
311 | { | ||
312 | return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
313 | } | ||
314 | |||
315 | static int jz4740_codec_resume(struct snd_soc_codec *codec) | ||
316 | { | ||
317 | return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
318 | } | ||
319 | |||
320 | #else | ||
321 | #define jz4740_codec_suspend NULL | ||
322 | #define jz4740_codec_resume NULL | ||
323 | #endif | ||
324 | |||
325 | static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | 299 | static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { |
326 | .probe = jz4740_codec_dev_probe, | 300 | .probe = jz4740_codec_dev_probe, |
327 | .remove = jz4740_codec_dev_remove, | ||
328 | .suspend = jz4740_codec_suspend, | ||
329 | .resume = jz4740_codec_resume, | ||
330 | .set_bias_level = jz4740_codec_set_bias_level, | 301 | .set_bias_level = jz4740_codec_set_bias_level, |
302 | .suspend_bias_off = true, | ||
331 | 303 | ||
332 | .controls = jz4740_codec_controls, | 304 | .controls = jz4740_codec_controls, |
333 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), | 305 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), |
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 275b3f72f3f4..c1ae5764983f 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -1395,18 +1395,6 @@ static struct snd_soc_dai_driver lm49453_dai[] = { | |||
1395 | }, | 1395 | }, |
1396 | }; | 1396 | }; |
1397 | 1397 | ||
1398 | static int lm49453_suspend(struct snd_soc_codec *codec) | ||
1399 | { | ||
1400 | lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1401 | return 0; | ||
1402 | } | ||
1403 | |||
1404 | static int lm49453_resume(struct snd_soc_codec *codec) | ||
1405 | { | ||
1406 | lm49453_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | /* power down chip */ | 1398 | /* power down chip */ |
1411 | static int lm49453_remove(struct snd_soc_codec *codec) | 1399 | static int lm49453_remove(struct snd_soc_codec *codec) |
1412 | { | 1400 | { |
@@ -1416,8 +1404,6 @@ static int lm49453_remove(struct snd_soc_codec *codec) | |||
1416 | 1404 | ||
1417 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { | 1405 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { |
1418 | .remove = lm49453_remove, | 1406 | .remove = lm49453_remove, |
1419 | .suspend = lm49453_suspend, | ||
1420 | .resume = lm49453_resume, | ||
1421 | .set_bias_level = lm49453_set_bias_level, | 1407 | .set_bias_level = lm49453_set_bias_level, |
1422 | .controls = lm49453_snd_controls, | 1408 | .controls = lm49453_snd_controls, |
1423 | .num_controls = ARRAY_SIZE(lm49453_snd_controls), | 1409 | .num_controls = ARRAY_SIZE(lm49453_snd_controls), |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 4a063fa88526..d519294f57c7 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -1311,8 +1311,6 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = { | |||
1311 | {"MIC1 Input", NULL, "MIC1"}, | 1311 | {"MIC1 Input", NULL, "MIC1"}, |
1312 | {"MIC2 Input", NULL, "MIC2"}, | 1312 | {"MIC2 Input", NULL, "MIC2"}, |
1313 | 1313 | ||
1314 | {"DMICL", NULL, "DMICL_ENA"}, | ||
1315 | {"DMICR", NULL, "DMICR_ENA"}, | ||
1316 | {"DMICL", NULL, "AHPF"}, | 1314 | {"DMICL", NULL, "AHPF"}, |
1317 | {"DMICR", NULL, "AHPF"}, | 1315 | {"DMICR", NULL, "AHPF"}, |
1318 | 1316 | ||
@@ -1370,6 +1368,8 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = { | |||
1370 | {"DMIC Mux", "ADC", "ADCR"}, | 1368 | {"DMIC Mux", "ADC", "ADCR"}, |
1371 | {"DMIC Mux", "DMIC", "DMICL"}, | 1369 | {"DMIC Mux", "DMIC", "DMICL"}, |
1372 | {"DMIC Mux", "DMIC", "DMICR"}, | 1370 | {"DMIC Mux", "DMIC", "DMICR"}, |
1371 | {"DMIC Mux", "DMIC", "DMICL_ENA"}, | ||
1372 | {"DMIC Mux", "DMIC", "DMICR_ENA"}, | ||
1373 | 1373 | ||
1374 | {"LBENL Mux", "Normal", "DMIC Mux"}, | 1374 | {"LBENL Mux", "Normal", "DMIC Mux"}, |
1375 | {"LBENL Mux", "Loopback", "LTENL Mux"}, | 1375 | {"LBENL Mux", "Loopback", "LTENL Mux"}, |
@@ -1972,6 +1972,102 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
1972 | return 0; | 1972 | return 0; |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd, | ||
1976 | struct snd_soc_dai *dai) | ||
1977 | { | ||
1978 | struct snd_soc_codec *codec = dai->codec; | ||
1979 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | ||
1980 | |||
1981 | switch (cmd) { | ||
1982 | case SNDRV_PCM_TRIGGER_START: | ||
1983 | case SNDRV_PCM_TRIGGER_RESUME: | ||
1984 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
1985 | if (!max98090->master && dai->active == 1) | ||
1986 | queue_delayed_work(system_power_efficient_wq, | ||
1987 | &max98090->pll_det_enable_work, | ||
1988 | msecs_to_jiffies(10)); | ||
1989 | break; | ||
1990 | case SNDRV_PCM_TRIGGER_STOP: | ||
1991 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
1992 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
1993 | if (!max98090->master && dai->active == 1) | ||
1994 | schedule_work(&max98090->pll_det_disable_work); | ||
1995 | break; | ||
1996 | default: | ||
1997 | break; | ||
1998 | } | ||
1999 | |||
2000 | return 0; | ||
2001 | } | ||
2002 | |||
2003 | static void max98090_pll_det_enable_work(struct work_struct *work) | ||
2004 | { | ||
2005 | struct max98090_priv *max98090 = | ||
2006 | container_of(work, struct max98090_priv, | ||
2007 | pll_det_enable_work.work); | ||
2008 | struct snd_soc_codec *codec = max98090->codec; | ||
2009 | unsigned int status, mask; | ||
2010 | |||
2011 | /* | ||
2012 | * Clear status register in order to clear possibly already occurred | ||
2013 | * PLL unlock. If PLL hasn't still locked, the status will be set | ||
2014 | * again and PLL unlock interrupt will occur. | ||
2015 | * Note this will clear all status bits | ||
2016 | */ | ||
2017 | regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status); | ||
2018 | |||
2019 | /* | ||
2020 | * Queue jack work in case jack state has just changed but handler | ||
2021 | * hasn't run yet | ||
2022 | */ | ||
2023 | regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask); | ||
2024 | status &= mask; | ||
2025 | if (status & M98090_JDET_MASK) | ||
2026 | queue_delayed_work(system_power_efficient_wq, | ||
2027 | &max98090->jack_work, | ||
2028 | msecs_to_jiffies(100)); | ||
2029 | |||
2030 | /* Enable PLL unlock interrupt */ | ||
2031 | snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, | ||
2032 | M98090_IULK_MASK, | ||
2033 | 1 << M98090_IULK_SHIFT); | ||
2034 | } | ||
2035 | |||
2036 | static void max98090_pll_det_disable_work(struct work_struct *work) | ||
2037 | { | ||
2038 | struct max98090_priv *max98090 = | ||
2039 | container_of(work, struct max98090_priv, pll_det_disable_work); | ||
2040 | struct snd_soc_codec *codec = max98090->codec; | ||
2041 | |||
2042 | cancel_delayed_work_sync(&max98090->pll_det_enable_work); | ||
2043 | |||
2044 | /* Disable PLL unlock interrupt */ | ||
2045 | snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, | ||
2046 | M98090_IULK_MASK, 0); | ||
2047 | } | ||
2048 | |||
2049 | static void max98090_pll_work(struct work_struct *work) | ||
2050 | { | ||
2051 | struct max98090_priv *max98090 = | ||
2052 | container_of(work, struct max98090_priv, pll_work); | ||
2053 | struct snd_soc_codec *codec = max98090->codec; | ||
2054 | |||
2055 | if (!snd_soc_codec_is_active(codec)) | ||
2056 | return; | ||
2057 | |||
2058 | dev_info(codec->dev, "PLL unlocked\n"); | ||
2059 | |||
2060 | /* Toggle shutdown OFF then ON */ | ||
2061 | snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, | ||
2062 | M98090_SHDNN_MASK, 0); | ||
2063 | msleep(10); | ||
2064 | snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, | ||
2065 | M98090_SHDNN_MASK, M98090_SHDNN_MASK); | ||
2066 | |||
2067 | /* Give PLL time to lock */ | ||
2068 | msleep(10); | ||
2069 | } | ||
2070 | |||
1975 | static void max98090_jack_work(struct work_struct *work) | 2071 | static void max98090_jack_work(struct work_struct *work) |
1976 | { | 2072 | { |
1977 | struct max98090_priv *max98090 = container_of(work, | 2073 | struct max98090_priv *max98090 = container_of(work, |
@@ -2063,12 +2159,16 @@ static void max98090_jack_work(struct work_struct *work) | |||
2063 | 2159 | ||
2064 | static irqreturn_t max98090_interrupt(int irq, void *data) | 2160 | static irqreturn_t max98090_interrupt(int irq, void *data) |
2065 | { | 2161 | { |
2066 | struct snd_soc_codec *codec = data; | 2162 | struct max98090_priv *max98090 = data; |
2067 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | 2163 | struct snd_soc_codec *codec = max98090->codec; |
2068 | int ret; | 2164 | int ret; |
2069 | unsigned int mask; | 2165 | unsigned int mask; |
2070 | unsigned int active; | 2166 | unsigned int active; |
2071 | 2167 | ||
2168 | /* Treat interrupt before codec is initialized as spurious */ | ||
2169 | if (codec == NULL) | ||
2170 | return IRQ_NONE; | ||
2171 | |||
2072 | dev_dbg(codec->dev, "***** max98090_interrupt *****\n"); | 2172 | dev_dbg(codec->dev, "***** max98090_interrupt *****\n"); |
2073 | 2173 | ||
2074 | ret = regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask); | 2174 | ret = regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask); |
@@ -2103,8 +2203,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data) | |||
2103 | if (active & M98090_SLD_MASK) | 2203 | if (active & M98090_SLD_MASK) |
2104 | dev_dbg(codec->dev, "M98090_SLD_MASK\n"); | 2204 | dev_dbg(codec->dev, "M98090_SLD_MASK\n"); |
2105 | 2205 | ||
2106 | if (active & M98090_ULK_MASK) | 2206 | if (active & M98090_ULK_MASK) { |
2107 | dev_err(codec->dev, "M98090_ULK_MASK\n"); | 2207 | dev_dbg(codec->dev, "M98090_ULK_MASK\n"); |
2208 | schedule_work(&max98090->pll_work); | ||
2209 | } | ||
2108 | 2210 | ||
2109 | if (active & M98090_JDET_MASK) { | 2211 | if (active & M98090_JDET_MASK) { |
2110 | dev_dbg(codec->dev, "M98090_JDET_MASK\n"); | 2212 | dev_dbg(codec->dev, "M98090_JDET_MASK\n"); |
@@ -2177,6 +2279,7 @@ static struct snd_soc_dai_ops max98090_dai_ops = { | |||
2177 | .set_tdm_slot = max98090_set_tdm_slot, | 2279 | .set_tdm_slot = max98090_set_tdm_slot, |
2178 | .hw_params = max98090_dai_hw_params, | 2280 | .hw_params = max98090_dai_hw_params, |
2179 | .digital_mute = max98090_dai_digital_mute, | 2281 | .digital_mute = max98090_dai_digital_mute, |
2282 | .trigger = max98090_dai_trigger, | ||
2180 | }; | 2283 | }; |
2181 | 2284 | ||
2182 | static struct snd_soc_dai_driver max98090_dai[] = { | 2285 | static struct snd_soc_dai_driver max98090_dai[] = { |
@@ -2230,7 +2333,6 @@ static int max98090_probe(struct snd_soc_codec *codec) | |||
2230 | max98090->lin_state = 0; | 2333 | max98090->lin_state = 0; |
2231 | max98090->pa1en = 0; | 2334 | max98090->pa1en = 0; |
2232 | max98090->pa2en = 0; | 2335 | max98090->pa2en = 0; |
2233 | max98090->extmic_mux = 0; | ||
2234 | 2336 | ||
2235 | ret = snd_soc_read(codec, M98090_REG_REVISION_ID); | 2337 | ret = snd_soc_read(codec, M98090_REG_REVISION_ID); |
2236 | if (ret < 0) { | 2338 | if (ret < 0) { |
@@ -2258,22 +2360,16 @@ static int max98090_probe(struct snd_soc_codec *codec) | |||
2258 | max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; | 2360 | max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; |
2259 | 2361 | ||
2260 | INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); | 2362 | INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); |
2363 | INIT_DELAYED_WORK(&max98090->pll_det_enable_work, | ||
2364 | max98090_pll_det_enable_work); | ||
2365 | INIT_WORK(&max98090->pll_det_disable_work, | ||
2366 | max98090_pll_det_disable_work); | ||
2367 | INIT_WORK(&max98090->pll_work, max98090_pll_work); | ||
2261 | 2368 | ||
2262 | /* Enable jack detection */ | 2369 | /* Enable jack detection */ |
2263 | snd_soc_write(codec, M98090_REG_JACK_DETECT, | 2370 | snd_soc_write(codec, M98090_REG_JACK_DETECT, |
2264 | M98090_JDETEN_MASK | M98090_JDEB_25MS); | 2371 | M98090_JDETEN_MASK | M98090_JDEB_25MS); |
2265 | 2372 | ||
2266 | /* Register for interrupts */ | ||
2267 | dev_dbg(codec->dev, "irq = %d\n", max98090->irq); | ||
2268 | |||
2269 | ret = devm_request_threaded_irq(codec->dev, max98090->irq, NULL, | ||
2270 | max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
2271 | "max98090_interrupt", codec); | ||
2272 | if (ret < 0) { | ||
2273 | dev_err(codec->dev, "request_irq failed: %d\n", | ||
2274 | ret); | ||
2275 | } | ||
2276 | |||
2277 | /* | 2373 | /* |
2278 | * Clear any old interrupts. | 2374 | * Clear any old interrupts. |
2279 | * An old interrupt ocurring prior to installing the ISR | 2375 | * An old interrupt ocurring prior to installing the ISR |
@@ -2310,6 +2406,10 @@ static int max98090_remove(struct snd_soc_codec *codec) | |||
2310 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | 2406 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); |
2311 | 2407 | ||
2312 | cancel_delayed_work_sync(&max98090->jack_work); | 2408 | cancel_delayed_work_sync(&max98090->jack_work); |
2409 | cancel_delayed_work_sync(&max98090->pll_det_enable_work); | ||
2410 | cancel_work_sync(&max98090->pll_det_disable_work); | ||
2411 | cancel_work_sync(&max98090->pll_work); | ||
2412 | max98090->codec = NULL; | ||
2313 | 2413 | ||
2314 | return 0; | 2414 | return 0; |
2315 | } | 2415 | } |
@@ -2362,7 +2462,6 @@ static int max98090_i2c_probe(struct i2c_client *i2c, | |||
2362 | max98090->devtype = driver_data; | 2462 | max98090->devtype = driver_data; |
2363 | i2c_set_clientdata(i2c, max98090); | 2463 | i2c_set_clientdata(i2c, max98090); |
2364 | max98090->pdata = i2c->dev.platform_data; | 2464 | max98090->pdata = i2c->dev.platform_data; |
2365 | max98090->irq = i2c->irq; | ||
2366 | 2465 | ||
2367 | max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); | 2466 | max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); |
2368 | if (IS_ERR(max98090->regmap)) { | 2467 | if (IS_ERR(max98090->regmap)) { |
@@ -2371,6 +2470,15 @@ static int max98090_i2c_probe(struct i2c_client *i2c, | |||
2371 | goto err_enable; | 2470 | goto err_enable; |
2372 | } | 2471 | } |
2373 | 2472 | ||
2473 | ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, | ||
2474 | max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
2475 | "max98090_interrupt", max98090); | ||
2476 | if (ret < 0) { | ||
2477 | dev_err(&i2c->dev, "request_irq failed: %d\n", | ||
2478 | ret); | ||
2479 | return ret; | ||
2480 | } | ||
2481 | |||
2374 | ret = snd_soc_register_codec(&i2c->dev, | 2482 | ret = snd_soc_register_codec(&i2c->dev, |
2375 | &soc_codec_dev_max98090, max98090_dai, | 2483 | &soc_codec_dev_max98090, max98090_dai, |
2376 | ARRAY_SIZE(max98090_dai)); | 2484 | ARRAY_SIZE(max98090_dai)); |
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index cf1b6062ba8c..a5f6bada06da 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h | |||
@@ -11,11 +11,6 @@ | |||
11 | #ifndef _MAX98090_H | 11 | #ifndef _MAX98090_H |
12 | #define _MAX98090_H | 12 | #define _MAX98090_H |
13 | 13 | ||
14 | #include <linux/version.h> | ||
15 | |||
16 | /* One can override the Linux version here with an explicit version number */ | ||
17 | #define M98090_LINUX_VERSION LINUX_VERSION_CODE | ||
18 | |||
19 | /* | 14 | /* |
20 | * MAX98090 Register Definitions | 15 | * MAX98090 Register Definitions |
21 | */ | 16 | */ |
@@ -1502,9 +1497,6 @@ | |||
1502 | #define M98090_REVID_WIDTH 8 | 1497 | #define M98090_REVID_WIDTH 8 |
1503 | #define M98090_REVID_NUM (1<<M98090_REVID_WIDTH) | 1498 | #define M98090_REVID_NUM (1<<M98090_REVID_WIDTH) |
1504 | 1499 | ||
1505 | #define M98090_BYTE1(w) ((w >> 8) & 0xff) | ||
1506 | #define M98090_BYTE0(w) (w & 0xff) | ||
1507 | |||
1508 | /* Silicon revision number */ | 1500 | /* Silicon revision number */ |
1509 | #define M98090_REVA 0x40 | 1501 | #define M98090_REVA 0x40 |
1510 | #define M98091_REVA 0x50 | 1502 | #define M98091_REVA 0x50 |
@@ -1529,9 +1521,11 @@ struct max98090_priv { | |||
1529 | unsigned int bclk; | 1521 | unsigned int bclk; |
1530 | unsigned int lrclk; | 1522 | unsigned int lrclk; |
1531 | struct max98090_cdata dai[1]; | 1523 | struct max98090_cdata dai[1]; |
1532 | int irq; | ||
1533 | int jack_state; | 1524 | int jack_state; |
1534 | struct delayed_work jack_work; | 1525 | struct delayed_work jack_work; |
1526 | struct delayed_work pll_det_enable_work; | ||
1527 | struct work_struct pll_det_disable_work; | ||
1528 | struct work_struct pll_work; | ||
1535 | struct snd_soc_jack *jack; | 1529 | struct snd_soc_jack *jack; |
1536 | unsigned int dai_fmt; | 1530 | unsigned int dai_fmt; |
1537 | int tdm_slots; | 1531 | int tdm_slots; |
@@ -1539,7 +1533,6 @@ struct max98090_priv { | |||
1539 | u8 lin_state; | 1533 | u8 lin_state; |
1540 | unsigned int pa1en; | 1534 | unsigned int pa1en; |
1541 | unsigned int pa2en; | 1535 | unsigned int pa2en; |
1542 | unsigned int extmic_mux; | ||
1543 | unsigned int sidetone; | 1536 | unsigned int sidetone; |
1544 | bool master; | 1537 | bool master; |
1545 | }; | 1538 | }; |
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index e661e8420e3d..711f55039522 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c | |||
@@ -565,41 +565,19 @@ static struct snd_soc_dai_driver ml26124_dai = { | |||
565 | .symmetric_rates = 1, | 565 | .symmetric_rates = 1, |
566 | }; | 566 | }; |
567 | 567 | ||
568 | #ifdef CONFIG_PM | ||
569 | static int ml26124_suspend(struct snd_soc_codec *codec) | ||
570 | { | ||
571 | ml26124_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
572 | |||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static int ml26124_resume(struct snd_soc_codec *codec) | ||
577 | { | ||
578 | ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
579 | |||
580 | return 0; | ||
581 | } | ||
582 | #else | ||
583 | #define ml26124_suspend NULL | ||
584 | #define ml26124_resume NULL | ||
585 | #endif | ||
586 | |||
587 | static int ml26124_probe(struct snd_soc_codec *codec) | 568 | static int ml26124_probe(struct snd_soc_codec *codec) |
588 | { | 569 | { |
589 | /* Software Reset */ | 570 | /* Software Reset */ |
590 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1); | 571 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1); |
591 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0); | 572 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0); |
592 | 573 | ||
593 | ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
594 | |||
595 | return 0; | 574 | return 0; |
596 | } | 575 | } |
597 | 576 | ||
598 | static struct snd_soc_codec_driver soc_codec_dev_ml26124 = { | 577 | static struct snd_soc_codec_driver soc_codec_dev_ml26124 = { |
599 | .probe = ml26124_probe, | 578 | .probe = ml26124_probe, |
600 | .suspend = ml26124_suspend, | ||
601 | .resume = ml26124_resume, | ||
602 | .set_bias_level = ml26124_set_bias_level, | 579 | .set_bias_level = ml26124_set_bias_level, |
580 | .suspend_bias_off = true, | ||
603 | .dapm_widgets = ml26124_dapm_widgets, | 581 | .dapm_widgets = ml26124_dapm_widgets, |
604 | .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), | 582 | .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), |
605 | .dapm_routes = ml26124_intercon, | 583 | .dapm_routes = ml26124_intercon, |
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index e4f6102efc1a..4aa555cbcca8 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -51,7 +51,7 @@ static struct reg_default rt286_index_def[] = { | |||
51 | { 0x04, 0xaf01 }, | 51 | { 0x04, 0xaf01 }, |
52 | { 0x08, 0x000d }, | 52 | { 0x08, 0x000d }, |
53 | { 0x09, 0xd810 }, | 53 | { 0x09, 0xd810 }, |
54 | { 0x0a, 0x0060 }, | 54 | { 0x0a, 0x0120 }, |
55 | { 0x0b, 0x0000 }, | 55 | { 0x0b, 0x0000 }, |
56 | { 0x0d, 0x2800 }, | 56 | { 0x0d, 0x2800 }, |
57 | { 0x0f, 0x0000 }, | 57 | { 0x0f, 0x0000 }, |
@@ -60,7 +60,7 @@ static struct reg_default rt286_index_def[] = { | |||
60 | { 0x33, 0x0208 }, | 60 | { 0x33, 0x0208 }, |
61 | { 0x49, 0x0004 }, | 61 | { 0x49, 0x0004 }, |
62 | { 0x4f, 0x50e9 }, | 62 | { 0x4f, 0x50e9 }, |
63 | { 0x50, 0x2c00 }, | 63 | { 0x50, 0x2000 }, |
64 | { 0x63, 0x2902 }, | 64 | { 0x63, 0x2902 }, |
65 | { 0x67, 0x1111 }, | 65 | { 0x67, 0x1111 }, |
66 | { 0x68, 0x1016 }, | 66 | { 0x68, 0x1016 }, |
@@ -104,7 +104,6 @@ static const struct reg_default rt286_reg[] = { | |||
104 | { 0x02170700, 0x00000000 }, | 104 | { 0x02170700, 0x00000000 }, |
105 | { 0x02270100, 0x00000000 }, | 105 | { 0x02270100, 0x00000000 }, |
106 | { 0x02370100, 0x00000000 }, | 106 | { 0x02370100, 0x00000000 }, |
107 | { 0x02040000, 0x00004002 }, | ||
108 | { 0x01870700, 0x00000020 }, | 107 | { 0x01870700, 0x00000020 }, |
109 | { 0x00830000, 0x000000c3 }, | 108 | { 0x00830000, 0x000000c3 }, |
110 | { 0x00930000, 0x000000c3 }, | 109 | { 0x00930000, 0x000000c3 }, |
@@ -192,7 +191,6 @@ static int rt286_hw_write(void *context, unsigned int reg, unsigned int value) | |||
192 | /*handle index registers*/ | 191 | /*handle index registers*/ |
193 | if (reg <= 0xff) { | 192 | if (reg <= 0xff) { |
194 | rt286_hw_write(client, RT286_COEF_INDEX, reg); | 193 | rt286_hw_write(client, RT286_COEF_INDEX, reg); |
195 | reg = RT286_PROC_COEF; | ||
196 | for (i = 0; i < INDEX_CACHE_SIZE; i++) { | 194 | for (i = 0; i < INDEX_CACHE_SIZE; i++) { |
197 | if (reg == rt286->index_cache[i].reg) { | 195 | if (reg == rt286->index_cache[i].reg) { |
198 | rt286->index_cache[i].def = value; | 196 | rt286->index_cache[i].def = value; |
@@ -200,6 +198,7 @@ static int rt286_hw_write(void *context, unsigned int reg, unsigned int value) | |||
200 | } | 198 | } |
201 | 199 | ||
202 | } | 200 | } |
201 | reg = RT286_PROC_COEF; | ||
203 | } | 202 | } |
204 | 203 | ||
205 | data[0] = (reg >> 24) & 0xff; | 204 | data[0] = (reg >> 24) & 0xff; |
@@ -270,6 +269,7 @@ static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value) | |||
270 | return 0; | 269 | return 0; |
271 | } | 270 | } |
272 | 271 | ||
272 | #ifdef CONFIG_PM | ||
273 | static void rt286_index_sync(struct snd_soc_codec *codec) | 273 | static void rt286_index_sync(struct snd_soc_codec *codec) |
274 | { | 274 | { |
275 | struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); | 275 | struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); |
@@ -280,6 +280,7 @@ static void rt286_index_sync(struct snd_soc_codec *codec) | |||
280 | rt286->index_cache[i].def); | 280 | rt286->index_cache[i].def); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | #endif | ||
283 | 284 | ||
284 | static int rt286_support_power_controls[] = { | 285 | static int rt286_support_power_controls[] = { |
285 | RT286_DAC_OUT1, | 286 | RT286_DAC_OUT1, |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index f1ec6e6bd08a..c3f2decd643c 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -1906,6 +1906,32 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, | |||
1906 | return 0; | 1906 | return 0; |
1907 | } | 1907 | } |
1908 | 1908 | ||
1909 | int rt5640_dmic_enable(struct snd_soc_codec *codec, | ||
1910 | bool dmic1_data_pin, bool dmic2_data_pin) | ||
1911 | { | ||
1912 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
1913 | |||
1914 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
1915 | RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); | ||
1916 | |||
1917 | if (dmic1_data_pin) { | ||
1918 | regmap_update_bits(rt5640->regmap, RT5640_DMIC, | ||
1919 | RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3); | ||
1920 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
1921 | RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA); | ||
1922 | } | ||
1923 | |||
1924 | if (dmic2_data_pin) { | ||
1925 | regmap_update_bits(rt5640->regmap, RT5640_DMIC, | ||
1926 | RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4); | ||
1927 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
1928 | RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA); | ||
1929 | } | ||
1930 | |||
1931 | return 0; | ||
1932 | } | ||
1933 | EXPORT_SYMBOL_GPL(rt5640_dmic_enable); | ||
1934 | |||
1909 | static int rt5640_probe(struct snd_soc_codec *codec) | 1935 | static int rt5640_probe(struct snd_soc_codec *codec) |
1910 | { | 1936 | { |
1911 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 1937 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
@@ -1945,6 +1971,10 @@ static int rt5640_probe(struct snd_soc_codec *codec) | |||
1945 | return -ENODEV; | 1971 | return -ENODEV; |
1946 | } | 1972 | } |
1947 | 1973 | ||
1974 | if (rt5640->pdata.dmic_en) | ||
1975 | rt5640_dmic_enable(codec, rt5640->pdata.dmic1_data_pin, | ||
1976 | rt5640->pdata.dmic2_data_pin); | ||
1977 | |||
1948 | return 0; | 1978 | return 0; |
1949 | } | 1979 | } |
1950 | 1980 | ||
@@ -2195,25 +2225,6 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, | |||
2195 | regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, | 2225 | regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, |
2196 | RT5640_IN_DF2, RT5640_IN_DF2); | 2226 | RT5640_IN_DF2, RT5640_IN_DF2); |
2197 | 2227 | ||
2198 | if (rt5640->pdata.dmic_en) { | ||
2199 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
2200 | RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); | ||
2201 | |||
2202 | if (rt5640->pdata.dmic1_data_pin) { | ||
2203 | regmap_update_bits(rt5640->regmap, RT5640_DMIC, | ||
2204 | RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3); | ||
2205 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
2206 | RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA); | ||
2207 | } | ||
2208 | |||
2209 | if (rt5640->pdata.dmic2_data_pin) { | ||
2210 | regmap_update_bits(rt5640->regmap, RT5640_DMIC, | ||
2211 | RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4); | ||
2212 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
2213 | RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA); | ||
2214 | } | ||
2215 | } | ||
2216 | |||
2217 | rt5640->hp_mute = 1; | 2228 | rt5640->hp_mute = 1; |
2218 | 2229 | ||
2219 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, | 2230 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, |
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 58ebe96b86da..3deb8babeabb 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h | |||
@@ -2097,4 +2097,7 @@ struct rt5640_priv { | |||
2097 | bool hp_mute; | 2097 | bool hp_mute; |
2098 | }; | 2098 | }; |
2099 | 2099 | ||
2100 | int rt5640_dmic_enable(struct snd_soc_codec *codec, | ||
2101 | bool dmic1_data_pin, bool dmic2_data_pin); | ||
2102 | |||
2100 | #endif | 2103 | #endif |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index a7762d0a623e..3fb83bf09768 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
20 | #include <linux/gpio.h> | ||
20 | #include <sound/core.h> | 21 | #include <sound/core.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
22 | #include <sound/pcm_params.h> | 23 | #include <sound/pcm_params.h> |
@@ -2103,6 +2104,77 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, | |||
2103 | return 0; | 2104 | return 0; |
2104 | } | 2105 | } |
2105 | 2106 | ||
2107 | static int rt5645_jack_detect(struct snd_soc_codec *codec, | ||
2108 | struct snd_soc_jack *jack) | ||
2109 | { | ||
2110 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
2111 | int gpio_state, jack_type = 0; | ||
2112 | unsigned int val; | ||
2113 | |||
2114 | gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); | ||
2115 | |||
2116 | dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio, | ||
2117 | gpio_state); | ||
2118 | |||
2119 | if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) || | ||
2120 | (!rt5645->pdata.gpio_hp_det_active_high && !gpio_state)) { | ||
2121 | snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias1"); | ||
2122 | snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias2"); | ||
2123 | snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); | ||
2124 | snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power"); | ||
2125 | snd_soc_dapm_sync(&codec->dapm); | ||
2126 | |||
2127 | snd_soc_write(codec, RT5645_IN1_CTRL1, 0x0006); | ||
2128 | snd_soc_write(codec, RT5645_JD_CTRL3, 0x00b0); | ||
2129 | |||
2130 | snd_soc_update_bits(codec, RT5645_IN1_CTRL2, | ||
2131 | RT5645_CBJ_MN_JD, 0); | ||
2132 | snd_soc_update_bits(codec, RT5645_IN1_CTRL2, | ||
2133 | RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD); | ||
2134 | |||
2135 | msleep(400); | ||
2136 | val = snd_soc_read(codec, RT5645_IN1_CTRL3) & 0x7; | ||
2137 | dev_dbg(codec->dev, "val = %d\n", val); | ||
2138 | |||
2139 | if (val == 1 || val == 2) | ||
2140 | jack_type = SND_JACK_HEADSET; | ||
2141 | else | ||
2142 | jack_type = SND_JACK_HEADPHONE; | ||
2143 | |||
2144 | snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); | ||
2145 | snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); | ||
2146 | snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); | ||
2147 | snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); | ||
2148 | snd_soc_dapm_sync(&codec->dapm); | ||
2149 | } | ||
2150 | |||
2151 | snd_soc_jack_report(rt5645->jack, jack_type, SND_JACK_HEADSET); | ||
2152 | |||
2153 | return 0; | ||
2154 | } | ||
2155 | |||
2156 | int rt5645_set_jack_detect(struct snd_soc_codec *codec, | ||
2157 | struct snd_soc_jack *jack) | ||
2158 | { | ||
2159 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
2160 | |||
2161 | rt5645->jack = jack; | ||
2162 | |||
2163 | rt5645_jack_detect(codec, rt5645->jack); | ||
2164 | |||
2165 | return 0; | ||
2166 | } | ||
2167 | EXPORT_SYMBOL_GPL(rt5645_set_jack_detect); | ||
2168 | |||
2169 | static irqreturn_t rt5645_irq(int irq, void *data) | ||
2170 | { | ||
2171 | struct rt5645_priv *rt5645 = data; | ||
2172 | |||
2173 | rt5645_jack_detect(rt5645->codec, rt5645->jack); | ||
2174 | |||
2175 | return IRQ_HANDLED; | ||
2176 | } | ||
2177 | |||
2106 | static int rt5645_probe(struct snd_soc_codec *codec) | 2178 | static int rt5645_probe(struct snd_soc_codec *codec) |
2107 | { | 2179 | { |
2108 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | 2180 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); |
@@ -2250,6 +2322,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2250 | if (rt5645 == NULL) | 2322 | if (rt5645 == NULL) |
2251 | return -ENOMEM; | 2323 | return -ENOMEM; |
2252 | 2324 | ||
2325 | rt5645->i2c = i2c; | ||
2253 | i2c_set_clientdata(i2c, rt5645); | 2326 | i2c_set_clientdata(i2c, rt5645); |
2254 | 2327 | ||
2255 | if (pdata) | 2328 | if (pdata) |
@@ -2345,12 +2418,38 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2345 | 2418 | ||
2346 | } | 2419 | } |
2347 | 2420 | ||
2421 | if (rt5645->i2c->irq) { | ||
2422 | ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, | ||
2423 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | ||
2424 | | IRQF_ONESHOT, "rt5645", rt5645); | ||
2425 | if (ret) | ||
2426 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); | ||
2427 | } | ||
2428 | |||
2429 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { | ||
2430 | ret = gpio_request(rt5645->pdata.hp_det_gpio, "rt5645"); | ||
2431 | if (ret) | ||
2432 | dev_err(&i2c->dev, "Fail gpio_request hp_det_gpio\n"); | ||
2433 | |||
2434 | ret = gpio_direction_input(rt5645->pdata.hp_det_gpio); | ||
2435 | if (ret) | ||
2436 | dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); | ||
2437 | } | ||
2438 | |||
2348 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, | 2439 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, |
2349 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); | 2440 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); |
2350 | } | 2441 | } |
2351 | 2442 | ||
2352 | static int rt5645_i2c_remove(struct i2c_client *i2c) | 2443 | static int rt5645_i2c_remove(struct i2c_client *i2c) |
2353 | { | 2444 | { |
2445 | struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c); | ||
2446 | |||
2447 | if (i2c->irq) | ||
2448 | free_irq(i2c->irq, rt5645); | ||
2449 | |||
2450 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) | ||
2451 | gpio_free(rt5645->pdata.hp_det_gpio); | ||
2452 | |||
2354 | snd_soc_unregister_codec(&i2c->dev); | 2453 | snd_soc_unregister_codec(&i2c->dev); |
2355 | 2454 | ||
2356 | return 0; | 2455 | return 0; |
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 355b7e9eefab..50c62c5668ea 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h | |||
@@ -2166,6 +2166,8 @@ struct rt5645_priv { | |||
2166 | struct snd_soc_codec *codec; | 2166 | struct snd_soc_codec *codec; |
2167 | struct rt5645_platform_data pdata; | 2167 | struct rt5645_platform_data pdata; |
2168 | struct regmap *regmap; | 2168 | struct regmap *regmap; |
2169 | struct i2c_client *i2c; | ||
2170 | struct snd_soc_jack *jack; | ||
2169 | 2171 | ||
2170 | int sysclk; | 2172 | int sysclk; |
2171 | int sysclk_src; | 2173 | int sysclk_src; |
@@ -2178,4 +2180,7 @@ struct rt5645_priv { | |||
2178 | int pll_out; | 2180 | int pll_out; |
2179 | }; | 2181 | }; |
2180 | 2182 | ||
2183 | int rt5645_set_jack_detect(struct snd_soc_codec *codec, | ||
2184 | struct snd_soc_jack *jack); | ||
2185 | |||
2181 | #endif /* __RT5645_H__ */ | 2186 | #endif /* __RT5645_H__ */ |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 5337c448b5e3..16aa4d99a713 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
@@ -15,10 +15,12 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/of_gpio.h> | ||
18 | #include <linux/regmap.h> | 19 | #include <linux/regmap.h> |
19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
23 | #include <linux/gpio.h> | ||
22 | #include <sound/core.h> | 24 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
24 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
@@ -540,6 +542,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); | |||
540 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | 542 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); |
541 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | 543 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); |
542 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | 544 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); |
545 | static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0); | ||
543 | 546 | ||
544 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | 547 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ |
545 | static unsigned int bst_tlv[] = { | 548 | static unsigned int bst_tlv[] = { |
@@ -604,6 +607,10 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = { | |||
604 | RT5677_MONO_ADC_L_VOL_SFT, RT5677_MONO_ADC_R_VOL_SFT, 127, 0, | 607 | RT5677_MONO_ADC_L_VOL_SFT, RT5677_MONO_ADC_R_VOL_SFT, 127, 0, |
605 | adc_vol_tlv), | 608 | adc_vol_tlv), |
606 | 609 | ||
610 | /* Sidetone Control */ | ||
611 | SOC_SINGLE_TLV("Sidetone Volume", RT5677_SIDETONE_CTRL, | ||
612 | RT5677_ST_VOL_SFT, 31, 0, st_vol_tlv), | ||
613 | |||
607 | /* ADC Boost Volume Control */ | 614 | /* ADC Boost Volume Control */ |
608 | SOC_DOUBLE_TLV("STO1 ADC Boost Volume", RT5677_STO1_2_ADC_BST, | 615 | SOC_DOUBLE_TLV("STO1 ADC Boost Volume", RT5677_STO1_2_ADC_BST, |
609 | RT5677_STO1_ADC_L_BST_SFT, RT5677_STO1_ADC_R_BST_SFT, 3, 0, | 616 | RT5677_STO1_ADC_L_BST_SFT, RT5677_STO1_ADC_R_BST_SFT, 3, 0, |
@@ -1700,14 +1707,19 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
1700 | 1707 | ||
1701 | SND_SOC_DAPM_INPUT("Haptic Generator"), | 1708 | SND_SOC_DAPM_INPUT("Haptic Generator"), |
1702 | 1709 | ||
1703 | SND_SOC_DAPM_PGA("DMIC1", RT5677_DMIC_CTRL1, RT5677_DMIC_1_EN_SFT, 0, | 1710 | SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), |
1704 | NULL, 0), | 1711 | SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), |
1705 | SND_SOC_DAPM_PGA("DMIC2", RT5677_DMIC_CTRL1, RT5677_DMIC_2_EN_SFT, 0, | 1712 | SND_SOC_DAPM_PGA("DMIC3", SND_SOC_NOPM, 0, 0, NULL, 0), |
1706 | NULL, 0), | 1713 | SND_SOC_DAPM_PGA("DMIC4", SND_SOC_NOPM, 0, 0, NULL, 0), |
1707 | SND_SOC_DAPM_PGA("DMIC3", RT5677_DMIC_CTRL1, RT5677_DMIC_3_EN_SFT, 0, | 1714 | |
1708 | NULL, 0), | 1715 | SND_SOC_DAPM_SUPPLY("DMIC1 power", RT5677_DMIC_CTRL1, |
1709 | SND_SOC_DAPM_PGA("DMIC4", RT5677_DMIC_CTRL2, RT5677_DMIC_4_EN_SFT, 0, | 1716 | RT5677_DMIC_1_EN_SFT, 0, NULL, 0), |
1710 | NULL, 0), | 1717 | SND_SOC_DAPM_SUPPLY("DMIC2 power", RT5677_DMIC_CTRL1, |
1718 | RT5677_DMIC_2_EN_SFT, 0, NULL, 0), | ||
1719 | SND_SOC_DAPM_SUPPLY("DMIC3 power", RT5677_DMIC_CTRL1, | ||
1720 | RT5677_DMIC_3_EN_SFT, 0, NULL, 0), | ||
1721 | SND_SOC_DAPM_SUPPLY("DMIC4 power", RT5677_DMIC_CTRL2, | ||
1722 | RT5677_DMIC_4_EN_SFT, 0, NULL, 0), | ||
1711 | 1723 | ||
1712 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | 1724 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, |
1713 | set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | 1725 | set_dmic_clk, SND_SOC_DAPM_PRE_PMU), |
@@ -1987,6 +1999,9 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
1987 | /* Sidetone Mux */ | 1999 | /* Sidetone Mux */ |
1988 | SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0, | 2000 | SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0, |
1989 | &rt5677_sidetone_mux), | 2001 | &rt5677_sidetone_mux), |
2002 | SND_SOC_DAPM_SUPPLY("Sidetone Power", RT5677_SIDETONE_CTRL, | ||
2003 | RT5677_ST_EN_SFT, 0, NULL, 0), | ||
2004 | |||
1990 | /* VAD Mux*/ | 2005 | /* VAD Mux*/ |
1991 | SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0, | 2006 | SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0, |
1992 | &rt5677_vad_src_mux), | 2007 | &rt5677_vad_src_mux), |
@@ -2130,6 +2145,13 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2130 | { "DMIC L4", NULL, "DMIC CLK" }, | 2145 | { "DMIC L4", NULL, "DMIC CLK" }, |
2131 | { "DMIC R4", NULL, "DMIC CLK" }, | 2146 | { "DMIC R4", NULL, "DMIC CLK" }, |
2132 | 2147 | ||
2148 | { "DMIC L1", NULL, "DMIC1 power" }, | ||
2149 | { "DMIC R1", NULL, "DMIC1 power" }, | ||
2150 | { "DMIC L3", NULL, "DMIC3 power" }, | ||
2151 | { "DMIC R3", NULL, "DMIC3 power" }, | ||
2152 | { "DMIC L4", NULL, "DMIC4 power" }, | ||
2153 | { "DMIC R4", NULL, "DMIC4 power" }, | ||
2154 | |||
2133 | { "BST1", NULL, "IN1P" }, | 2155 | { "BST1", NULL, "IN1P" }, |
2134 | { "BST1", NULL, "IN1N" }, | 2156 | { "BST1", NULL, "IN1N" }, |
2135 | { "BST2", NULL, "IN2P" }, | 2157 | { "BST2", NULL, "IN2P" }, |
@@ -2691,6 +2713,7 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2691 | { "Sidetone Mux", "DMIC4 L", "DMIC L4" }, | 2713 | { "Sidetone Mux", "DMIC4 L", "DMIC L4" }, |
2692 | { "Sidetone Mux", "ADC1", "ADC 1" }, | 2714 | { "Sidetone Mux", "ADC1", "ADC 1" }, |
2693 | { "Sidetone Mux", "ADC2", "ADC 2" }, | 2715 | { "Sidetone Mux", "ADC2", "ADC 2" }, |
2716 | { "Sidetone Mux", NULL, "Sidetone Power" }, | ||
2694 | 2717 | ||
2695 | { "Stereo DAC MIXL", "ST L Switch", "Sidetone Mux" }, | 2718 | { "Stereo DAC MIXL", "ST L Switch", "Sidetone Mux" }, |
2696 | { "Stereo DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" }, | 2719 | { "Stereo DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" }, |
@@ -2793,6 +2816,16 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2793 | { "PDM2R", NULL, "PDM2 R Mux" }, | 2816 | { "PDM2R", NULL, "PDM2 R Mux" }, |
2794 | }; | 2817 | }; |
2795 | 2818 | ||
2819 | static const struct snd_soc_dapm_route rt5677_dmic2_clk_1[] = { | ||
2820 | { "DMIC L2", NULL, "DMIC1 power" }, | ||
2821 | { "DMIC R2", NULL, "DMIC1 power" }, | ||
2822 | }; | ||
2823 | |||
2824 | static const struct snd_soc_dapm_route rt5677_dmic2_clk_2[] = { | ||
2825 | { "DMIC L2", NULL, "DMIC2 power" }, | ||
2826 | { "DMIC R2", NULL, "DMIC2 power" }, | ||
2827 | }; | ||
2828 | |||
2796 | static int rt5677_hw_params(struct snd_pcm_substream *substream, | 2829 | static int rt5677_hw_params(struct snd_pcm_substream *substream, |
2797 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 2830 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
2798 | { | 2831 | { |
@@ -3084,6 +3117,59 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | |||
3084 | return 0; | 3117 | return 0; |
3085 | } | 3118 | } |
3086 | 3119 | ||
3120 | static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
3121 | unsigned int rx_mask, int slots, int slot_width) | ||
3122 | { | ||
3123 | struct snd_soc_codec *codec = dai->codec; | ||
3124 | unsigned int val = 0; | ||
3125 | |||
3126 | if (rx_mask || tx_mask) | ||
3127 | val |= (1 << 12); | ||
3128 | |||
3129 | switch (slots) { | ||
3130 | case 4: | ||
3131 | val |= (1 << 10); | ||
3132 | break; | ||
3133 | case 6: | ||
3134 | val |= (2 << 10); | ||
3135 | break; | ||
3136 | case 8: | ||
3137 | val |= (3 << 10); | ||
3138 | break; | ||
3139 | case 2: | ||
3140 | default: | ||
3141 | break; | ||
3142 | } | ||
3143 | |||
3144 | switch (slot_width) { | ||
3145 | case 20: | ||
3146 | val |= (1 << 8); | ||
3147 | break; | ||
3148 | case 24: | ||
3149 | val |= (2 << 8); | ||
3150 | break; | ||
3151 | case 32: | ||
3152 | val |= (3 << 8); | ||
3153 | break; | ||
3154 | case 16: | ||
3155 | default: | ||
3156 | break; | ||
3157 | } | ||
3158 | |||
3159 | switch (dai->id) { | ||
3160 | case RT5677_AIF1: | ||
3161 | snd_soc_update_bits(codec, RT5677_TDM1_CTRL1, 0x1f00, val); | ||
3162 | break; | ||
3163 | case RT5677_AIF2: | ||
3164 | snd_soc_update_bits(codec, RT5677_TDM2_CTRL1, 0x1f00, val); | ||
3165 | break; | ||
3166 | default: | ||
3167 | break; | ||
3168 | } | ||
3169 | |||
3170 | return 0; | ||
3171 | } | ||
3172 | |||
3087 | static int rt5677_set_bias_level(struct snd_soc_codec *codec, | 3173 | static int rt5677_set_bias_level(struct snd_soc_codec *codec, |
3088 | enum snd_soc_bias_level level) | 3174 | enum snd_soc_bias_level level) |
3089 | { | 3175 | { |
@@ -3138,12 +3224,148 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec, | |||
3138 | return 0; | 3224 | return 0; |
3139 | } | 3225 | } |
3140 | 3226 | ||
3227 | #ifdef CONFIG_GPIOLIB | ||
3228 | static inline struct rt5677_priv *gpio_to_rt5677(struct gpio_chip *chip) | ||
3229 | { | ||
3230 | return container_of(chip, struct rt5677_priv, gpio_chip); | ||
3231 | } | ||
3232 | |||
3233 | static void rt5677_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
3234 | { | ||
3235 | struct rt5677_priv *rt5677 = gpio_to_rt5677(chip); | ||
3236 | |||
3237 | switch (offset) { | ||
3238 | case RT5677_GPIO1 ... RT5677_GPIO5: | ||
3239 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2, | ||
3240 | 0x1 << (offset * 3 + 1), !!value << (offset * 3 + 1)); | ||
3241 | break; | ||
3242 | |||
3243 | case RT5677_GPIO6: | ||
3244 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3, | ||
3245 | RT5677_GPIO6_OUT_MASK, !!value << RT5677_GPIO6_OUT_SFT); | ||
3246 | break; | ||
3247 | |||
3248 | default: | ||
3249 | break; | ||
3250 | } | ||
3251 | } | ||
3252 | |||
3253 | static int rt5677_gpio_direction_out(struct gpio_chip *chip, | ||
3254 | unsigned offset, int value) | ||
3255 | { | ||
3256 | struct rt5677_priv *rt5677 = gpio_to_rt5677(chip); | ||
3257 | |||
3258 | switch (offset) { | ||
3259 | case RT5677_GPIO1 ... RT5677_GPIO5: | ||
3260 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2, | ||
3261 | 0x3 << (offset * 3 + 1), | ||
3262 | (0x2 | !!value) << (offset * 3 + 1)); | ||
3263 | break; | ||
3264 | |||
3265 | case RT5677_GPIO6: | ||
3266 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3, | ||
3267 | RT5677_GPIO6_DIR_MASK | RT5677_GPIO6_OUT_MASK, | ||
3268 | RT5677_GPIO6_DIR_OUT | !!value << RT5677_GPIO6_OUT_SFT); | ||
3269 | break; | ||
3270 | |||
3271 | default: | ||
3272 | break; | ||
3273 | } | ||
3274 | |||
3275 | return 0; | ||
3276 | } | ||
3277 | |||
3278 | static int rt5677_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
3279 | { | ||
3280 | struct rt5677_priv *rt5677 = gpio_to_rt5677(chip); | ||
3281 | int value, ret; | ||
3282 | |||
3283 | ret = regmap_read(rt5677->regmap, RT5677_GPIO_ST, &value); | ||
3284 | if (ret < 0) | ||
3285 | return ret; | ||
3286 | |||
3287 | return (value & (0x1 << offset)) >> offset; | ||
3288 | } | ||
3289 | |||
3290 | static int rt5677_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | ||
3291 | { | ||
3292 | struct rt5677_priv *rt5677 = gpio_to_rt5677(chip); | ||
3293 | |||
3294 | switch (offset) { | ||
3295 | case RT5677_GPIO1 ... RT5677_GPIO5: | ||
3296 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2, | ||
3297 | 0x1 << (offset * 3 + 2), 0x0); | ||
3298 | break; | ||
3299 | |||
3300 | case RT5677_GPIO6: | ||
3301 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3, | ||
3302 | RT5677_GPIO6_DIR_MASK, RT5677_GPIO6_DIR_IN); | ||
3303 | break; | ||
3304 | |||
3305 | default: | ||
3306 | break; | ||
3307 | } | ||
3308 | |||
3309 | return 0; | ||
3310 | } | ||
3311 | |||
3312 | static struct gpio_chip rt5677_template_chip = { | ||
3313 | .label = "rt5677", | ||
3314 | .owner = THIS_MODULE, | ||
3315 | .direction_output = rt5677_gpio_direction_out, | ||
3316 | .set = rt5677_gpio_set, | ||
3317 | .direction_input = rt5677_gpio_direction_in, | ||
3318 | .get = rt5677_gpio_get, | ||
3319 | .can_sleep = 1, | ||
3320 | }; | ||
3321 | |||
3322 | static void rt5677_init_gpio(struct i2c_client *i2c) | ||
3323 | { | ||
3324 | struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); | ||
3325 | int ret; | ||
3326 | |||
3327 | rt5677->gpio_chip = rt5677_template_chip; | ||
3328 | rt5677->gpio_chip.ngpio = RT5677_GPIO_NUM; | ||
3329 | rt5677->gpio_chip.dev = &i2c->dev; | ||
3330 | rt5677->gpio_chip.base = -1; | ||
3331 | |||
3332 | ret = gpiochip_add(&rt5677->gpio_chip); | ||
3333 | if (ret != 0) | ||
3334 | dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret); | ||
3335 | } | ||
3336 | |||
3337 | static void rt5677_free_gpio(struct i2c_client *i2c) | ||
3338 | { | ||
3339 | struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); | ||
3340 | |||
3341 | gpiochip_remove(&rt5677->gpio_chip); | ||
3342 | } | ||
3343 | #else | ||
3344 | static void rt5677_init_gpio(struct i2c_client *i2c) | ||
3345 | { | ||
3346 | } | ||
3347 | |||
3348 | static void rt5677_free_gpio(struct i2c_client *i2c) | ||
3349 | { | ||
3350 | } | ||
3351 | #endif | ||
3352 | |||
3141 | static int rt5677_probe(struct snd_soc_codec *codec) | 3353 | static int rt5677_probe(struct snd_soc_codec *codec) |
3142 | { | 3354 | { |
3143 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 3355 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
3144 | 3356 | ||
3145 | rt5677->codec = codec; | 3357 | rt5677->codec = codec; |
3146 | 3358 | ||
3359 | if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) { | ||
3360 | snd_soc_dapm_add_routes(&codec->dapm, | ||
3361 | rt5677_dmic2_clk_2, | ||
3362 | ARRAY_SIZE(rt5677_dmic2_clk_2)); | ||
3363 | } else { /*use dmic1 clock by default*/ | ||
3364 | snd_soc_dapm_add_routes(&codec->dapm, | ||
3365 | rt5677_dmic2_clk_1, | ||
3366 | ARRAY_SIZE(rt5677_dmic2_clk_1)); | ||
3367 | } | ||
3368 | |||
3147 | rt5677_set_bias_level(codec, SND_SOC_BIAS_OFF); | 3369 | rt5677_set_bias_level(codec, SND_SOC_BIAS_OFF); |
3148 | 3370 | ||
3149 | regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020); | 3371 | regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020); |
@@ -3157,6 +3379,8 @@ static int rt5677_remove(struct snd_soc_codec *codec) | |||
3157 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 3379 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
3158 | 3380 | ||
3159 | regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); | 3381 | regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); |
3382 | if (gpio_is_valid(rt5677->pow_ldo2)) | ||
3383 | gpio_set_value_cansleep(rt5677->pow_ldo2, 0); | ||
3160 | 3384 | ||
3161 | return 0; | 3385 | return 0; |
3162 | } | 3386 | } |
@@ -3168,6 +3392,8 @@ static int rt5677_suspend(struct snd_soc_codec *codec) | |||
3168 | 3392 | ||
3169 | regcache_cache_only(rt5677->regmap, true); | 3393 | regcache_cache_only(rt5677->regmap, true); |
3170 | regcache_mark_dirty(rt5677->regmap); | 3394 | regcache_mark_dirty(rt5677->regmap); |
3395 | if (gpio_is_valid(rt5677->pow_ldo2)) | ||
3396 | gpio_set_value_cansleep(rt5677->pow_ldo2, 0); | ||
3171 | 3397 | ||
3172 | return 0; | 3398 | return 0; |
3173 | } | 3399 | } |
@@ -3176,6 +3402,10 @@ static int rt5677_resume(struct snd_soc_codec *codec) | |||
3176 | { | 3402 | { |
3177 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 3403 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
3178 | 3404 | ||
3405 | if (gpio_is_valid(rt5677->pow_ldo2)) { | ||
3406 | gpio_set_value_cansleep(rt5677->pow_ldo2, 1); | ||
3407 | msleep(10); | ||
3408 | } | ||
3179 | regcache_cache_only(rt5677->regmap, false); | 3409 | regcache_cache_only(rt5677->regmap, false); |
3180 | regcache_sync(rt5677->regmap); | 3410 | regcache_sync(rt5677->regmap); |
3181 | 3411 | ||
@@ -3195,6 +3425,7 @@ static struct snd_soc_dai_ops rt5677_aif_dai_ops = { | |||
3195 | .set_fmt = rt5677_set_dai_fmt, | 3425 | .set_fmt = rt5677_set_dai_fmt, |
3196 | .set_sysclk = rt5677_set_dai_sysclk, | 3426 | .set_sysclk = rt5677_set_dai_sysclk, |
3197 | .set_pll = rt5677_set_dai_pll, | 3427 | .set_pll = rt5677_set_dai_pll, |
3428 | .set_tdm_slot = rt5677_set_tdm_slot, | ||
3198 | }; | 3429 | }; |
3199 | 3430 | ||
3200 | static struct snd_soc_dai_driver rt5677_dai[] = { | 3431 | static struct snd_soc_dai_driver rt5677_dai[] = { |
@@ -3333,6 +3564,35 @@ static const struct i2c_device_id rt5677_i2c_id[] = { | |||
3333 | }; | 3564 | }; |
3334 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); | 3565 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); |
3335 | 3566 | ||
3567 | static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) | ||
3568 | { | ||
3569 | rt5677->pdata.in1_diff = of_property_read_bool(np, | ||
3570 | "realtek,in1-differential"); | ||
3571 | rt5677->pdata.in2_diff = of_property_read_bool(np, | ||
3572 | "realtek,in2-differential"); | ||
3573 | rt5677->pdata.lout1_diff = of_property_read_bool(np, | ||
3574 | "realtek,lout1-differential"); | ||
3575 | rt5677->pdata.lout2_diff = of_property_read_bool(np, | ||
3576 | "realtek,lout2-differential"); | ||
3577 | rt5677->pdata.lout3_diff = of_property_read_bool(np, | ||
3578 | "realtek,lout3-differential"); | ||
3579 | |||
3580 | rt5677->pow_ldo2 = of_get_named_gpio(np, | ||
3581 | "realtek,pow-ldo2-gpio", 0); | ||
3582 | |||
3583 | /* | ||
3584 | * POW_LDO2 is optional (it may be statically tied on the board). | ||
3585 | * -ENOENT means that the property doesn't exist, i.e. there is no | ||
3586 | * GPIO, so is not an error. Any other error code means the property | ||
3587 | * exists, but could not be parsed. | ||
3588 | */ | ||
3589 | if (!gpio_is_valid(rt5677->pow_ldo2) && | ||
3590 | (rt5677->pow_ldo2 != -ENOENT)) | ||
3591 | return rt5677->pow_ldo2; | ||
3592 | |||
3593 | return 0; | ||
3594 | } | ||
3595 | |||
3336 | static int rt5677_i2c_probe(struct i2c_client *i2c, | 3596 | static int rt5677_i2c_probe(struct i2c_client *i2c, |
3337 | const struct i2c_device_id *id) | 3597 | const struct i2c_device_id *id) |
3338 | { | 3598 | { |
@@ -3351,6 +3611,33 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
3351 | if (pdata) | 3611 | if (pdata) |
3352 | rt5677->pdata = *pdata; | 3612 | rt5677->pdata = *pdata; |
3353 | 3613 | ||
3614 | if (i2c->dev.of_node) { | ||
3615 | ret = rt5677_parse_dt(rt5677, i2c->dev.of_node); | ||
3616 | if (ret) { | ||
3617 | dev_err(&i2c->dev, "Failed to parse device tree: %d\n", | ||
3618 | ret); | ||
3619 | return ret; | ||
3620 | } | ||
3621 | } else { | ||
3622 | rt5677->pow_ldo2 = -EINVAL; | ||
3623 | } | ||
3624 | |||
3625 | if (gpio_is_valid(rt5677->pow_ldo2)) { | ||
3626 | ret = devm_gpio_request_one(&i2c->dev, rt5677->pow_ldo2, | ||
3627 | GPIOF_OUT_INIT_HIGH, | ||
3628 | "RT5677 POW_LDO2"); | ||
3629 | if (ret < 0) { | ||
3630 | dev_err(&i2c->dev, "Failed to request POW_LDO2 %d: %d\n", | ||
3631 | rt5677->pow_ldo2, ret); | ||
3632 | return ret; | ||
3633 | } | ||
3634 | /* Wait a while until I2C bus becomes available. The datasheet | ||
3635 | * does not specify the exact we should wait but startup | ||
3636 | * sequence mentiones at least a few milliseconds. | ||
3637 | */ | ||
3638 | msleep(10); | ||
3639 | } | ||
3640 | |||
3354 | rt5677->regmap = devm_regmap_init_i2c(i2c, &rt5677_regmap); | 3641 | rt5677->regmap = devm_regmap_init_i2c(i2c, &rt5677_regmap); |
3355 | if (IS_ERR(rt5677->regmap)) { | 3642 | if (IS_ERR(rt5677->regmap)) { |
3356 | ret = PTR_ERR(rt5677->regmap); | 3643 | ret = PTR_ERR(rt5677->regmap); |
@@ -3381,6 +3668,29 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
3381 | regmap_update_bits(rt5677->regmap, RT5677_IN1, | 3668 | regmap_update_bits(rt5677->regmap, RT5677_IN1, |
3382 | RT5677_IN_DF2, RT5677_IN_DF2); | 3669 | RT5677_IN_DF2, RT5677_IN_DF2); |
3383 | 3670 | ||
3671 | if (rt5677->pdata.lout1_diff) | ||
3672 | regmap_update_bits(rt5677->regmap, RT5677_LOUT1, | ||
3673 | RT5677_LOUT1_L_DF, RT5677_LOUT1_L_DF); | ||
3674 | |||
3675 | if (rt5677->pdata.lout2_diff) | ||
3676 | regmap_update_bits(rt5677->regmap, RT5677_LOUT1, | ||
3677 | RT5677_LOUT2_L_DF, RT5677_LOUT2_L_DF); | ||
3678 | |||
3679 | if (rt5677->pdata.lout3_diff) | ||
3680 | regmap_update_bits(rt5677->regmap, RT5677_LOUT1, | ||
3681 | RT5677_LOUT3_L_DF, RT5677_LOUT3_L_DF); | ||
3682 | |||
3683 | if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) { | ||
3684 | regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL2, | ||
3685 | RT5677_GPIO5_FUNC_MASK, | ||
3686 | RT5677_GPIO5_FUNC_DMIC); | ||
3687 | regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2, | ||
3688 | RT5677_GPIO5_DIR_MASK, | ||
3689 | RT5677_GPIO5_DIR_OUT); | ||
3690 | } | ||
3691 | |||
3692 | rt5677_init_gpio(i2c); | ||
3693 | |||
3384 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677, | 3694 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677, |
3385 | rt5677_dai, ARRAY_SIZE(rt5677_dai)); | 3695 | rt5677_dai, ARRAY_SIZE(rt5677_dai)); |
3386 | } | 3696 | } |
@@ -3388,6 +3698,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
3388 | static int rt5677_i2c_remove(struct i2c_client *i2c) | 3698 | static int rt5677_i2c_remove(struct i2c_client *i2c) |
3389 | { | 3699 | { |
3390 | snd_soc_unregister_codec(&i2c->dev); | 3700 | snd_soc_unregister_codec(&i2c->dev); |
3701 | rt5677_free_gpio(i2c); | ||
3391 | 3702 | ||
3392 | return 0; | 3703 | return 0; |
3393 | } | 3704 | } |
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index 863393e62096..d4eb6d5e6746 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h | |||
@@ -382,6 +382,10 @@ | |||
382 | #define RT5677_ST_SEL_SFT 9 | 382 | #define RT5677_ST_SEL_SFT 9 |
383 | #define RT5677_ST_EN (0x1 << 6) | 383 | #define RT5677_ST_EN (0x1 << 6) |
384 | #define RT5677_ST_EN_SFT 6 | 384 | #define RT5677_ST_EN_SFT 6 |
385 | #define RT5677_ST_GAIN (0x1 << 5) | ||
386 | #define RT5677_ST_GAIN_SFT 5 | ||
387 | #define RT5677_ST_VOL_MASK (0x1f << 0) | ||
388 | #define RT5677_ST_VOL_SFT 0 | ||
385 | 389 | ||
386 | /* Analog DAC1/2/3 Source Control (0x15) */ | 390 | /* Analog DAC1/2/3 Source Control (0x15) */ |
387 | #define RT5677_ANA_DAC3_SRC_SEL_MASK (0x3 << 4) | 391 | #define RT5677_ANA_DAC3_SRC_SEL_MASK (0x3 << 4) |
@@ -1287,16 +1291,16 @@ | |||
1287 | #define RT5677_PLL1_PD_SFT 8 | 1291 | #define RT5677_PLL1_PD_SFT 8 |
1288 | #define RT5677_PLL1_PD_1 (0x0 << 8) | 1292 | #define RT5677_PLL1_PD_1 (0x0 << 8) |
1289 | #define RT5677_PLL1_PD_2 (0x1 << 8) | 1293 | #define RT5677_PLL1_PD_2 (0x1 << 8) |
1290 | #define RT5671_DAC_OSR_MASK (0x3 << 6) | 1294 | #define RT5677_DAC_OSR_MASK (0x3 << 6) |
1291 | #define RT5671_DAC_OSR_SFT 6 | 1295 | #define RT5677_DAC_OSR_SFT 6 |
1292 | #define RT5671_DAC_OSR_128 (0x0 << 6) | 1296 | #define RT5677_DAC_OSR_128 (0x0 << 6) |
1293 | #define RT5671_DAC_OSR_64 (0x1 << 6) | 1297 | #define RT5677_DAC_OSR_64 (0x1 << 6) |
1294 | #define RT5671_DAC_OSR_32 (0x2 << 6) | 1298 | #define RT5677_DAC_OSR_32 (0x2 << 6) |
1295 | #define RT5671_ADC_OSR_MASK (0x3 << 4) | 1299 | #define RT5677_ADC_OSR_MASK (0x3 << 4) |
1296 | #define RT5671_ADC_OSR_SFT 4 | 1300 | #define RT5677_ADC_OSR_SFT 4 |
1297 | #define RT5671_ADC_OSR_128 (0x0 << 4) | 1301 | #define RT5677_ADC_OSR_128 (0x0 << 4) |
1298 | #define RT5671_ADC_OSR_64 (0x1 << 4) | 1302 | #define RT5677_ADC_OSR_64 (0x1 << 4) |
1299 | #define RT5671_ADC_OSR_32 (0x2 << 4) | 1303 | #define RT5677_ADC_OSR_32 (0x2 << 4) |
1300 | 1304 | ||
1301 | /* Global Clock Control 2 (0x81) */ | 1305 | /* Global Clock Control 2 (0x81) */ |
1302 | #define RT5677_PLL2_PR_SRC_MASK (0x1 << 15) | 1306 | #define RT5677_PLL2_PR_SRC_MASK (0x1 << 15) |
@@ -1312,18 +1316,18 @@ | |||
1312 | #define RT5677_PLL2_SRC_BCLK4 (0x4 << 12) | 1316 | #define RT5677_PLL2_SRC_BCLK4 (0x4 << 12) |
1313 | #define RT5677_PLL2_SRC_RCCLK (0x5 << 12) | 1317 | #define RT5677_PLL2_SRC_RCCLK (0x5 << 12) |
1314 | #define RT5677_PLL2_SRC_SLIM (0x6 << 12) | 1318 | #define RT5677_PLL2_SRC_SLIM (0x6 << 12) |
1315 | #define RT5671_DSP_ASRC_O_SRC (0x3 << 10) | 1319 | #define RT5677_DSP_ASRC_O_SRC (0x3 << 10) |
1316 | #define RT5671_DSP_ASRC_O_SRC_SFT 10 | 1320 | #define RT5677_DSP_ASRC_O_SRC_SFT 10 |
1317 | #define RT5671_DSP_ASRC_O_MCLK (0x0 << 10) | 1321 | #define RT5677_DSP_ASRC_O_MCLK (0x0 << 10) |
1318 | #define RT5671_DSP_ASRC_O_PLL1 (0x1 << 10) | 1322 | #define RT5677_DSP_ASRC_O_PLL1 (0x1 << 10) |
1319 | #define RT5671_DSP_ASRC_O_SLIM (0x2 << 10) | 1323 | #define RT5677_DSP_ASRC_O_SLIM (0x2 << 10) |
1320 | #define RT5671_DSP_ASRC_O_RCCLK (0x3 << 10) | 1324 | #define RT5677_DSP_ASRC_O_RCCLK (0x3 << 10) |
1321 | #define RT5671_DSP_ASRC_I_SRC (0x3 << 8) | 1325 | #define RT5677_DSP_ASRC_I_SRC (0x3 << 8) |
1322 | #define RT5671_DSP_ASRC_I_SRC_SFT 8 | 1326 | #define RT5677_DSP_ASRC_I_SRC_SFT 8 |
1323 | #define RT5671_DSP_ASRC_I_MCLK (0x0 << 8) | 1327 | #define RT5677_DSP_ASRC_I_MCLK (0x0 << 8) |
1324 | #define RT5671_DSP_ASRC_I_PLL1 (0x1 << 8) | 1328 | #define RT5677_DSP_ASRC_I_PLL1 (0x1 << 8) |
1325 | #define RT5671_DSP_ASRC_I_SLIM (0x2 << 8) | 1329 | #define RT5677_DSP_ASRC_I_SLIM (0x2 << 8) |
1326 | #define RT5671_DSP_ASRC_I_RCCLK (0x3 << 8) | 1330 | #define RT5677_DSP_ASRC_I_RCCLK (0x3 << 8) |
1327 | #define RT5677_DSP_CLK_SRC_MASK (0x1 << 7) | 1331 | #define RT5677_DSP_CLK_SRC_MASK (0x1 << 7) |
1328 | #define RT5677_DSP_CLK_SRC_SFT 7 | 1332 | #define RT5677_DSP_CLK_SRC_SFT 7 |
1329 | #define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7) | 1333 | #define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7) |
@@ -1363,6 +1367,110 @@ | |||
1363 | #define RT5677_SEL_SRC_IB01 (0x1 << 0) | 1367 | #define RT5677_SEL_SRC_IB01 (0x1 << 0) |
1364 | #define RT5677_SEL_SRC_IB01_SFT 0 | 1368 | #define RT5677_SEL_SRC_IB01_SFT 0 |
1365 | 1369 | ||
1370 | /* GPIO status (0xbf) */ | ||
1371 | #define RT5677_GPIO6_STATUS_MASK (0x1 << 5) | ||
1372 | #define RT5677_GPIO6_STATUS_SFT 5 | ||
1373 | #define RT5677_GPIO5_STATUS_MASK (0x1 << 4) | ||
1374 | #define RT5677_GPIO5_STATUS_SFT 4 | ||
1375 | #define RT5677_GPIO4_STATUS_MASK (0x1 << 3) | ||
1376 | #define RT5677_GPIO4_STATUS_SFT 3 | ||
1377 | #define RT5677_GPIO3_STATUS_MASK (0x1 << 2) | ||
1378 | #define RT5677_GPIO3_STATUS_SFT 2 | ||
1379 | #define RT5677_GPIO2_STATUS_MASK (0x1 << 1) | ||
1380 | #define RT5677_GPIO2_STATUS_SFT 1 | ||
1381 | #define RT5677_GPIO1_STATUS_MASK (0x1 << 0) | ||
1382 | #define RT5677_GPIO1_STATUS_SFT 0 | ||
1383 | |||
1384 | /* GPIO Control 1 (0xc0) */ | ||
1385 | #define RT5677_GPIO1_PIN_MASK (0x1 << 15) | ||
1386 | #define RT5677_GPIO1_PIN_SFT 15 | ||
1387 | #define RT5677_GPIO1_PIN_GPIO1 (0x0 << 15) | ||
1388 | #define RT5677_GPIO1_PIN_IRQ (0x1 << 15) | ||
1389 | #define RT5677_IPTV_MODE_MASK (0x1 << 14) | ||
1390 | #define RT5677_IPTV_MODE_SFT 14 | ||
1391 | #define RT5677_IPTV_MODE_GPIO (0x0 << 14) | ||
1392 | #define RT5677_IPTV_MODE_IPTV (0x1 << 14) | ||
1393 | #define RT5677_FUNC_MODE_MASK (0x1 << 13) | ||
1394 | #define RT5677_FUNC_MODE_SFT 13 | ||
1395 | #define RT5677_FUNC_MODE_DMIC_GPIO (0x0 << 13) | ||
1396 | #define RT5677_FUNC_MODE_JTAG (0x1 << 13) | ||
1397 | |||
1398 | /* GPIO Control 2 (0xc1) */ | ||
1399 | #define RT5677_GPIO5_DIR_MASK (0x1 << 14) | ||
1400 | #define RT5677_GPIO5_DIR_SFT 14 | ||
1401 | #define RT5677_GPIO5_DIR_IN (0x0 << 14) | ||
1402 | #define RT5677_GPIO5_DIR_OUT (0x1 << 14) | ||
1403 | #define RT5677_GPIO5_OUT_MASK (0x1 << 13) | ||
1404 | #define RT5677_GPIO5_OUT_SFT 13 | ||
1405 | #define RT5677_GPIO5_OUT_LO (0x0 << 13) | ||
1406 | #define RT5677_GPIO5_OUT_HI (0x1 << 13) | ||
1407 | #define RT5677_GPIO5_P_MASK (0x1 << 12) | ||
1408 | #define RT5677_GPIO5_P_SFT 12 | ||
1409 | #define RT5677_GPIO5_P_NOR (0x0 << 12) | ||
1410 | #define RT5677_GPIO5_P_INV (0x1 << 12) | ||
1411 | #define RT5677_GPIO4_DIR_MASK (0x1 << 11) | ||
1412 | #define RT5677_GPIO4_DIR_SFT 11 | ||
1413 | #define RT5677_GPIO4_DIR_IN (0x0 << 11) | ||
1414 | #define RT5677_GPIO4_DIR_OUT (0x1 << 11) | ||
1415 | #define RT5677_GPIO4_OUT_MASK (0x1 << 10) | ||
1416 | #define RT5677_GPIO4_OUT_SFT 10 | ||
1417 | #define RT5677_GPIO4_OUT_LO (0x0 << 10) | ||
1418 | #define RT5677_GPIO4_OUT_HI (0x1 << 10) | ||
1419 | #define RT5677_GPIO4_P_MASK (0x1 << 9) | ||
1420 | #define RT5677_GPIO4_P_SFT 9 | ||
1421 | #define RT5677_GPIO4_P_NOR (0x0 << 9) | ||
1422 | #define RT5677_GPIO4_P_INV (0x1 << 9) | ||
1423 | #define RT5677_GPIO3_DIR_MASK (0x1 << 8) | ||
1424 | #define RT5677_GPIO3_DIR_SFT 8 | ||
1425 | #define RT5677_GPIO3_DIR_IN (0x0 << 8) | ||
1426 | #define RT5677_GPIO3_DIR_OUT (0x1 << 8) | ||
1427 | #define RT5677_GPIO3_OUT_MASK (0x1 << 7) | ||
1428 | #define RT5677_GPIO3_OUT_SFT 7 | ||
1429 | #define RT5677_GPIO3_OUT_LO (0x0 << 7) | ||
1430 | #define RT5677_GPIO3_OUT_HI (0x1 << 7) | ||
1431 | #define RT5677_GPIO3_P_MASK (0x1 << 6) | ||
1432 | #define RT5677_GPIO3_P_SFT 6 | ||
1433 | #define RT5677_GPIO3_P_NOR (0x0 << 6) | ||
1434 | #define RT5677_GPIO3_P_INV (0x1 << 6) | ||
1435 | #define RT5677_GPIO2_DIR_MASK (0x1 << 5) | ||
1436 | #define RT5677_GPIO2_DIR_SFT 5 | ||
1437 | #define RT5677_GPIO2_DIR_IN (0x0 << 5) | ||
1438 | #define RT5677_GPIO2_DIR_OUT (0x1 << 5) | ||
1439 | #define RT5677_GPIO2_OUT_MASK (0x1 << 4) | ||
1440 | #define RT5677_GPIO2_OUT_SFT 4 | ||
1441 | #define RT5677_GPIO2_OUT_LO (0x0 << 4) | ||
1442 | #define RT5677_GPIO2_OUT_HI (0x1 << 4) | ||
1443 | #define RT5677_GPIO2_P_MASK (0x1 << 3) | ||
1444 | #define RT5677_GPIO2_P_SFT 3 | ||
1445 | #define RT5677_GPIO2_P_NOR (0x0 << 3) | ||
1446 | #define RT5677_GPIO2_P_INV (0x1 << 3) | ||
1447 | #define RT5677_GPIO1_DIR_MASK (0x1 << 2) | ||
1448 | #define RT5677_GPIO1_DIR_SFT 2 | ||
1449 | #define RT5677_GPIO1_DIR_IN (0x0 << 2) | ||
1450 | #define RT5677_GPIO1_DIR_OUT (0x1 << 2) | ||
1451 | #define RT5677_GPIO1_OUT_MASK (0x1 << 1) | ||
1452 | #define RT5677_GPIO1_OUT_SFT 1 | ||
1453 | #define RT5677_GPIO1_OUT_LO (0x0 << 1) | ||
1454 | #define RT5677_GPIO1_OUT_HI (0x1 << 1) | ||
1455 | #define RT5677_GPIO1_P_MASK (0x1 << 0) | ||
1456 | #define RT5677_GPIO1_P_SFT 0 | ||
1457 | #define RT5677_GPIO1_P_NOR (0x0 << 0) | ||
1458 | #define RT5677_GPIO1_P_INV (0x1 << 0) | ||
1459 | |||
1460 | /* GPIO Control 3 (0xc2) */ | ||
1461 | #define RT5677_GPIO6_DIR_MASK (0x1 << 2) | ||
1462 | #define RT5677_GPIO6_DIR_SFT 2 | ||
1463 | #define RT5677_GPIO6_DIR_IN (0x0 << 2) | ||
1464 | #define RT5677_GPIO6_DIR_OUT (0x1 << 2) | ||
1465 | #define RT5677_GPIO6_OUT_MASK (0x1 << 1) | ||
1466 | #define RT5677_GPIO6_OUT_SFT 1 | ||
1467 | #define RT5677_GPIO6_OUT_LO (0x0 << 1) | ||
1468 | #define RT5677_GPIO6_OUT_HI (0x1 << 1) | ||
1469 | #define RT5677_GPIO6_P_MASK (0x1 << 0) | ||
1470 | #define RT5677_GPIO6_P_SFT 0 | ||
1471 | #define RT5677_GPIO6_P_NOR (0x0 << 0) | ||
1472 | #define RT5677_GPIO6_P_INV (0x1 << 0) | ||
1473 | |||
1366 | /* Virtual DSP Mixer Control (0xf7 0xf8 0xf9) */ | 1474 | /* Virtual DSP Mixer Control (0xf7 0xf8 0xf9) */ |
1367 | #define RT5677_DSP_IB_01_H (0x1 << 15) | 1475 | #define RT5677_DSP_IB_01_H (0x1 << 15) |
1368 | #define RT5677_DSP_IB_01_H_SFT 15 | 1476 | #define RT5677_DSP_IB_01_H_SFT 15 |
@@ -1393,6 +1501,11 @@ | |||
1393 | #define RT5677_DSP_IB_9_L (0x1 << 1) | 1501 | #define RT5677_DSP_IB_9_L (0x1 << 1) |
1394 | #define RT5677_DSP_IB_9_L_SFT 1 | 1502 | #define RT5677_DSP_IB_9_L_SFT 1 |
1395 | 1503 | ||
1504 | /* General Control2 (0xfc)*/ | ||
1505 | #define RT5677_GPIO5_FUNC_MASK (0x1 << 9) | ||
1506 | #define RT5677_GPIO5_FUNC_GPIO (0x0 << 9) | ||
1507 | #define RT5677_GPIO5_FUNC_DMIC (0x1 << 9) | ||
1508 | |||
1396 | /* System Clock Source */ | 1509 | /* System Clock Source */ |
1397 | enum { | 1510 | enum { |
1398 | RT5677_SCLK_S_MCLK, | 1511 | RT5677_SCLK_S_MCLK, |
@@ -1418,6 +1531,16 @@ enum { | |||
1418 | RT5677_AIFS, | 1531 | RT5677_AIFS, |
1419 | }; | 1532 | }; |
1420 | 1533 | ||
1534 | enum { | ||
1535 | RT5677_GPIO1, | ||
1536 | RT5677_GPIO2, | ||
1537 | RT5677_GPIO3, | ||
1538 | RT5677_GPIO4, | ||
1539 | RT5677_GPIO5, | ||
1540 | RT5677_GPIO6, | ||
1541 | RT5677_GPIO_NUM, | ||
1542 | }; | ||
1543 | |||
1421 | struct rt5677_priv { | 1544 | struct rt5677_priv { |
1422 | struct snd_soc_codec *codec; | 1545 | struct snd_soc_codec *codec; |
1423 | struct rt5677_platform_data pdata; | 1546 | struct rt5677_platform_data pdata; |
@@ -1431,6 +1554,10 @@ struct rt5677_priv { | |||
1431 | int pll_src; | 1554 | int pll_src; |
1432 | int pll_in; | 1555 | int pll_in; |
1433 | int pll_out; | 1556 | int pll_out; |
1557 | int pow_ldo2; /* POW_LDO2 pin */ | ||
1558 | #ifdef CONFIG_GPIOLIB | ||
1559 | struct gpio_chip gpio_chip; | ||
1560 | #endif | ||
1434 | }; | 1561 | }; |
1435 | 1562 | ||
1436 | #endif /* __RT5677_H__ */ | 1563 | #endif /* __RT5677_H__ */ |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index e997d271728d..6bb77d76561b 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -626,6 +626,9 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate) | |||
626 | } else { | 626 | } else { |
627 | dev_err(codec->dev, | 627 | dev_err(codec->dev, |
628 | "PLL not supported in slave mode\n"); | 628 | "PLL not supported in slave mode\n"); |
629 | dev_err(codec->dev, "%d ratio is not supported. " | ||
630 | "SYS_MCLK needs to be 256, 384 or 512 * fs\n", | ||
631 | sgtl5000->sysclk / sys_fs); | ||
629 | return -EINVAL; | 632 | return -EINVAL; |
630 | } | 633 | } |
631 | } | 634 | } |
@@ -1073,26 +1076,6 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg) | |||
1073 | } | 1076 | } |
1074 | } | 1077 | } |
1075 | 1078 | ||
1076 | #ifdef CONFIG_SUSPEND | ||
1077 | static int sgtl5000_suspend(struct snd_soc_codec *codec) | ||
1078 | { | ||
1079 | sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1080 | |||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static int sgtl5000_resume(struct snd_soc_codec *codec) | ||
1085 | { | ||
1086 | /* Bring the codec back up to standby to enable regulators */ | ||
1087 | sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1088 | |||
1089 | return 0; | ||
1090 | } | ||
1091 | #else | ||
1092 | #define sgtl5000_suspend NULL | ||
1093 | #define sgtl5000_resume NULL | ||
1094 | #endif /* CONFIG_SUSPEND */ | ||
1095 | |||
1096 | /* | 1079 | /* |
1097 | * sgtl5000 has 3 internal power supplies: | 1080 | * sgtl5000 has 3 internal power supplies: |
1098 | * 1. VAG, normally set to vdda/2 | 1081 | * 1. VAG, normally set to vdda/2 |
@@ -1352,11 +1335,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1352 | */ | 1335 | */ |
1353 | snd_soc_write(codec, SGTL5000_DAP_CTRL, 0); | 1336 | snd_soc_write(codec, SGTL5000_DAP_CTRL, 0); |
1354 | 1337 | ||
1355 | /* leading to standby state */ | ||
1356 | ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1357 | if (ret) | ||
1358 | goto err; | ||
1359 | |||
1360 | return 0; | 1338 | return 0; |
1361 | 1339 | ||
1362 | err: | 1340 | err: |
@@ -1373,8 +1351,6 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) | |||
1373 | { | 1351 | { |
1374 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); | 1352 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); |
1375 | 1353 | ||
1376 | sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1377 | |||
1378 | regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), | 1354 | regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), |
1379 | sgtl5000->supplies); | 1355 | sgtl5000->supplies); |
1380 | regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), | 1356 | regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), |
@@ -1387,9 +1363,8 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) | |||
1387 | static struct snd_soc_codec_driver sgtl5000_driver = { | 1363 | static struct snd_soc_codec_driver sgtl5000_driver = { |
1388 | .probe = sgtl5000_probe, | 1364 | .probe = sgtl5000_probe, |
1389 | .remove = sgtl5000_remove, | 1365 | .remove = sgtl5000_remove, |
1390 | .suspend = sgtl5000_suspend, | ||
1391 | .resume = sgtl5000_resume, | ||
1392 | .set_bias_level = sgtl5000_set_bias_level, | 1366 | .set_bias_level = sgtl5000_set_bias_level, |
1367 | .suspend_bias_off = true, | ||
1393 | .controls = sgtl5000_snd_controls, | 1368 | .controls = sgtl5000_snd_controls, |
1394 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), | 1369 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), |
1395 | .dapm_widgets = sgtl5000_dapm_widgets, | 1370 | .dapm_widgets = sgtl5000_dapm_widgets, |
@@ -1442,6 +1417,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, | |||
1442 | { | 1417 | { |
1443 | struct sgtl5000_priv *sgtl5000; | 1418 | struct sgtl5000_priv *sgtl5000; |
1444 | int ret, reg, rev; | 1419 | int ret, reg, rev; |
1420 | unsigned int mclk; | ||
1445 | 1421 | ||
1446 | sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), | 1422 | sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), |
1447 | GFP_KERNEL); | 1423 | GFP_KERNEL); |
@@ -1465,6 +1441,14 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, | |||
1465 | return ret; | 1441 | return ret; |
1466 | } | 1442 | } |
1467 | 1443 | ||
1444 | /* SGTL5000 SYS_MCLK should be between 8 and 27 MHz */ | ||
1445 | mclk = clk_get_rate(sgtl5000->mclk); | ||
1446 | if (mclk < 8000000 || mclk > 27000000) { | ||
1447 | dev_err(&client->dev, "Invalid SYS_CLK frequency: %u.%03uMHz\n", | ||
1448 | mclk / 1000000, mclk / 1000 % 1000); | ||
1449 | return -EINVAL; | ||
1450 | } | ||
1451 | |||
1468 | ret = clk_prepare_enable(sgtl5000->mclk); | 1452 | ret = clk_prepare_enable(sgtl5000->mclk); |
1469 | if (ret) | 1453 | if (ret) |
1470 | return ret; | 1454 | return ret; |
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index e8680bea5f86..67ea55adb307 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c | |||
@@ -646,17 +646,6 @@ static struct snd_soc_dai_driver ssm2518_dai = { | |||
646 | .ops = &ssm2518_dai_ops, | 646 | .ops = &ssm2518_dai_ops, |
647 | }; | 647 | }; |
648 | 648 | ||
649 | static int ssm2518_probe(struct snd_soc_codec *codec) | ||
650 | { | ||
651 | return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
652 | } | ||
653 | |||
654 | static int ssm2518_remove(struct snd_soc_codec *codec) | ||
655 | { | ||
656 | ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 649 | static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
661 | int source, unsigned int freq, int dir) | 650 | int source, unsigned int freq, int dir) |
662 | { | 651 | { |
@@ -727,8 +716,6 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
727 | } | 716 | } |
728 | 717 | ||
729 | static struct snd_soc_codec_driver ssm2518_codec_driver = { | 718 | static struct snd_soc_codec_driver ssm2518_codec_driver = { |
730 | .probe = ssm2518_probe, | ||
731 | .remove = ssm2518_remove, | ||
732 | .set_bias_level = ssm2518_set_bias_level, | 719 | .set_bias_level = ssm2518_set_bias_level, |
733 | .set_sysclk = ssm2518_set_sysclk, | 720 | .set_sysclk = ssm2518_set_sysclk, |
734 | .idle_bias_off = true, | 721 | .idle_bias_off = true, |
diff --git a/sound/soc/codecs/ssm2602-i2c.c b/sound/soc/codecs/ssm2602-i2c.c index abd63d537173..0d9779d6bfda 100644 --- a/sound/soc/codecs/ssm2602-i2c.c +++ b/sound/soc/codecs/ssm2602-i2c.c | |||
@@ -41,10 +41,19 @@ static const struct i2c_device_id ssm2602_i2c_id[] = { | |||
41 | }; | 41 | }; |
42 | MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); | 42 | MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); |
43 | 43 | ||
44 | static const struct of_device_id ssm2602_of_match[] = { | ||
45 | { .compatible = "adi,ssm2602", }, | ||
46 | { .compatible = "adi,ssm2603", }, | ||
47 | { .compatible = "adi,ssm2604", }, | ||
48 | { } | ||
49 | }; | ||
50 | MODULE_DEVICE_TABLE(of, ssm2602_of_match); | ||
51 | |||
44 | static struct i2c_driver ssm2602_i2c_driver = { | 52 | static struct i2c_driver ssm2602_i2c_driver = { |
45 | .driver = { | 53 | .driver = { |
46 | .name = "ssm2602", | 54 | .name = "ssm2602", |
47 | .owner = THIS_MODULE, | 55 | .owner = THIS_MODULE, |
56 | .of_match_table = ssm2602_of_match, | ||
48 | }, | 57 | }, |
49 | .probe = ssm2602_i2c_probe, | 58 | .probe = ssm2602_i2c_probe, |
50 | .remove = ssm2602_i2c_remove, | 59 | .remove = ssm2602_i2c_remove, |
diff --git a/sound/soc/codecs/ssm2602-spi.c b/sound/soc/codecs/ssm2602-spi.c index 2bf55e24a7bb..b5df14fbe3ad 100644 --- a/sound/soc/codecs/ssm2602-spi.c +++ b/sound/soc/codecs/ssm2602-spi.c | |||
@@ -26,10 +26,17 @@ static int ssm2602_spi_remove(struct spi_device *spi) | |||
26 | return 0; | 26 | return 0; |
27 | } | 27 | } |
28 | 28 | ||
29 | static const struct of_device_id ssm2602_of_match[] = { | ||
30 | { .compatible = "adi,ssm2602", }, | ||
31 | { } | ||
32 | }; | ||
33 | MODULE_DEVICE_TABLE(of, ssm2602_of_match); | ||
34 | |||
29 | static struct spi_driver ssm2602_spi_driver = { | 35 | static struct spi_driver ssm2602_spi_driver = { |
30 | .driver = { | 36 | .driver = { |
31 | .name = "ssm2602", | 37 | .name = "ssm2602", |
32 | .owner = THIS_MODULE, | 38 | .owner = THIS_MODULE, |
39 | .of_match_table = ssm2602_of_match, | ||
33 | }, | 40 | }, |
34 | .probe = ssm2602_spi_probe, | 41 | .probe = ssm2602_spi_probe, |
35 | .remove = ssm2602_spi_remove, | 42 | .remove = ssm2602_spi_remove, |
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 484b3bbe8624..314eaece1b7d 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -192,7 +192,7 @@ static const struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { | |||
192 | }; | 192 | }; |
193 | 193 | ||
194 | static const unsigned int ssm2602_rates_11289600[] = { | 194 | static const unsigned int ssm2602_rates_11289600[] = { |
195 | 8000, 44100, 88200, | 195 | 8000, 11025, 22050, 44100, 88200, |
196 | }; | 196 | }; |
197 | 197 | ||
198 | static const struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { | 198 | static const struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { |
@@ -237,6 +237,16 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = { | |||
237 | {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)}, | 237 | {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)}, |
238 | {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)}, | 238 | {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)}, |
239 | 239 | ||
240 | /* 11.025k */ | ||
241 | {11289600, 11025, SSM2602_COEFF_SRATE(0xc, 0x0, 0x0)}, | ||
242 | {16934400, 11025, SSM2602_COEFF_SRATE(0xc, 0x1, 0x0)}, | ||
243 | {12000000, 11025, SSM2602_COEFF_SRATE(0xc, 0x1, 0x1)}, | ||
244 | |||
245 | /* 22.05k */ | ||
246 | {11289600, 22050, SSM2602_COEFF_SRATE(0xd, 0x0, 0x0)}, | ||
247 | {16934400, 22050, SSM2602_COEFF_SRATE(0xd, 0x1, 0x0)}, | ||
248 | {12000000, 22050, SSM2602_COEFF_SRATE(0xd, 0x1, 0x1)}, | ||
249 | |||
240 | /* 44.1k */ | 250 | /* 44.1k */ |
241 | {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)}, | 251 | {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)}, |
242 | {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)}, | 252 | {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)}, |
@@ -467,7 +477,8 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, | |||
467 | return 0; | 477 | return 0; |
468 | } | 478 | } |
469 | 479 | ||
470 | #define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | 480 | #define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
481 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ | ||
471 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ | 482 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ |
472 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ | 483 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ |
473 | SNDRV_PCM_RATE_96000) | 484 | SNDRV_PCM_RATE_96000) |
@@ -502,18 +513,11 @@ static struct snd_soc_dai_driver ssm2602_dai = { | |||
502 | .symmetric_samplebits = 1, | 513 | .symmetric_samplebits = 1, |
503 | }; | 514 | }; |
504 | 515 | ||
505 | static int ssm2602_suspend(struct snd_soc_codec *codec) | ||
506 | { | ||
507 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int ssm2602_resume(struct snd_soc_codec *codec) | 516 | static int ssm2602_resume(struct snd_soc_codec *codec) |
512 | { | 517 | { |
513 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); | 518 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
514 | 519 | ||
515 | regcache_sync(ssm2602->regmap); | 520 | regcache_sync(ssm2602->regmap); |
516 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
517 | 521 | ||
518 | return 0; | 522 | return 0; |
519 | } | 523 | } |
@@ -586,27 +590,14 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec) | |||
586 | break; | 590 | break; |
587 | } | 591 | } |
588 | 592 | ||
589 | if (ret) | 593 | return ret; |
590 | return ret; | ||
591 | |||
592 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | /* remove everything here */ | ||
598 | static int ssm2602_remove(struct snd_soc_codec *codec) | ||
599 | { | ||
600 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
601 | return 0; | ||
602 | } | 594 | } |
603 | 595 | ||
604 | static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { | 596 | static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { |
605 | .probe = ssm260x_codec_probe, | 597 | .probe = ssm260x_codec_probe, |
606 | .remove = ssm2602_remove, | ||
607 | .suspend = ssm2602_suspend, | ||
608 | .resume = ssm2602_resume, | 598 | .resume = ssm2602_resume, |
609 | .set_bias_level = ssm2602_set_bias_level, | 599 | .set_bias_level = ssm2602_set_bias_level, |
600 | .suspend_bias_off = true, | ||
610 | 601 | ||
611 | .controls = ssm260x_snd_controls, | 602 | .controls = ssm260x_snd_controls, |
612 | .num_controls = ARRAY_SIZE(ssm260x_snd_controls), | 603 | .num_controls = ARRAY_SIZE(ssm260x_snd_controls), |
@@ -647,7 +638,7 @@ int ssm2602_probe(struct device *dev, enum ssm2602_type type, | |||
647 | return -ENOMEM; | 638 | return -ENOMEM; |
648 | 639 | ||
649 | dev_set_drvdata(dev, ssm2602); | 640 | dev_set_drvdata(dev, ssm2602); |
650 | ssm2602->type = SSM2602; | 641 | ssm2602->type = type; |
651 | ssm2602->regmap = regmap; | 642 | ssm2602->regmap = regmap; |
652 | 643 | ||
653 | return snd_soc_register_codec(dev, &soc_codec_dev_ssm2602, | 644 | return snd_soc_register_codec(dev, &soc_codec_dev_ssm2602, |
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c new file mode 100644 index 000000000000..4b5c17f8507e --- /dev/null +++ b/sound/soc/codecs/ssm4567.c | |||
@@ -0,0 +1,343 @@ | |||
1 | /* | ||
2 | * SSM4567 amplifier audio driver | ||
3 | * | ||
4 | * Copyright 2014 Google Chromium project. | ||
5 | * Author: Anatol Pomozov <anatol@chromium.org> | ||
6 | * | ||
7 | * Based on code copyright/by: | ||
8 | * Copyright 2013 Analog Devices Inc. | ||
9 | * | ||
10 | * Licensed under the GPL-2. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/regmap.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <sound/core.h> | ||
19 | #include <sound/pcm.h> | ||
20 | #include <sound/pcm_params.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/tlv.h> | ||
24 | |||
25 | #define SSM4567_REG_POWER_CTRL 0x00 | ||
26 | #define SSM4567_REG_AMP_SNS_CTRL 0x01 | ||
27 | #define SSM4567_REG_DAC_CTRL 0x02 | ||
28 | #define SSM4567_REG_DAC_VOLUME 0x03 | ||
29 | #define SSM4567_REG_SAI_CTRL_1 0x04 | ||
30 | #define SSM4567_REG_SAI_CTRL_2 0x05 | ||
31 | #define SSM4567_REG_SAI_PLACEMENT_1 0x06 | ||
32 | #define SSM4567_REG_SAI_PLACEMENT_2 0x07 | ||
33 | #define SSM4567_REG_SAI_PLACEMENT_3 0x08 | ||
34 | #define SSM4567_REG_SAI_PLACEMENT_4 0x09 | ||
35 | #define SSM4567_REG_SAI_PLACEMENT_5 0x0a | ||
36 | #define SSM4567_REG_SAI_PLACEMENT_6 0x0b | ||
37 | #define SSM4567_REG_BATTERY_V_OUT 0x0c | ||
38 | #define SSM4567_REG_LIMITER_CTRL_1 0x0d | ||
39 | #define SSM4567_REG_LIMITER_CTRL_2 0x0e | ||
40 | #define SSM4567_REG_LIMITER_CTRL_3 0x0f | ||
41 | #define SSM4567_REG_STATUS_1 0x10 | ||
42 | #define SSM4567_REG_STATUS_2 0x11 | ||
43 | #define SSM4567_REG_FAULT_CTRL 0x12 | ||
44 | #define SSM4567_REG_PDM_CTRL 0x13 | ||
45 | #define SSM4567_REG_MCLK_RATIO 0x14 | ||
46 | #define SSM4567_REG_BOOST_CTRL_1 0x15 | ||
47 | #define SSM4567_REG_BOOST_CTRL_2 0x16 | ||
48 | #define SSM4567_REG_SOFT_RESET 0xff | ||
49 | |||
50 | /* POWER_CTRL */ | ||
51 | #define SSM4567_POWER_APWDN_EN BIT(7) | ||
52 | #define SSM4567_POWER_BSNS_PWDN BIT(6) | ||
53 | #define SSM4567_POWER_VSNS_PWDN BIT(5) | ||
54 | #define SSM4567_POWER_ISNS_PWDN BIT(4) | ||
55 | #define SSM4567_POWER_BOOST_PWDN BIT(3) | ||
56 | #define SSM4567_POWER_AMP_PWDN BIT(2) | ||
57 | #define SSM4567_POWER_VBAT_ONLY BIT(1) | ||
58 | #define SSM4567_POWER_SPWDN BIT(0) | ||
59 | |||
60 | /* DAC_CTRL */ | ||
61 | #define SSM4567_DAC_HV BIT(7) | ||
62 | #define SSM4567_DAC_MUTE BIT(6) | ||
63 | #define SSM4567_DAC_HPF BIT(5) | ||
64 | #define SSM4567_DAC_LPM BIT(4) | ||
65 | #define SSM4567_DAC_FS_MASK 0x7 | ||
66 | #define SSM4567_DAC_FS_8000_12000 0x0 | ||
67 | #define SSM4567_DAC_FS_16000_24000 0x1 | ||
68 | #define SSM4567_DAC_FS_32000_48000 0x2 | ||
69 | #define SSM4567_DAC_FS_64000_96000 0x3 | ||
70 | #define SSM4567_DAC_FS_128000_192000 0x4 | ||
71 | |||
72 | struct ssm4567 { | ||
73 | struct regmap *regmap; | ||
74 | }; | ||
75 | |||
76 | static const struct reg_default ssm4567_reg_defaults[] = { | ||
77 | { SSM4567_REG_POWER_CTRL, 0x81 }, | ||
78 | { SSM4567_REG_AMP_SNS_CTRL, 0x09 }, | ||
79 | { SSM4567_REG_DAC_CTRL, 0x32 }, | ||
80 | { SSM4567_REG_DAC_VOLUME, 0x40 }, | ||
81 | { SSM4567_REG_SAI_CTRL_1, 0x00 }, | ||
82 | { SSM4567_REG_SAI_CTRL_2, 0x08 }, | ||
83 | { SSM4567_REG_SAI_PLACEMENT_1, 0x01 }, | ||
84 | { SSM4567_REG_SAI_PLACEMENT_2, 0x20 }, | ||
85 | { SSM4567_REG_SAI_PLACEMENT_3, 0x32 }, | ||
86 | { SSM4567_REG_SAI_PLACEMENT_4, 0x07 }, | ||
87 | { SSM4567_REG_SAI_PLACEMENT_5, 0x07 }, | ||
88 | { SSM4567_REG_SAI_PLACEMENT_6, 0x07 }, | ||
89 | { SSM4567_REG_BATTERY_V_OUT, 0x00 }, | ||
90 | { SSM4567_REG_LIMITER_CTRL_1, 0xa4 }, | ||
91 | { SSM4567_REG_LIMITER_CTRL_2, 0x73 }, | ||
92 | { SSM4567_REG_LIMITER_CTRL_3, 0x00 }, | ||
93 | { SSM4567_REG_STATUS_1, 0x00 }, | ||
94 | { SSM4567_REG_STATUS_2, 0x00 }, | ||
95 | { SSM4567_REG_FAULT_CTRL, 0x30 }, | ||
96 | { SSM4567_REG_PDM_CTRL, 0x40 }, | ||
97 | { SSM4567_REG_MCLK_RATIO, 0x11 }, | ||
98 | { SSM4567_REG_BOOST_CTRL_1, 0x03 }, | ||
99 | { SSM4567_REG_BOOST_CTRL_2, 0x00 }, | ||
100 | { SSM4567_REG_SOFT_RESET, 0x00 }, | ||
101 | }; | ||
102 | |||
103 | |||
104 | static bool ssm4567_readable_reg(struct device *dev, unsigned int reg) | ||
105 | { | ||
106 | switch (reg) { | ||
107 | case SSM4567_REG_POWER_CTRL ... SSM4567_REG_BOOST_CTRL_2: | ||
108 | return true; | ||
109 | default: | ||
110 | return false; | ||
111 | } | ||
112 | |||
113 | } | ||
114 | |||
115 | static bool ssm4567_writeable_reg(struct device *dev, unsigned int reg) | ||
116 | { | ||
117 | switch (reg) { | ||
118 | case SSM4567_REG_POWER_CTRL ... SSM4567_REG_SAI_PLACEMENT_6: | ||
119 | case SSM4567_REG_LIMITER_CTRL_1 ... SSM4567_REG_LIMITER_CTRL_3: | ||
120 | case SSM4567_REG_FAULT_CTRL ... SSM4567_REG_BOOST_CTRL_2: | ||
121 | /* The datasheet states that soft reset register is read-only, | ||
122 | * but logically it is write-only. */ | ||
123 | case SSM4567_REG_SOFT_RESET: | ||
124 | return true; | ||
125 | default: | ||
126 | return false; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | static bool ssm4567_volatile_reg(struct device *dev, unsigned int reg) | ||
131 | { | ||
132 | switch (reg) { | ||
133 | case SSM4567_REG_BATTERY_V_OUT: | ||
134 | case SSM4567_REG_STATUS_1 ... SSM4567_REG_STATUS_2: | ||
135 | case SSM4567_REG_SOFT_RESET: | ||
136 | return true; | ||
137 | default: | ||
138 | return false; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static const DECLARE_TLV_DB_MINMAX_MUTE(ssm4567_vol_tlv, -7125, 2400); | ||
143 | |||
144 | static const struct snd_kcontrol_new ssm4567_snd_controls[] = { | ||
145 | SOC_SINGLE_TLV("Master Playback Volume", SSM4567_REG_DAC_VOLUME, 0, | ||
146 | 0xff, 1, ssm4567_vol_tlv), | ||
147 | SOC_SINGLE("DAC Low Power Mode Switch", SSM4567_REG_DAC_CTRL, 4, 1, 0), | ||
148 | }; | ||
149 | |||
150 | static const struct snd_soc_dapm_widget ssm4567_dapm_widgets[] = { | ||
151 | SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM4567_REG_POWER_CTRL, 2, 1), | ||
152 | |||
153 | SND_SOC_DAPM_OUTPUT("OUT"), | ||
154 | }; | ||
155 | |||
156 | static const struct snd_soc_dapm_route ssm4567_routes[] = { | ||
157 | { "OUT", NULL, "DAC" }, | ||
158 | }; | ||
159 | |||
160 | static int ssm4567_hw_params(struct snd_pcm_substream *substream, | ||
161 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
162 | { | ||
163 | struct snd_soc_codec *codec = dai->codec; | ||
164 | struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec); | ||
165 | unsigned int rate = params_rate(params); | ||
166 | unsigned int dacfs; | ||
167 | |||
168 | if (rate >= 8000 && rate <= 12000) | ||
169 | dacfs = SSM4567_DAC_FS_8000_12000; | ||
170 | else if (rate >= 16000 && rate <= 24000) | ||
171 | dacfs = SSM4567_DAC_FS_16000_24000; | ||
172 | else if (rate >= 32000 && rate <= 48000) | ||
173 | dacfs = SSM4567_DAC_FS_32000_48000; | ||
174 | else if (rate >= 64000 && rate <= 96000) | ||
175 | dacfs = SSM4567_DAC_FS_64000_96000; | ||
176 | else if (rate >= 128000 && rate <= 192000) | ||
177 | dacfs = SSM4567_DAC_FS_128000_192000; | ||
178 | else | ||
179 | return -EINVAL; | ||
180 | |||
181 | return regmap_update_bits(ssm4567->regmap, SSM4567_REG_DAC_CTRL, | ||
182 | SSM4567_DAC_FS_MASK, dacfs); | ||
183 | } | ||
184 | |||
185 | static int ssm4567_mute(struct snd_soc_dai *dai, int mute) | ||
186 | { | ||
187 | struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(dai->codec); | ||
188 | unsigned int val; | ||
189 | |||
190 | val = mute ? SSM4567_DAC_MUTE : 0; | ||
191 | return regmap_update_bits(ssm4567->regmap, SSM4567_REG_DAC_CTRL, | ||
192 | SSM4567_DAC_MUTE, val); | ||
193 | } | ||
194 | |||
195 | static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable) | ||
196 | { | ||
197 | int ret = 0; | ||
198 | |||
199 | if (!enable) { | ||
200 | ret = regmap_update_bits(ssm4567->regmap, | ||
201 | SSM4567_REG_POWER_CTRL, | ||
202 | SSM4567_POWER_SPWDN, SSM4567_POWER_SPWDN); | ||
203 | regcache_mark_dirty(ssm4567->regmap); | ||
204 | } | ||
205 | |||
206 | regcache_cache_only(ssm4567->regmap, !enable); | ||
207 | |||
208 | if (enable) { | ||
209 | ret = regmap_update_bits(ssm4567->regmap, | ||
210 | SSM4567_REG_POWER_CTRL, | ||
211 | SSM4567_POWER_SPWDN, 0x00); | ||
212 | regcache_sync(ssm4567->regmap); | ||
213 | } | ||
214 | |||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | static int ssm4567_set_bias_level(struct snd_soc_codec *codec, | ||
219 | enum snd_soc_bias_level level) | ||
220 | { | ||
221 | struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec); | ||
222 | int ret = 0; | ||
223 | |||
224 | switch (level) { | ||
225 | case SND_SOC_BIAS_ON: | ||
226 | break; | ||
227 | case SND_SOC_BIAS_PREPARE: | ||
228 | break; | ||
229 | case SND_SOC_BIAS_STANDBY: | ||
230 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
231 | ret = ssm4567_set_power(ssm4567, true); | ||
232 | break; | ||
233 | case SND_SOC_BIAS_OFF: | ||
234 | ret = ssm4567_set_power(ssm4567, false); | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | if (ret) | ||
239 | return ret; | ||
240 | |||
241 | codec->dapm.bias_level = level; | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static const struct snd_soc_dai_ops ssm4567_dai_ops = { | ||
247 | .hw_params = ssm4567_hw_params, | ||
248 | .digital_mute = ssm4567_mute, | ||
249 | }; | ||
250 | |||
251 | static struct snd_soc_dai_driver ssm4567_dai = { | ||
252 | .name = "ssm4567-hifi", | ||
253 | .playback = { | ||
254 | .stream_name = "Playback", | ||
255 | .channels_min = 1, | ||
256 | .channels_max = 1, | ||
257 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
258 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | | ||
259 | SNDRV_PCM_FMTBIT_S32, | ||
260 | }, | ||
261 | .ops = &ssm4567_dai_ops, | ||
262 | }; | ||
263 | |||
264 | static struct snd_soc_codec_driver ssm4567_codec_driver = { | ||
265 | .set_bias_level = ssm4567_set_bias_level, | ||
266 | .idle_bias_off = true, | ||
267 | |||
268 | .controls = ssm4567_snd_controls, | ||
269 | .num_controls = ARRAY_SIZE(ssm4567_snd_controls), | ||
270 | .dapm_widgets = ssm4567_dapm_widgets, | ||
271 | .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets), | ||
272 | .dapm_routes = ssm4567_routes, | ||
273 | .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), | ||
274 | }; | ||
275 | |||
276 | static const struct regmap_config ssm4567_regmap_config = { | ||
277 | .val_bits = 8, | ||
278 | .reg_bits = 8, | ||
279 | |||
280 | .max_register = SSM4567_REG_SOFT_RESET, | ||
281 | .readable_reg = ssm4567_readable_reg, | ||
282 | .writeable_reg = ssm4567_writeable_reg, | ||
283 | .volatile_reg = ssm4567_volatile_reg, | ||
284 | |||
285 | .cache_type = REGCACHE_RBTREE, | ||
286 | .reg_defaults = ssm4567_reg_defaults, | ||
287 | .num_reg_defaults = ARRAY_SIZE(ssm4567_reg_defaults), | ||
288 | }; | ||
289 | |||
290 | static int ssm4567_i2c_probe(struct i2c_client *i2c, | ||
291 | const struct i2c_device_id *id) | ||
292 | { | ||
293 | struct ssm4567 *ssm4567; | ||
294 | int ret; | ||
295 | |||
296 | ssm4567 = devm_kzalloc(&i2c->dev, sizeof(*ssm4567), GFP_KERNEL); | ||
297 | if (ssm4567 == NULL) | ||
298 | return -ENOMEM; | ||
299 | |||
300 | i2c_set_clientdata(i2c, ssm4567); | ||
301 | |||
302 | ssm4567->regmap = devm_regmap_init_i2c(i2c, &ssm4567_regmap_config); | ||
303 | if (IS_ERR(ssm4567->regmap)) | ||
304 | return PTR_ERR(ssm4567->regmap); | ||
305 | |||
306 | ret = regmap_write(ssm4567->regmap, SSM4567_REG_SOFT_RESET, 0x00); | ||
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
310 | ret = ssm4567_set_power(ssm4567, false); | ||
311 | if (ret) | ||
312 | return ret; | ||
313 | |||
314 | return snd_soc_register_codec(&i2c->dev, &ssm4567_codec_driver, | ||
315 | &ssm4567_dai, 1); | ||
316 | } | ||
317 | |||
318 | static int ssm4567_i2c_remove(struct i2c_client *client) | ||
319 | { | ||
320 | snd_soc_unregister_codec(&client->dev); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static const struct i2c_device_id ssm4567_i2c_ids[] = { | ||
325 | { "ssm4567", 0 }, | ||
326 | { } | ||
327 | }; | ||
328 | MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids); | ||
329 | |||
330 | static struct i2c_driver ssm4567_driver = { | ||
331 | .driver = { | ||
332 | .name = "ssm4567", | ||
333 | .owner = THIS_MODULE, | ||
334 | }, | ||
335 | .probe = ssm4567_i2c_probe, | ||
336 | .remove = ssm4567_i2c_remove, | ||
337 | .id_table = ssm4567_i2c_ids, | ||
338 | }; | ||
339 | module_i2c_driver(ssm4567_driver); | ||
340 | |||
341 | MODULE_DESCRIPTION("ASoC SSM4567 driver"); | ||
342 | MODULE_AUTHOR("Anatol Pomozov <anatol@chromium.org>"); | ||
343 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 9aa1323fb2ab..89c748dd3d6e 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * sound/soc/codecs/sta529.c -- spear ALSA Soc codec driver | 4 | * sound/soc/codecs/sta529.c -- spear ALSA Soc codec driver |
5 | * | 5 | * |
6 | * Copyright (C) 2012 ST Microelectronics | 6 | * Copyright (C) 2012 ST Microelectronics |
7 | * Rajeev Kumar <rajeev-dlh.kumar@st.com> | 7 | * Rajeev Kumar <rajeevkumar.linux@gmail.com> |
8 | * | 8 | * |
9 | * This file is licensed under the terms of the GNU General Public | 9 | * This file is licensed under the terms of the GNU General Public |
10 | * License version 2. This program is licensed "as is" without any | 10 | * License version 2. This program is licensed "as is" without any |
@@ -426,5 +426,5 @@ static struct i2c_driver sta529_i2c_driver = { | |||
426 | module_i2c_driver(sta529_i2c_driver); | 426 | module_i2c_driver(sta529_i2c_driver); |
427 | 427 | ||
428 | MODULE_DESCRIPTION("ASoC STA529 codec driver"); | 428 | MODULE_DESCRIPTION("ASoC STA529 codec driver"); |
429 | MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); | 429 | MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>"); |
430 | MODULE_LICENSE("GPL"); | 430 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 23b32960ff1d..f039dc825971 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c | |||
@@ -78,6 +78,44 @@ struct tas2552_data { | |||
78 | unsigned int mclk; | 78 | unsigned int mclk; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* Input mux controls */ | ||
82 | static const char *tas2552_input_texts[] = { | ||
83 | "Digital", "Analog" | ||
84 | }; | ||
85 | |||
86 | static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7, | ||
87 | tas2552_input_texts); | ||
88 | |||
89 | static const struct snd_kcontrol_new tas2552_input_mux_control[] = { | ||
90 | SOC_DAPM_ENUM("Input selection", tas2552_input_mux_enum) | ||
91 | }; | ||
92 | |||
93 | static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] = | ||
94 | { | ||
95 | SND_SOC_DAPM_INPUT("IN"), | ||
96 | |||
97 | /* MUX Controls */ | ||
98 | SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0, | ||
99 | tas2552_input_mux_control), | ||
100 | |||
101 | SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), | ||
102 | SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), | ||
103 | SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0), | ||
104 | SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0), | ||
105 | |||
106 | SND_SOC_DAPM_OUTPUT("OUT") | ||
107 | }; | ||
108 | |||
109 | static const struct snd_soc_dapm_route tas2552_audio_map[] = { | ||
110 | {"DAC", NULL, "DAC IN"}, | ||
111 | {"Input selection", "Digital", "DAC"}, | ||
112 | {"Input selection", "Analog", "IN"}, | ||
113 | {"ClassD", NULL, "Input selection"}, | ||
114 | {"OUT", NULL, "ClassD"}, | ||
115 | {"ClassD", NULL, "PLL"}, | ||
116 | }; | ||
117 | |||
118 | #ifdef CONFIG_PM_RUNTIME | ||
81 | static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) | 119 | static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) |
82 | { | 120 | { |
83 | u8 cfg1_reg; | 121 | u8 cfg1_reg; |
@@ -90,6 +128,7 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) | |||
90 | snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, | 128 | snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, |
91 | TAS2552_SWS_MASK, cfg1_reg); | 129 | TAS2552_SWS_MASK, cfg1_reg); |
92 | } | 130 | } |
131 | #endif | ||
93 | 132 | ||
94 | static int tas2552_hw_params(struct snd_pcm_substream *substream, | 133 | static int tas2552_hw_params(struct snd_pcm_substream *substream, |
95 | struct snd_pcm_hw_params *params, | 134 | struct snd_pcm_hw_params *params, |
@@ -101,10 +140,6 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream, | |||
101 | int d; | 140 | int d; |
102 | u8 p, j; | 141 | u8 p, j; |
103 | 142 | ||
104 | /* Turn on Class D amplifier */ | ||
105 | snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN_MASK, | ||
106 | TAS2552_CLASSD_EN); | ||
107 | |||
108 | if (!tas2552->mclk) | 143 | if (!tas2552->mclk) |
109 | return -EINVAL; | 144 | return -EINVAL; |
110 | 145 | ||
@@ -147,9 +182,6 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream, | |||
147 | 182 | ||
148 | } | 183 | } |
149 | 184 | ||
150 | snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, | ||
151 | TAS2552_PLL_ENABLE); | ||
152 | |||
153 | return 0; | 185 | return 0; |
154 | } | 186 | } |
155 | 187 | ||
@@ -269,19 +301,10 @@ static const struct dev_pm_ops tas2552_pm = { | |||
269 | NULL) | 301 | NULL) |
270 | }; | 302 | }; |
271 | 303 | ||
272 | static void tas2552_shutdown(struct snd_pcm_substream *substream, | ||
273 | struct snd_soc_dai *dai) | ||
274 | { | ||
275 | struct snd_soc_codec *codec = dai->codec; | ||
276 | |||
277 | snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0); | ||
278 | } | ||
279 | |||
280 | static struct snd_soc_dai_ops tas2552_speaker_dai_ops = { | 304 | static struct snd_soc_dai_ops tas2552_speaker_dai_ops = { |
281 | .hw_params = tas2552_hw_params, | 305 | .hw_params = tas2552_hw_params, |
282 | .set_sysclk = tas2552_set_dai_sysclk, | 306 | .set_sysclk = tas2552_set_dai_sysclk, |
283 | .set_fmt = tas2552_set_dai_fmt, | 307 | .set_fmt = tas2552_set_dai_fmt, |
284 | .shutdown = tas2552_shutdown, | ||
285 | .digital_mute = tas2552_mute, | 308 | .digital_mute = tas2552_mute, |
286 | }; | 309 | }; |
287 | 310 | ||
@@ -294,7 +317,7 @@ static struct snd_soc_dai_driver tas2552_dai[] = { | |||
294 | { | 317 | { |
295 | .name = "tas2552-amplifier", | 318 | .name = "tas2552-amplifier", |
296 | .playback = { | 319 | .playback = { |
297 | .stream_name = "Speaker", | 320 | .stream_name = "Playback", |
298 | .channels_min = 2, | 321 | .channels_min = 2, |
299 | .channels_max = 2, | 322 | .channels_max = 2, |
300 | .rates = SNDRV_PCM_RATE_8000_192000, | 323 | .rates = SNDRV_PCM_RATE_8000_192000, |
@@ -312,6 +335,7 @@ static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 24); | |||
312 | static const struct snd_kcontrol_new tas2552_snd_controls[] = { | 335 | static const struct snd_kcontrol_new tas2552_snd_controls[] = { |
313 | SOC_SINGLE_TLV("Speaker Driver Playback Volume", | 336 | SOC_SINGLE_TLV("Speaker Driver Playback Volume", |
314 | TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv), | 337 | TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv), |
338 | SOC_DAPM_SINGLE("Playback AMP", SND_SOC_NOPM, 0, 1, 0), | ||
315 | }; | 339 | }; |
316 | 340 | ||
317 | static const struct reg_default tas2552_init_regs[] = { | 341 | static const struct reg_default tas2552_init_regs[] = { |
@@ -321,6 +345,7 @@ static const struct reg_default tas2552_init_regs[] = { | |||
321 | static int tas2552_codec_probe(struct snd_soc_codec *codec) | 345 | static int tas2552_codec_probe(struct snd_soc_codec *codec) |
322 | { | 346 | { |
323 | struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); | 347 | struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); |
348 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
324 | int ret; | 349 | int ret; |
325 | 350 | ||
326 | tas2552->codec = codec; | 351 | tas2552->codec = codec; |
@@ -362,9 +387,14 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec) | |||
362 | goto patch_fail; | 387 | goto patch_fail; |
363 | } | 388 | } |
364 | 389 | ||
365 | snd_soc_write(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN | | 390 | snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | |
366 | TAS2552_BOOST_EN | TAS2552_APT_EN | | 391 | TAS2552_APT_EN | TAS2552_LIM_EN); |
367 | TAS2552_LIM_EN); | 392 | |
393 | snd_soc_dapm_new_controls(dapm, tas2552_dapm_widgets, | ||
394 | ARRAY_SIZE(tas2552_dapm_widgets)); | ||
395 | snd_soc_dapm_add_routes(dapm, tas2552_audio_map, | ||
396 | ARRAY_SIZE(tas2552_audio_map)); | ||
397 | |||
368 | return 0; | 398 | return 0; |
369 | 399 | ||
370 | patch_fail: | 400 | patch_fail: |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 0f64c7890eed..145fe5b253d4 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -167,13 +167,13 @@ struct aic31xx_priv { | |||
167 | struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; | 167 | struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; |
168 | struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; | 168 | struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; |
169 | unsigned int sysclk; | 169 | unsigned int sysclk; |
170 | u8 p_div; | ||
170 | int rate_div_line; | 171 | int rate_div_line; |
171 | }; | 172 | }; |
172 | 173 | ||
173 | struct aic31xx_rate_divs { | 174 | struct aic31xx_rate_divs { |
174 | u32 mclk; | 175 | u32 mclk_p; |
175 | u32 rate; | 176 | u32 rate; |
176 | u8 p_val; | ||
177 | u8 pll_j; | 177 | u8 pll_j; |
178 | u16 pll_d; | 178 | u16 pll_d; |
179 | u16 dosr; | 179 | u16 dosr; |
@@ -186,51 +186,51 @@ struct aic31xx_rate_divs { | |||
186 | 186 | ||
187 | /* ADC dividers can be disabled by cofiguring them to 0 */ | 187 | /* ADC dividers can be disabled by cofiguring them to 0 */ |
188 | static const struct aic31xx_rate_divs aic31xx_divs[] = { | 188 | static const struct aic31xx_rate_divs aic31xx_divs[] = { |
189 | /* mclk rate pll: p j d dosr ndac mdac aors nadc madc */ | 189 | /* mclk/p rate pll: j d dosr ndac mdac aors nadc madc */ |
190 | /* 8k rate */ | 190 | /* 8k rate */ |
191 | {12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2}, | 191 | {12000000, 8000, 8, 1920, 128, 48, 2, 128, 48, 2}, |
192 | {24000000, 8000, 2, 8, 1920, 128, 48, 2, 128, 48, 2}, | 192 | {12000000, 8000, 8, 1920, 128, 32, 3, 128, 32, 3}, |
193 | {25000000, 8000, 2, 7, 8643, 128, 48, 2, 128, 48, 2}, | 193 | {12500000, 8000, 7, 8643, 128, 48, 2, 128, 48, 2}, |
194 | /* 11.025k rate */ | 194 | /* 11.025k rate */ |
195 | {12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2}, | 195 | {12000000, 11025, 7, 5264, 128, 32, 2, 128, 32, 2}, |
196 | {24000000, 11025, 2, 7, 5264, 128, 32, 2, 128, 32, 2}, | 196 | {12000000, 11025, 8, 4672, 128, 24, 3, 128, 24, 3}, |
197 | {25000000, 11025, 2, 7, 2253, 128, 32, 2, 128, 32, 2}, | 197 | {12500000, 11025, 7, 2253, 128, 32, 2, 128, 32, 2}, |
198 | /* 16k rate */ | 198 | /* 16k rate */ |
199 | {12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2}, | 199 | {12000000, 16000, 8, 1920, 128, 24, 2, 128, 24, 2}, |
200 | {24000000, 16000, 2, 8, 1920, 128, 24, 2, 128, 24, 2}, | 200 | {12000000, 16000, 8, 1920, 128, 16, 3, 128, 16, 3}, |
201 | {25000000, 16000, 2, 7, 8643, 128, 24, 2, 128, 24, 2}, | 201 | {12500000, 16000, 7, 8643, 128, 24, 2, 128, 24, 2}, |
202 | /* 22.05k rate */ | 202 | /* 22.05k rate */ |
203 | {12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2}, | 203 | {12000000, 22050, 7, 5264, 128, 16, 2, 128, 16, 2}, |
204 | {24000000, 22050, 2, 7, 5264, 128, 16, 2, 128, 16, 2}, | 204 | {12000000, 22050, 8, 4672, 128, 12, 3, 128, 12, 3}, |
205 | {25000000, 22050, 2, 7, 2253, 128, 16, 2, 128, 16, 2}, | 205 | {12500000, 22050, 7, 2253, 128, 16, 2, 128, 16, 2}, |
206 | /* 32k rate */ | 206 | /* 32k rate */ |
207 | {12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2}, | 207 | {12000000, 32000, 8, 1920, 128, 12, 2, 128, 12, 2}, |
208 | {24000000, 32000, 2, 8, 1920, 128, 12, 2, 128, 12, 2}, | 208 | {12000000, 32000, 8, 1920, 128, 8, 3, 128, 8, 3}, |
209 | {25000000, 32000, 2, 7, 8643, 128, 12, 2, 128, 12, 2}, | 209 | {12500000, 32000, 7, 8643, 128, 12, 2, 128, 12, 2}, |
210 | /* 44.1k rate */ | 210 | /* 44.1k rate */ |
211 | {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2}, | 211 | {12000000, 44100, 7, 5264, 128, 8, 2, 128, 8, 2}, |
212 | {24000000, 44100, 2, 7, 5264, 128, 8, 2, 128, 8, 2}, | 212 | {12000000, 44100, 8, 4672, 128, 6, 3, 128, 6, 3}, |
213 | {25000000, 44100, 2, 7, 2253, 128, 8, 2, 128, 8, 2}, | 213 | {12500000, 44100, 7, 2253, 128, 8, 2, 128, 8, 2}, |
214 | /* 48k rate */ | 214 | /* 48k rate */ |
215 | {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2}, | 215 | {12000000, 48000, 8, 1920, 128, 8, 2, 128, 8, 2}, |
216 | {24000000, 48000, 2, 8, 1920, 128, 8, 2, 128, 8, 2}, | 216 | {12000000, 48000, 7, 6800, 96, 5, 4, 96, 5, 4}, |
217 | {25000000, 48000, 2, 7, 8643, 128, 8, 2, 128, 8, 2}, | 217 | {12500000, 48000, 7, 8643, 128, 8, 2, 128, 8, 2}, |
218 | /* 88.2k rate */ | 218 | /* 88.2k rate */ |
219 | {12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2}, | 219 | {12000000, 88200, 7, 5264, 64, 8, 2, 64, 8, 2}, |
220 | {24000000, 88200, 2, 7, 5264, 64, 8, 2, 64, 8, 2}, | 220 | {12000000, 88200, 8, 4672, 64, 6, 3, 64, 6, 3}, |
221 | {25000000, 88200, 2, 7, 2253, 64, 8, 2, 64, 8, 2}, | 221 | {12500000, 88200, 7, 2253, 64, 8, 2, 64, 8, 2}, |
222 | /* 96k rate */ | 222 | /* 96k rate */ |
223 | {12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2}, | 223 | {12000000, 96000, 8, 1920, 64, 8, 2, 64, 8, 2}, |
224 | {24000000, 96000, 2, 8, 1920, 64, 8, 2, 64, 8, 2}, | 224 | {12000000, 96000, 7, 6800, 48, 5, 4, 48, 5, 4}, |
225 | {25000000, 96000, 2, 7, 8643, 64, 8, 2, 64, 8, 2}, | 225 | {12500000, 96000, 7, 8643, 64, 8, 2, 64, 8, 2}, |
226 | /* 176.4k rate */ | 226 | /* 176.4k rate */ |
227 | {12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2}, | 227 | {12000000, 176400, 7, 5264, 32, 8, 2, 32, 8, 2}, |
228 | {24000000, 176400, 2, 7, 5264, 32, 8, 2, 32, 8, 2}, | 228 | {12000000, 176400, 8, 4672, 32, 6, 3, 32, 6, 3}, |
229 | {25000000, 176400, 2, 7, 2253, 32, 8, 2, 32, 8, 2}, | 229 | {12500000, 176400, 7, 2253, 32, 8, 2, 32, 8, 2}, |
230 | /* 192k rate */ | 230 | /* 192k rate */ |
231 | {12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2}, | 231 | {12000000, 192000, 8, 1920, 32, 8, 2, 32, 8, 2}, |
232 | {24000000, 192000, 2, 8, 1920, 32, 8, 2, 32, 8, 2}, | 232 | {12000000, 192000, 7, 6800, 24, 5, 4, 24, 5, 4}, |
233 | {25000000, 192000, 2, 7, 8643, 32, 8, 2, 32, 8, 2}, | 233 | {12500000, 192000, 7, 8643, 32, 8, 2, 32, 8, 2}, |
234 | }; | 234 | }; |
235 | 235 | ||
236 | static const char * const ldac_in_text[] = { | 236 | static const char * const ldac_in_text[] = { |
@@ -680,7 +680,10 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, | |||
680 | struct snd_pcm_hw_params *params) | 680 | struct snd_pcm_hw_params *params) |
681 | { | 681 | { |
682 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 682 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
683 | int bclk_score = snd_soc_params_to_frame_size(params); | ||
684 | int mclk_p = aic31xx->sysclk / aic31xx->p_div; | ||
683 | int bclk_n = 0; | 685 | int bclk_n = 0; |
686 | int match = -1; | ||
684 | int i; | 687 | int i; |
685 | 688 | ||
686 | /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ | 689 | /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ |
@@ -691,19 +694,41 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, | |||
691 | 694 | ||
692 | for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) { | 695 | for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) { |
693 | if (aic31xx_divs[i].rate == params_rate(params) && | 696 | if (aic31xx_divs[i].rate == params_rate(params) && |
694 | aic31xx_divs[i].mclk == aic31xx->sysclk) | 697 | aic31xx_divs[i].mclk_p == mclk_p) { |
695 | break; | 698 | int s = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) % |
699 | snd_soc_params_to_frame_size(params); | ||
700 | int bn = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) / | ||
701 | snd_soc_params_to_frame_size(params); | ||
702 | if (s < bclk_score && bn > 0) { | ||
703 | match = i; | ||
704 | bclk_n = bn; | ||
705 | bclk_score = s; | ||
706 | } | ||
707 | } | ||
696 | } | 708 | } |
697 | 709 | ||
698 | if (i == ARRAY_SIZE(aic31xx_divs)) { | 710 | if (match == -1) { |
699 | dev_err(codec->dev, "%s: Sampling rate %u not supported\n", | 711 | dev_err(codec->dev, |
712 | "%s: Sample rate (%u) and format not supported\n", | ||
700 | __func__, params_rate(params)); | 713 | __func__, params_rate(params)); |
714 | /* See bellow for details how fix this. */ | ||
701 | return -EINVAL; | 715 | return -EINVAL; |
702 | } | 716 | } |
717 | if (bclk_score != 0) { | ||
718 | dev_warn(codec->dev, "Can not produce exact bitclock"); | ||
719 | /* This is fine if using dsp format, but if using i2s | ||
720 | there may be trouble. To fix the issue edit the | ||
721 | aic31xx_divs table for your mclk and sample | ||
722 | rate. Details can be found from: | ||
723 | http://www.ti.com/lit/ds/symlink/tlv320aic3100.pdf | ||
724 | Section: 5.6 CLOCK Generation and PLL | ||
725 | */ | ||
726 | } | ||
727 | i = match; | ||
703 | 728 | ||
704 | /* PLL configuration */ | 729 | /* PLL configuration */ |
705 | snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK, | 730 | snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK, |
706 | (aic31xx_divs[i].p_val << 4) | 0x01); | 731 | (aic31xx->p_div << 4) | 0x01); |
707 | snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j); | 732 | snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j); |
708 | 733 | ||
709 | snd_soc_write(codec, AIC31XX_PLLDMSB, | 734 | snd_soc_write(codec, AIC31XX_PLLDMSB, |
@@ -729,14 +754,6 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, | |||
729 | snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr); | 754 | snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr); |
730 | 755 | ||
731 | /* Bit clock divider configuration. */ | 756 | /* Bit clock divider configuration. */ |
732 | bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) | ||
733 | / snd_soc_params_to_frame_size(params); | ||
734 | if (bclk_n == 0) { | ||
735 | dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n", | ||
736 | __func__); | ||
737 | return -EINVAL; | ||
738 | } | ||
739 | |||
740 | snd_soc_update_bits(codec, AIC31XX_BCLKN, | 757 | snd_soc_update_bits(codec, AIC31XX_BCLKN, |
741 | AIC31XX_PLL_MASK, bclk_n); | 758 | AIC31XX_PLL_MASK, bclk_n); |
742 | 759 | ||
@@ -745,7 +762,7 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, | |||
745 | dev_dbg(codec->dev, | 762 | dev_dbg(codec->dev, |
746 | "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", | 763 | "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", |
747 | aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d, | 764 | aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d, |
748 | aic31xx_divs[i].p_val, aic31xx_divs[i].dosr, | 765 | aic31xx->p_div, aic31xx_divs[i].dosr, |
749 | aic31xx_divs[i].ndac, aic31xx_divs[i].mdac, | 766 | aic31xx_divs[i].ndac, aic31xx_divs[i].mdac, |
750 | aic31xx_divs[i].aosr, aic31xx_divs[i].nadc, | 767 | aic31xx_divs[i].aosr, aic31xx_divs[i].nadc, |
751 | aic31xx_divs[i].madc, bclk_n); | 768 | aic31xx_divs[i].madc, bclk_n); |
@@ -813,7 +830,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
813 | { | 830 | { |
814 | struct snd_soc_codec *codec = codec_dai->codec; | 831 | struct snd_soc_codec *codec = codec_dai->codec; |
815 | u8 iface_reg1 = 0; | 832 | u8 iface_reg1 = 0; |
816 | u8 iface_reg3 = 0; | 833 | u8 iface_reg2 = 0; |
817 | u8 dsp_a_val = 0; | 834 | u8 dsp_a_val = 0; |
818 | 835 | ||
819 | dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt); | 836 | dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt); |
@@ -838,7 +855,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
838 | /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */ | 855 | /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */ |
839 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 856 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
840 | case SND_SOC_DAIFMT_NB_NF: | 857 | case SND_SOC_DAIFMT_NB_NF: |
841 | iface_reg3 |= AIC31XX_BCLKINV_MASK; | 858 | iface_reg2 |= AIC31XX_BCLKINV_MASK; |
842 | break; | 859 | break; |
843 | case SND_SOC_DAIFMT_IB_NF: | 860 | case SND_SOC_DAIFMT_IB_NF: |
844 | break; | 861 | break; |
@@ -870,7 +887,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
870 | dsp_a_val); | 887 | dsp_a_val); |
871 | snd_soc_update_bits(codec, AIC31XX_IFACE2, | 888 | snd_soc_update_bits(codec, AIC31XX_IFACE2, |
872 | AIC31XX_BCLKINV_MASK, | 889 | AIC31XX_BCLKINV_MASK, |
873 | iface_reg3); | 890 | iface_reg2); |
874 | 891 | ||
875 | return 0; | 892 | return 0; |
876 | } | 893 | } |
@@ -885,7 +902,16 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
885 | dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", | 902 | dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", |
886 | __func__, clk_id, freq, dir); | 903 | __func__, clk_id, freq, dir); |
887 | 904 | ||
888 | for (i = 0; aic31xx_divs[i].mclk != freq; i++) { | 905 | for (i = 1; freq/i > 20000000 && i < 8; i++) |
906 | ; | ||
907 | if (freq/i > 20000000) { | ||
908 | dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n", | ||
909 | __func__, freq); | ||
910 | return -EINVAL; | ||
911 | } | ||
912 | aic31xx->p_div = i; | ||
913 | |||
914 | for (i = 0; aic31xx_divs[i].mclk_p != freq/aic31xx->p_div; i++) { | ||
889 | if (i == ARRAY_SIZE(aic31xx_divs)) { | 915 | if (i == ARRAY_SIZE(aic31xx_divs)) { |
890 | dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", | 916 | dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", |
891 | __func__, freq); | 917 | __func__, freq); |
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h index 52ed57c69dfa..fe16c34607bb 100644 --- a/sound/soc/codecs/tlv320aic31xx.h +++ b/sound/soc/codecs/tlv320aic31xx.h | |||
@@ -18,7 +18,8 @@ | |||
18 | #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 | 18 | #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 |
19 | 19 | ||
20 | #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ | 20 | #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ |
21 | | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) | 21 | | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE \ |
22 | | SNDRV_PCM_FMTBIT_S32_LE) | ||
22 | 23 | ||
23 | 24 | ||
24 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 | 25 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64f179ee9834..f7c2a575a892 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1121,6 +1121,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, | |||
1121 | static int aic3x_set_power(struct snd_soc_codec *codec, int power) | 1121 | static int aic3x_set_power(struct snd_soc_codec *codec, int power) |
1122 | { | 1122 | { |
1123 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); | 1123 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); |
1124 | unsigned int pll_c, pll_d; | ||
1124 | int ret; | 1125 | int ret; |
1125 | 1126 | ||
1126 | if (power) { | 1127 | if (power) { |
@@ -1138,6 +1139,18 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) | |||
1138 | /* Sync reg_cache with the hardware */ | 1139 | /* Sync reg_cache with the hardware */ |
1139 | regcache_cache_only(aic3x->regmap, false); | 1140 | regcache_cache_only(aic3x->regmap, false); |
1140 | regcache_sync(aic3x->regmap); | 1141 | regcache_sync(aic3x->regmap); |
1142 | |||
1143 | /* Rewrite paired PLL D registers in case cached sync skipped | ||
1144 | * writing one of them and thus caused other one also not | ||
1145 | * being written | ||
1146 | */ | ||
1147 | pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG); | ||
1148 | pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG); | ||
1149 | if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def || | ||
1150 | pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) { | ||
1151 | snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c); | ||
1152 | snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d); | ||
1153 | } | ||
1141 | } else { | 1154 | } else { |
1142 | /* | 1155 | /* |
1143 | * Do soft reset to this codec instance in order to clear | 1156 | * Do soft reset to this codec instance in order to clear |
@@ -1222,20 +1235,6 @@ static struct snd_soc_dai_driver aic3x_dai = { | |||
1222 | .symmetric_rates = 1, | 1235 | .symmetric_rates = 1, |
1223 | }; | 1236 | }; |
1224 | 1237 | ||
1225 | static int aic3x_suspend(struct snd_soc_codec *codec) | ||
1226 | { | ||
1227 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1228 | |||
1229 | return 0; | ||
1230 | } | ||
1231 | |||
1232 | static int aic3x_resume(struct snd_soc_codec *codec) | ||
1233 | { | ||
1234 | aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1235 | |||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | static void aic3x_mono_init(struct snd_soc_codec *codec) | 1238 | static void aic3x_mono_init(struct snd_soc_codec *codec) |
1240 | { | 1239 | { |
1241 | /* DAC to Mono Line Out default volume and route to Output mixer */ | 1240 | /* DAC to Mono Line Out default volume and route to Output mixer */ |
@@ -1429,8 +1428,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | |||
1429 | .idle_bias_off = true, | 1428 | .idle_bias_off = true, |
1430 | .probe = aic3x_probe, | 1429 | .probe = aic3x_probe, |
1431 | .remove = aic3x_remove, | 1430 | .remove = aic3x_remove, |
1432 | .suspend = aic3x_suspend, | ||
1433 | .resume = aic3x_resume, | ||
1434 | .controls = aic3x_snd_controls, | 1431 | .controls = aic3x_snd_controls, |
1435 | .num_controls = ARRAY_SIZE(aic3x_snd_controls), | 1432 | .num_controls = ARRAY_SIZE(aic3x_snd_controls), |
1436 | .dapm_widgets = aic3x_dapm_widgets, | 1433 | .dapm_widgets = aic3x_dapm_widgets, |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 7bb0d36d4c54..a01ad629ed61 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -2319,11 +2319,8 @@ static void wm5100_init_gpio(struct i2c_client *i2c) | |||
2319 | static void wm5100_free_gpio(struct i2c_client *i2c) | 2319 | static void wm5100_free_gpio(struct i2c_client *i2c) |
2320 | { | 2320 | { |
2321 | struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); | 2321 | struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); |
2322 | int ret; | ||
2323 | 2322 | ||
2324 | ret = gpiochip_remove(&wm5100->gpio_chip); | 2323 | gpiochip_remove(&wm5100->gpio_chip); |
2325 | if (ret != 0) | ||
2326 | dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret); | ||
2327 | } | 2324 | } |
2328 | #else | 2325 | #else |
2329 | static void wm5100_init_gpio(struct i2c_client *i2c) | 2326 | static void wm5100_init_gpio(struct i2c_client *i2c) |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 3dfdcc4197fa..628ec774cf22 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -212,7 +212,7 @@ static void wm8350_pga_work(struct work_struct *work) | |||
212 | { | 212 | { |
213 | struct snd_soc_dapm_context *dapm = | 213 | struct snd_soc_dapm_context *dapm = |
214 | container_of(work, struct snd_soc_dapm_context, delayed_work.work); | 214 | container_of(work, struct snd_soc_dapm_context, delayed_work.work); |
215 | struct snd_soc_codec *codec = dapm->codec; | 215 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); |
216 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); | 216 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); |
217 | struct wm8350_output *out1 = &wm8350_data->out1, | 217 | struct wm8350_output *out1 = &wm8350_data->out1, |
218 | *out2 = &wm8350_data->out2; | 218 | *out2 = &wm8350_data->out2; |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index a237f1627f61..31bb4801a005 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -413,7 +413,6 @@ static int wm8741_resume(struct snd_soc_codec *codec) | |||
413 | return 0; | 413 | return 0; |
414 | } | 414 | } |
415 | #else | 415 | #else |
416 | #define wm8741_suspend NULL | ||
417 | #define wm8741_resume NULL | 416 | #define wm8741_resume NULL |
418 | #endif | 417 | #endif |
419 | 418 | ||
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index e54e097f4fcb..21ca3a94fc96 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -1433,7 +1433,7 @@ static void wm8753_work(struct work_struct *work) | |||
1433 | struct snd_soc_dapm_context *dapm = | 1433 | struct snd_soc_dapm_context *dapm = |
1434 | container_of(work, struct snd_soc_dapm_context, | 1434 | container_of(work, struct snd_soc_dapm_context, |
1435 | delayed_work.work); | 1435 | delayed_work.work); |
1436 | struct snd_soc_codec *codec = dapm->codec; | 1436 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); |
1437 | wm8753_set_bias_level(codec, dapm->bias_level); | 1437 | wm8753_set_bias_level(codec, dapm->bias_level); |
1438 | } | 1438 | } |
1439 | 1439 | ||
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 0ea01dfcb6e1..3addc5fe5cb2 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -518,23 +518,6 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, | |||
518 | return 0; | 518 | return 0; |
519 | } | 519 | } |
520 | 520 | ||
521 | #ifdef CONFIG_PM | ||
522 | static int wm8804_suspend(struct snd_soc_codec *codec) | ||
523 | { | ||
524 | wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static int wm8804_resume(struct snd_soc_codec *codec) | ||
529 | { | ||
530 | wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
531 | return 0; | ||
532 | } | ||
533 | #else | ||
534 | #define wm8804_suspend NULL | ||
535 | #define wm8804_resume NULL | ||
536 | #endif | ||
537 | |||
538 | static int wm8804_remove(struct snd_soc_codec *codec) | 521 | static int wm8804_remove(struct snd_soc_codec *codec) |
539 | { | 522 | { |
540 | struct wm8804_priv *wm8804; | 523 | struct wm8804_priv *wm8804; |
@@ -671,8 +654,6 @@ static struct snd_soc_dai_driver wm8804_dai = { | |||
671 | static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { | 654 | static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { |
672 | .probe = wm8804_probe, | 655 | .probe = wm8804_probe, |
673 | .remove = wm8804_remove, | 656 | .remove = wm8804_remove, |
674 | .suspend = wm8804_suspend, | ||
675 | .resume = wm8804_resume, | ||
676 | .set_bias_level = wm8804_set_bias_level, | 657 | .set_bias_level = wm8804_set_bias_level, |
677 | .idle_bias_off = true, | 658 | .idle_bias_off = true, |
678 | 659 | ||
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index aa0984864e76..c038b3e04398 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -1877,11 +1877,7 @@ static void wm8903_init_gpio(struct wm8903_priv *wm8903) | |||
1877 | 1877 | ||
1878 | static void wm8903_free_gpio(struct wm8903_priv *wm8903) | 1878 | static void wm8903_free_gpio(struct wm8903_priv *wm8903) |
1879 | { | 1879 | { |
1880 | int ret; | 1880 | gpiochip_remove(&wm8903->gpio_chip); |
1881 | |||
1882 | ret = gpiochip_remove(&wm8903->gpio_chip); | ||
1883 | if (ret != 0) | ||
1884 | dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret); | ||
1885 | } | 1881 | } |
1886 | #else | 1882 | #else |
1887 | static void wm8903_init_gpio(struct wm8903_priv *wm8903) | 1883 | static void wm8903_init_gpio(struct wm8903_priv *wm8903) |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 1098ae32f1f9..9077411e62ce 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -3398,11 +3398,8 @@ static void wm8962_init_gpio(struct snd_soc_codec *codec) | |||
3398 | static void wm8962_free_gpio(struct snd_soc_codec *codec) | 3398 | static void wm8962_free_gpio(struct snd_soc_codec *codec) |
3399 | { | 3399 | { |
3400 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3400 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
3401 | int ret; | ||
3402 | 3401 | ||
3403 | ret = gpiochip_remove(&wm8962->gpio_chip); | 3402 | gpiochip_remove(&wm8962->gpio_chip); |
3404 | if (ret != 0) | ||
3405 | dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); | ||
3406 | } | 3403 | } |
3407 | #else | 3404 | #else |
3408 | static void wm8962_init_gpio(struct snd_soc_codec *codec) | 3405 | static void wm8962_init_gpio(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 0499cd4cfb71..39ddb9b8834c 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -615,7 +615,7 @@ static void wm8971_work(struct work_struct *work) | |||
615 | struct snd_soc_dapm_context *dapm = | 615 | struct snd_soc_dapm_context *dapm = |
616 | container_of(work, struct snd_soc_dapm_context, | 616 | container_of(work, struct snd_soc_dapm_context, |
617 | delayed_work.work); | 617 | delayed_work.work); |
618 | struct snd_soc_codec *codec = dapm->codec; | 618 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); |
619 | wm8971_set_bias_level(codec, codec->dapm.bias_level); | 619 | wm8971_set_bias_level(codec, codec->dapm.bias_level); |
620 | } | 620 | } |
621 | 621 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6cc0566dc29a..1fcb9f3f3097 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -4082,17 +4082,23 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4082 | 4082 | ||
4083 | switch (control->type) { | 4083 | switch (control->type) { |
4084 | case WM8994: | 4084 | case WM8994: |
4085 | if (wm8994->micdet_irq) { | 4085 | if (wm8994->micdet_irq) |
4086 | ret = request_threaded_irq(wm8994->micdet_irq, NULL, | 4086 | ret = request_threaded_irq(wm8994->micdet_irq, NULL, |
4087 | wm8994_mic_irq, | 4087 | wm8994_mic_irq, |
4088 | IRQF_TRIGGER_RISING, | 4088 | IRQF_TRIGGER_RISING, |
4089 | "Mic1 detect", | 4089 | "Mic1 detect", |
4090 | wm8994); | 4090 | wm8994); |
4091 | if (ret != 0) | 4091 | else |
4092 | dev_warn(codec->dev, | 4092 | ret = wm8994_request_irq(wm8994->wm8994, |
4093 | "Failed to request Mic1 detect IRQ: %d\n", | 4093 | WM8994_IRQ_MIC1_DET, |
4094 | ret); | 4094 | wm8994_mic_irq, "Mic 1 detect", |
4095 | } | 4095 | wm8994); |
4096 | |||
4097 | if (ret != 0) | ||
4098 | dev_warn(codec->dev, | ||
4099 | "Failed to request Mic1 detect IRQ: %d\n", | ||
4100 | ret); | ||
4101 | |||
4096 | 4102 | ||
4097 | ret = wm8994_request_irq(wm8994->wm8994, | 4103 | ret = wm8994_request_irq(wm8994->wm8994, |
4098 | WM8994_IRQ_MIC1_SHRT, | 4104 | WM8994_IRQ_MIC1_SHRT, |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index cae4ac5a5730..1288edeb8c7d 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -1998,23 +1998,6 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec, | |||
1998 | return 0; | 1998 | return 0; |
1999 | } | 1999 | } |
2000 | 2000 | ||
2001 | #ifdef CONFIG_PM | ||
2002 | static int wm8995_suspend(struct snd_soc_codec *codec) | ||
2003 | { | ||
2004 | wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2005 | return 0; | ||
2006 | } | ||
2007 | |||
2008 | static int wm8995_resume(struct snd_soc_codec *codec) | ||
2009 | { | ||
2010 | wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
2011 | return 0; | ||
2012 | } | ||
2013 | #else | ||
2014 | #define wm8995_suspend NULL | ||
2015 | #define wm8995_resume NULL | ||
2016 | #endif | ||
2017 | |||
2018 | static int wm8995_remove(struct snd_soc_codec *codec) | 2001 | static int wm8995_remove(struct snd_soc_codec *codec) |
2019 | { | 2002 | { |
2020 | struct wm8995_priv *wm8995; | 2003 | struct wm8995_priv *wm8995; |
@@ -2220,8 +2203,6 @@ static struct snd_soc_dai_driver wm8995_dai[] = { | |||
2220 | static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { | 2203 | static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { |
2221 | .probe = wm8995_probe, | 2204 | .probe = wm8995_probe, |
2222 | .remove = wm8995_remove, | 2205 | .remove = wm8995_remove, |
2223 | .suspend = wm8995_suspend, | ||
2224 | .resume = wm8995_resume, | ||
2225 | .set_bias_level = wm8995_set_bias_level, | 2206 | .set_bias_level = wm8995_set_bias_level, |
2226 | .idle_bias_off = true, | 2207 | .idle_bias_off = true, |
2227 | }; | 2208 | }; |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index f16ff4f56923..b1dcc11c1b23 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -2216,11 +2216,7 @@ static void wm8996_init_gpio(struct wm8996_priv *wm8996) | |||
2216 | 2216 | ||
2217 | static void wm8996_free_gpio(struct wm8996_priv *wm8996) | 2217 | static void wm8996_free_gpio(struct wm8996_priv *wm8996) |
2218 | { | 2218 | { |
2219 | int ret; | 2219 | gpiochip_remove(&wm8996->gpio_chip); |
2220 | |||
2221 | ret = gpiochip_remove(&wm8996->gpio_chip); | ||
2222 | if (ret != 0) | ||
2223 | dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret); | ||
2224 | } | 2220 | } |
2225 | #else | 2221 | #else |
2226 | static void wm8996_init_gpio(struct wm8996_priv *wm8996) | 2222 | static void wm8996_init_gpio(struct wm8996_priv *wm8996) |