aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/88pm860x-codec.c6
-rw-r--r--sound/soc/codecs/ac97.c6
-rw-r--r--sound/soc/codecs/adau7002.c6
-rw-r--r--sound/soc/codecs/bt-sco.c6
-rw-r--r--sound/soc/codecs/cq93vc.c6
-rw-r--r--sound/soc/codecs/da7213.c30
-rw-r--r--sound/soc/codecs/da7213.h3
-rw-r--r--sound/soc/codecs/mc13783.c6
-rw-r--r--sound/soc/codecs/rt5640.c4
-rw-r--r--sound/soc/codecs/rt5640.h2
-rw-r--r--sound/soc/codecs/rt711-sdca.c15
-rw-r--r--sound/soc/codecs/rt711-sdca.h8
-rw-r--r--sound/soc/codecs/wl1273.c6
-rw-r--r--sound/soc/codecs/wm8940.c116
-rw-r--r--sound/soc/codecs/wm8940.h3
15 files changed, 156 insertions, 67 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index fc65283031cd..3574c68e0dda 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1386,17 +1386,11 @@ static int pm860x_codec_probe(struct platform_device *pdev)
return ret;
}
-static int pm860x_codec_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver pm860x_codec_driver = {
.driver = {
.name = "88pm860x-codec",
},
.probe = pm860x_codec_probe,
- .remove = pm860x_codec_remove,
};
module_platform_driver(pm860x_codec_driver);
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index cc12052e1920..0e013edfe63d 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -127,18 +127,12 @@ static int ac97_probe(struct platform_device *pdev)
&soc_component_dev_ac97, &ac97_dai, 1);
}
-static int ac97_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver ac97_codec_driver = {
.driver = {
.name = "ac97-codec",
},
.probe = ac97_probe,
- .remove = ac97_remove,
};
module_platform_driver(ac97_codec_driver);
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c
index 401bafabc8eb..c9134e1de0b2 100644
--- a/sound/soc/codecs/adau7002.c
+++ b/sound/soc/codecs/adau7002.c
@@ -100,11 +100,6 @@ static int adau7002_probe(struct platform_device *pdev)
&adau7002_dai, 1);
}
-static int adau7002_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
#ifdef CONFIG_OF
static const struct of_device_id adau7002_dt_ids[] = {
{ .compatible = "adi,adau7002", },
@@ -128,7 +123,6 @@ static struct platform_driver adau7002_driver = {
.acpi_match_table = ACPI_PTR(adau7002_acpi_match),
},
.probe = adau7002_probe,
- .remove = adau7002_remove,
};
module_platform_driver(adau7002_driver);
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index 4086b6a53de8..3afcef2dfa35 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -78,11 +78,6 @@ static int bt_sco_probe(struct platform_device *pdev)
bt_sco_dai, ARRAY_SIZE(bt_sco_dai));
}
-static int bt_sco_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static const struct platform_device_id bt_sco_driver_ids[] = {
{
.name = "dfbmcs320",
@@ -109,7 +104,6 @@ static struct platform_driver bt_sco_driver = {
.of_match_table = of_match_ptr(bt_sco_codec_of_match),
},
.probe = bt_sco_probe,
- .remove = bt_sco_remove,
.id_table = bt_sco_driver_ids,
};
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 14403b76c724..32b6a417d0e8 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -134,18 +134,12 @@ static int cq93vc_platform_probe(struct platform_device *pdev)
&soc_component_dev_cq93vc, &cq93vc_dai, 1);
}
-static int cq93vc_platform_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver cq93vc_codec_driver = {
.driver = {
.name = "cq93vc-codec",
},
.probe = cq93vc_platform_probe,
- .remove = cq93vc_platform_remove,
};
module_platform_driver(cq93vc_codec_driver);
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 544ccbcfc884..0068780fe0a7 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1157,13 +1157,31 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
+ u8 dai_clk_mode = DA7213_DAI_BCLKS_PER_WCLK_64;
u8 dai_ctrl = 0;
u8 fs;
+ /* Set channels */
+ switch (params_channels(params)) {
+ case 1:
+ if (da7213->fmt != DA7213_DAI_FORMAT_DSP) {
+ dev_err(component->dev, "Mono supported only in DSP mode\n");
+ return -EINVAL;
+ }
+ dai_ctrl |= DA7213_DAI_MONO_MODE_EN;
+ break;
+ case 2:
+ dai_ctrl &= ~(DA7213_DAI_MONO_MODE_EN);
+ break;
+ default:
+ return -EINVAL;
+ }
+
/* Set DAI format */
switch (params_width(params)) {
case 16:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
+ dai_clk_mode = DA7213_DAI_BCLKS_PER_WCLK_32; /* 32bit for 1ch and 2ch */
break;
case 20:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
@@ -1224,8 +1242,11 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
- dai_ctrl);
+ snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
+ DA7213_DAI_BCLKS_PER_WCLK_MASK, dai_clk_mode);
+
+ snd_soc_component_update_bits(component, DA7213_DAI_CTRL,
+ DA7213_DAI_WORD_LENGTH_MASK | DA7213_DAI_MONO_MODE_MASK, dai_ctrl);
snd_soc_component_write(component, DA7213_SR, fs);
return 0;
@@ -1300,19 +1321,24 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
dai_ctrl |= DA7213_DAI_FORMAT_I2S_MODE;
+ da7213->fmt = DA7213_DAI_FORMAT_I2S_MODE;
break;
case SND_SOC_DAIFMT_LEFT_J:
dai_ctrl |= DA7213_DAI_FORMAT_LEFT_J;
+ da7213->fmt = DA7213_DAI_FORMAT_LEFT_J;
break;
case SND_SOC_DAIFMT_RIGHT_J:
dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J;
+ da7213->fmt = DA7213_DAI_FORMAT_RIGHT_J;
break;
case SND_SOC_DAI_FORMAT_DSP_A: /* L data MSB after FRM LRC */
dai_ctrl |= DA7213_DAI_FORMAT_DSP;
dai_offset = 1;
+ da7213->fmt = DA7213_DAI_FORMAT_DSP;
break;
case SND_SOC_DAI_FORMAT_DSP_B: /* L data MSB during FRM LRC */
dai_ctrl |= DA7213_DAI_FORMAT_DSP;
+ da7213->fmt = DA7213_DAI_FORMAT_DSP;
break;
default:
return -EINVAL;
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 97ccf0ddd2be..4ca9cfdea06d 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -195,6 +195,8 @@
#define DA7213_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
#define DA7213_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
#define DA7213_DAI_WORD_LENGTH_MASK (0x3 << 2)
+#define DA7213_DAI_MONO_MODE_EN (0x1 << 4)
+#define DA7213_DAI_MONO_MODE_MASK (0x1 << 4)
#define DA7213_DAI_EN_SHIFT 7
/* DA7213_DIG_ROUTING_DAI = 0x21 */
@@ -542,6 +544,7 @@ struct da7213_priv {
bool alc_en;
bool fixed_clk_auto_pll;
struct da7213_platform_data *pdata;
+ int fmt;
};
#endif /* _DA7213_H */
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 71490f11d96a..086ac97e8386 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -776,16 +776,10 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
return ret;
}
-static int mc13783_codec_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver mc13783_codec_driver = {
.driver = {
.name = "mc13783-codec",
},
- .remove = mc13783_codec_remove,
};
module_platform_driver_probe(mc13783_codec_driver, mc13783_codec_probe);
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 708e55b7431a..9e6341a68c6b 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2717,6 +2717,10 @@ static int rt5640_probe(struct snd_soc_component *component)
snd_soc_component_update_bits(component, RT5640_IN1_IN2,
RT5640_IN_DF2, RT5640_IN_DF2);
+ if (device_property_read_bool(component->dev, "realtek,lout-differential"))
+ snd_soc_component_update_bits(component, RT5640_DUMMY1,
+ RT5640_EN_LOUT_DF, RT5640_EN_LOUT_DF);
+
if (device_property_read_u32(component->dev, "realtek,dmic1-data-pin",
&val) == 0 && val) {
dmic1_data_pin = val - 1;
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index f58b88e3325b..9847a1ae01f4 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -1978,6 +1978,8 @@
#define RT5640_ZCD_HP_EN (0x1 << 15)
/* General Control 1 (0xfa) */
+#define RT5640_EN_LOUT_DF (0x1 << 14)
+#define RT5640_EN_LOUT_DF_SFT 14
#define RT5640_M_MONO_ADC_L (0x1 << 13)
#define RT5640_M_MONO_ADC_L_SFT 13
#define RT5640_M_MONO_ADC_R (0x1 << 12)
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
index b78dd5994edb..7cdf184d380b 100644
--- a/sound/soc/codecs/rt711-sdca.c
+++ b/sound/soc/codecs/rt711-sdca.c
@@ -463,6 +463,21 @@ static void rt711_sdca_jack_init(struct rt711_sdca_priv *rt711)
RT711_HP_JD_FINAL_RESULT_CTL_JD12,
RT711_HP_JD_FINAL_RESULT_CTL_JD12);
break;
+ case RT711_JD2_100K:
+ rt711_sdca_index_write(rt711, RT711_VENDOR_REG,
+ RT711_COMBO_JACK_AUTO_CTL3, 0xa47e);
+ rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG,
+ RT711_JD_CTL1, RT711_JD2_DIGITAL_MODE_SEL,
+ RT711_JD2_DIGITAL_MODE_SEL);
+ rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG,
+ RT711_JD_CTL2, RT711_JD2_2PORT_200K_DECODE_HP |
+ RT711_JD2_2PORT_100K_DECODE_MASK | RT711_HP_JD_SEL_JD2,
+ RT711_JD2_2PORT_100K_DECODE_HP | RT711_HP_JD_SEL_JD2);
+ rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG,
+ RT711_CC_DET1,
+ RT711_HP_JD_FINAL_RESULT_CTL_JD12 | RT711_POW_CC1_AGPI,
+ RT711_HP_JD_FINAL_RESULT_CTL_JD12 | RT711_POW_CC1_AGPI_OFF);
+ break;
default:
dev_warn(rt711->component->dev, "Wrong JD source\n");
break;
diff --git a/sound/soc/codecs/rt711-sdca.h b/sound/soc/codecs/rt711-sdca.h
index 498ca687c47b..10e3c801b813 100644
--- a/sound/soc/codecs/rt711-sdca.h
+++ b/sound/soc/codecs/rt711-sdca.h
@@ -127,12 +127,17 @@ struct sdw_stream_data {
/* jack detect control 2 (0x09)(NID:20h) */
#define RT711_JD2_2PORT_200K_DECODE_HP (0x1 << 13)
+#define RT711_JD2_2PORT_100K_DECODE_MASK (0x1 << 12)
+#define RT711_JD2_2PORT_100K_DECODE_HP (0x0 << 12)
#define RT711_HP_JD_SEL_JD1 (0x0 << 1)
#define RT711_HP_JD_SEL_JD2 (0x1 << 1)
/* CC DET1 (0x11)(NID:20h) */
#define RT711_HP_JD_FINAL_RESULT_CTL_JD12 (0x1 << 10)
#define RT711_HP_JD_FINAL_RESULT_CTL_CCDET (0x0 << 10)
+#define RT711_POW_CC1_AGPI (0x1 << 5)
+#define RT711_POW_CC1_AGPI_ON (0x1 << 5)
+#define RT711_POW_CC1_AGPI_OFF (0x0 << 5)
/* Parameter & Verb control (0x1a)(NID:20h) */
#define RT711_HIDDEN_REG_SW_RESET (0x1 << 14)
@@ -226,7 +231,8 @@ enum {
enum rt711_sdca_jd_src {
RT711_JD_NULL,
RT711_JD1,
- RT711_JD2
+ RT711_JD2,
+ RT711_JD2_100K
};
enum rt711_sdca_ver {
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 626278e4c923..737ca82cf976 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -484,11 +484,6 @@ static int wl1273_platform_probe(struct platform_device *pdev)
&wl1273_dai, 1);
}
-static int wl1273_platform_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
MODULE_ALIAS("platform:wl1273-codec");
static struct platform_driver wl1273_platform_driver = {
@@ -496,7 +491,6 @@ static struct platform_driver wl1273_platform_driver = {
.name = "wl1273-codec",
},
.probe = wl1273_platform_probe,
- .remove = wl1273_platform_remove,
};
module_platform_driver(wl1273_platform_driver);
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 8dac9fd88547..8eb4782c9232 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -37,7 +37,9 @@
#include "wm8940.h"
struct wm8940_priv {
- unsigned int sysclk;
+ unsigned int mclk;
+ unsigned int fs;
+
struct regmap *regmap;
};
@@ -387,17 +389,24 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
+static int wm8940_update_clocks(struct snd_soc_dai *dai);
static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
+ struct wm8940_priv *priv = snd_soc_component_get_drvdata(component);
u16 iface = snd_soc_component_read(component, WM8940_IFACE) & 0xFD9F;
u16 addcntrl = snd_soc_component_read(component, WM8940_ADDCNTRL) & 0xFFF1;
u16 companding = snd_soc_component_read(component,
WM8940_COMPANDINGCTL) & 0xFFDF;
int ret;
+ priv->fs = params_rate(params);
+ ret = wm8940_update_clocks(dai);
+ if (ret)
+ return ret;
+
/* LoutR control */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
&& params_channels(params) == 2)
@@ -611,24 +620,6 @@ static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
return 0;
}
-static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8940->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
int div_id, int div)
{
@@ -653,6 +644,78 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
return ret;
}
+static unsigned int wm8940_get_mclkdiv(unsigned int f_in, unsigned int f_out,
+ int *mclkdiv)
+{
+ unsigned int ratio = 2 * f_in / f_out;
+
+ if (ratio <= 2) {
+ *mclkdiv = WM8940_MCLKDIV_1;
+ ratio = 2;
+ } else if (ratio == 3) {
+ *mclkdiv = WM8940_MCLKDIV_1_5;
+ } else if (ratio == 4) {
+ *mclkdiv = WM8940_MCLKDIV_2;
+ } else if (ratio <= 6) {
+ *mclkdiv = WM8940_MCLKDIV_3;
+ ratio = 6;
+ } else if (ratio <= 8) {
+ *mclkdiv = WM8940_MCLKDIV_4;
+ ratio = 8;
+ } else if (ratio <= 12) {
+ *mclkdiv = WM8940_MCLKDIV_6;
+ ratio = 12;
+ } else if (ratio <= 16) {
+ *mclkdiv = WM8940_MCLKDIV_8;
+ ratio = 16;
+ } else {
+ *mclkdiv = WM8940_MCLKDIV_12;
+ ratio = 24;
+ }
+
+ return f_out * ratio / 2;
+}
+
+static int wm8940_update_clocks(struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *codec = dai->component;
+ struct wm8940_priv *priv = snd_soc_component_get_drvdata(codec);
+ unsigned int fs256;
+ unsigned int fpll = 0;
+ unsigned int f;
+ int mclkdiv;
+
+ if (!priv->mclk || !priv->fs)
+ return 0;
+
+ fs256 = 256 * priv->fs;
+
+ f = wm8940_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
+ if (f != priv->mclk) {
+ /* The PLL performs best around 90MHz */
+ fpll = wm8940_get_mclkdiv(22500000, fs256, &mclkdiv);
+ }
+
+ wm8940_set_dai_pll(dai, 0, 0, priv->mclk, fpll);
+ wm8940_set_dai_clkdiv(dai, WM8940_MCLKDIV, mclkdiv);
+
+ return 0;
+}
+
+static int wm8940_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_component *codec = dai->component;
+ struct wm8940_priv *priv = snd_soc_component_get_drvdata(codec);
+
+ if (dir != SND_SOC_CLOCK_IN)
+ return -EINVAL;
+
+ priv->mclk = freq;
+
+ return wm8940_update_clocks(dai);
+}
+
#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
@@ -697,6 +760,17 @@ static int wm8940_probe(struct snd_soc_component *component)
int ret;
u16 reg;
+ /*
+ * Check chip ID for wm8940 - value of 0x00 offset
+ * SOFTWARE_RESET on write
+ * CHIP_ID on read
+ */
+ reg = snd_soc_component_read(component, WM8940_SOFTRESET);
+ if (reg != WM8940_CHIP_ID) {
+ dev_err(component->dev, "Wrong wm8940 chip ID: 0x%x\n", reg);
+ return -ENODEV;
+ }
+
ret = wm8940_reset(component);
if (ret < 0) {
dev_err(component->dev, "Failed to issue reset\n");
@@ -709,9 +783,7 @@ static int wm8940_probe(struct snd_soc_component *component)
if (ret < 0)
return ret;
- if (!pdata)
- dev_warn(component->dev, "No platform data supplied\n");
- else {
+ if (pdata) {
reg = snd_soc_component_read(component, WM8940_OUTPUTCTL);
ret = snd_soc_component_write(component, WM8940_OUTPUTCTL, reg | pdata->vroi);
if (ret < 0)
diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h
index 0d4f53ada2e6..86bbf902ef5a 100644
--- a/sound/soc/codecs/wm8940.h
+++ b/sound/soc/codecs/wm8940.h
@@ -95,5 +95,8 @@ struct wm8940_setup_data {
#define WM8940_OPCLKDIV_3 2
#define WM8940_OPCLKDIV_4 3
+/* Chip ID */
+#define WM8940_CHIP_ID 0x8940
+
#endif /* _WM8940_H */