summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c13
-rw-r--r--sound/soc/blackfin/Kconfig11
-rw-r--r--sound/soc/codecs/Kconfig106
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ak4671.c226
-rw-r--r--sound/soc/codecs/ak4671.h2
-rw-r--r--sound/soc/codecs/cs4271.c1
-rw-r--r--sound/soc/codecs/cs42l51.c70
-rw-r--r--sound/soc/codecs/cs42l73.c19
-rw-r--r--sound/soc/codecs/da9055.c19
-rw-r--r--sound/soc/codecs/max98090.c20
-rw-r--r--sound/soc/codecs/pcm1681.c15
-rw-r--r--sound/soc/codecs/pcm1792a.c33
-rw-r--r--sound/soc/codecs/pcm512x.c707
-rw-r--r--sound/soc/codecs/pcm512x.h162
-rw-r--r--sound/soc/codecs/rt5640.c1
-rw-r--r--sound/soc/davinci/davinci-evm.c1
-rw-r--r--sound/soc/davinci/davinci-mcasp.c83
-rw-r--r--sound/soc/fsl/fsl_esai.c4
-rw-r--r--sound/soc/fsl/fsl_esai.h2
-rw-r--r--sound/soc/fsl/imx-mc13783.c1
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c10
-rw-r--r--sound/soc/fsl/imx-wm8962.c11
-rw-r--r--sound/soc/samsung/Kconfig6
-rw-r--r--sound/soc/soc-core.c2
-rw-r--r--sound/soc/soc-dapm.c9
26 files changed, 1235 insertions, 301 deletions
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 1ead3c977a51..de433cfd044c 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -341,6 +341,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
{
int id = dai->id;
struct atmel_ssc_info *ssc_p = &ssc_info[id];
+ struct ssc_device *ssc = ssc_p->ssc;
struct atmel_pcm_dma_params *dma_params;
int dir, channels, bits;
u32 tfmr, rfmr, tcmr, rcmr;
@@ -466,7 +467,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(RCMR_START, start_event)
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
+ | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_PIN : SSC_CKS_CLOCK);
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
@@ -481,7 +483,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(TCMR_START, start_event)
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
+ | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_CLOCK : SSC_CKS_PIN);
tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(TFMR_FSDEN, 0)
@@ -550,7 +553,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(RCMR_START, SSC_START_RISING_RF)
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_PIN);
+ | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_PIN : SSC_CKS_CLOCK);
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
@@ -565,7 +569,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(TCMR_START, SSC_START_RISING_RF)
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
+ | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
+ SSC_CKS_CLOCK : SSC_CKS_PIN);
tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(TFMR_FSDEN, 0)
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 54f74f8cbb75..4544d8eb1452 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -11,7 +11,7 @@ config SND_BF5XX_I2S
config SND_BF5XX_SOC_SSM2602
tristate "SoC SSM2602 Audio Codec Add-On Card support"
- depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
+ depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
select SND_BF5XX_SOC_I2S if !BF60x
select SND_BF6XX_SOC_I2S if BF60x
select SND_SOC_SSM2602
@@ -21,10 +21,9 @@ config SND_BF5XX_SOC_SSM2602
config SND_SOC_BFIN_EVAL_ADAU1701
tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
- depends on SND_BF5XX_I2S
+ depends on SND_BF5XX_I2S && I2C
select SND_BF5XX_SOC_I2S
select SND_SOC_ADAU1701
- select I2C
help
Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ
board connected to one of the Blackfin evaluation boards like the
@@ -45,7 +44,7 @@ config SND_SOC_BFIN_EVAL_ADAU1373
config SND_SOC_BFIN_EVAL_ADAV80X
tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
- depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
+ depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
select SND_BF5XX_SOC_I2S
select SND_SOC_ADAV80X
help
@@ -58,7 +57,7 @@ config SND_SOC_BFIN_EVAL_ADAV80X
config SND_BF5XX_SOC_AD1836
tristate "SoC AD1836 Audio support for BF5xx"
- depends on SND_BF5XX_I2S
+ depends on SND_BF5XX_I2S && SPI_MASTER
select SND_BF5XX_SOC_I2S
select SND_SOC_AD1836
help
@@ -66,7 +65,7 @@ config SND_BF5XX_SOC_AD1836
config SND_BF5XX_SOC_AD193X
tristate "SoC AD193X Audio support for Blackfin"
- depends on SND_BF5XX_I2S
+ depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
select SND_BF5XX_SOC_I2S
select SND_SOC_AD193X
help
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 983d087aa92a..1035c38c5ab4 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -8,6 +8,8 @@ config SND_SOC_I2C_AND_SPI
default y if I2C=y
default y if SPI_MASTER=y
+menu "CODEC drivers"
+
config SND_SOC_ALL_CODECS
tristate "Build all ASoC CODEC drivers"
depends on COMPILE_TEST
@@ -25,6 +27,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ADS117X
select SND_SOC_AK4104 if SPI_MASTER
select SND_SOC_AK4535 if I2C
+ select SND_SOC_AK4554
select SND_SOC_AK4641 if I2C
select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C
@@ -59,6 +62,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008
+ select SND_SOC_PCM512x if SND_SOC_I2C_AND_SPI
select SND_SOC_RT5631 if I2C
select SND_SOC_RT5640 if I2C
select SND_SOC_SGTL5000 if I2C
@@ -189,8 +193,9 @@ config SND_SOC_AD73311
tristate
config SND_SOC_ADAU1701
+ tristate "Analog Devices ADAU1701 CODEC"
+ depends on I2C
select SND_SOC_SIGMADSP
- tristate
config SND_SOC_ADAU1373
tristate
@@ -202,28 +207,31 @@ config SND_SOC_ADS117X
tristate
config SND_SOC_AK4104
- tristate
+ tristate "AKM AK4104 CODEC"
+ depends on SPI_MASTER
config SND_SOC_AK4535
tristate
config SND_SOC_AK4554
- tristate
+ tristate "AKM AK4554 CODEC"
config SND_SOC_AK4641
tristate
config SND_SOC_AK4642
- tristate
+ tristate "AKM AK4642 CODEC"
+ depends on I2C
config SND_SOC_AK4671
tristate
config SND_SOC_AK5386
- tristate
+ tristate "AKM AK5638 CODEC"
config SND_SOC_ALC5623
tristate
+
config SND_SOC_ALC5632
tristate
@@ -234,14 +242,17 @@ config SND_SOC_CS42L51
tristate
config SND_SOC_CS42L52
- tristate
+ tristate "Cirrus Logic CS42L52 CODEC"
+ depends on I2C
config SND_SOC_CS42L73
- tristate
+ tristate "Cirrus Logic CS42L73 CODEC"
+ depends on I2C
# Cirrus Logic CS4270 Codec
config SND_SOC_CS4270
- tristate
+ tristate "Cirrus Logic CS4270 CODEC"
+ depends on I2C
# Cirrus Logic CS4270 Codec VD = 3.3V Errata
# Select if you are affected by the errata where the part will not function
@@ -252,7 +263,8 @@ config SND_SOC_CS4270_VD33_ERRATA
depends on SND_SOC_CS4270
config SND_SOC_CS4271
- tristate
+ tristate "Cirrus Logic CS4271 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_CX20442
tristate
@@ -283,6 +295,9 @@ config SND_SOC_BT_SCO
config SND_SOC_DMIC
tristate
+config SND_SOC_HDMI_CODEC
+ tristate "HDMI stub CODEC"
+
config SND_SOC_ISABELLE
tristate
@@ -301,18 +316,20 @@ config SND_SOC_MAX98095
config SND_SOC_MAX9850
tristate
-config SND_SOC_HDMI_CODEC
- tristate
-
config SND_SOC_PCM1681
- tristate
+ tristate "Texas Instruments PCM1681 CODEC"
+ depends on I2C
config SND_SOC_PCM1792A
- tristate
+ tristate "Texas Instruments PCM1792A CODEC"
+ depends on SPI_MASTER
config SND_SOC_PCM3008
tristate
+config SND_SOC_PCM512x
+ tristate "Texas Instruments PCM512x CODECs"
+
config SND_SOC_RT5631
tristate
@@ -321,7 +338,8 @@ config SND_SOC_RT5640
#Freescale sgtl5000 codec
config SND_SOC_SGTL5000
- tristate
+ tristate "Freescale SGTL5000 CODEC"
+ depends on I2C
config SND_SOC_SI476X
tristate
@@ -334,7 +352,7 @@ config SND_SOC_SN95031
tristate
config SND_SOC_SPDIF
- tristate
+ tristate "S/PDIF CODEC"
config SND_SOC_SSM2518
tristate
@@ -352,7 +370,8 @@ config SND_SOC_STAC9766
tristate
config SND_SOC_TAS5086
- tristate
+ tristate "Texas Instruments TAS5086 speaker amplifier"
+ depends on I2C
config SND_SOC_TLV320AIC23
tristate
@@ -365,7 +384,8 @@ config SND_SOC_TLV320AIC32X4
tristate
config SND_SOC_TLV320AIC3X
- tristate
+ tristate "Texas Instruments TLV320AIC3x CODECs"
+ depends on I2C
config SND_SOC_TLV320DAC33
tristate
@@ -414,55 +434,69 @@ config SND_SOC_WM8400
tristate
config SND_SOC_WM8510
- tristate
+ tristate "Wolfson Microelectronics WM8510 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8523
- tristate
+ tristate "Wolfson Microelectronics WM8523 DAC"
+ depends on I2C
config SND_SOC_WM8580
- tristate
+ tristate "Wolfson Microelectronics WM8523 CODEC"
+ depends on I2C
config SND_SOC_WM8711
- tristate
+ tristate "Wolfson Microelectronics WM8711 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8727
tristate
config SND_SOC_WM8728
- tristate
+ tristate "Wolfson Microelectronics WM8728 DAC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8731
- tristate
+ tristate "Wolfson Microelectronics WM8731 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8737
- tristate
+ tristate "Wolfson Microelectronics WM8737 ADC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8741
- tristate
+ tristate "Wolfson Microelectronics WM8737 DAC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8750
- tristate
+ tristate "Wolfson Microelectronics WM8750 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8753
- tristate
+ tristate "Wolfson Microelectronics WM8753 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8770
- tristate
+ tristate "Wolfson Microelectronics WM8770 CODEC"
+ depends on SPI_MASTER
config SND_SOC_WM8776
- tristate
+ tristate "Wolfson Microelectronics WM8776 CODEC"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8782
tristate
config SND_SOC_WM8804
- tristate
+ tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver"
+ depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8900
tristate
config SND_SOC_WM8903
- tristate
+ tristate "Wolfson Microelectronics WM8903 CODEC"
+ depends on I2C
config SND_SOC_WM8904
tristate
@@ -480,7 +514,8 @@ config SND_SOC_WM8961
tristate
config SND_SOC_WM8962
- tristate
+ tristate "Wolfson Microelectronics WM8962 CODEC"
+ depends on I2C
config SND_SOC_WM8971
tristate
@@ -553,4 +588,7 @@ config SND_SOC_ML26124
tristate
config SND_SOC_TPA6130A2
- tristate
+ tristate "Texas Instruments TPA6130A2 headphone amplifier"
+ depends on I2C
+
+endmenu
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index bc126764a44d..d3b536fc075d 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -46,6 +46,7 @@ snd-soc-hdmi-codec-objs := hdmi.o
snd-soc-pcm1681-objs := pcm1681.o
snd-soc-pcm1792a-codec-objs := pcm1792a.o
snd-soc-pcm3008-objs := pcm3008.o
+snd-soc-pcm512x-objs := pcm512x.o
snd-soc-rt5631-objs := rt5631.o
snd-soc-rt5640-objs := rt5640.o
snd-soc-sgtl5000-objs := sgtl5000.o
@@ -179,6 +180,7 @@ obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
+obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 25bdf6ad4a54..743bbe31bc08 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/soc.h>
#include <sound/initval.h>
@@ -23,104 +24,99 @@
#include "ak4671.h"
-/* codec private data */
-struct ak4671_priv {
- enum snd_soc_control_type control_type;
-};
-
/* ak4671 register cache & default register settings */
-static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
- 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
- 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
- 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
- 0x02, /* AK4671_FORMAT_SELECT (0x03) */
- 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
- 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
- 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
- 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
- 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
- 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
- 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
- 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
- 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
- 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
- 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
- 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
- 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
- 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
- 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
- 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
- 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
- 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
- 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
- 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
- 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
- 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
- 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
- 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
- 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
- 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
- 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
- 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
- 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
- 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
- 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
- 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
- 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
- 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
- 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
- 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
- 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
- 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
- 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
- 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
- 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
- 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
- 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
- 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
- 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
- 0x00, /* this register not used */
- 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
- 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
- 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
- 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
- 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
- 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
- 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
- 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
- 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
- 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
- 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
- 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
- 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
- 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
- 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
- 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
- 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
- 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
- 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
- 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
- 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
- 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
- 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
- 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
- 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
- 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
- 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
- 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
- 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
- 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
- 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
- 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
- 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
- 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
- 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
- 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
- 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
- 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
- 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
- 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
- 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
+static const struct reg_default ak4671_reg_defaults[] = {
+ { 0x00, 0x00 }, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
+ { 0x01, 0xf6 }, /* AK4671_PLL_MODE_SELECT0 (0x01) */
+ { 0x02, 0x00 }, /* AK4671_PLL_MODE_SELECT1 (0x02) */
+ { 0x03, 0x02 }, /* AK4671_FORMAT_SELECT (0x03) */
+ { 0x04, 0x00 }, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
+ { 0x05, 0x55 }, /* AK4671_MIC_AMP_GAIN (0x05) */
+ { 0x06, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
+ { 0x07, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
+ { 0x08, 0xb5 }, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
+ { 0x09, 0x00 }, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
+ { 0x0a, 0x00 }, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
+ { 0x0b, 0x00 }, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
+ { 0x0c, 0x00 }, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
+ { 0x0d, 0x00 }, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
+ { 0x0e, 0x00 }, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
+ { 0x0f, 0x00 }, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
+ { 0x10, 0x00 }, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
+ { 0x11, 0x80 }, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
+ { 0x12, 0x91 }, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
+ { 0x13, 0x91 }, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
+ { 0x14, 0xe1 }, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
+ { 0x15, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
+ { 0x16, 0x00 }, /* AK4671_ALC_TIMER_SELECT (0x16) */
+ { 0x17, 0x00 }, /* AK4671_ALC_MODE_CONTROL (0x17) */
+ { 0x18, 0x02 }, /* AK4671_MODE_CONTROL1 (0x18) */
+ { 0x19, 0x01 }, /* AK4671_MODE_CONTROL2 (0x19) */
+ { 0x1a, 0x18 }, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
+ { 0x1b, 0x18 }, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
+ { 0x1c, 0x00 }, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
+ { 0x1d, 0x02 }, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
+ { 0x1e, 0x00 }, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
+ { 0x1f, 0x00 }, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
+ { 0x20, 0x00 }, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
+ { 0x21, 0x00 }, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
+ { 0x22, 0x00 }, /* AK4671_EQ_COEFFICIENT0 (0x22) */
+ { 0x23, 0x00 }, /* AK4671_EQ_COEFFICIENT1 (0x23) */
+ { 0x24, 0x00 }, /* AK4671_EQ_COEFFICIENT2 (0x24) */
+ { 0x25, 0x00 }, /* AK4671_EQ_COEFFICIENT3 (0x25) */
+ { 0x26, 0x00 }, /* AK4671_EQ_COEFFICIENT4 (0x26) */
+ { 0x27, 0x00 }, /* AK4671_EQ_COEFFICIENT5 (0x27) */
+ { 0x28, 0xa9 }, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
+ { 0x29, 0x1f }, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
+ { 0x2a, 0xad }, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
+ { 0x2b, 0x20 }, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
+ { 0x2c, 0x00 }, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
+ { 0x2d, 0x00 }, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
+ { 0x2e, 0x00 }, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
+ { 0x2f, 0x00 }, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
+ { 0x30, 0x00 }, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
+
+ { 0x32, 0x00 }, /* AK4671_E1_COEFFICIENT0 (0x32) */
+ { 0x33, 0x00 }, /* AK4671_E1_COEFFICIENT1 (0x33) */
+ { 0x34, 0x00 }, /* AK4671_E1_COEFFICIENT2 (0x34) */
+ { 0x35, 0x00 }, /* AK4671_E1_COEFFICIENT3 (0x35) */
+ { 0x36, 0x00 }, /* AK4671_E1_COEFFICIENT4 (0x36) */
+ { 0x37, 0x00 }, /* AK4671_E1_COEFFICIENT5 (0x37) */
+ { 0x38, 0x00 }, /* AK4671_E2_COEFFICIENT0 (0x38) */
+ { 0x39, 0x00 }, /* AK4671_E2_COEFFICIENT1 (0x39) */
+ { 0x3a, 0x00 }, /* AK4671_E2_COEFFICIENT2 (0x3a) */
+ { 0x3b, 0x00 }, /* AK4671_E2_COEFFICIENT3 (0x3b) */
+ { 0x3c, 0x00 }, /* AK4671_E2_COEFFICIENT4 (0x3c) */
+ { 0x3d, 0x00 }, /* AK4671_E2_COEFFICIENT5 (0x3d) */
+ { 0x3e, 0x00 }, /* AK4671_E3_COEFFICIENT0 (0x3e) */
+ { 0x3f, 0x00 }, /* AK4671_E3_COEFFICIENT1 (0x3f) */
+ { 0x40, 0x00 }, /* AK4671_E3_COEFFICIENT2 (0x40) */
+ { 0x41, 0x00 }, /* AK4671_E3_COEFFICIENT3 (0x41) */
+ { 0x42, 0x00 }, /* AK4671_E3_COEFFICIENT4 (0x42) */
+ { 0x43, 0x00 }, /* AK4671_E3_COEFFICIENT5 (0x43) */
+ { 0x44, 0x00 }, /* AK4671_E4_COEFFICIENT0 (0x44) */
+ { 0x45, 0x00 }, /* AK4671_E4_COEFFICIENT1 (0x45) */
+ { 0x46, 0x00 }, /* AK4671_E4_COEFFICIENT2 (0x46) */
+ { 0x47, 0x00 }, /* AK4671_E4_COEFFICIENT3 (0x47) */
+ { 0x48, 0x00 }, /* AK4671_E4_COEFFICIENT4 (0x48) */
+ { 0x49, 0x00 }, /* AK4671_E4_COEFFICIENT5 (0x49) */
+ { 0x4a, 0x00 }, /* AK4671_E5_COEFFICIENT0 (0x4a) */
+ { 0x4b, 0x00 }, /* AK4671_E5_COEFFICIENT1 (0x4b) */
+ { 0x4c, 0x00 }, /* AK4671_E5_COEFFICIENT2 (0x4c) */
+ { 0x4d, 0x00 }, /* AK4671_E5_COEFFICIENT3 (0x4d) */
+ { 0x4e, 0x00 }, /* AK4671_E5_COEFFICIENT4 (0x4e) */
+ { 0x4f, 0x00 }, /* AK4671_E5_COEFFICIENT5 (0x4f) */
+ { 0x50, 0x88 }, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
+ { 0x51, 0x88 }, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
+ { 0x52, 0x08 }, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
+ { 0x53, 0x00 }, /* AK4671_PCM_IF_CONTROL0 (0x53) */
+ { 0x54, 0x00 }, /* AK4671_PCM_IF_CONTROL1 (0x54) */
+ { 0x55, 0x00 }, /* AK4671_PCM_IF_CONTROL2 (0x55) */
+ { 0x56, 0x18 }, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
+ { 0x57, 0x18 }, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
+ { 0x58, 0x00 }, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
+ { 0x59, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
+ { 0x5a, 0x00 }, /* AK4671_SAR_ADC_CONTROL (0x5a) */
};
/*
@@ -619,18 +615,14 @@ static struct snd_soc_dai_driver ak4671_dai = {
static int ak4671_probe(struct snd_soc_codec *codec)
{
- struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- snd_soc_add_codec_controls(codec, ak4671_snd_controls,
- ARRAY_SIZE(ak4671_snd_controls));
-
ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return ret;
@@ -646,28 +638,36 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
.probe = ak4671_probe,
.remove = ak4671_remove,
.set_bias_level = ak4671_set_bias_level,
- .reg_cache_size = AK4671_CACHEREGNUM,
- .reg_word_size = sizeof(u8),
- .reg_cache_default = ak4671_reg,
+ .controls = ak4671_snd_controls,
+ .num_controls = ARRAY_SIZE(ak4671_snd_controls),
.dapm_widgets = ak4671_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
.dapm_routes = ak4671_intercon,
.num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
};
+static const struct regmap_config ak4671_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK4671_SAR_ADC_CONTROL,
+ .reg_defaults = ak4671_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(ak4671_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int ak4671_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct ak4671_priv *ak4671;
+ struct regmap *regmap;
int ret;
- ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv),
- GFP_KERNEL);
- if (ak4671 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(client, ak4671);
- ak4671->control_type = SND_SOC_I2C;
+ regmap = devm_regmap_init_i2c(client, &ak4671_regmap);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(&client->dev, "Failed to create regmap: %d\n", ret);
+ return ret;
+ }
ret = snd_soc_register_codec(&client->dev,
&soc_codec_dev_ak4671, &ak4671_dai, 1);
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
index 61cb7ab7552c..394a34d3f50a 100644
--- a/sound/soc/codecs/ak4671.h
+++ b/sound/soc/codecs/ak4671.h
@@ -105,8 +105,6 @@
#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
#define AK4671_SAR_ADC_CONTROL 0x5a
-#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
-
/* Bitfield Definitions */
/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index ce05fd93dc74..f7bbe6fdba67 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -159,7 +159,6 @@ static bool cs4271_volatile_reg(struct device *dev, unsigned int reg)
}
struct cs4271_private {
- /* SND_SOC_I2C or SND_SOC_SPI */
unsigned int mclk;
bool master;
bool deemph;
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 6e9ea8379a91..e53c8714591f 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -30,6 +30,7 @@
#include <sound/pcm_params.h>
#include <sound/pcm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include "cs42l51.h"
@@ -40,7 +41,6 @@ enum master_slave_mode {
};
struct cs42l51_private {
- enum snd_soc_control_type control_type;
unsigned int mclk;
unsigned int audio_mode; /* The mode (I2S or left-justified) */
enum master_slave_mode func;
@@ -52,24 +52,6 @@ struct cs42l51_private {
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
-static int cs42l51_fill_cache(struct snd_soc_codec *codec)
-{
- u8 *cache = codec->reg_cache + 1;
- struct i2c_client *i2c_client = to_i2c_client(codec->dev);
- s32 length;
-
- length = i2c_smbus_read_i2c_block_data(i2c_client,
- CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
- if (length != CS42L51_NUMREGS) {
- dev_err(&i2c_client->dev,
- "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
- i2c_client->addr, length, CS42L51_NUMREGS);
- return -EIO;
- }
-
- return 0;
-}
-
static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -508,13 +490,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
int ret, reg;
- ret = cs42l51_fill_cache(codec);
- if (ret < 0) {
- dev_err(codec->dev, "failed to fill register cache\n");
- return ret;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -538,8 +514,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
.probe = cs42l51_probe,
- .reg_cache_size = CS42L51_NUMREGS + 1,
- .reg_word_size = sizeof(u8),
.controls = cs42l51_snd_controls,
.num_controls = ARRAY_SIZE(cs42l51_snd_controls),
@@ -549,38 +523,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
.num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
};
+static const struct regmap_config cs42l51_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CS42L51_CHARGE_FREQ,
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct cs42l51_private *cs42l51;
+ struct regmap *regmap;
+ unsigned int val;
int ret;
+ regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(&i2c_client->dev, "Failed to create regmap: %d\n",
+ ret);
+ return ret;
+ }
+
/* Verify that we have a CS42L51 */
- ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
+ ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read I2C\n");
goto error;
}
- if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
- (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
- dev_err(&i2c_client->dev, "Invalid chip id\n");
+ if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
+ (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
+ dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val);
ret = -ENODEV;
goto error;
}
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
- ret & 7);
+ val & 7);
cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
GFP_KERNEL);
- if (!cs42l51) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
+ if (!cs42l51)
return -ENOMEM;
- }
i2c_set_clientdata(i2c_client, cs42l51);
- cs42l51->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs42l51, &cs42l51_dai, 1);
@@ -600,10 +589,17 @@ static const struct i2c_device_id cs42l51_id[] = {
};
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
+static const struct of_device_id cs42l51_of_match[] = {
+ { .compatible = "cirrus,cs42l51", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cs42l51_of_match);
+
static struct i2c_driver cs42l51_i2c_driver = {
.driver = {
.name = "cs42l51-codec",
.owner = THIS_MODULE,
+ .of_match_table = cs42l51_of_match,
},
.id_table = cs42l51_id,
.probe = cs42l51_i2c_probe,
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 549d5d6a3fef..69c8e2de7d0e 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1108,7 +1108,7 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
return 0;
}
-static u32 cs42l73_asrc_rates[] = {
+static const unsigned int cs42l73_asrc_rates[] = {
8000, 11025, 12000, 16000, 22050,
24000, 32000, 44100, 48000
};
@@ -1241,7 +1241,7 @@ static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
0x7F, tristate << 7);
}
-static struct snd_pcm_hw_constraint_list constraints_12_24 = {
+static const struct snd_pcm_hw_constraint_list constraints_12_24 = {
.count = ARRAY_SIZE(cs42l73_asrc_rates),
.list = cs42l73_asrc_rates,
};
@@ -1255,9 +1255,6 @@ static int cs42l73_pcm_startup(struct snd_pcm_substream *substream,
return 0;
}
-/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
-#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
-
#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
@@ -1278,14 +1275,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
.stream_name = "XSP Playback",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.capture = {
.stream_name = "XSP Capture",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.ops = &cs42l73_ops,
@@ -1298,14 +1295,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
.stream_name = "ASP Playback",
.channels_min = 2,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.capture = {
.stream_name = "ASP Capture",
.channels_min = 2,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.ops = &cs42l73_ops,
@@ -1318,14 +1315,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
.stream_name = "VSP Playback",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.capture = {
.stream_name = "VSP Capture",
.channels_min = 1,
.channels_max = 2,
- .rates = CS42L73_RATES,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L73_FORMATS,
},
.ops = &cs42l73_ops,
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index 52b79a487ac7..be31f3cfd46e 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -18,6 +18,8 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -1523,17 +1525,30 @@ static int da9055_remove(struct i2c_client *client)
return 0;
}
+/*
+ * DO NOT change the device Ids. The naming is intentionally specific as both
+ * the CODEC and PMIC parts of this chip are instantiated separately as I2C
+ * devices (both have configurable I2C addresses, and are to all intents and
+ * purposes separate). As a result there are specific DA9055 Ids for CODEC
+ * and PMIC, which must be different to operate together.
+ */
static const struct i2c_device_id da9055_i2c_id[] = {
- { "da9055", 0 },
+ { "da9055-codec", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
+static const struct of_device_id da9055_of_match[] = {
+ { .compatible = "dlg,da9055-codec", },
+ { }
+};
+
/* I2C codec control layer */
static struct i2c_driver da9055_i2c_driver = {
.driver = {
- .name = "da9055",
+ .name = "da9055-codec",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(da9055_of_match),
},
.probe = da9055_i2c_probe,
.remove = da9055_remove,
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 51f9b3d16b41..149b57f6334b 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1769,16 +1769,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
switch (level) {
case SND_SOC_BIAS_ON:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regcache_sync(max98090->regmap);
-
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to sync cache: %d\n", ret);
- return ret;
- }
- }
-
if (max98090->jack_state == M98090_JACK_STATE_HEADSET) {
/*
* Set to normal bias level.
@@ -1792,6 +1782,16 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = regcache_sync(max98090->regmap);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to sync cache: %d\n", ret);
+ return ret;
+ }
+ }
+ break;
+
case SND_SOC_BIAS_OFF:
/* Set internal pull-up to lowest power mode */
snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
index 73f9c3630e2c..e427544183d7 100644
--- a/sound/soc/codecs/pcm1681.c
+++ b/sound/soc/codecs/pcm1681.c
@@ -172,16 +172,21 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
int val = 0, ret;
- int pcm_format = params_format(params);
priv->rate = params_rate(params);
switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_RIGHT_J:
- if (pcm_format == SNDRV_PCM_FORMAT_S24_LE)
- val = 0x00;
- else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
- val = 0x03;
+ switch (params_width(params)) {
+ case 24:
+ val = 0;
+ break;
+ case 16:
+ val = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
break;
case SND_SOC_DAIFMT_I2S:
val = 0x04;
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c
index 7146653a8e16..3a80ba4452df 100644
--- a/sound/soc/codecs/pcm1792a.c
+++ b/sound/soc/codecs/pcm1792a.c
@@ -107,24 +107,35 @@ static int pcm1792a_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
int val = 0, ret;
- int pcm_format = params_format(params);
priv->rate = params_rate(params);
switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_RIGHT_J:
- if (pcm_format == SNDRV_PCM_FORMAT_S24_LE ||
- pcm_format == SNDRV_PCM_FORMAT_S32_LE)
- val = 0x02;
- else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
- val = 0x00;
+ switch (params_width(params)) {
+ case 24:
+ case 32:
+ val = 2;
+ break;
+ case 16:
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
break;
case SND_SOC_DAIFMT_I2S:
- if (pcm_format == SNDRV_PCM_FORMAT_S24_LE ||
- pcm_format == SNDRV_PCM_FORMAT_S32_LE)
- val = 0x05;
- else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
- val = 0x04;
+ switch (params_width(params)) {
+ case 24:
+ case 32:
+ val = 5;
+ break;
+ case 16:
+ val = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
break;
default:
dev_err(codec->dev, "Invalid DAI format\n");
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
new file mode 100644
index 000000000000..3a0bbb6ab242
--- /dev/null
+++ b/sound/soc/codecs/pcm512x.c
@@ -0,0 +1,707 @@
+/*
+ * Driver for the PCM512x CODECs
+ *
+ * Author: Mark Brown <broonie@linaro.org>
+ * Copyright 2014 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "pcm512x.h"
+
+#define PCM512x_NUM_SUPPLIES 3
+static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
+ "AVDD",
+ "DVDD",
+ "CPVDD",
+};
+
+struct pcm512x_priv {
+ struct regmap *regmap;
+ struct clk *sclk;
+ struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
+ struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
+};
+
+/*
+ * We can't use the same notifier block for more than one supply and
+ * there's no way I can see to get from a callback to the caller
+ * except container_of().
+ */
+#define PCM512x_REGULATOR_EVENT(n) \
+static int pcm512x_regulator_event_##n(struct notifier_block *nb, \
+ unsigned long event, void *data) \
+{ \
+ struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \
+ supply_nb[n]); \
+ if (event & REGULATOR_EVENT_DISABLE) { \
+ regcache_mark_dirty(pcm512x->regmap); \
+ regcache_cache_only(pcm512x->regmap, true); \
+ } \
+ return 0; \
+}
+
+PCM512x_REGULATOR_EVENT(0)
+PCM512x_REGULATOR_EVENT(1)
+PCM512x_REGULATOR_EVENT(2)
+
+static const struct reg_default pcm512x_reg_defaults[] = {
+ { PCM512x_RESET, 0x00 },
+ { PCM512x_POWER, 0x00 },
+ { PCM512x_MUTE, 0x00 },
+ { PCM512x_DSP, 0x00 },
+ { PCM512x_PLL_REF, 0x00 },
+ { PCM512x_DAC_ROUTING, 0x11 },
+ { PCM512x_DSP_PROGRAM, 0x01 },
+ { PCM512x_CLKDET, 0x00 },
+ { PCM512x_AUTO_MUTE, 0x00 },
+ { PCM512x_ERROR_DETECT, 0x00 },
+ { PCM512x_DIGITAL_VOLUME_1, 0x00 },
+ { PCM512x_DIGITAL_VOLUME_2, 0x30 },
+ { PCM512x_DIGITAL_VOLUME_3, 0x30 },
+ { PCM512x_DIGITAL_MUTE_1, 0x22 },
+ { PCM512x_DIGITAL_MUTE_2, 0x00 },
+ { PCM512x_DIGITAL_MUTE_3, 0x07 },
+ { PCM512x_OUTPUT_AMPLITUDE, 0x00 },
+ { PCM512x_ANALOG_GAIN_CTRL, 0x00 },
+ { PCM512x_UNDERVOLTAGE_PROT, 0x00 },
+ { PCM512x_ANALOG_MUTE_CTRL, 0x00 },
+ { PCM512x_ANALOG_GAIN_BOOST, 0x00 },
+ { PCM512x_VCOM_CTRL_1, 0x00 },
+ { PCM512x_VCOM_CTRL_2, 0x01 },
+};
+
+static bool pcm512x_readable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case PCM512x_RESET:
+ case PCM512x_POWER:
+ case PCM512x_MUTE:
+ case PCM512x_PLL_EN:
+ case PCM512x_SPI_MISO_FUNCTION:
+ case PCM512x_DSP:
+ case PCM512x_GPIO_EN:
+ case PCM512x_BCLK_LRCLK_CFG:
+ case PCM512x_DSP_GPIO_INPUT:
+ case PCM512x_MASTER_MODE:
+ case PCM512x_PLL_REF:
+ case PCM512x_PLL_COEFF_0:
+ case PCM512x_PLL_COEFF_1:
+ case PCM512x_PLL_COEFF_2:
+ case PCM512x_PLL_COEFF_3:
+ case PCM512x_PLL_COEFF_4:
+ case PCM512x_DSP_CLKDIV:
+ case PCM512x_DAC_CLKDIV:
+ case PCM512x_NCP_CLKDIV:
+ case PCM512x_OSR_CLKDIV:
+ case PCM512x_MASTER_CLKDIV_1:
+ case PCM512x_MASTER_CLKDIV_2:
+ case PCM512x_FS_SPEED_MODE:
+ case PCM512x_IDAC_1:
+ case PCM512x_IDAC_2:
+ case PCM512x_ERROR_DETECT:
+ case PCM512x_I2S_1:
+ case PCM512x_I2S_2:
+ case PCM512x_DAC_ROUTING:
+ case PCM512x_DSP_PROGRAM:
+ case PCM512x_CLKDET:
+ case PCM512x_AUTO_MUTE:
+ case PCM512x_DIGITAL_VOLUME_1:
+ case PCM512x_DIGITAL_VOLUME_2:
+ case PCM512x_DIGITAL_VOLUME_3:
+ case PCM512x_DIGITAL_MUTE_1:
+ case PCM512x_DIGITAL_MUTE_2:
+ case PCM512x_DIGITAL_MUTE_3:
+ case PCM512x_GPIO_OUTPUT_1:
+ case PCM512x_GPIO_OUTPUT_2:
+ case PCM512x_GPIO_OUTPUT_3:
+ case PCM512x_GPIO_OUTPUT_4:
+ case PCM512x_GPIO_OUTPUT_5:
+ case PCM512x_GPIO_OUTPUT_6:
+ case PCM512x_GPIO_CONTROL_1:
+ case PCM512x_GPIO_CONTROL_2:
+ case PCM512x_OVERFLOW:
+ case PCM512x_RATE_DET_1:
+ case PCM512x_RATE_DET_2:
+ case PCM512x_RATE_DET_3:
+ case PCM512x_RATE_DET_4:
+ case PCM512x_ANALOG_MUTE_DET:
+ case PCM512x_GPIN:
+ case PCM512x_DIGITAL_MUTE_DET:
+ case PCM512x_OUTPUT_AMPLITUDE:
+ case PCM512x_ANALOG_GAIN_CTRL:
+ case PCM512x_UNDERVOLTAGE_PROT:
+ case PCM512x_ANALOG_MUTE_CTRL:
+ case PCM512x_ANALOG_GAIN_BOOST:
+ case PCM512x_VCOM_CTRL_1:
+ case PCM512x_VCOM_CTRL_2:
+ case PCM512x_CRAM_CTRL:
+ return true;
+ default:
+ /* There are 256 raw register addresses */
+ return reg < 0xff;
+ }
+}
+
+static bool pcm512x_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case PCM512x_PLL_EN:
+ case PCM512x_OVERFLOW:
+ case PCM512x_RATE_DET_1:
+ case PCM512x_RATE_DET_2:
+ case PCM512x_RATE_DET_3:
+ case PCM512x_RATE_DET_4:
+ case PCM512x_ANALOG_MUTE_DET:
+ case PCM512x_GPIN:
+ case PCM512x_DIGITAL_MUTE_DET:
+ case PCM512x_CRAM_CTRL:
+ return true;
+ default:
+ /* There are 256 raw register addresses */
+ return reg < 0xff;
+ }
+}
+
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
+static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
+
+static const char * const pcm512x_dsp_program_texts[] = {
+ "FIR interpolation with de-emphasis",
+ "Low latency IIR with de-emphasis",
+ "Fixed process flow",
+ "High attenuation with de-emphasis",
+ "Ringing-less low latency FIR",
+};
+
+static const unsigned int pcm512x_dsp_program_values[] = {
+ 1,
+ 2,
+ 3,
+ 5,
+ 7,
+};
+
+static const SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program,
+ PCM512x_DSP_PROGRAM, 0, 0x1f,
+ pcm512x_dsp_program_texts,
+ pcm512x_dsp_program_values);
+
+static const char * const pcm512x_clk_missing_text[] = {
+ "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s"
+};
+
+static const struct soc_enum pcm512x_clk_missing =
+ SOC_ENUM_SINGLE(PCM512x_CLKDET, 0, 8, pcm512x_clk_missing_text);
+
+static const char * const pcm512x_autom_text[] = {
+ "21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s"
+};
+
+static const struct soc_enum pcm512x_autom_l =
+ SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8,
+ pcm512x_autom_text);
+
+static const struct soc_enum pcm512x_autom_r =
+ SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8,
+ pcm512x_autom_text);
+
+static const char * const pcm512x_ramp_rate_text[] = {
+ "1 sample/update", "2 samples/update", "4 samples/update",
+ "Immediate"
+};
+
+static const struct soc_enum pcm512x_vndf =
+ SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4,
+ pcm512x_ramp_rate_text);
+
+static const struct soc_enum pcm512x_vnuf =
+ SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4,
+ pcm512x_ramp_rate_text);
+
+static const struct soc_enum pcm512x_vedf =
+ SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4,
+ pcm512x_ramp_rate_text);
+
+static const char * const pcm512x_ramp_step_text[] = {
+ "4dB/step", "2dB/step", "1dB/step", "0.5dB/step"
+};
+
+static const struct soc_enum pcm512x_vnds =
+ SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4,
+ pcm512x_ramp_step_text);
+
+static const struct soc_enum pcm512x_vnus =
+ SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4,
+ pcm512x_ramp_step_text);
+
+static const struct soc_enum pcm512x_veds =
+ SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
+ pcm512x_ramp_step_text);
+
+static const struct snd_kcontrol_new pcm512x_controls[] = {
+SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2,
+ PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
+SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
+ PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
+SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
+ PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
+SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
+ PCM512x_RQMR_SHIFT, 1, 1),
+
+SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
+SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program),
+
+SOC_ENUM("Clock Missing Period", pcm512x_clk_missing),
+SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l),
+SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r),
+SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3,
+ PCM512x_ACTL_SHIFT, 1, 0),
+SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT,
+ PCM512x_AMLR_SHIFT, 1, 0),
+
+SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf),
+SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds),
+SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
+SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
+SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
+SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
+};
+
+static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
+SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
+
+SND_SOC_DAPM_OUTPUT("OUTL"),
+SND_SOC_DAPM_OUTPUT("OUTR"),
+};
+
+static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
+ { "DACL", NULL, "Playback" },
+ { "DACR", NULL, "Playback" },
+
+ { "OUTL", NULL, "DACL" },
+ { "OUTR", NULL, "DACR" },
+};
+
+static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
+ int ret;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
+ PCM512x_RQST, 0);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to remove standby: %d\n",
+ ret);
+ return ret;
+ }
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
+ PCM512x_RQST, PCM512x_RQST);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request standby: %d\n",
+ ret);
+ return ret;
+ }
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver pcm512x_dai = {
+ .name = "pcm512x-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE
+ },
+};
+
+static struct snd_soc_codec_driver pcm512x_codec_driver = {
+ .set_bias_level = pcm512x_set_bias_level,
+ .idle_bias_off = true,
+
+ .controls = pcm512x_controls,
+ .num_controls = ARRAY_SIZE(pcm512x_controls),
+ .dapm_widgets = pcm512x_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
+ .dapm_routes = pcm512x_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
+};
+
+static const struct regmap_range_cfg pcm512x_range = {
+ .name = "Pages", .range_min = PCM512x_VIRT_BASE,
+ .range_max = PCM512x_MAX_REGISTER,
+ .selector_reg = PCM512x_PAGE,
+ .selector_mask = 0xff,
+ .window_start = 0, .window_len = 0x100,
+};
+
+static const struct regmap_config pcm512x_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .readable_reg = pcm512x_readable,
+ .volatile_reg = pcm512x_volatile,
+
+ .ranges = &pcm512x_range,
+ .num_ranges = 1,
+
+ .max_register = PCM512x_MAX_REGISTER,
+ .reg_defaults = pcm512x_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static const struct of_device_id pcm512x_of_match[] = {
+ { .compatible = "ti,pcm5121", },
+ { .compatible = "ti,pcm5122", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pcm512x_of_match);
+
+static int pcm512x_probe(struct device *dev, struct regmap *regmap)
+{
+ struct pcm512x_priv *pcm512x;
+ int i, ret;
+
+ pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL);
+ if (!pcm512x)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, pcm512x);
+ pcm512x->regmap = regmap;
+
+ for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++)
+ pcm512x->supplies[i].supply = pcm512x_supply_names[i];
+
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies),
+ pcm512x->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to get supplies: %d\n", ret);
+ return ret;
+ }
+
+ pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0;
+ pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1;
+ pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
+
+ for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
+ ret = regulator_register_notifier(pcm512x->supplies[i].consumer,
+ &pcm512x->supply_nb[i]);
+ if (ret != 0) {
+ dev_err(dev,
+ "Failed to register regulator notifier: %d\n",
+ ret);
+ }
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
+ pcm512x->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ /* Reset the device, verifying I/O in the process for I2C */
+ ret = regmap_write(regmap, PCM512x_RESET,
+ PCM512x_RSTM | PCM512x_RSTR);
+ if (ret != 0) {
+ dev_err(dev, "Failed to reset device: %d\n", ret);
+ goto err;
+ }
+
+ ret = regmap_write(regmap, PCM512x_RESET, 0);
+ if (ret != 0) {
+ dev_err(dev, "Failed to reset device: %d\n", ret);
+ goto err;
+ }
+
+ pcm512x->sclk = devm_clk_get(dev, NULL);
+ if (IS_ERR(pcm512x->sclk)) {
+ if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ dev_info(dev, "No SCLK, using BCLK: %ld\n",
+ PTR_ERR(pcm512x->sclk));
+
+ /* Disable reporting of missing SCLK as an error */
+ regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
+ PCM512x_IDCH, PCM512x_IDCH);
+
+ /* Switch PLL input to BCLK */
+ regmap_update_bits(regmap, PCM512x_PLL_REF,
+ PCM512x_SREF, PCM512x_SREF);
+ } else {
+ ret = clk_prepare_enable(pcm512x->sclk);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable SCLK: %d\n", ret);
+ return ret;
+ }
+ }
+
+ /* Default to standby mode */
+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
+ PCM512x_RQST, PCM512x_RQST);
+ if (ret != 0) {
+ dev_err(dev, "Failed to request standby: %d\n",
+ ret);
+ goto err_clk;
+ }
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
+
+ ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
+ &pcm512x_dai, 1);
+ if (ret != 0) {
+ dev_err(dev, "Failed to register CODEC: %d\n", ret);
+ goto err_pm;
+ }
+
+ return 0;
+
+err_pm:
+ pm_runtime_disable(dev);
+err_clk:
+ if (!IS_ERR(pcm512x->sclk))
+ clk_disable_unprepare(pcm512x->sclk);
+err:
+ regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
+ pcm512x->supplies);
+ return ret;
+}
+
+static void pcm512x_remove(struct device *dev)
+{
+ struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
+
+ snd_soc_unregister_codec(dev);
+ pm_runtime_disable(dev);
+ if (!IS_ERR(pcm512x->sclk))
+ clk_disable_unprepare(pcm512x->sclk);
+ regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
+ pcm512x->supplies);
+}
+
+static int pcm512x_suspend(struct device *dev)
+{
+ struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
+ PCM512x_RQPD, PCM512x_RQPD);
+ if (ret != 0) {
+ dev_err(dev, "Failed to request power down: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
+ pcm512x->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to disable supplies: %d\n", ret);
+ return ret;
+ }
+
+ if (!IS_ERR(pcm512x->sclk))
+ clk_disable_unprepare(pcm512x->sclk);
+
+ return 0;
+}
+
+static int pcm512x_resume(struct device *dev)
+{
+ struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
+ int ret;
+
+ if (!IS_ERR(pcm512x->sclk)) {
+ ret = clk_prepare_enable(pcm512x->sclk);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable SCLK: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
+ pcm512x->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(pcm512x->regmap, false);
+ ret = regcache_sync(pcm512x->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to sync cache: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
+ PCM512x_RQPD, 0);
+ if (ret != 0) {
+ dev_err(dev, "Failed to remove power down: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops pcm512x_pm_ops = {
+ SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL)
+};
+
+#if IS_ENABLED(CONFIG_I2C)
+static int pcm512x_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_i2c(i2c, &pcm512x_regmap);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return pcm512x_probe(&i2c->dev, regmap);
+}
+
+static int pcm512x_i2c_remove(struct i2c_client *i2c)
+{
+ pcm512x_remove(&i2c->dev);
+ return 0;
+}
+
+static const struct i2c_device_id pcm512x_i2c_id[] = {
+ { "pcm5121", },
+ { "pcm5122", },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
+
+static struct i2c_driver pcm512x_i2c_driver = {
+ .probe = pcm512x_i2c_probe,
+ .remove = pcm512x_i2c_remove,
+ .id_table = pcm512x_i2c_id,
+ .driver = {
+ .name = "pcm512x",
+ .owner = THIS_MODULE,
+ .of_match_table = pcm512x_of_match,
+ .pm = &pcm512x_pm_ops,
+ },
+};
+#endif
+
+#if defined(CONFIG_SPI_MASTER)
+static int pcm512x_spi_probe(struct spi_device *spi)
+{
+ struct regmap *regmap;
+ int ret;
+
+ regmap = devm_regmap_init_spi(spi, &pcm512x_regmap);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ return ret;
+ }
+
+ return pcm512x_probe(&spi->dev, regmap);
+}
+
+static int pcm512x_spi_remove(struct spi_device *spi)
+{
+ pcm512x_remove(&spi->dev);
+ return 0;
+}
+
+static const struct spi_device_id pcm512x_spi_id[] = {
+ { "pcm5121", },
+ { "pcm5122", },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, pcm512x_spi_id);
+
+static struct spi_driver pcm512x_spi_driver = {
+ .probe = pcm512x_spi_probe,
+ .remove = pcm512x_spi_remove,
+ .id_table = pcm512x_spi_id,
+ .driver = {
+ .name = "pcm512x",
+ .owner = THIS_MODULE,
+ .of_match_table = pcm512x_of_match,
+ .pm = &pcm512x_pm_ops,
+ },
+};
+#endif
+
+static int __init pcm512x_modinit(void)
+{
+ int ret = 0;
+
+#if IS_ENABLED(CONFIG_I2C)
+ ret = i2c_add_driver(&pcm512x_i2c_driver);
+ if (ret) {
+ printk(KERN_ERR "Failed to register pcm512x I2C driver: %d\n",
+ ret);
+ }
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&pcm512x_spi_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register pcm512x SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
+}
+module_init(pcm512x_modinit);
+
+static void __exit pcm512x_exit(void)
+{
+#if IS_ENABLED(CONFIG_I2C)
+ i2c_del_driver(&pcm512x_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&pcm512x_spi_driver);
+#endif
+}
+module_exit(pcm512x_exit);
+
+MODULE_DESCRIPTION("ASoC PCM512x codec driver");
+MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h
new file mode 100644
index 000000000000..ac4a52c9ccf4
--- /dev/null
+++ b/sound/soc/codecs/pcm512x.h
@@ -0,0 +1,162 @@
+/*
+ * Driver for the PCM512x CODECs
+ *
+ * Author: Mark Brown <broonie@linaro.org>
+ * Copyright 2014 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _SND_SOC_PCM512X
+#define _SND_SOC_PCM512X
+
+#define PCM512x_VIRT_BASE 0x100
+#define PCM512x_PAGE_LEN 0x100
+#define PCM512x_PAGE_BASE(n) (PCM512x_VIRT_BASE + (PCM512x_PAGE_LEN * n))
+
+#define PCM512x_PAGE 0
+
+#define PCM512x_RESET (PCM512x_PAGE_BASE(0) + 1)
+#define PCM512x_POWER (PCM512x_PAGE_BASE(0) + 2)
+#define PCM512x_MUTE (PCM512x_PAGE_BASE(0) + 3)
+#define PCM512x_PLL_EN (PCM512x_PAGE_BASE(0) + 4)
+#define PCM512x_SPI_MISO_FUNCTION (PCM512x_PAGE_BASE(0) + 6)
+#define PCM512x_DSP (PCM512x_PAGE_BASE(0) + 7)
+#define PCM512x_GPIO_EN (PCM512x_PAGE_BASE(0) + 8)
+#define PCM512x_BCLK_LRCLK_CFG (PCM512x_PAGE_BASE(0) + 9)
+#define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10)
+#define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12)
+#define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13)
+#define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20)
+#define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21)
+#define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22)
+#define PCM512x_PLL_COEFF_3 (PCM512x_PAGE_BASE(0) + 23)
+#define PCM512x_PLL_COEFF_4 (PCM512x_PAGE_BASE(0) + 24)
+#define PCM512x_DSP_CLKDIV (PCM512x_PAGE_BASE(0) + 27)
+#define PCM512x_DAC_CLKDIV (PCM512x_PAGE_BASE(0) + 28)
+#define PCM512x_NCP_CLKDIV (PCM512x_PAGE_BASE(0) + 29)
+#define PCM512x_OSR_CLKDIV (PCM512x_PAGE_BASE(0) + 30)
+#define PCM512x_MASTER_CLKDIV_1 (PCM512x_PAGE_BASE(0) + 32)
+#define PCM512x_MASTER_CLKDIV_2 (PCM512x_PAGE_BASE(0) + 33)
+#define PCM512x_FS_SPEED_MODE (PCM512x_PAGE_BASE(0) + 34)
+#define PCM512x_IDAC_1 (PCM512x_PAGE_BASE(0) + 35)
+#define PCM512x_IDAC_2 (PCM512x_PAGE_BASE(0) + 36)
+#define PCM512x_ERROR_DETECT (PCM512x_PAGE_BASE(0) + 37)
+#define PCM512x_I2S_1 (PCM512x_PAGE_BASE(0) + 40)
+#define PCM512x_I2S_2 (PCM512x_PAGE_BASE(0) + 41)
+#define PCM512x_DAC_ROUTING (PCM512x_PAGE_BASE(0) + 42)
+#define PCM512x_DSP_PROGRAM (PCM512x_PAGE_BASE(0) + 43)
+#define PCM512x_CLKDET (PCM512x_PAGE_BASE(0) + 44)
+#define PCM512x_AUTO_MUTE (PCM512x_PAGE_BASE(0) + 59)
+#define PCM512x_DIGITAL_VOLUME_1 (PCM512x_PAGE_BASE(0) + 60)
+#define PCM512x_DIGITAL_VOLUME_2 (PCM512x_PAGE_BASE(0) + 61)
+#define PCM512x_DIGITAL_VOLUME_3 (PCM512x_PAGE_BASE(0) + 62)
+#define PCM512x_DIGITAL_MUTE_1 (PCM512x_PAGE_BASE(0) + 63)
+#define PCM512x_DIGITAL_MUTE_2 (PCM512x_PAGE_BASE(0) + 64)
+#define PCM512x_DIGITAL_MUTE_3 (PCM512x_PAGE_BASE(0) + 65)
+#define PCM512x_GPIO_OUTPUT_1 (PCM512x_PAGE_BASE(0) + 80)
+#define PCM512x_GPIO_OUTPUT_2 (PCM512x_PAGE_BASE(0) + 81)
+#define PCM512x_GPIO_OUTPUT_3 (PCM512x_PAGE_BASE(0) + 82)
+#define PCM512x_GPIO_OUTPUT_4 (PCM512x_PAGE_BASE(0) + 83)
+#define PCM512x_GPIO_OUTPUT_5 (PCM512x_PAGE_BASE(0) + 84)
+#define PCM512x_GPIO_OUTPUT_6 (PCM512x_PAGE_BASE(0) + 85)
+#define PCM512x_GPIO_CONTROL_1 (PCM512x_PAGE_BASE(0) + 86)
+#define PCM512x_GPIO_CONTROL_2 (PCM512x_PAGE_BASE(0) + 87)
+#define PCM512x_OVERFLOW (PCM512x_PAGE_BASE(0) + 90)
+#define PCM512x_RATE_DET_1 (PCM512x_PAGE_BASE(0) + 91)
+#define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92)
+#define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93)
+#define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94)
+#define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108)
+#define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119)
+#define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120)
+
+#define PCM512x_OUTPUT_AMPLITUDE (PCM512x_PAGE_BASE(1) + 1)
+#define PCM512x_ANALOG_GAIN_CTRL (PCM512x_PAGE_BASE(1) + 2)
+#define PCM512x_UNDERVOLTAGE_PROT (PCM512x_PAGE_BASE(1) + 5)
+#define PCM512x_ANALOG_MUTE_CTRL (PCM512x_PAGE_BASE(1) + 6)
+#define PCM512x_ANALOG_GAIN_BOOST (PCM512x_PAGE_BASE(1) + 7)
+#define PCM512x_VCOM_CTRL_1 (PCM512x_PAGE_BASE(1) + 8)
+#define PCM512x_VCOM_CTRL_2 (PCM512x_PAGE_BASE(1) + 9)
+
+#define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1)
+
+#define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1)
+
+/* Page 0, Register 1 - reset */
+#define PCM512x_RSTR (1 << 0)
+#define PCM512x_RSTM (1 << 4)
+
+/* Page 0, Register 2 - power */
+#define PCM512x_RQPD (1 << 0)
+#define PCM512x_RQPD_SHIFT 0
+#define PCM512x_RQST (1 << 4)
+#define PCM512x_RQST_SHIFT 4
+
+/* Page 0, Register 3 - mute */
+#define PCM512x_RQMR_SHIFT 0
+#define PCM512x_RQML_SHIFT 4
+
+/* Page 0, Register 4 - PLL */
+#define PCM512x_PLCE (1 << 0)
+#define PCM512x_RLCE_SHIFT 0
+#define PCM512x_PLCK (1 << 4)
+#define PCM512x_PLCK_SHIFT 4
+
+/* Page 0, Register 7 - DSP */
+#define PCM512x_SDSL (1 << 0)
+#define PCM512x_SDSL_SHIFT 0
+#define PCM512x_DEMP (1 << 4)
+#define PCM512x_DEMP_SHIFT 4
+
+/* Page 0, Register 13 - PLL reference */
+#define PCM512x_SREF (1 << 4)
+
+/* Page 0, Register 37 - Error detection */
+#define PCM512x_IPLK (1 << 0)
+#define PCM512x_DCAS (1 << 1)
+#define PCM512x_IDCM (1 << 2)
+#define PCM512x_IDCH (1 << 3)
+#define PCM512x_IDSK (1 << 4)
+#define PCM512x_IDBK (1 << 5)
+#define PCM512x_IDFS (1 << 6)
+
+/* Page 0, Register 42 - DAC routing */
+#define PCM512x_AUPR_SHIFT 0
+#define PCM512x_AUPL_SHIFT 4
+
+/* Page 0, Register 59 - auto mute */
+#define PCM512x_ATMR_SHIFT 0
+#define PCM512x_ATML_SHIFT 4
+
+/* Page 0, Register 63 - ramp rates */
+#define PCM512x_VNDF_SHIFT 6
+#define PCM512x_VNDS_SHIFT 4
+#define PCM512x_VNUF_SHIFT 2
+#define PCM512x_VNUS_SHIFT 0
+
+/* Page 0, Register 64 - emergency ramp rates */
+#define PCM512x_VEDF_SHIFT 6
+#define PCM512x_VEDS_SHIFT 4
+
+/* Page 0, Register 65 - Digital mute enables */
+#define PCM512x_ACTL_SHIFT 2
+#define PCM512x_AMLE_SHIFT 1
+#define PCM512x_AMLR_SHIFT 0
+
+/* Page 1, Register 2 - analog volume control */
+#define PCM512x_RAGN_SHIFT 0
+#define PCM512x_LAGN_SHIFT 4
+
+/* Page 1, Register 7 - analog boost control */
+#define PCM512x_AGBR_SHIFT 0
+#define PCM512x_AGBL_SHIFT 4
+
+#endif
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index a3fb41179636..886924934aa5 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2093,6 +2093,7 @@ MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
#ifdef CONFIG_ACPI
static struct acpi_device_id rt5640_acpi_match[] = {
{ "INT33CA", 0 },
+ { "10EC5640", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 70ff3772079f..5e3bc3c6801a 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -399,6 +399,7 @@ static struct platform_driver davinci_evm_driver = {
.driver = {
.name = "davinci_evm",
.owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
.of_match_table = of_match_ptr(davinci_evm_dt_ids),
},
};
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index b7858bfa0295..670afa29e30d 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -263,7 +263,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
+ int ret = 0;
+ pm_runtime_get_sync(mcasp->dev);
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_B:
case SND_SOC_DAIFMT_AC97:
@@ -317,7 +319,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -354,10 +357,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
}
-
- return 0;
+out:
+ pm_runtime_put_sync(mcasp->dev);
+ return ret;
}
static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
@@ -448,7 +453,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
return 0;
}
-static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream,
+static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
int channels)
{
int i;
@@ -524,12 +529,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream,
return 0;
}
-static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream)
+static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
{
int i, active_slots;
u32 mask = 0;
u32 busel = 0;
+ if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) {
+ dev_err(mcasp->dev, "tdm slot %d not supported\n",
+ mcasp->tdm_slots);
+ return -EINVAL;
+ }
+
active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots;
for (i = 0; i < active_slots; i++)
mask |= (1 << i);
@@ -539,35 +550,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream)
if (!mcasp->dat_port)
busel = TXSEL;
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* bit stream is MSB first with no delay */
- /* DSP_B mode */
- mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
- mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
-
- if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32))
- mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
- FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF));
- else
- printk(KERN_ERR "playback tdm slot %d not supported\n",
- mcasp->tdm_slots);
- } else {
- /* bit stream is MSB first with no delay */
- /* DSP_B mode */
- mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
- mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
-
- if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32))
- mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
- FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF));
- else
- printk(KERN_ERR "capture tdm slot %d not supported\n",
- mcasp->tdm_slots);
- }
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
+ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
+ FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF));
+
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
+ mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
+ FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF));
+
+ return 0;
}
/* S/PDIF */
-static void davinci_hw_dit_param(struct davinci_mcasp *mcasp)
+static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
{
/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
and LSB first */
@@ -589,6 +586,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp)
/* Enable the DIT */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
+
+ return 0;
}
static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
@@ -605,13 +604,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
u8 slots = mcasp->tdm_slots;
u8 active_serializers;
int channels;
+ int ret;
struct snd_interval *pcm_channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
channels = pcm_channels->min;
active_serializers = (channels + slots - 1) / slots;
- if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL)
+ if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL)
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
fifo_level = mcasp->txnumevt * active_serializers;
@@ -619,9 +619,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
fifo_level = mcasp->rxnumevt * active_serializers;
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
- davinci_hw_dit_param(mcasp);
+ ret = mcasp_dit_hw_param(mcasp);
else
- davinci_hw_param(mcasp, substream->stream);
+ ret = mcasp_i2s_hw_param(mcasp, substream->stream);
+
+ if (ret)
+ return ret;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_U8:
@@ -678,19 +681,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ret = pm_runtime_get_sync(mcasp->dev);
- if (IS_ERR_VALUE(ret))
- dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n");
davinci_mcasp_start(mcasp, substream->stream);
break;
-
case SNDRV_PCM_TRIGGER_SUSPEND:
- davinci_mcasp_stop(mcasp, substream->stream);
- ret = pm_runtime_put_sync(mcasp->dev);
- if (IS_ERR_VALUE(ret))
- dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n");
- break;
-
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
davinci_mcasp_stop(mcasp, substream->stream);
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index d0c72ed261e7..c84026c99134 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -326,7 +326,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA,
ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask));
regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB,
- ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask));
+ ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask));
regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
@@ -334,7 +334,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA,
ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask));
regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB,
- ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask));
+ ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask));
esai_priv->slot_width = slot_width;
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h
index 9c9f957fcae1..75e14033e8d8 100644
--- a/sound/soc/fsl/fsl_esai.h
+++ b/sound/soc/fsl/fsl_esai.h
@@ -322,7 +322,7 @@
#define ESAI_xSMB_xS_SHIFT 0
#define ESAI_xSMB_xS_WIDTH 16
#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT)
-#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK)
+#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMB_xS_MASK)
/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */
#define ESAI_PRRC_PDC_SHIFT 0
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index 79cee782dbbf..a2fd7321b5a9 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = {
.driver = {
.name = "imx_mc13783",
.owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
},
.probe = imx_mc13783_probe,
.remove = imx_mc13783_remove
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index f2beae78969f..1cb22dd034eb 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -33,8 +33,7 @@ struct imx_sgtl5000_data {
static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd)
{
- struct imx_sgtl5000_data *data = container_of(rtd->card,
- struct imx_sgtl5000_data, card);
+ struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card);
struct device *dev = rtd->card->dev;
int ret;
@@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+
ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
goto fail;
}
- platform_set_drvdata(pdev, data);
of_node_put(ssi_np);
of_node_put(codec_np);
@@ -184,7 +185,8 @@ fail:
static int imx_sgtl5000_remove(struct platform_device *pdev)
{
- struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card);
clk_put(data->codec_clk);
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 3fd76bc391de..3a3d17ce6ba4 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
{
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
struct imx_priv *priv = &card_priv;
- struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
struct device *dev = &priv->pdev->dev;
unsigned int pll_out;
int ret;
@@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
{
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
struct imx_priv *priv = &card_priv;
- struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
struct device *dev = &priv->pdev->dev;
int ret;
@@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev)
data->card.late_probe = imx_wm8962_late_probe;
data->card.set_bias_level = imx_wm8962_set_bias_level;
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+
ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
goto clk_fail;
}
- platform_set_drvdata(pdev, data);
of_node_put(ssi_np);
of_node_put(codec_np);
@@ -289,7 +291,8 @@ fail:
static int imx_wm8962_remove(struct platform_device *pdev)
{
- struct imx_wm8962_data *data = platform_get_drvdata(pdev);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
if (!IS_ERR(data->codec_clk))
clk_disable_unprepare(data->codec_clk);
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 454f41cfc828..350757400391 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -59,7 +59,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750
select SND_SOC_WM8750
select SND_S3C2412_SOC_I2S
help
- Sat Y if you want to add support for SoC audio on the Jive.
+ Say Y if you want to add support for SoC audio on the Jive.
config SND_SOC_SAMSUNG_SMDK_WM8580
tristate "SoC I2S Audio support for WM8580 on SMDK"
@@ -145,11 +145,11 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380
config SND_SOC_SAMSUNG_SMDK_WM9713
tristate "SoC AC97 Audio support for SMDK with WM9713"
- depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210)
+ depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
select SND_SOC_WM9713
select SND_SAMSUNG_AC97
help
- Sat Y if you want to add support for SoC audio on the SMDK.
+ Say Y if you want to add support for SoC audio on the SMDK.
config SND_SOC_SMARTQ
tristate "SoC I2S Audio support for SmartQ board"
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index fe1df50805a3..393ff069af69 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3626,7 +3626,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
slots, slot_width);
else
- return -EINVAL;
+ return -ENOTSUPP;
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index dc8ff13187f7..2c2d751c6d54 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -386,7 +386,8 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
return -1;
}
-static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
+static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg,
+ unsigned int val)
{
if (w->codec)
return snd_soc_write(w->codec, reg, val);
@@ -506,7 +507,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl: {
- int val;
+ unsigned int val;
struct soc_mixer_control *mc = (struct soc_mixer_control *)
w->kcontrol_news[i].private_value;
int reg = mc->reg;
@@ -530,7 +531,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_mux: {
struct soc_enum *e = (struct soc_enum *)
w->kcontrol_news[i].private_value;
- int val, item;
+ unsigned int val, item;
soc_widget_read(w, e->reg, &val);
item = (val >> e->shift_l) & e->mask;
@@ -559,7 +560,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_value_mux: {
struct soc_enum *e = (struct soc_enum *)
w->kcontrol_news[i].private_value;
- int val, item;
+ unsigned int val, item;
soc_widget_read(w, e->reg, &val);
val = (val >> e->shift_l) & e->mask;