aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/arizona-haptics.c255
-rw-r--r--drivers/mfd/arizona-core.c2
-rw-r--r--include/linux/mfd/arizona/core.h4
-rw-r--r--include/linux/mfd/arizona/pdata.h6
-rw-r--r--sound/soc/codecs/Kconfig2
-rw-r--r--sound/soc/codecs/arizona.c21
-rw-r--r--sound/soc/codecs/arizona.h65
-rw-r--r--sound/soc/codecs/wm5102.c120
-rw-r--r--sound/soc/codecs/wm5110.c49
11 files changed, 477 insertions, 58 deletions
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
72 To compile this driver as a module, choose M here: the 72 To compile this driver as a module, choose M here: the
73 module will be called ad714x-spi. 73 module will be called ad714x-spi.
74 74
75config INPUT_ARIZONA_HAPTICS
76 tristate "Arizona haptics support"
77 depends on MFD_ARIZONA && SND_SOC
78 select INPUT_FF_MEMLESS
79 help
80 Say Y to enable support for the haptics module in Arizona CODECs.
81
82 To compile this driver as a module, choose M here: the
83 module will be called arizona-haptics.
84
75config INPUT_BMA150 85config INPUT_BMA150
76 tristate "BMA150/SMB380 acceleration sensor support" 86 tristate "BMA150/SMB380 acceleration sensor support"
77 depends on I2C 87 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
14obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o 14obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o
15obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o 15obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o
16obj-$(CONFIG_INPUT_APANEL) += apanel.o 16obj-$(CONFIG_INPUT_APANEL) += apanel.o
17obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o
17obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 18obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
18obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o 19obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
19obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o 20obj-$(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 @@
1/*
2 * Arizona haptics driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/input.h>
16#include <linux/slab.h>
17
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20
21#include <linux/mfd/arizona/core.h>
22#include <linux/mfd/arizona/pdata.h>
23#include <linux/mfd/arizona/registers.h>
24
25struct arizona_haptics {
26 struct arizona *arizona;
27 struct input_dev *input_dev;
28 struct work_struct work;
29
30 struct mutex mutex;
31 u8 intensity;
32};
33
34static void arizona_haptics_work(struct work_struct *work)
35{
36 struct arizona_haptics *haptics = container_of(work,
37 struct arizona_haptics,
38 work);
39 struct arizona *arizona = haptics->arizona;
40 struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex;
41 int ret;
42
43 if (!haptics->arizona->dapm) {
44 dev_err(arizona->dev, "No DAPM context\n");
45 return;
46 }
47
48 if (haptics->intensity) {
49 ret = regmap_update_bits(arizona->regmap,
50 ARIZONA_HAPTICS_PHASE_2_INTENSITY,
51 ARIZONA_PHASE2_INTENSITY_MASK,
52 haptics->intensity);
53 if (ret != 0) {
54 dev_err(arizona->dev, "Failed to set intensity: %d\n",
55 ret);
56 return;
57 }
58
59 /* This enable sequence will be a noop if already enabled */
60 ret = regmap_update_bits(arizona->regmap,
61 ARIZONA_HAPTICS_CONTROL_1,
62 ARIZONA_HAP_CTRL_MASK,
63 1 << ARIZONA_HAP_CTRL_SHIFT);
64 if (ret != 0) {
65 dev_err(arizona->dev, "Failed to start haptics: %d\n",
66 ret);
67 return;
68 }
69
70 mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
71
72 ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS");
73 if (ret != 0) {
74 dev_err(arizona->dev, "Failed to start HAPTICS: %d\n",
75 ret);
76 mutex_unlock(dapm_mutex);
77 return;
78 }
79
80 ret = snd_soc_dapm_sync(arizona->dapm);
81 if (ret != 0) {
82 dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
83 ret);
84 mutex_unlock(dapm_mutex);
85 return;
86 }
87
88 mutex_unlock(dapm_mutex);
89
90 } else {
91 /* This disable sequence will be a noop if already enabled */
92 mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
93
94 ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS");
95 if (ret != 0) {
96 dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n",
97 ret);
98 mutex_unlock(dapm_mutex);
99 return;
100 }
101
102 ret = snd_soc_dapm_sync(arizona->dapm);
103 if (ret != 0) {
104 dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
105 ret);
106 mutex_unlock(dapm_mutex);
107 return;
108 }
109
110 mutex_unlock(dapm_mutex);
111
112 ret = regmap_update_bits(arizona->regmap,
113 ARIZONA_HAPTICS_CONTROL_1,
114 ARIZONA_HAP_CTRL_MASK,
115 1 << ARIZONA_HAP_CTRL_SHIFT);
116 if (ret != 0) {
117 dev_err(arizona->dev, "Failed to stop haptics: %d\n",
118 ret);
119 return;
120 }
121 }
122}
123
124static int arizona_haptics_play(struct input_dev *input, void *data,
125 struct ff_effect *effect)
126{
127 struct arizona_haptics *haptics = input_get_drvdata(input);
128 struct arizona *arizona = haptics->arizona;
129
130 if (!arizona->dapm) {
131 dev_err(arizona->dev, "No DAPM context\n");
132 return -EBUSY;
133 }
134
135 if (effect->u.rumble.strong_magnitude) {
136 /* Scale the magnitude into the range the device supports */
137 if (arizona->pdata.hap_act) {
138 haptics->intensity =
139 effect->u.rumble.strong_magnitude >> 9;
140 if (effect->direction < 0x8000)
141 haptics->intensity += 0x7f;
142 } else {
143 haptics->intensity =
144 effect->u.rumble.strong_magnitude >> 8;
145 }
146 } else {
147 haptics->intensity = 0;
148 }
149
150 schedule_work(&haptics->work);
151
152 return 0;
153}
154
155static void arizona_haptics_close(struct input_dev *input)
156{
157 struct arizona_haptics *haptics = input_get_drvdata(input);
158 struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex;
159
160 cancel_work_sync(&haptics->work);
161
162 mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
163
164 if (haptics->arizona->dapm)
165 snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS");
166
167 mutex_unlock(dapm_mutex);
168}
169
170static int arizona_haptics_probe(struct platform_device *pdev)
171{
172 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
173 struct arizona_haptics *haptics;
174 int ret;
175
176 haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL);
177 if (!haptics)
178 return -ENOMEM;
179
180 haptics->arizona = arizona;
181
182 ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1,
183 ARIZONA_HAP_ACT, arizona->pdata.hap_act);
184 if (ret != 0) {
185 dev_err(arizona->dev, "Failed to set haptics actuator: %d\n",
186 ret);
187 return ret;
188 }
189
190 INIT_WORK(&haptics->work, arizona_haptics_work);
191
192 haptics->input_dev = input_allocate_device();
193 if (haptics->input_dev == NULL) {
194 dev_err(arizona->dev, "Failed to allocate input device\n");
195 return -ENOMEM;
196 }
197
198 input_set_drvdata(haptics->input_dev, haptics);
199
200 haptics->input_dev->name = "arizona:haptics";
201 haptics->input_dev->dev.parent = pdev->dev.parent;
202 haptics->input_dev->close = arizona_haptics_close;
203 __set_bit(FF_RUMBLE, haptics->input_dev->ffbit);
204
205 ret = input_ff_create_memless(haptics->input_dev, NULL,
206 arizona_haptics_play);
207 if (ret < 0) {
208 dev_err(arizona->dev, "input_ff_create_memless() failed: %d\n",
209 ret);
210 goto err_ialloc;
211 }
212
213 ret = input_register_device(haptics->input_dev);
214 if (ret < 0) {
215 dev_err(arizona->dev, "couldn't register input device: %d\n",
216 ret);
217 goto err_iff;
218 }
219
220 platform_set_drvdata(pdev, haptics);
221
222 return 0;
223
224err_iff:
225 if (haptics->input_dev)
226 input_ff_destroy(haptics->input_dev);
227err_ialloc:
228 input_free_device(haptics->input_dev);
229
230 return ret;
231}
232
233static int arizona_haptics_remove(struct platform_device *pdev)
234{
235 struct arizona_haptics *haptics = platform_get_drvdata(pdev);
236
237 input_unregister_device(haptics->input_dev);
238
239 return 0;
240}
241
242static struct platform_driver arizona_haptics_driver = {
243 .probe = arizona_haptics_probe,
244 .remove = arizona_haptics_remove,
245 .driver = {
246 .name = "arizona-haptics",
247 .owner = THIS_MODULE,
248 },
249};
250module_platform_driver(arizona_haptics_driver);
251
252MODULE_ALIAS("platform:arizona-haptics");
253MODULE_DESCRIPTION("Arizona haptics driver");
254MODULE_LICENSE("GPL");
255MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
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[] = {
272static struct mfd_cell wm5102_devs[] = { 272static struct mfd_cell wm5102_devs[] = {
273 { .name = "arizona-extcon" }, 273 { .name = "arizona-extcon" },
274 { .name = "arizona-gpio" }, 274 { .name = "arizona-gpio" },
275 { .name = "arizona-haptics" },
275 { .name = "arizona-micsupp" }, 276 { .name = "arizona-micsupp" },
276 { .name = "arizona-pwm" }, 277 { .name = "arizona-pwm" },
277 { .name = "wm5102-codec" }, 278 { .name = "wm5102-codec" },
@@ -280,6 +281,7 @@ static struct mfd_cell wm5102_devs[] = {
280static struct mfd_cell wm5110_devs[] = { 281static struct mfd_cell wm5110_devs[] = {
281 { .name = "arizona-extcon" }, 282 { .name = "arizona-extcon" },
282 { .name = "arizona-gpio" }, 283 { .name = "arizona-gpio" },
284 { .name = "arizona-haptics" },
283 { .name = "arizona-micsupp" }, 285 { .name = "arizona-micsupp" },
284 { .name = "arizona-pwm" }, 286 { .name = "arizona-pwm" },
285 { .name = "wm5110-codec" }, 287 { .name = "wm5110-codec" },
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 {
78 78
79#define ARIZONA_NUM_IRQ 50 79#define ARIZONA_NUM_IRQ 50
80 80
81struct snd_soc_dapm_context;
82
81struct arizona { 83struct arizona {
82 struct regmap *regmap; 84 struct regmap *regmap;
83 struct device *dev; 85 struct device *dev;
@@ -98,6 +100,8 @@ struct arizona {
98 100
99 struct mutex clk_lock; 101 struct mutex clk_lock;
100 int clk32k_ref; 102 int clk32k_ref;
103
104 struct snd_soc_dapm_context *dapm;
101}; 105};
102 106
103int arizona_clk32k_enable(struct arizona *arizona); 107int arizona_clk32k_enable(struct arizona *arizona);
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 @@
62 62
63#define ARIZONA_MAX_OUTPUT 6 63#define ARIZONA_MAX_OUTPUT 6
64 64
65#define ARIZONA_HAP_ACT_ERM 0
66#define ARIZONA_HAP_ACT_LRA 2
67
65#define ARIZONA_MAX_PDM_SPK 2 68#define ARIZONA_MAX_PDM_SPK 2
66 69
67struct regulator_init_data; 70struct regulator_init_data;
@@ -114,6 +117,9 @@ struct arizona_pdata {
114 117
115 /** PDM speaker format */ 118 /** PDM speaker format */
116 unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK]; 119 unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK];
120
121 /** Haptic actuator type */
122 unsigned int hap_act;
117}; 123};
118 124
119#endif 125#endif
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
148 148
149config SND_SOC_WM_ADSP 149config SND_SOC_WM_ADSP
150 tristate 150 tristate
151 default y if SND_SOC_WM5102=y
151 default y if SND_SOC_WM2200=y 152 default y if SND_SOC_WM2200=y
153 default m if SND_SOC_WM5102=m
152 default m if SND_SOC_WM2200=m 154 default m if SND_SOC_WM2200=m
153 155
154config SND_SOC_AB8500_CODEC 156config SND_SOC_AB8500_CODEC
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 054967d8bac2..87cfaa3a6f0e 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,
380 case 49152000: 380 case 49152000:
381 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; 381 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
382 break; 382 break;
383 case 67737600:
384 case 73728000:
385 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
386 break;
387 case 90316800:
388 case 98304000:
389 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
390 break;
391 case 135475200:
392 case 147456000:
393 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
394 break;
383 default: 395 default:
384 return -EINVAL; 396 return -EINVAL;
385 } 397 }
@@ -925,6 +937,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
925 bool ena; 937 bool ena;
926 int ret; 938 int ret;
927 939
940 if (fll->fref == Fref && fll->fout == Fout)
941 return 0;
942
928 ret = regmap_read(arizona->regmap, fll->base + 1, &reg); 943 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
929 if (ret != 0) { 944 if (ret != 0) {
930 arizona_fll_err(fll, "Failed to read current state: %d\n", 945 arizona_fll_err(fll, "Failed to read current state: %d\n",
@@ -970,6 +985,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
970 if (ena) 985 if (ena)
971 pm_runtime_put_autosuspend(arizona->dev); 986 pm_runtime_put_autosuspend(arizona->dev);
972 987
988 fll->fref = Fref;
989 fll->fout = Fout;
990
973 return 0; 991 return 0;
974 } 992 }
975 993
@@ -1002,6 +1020,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1002 if (ret == 0) 1020 if (ret == 0)
1003 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1021 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1004 1022
1023 fll->fref = Fref;
1024 fll->fout = Fout;
1025
1005 return 0; 1026 return 0;
1006} 1027}
1007EXPORT_SYMBOL_GPL(arizona_set_fll); 1028EXPORT_SYMBOL_GPL(arizona_set_fll);
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 36ec64946120..84c415d335bd 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -17,6 +17,8 @@
17 17
18#include <sound/soc.h> 18#include <sound/soc.h>
19 19
20#include "wm_adsp.h"
21
20#define ARIZONA_CLK_SYSCLK 1 22#define ARIZONA_CLK_SYSCLK 1
21#define ARIZONA_CLK_ASYNCCLK 2 23#define ARIZONA_CLK_ASYNCCLK 2
22#define ARIZONA_CLK_OPCLK 3 24#define ARIZONA_CLK_OPCLK 3
@@ -46,15 +48,18 @@
46#define ARIZONA_MIXER_VOL_SHIFT 1 48#define ARIZONA_MIXER_VOL_SHIFT 1
47#define ARIZONA_MIXER_VOL_WIDTH 7 49#define ARIZONA_MIXER_VOL_WIDTH 7
48 50
49#define ARIZONA_MAX_DAI 3 51#define ARIZONA_MAX_DAI 4
52#define ARIZONA_MAX_ADSP 4
50 53
51struct arizona; 54struct arizona;
55struct wm_adsp;
52 56
53struct arizona_dai_priv { 57struct arizona_dai_priv {
54 int clk; 58 int clk;
55}; 59};
56 60
57struct arizona_priv { 61struct arizona_priv {
62 struct wm_adsp adsp[ARIZONA_MAX_ADSP];
58 struct arizona *arizona; 63 struct arizona *arizona;
59 int sysclk; 64 int sysclk;
60 int asyncclk; 65 int asyncclk;
@@ -89,19 +94,30 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
89 const struct snd_kcontrol_new name##_mux = \ 94 const struct snd_kcontrol_new name##_mux = \
90 SOC_DAPM_VALUE_ENUM("Route", name##_enum) 95 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
91 96
97#define ARIZONA_MUX_ENUMS(name, base_reg) \
98 static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \
99 static ARIZONA_MUX_CTL_DECL(name)
100
92#define ARIZONA_MIXER_ENUMS(name, base_reg) \ 101#define ARIZONA_MIXER_ENUMS(name, base_reg) \
93 static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ 102 ARIZONA_MUX_ENUMS(name##_in1, base_reg); \
94 static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ 103 ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \
95 static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ 104 ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \
96 static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ 105 ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6)
97 static ARIZONA_MUX_CTL_DECL(name##_in1); \ 106
98 static ARIZONA_MUX_CTL_DECL(name##_in2); \ 107#define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \
99 static ARIZONA_MUX_CTL_DECL(name##_in3); \ 108 ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \
100 static ARIZONA_MUX_CTL_DECL(name##_in4) 109 ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \
110 ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \
111 ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \
112 ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \
113 ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40)
101 114
102#define ARIZONA_MUX(name, ctrl) \ 115#define ARIZONA_MUX(name, ctrl) \
103 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) 116 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
104 117
118#define ARIZONA_MUX_WIDGETS(name, name_str) \
119 ARIZONA_MUX(name_str " Input", &name##_mux)
120
105#define ARIZONA_MIXER_WIDGETS(name, name_str) \ 121#define ARIZONA_MIXER_WIDGETS(name, name_str) \
106 ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ 122 ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \
107 ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ 123 ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \
@@ -109,6 +125,19 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
109 ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ 125 ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \
110 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) 126 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
111 127
128#define ARIZONA_DSP_WIDGETS(name, name_str) \
129 ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \
130 ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \
131 ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \
132 ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \
133 ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \
134 ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \
135 ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \
136 ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux)
137
138#define ARIZONA_MUX_ROUTES(name) \
139 ARIZONA_MIXER_INPUT_ROUTES(name " Input")
140
112#define ARIZONA_MIXER_ROUTES(widget, name) \ 141#define ARIZONA_MIXER_ROUTES(widget, name) \
113 { widget, NULL, name " Mixer" }, \ 142 { widget, NULL, name " Mixer" }, \
114 { name " Mixer", NULL, name " Input 1" }, \ 143 { name " Mixer", NULL, name " Input 1" }, \
@@ -120,6 +149,22 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
120 ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ 149 ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \
121 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") 150 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
122 151
152#define ARIZONA_DSP_ROUTES(name) \
153 { name, NULL, name " Aux 1" }, \
154 { name, NULL, name " Aux 2" }, \
155 { name, NULL, name " Aux 3" }, \
156 { name, NULL, name " Aux 4" }, \
157 { name, NULL, name " Aux 5" }, \
158 { name, NULL, name " Aux 6" }, \
159 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
160 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
161 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
162 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
163 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
164 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
165 ARIZONA_MIXER_ROUTES(name, name "L"), \
166 ARIZONA_MIXER_ROUTES(name, name "R")
167
123extern const struct soc_enum arizona_lhpf1_mode; 168extern const struct soc_enum arizona_lhpf1_mode;
124extern const struct soc_enum arizona_lhpf2_mode; 169extern const struct soc_enum arizona_lhpf2_mode;
125extern const struct soc_enum arizona_lhpf3_mode; 170extern const struct soc_enum arizona_lhpf3_mode;
@@ -146,6 +191,8 @@ struct arizona_fll {
146 unsigned int vco_mult; 191 unsigned int vco_mult;
147 struct completion lock; 192 struct completion lock;
148 struct completion ok; 193 struct completion ok;
194 unsigned int fref;
195 unsigned int fout;
149 196
150 char lock_name[ARIZONA_FLL_NAME_LEN]; 197 char lock_name[ARIZONA_FLL_NAME_LEN];
151 char clock_ok_name[ARIZONA_FLL_NAME_LEN]; 198 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 7394e73fa43c..53793b1849f7 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -31,6 +31,7 @@
31 31
32#include "arizona.h" 32#include "arizona.h"
33#include "wm5102.h" 33#include "wm5102.h"
34#include "wm_adsp.h"
34 35
35struct wm5102_priv { 36struct wm5102_priv {
36 struct arizona_priv core; 37 struct arizona_priv core;
@@ -42,6 +43,13 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); 43static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); 44static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44 45
46static const struct wm_adsp_region wm5102_dsp1_regions[] = {
47 { .type = WMFW_ADSP2_PM, .base = 0x100000 },
48 { .type = WMFW_ADSP2_ZM, .base = 0x180000 },
49 { .type = WMFW_ADSP2_XM, .base = 0x190000 },
50 { .type = WMFW_ADSP2_YM, .base = 0x1a8000 },
51};
52
45static const struct reg_default wm5102_sysclk_reva_patch[] = { 53static const struct reg_default wm5102_sysclk_reva_patch[] = {
46 { 0x3000, 0x2225 }, 54 { 0x3000, 0x2225 },
47 { 0x3001, 0x3a03 }, 55 { 0x3001, 0x3a03 },
@@ -687,6 +695,9 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
687ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), 695ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
688ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), 696ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
689 697
698ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
699ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
700
690SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), 701SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
691SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), 702SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
692SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), 703SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
@@ -708,14 +719,6 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
708ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), 719ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
709ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), 720ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
710 721
711SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
712 ARIZONA_OUT1_OSR_SHIFT, 1, 0),
713SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
714 ARIZONA_OUT2_OSR_SHIFT, 1, 0),
715SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
716 ARIZONA_OUT3_OSR_SHIFT, 1, 0),
717SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
718 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
719SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, 722SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
720 ARIZONA_OUT5_OSR_SHIFT, 1, 0), 723 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
721 724
@@ -745,17 +748,6 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
745 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 748 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
746 0xbf, 0, digital_tlv), 749 0xbf, 0, digital_tlv),
747 750
748SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
749 ARIZONA_OUTPUT_PATH_CONFIG_1R,
750 ARIZONA_OUT1L_PGA_VOL_SHIFT,
751 0x34, 0x40, 0, ana_tlv),
752SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
753 ARIZONA_OUTPUT_PATH_CONFIG_2R,
754 ARIZONA_OUT2L_PGA_VOL_SHIFT,
755 0x34, 0x40, 0, ana_tlv),
756SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
757 ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
758
759SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, 751SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
760 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), 752 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
761 753
@@ -819,11 +811,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
819ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); 811ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
820ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); 812ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
821 813
822ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); 814ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
823ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); 815ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
824ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); 816ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
825ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); 817ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
818
819ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE);
820ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE);
826 821
822ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE);
827 823
828static const char *wm5102_aec_loopback_texts[] = { 824static const char *wm5102_aec_loopback_texts[] = {
829 "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", 825 "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
@@ -864,6 +860,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
864 860
865SND_SOC_DAPM_SIGGEN("TONE"), 861SND_SOC_DAPM_SIGGEN("TONE"),
866SND_SOC_DAPM_SIGGEN("NOISE"), 862SND_SOC_DAPM_SIGGEN("NOISE"),
863SND_SOC_DAPM_SIGGEN("HAPTICS"),
867 864
868SND_SOC_DAPM_INPUT("IN1L"), 865SND_SOC_DAPM_INPUT("IN1L"),
869SND_SOC_DAPM_INPUT("IN1R"), 866SND_SOC_DAPM_INPUT("IN1R"),
@@ -894,9 +891,9 @@ SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
894SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, 891SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
895 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 892 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
896SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, 893SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
897 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 894 ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0),
898SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, 895SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
899 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 896 ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0),
900 897
901SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, 898SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
902 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), 899 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
@@ -996,6 +993,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
996SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, 993SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
997 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), 994 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
998 995
996ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
997
999SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, 998SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
1000 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), 999 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
1001 1000
@@ -1071,10 +1070,12 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1071ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), 1070ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1072ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), 1071ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1073 1072
1074ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), 1073ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
1075ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), 1074ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
1076ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), 1075ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
1077ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), 1076ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
1077
1078WM_ADSP2("DSP1", 0),
1078 1079
1079SND_SOC_DAPM_OUTPUT("HPOUT1L"), 1080SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1080SND_SOC_DAPM_OUTPUT("HPOUT1R"), 1081SND_SOC_DAPM_OUTPUT("HPOUT1R"),
@@ -1094,6 +1095,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
1094 { name, "Noise Generator", "Noise Generator" }, \ 1095 { name, "Noise Generator", "Noise Generator" }, \
1095 { name, "Tone Generator 1", "Tone Generator 1" }, \ 1096 { name, "Tone Generator 1", "Tone Generator 1" }, \
1096 { name, "Tone Generator 2", "Tone Generator 2" }, \ 1097 { name, "Tone Generator 2", "Tone Generator 2" }, \
1098 { name, "Haptics", "HAPTICS" }, \
1097 { name, "AEC", "AEC Loopback" }, \ 1099 { name, "AEC", "AEC Loopback" }, \
1098 { name, "IN1L", "IN1L PGA" }, \ 1100 { name, "IN1L", "IN1L PGA" }, \
1099 { name, "IN1R", "IN1R PGA" }, \ 1101 { name, "IN1R", "IN1R PGA" }, \
@@ -1127,7 +1129,13 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
1127 { name, "ASRC1L", "ASRC1L" }, \ 1129 { name, "ASRC1L", "ASRC1L" }, \
1128 { name, "ASRC1R", "ASRC1R" }, \ 1130 { name, "ASRC1R", "ASRC1R" }, \
1129 { name, "ASRC2L", "ASRC2L" }, \ 1131 { name, "ASRC2L", "ASRC2L" }, \
1130 { name, "ASRC2R", "ASRC2R" } 1132 { name, "ASRC2R", "ASRC2R" }, \
1133 { name, "DSP1.1", "DSP1" }, \
1134 { name, "DSP1.2", "DSP1" }, \
1135 { name, "DSP1.3", "DSP1" }, \
1136 { name, "DSP1.4", "DSP1" }, \
1137 { name, "DSP1.5", "DSP1" }, \
1138 { name, "DSP1.6", "DSP1" }
1131 1139
1132static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { 1140static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1133 { "AIF2 Capture", NULL, "DBVDD2" }, 1141 { "AIF2 Capture", NULL, "DBVDD2" },
@@ -1213,6 +1221,11 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1213 { "IN3L PGA", NULL, "IN3L" }, 1221 { "IN3L PGA", NULL, "IN3L" },
1214 { "IN3R PGA", NULL, "IN3R" }, 1222 { "IN3R PGA", NULL, "IN3R" },
1215 1223
1224 { "ASRC1L", NULL, "ASRC1L Input" },
1225 { "ASRC1R", NULL, "ASRC1R Input" },
1226 { "ASRC2L", NULL, "ASRC2L Input" },
1227 { "ASRC2R", NULL, "ASRC2R Input" },
1228
1216 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), 1229 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1217 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), 1230 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1218 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), 1231 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
@@ -1255,10 +1268,12 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1255 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), 1268 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
1256 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), 1269 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
1257 1270
1258 ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), 1271 ARIZONA_MUX_ROUTES("ASRC1L"),
1259 ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), 1272 ARIZONA_MUX_ROUTES("ASRC1R"),
1260 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), 1273 ARIZONA_MUX_ROUTES("ASRC2L"),
1261 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), 1274 ARIZONA_MUX_ROUTES("ASRC2R"),
1275
1276 ARIZONA_DSP_ROUTES("DSP1"),
1262 1277
1263 { "AEC Loopback", "HPOUT1L", "OUT1L" }, 1278 { "AEC Loopback", "HPOUT1L", "OUT1L" },
1264 { "AEC Loopback", "HPOUT1R", "OUT1R" }, 1279 { "AEC Loopback", "HPOUT1R", "OUT1R" },
@@ -1377,9 +1392,28 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
1377static int wm5102_codec_probe(struct snd_soc_codec *codec) 1392static int wm5102_codec_probe(struct snd_soc_codec *codec)
1378{ 1393{
1379 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); 1394 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
1395 int ret;
1380 1396
1381 codec->control_data = priv->core.arizona->regmap; 1397 codec->control_data = priv->core.arizona->regmap;
1382 return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); 1398
1399 ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
1400 if (ret != 0)
1401 return ret;
1402
1403 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1404
1405 priv->core.arizona->dapm = &codec->dapm;
1406
1407 return 0;
1408}
1409
1410static int wm5102_codec_remove(struct snd_soc_codec *codec)
1411{
1412 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
1413
1414 priv->core.arizona->dapm = NULL;
1415
1416 return 0;
1383} 1417}
1384 1418
1385#define WM5102_DIG_VU 0x0200 1419#define WM5102_DIG_VU 0x0200
@@ -1406,6 +1440,7 @@ static unsigned int wm5102_digital_vu[] = {
1406 1440
1407static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { 1441static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
1408 .probe = wm5102_codec_probe, 1442 .probe = wm5102_codec_probe,
1443 .remove = wm5102_codec_remove,
1409 1444
1410 .idle_bias_off = true, 1445 .idle_bias_off = true,
1411 1446
@@ -1424,7 +1459,7 @@ static int __devinit wm5102_probe(struct platform_device *pdev)
1424{ 1459{
1425 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 1460 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1426 struct wm5102_priv *wm5102; 1461 struct wm5102_priv *wm5102;
1427 int i; 1462 int i, ret;
1428 1463
1429 wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), 1464 wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv),
1430 GFP_KERNEL); 1465 GFP_KERNEL);
@@ -1434,6 +1469,19 @@ static int __devinit wm5102_probe(struct platform_device *pdev)
1434 1469
1435 wm5102->core.arizona = arizona; 1470 wm5102->core.arizona = arizona;
1436 1471
1472 wm5102->core.adsp[0].part = "wm5102";
1473 wm5102->core.adsp[0].num = 1;
1474 wm5102->core.adsp[0].type = WMFW_ADSP2;
1475 wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1;
1476 wm5102->core.adsp[0].dev = arizona->dev;
1477 wm5102->core.adsp[0].regmap = arizona->regmap;
1478 wm5102->core.adsp[0].mem = wm5102_dsp1_regions;
1479 wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions);
1480
1481 ret = wm_adsp2_init(&wm5102->core.adsp[0], true);
1482 if (ret != 0)
1483 return ret;
1484
1437 for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) 1485 for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++)
1438 wm5102->fll[i].vco_mult = 1; 1486 wm5102->fll[i].vco_mult = 1;
1439 1487
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 9211e4192f71..2a075ad00d5b 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);
308ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); 308ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
309ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); 309ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
310 310
311ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); 311ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
312ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); 312ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
313ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); 313ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
314ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); 314ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
315 315
316static const char *wm5110_aec_loopback_texts[] = { 316static const char *wm5110_aec_loopback_texts[] = {
317 "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", 317 "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
@@ -352,6 +352,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
352 352
353SND_SOC_DAPM_SIGGEN("TONE"), 353SND_SOC_DAPM_SIGGEN("TONE"),
354SND_SOC_DAPM_SIGGEN("NOISE"), 354SND_SOC_DAPM_SIGGEN("NOISE"),
355SND_SOC_DAPM_SIGGEN("HAPTICS"),
355 356
356SND_SOC_DAPM_INPUT("IN1L"), 357SND_SOC_DAPM_INPUT("IN1L"),
357SND_SOC_DAPM_INPUT("IN1R"), 358SND_SOC_DAPM_INPUT("IN1R"),
@@ -585,10 +586,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
585ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), 586ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
586ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), 587ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
587 588
588ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), 589ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
589ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), 590ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
590ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), 591ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
591ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), 592ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
592 593
593SND_SOC_DAPM_OUTPUT("HPOUT1L"), 594SND_SOC_DAPM_OUTPUT("HPOUT1L"),
594SND_SOC_DAPM_OUTPUT("HPOUT1R"), 595SND_SOC_DAPM_OUTPUT("HPOUT1R"),
@@ -610,6 +611,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
610 { name, "Noise Generator", "Noise Generator" }, \ 611 { name, "Noise Generator", "Noise Generator" }, \
611 { name, "Tone Generator 1", "Tone Generator 1" }, \ 612 { name, "Tone Generator 1", "Tone Generator 1" }, \
612 { name, "Tone Generator 2", "Tone Generator 2" }, \ 613 { name, "Tone Generator 2", "Tone Generator 2" }, \
614 { name, "Haptics", "HAPTICS" }, \
613 { name, "AEC", "AEC Loopback" }, \ 615 { name, "AEC", "AEC Loopback" }, \
614 { name, "IN1L", "IN1L PGA" }, \ 616 { name, "IN1L", "IN1L PGA" }, \
615 { name, "IN1R", "IN1R PGA" }, \ 617 { name, "IN1R", "IN1R PGA" }, \
@@ -786,10 +788,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
786 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), 788 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
787 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), 789 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
788 790
789 ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), 791 ARIZONA_MUX_ROUTES("ASRC1L"),
790 ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), 792 ARIZONA_MUX_ROUTES("ASRC1R"),
791 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), 793 ARIZONA_MUX_ROUTES("ASRC2L"),
792 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), 794 ARIZONA_MUX_ROUTES("ASRC2R"),
793 795
794 { "HPOUT1L", NULL, "OUT1L" }, 796 { "HPOUT1L", NULL, "OUT1L" },
795 { "HPOUT1R", NULL, "OUT1R" }, 797 { "HPOUT1R", NULL, "OUT1R" },
@@ -902,9 +904,29 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
902static int wm5110_codec_probe(struct snd_soc_codec *codec) 904static int wm5110_codec_probe(struct snd_soc_codec *codec)
903{ 905{
904 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); 906 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
907 int ret;
905 908
906 codec->control_data = priv->core.arizona->regmap; 909 codec->control_data = priv->core.arizona->regmap;
907 return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); 910 priv->core.arizona->dapm = &codec->dapm;
911
912 ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
913 if (ret != 0)
914 return ret;
915
916 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
917
918 priv->core.arizona->dapm = &codec->dapm;
919
920 return 0;
921}
922
923static int wm5110_codec_remove(struct snd_soc_codec *codec)
924{
925 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
926
927 priv->core.arizona->dapm = NULL;
928
929 return 0;
908} 930}
909 931
910#define WM5110_DIG_VU 0x0200 932#define WM5110_DIG_VU 0x0200
@@ -935,6 +957,7 @@ static unsigned int wm5110_digital_vu[] = {
935 957
936static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { 958static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
937 .probe = wm5110_codec_probe, 959 .probe = wm5110_codec_probe,
960 .remove = wm5110_codec_remove,
938 961
939 .idle_bias_off = true, 962 .idle_bias_off = true,
940 963