summaryrefslogtreecommitdiff
path: root/sound/soc/sunxi/sun8i-codec-analog.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-03 11:58:59 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-03 11:58:59 -0700
commit221656e7c4ce342b99c31eca96c1cbb6d1dce45f (patch)
tree1af3655475361f3ec75d8e26bc8d5f4bad8a87b0 /sound/soc/sunxi/sun8i-codec-analog.c
parent2f34c1231bfc9f2550f934acb268ac7315fb3837 (diff)
parenta5c3b32a1146e44f6b38fdfdfffc27842953420c (diff)
Merge tag 'sound-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "It was a relatively calm development cycle, and no scaring changes are seen in both core and driver sides. Here are some highlights: ASoC: - A new API for hooking up jacks more generically and easily - Card longname is set based on DMI for a unique UCM profile - Lots of Intel driver fixes: Atom, Broxton, Skylake and newer chips - New drivers for Cirrus CS35L35, DIO DIO2125, Everest ES7132, HiSilicon hi6210, Maxim MAX98927, MT2701 systems with WM8960, Nuvoton NAU8824, Odroid systems, ST STM32 SAI controllers and x86 systems with DA7213 HD-audio: - Many new quirks to support headset for various devices (mostly ASUS ones) as usual - Support for dual codecs on some Gigabyte mobos and Lenovo laptop - Improvement on PCM position reporting for Skylake and newer FireWire: - New drivers for MOTU and RME Fireface series - Updates for Digidesign Digi00x and TASCAM series - Support for tracepoints Others: - USB-audio: improved support for quirk_alias option - Cleanups, constification allover the places" * tag 'sound-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (299 commits) ASoC: codec: wm8960: Relax bit clock computation when using PLL ASoC: codec: wm9860: avoid maybe-uninitialized warning ASoC: nau8824: leave Class D gain at chip default ASoC: nau8824: rename controls to match DAPM controls ASoC: Intel: Skylake: Return negative error code ASoC: Intel: Skylake: Fix unused variable warning ASoC: Intel: Skylake: fix uninitialized pointer use ASoC: sti: Fix error handling if of_clk_get() fails ASoC: cs4271: configure reset GPIO as output ASoC: dwc: Disallow building designware_pcm as a module ALSA: ali5451: fix spelling mistake in "ali_capture_preapre" ASoC: stm32: add SAI driver ASoC: stm32: add bindings for SAI ASoC: Intel: Skylake: Add loadable module support on KBL platform ASoC: Intel: Skylake: Modify load_lib_ipc arguments for a nowait version ASoC: Intel: Skylake: Register dsp_fw_ops for kabylake ASoC: Intel: Skylake: Modify arguments to reuse module transfer function ASoC: Intel: Skylake: Commonize library load ASoC: Intel: Skylake: Move sst common initialization to a helper function ASoC: nau8824: new driver ...
Diffstat (limited to 'sound/soc/sunxi/sun8i-codec-analog.c')
-rw-r--r--sound/soc/sunxi/sun8i-codec-analog.c168
1 files changed, 141 insertions, 27 deletions
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
index 72331332b72e..6c17c99c2c8d 100644
--- a/sound/soc/sunxi/sun8i-codec-analog.c
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -252,24 +252,15 @@ static const DECLARE_TLV_DB_RANGE(sun8i_codec_mic_gain_scale,
);
static const struct snd_kcontrol_new sun8i_codec_common_controls[] = {
- /* Mixer pre-gains */
- SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
- SUN8I_ADDA_LINEIN_GCTRL_LINEING,
- 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
+ /* Mixer pre-gain */
SOC_SINGLE_TLV("Mic1 Playback Volume", SUN8I_ADDA_MICIN_GCTRL,
SUN8I_ADDA_MICIN_GCTRL_MIC1G,
0x7, 0, sun8i_codec_out_mixer_pregain_scale),
- SOC_SINGLE_TLV("Mic2 Playback Volume",
- SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
- 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
- /* Microphone Amp boost gains */
+ /* Microphone Amp boost gain */
SOC_SINGLE_TLV("Mic1 Boost Volume", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST, 0x7, 0,
sun8i_codec_mic_gain_scale),
- SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
- SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
- sun8i_codec_mic_gain_scale),
/* ADC */
SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN8I_ADDA_ADC_AP_EN,
@@ -295,12 +286,8 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
* stream widgets at the card level.
*/
- /* Line In */
- SND_SOC_DAPM_INPUT("LINEIN"),
-
- /* Microphone inputs */
+ /* Microphone input */
SND_SOC_DAPM_INPUT("MIC1"),
- SND_SOC_DAPM_INPUT("MIC2"),
/* Microphone Bias */
SND_SOC_DAPM_SUPPLY("MBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
@@ -310,8 +297,6 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
/* Mic input path */
SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
- SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
/* Mixers */
SND_SOC_DAPM_MIXER("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
@@ -335,35 +320,26 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
static const struct snd_soc_dapm_route sun8i_codec_common_routes[] = {
/* Microphone Routes */
{ "Mic1 Amplifier", NULL, "MIC1"},
- { "Mic2 Amplifier", NULL, "MIC2"},
/* Left Mixer Routes */
{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
{ "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
- { "Left Mixer", "Line In Playback Switch", "LINEIN" },
{ "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
- { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
/* Right Mixer Routes */
{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
{ "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
- { "Right Mixer", "Line In Playback Switch", "LINEIN" },
{ "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
- { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
/* Left ADC Mixer Routes */
{ "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
{ "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
- { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
{ "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
- { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
/* Right ADC Mixer Routes */
{ "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
{ "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
- { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
{ "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
- { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
/* ADC Routes */
{ "Left ADC", NULL, "Left ADC Mixer" },
@@ -498,6 +474,61 @@ static int sun8i_codec_add_hmic(struct snd_soc_component *cmpnt)
return ret;
}
+/* line in specific controls, widgets and rines */
+static const struct snd_kcontrol_new sun8i_codec_linein_controls[] = {
+ /* Mixer pre-gain */
+ SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
+ SUN8I_ADDA_LINEIN_GCTRL_LINEING,
+ 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_linein_widgets[] = {
+ /* Line input */
+ SND_SOC_DAPM_INPUT("LINEIN"),
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_linein_routes[] = {
+ { "Left Mixer", "Line In Playback Switch", "LINEIN" },
+
+ { "Right Mixer", "Line In Playback Switch", "LINEIN" },
+
+ { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
+
+ { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
+};
+
+static int sun8i_codec_add_linein(struct snd_soc_component *cmpnt)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
+ struct device *dev = cmpnt->dev;
+ int ret;
+
+ ret = snd_soc_add_component_controls(cmpnt,
+ sun8i_codec_linein_controls,
+ ARRAY_SIZE(sun8i_codec_linein_controls));
+ if (ret) {
+ dev_err(dev, "Failed to add Line In controls: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_linein_widgets,
+ ARRAY_SIZE(sun8i_codec_linein_widgets));
+ if (ret) {
+ dev_err(dev, "Failed to add Line In DAPM widgets: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_linein_routes,
+ ARRAY_SIZE(sun8i_codec_linein_routes));
+ if (ret) {
+ dev_err(dev, "Failed to add Line In DAPM routes: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+
/* line out specific controls, widgets and routes */
static const DECLARE_TLV_DB_RANGE(sun8i_codec_lineout_vol_scale,
0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
@@ -578,19 +609,90 @@ static int sun8i_codec_add_lineout(struct snd_soc_component *cmpnt)
return 0;
}
+/* mic2 specific controls, widgets and routes */
+static const struct snd_kcontrol_new sun8i_codec_mic2_controls[] = {
+ /* Mixer pre-gain */
+ SOC_SINGLE_TLV("Mic2 Playback Volume",
+ SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
+ 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
+
+ /* Microphone Amp boost gain */
+ SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
+ SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
+ sun8i_codec_mic_gain_scale),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_mic2_widgets[] = {
+ /* Microphone input */
+ SND_SOC_DAPM_INPUT("MIC2"),
+
+ /* Mic input path */
+ SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
+ SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_mic2_routes[] = {
+ { "Mic2 Amplifier", NULL, "MIC2"},
+
+ { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
+
+ { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
+
+ { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
+
+ { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
+};
+
+static int sun8i_codec_add_mic2(struct snd_soc_component *cmpnt)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
+ struct device *dev = cmpnt->dev;
+ int ret;
+
+ ret = snd_soc_add_component_controls(cmpnt,
+ sun8i_codec_mic2_controls,
+ ARRAY_SIZE(sun8i_codec_mic2_controls));
+ if (ret) {
+ dev_err(dev, "Failed to add MIC2 controls: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_mic2_widgets,
+ ARRAY_SIZE(sun8i_codec_mic2_widgets));
+ if (ret) {
+ dev_err(dev, "Failed to add MIC2 DAPM widgets: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_mic2_routes,
+ ARRAY_SIZE(sun8i_codec_mic2_routes));
+ if (ret) {
+ dev_err(dev, "Failed to add MIC2 DAPM routes: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
struct sun8i_codec_analog_quirks {
bool has_headphone;
bool has_hmic;
+ bool has_linein;
bool has_lineout;
+ bool has_mic2;
};
static const struct sun8i_codec_analog_quirks sun8i_a23_quirks = {
.has_headphone = true,
.has_hmic = true,
+ .has_linein = true,
+ .has_mic2 = true,
};
static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = {
+ .has_linein = true,
.has_lineout = true,
+ .has_mic2 = true,
};
static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
@@ -620,12 +722,24 @@ static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
return ret;
}
+ if (quirks->has_linein) {
+ ret = sun8i_codec_add_linein(cmpnt);
+ if (ret)
+ return ret;
+ }
+
if (quirks->has_lineout) {
ret = sun8i_codec_add_lineout(cmpnt);
if (ret)
return ret;
}
+ if (quirks->has_mic2) {
+ ret = sun8i_codec_add_mic2(cmpnt);
+ if (ret)
+ return ret;
+ }
+
return 0;
}