From 2a0db30765bce6f552f187c9b26ce70f5fb79c16 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 25 Oct 2012 15:24:42 +0100 Subject: [PATCH 01/31] ASoC: wm5102: Correct micbias DAPM supplies ARIZONA_MICB1_ENA_SHIFT was used for micbias 2 and 3. This change correctly uses the ARIZONA_MICBX_ENA_SHIFT for each corresponding DAPM supply. This should not have caused any problems as the micbias enables are in the same place in each register. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 1722b586bdba..8714d6280dca 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -344,9 +344,9 @@ SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, - ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), + ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, - ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), + ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), From 0b09df665269fc883a242efff46a6b28e8850a97 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 11 Oct 2012 11:31:35 +0900 Subject: [PATCH 02/31] ASoC: arizona: Define standard hookup for ADSP2 Many Arizona class devices contain ADSP2 cores with a standard method for hooking them into the audio map. Define standard helpers for this. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.h | 47 +++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 36ec64946120..5a09127fcbab 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -17,6 +17,8 @@ #include +#include "wm_adsp.h" + #define ARIZONA_CLK_SYSCLK 1 #define ARIZONA_CLK_ASYNCCLK 2 #define ARIZONA_CLK_OPCLK 3 @@ -46,15 +48,18 @@ #define ARIZONA_MIXER_VOL_SHIFT 1 #define ARIZONA_MIXER_VOL_WIDTH 7 -#define ARIZONA_MAX_DAI 3 +#define ARIZONA_MAX_DAI 4 +#define ARIZONA_MAX_ADSP 4 struct arizona; +struct wm_adsp; struct arizona_dai_priv { int clk; }; struct arizona_priv { + struct wm_adsp adsp[ARIZONA_MAX_ADSP]; struct arizona *arizona; int sysclk; int asyncclk; @@ -99,6 +104,20 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; static ARIZONA_MUX_CTL_DECL(name##_in3); \ static ARIZONA_MUX_CTL_DECL(name##_in4) +#define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \ + static ARIZONA_MUX_ENUM_DECL(name##_aux1_enum, base_reg); \ + static ARIZONA_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 8); \ + static ARIZONA_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 16); \ + static ARIZONA_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 24); \ + static ARIZONA_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 32); \ + static ARIZONA_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 40); \ + static ARIZONA_MUX_CTL_DECL(name##_aux1); \ + static ARIZONA_MUX_CTL_DECL(name##_aux2); \ + static ARIZONA_MUX_CTL_DECL(name##_aux3); \ + static ARIZONA_MUX_CTL_DECL(name##_aux4); \ + static ARIZONA_MUX_CTL_DECL(name##_aux5); \ + static ARIZONA_MUX_CTL_DECL(name##_aux6) + #define ARIZONA_MUX(name, ctrl) \ SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) @@ -109,6 +128,16 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) +#define ARIZONA_DSP_WIDGETS(name, name_str) \ + ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \ + ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \ + ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \ + ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \ + ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \ + ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \ + ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ + ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) + #define ARIZONA_MIXER_ROUTES(widget, name) \ { widget, NULL, name " Mixer" }, \ { name " Mixer", NULL, name " Input 1" }, \ @@ -120,6 +149,22 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") +#define ARIZONA_DSP_ROUTES(name) \ + { name, NULL, name " Aux 1" }, \ + { name, NULL, name " Aux 2" }, \ + { name, NULL, name " Aux 3" }, \ + { name, NULL, name " Aux 4" }, \ + { name, NULL, name " Aux 5" }, \ + { name, NULL, name " Aux 6" }, \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ + ARIZONA_MIXER_ROUTES(name, name "L"), \ + ARIZONA_MIXER_ROUTES(name, name "R") + extern const struct soc_enum arizona_lhpf1_mode; extern const struct soc_enum arizona_lhpf2_mode; extern const struct soc_enum arizona_lhpf3_mode; From 804f5ba7e81bde8e36dba10eb5bdeca4552dd01b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 25 Aug 2012 20:29:05 -0700 Subject: [PATCH 03/31] ASoC: wm5102: Hook up DSP1 Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 ++ sound/soc/codecs/wm5102.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f866e18e7876..80799639814e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -148,7 +148,9 @@ config SND_SOC_WM_HUBS config SND_SOC_WM_ADSP tristate + default y if SND_SOC_WM5102=y default y if SND_SOC_WM2200=y + default m if SND_SOC_WM5102=m default m if SND_SOC_WM2200=m config SND_SOC_AB8500_CODEC diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 8714d6280dca..f27527b0d61f 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -31,6 +31,7 @@ #include "arizona.h" #include "wm5102.h" +#include "wm_adsp.h" struct wm5102_priv { struct arizona_priv core; @@ -42,6 +43,13 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); +static const struct wm_adsp_region wm5102_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, + { .type = WMFW_ADSP2_XM, .base = 0x190000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1a0000 }, +}; + static const struct snd_kcontrol_new wm5102_snd_controls[] = { SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT, 1, 0), @@ -137,6 +145,9 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), + SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), @@ -274,6 +285,10 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); + +ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE); static const char *wm5102_aec_loopback_texts[] = { "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", @@ -446,6 +461,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), +WM_ADSP2("DSP1", 0), + SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), @@ -526,6 +543,8 @@ ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), +WM_ADSP2("DSP1", 0), + SND_SOC_DAPM_OUTPUT("HPOUT1L"), SND_SOC_DAPM_OUTPUT("HPOUT1R"), SND_SOC_DAPM_OUTPUT("HPOUT2L"), @@ -577,7 +596,13 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), { name, "ASRC1L", "ASRC1L" }, \ { name, "ASRC1R", "ASRC1R" }, \ { name, "ASRC2L", "ASRC2L" }, \ - { name, "ASRC2R", "ASRC2R" } + { name, "ASRC2R", "ASRC2R" }, \ + { name, "DSP1.1", "DSP1" }, \ + { name, "DSP1.2", "DSP1" }, \ + { name, "DSP1.3", "DSP1" }, \ + { name, "DSP1.4", "DSP1" }, \ + { name, "DSP1.5", "DSP1" }, \ + { name, "DSP1.6", "DSP1" } static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { { "AIF2 Capture", NULL, "DBVDD2" }, @@ -710,6 +735,8 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), + ARIZONA_DSP_ROUTES("DSP1"), + { "AEC Loopback", "HPOUT1L", "OUT1L" }, { "AEC Loopback", "HPOUT1R", "OUT1R" }, { "HPOUT1L", NULL, "OUT1L" }, @@ -884,6 +911,15 @@ static int __devinit wm5102_probe(struct platform_device *pdev) wm5102->core.arizona = arizona; + wm5102->core.adsp[0].part = "wm5102"; + wm5102->core.adsp[0].num = 1; + wm5102->core.adsp[0].type = WMFW_ADSP2; + wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1; + wm5102->core.adsp[0].dev = arizona->dev; + wm5102->core.adsp[0].regmap = arizona->regmap; + wm5102->core.adsp[0].mem = wm5102_dsp1_regions; + wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); + for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) wm5102->fll[i].vco_mult = 1; From 17bd09e5457740425fee6ca2bb685a2a55c12c18 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 13 Nov 2012 16:40:32 +0000 Subject: [PATCH 04/31] ASoC: arizona: Add support for multiplexer with no associated mixer The Asynchronous Sample Rate Converters on the wm5102/wm5110 have no mixer attached to their input, but they do allow the input to be selected from a number of sources via a multiplexer. Currently the platform assumes the presence of 4 multiplexers and a mixer for each block. This patch adds support multiplexed single input blocks into the Arizona platform. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.h | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 5a09127fcbab..f1c0ec924e3c 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -94,33 +94,30 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; const struct snd_kcontrol_new name##_mux = \ SOC_DAPM_VALUE_ENUM("Route", name##_enum) +#define ARIZONA_MUX_ENUMS(name, base_reg) \ + static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ + static ARIZONA_MUX_CTL_DECL(name) + #define ARIZONA_MIXER_ENUMS(name, base_reg) \ - static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ - static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ - static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ - static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ - static ARIZONA_MUX_CTL_DECL(name##_in1); \ - static ARIZONA_MUX_CTL_DECL(name##_in2); \ - static ARIZONA_MUX_CTL_DECL(name##_in3); \ - static ARIZONA_MUX_CTL_DECL(name##_in4) + ARIZONA_MUX_ENUMS(name##_in1, base_reg); \ + ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \ + ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \ + ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6) #define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \ - static ARIZONA_MUX_ENUM_DECL(name##_aux1_enum, base_reg); \ - static ARIZONA_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 8); \ - static ARIZONA_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 16); \ - static ARIZONA_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 24); \ - static ARIZONA_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 32); \ - static ARIZONA_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 40); \ - static ARIZONA_MUX_CTL_DECL(name##_aux1); \ - static ARIZONA_MUX_CTL_DECL(name##_aux2); \ - static ARIZONA_MUX_CTL_DECL(name##_aux3); \ - static ARIZONA_MUX_CTL_DECL(name##_aux4); \ - static ARIZONA_MUX_CTL_DECL(name##_aux5); \ - static ARIZONA_MUX_CTL_DECL(name##_aux6) + ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \ + ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \ + ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \ + ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \ + ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \ + ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) #define ARIZONA_MUX(name, ctrl) \ SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) +#define ARIZONA_MUX_WIDGETS(name, name_str) \ + ARIZONA_MUX(name_str " Input", &name##_mux) + #define ARIZONA_MIXER_WIDGETS(name, name_str) \ ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ @@ -138,6 +135,9 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) +#define ARIZONA_MUX_ROUTES(name) \ + ARIZONA_MIXER_INPUT_ROUTES(name " Input") + #define ARIZONA_MIXER_ROUTES(widget, name) \ { widget, NULL, name " Mixer" }, \ { name " Mixer", NULL, name " Input 1" }, \ From 0f3ec6a935da8a99ece2dab30f3bac308b4ac355 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 13 Nov 2012 16:40:33 +0000 Subject: [PATCH 05/31] ASoC: wm5102: Remove mixer widgets on the ASRC There is no mixer attached to the ASRC on the wm5102 only a multiplexer to select the source for the single input line. This change correctly defines this in the wm5102 CODEC driver. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index f27527b0d61f..28a57cc5c015 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -280,10 +280,10 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); @@ -538,10 +538,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), -ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), -ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), -ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), -ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), +ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), +ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), +ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), +ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), WM_ADSP2("DSP1", 0), @@ -730,10 +730,10 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), - ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), - ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), - ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), - ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), + ARIZONA_MUX_ROUTES("ASRC1L"), + ARIZONA_MUX_ROUTES("ASRC1R"), + ARIZONA_MUX_ROUTES("ASRC2L"), + ARIZONA_MUX_ROUTES("ASRC2R"), ARIZONA_DSP_ROUTES("DSP1"), From 5886c743799f9190304b40255519cea5b50164ca Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 13 Nov 2012 16:40:34 +0000 Subject: [PATCH 06/31] ASoC: wm5110: Remove mixer widgets on the ASRC There is no mixer attached to the ASRC on the wm5110 only a multiplexer to select the source for the single input line. This change correctly defines this in the wm5110 CODEC driver. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 9211e4192f71..3485b83dc068 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -308,10 +308,10 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); -ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); static const char *wm5110_aec_loopback_texts[] = { "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", @@ -585,10 +585,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), -ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), -ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), -ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), -ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), +ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), +ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), +ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), +ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), SND_SOC_DAPM_OUTPUT("HPOUT1L"), SND_SOC_DAPM_OUTPUT("HPOUT1R"), @@ -786,10 +786,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), - ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), - ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), - ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), - ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), + ARIZONA_MUX_ROUTES("ASRC1L"), + ARIZONA_MUX_ROUTES("ASRC1R"), + ARIZONA_MUX_ROUTES("ASRC2L"), + ARIZONA_MUX_ROUTES("ASRC2R"), { "HPOUT1L", NULL, "OUT1L" }, { "HPOUT1R", NULL, "OUT1R" }, From 9ce6565faa467205d68474e1ee1995f41661b7b8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 15 Nov 2012 11:09:17 +0900 Subject: [PATCH 07/31] ASoC: wm5102: Remove output OSR and PGA volume control These are managed automatically in current revisions. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 05c2add66e3b..b81251f2ecf0 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -719,14 +719,6 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), -SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L, - ARIZONA_OUT1_OSR_SHIFT, 1, 0), -SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, - ARIZONA_OUT2_OSR_SHIFT, 1, 0), -SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, - ARIZONA_OUT3_OSR_SHIFT, 1, 0), -SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, - ARIZONA_OUT4_OSR_SHIFT, 1, 0), SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, ARIZONA_OUT5_OSR_SHIFT, 1, 0), @@ -756,17 +748,6 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L, - ARIZONA_OUTPUT_PATH_CONFIG_1R, - ARIZONA_OUT1L_PGA_VOL_SHIFT, - 0x34, 0x40, 0, ana_tlv), -SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L, - ARIZONA_OUTPUT_PATH_CONFIG_2R, - ARIZONA_OUT2L_PGA_VOL_SHIFT, - 0x34, 0x40, 0, ana_tlv), -SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, - ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), - SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), From 4cbc365509560086faca950d69bd89fc956033b3 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 20 Nov 2012 13:15:21 +0000 Subject: [PATCH 08/31] ASoC: wm5102: Register DSP1 Aux widgets It seems WM_ADSP2("DSP1", 0) is added twice to the widgets list, remove that and in place use ARIZONA_DSP_WIDGETS(DSP1, "DSP1"). We need to make sure that the DSP1 Aux widgets are provided otherwise we'll see errors such as "Failed to add route DSP1 Aux 1 -> DSP1" etc. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b81251f2ecf0..b18fd2ea1874 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -992,7 +992,7 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), -WM_ADSP2("DSP1", 0), +ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), From 38113360f03c0834135c89e43d0fe307b04aca08 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 26 Nov 2012 16:01:37 +0000 Subject: [PATCH 09/31] ASoC: arizona: Support higher clock rates Some devices support higher clock rates, allow users to select these. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c03b65af3059..500e6cb462d8 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -380,6 +380,18 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, case 49152000: val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; break; + case 67737600: + case 73728000: + val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + case 90316800: + case 98304000: + val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + case 135475200: + case 147456000: + val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; default: return -EINVAL; } From ba6b047ab9af433fb53939032858b196d05e6a18 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 19:02:05 +0000 Subject: [PATCH 10/31] ASoC: wm5102: Add missing routes for ASRC inputs Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b18fd2ea1874..f4c122acf762 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1219,6 +1219,11 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { { "IN3L PGA", NULL, "IN3L" }, { "IN3R PGA", NULL, "IN3R" }, + { "ASRC1L", NULL, "ASRC1L Input" }, + { "ASRC1R", NULL, "ASRC1R Input" }, + { "ASRC2L", NULL, "ASRC2L Input" }, + { "ASRC2R", NULL, "ASRC2R Input" }, + ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), From 1cbe4bcae342973e36447aa03a609bc25804f416 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 21 Nov 2012 14:12:22 +0900 Subject: [PATCH 11/31] ASoC: arizona: Suppress noop FLL updates Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 6 ++++++ sound/soc/codecs/arizona.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 500e6cb462d8..d49764388f1c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -937,6 +937,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, bool ena; int ret; + if (fll->fref == Fref && fll->fout == Fout) + return 0; + ret = regmap_read(arizona->regmap, fll->base + 1, ®); if (ret != 0) { arizona_fll_err(fll, "Failed to read current state: %d\n", @@ -1014,6 +1017,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, if (ret == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); + fll->fref = Fref; + fll->fout = Fout; + return 0; } EXPORT_SYMBOL_GPL(arizona_set_fll); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index f1c0ec924e3c..84c415d335bd 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -191,6 +191,8 @@ struct arizona_fll { unsigned int vco_mult; struct completion lock; struct completion ok; + unsigned int fref; + unsigned int fout; char lock_name[ARIZONA_FLL_NAME_LEN]; char clock_ok_name[ARIZONA_FLL_NAME_LEN]; From 50fcfe45d70b0059d53904e5245be65e1a8bca7c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 Nov 2012 11:50:34 +0000 Subject: [PATCH 12/31] ASoC: arizona: Record FLL setting when disabling Otherwise we skip reenables. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index d49764388f1c..bf6844389ebf 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -985,6 +985,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, if (ena) pm_runtime_put_autosuspend(arizona->dev); + fll->fref = Fref; + fll->fout = Fout; + return 0; } From b951b523ea45d5717377ce2216afe98440001660 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 26 Nov 2012 21:11:10 +0000 Subject: [PATCH 13/31] mfd: arizona: Allow the CODEC DAPM context to be accessed elsewhere Some other device functions need to integrate with signal sources in the audio portion (primarily for haptics) so allow CODEC to export the DAPM context by pointing to it from the core driver. Signed-off-by: Mark Brown --- include/linux/mfd/arizona/core.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index dd231ac0bb1f..a580363a7d29 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -78,6 +78,8 @@ enum arizona_type { #define ARIZONA_NUM_IRQ 50 +struct snd_soc_dapm_context; + struct arizona { struct regmap *regmap; struct device *dev; @@ -98,6 +100,8 @@ struct arizona { struct mutex clk_lock; int clk32k_ref; + + struct snd_soc_dapm_context *dapm; }; int arizona_clk32k_enable(struct arizona *arizona); From 9dd555e2f4de1af1bb0f75cc84ed0708fcdb5987 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 26 Nov 2012 21:17:21 +0000 Subject: [PATCH 14/31] Input - arizona-haptics: Add driver haptics module on Arizona CODECs The Arizona CODECs contain a haptics module providing vibration feedback support. Implement basic support for this, providing simple start/stop and signal magnitude control. Since the output path for haptics is routed through the CODEC audio routing it is modelled as a signal generator within ASoC, the haptics driver calls DAPM to start and stop the output drivers. An appropriate output path must be configured via ALSA to connect the haptics source to the correct output. Signed-off-by: Mark Brown --- drivers/input/misc/Kconfig | 10 ++ drivers/input/misc/Makefile | 1 + drivers/input/misc/arizona-haptics.c | 255 +++++++++++++++++++++++++++ include/linux/mfd/arizona/pdata.h | 6 + 4 files changed, 272 insertions(+) create mode 100644 drivers/input/misc/arizona-haptics.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7c0f1ecfdd7a..104a7c3153c0 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -72,6 +72,16 @@ config INPUT_AD714X_SPI To compile this driver as a module, choose M here: the module will be called ad714x-spi. +config INPUT_ARIZONA_HAPTICS + tristate "Arizona haptics support" + depends on MFD_ARIZONA && SND_SOC + select INPUT_FF_MEMLESS + help + Say Y to enable support for the haptics module in Arizona CODECs. + + To compile this driver as a module, choose M here: the + module will be called arizona-haptics. + config INPUT_BMA150 tristate "BMA150/SMB380 acceleration sensor support" depends on I2C diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 83fe6f5b77d1..5ea769eda999 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o obj-$(CONFIG_INPUT_APANEL) += apanel.o +obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c new file mode 100644 index 000000000000..7a04f54ef961 --- /dev/null +++ b/drivers/input/misc/arizona-haptics.c @@ -0,0 +1,255 @@ +/* + * Arizona haptics driver + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * 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. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +struct arizona_haptics { + struct arizona *arizona; + struct input_dev *input_dev; + struct work_struct work; + + struct mutex mutex; + u8 intensity; +}; + +static void arizona_haptics_work(struct work_struct *work) +{ + struct arizona_haptics *haptics = container_of(work, + struct arizona_haptics, + work); + struct arizona *arizona = haptics->arizona; + struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex; + int ret; + + if (!haptics->arizona->dapm) { + dev_err(arizona->dev, "No DAPM context\n"); + return; + } + + if (haptics->intensity) { + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HAPTICS_PHASE_2_INTENSITY, + ARIZONA_PHASE2_INTENSITY_MASK, + haptics->intensity); + if (ret != 0) { + dev_err(arizona->dev, "Failed to set intensity: %d\n", + ret); + return; + } + + /* This enable sequence will be a noop if already enabled */ + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HAPTICS_CONTROL_1, + ARIZONA_HAP_CTRL_MASK, + 1 << ARIZONA_HAP_CTRL_SHIFT); + if (ret != 0) { + dev_err(arizona->dev, "Failed to start haptics: %d\n", + ret); + return; + } + + mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + + ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); + if (ret != 0) { + dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + ret = snd_soc_dapm_sync(arizona->dapm); + if (ret != 0) { + dev_err(arizona->dev, "Failed to sync DAPM: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + mutex_unlock(dapm_mutex); + + } else { + /* This disable sequence will be a noop if already enabled */ + mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + + ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); + if (ret != 0) { + dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + ret = snd_soc_dapm_sync(arizona->dapm); + if (ret != 0) { + dev_err(arizona->dev, "Failed to sync DAPM: %d\n", + ret); + mutex_unlock(dapm_mutex); + return; + } + + mutex_unlock(dapm_mutex); + + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HAPTICS_CONTROL_1, + ARIZONA_HAP_CTRL_MASK, + 1 << ARIZONA_HAP_CTRL_SHIFT); + if (ret != 0) { + dev_err(arizona->dev, "Failed to stop haptics: %d\n", + ret); + return; + } + } +} + +static int arizona_haptics_play(struct input_dev *input, void *data, + struct ff_effect *effect) +{ + struct arizona_haptics *haptics = input_get_drvdata(input); + struct arizona *arizona = haptics->arizona; + + if (!arizona->dapm) { + dev_err(arizona->dev, "No DAPM context\n"); + return -EBUSY; + } + + if (effect->u.rumble.strong_magnitude) { + /* Scale the magnitude into the range the device supports */ + if (arizona->pdata.hap_act) { + haptics->intensity = + effect->u.rumble.strong_magnitude >> 9; + if (effect->direction < 0x8000) + haptics->intensity += 0x7f; + } else { + haptics->intensity = + effect->u.rumble.strong_magnitude >> 8; + } + } else { + haptics->intensity = 0; + } + + schedule_work(&haptics->work); + + return 0; +} + +static void arizona_haptics_close(struct input_dev *input) +{ + struct arizona_haptics *haptics = input_get_drvdata(input); + struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex; + + cancel_work_sync(&haptics->work); + + mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + + if (haptics->arizona->dapm) + snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); + + mutex_unlock(dapm_mutex); +} + +static int arizona_haptics_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct arizona_haptics *haptics; + int ret; + + haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL); + if (!haptics) + return -ENOMEM; + + haptics->arizona = arizona; + + ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1, + ARIZONA_HAP_ACT, arizona->pdata.hap_act); + if (ret != 0) { + dev_err(arizona->dev, "Failed to set haptics actuator: %d\n", + ret); + return ret; + } + + INIT_WORK(&haptics->work, arizona_haptics_work); + + haptics->input_dev = input_allocate_device(); + if (haptics->input_dev == NULL) { + dev_err(arizona->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + input_set_drvdata(haptics->input_dev, haptics); + + haptics->input_dev->name = "arizona:haptics"; + haptics->input_dev->dev.parent = pdev->dev.parent; + haptics->input_dev->close = arizona_haptics_close; + __set_bit(FF_RUMBLE, haptics->input_dev->ffbit); + + ret = input_ff_create_memless(haptics->input_dev, NULL, + arizona_haptics_play); + if (ret < 0) { + dev_err(arizona->dev, "input_ff_create_memless() failed: %d\n", + ret); + goto err_ialloc; + } + + ret = input_register_device(haptics->input_dev); + if (ret < 0) { + dev_err(arizona->dev, "couldn't register input device: %d\n", + ret); + goto err_iff; + } + + platform_set_drvdata(pdev, haptics); + + return 0; + +err_iff: + if (haptics->input_dev) + input_ff_destroy(haptics->input_dev); +err_ialloc: + input_free_device(haptics->input_dev); + + return ret; +} + +static int arizona_haptics_remove(struct platform_device *pdev) +{ + struct arizona_haptics *haptics = platform_get_drvdata(pdev); + + input_unregister_device(haptics->input_dev); + + return 0; +} + +static struct platform_driver arizona_haptics_driver = { + .probe = arizona_haptics_probe, + .remove = arizona_haptics_remove, + .driver = { + .name = "arizona-haptics", + .owner = THIS_MODULE, + }, +}; +module_platform_driver(arizona_haptics_driver); + +MODULE_ALIAS("platform:arizona-haptics"); +MODULE_DESCRIPTION("Arizona haptics driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mark Brown "); diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 7ab442905a57..8b1d1daaae16 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -62,6 +62,9 @@ #define ARIZONA_MAX_OUTPUT 6 +#define ARIZONA_HAP_ACT_ERM 0 +#define ARIZONA_HAP_ACT_LRA 2 + #define ARIZONA_MAX_PDM_SPK 2 struct regulator_init_data; @@ -114,6 +117,9 @@ struct arizona_pdata { /** PDM speaker format */ unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK]; + + /** Haptic actuator type */ + unsigned int hap_act; }; #endif From 3f41e3d2e80ebd093128a02b2009e14faf488052 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 26 Nov 2012 21:18:00 +0000 Subject: [PATCH 15/31] ASoC: wm5102: Implement haptics support Provide a haptics widget for use by the haptics driver and expose the DAPM context for it. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index f4c122acf762..5a1eb5b62fb5 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -860,6 +860,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), SND_SOC_DAPM_SIGGEN("TONE"), SND_SOC_DAPM_SIGGEN("NOISE"), +SND_SOC_DAPM_SIGGEN("HAPTICS"), SND_SOC_DAPM_INPUT("IN1L"), SND_SOC_DAPM_INPUT("IN1R"), @@ -1094,6 +1095,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), { name, "Noise Generator", "Noise Generator" }, \ { name, "Tone Generator 1", "Tone Generator 1" }, \ { name, "Tone Generator 2", "Tone Generator 2" }, \ + { name, "Haptics", "HAPTICS" }, \ { name, "AEC", "AEC Loopback" }, \ { name, "IN1L", "IN1L PGA" }, \ { name, "IN1R", "IN1R PGA" }, \ @@ -1390,9 +1392,28 @@ static struct snd_soc_dai_driver wm5102_dai[] = { static int wm5102_codec_probe(struct snd_soc_codec *codec) { struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); + int ret; codec->control_data = priv->core.arizona->regmap; - return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + + ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + if (ret != 0) + return ret; + + snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); + + priv->core.arizona->dapm = &codec->dapm; + + return 0; +} + +static int wm5102_codec_remove(struct snd_soc_codec *codec) +{ + struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); + + priv->core.arizona->dapm = NULL; + + return 0; } #define WM5102_DIG_VU 0x0200 @@ -1419,6 +1440,7 @@ static unsigned int wm5102_digital_vu[] = { static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { .probe = wm5102_codec_probe, + .remove = wm5102_codec_remove, .idle_bias_off = true, From 2f76e6855ff7257230b81dfb223acc1ab0e41b0b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 26 Nov 2012 21:18:18 +0000 Subject: [PATCH 16/31] ASoC: wm5110: Implement haptics support Provide a haptics widget for use by the haptics driver and expose the DAPM context for it. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 3485b83dc068..2a075ad00d5b 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -352,6 +352,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), SND_SOC_DAPM_SIGGEN("TONE"), SND_SOC_DAPM_SIGGEN("NOISE"), +SND_SOC_DAPM_SIGGEN("HAPTICS"), SND_SOC_DAPM_INPUT("IN1L"), SND_SOC_DAPM_INPUT("IN1R"), @@ -610,6 +611,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"), { name, "Noise Generator", "Noise Generator" }, \ { name, "Tone Generator 1", "Tone Generator 1" }, \ { name, "Tone Generator 2", "Tone Generator 2" }, \ + { name, "Haptics", "HAPTICS" }, \ { name, "AEC", "AEC Loopback" }, \ { name, "IN1L", "IN1L PGA" }, \ { name, "IN1R", "IN1R PGA" }, \ @@ -902,9 +904,29 @@ static struct snd_soc_dai_driver wm5110_dai[] = { static int wm5110_codec_probe(struct snd_soc_codec *codec) { struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); + int ret; codec->control_data = priv->core.arizona->regmap; - return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + priv->core.arizona->dapm = &codec->dapm; + + ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); + if (ret != 0) + return ret; + + snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); + + priv->core.arizona->dapm = &codec->dapm; + + return 0; +} + +static int wm5110_codec_remove(struct snd_soc_codec *codec) +{ + struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); + + priv->core.arizona->dapm = NULL; + + return 0; } #define WM5110_DIG_VU 0x0200 @@ -935,6 +957,7 @@ static unsigned int wm5110_digital_vu[] = { static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { .probe = wm5110_codec_probe, + .remove = wm5110_codec_remove, .idle_bias_off = true, From 503b1cac5c7bb94b267c831d0a7966a18d38365e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 17:36:38 +0000 Subject: [PATCH 17/31] mfd: arizona: Register haptics devices Both WM5102 and WM5110 support haptics, register the device. Signed-off-by: Mark Brown --- drivers/mfd/arizona-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 1b48f2094806..75619711a9e7 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -272,6 +272,7 @@ static struct mfd_cell early_devs[] = { static struct mfd_cell wm5102_devs[] = { { .name = "arizona-extcon" }, { .name = "arizona-gpio" }, + { .name = "arizona-haptics" }, { .name = "arizona-micsupp" }, { .name = "arizona-pwm" }, { .name = "wm5102-codec" }, @@ -280,6 +281,7 @@ static struct mfd_cell wm5102_devs[] = { static struct mfd_cell wm5110_devs[] = { { .name = "arizona-extcon" }, { .name = "arizona-gpio" }, + { .name = "arizona-haptics" }, { .name = "arizona-micsupp" }, { .name = "arizona-pwm" }, { .name = "wm5110-codec" }, From cac27cff066cf86c6fefe33d99d935e9d0d9c78c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 Nov 2012 17:20:52 +0000 Subject: [PATCH 18/31] ASoC: wm5102: Enable DVFS support for the DSP Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 5a1eb5b62fb5..760df353540d 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1459,7 +1459,7 @@ static int __devinit wm5102_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct wm5102_priv *wm5102; - int i; + int i, ret; wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), GFP_KERNEL); @@ -1478,6 +1478,10 @@ static int __devinit wm5102_probe(struct platform_device *pdev) wm5102->core.adsp[0].mem = wm5102_dsp1_regions; wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); + ret = wm_adsp2_init(&wm5102->core.adsp[0], true); + if (ret != 0) + return ret; + for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) wm5102->fll[i].vco_mult = 1; From e436cadd65c51a57639522f334269793b1c68e22 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 2 Dec 2012 10:42:22 +0900 Subject: [PATCH 19/31] ASoC: wm5102: Correct base address for Y region Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 760df353540d..53793b1849f7 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -47,7 +47,7 @@ static const struct wm_adsp_region wm5102_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x100000 }, { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, { .type = WMFW_ADSP2_XM, .base = 0x190000 }, - { .type = WMFW_ADSP2_YM, .base = 0x1a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, }; static const struct reg_default wm5102_sysclk_reva_patch[] = { From 10a2b662c4b49e91a09e225071d3c3508cd6ee83 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 2 Dec 2012 21:37:00 +0900 Subject: [PATCH 20/31] ASoC: adsp: Keep ADSP2 memory powered off when not in use Turn off the ADSP memory when we aren't using it, saving a small amount of power. Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index a41742da20cb..3a8d75bfb0b1 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -629,6 +629,17 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) { int ret; + /* + * Disable the DSP memory by default when in reset for a small + * power saving. + */ + ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + if (ret != 0) { + adsp_err(adsp, "Failed to clear memory retention: %d\n", ret); + return ret; + } + if (dvfs) { adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); if (IS_ERR(adsp->dvfs)) { From dd49e2c8b9f18bd4f2848a9d558da08db3966319 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 2 Dec 2012 21:50:46 +0900 Subject: [PATCH 21/31] ASoC: adsp: Set DSP clock rate to SYSCLK rate For simplicity always run the DSP at the SYSCLK rate. Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 3a8d75bfb0b1..dcf14c38e67e 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -544,6 +544,28 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); + if (ret != 0) { + adsp_err(dsp, "Failed to read SYSCLK state: %d\n", + ret); + return ret; + } + val = (val & ARIZONA_SYSCLK_FREQ_MASK) + >> ARIZONA_SYSCLK_FREQ_SHIFT; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP2_CLOCKING, + ADSP2_CLK_SEL_MASK, val); + if (ret != 0) { + adsp_err(dsp, "Failed to set clock rate: %d\n", + ret); + return ret; + } + if (dsp->dvfs) { ret = regmap_read(dsp->regmap, dsp->base + ADSP2_CLOCKING, &val); From f055c8f0fea20c991e154592c9df7b0f13322fc9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 3 Dec 2012 11:23:51 +0900 Subject: [PATCH 22/31] ASoC: wm5102: Add support for configuring LHPF coefficients Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 53793b1849f7..b85e2a119f7e 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -695,6 +695,11 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1), +SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), +SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), +SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), + ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), From 2aeffd406e94c6a0f62fcfab8242590f9dfbfa63 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 5 Dec 2012 14:49:05 +0900 Subject: [PATCH 23/31] ASoC: wm5102: Make EQ coefficents configurable Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b85e2a119f7e..ed33cae04c3c 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -640,6 +640,15 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21, + ARIZONA_EQ1_ENA_MASK), +SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21, + ARIZONA_EQ2_ENA_MASK), +SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21, + ARIZONA_EQ3_ENA_MASK), +SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21, + ARIZONA_EQ4_ENA_MASK), + SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 24, 0, eq_tlv), SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, From 56fd4608edf779340ef9dfb20b5f19fe88c56cbd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 5 Dec 2012 16:38:12 +0900 Subject: [PATCH 24/31] ASoC: wm5110: Add EQ coefficient configuration Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2a075ad00d5b..dc8e44f44c99 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -89,6 +89,15 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21, + ARIZONA_EQ1_ENA_MASK), +SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21, + ARIZONA_EQ2_ENA_MASK), +SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21, + ARIZONA_EQ3_ENA_MASK), +SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21, + ARIZONA_EQ4_ENA_MASK), + SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, 24, 0, eq_tlv), SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, From d4d1eaaca05a45059eb5bc2d2a397b7841c853a9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 5 Dec 2012 16:38:30 +0900 Subject: [PATCH 25/31] ASoC: wm5110: Add LHPF coefficient configuration Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index dc8e44f44c99..14c90aa8a9b7 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -157,6 +157,11 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), +SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1), +SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), +SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), +SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), + SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), From 09871a942ab71fb06ceb7f0a4d38ea62fe7459ec Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 6 Dec 2012 15:29:34 +0900 Subject: [PATCH 26/31] ASoC: arizona: Make FLL lock timeout very high Provide robustness against low quality FLL sync clocks by increasing the timeout for lock to an absurdly high point; we should never get anywhere near hitting the timeout in a real system unless it is failing. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index bf6844389ebf..49d115205810 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1016,7 +1016,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, ARIZONA_FLL1_SYNC_ENA); ret = wait_for_completion_timeout(&fll->ok, - msecs_to_jiffies(25)); + msecs_to_jiffies(250)); if (ret == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); From 0c778e86337148110b13b609074109eb4dcacd15 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 6 Dec 2012 18:22:25 +0900 Subject: [PATCH 27/31] ASoC: arizona: Store the DAI clock ID when setting So the code to suppress duplicate changes is effective. Reported-by: Kyung Kwee Ryu Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 49d115205810..6c1be6cadc0b 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -761,6 +761,8 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, routes[1].source = arizona_dai_clk_str(clk_id); snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); + dai_priv->clk = clk_id; + return snd_soc_dapm_sync(&codec->dapm); } From c8d35a6a3e071a93814a78ce997143aa02067351 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 7 Dec 2012 12:49:40 +0900 Subject: [PATCH 28/31] ASoC: arizona: Log the clock we're setting the DAI to use Useful for diagnostics. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 6c1be6cadc0b..8e1da574f33b 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -749,6 +749,9 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, return -EBUSY; } + dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1, + arizona_dai_clk_str(clk_id)); + memset(&routes, 0, sizeof(routes)); routes[0].sink = dai->driver->capture.stream_name; routes[1].sink = dai->driver->playback.stream_name; From e853a00f5feed5f602b370465a8fb2bb81594106 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 9 Dec 2012 12:25:52 +0900 Subject: [PATCH 29/31] ASoC: arizona: Add volume ramp controls Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 25 +++++++++++++++++++++++++ sound/soc/codecs/arizona.h | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 8e1da574f33b..b9865090ef9e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -226,6 +226,31 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values); const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); EXPORT_SYMBOL_GPL(arizona_mixer_tlv); +static const char *arizona_vol_ramp_text[] = { + "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", + "15ms/6dB", "30ms/6dB", +}; + +const struct soc_enum arizona_in_vd_ramp = + SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, + ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); + +const struct soc_enum arizona_in_vi_ramp = + SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, + ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); + +const struct soc_enum arizona_out_vd_ramp = + SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, + ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); + +const struct soc_enum arizona_out_vi_ramp = + SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, + ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); +EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); + static const char *arizona_lhpf_mode_text[] = { "Low-pass", "High-pass" }; diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 84c415d335bd..41dae1ed3b71 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -165,6 +165,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_ROUTES(name, name "L"), \ ARIZONA_MIXER_ROUTES(name, name "R") +extern const struct soc_enum arizona_in_vi_ramp; +extern const struct soc_enum arizona_in_vd_ramp; + +extern const struct soc_enum arizona_out_vi_ramp; +extern const struct soc_enum arizona_out_vd_ramp; + extern const struct soc_enum arizona_lhpf1_mode; extern const struct soc_enum arizona_lhpf2_mode; extern const struct soc_enum arizona_lhpf3_mode; From dfc075cb66c2967c7d1a05a65928638e52eae140 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 9 Dec 2012 12:26:49 +0900 Subject: [PATCH 30/31] ASoC: wm5102: Enable volume ramp control Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index ed33cae04c3c..27f7e38e7eca 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -635,6 +635,9 @@ SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L, ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), +SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), + ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), @@ -762,6 +765,9 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), +SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), + SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), From a1abfa86d01c68d4d05d312998f00513c0c0d834 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 9 Dec 2012 12:50:05 +0900 Subject: [PATCH 31/31] ASoC: wm5110: Enable volume ramp control Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 14c90aa8a9b7..c57dc7468300 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -84,6 +84,9 @@ SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L, ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), +SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), + ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), @@ -257,6 +260,9 @@ SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT, ARIZONA_SPK2R_MUTE_SHIFT, 1, 1), +SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), +SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), + ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),