diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-05-29 22:54:18 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-05-29 22:54:18 -0400 |
commit | d21685ec258f803d3badae5eae821383a34815a9 (patch) | |
tree | 7ab60a2a5d557a4f345b01a79ca2f877c06d9b92 /sound | |
parent | 74ab24af4fe165de5af01d0507250dd099f096b0 (diff) | |
parent | ea02c63d57d7ec099f66ddb2942b4022e865cd5f (diff) |
Merge branch 'for-2.6.40' into for-2.6.41
Diffstat (limited to 'sound')
40 files changed, 1271 insertions, 247 deletions
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 28afbbf69ce0..95572d290c27 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
@@ -146,7 +146,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
146 | "at91sam9g20ek_wm8731 " | 146 | "at91sam9g20ek_wm8731 " |
147 | ": at91sam9g20ek_wm8731_init() called\n"); | 147 | ": at91sam9g20ek_wm8731_init() called\n"); |
148 | 148 | ||
149 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, | 149 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_MCLK, |
150 | MCLK_RATE, SND_SOC_CLOCK_IN); | 150 | MCLK_RATE, SND_SOC_CLOCK_IN); |
151 | if (ret < 0) { | 151 | if (ret < 0) { |
152 | printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret); | 152 | printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret); |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 2a6971891d31..98175a096df2 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -20,6 +20,7 @@ config SND_SOC_ALL_CODECS | |||
20 | select SND_SOC_ADS117X | 20 | select SND_SOC_ADS117X |
21 | select SND_SOC_AK4104 if SPI_MASTER | 21 | select SND_SOC_AK4104 if SPI_MASTER |
22 | select SND_SOC_AK4535 if I2C | 22 | select SND_SOC_AK4535 if I2C |
23 | select SND_SOC_AK4641 if I2C | ||
23 | select SND_SOC_AK4642 if I2C | 24 | select SND_SOC_AK4642 if I2C |
24 | select SND_SOC_AK4671 if I2C | 25 | select SND_SOC_AK4671 if I2C |
25 | select SND_SOC_ALC5623 if I2C | 26 | select SND_SOC_ALC5623 if I2C |
@@ -139,6 +140,9 @@ config SND_SOC_AK4104 | |||
139 | config SND_SOC_AK4535 | 140 | config SND_SOC_AK4535 |
140 | tristate | 141 | tristate |
141 | 142 | ||
143 | config SND_SOC_AK4641 | ||
144 | tristate | ||
145 | |||
142 | config SND_SOC_AK4642 | 146 | config SND_SOC_AK4642 |
143 | tristate | 147 | tristate |
144 | 148 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 4cb2f42dbffa..fd8558406ef0 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -7,6 +7,7 @@ snd-soc-ad73311-objs := ad73311.o | |||
7 | snd-soc-ads117x-objs := ads117x.o | 7 | snd-soc-ads117x-objs := ads117x.o |
8 | snd-soc-ak4104-objs := ak4104.o | 8 | snd-soc-ak4104-objs := ak4104.o |
9 | snd-soc-ak4535-objs := ak4535.o | 9 | snd-soc-ak4535-objs := ak4535.o |
10 | snd-soc-ak4641-objs := ak4641.o | ||
10 | snd-soc-ak4642-objs := ak4642.o | 11 | snd-soc-ak4642-objs := ak4642.o |
11 | snd-soc-ak4671-objs := ak4671.o | 12 | snd-soc-ak4671-objs := ak4671.o |
12 | snd-soc-cq93vc-objs := cq93vc.o | 13 | snd-soc-cq93vc-objs := cq93vc.o |
@@ -97,6 +98,7 @@ obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o | |||
97 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o | 98 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o |
98 | obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o | 99 | obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o |
99 | obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o | 100 | obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o |
101 | obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o | ||
100 | obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o | 102 | obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o |
101 | obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o | 103 | obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o |
102 | obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o | 104 | obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o |
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c new file mode 100644 index 000000000000..ed96f247c2da --- /dev/null +++ b/sound/soc/codecs/ak4641.c | |||
@@ -0,0 +1,664 @@ | |||
1 | /* | ||
2 | * ak4641.c -- AK4641 ALSA Soc Audio driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Harald Welte <laforge@gnufiish.org> | ||
5 | * Copyright (C) 2011 Dmitry Artamonow <mad_soft@inbox.ru> | ||
6 | * | ||
7 | * Based on ak4535.c by Richard Purdie | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/initval.h> | ||
27 | #include <sound/tlv.h> | ||
28 | #include <sound/ak4641.h> | ||
29 | |||
30 | #include "ak4641.h" | ||
31 | |||
32 | /* codec private data */ | ||
33 | struct ak4641_priv { | ||
34 | struct snd_soc_codec *codec; | ||
35 | unsigned int sysclk; | ||
36 | int deemph; | ||
37 | int playback_fs; | ||
38 | }; | ||
39 | |||
40 | /* | ||
41 | * ak4641 register cache | ||
42 | */ | ||
43 | static const u8 ak4641_reg[AK4641_CACHEREGNUM] = { | ||
44 | 0x00, 0x80, 0x00, 0x80, | ||
45 | 0x02, 0x00, 0x11, 0x05, | ||
46 | 0x00, 0x00, 0x36, 0x10, | ||
47 | 0x00, 0x00, 0x57, 0x00, | ||
48 | 0x88, 0x88, 0x08, 0x08 | ||
49 | }; | ||
50 | |||
51 | static const int deemph_settings[] = {44100, 0, 48000, 32000}; | ||
52 | |||
53 | static int ak4641_set_deemph(struct snd_soc_codec *codec) | ||
54 | { | ||
55 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | ||
56 | int i, best = 0; | ||
57 | |||
58 | for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) { | ||
59 | /* if deemphasis is on, select the nearest available rate */ | ||
60 | if (ak4641->deemph && deemph_settings[i] != 0 && | ||
61 | abs(deemph_settings[i] - ak4641->playback_fs) < | ||
62 | abs(deemph_settings[best] - ak4641->playback_fs)) | ||
63 | best = i; | ||
64 | |||
65 | if (!ak4641->deemph && deemph_settings[i] == 0) | ||
66 | best = i; | ||
67 | } | ||
68 | |||
69 | dev_dbg(codec->dev, "Set deemphasis %d\n", best); | ||
70 | |||
71 | return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best); | ||
72 | } | ||
73 | |||
74 | static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, | ||
75 | struct snd_ctl_elem_value *ucontrol) | ||
76 | { | ||
77 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
78 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | ||
79 | int deemph = ucontrol->value.enumerated.item[0]; | ||
80 | |||
81 | if (deemph > 1) | ||
82 | return -EINVAL; | ||
83 | |||
84 | ak4641->deemph = deemph; | ||
85 | |||
86 | return ak4641_set_deemph(codec); | ||
87 | } | ||
88 | |||
89 | static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, | ||
90 | struct snd_ctl_elem_value *ucontrol) | ||
91 | { | ||
92 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
93 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | ||
94 | |||
95 | ucontrol->value.enumerated.item[0] = ak4641->deemph; | ||
96 | return 0; | ||
97 | }; | ||
98 | |||
99 | static const char *ak4641_mono_out[] = {"(L + R)/2", "Hi-Z"}; | ||
100 | static const char *ak4641_hp_out[] = {"Stereo", "Mono"}; | ||
101 | static const char *ak4641_mic_select[] = {"Internal", "External"}; | ||
102 | static const char *ak4641_mic_or_dac[] = {"Microphone", "Voice DAC"}; | ||
103 | |||
104 | |||
105 | static const DECLARE_TLV_DB_SCALE(mono_gain_tlv, -1700, 2300, 0); | ||
106 | static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 2000, 0); | ||
107 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1050, 150, 0); | ||
108 | static const DECLARE_TLV_DB_SCALE(master_tlv, -12750, 50, 0); | ||
109 | static const DECLARE_TLV_DB_SCALE(mic_stereo_sidetone_tlv, -2700, 300, 0); | ||
110 | static const DECLARE_TLV_DB_SCALE(mic_mono_sidetone_tlv, -400, 400, 0); | ||
111 | static const DECLARE_TLV_DB_SCALE(capture_tlv, -800, 50, 0); | ||
112 | static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0); | ||
113 | static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0); | ||
114 | |||
115 | |||
116 | static const struct soc_enum ak4641_mono_out_enum = | ||
117 | SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out); | ||
118 | static const struct soc_enum ak4641_hp_out_enum = | ||
119 | SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out); | ||
120 | static const struct soc_enum ak4641_mic_select_enum = | ||
121 | SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select); | ||
122 | static const struct soc_enum ak4641_mic_or_dac_enum = | ||
123 | SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac); | ||
124 | |||
125 | static const struct snd_kcontrol_new ak4641_snd_controls[] = { | ||
126 | SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum), | ||
127 | SOC_SINGLE_TLV("Mono 1 Gain Volume", AK4641_SIG1, 7, 1, 1, | ||
128 | mono_gain_tlv), | ||
129 | SOC_ENUM("Headphone Output", ak4641_hp_out_enum), | ||
130 | SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, | ||
131 | ak4641_get_deemph, ak4641_put_deemph), | ||
132 | |||
133 | SOC_SINGLE_TLV("Mic Boost Volume", AK4641_MIC, 0, 1, 0, mic_boost_tlv), | ||
134 | |||
135 | SOC_SINGLE("ALC Operation Time", AK4641_TIMER, 0, 3, 0), | ||
136 | SOC_SINGLE("ALC Recovery Time", AK4641_TIMER, 2, 3, 0), | ||
137 | SOC_SINGLE("ALC ZC Time", AK4641_TIMER, 4, 3, 0), | ||
138 | |||
139 | SOC_SINGLE("ALC 1 Switch", AK4641_ALC1, 5, 1, 0), | ||
140 | |||
141 | SOC_SINGLE_TLV("ALC Volume", AK4641_ALC2, 0, 71, 0, alc_tlv), | ||
142 | SOC_SINGLE("Left Out Enable Switch", AK4641_SIG2, 1, 1, 0), | ||
143 | SOC_SINGLE("Right Out Enable Switch", AK4641_SIG2, 0, 1, 0), | ||
144 | |||
145 | SOC_SINGLE_TLV("Capture Volume", AK4641_PGA, 0, 71, 0, capture_tlv), | ||
146 | |||
147 | SOC_DOUBLE_R_TLV("Master Playback Volume", AK4641_LATT, | ||
148 | AK4641_RATT, 0, 255, 1, master_tlv), | ||
149 | |||
150 | SOC_SINGLE_TLV("AUX In Volume", AK4641_VOL, 0, 15, 0, aux_in_tlv), | ||
151 | |||
152 | SOC_SINGLE("Equalizer Switch", AK4641_DAC, 2, 1, 0), | ||
153 | SOC_SINGLE_TLV("EQ1 100 Hz Volume", AK4641_EQLO, 0, 15, 1, eq_tlv), | ||
154 | SOC_SINGLE_TLV("EQ2 250 Hz Volume", AK4641_EQLO, 4, 15, 1, eq_tlv), | ||
155 | SOC_SINGLE_TLV("EQ3 1 kHz Volume", AK4641_EQMID, 0, 15, 1, eq_tlv), | ||
156 | SOC_SINGLE_TLV("EQ4 3.5 kHz Volume", AK4641_EQMID, 4, 15, 1, eq_tlv), | ||
157 | SOC_SINGLE_TLV("EQ5 10 kHz Volume", AK4641_EQHI, 0, 15, 1, eq_tlv), | ||
158 | }; | ||
159 | |||
160 | /* Mono 1 Mixer */ | ||
161 | static const struct snd_kcontrol_new ak4641_mono1_mixer_controls[] = { | ||
162 | SOC_DAPM_SINGLE_TLV("Mic Mono Sidetone Volume", AK4641_VOL, 7, 1, 0, | ||
163 | mic_mono_sidetone_tlv), | ||
164 | SOC_DAPM_SINGLE("Mic Mono Sidetone Switch", AK4641_SIG1, 4, 1, 0), | ||
165 | SOC_DAPM_SINGLE("Mono Playback Switch", AK4641_SIG1, 5, 1, 0), | ||
166 | }; | ||
167 | |||
168 | /* Stereo Mixer */ | ||
169 | static const struct snd_kcontrol_new ak4641_stereo_mixer_controls[] = { | ||
170 | SOC_DAPM_SINGLE_TLV("Mic Sidetone Volume", AK4641_VOL, 4, 7, 0, | ||
171 | mic_stereo_sidetone_tlv), | ||
172 | SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4641_SIG2, 4, 1, 0), | ||
173 | SOC_DAPM_SINGLE("Playback Switch", AK4641_SIG2, 7, 1, 0), | ||
174 | SOC_DAPM_SINGLE("Aux Bypass Switch", AK4641_SIG2, 5, 1, 0), | ||
175 | }; | ||
176 | |||
177 | /* Input Mixer */ | ||
178 | static const struct snd_kcontrol_new ak4641_input_mixer_controls[] = { | ||
179 | SOC_DAPM_SINGLE("Mic Capture Switch", AK4641_MIC, 2, 1, 0), | ||
180 | SOC_DAPM_SINGLE("Aux Capture Switch", AK4641_MIC, 5, 1, 0), | ||
181 | }; | ||
182 | |||
183 | /* Mic mux */ | ||
184 | static const struct snd_kcontrol_new ak4641_mic_mux_control = | ||
185 | SOC_DAPM_ENUM("Mic Select", ak4641_mic_select_enum); | ||
186 | |||
187 | /* Input mux */ | ||
188 | static const struct snd_kcontrol_new ak4641_input_mux_control = | ||
189 | SOC_DAPM_ENUM("Input Select", ak4641_mic_or_dac_enum); | ||
190 | |||
191 | /* mono 2 switch */ | ||
192 | static const struct snd_kcontrol_new ak4641_mono2_control = | ||
193 | SOC_DAPM_SINGLE("Switch", AK4641_SIG1, 0, 1, 0); | ||
194 | |||
195 | /* ak4641 dapm widgets */ | ||
196 | static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = { | ||
197 | SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0, | ||
198 | &ak4641_stereo_mixer_controls[0], | ||
199 | ARRAY_SIZE(ak4641_stereo_mixer_controls)), | ||
200 | SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0, | ||
201 | &ak4641_mono1_mixer_controls[0], | ||
202 | ARRAY_SIZE(ak4641_mono1_mixer_controls)), | ||
203 | SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, | ||
204 | &ak4641_input_mixer_controls[0], | ||
205 | ARRAY_SIZE(ak4641_input_mixer_controls)), | ||
206 | SND_SOC_DAPM_MUX("Mic Mux", SND_SOC_NOPM, 0, 0, | ||
207 | &ak4641_mic_mux_control), | ||
208 | SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, | ||
209 | &ak4641_input_mux_control), | ||
210 | SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0, | ||
211 | &ak4641_mono2_control), | ||
212 | |||
213 | SND_SOC_DAPM_OUTPUT("LOUT"), | ||
214 | SND_SOC_DAPM_OUTPUT("ROUT"), | ||
215 | SND_SOC_DAPM_OUTPUT("MOUT1"), | ||
216 | SND_SOC_DAPM_OUTPUT("MOUT2"), | ||
217 | SND_SOC_DAPM_OUTPUT("MICOUT"), | ||
218 | |||
219 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", AK4641_PM1, 0, 0), | ||
220 | SND_SOC_DAPM_PGA("Mic", AK4641_PM1, 1, 0, NULL, 0), | ||
221 | SND_SOC_DAPM_PGA("AUX In", AK4641_PM1, 2, 0, NULL, 0), | ||
222 | SND_SOC_DAPM_PGA("Mono Out", AK4641_PM1, 3, 0, NULL, 0), | ||
223 | SND_SOC_DAPM_PGA("Line Out", AK4641_PM1, 4, 0, NULL, 0), | ||
224 | |||
225 | SND_SOC_DAPM_DAC("DAC", "HiFi Playback", AK4641_PM2, 0, 0), | ||
226 | SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0), | ||
227 | |||
228 | SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0), | ||
229 | SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0), | ||
230 | |||
231 | SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0), | ||
232 | SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0), | ||
233 | |||
234 | SND_SOC_DAPM_INPUT("MICIN"), | ||
235 | SND_SOC_DAPM_INPUT("MICEXT"), | ||
236 | SND_SOC_DAPM_INPUT("AUX"), | ||
237 | SND_SOC_DAPM_INPUT("AIN"), | ||
238 | }; | ||
239 | |||
240 | static const struct snd_soc_dapm_route ak4641_audio_map[] = { | ||
241 | /* Stereo Mixer */ | ||
242 | {"Stereo Mixer", "Playback Switch", "DAC"}, | ||
243 | {"Stereo Mixer", "Mic Sidetone Switch", "Input Mux"}, | ||
244 | {"Stereo Mixer", "Aux Bypass Switch", "AUX In"}, | ||
245 | |||
246 | /* Mono 1 Mixer */ | ||
247 | {"Mono1 Mixer", "Mic Mono Sidetone Switch", "Input Mux"}, | ||
248 | {"Mono1 Mixer", "Mono Playback Switch", "DAC"}, | ||
249 | |||
250 | /* Mic */ | ||
251 | {"Mic", NULL, "AIN"}, | ||
252 | {"Mic Mux", "Internal", "Mic Int Bias"}, | ||
253 | {"Mic Mux", "External", "Mic Ext Bias"}, | ||
254 | {"Mic Int Bias", NULL, "MICIN"}, | ||
255 | {"Mic Ext Bias", NULL, "MICEXT"}, | ||
256 | {"MICOUT", NULL, "Mic Mux"}, | ||
257 | |||
258 | /* Input Mux */ | ||
259 | {"Input Mux", "Microphone", "Mic"}, | ||
260 | {"Input Mux", "Voice DAC", "Voice DAC"}, | ||
261 | |||
262 | /* Line Out */ | ||
263 | {"LOUT", NULL, "Line Out"}, | ||
264 | {"ROUT", NULL, "Line Out"}, | ||
265 | {"Line Out", NULL, "Stereo Mixer"}, | ||
266 | |||
267 | /* Mono 1 Out */ | ||
268 | {"MOUT1", NULL, "Mono Out"}, | ||
269 | {"Mono Out", NULL, "Mono1 Mixer"}, | ||
270 | |||
271 | /* Mono 2 Out */ | ||
272 | {"MOUT2", NULL, "Mono 2 Enable"}, | ||
273 | {"Mono 2 Enable", "Switch", "Mono Out 2"}, | ||
274 | {"Mono Out 2", NULL, "Stereo Mixer"}, | ||
275 | |||
276 | {"Voice ADC", NULL, "Mono 2 Enable"}, | ||
277 | |||
278 | /* Aux In */ | ||
279 | {"AUX In", NULL, "AUX"}, | ||
280 | |||
281 | /* ADC */ | ||
282 | {"ADC", NULL, "Input Mixer"}, | ||
283 | {"Input Mixer", "Mic Capture Switch", "Mic"}, | ||
284 | {"Input Mixer", "Aux Capture Switch", "AUX In"}, | ||
285 | }; | ||
286 | |||
287 | static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
288 | int clk_id, unsigned int freq, int dir) | ||
289 | { | ||
290 | struct snd_soc_codec *codec = codec_dai->codec; | ||
291 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | ||
292 | |||
293 | ak4641->sysclk = freq; | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream, | ||
298 | struct snd_pcm_hw_params *params, | ||
299 | struct snd_soc_dai *dai) | ||
300 | { | ||
301 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
302 | struct snd_soc_codec *codec = rtd->codec; | ||
303 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | ||
304 | int rate = params_rate(params), fs = 256; | ||
305 | u8 mode2; | ||
306 | |||
307 | if (rate) | ||
308 | fs = ak4641->sysclk / rate; | ||
309 | else | ||
310 | return -EINVAL; | ||
311 | |||
312 | /* set fs */ | ||
313 | switch (fs) { | ||
314 | case 1024: | ||
315 | mode2 = (0x2 << 5); | ||
316 | break; | ||
317 | case 512: | ||
318 | mode2 = (0x1 << 5); | ||
319 | break; | ||
320 | case 256: | ||
321 | mode2 = (0x0 << 5); | ||
322 | break; | ||
323 | default: | ||
324 | dev_err(codec->dev, "Error: unsupported fs=%d\n", fs); | ||
325 | return -EINVAL; | ||
326 | } | ||
327 | |||
328 | snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2); | ||
329 | |||
330 | /* Update de-emphasis filter for the new rate */ | ||
331 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
332 | ak4641->playback_fs = rate; | ||
333 | ak4641_set_deemph(codec); | ||
334 | }; | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
340 | unsigned int fmt) | ||
341 | { | ||
342 | struct snd_soc_codec *codec = codec_dai->codec; | ||
343 | u8 btif; | ||
344 | |||
345 | /* interface format */ | ||
346 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
347 | case SND_SOC_DAIFMT_I2S: | ||
348 | btif = (0x3 << 5); | ||
349 | break; | ||
350 | case SND_SOC_DAIFMT_LEFT_J: | ||
351 | btif = (0x2 << 5); | ||
352 | break; | ||
353 | case SND_SOC_DAIFMT_DSP_A: /* MSB after FRM */ | ||
354 | btif = (0x0 << 5); | ||
355 | break; | ||
356 | case SND_SOC_DAIFMT_DSP_B: /* MSB during FRM */ | ||
357 | btif = (0x1 << 5); | ||
358 | break; | ||
359 | default: | ||
360 | return -EINVAL; | ||
361 | } | ||
362 | |||
363 | return snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif); | ||
364 | } | ||
365 | |||
366 | static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
367 | unsigned int fmt) | ||
368 | { | ||
369 | struct snd_soc_codec *codec = codec_dai->codec; | ||
370 | u8 mode1 = 0; | ||
371 | |||
372 | /* interface format */ | ||
373 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
374 | case SND_SOC_DAIFMT_I2S: | ||
375 | mode1 = 0x02; | ||
376 | break; | ||
377 | case SND_SOC_DAIFMT_LEFT_J: | ||
378 | mode1 = 0x01; | ||
379 | break; | ||
380 | default: | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | |||
384 | return snd_soc_write(codec, AK4641_MODE1, mode1); | ||
385 | } | ||
386 | |||
387 | static int ak4641_mute(struct snd_soc_dai *dai, int mute) | ||
388 | { | ||
389 | struct snd_soc_codec *codec = dai->codec; | ||
390 | |||
391 | return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0); | ||
392 | } | ||
393 | |||
394 | static int ak4641_set_bias_level(struct snd_soc_codec *codec, | ||
395 | enum snd_soc_bias_level level) | ||
396 | { | ||
397 | struct ak4641_platform_data *pdata = codec->dev->platform_data; | ||
398 | int ret; | ||
399 | |||
400 | switch (level) { | ||
401 | case SND_SOC_BIAS_ON: | ||
402 | /* unmute */ | ||
403 | snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0); | ||
404 | break; | ||
405 | case SND_SOC_BIAS_PREPARE: | ||
406 | /* mute */ | ||
407 | snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20); | ||
408 | break; | ||
409 | case SND_SOC_BIAS_STANDBY: | ||
410 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
411 | if (pdata && gpio_is_valid(pdata->gpio_power)) | ||
412 | gpio_set_value(pdata->gpio_power, 1); | ||
413 | mdelay(1); | ||
414 | if (pdata && gpio_is_valid(pdata->gpio_npdn)) | ||
415 | gpio_set_value(pdata->gpio_npdn, 1); | ||
416 | mdelay(1); | ||
417 | |||
418 | ret = snd_soc_cache_sync(codec); | ||
419 | if (ret) { | ||
420 | dev_err(codec->dev, | ||
421 | "Failed to sync cache: %d\n", ret); | ||
422 | return ret; | ||
423 | } | ||
424 | } | ||
425 | snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80); | ||
426 | snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0); | ||
427 | break; | ||
428 | case SND_SOC_BIAS_OFF: | ||
429 | snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0); | ||
430 | if (pdata && gpio_is_valid(pdata->gpio_npdn)) | ||
431 | gpio_set_value(pdata->gpio_npdn, 0); | ||
432 | if (pdata && gpio_is_valid(pdata->gpio_power)) | ||
433 | gpio_set_value(pdata->gpio_power, 0); | ||
434 | codec->cache_sync = 1; | ||
435 | break; | ||
436 | } | ||
437 | codec->dapm.bias_level = level; | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | #define AK4641_RATES (SNDRV_PCM_RATE_8000_48000) | ||
442 | #define AK4641_RATES_BT (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | ||
443 | SNDRV_PCM_RATE_16000) | ||
444 | #define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) | ||
445 | |||
446 | static struct snd_soc_dai_ops ak4641_i2s_dai_ops = { | ||
447 | .hw_params = ak4641_i2s_hw_params, | ||
448 | .set_fmt = ak4641_i2s_set_dai_fmt, | ||
449 | .digital_mute = ak4641_mute, | ||
450 | .set_sysclk = ak4641_set_dai_sysclk, | ||
451 | }; | ||
452 | |||
453 | static struct snd_soc_dai_ops ak4641_pcm_dai_ops = { | ||
454 | .hw_params = NULL, /* rates are controlled by BT chip */ | ||
455 | .set_fmt = ak4641_pcm_set_dai_fmt, | ||
456 | .digital_mute = ak4641_mute, | ||
457 | .set_sysclk = ak4641_set_dai_sysclk, | ||
458 | }; | ||
459 | |||
460 | struct snd_soc_dai_driver ak4641_dai[] = { | ||
461 | { | ||
462 | .name = "ak4641-hifi", | ||
463 | .id = 1, | ||
464 | .playback = { | ||
465 | .stream_name = "HiFi Playback", | ||
466 | .channels_min = 1, | ||
467 | .channels_max = 2, | ||
468 | .rates = AK4641_RATES, | ||
469 | .formats = AK4641_FORMATS, | ||
470 | }, | ||
471 | .capture = { | ||
472 | .stream_name = "HiFi Capture", | ||
473 | .channels_min = 1, | ||
474 | .channels_max = 2, | ||
475 | .rates = AK4641_RATES, | ||
476 | .formats = AK4641_FORMATS, | ||
477 | }, | ||
478 | .ops = &ak4641_i2s_dai_ops, | ||
479 | .symmetric_rates = 1, | ||
480 | }, | ||
481 | { | ||
482 | .name = "ak4641-voice", | ||
483 | .id = 1, | ||
484 | .playback = { | ||
485 | .stream_name = "Voice Playback", | ||
486 | .channels_min = 1, | ||
487 | .channels_max = 1, | ||
488 | .rates = AK4641_RATES_BT, | ||
489 | .formats = AK4641_FORMATS, | ||
490 | }, | ||
491 | .capture = { | ||
492 | .stream_name = "Voice Capture", | ||
493 | .channels_min = 1, | ||
494 | .channels_max = 1, | ||
495 | .rates = AK4641_RATES_BT, | ||
496 | .formats = AK4641_FORMATS, | ||
497 | }, | ||
498 | .ops = &ak4641_pcm_dai_ops, | ||
499 | .symmetric_rates = 1, | ||
500 | }, | ||
501 | }; | ||
502 | |||
503 | static int ak4641_suspend(struct snd_soc_codec *codec, pm_message_t state) | ||
504 | { | ||
505 | ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static int ak4641_resume(struct snd_soc_codec *codec) | ||
510 | { | ||
511 | ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int ak4641_probe(struct snd_soc_codec *codec) | ||
516 | { | ||
517 | struct ak4641_platform_data *pdata = codec->dev->platform_data; | ||
518 | int ret; | ||
519 | |||
520 | |||
521 | if (pdata) { | ||
522 | if (gpio_is_valid(pdata->gpio_power)) { | ||
523 | ret = gpio_request_one(pdata->gpio_power, | ||
524 | GPIOF_OUT_INIT_LOW, "ak4641 power"); | ||
525 | if (ret) | ||
526 | goto err_out; | ||
527 | } | ||
528 | if (gpio_is_valid(pdata->gpio_npdn)) { | ||
529 | ret = gpio_request_one(pdata->gpio_npdn, | ||
530 | GPIOF_OUT_INIT_LOW, "ak4641 npdn"); | ||
531 | if (ret) | ||
532 | goto err_gpio; | ||
533 | |||
534 | udelay(1); /* > 150 ns */ | ||
535 | gpio_set_value(pdata->gpio_npdn, 1); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); | ||
540 | if (ret != 0) { | ||
541 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
542 | goto err_register; | ||
543 | } | ||
544 | |||
545 | /* power on device */ | ||
546 | ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
547 | |||
548 | return 0; | ||
549 | |||
550 | err_register: | ||
551 | if (pdata) { | ||
552 | if (gpio_is_valid(pdata->gpio_power)) | ||
553 | gpio_set_value(pdata->gpio_power, 0); | ||
554 | if (gpio_is_valid(pdata->gpio_npdn)) | ||
555 | gpio_free(pdata->gpio_npdn); | ||
556 | } | ||
557 | err_gpio: | ||
558 | if (pdata && gpio_is_valid(pdata->gpio_power)) | ||
559 | gpio_free(pdata->gpio_power); | ||
560 | err_out: | ||
561 | return ret; | ||
562 | } | ||
563 | |||
564 | static int ak4641_remove(struct snd_soc_codec *codec) | ||
565 | { | ||
566 | struct ak4641_platform_data *pdata = codec->dev->platform_data; | ||
567 | |||
568 | ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
569 | |||
570 | if (pdata) { | ||
571 | if (gpio_is_valid(pdata->gpio_power)) { | ||
572 | gpio_set_value(pdata->gpio_power, 0); | ||
573 | gpio_free(pdata->gpio_power); | ||
574 | } | ||
575 | if (gpio_is_valid(pdata->gpio_npdn)) | ||
576 | gpio_free(pdata->gpio_npdn); | ||
577 | } | ||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | |||
582 | static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { | ||
583 | .probe = ak4641_probe, | ||
584 | .remove = ak4641_remove, | ||
585 | .suspend = ak4641_suspend, | ||
586 | .resume = ak4641_resume, | ||
587 | .controls = ak4641_snd_controls, | ||
588 | .num_controls = ARRAY_SIZE(ak4641_snd_controls), | ||
589 | .dapm_widgets = ak4641_dapm_widgets, | ||
590 | .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets), | ||
591 | .dapm_routes = ak4641_audio_map, | ||
592 | .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), | ||
593 | .set_bias_level = ak4641_set_bias_level, | ||
594 | .reg_cache_size = ARRAY_SIZE(ak4641_reg), | ||
595 | .reg_word_size = sizeof(u8), | ||
596 | .reg_cache_default = ak4641_reg, | ||
597 | .reg_cache_step = 1, | ||
598 | }; | ||
599 | |||
600 | |||
601 | static int __devinit ak4641_i2c_probe(struct i2c_client *i2c, | ||
602 | const struct i2c_device_id *id) | ||
603 | { | ||
604 | struct ak4641_priv *ak4641; | ||
605 | int ret; | ||
606 | |||
607 | ak4641 = kzalloc(sizeof(struct ak4641_priv), GFP_KERNEL); | ||
608 | if (!ak4641) | ||
609 | return -ENOMEM; | ||
610 | |||
611 | i2c_set_clientdata(i2c, ak4641); | ||
612 | |||
613 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641, | ||
614 | ak4641_dai, ARRAY_SIZE(ak4641_dai)); | ||
615 | if (ret < 0) | ||
616 | kfree(ak4641); | ||
617 | |||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | static int __devexit ak4641_i2c_remove(struct i2c_client *i2c) | ||
622 | { | ||
623 | snd_soc_unregister_codec(&i2c->dev); | ||
624 | kfree(i2c_get_clientdata(i2c)); | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static const struct i2c_device_id ak4641_i2c_id[] = { | ||
629 | { "ak4641", 0 }, | ||
630 | { } | ||
631 | }; | ||
632 | MODULE_DEVICE_TABLE(i2c, ak4641_i2c_id); | ||
633 | |||
634 | static struct i2c_driver ak4641_i2c_driver = { | ||
635 | .driver = { | ||
636 | .name = "ak4641", | ||
637 | .owner = THIS_MODULE, | ||
638 | }, | ||
639 | .probe = ak4641_i2c_probe, | ||
640 | .remove = __devexit_p(ak4641_i2c_remove), | ||
641 | .id_table = ak4641_i2c_id, | ||
642 | }; | ||
643 | |||
644 | static int __init ak4641_modinit(void) | ||
645 | { | ||
646 | int ret; | ||
647 | |||
648 | ret = i2c_add_driver(&ak4641_i2c_driver); | ||
649 | if (ret != 0) | ||
650 | pr_err("Failed to register AK4641 I2C driver: %d\n", ret); | ||
651 | |||
652 | return ret; | ||
653 | } | ||
654 | module_init(ak4641_modinit); | ||
655 | |||
656 | static void __exit ak4641_exit(void) | ||
657 | { | ||
658 | i2c_del_driver(&ak4641_i2c_driver); | ||
659 | } | ||
660 | module_exit(ak4641_exit); | ||
661 | |||
662 | MODULE_DESCRIPTION("SoC AK4641 driver"); | ||
663 | MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>"); | ||
664 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ak4641.h b/sound/soc/codecs/ak4641.h new file mode 100644 index 000000000000..4a263248efea --- /dev/null +++ b/sound/soc/codecs/ak4641.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * ak4641.h -- AK4641 SoC Audio driver | ||
3 | * | ||
4 | * Copyright 2008 Harald Welte <laforge@gnufiish.org> | ||
5 | * | ||
6 | * Based on ak4535.h | ||
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 | #ifndef _AK4641_H | ||
14 | #define _AK4641_H | ||
15 | |||
16 | /* AK4641 register space */ | ||
17 | |||
18 | #define AK4641_PM1 0x00 | ||
19 | #define AK4641_PM2 0x01 | ||
20 | #define AK4641_SIG1 0x02 | ||
21 | #define AK4641_SIG2 0x03 | ||
22 | #define AK4641_MODE1 0x04 | ||
23 | #define AK4641_MODE2 0x05 | ||
24 | #define AK4641_DAC 0x06 | ||
25 | #define AK4641_MIC 0x07 | ||
26 | #define AK4641_TIMER 0x08 | ||
27 | #define AK4641_ALC1 0x09 | ||
28 | #define AK4641_ALC2 0x0a | ||
29 | #define AK4641_PGA 0x0b | ||
30 | #define AK4641_LATT 0x0c | ||
31 | #define AK4641_RATT 0x0d | ||
32 | #define AK4641_VOL 0x0e | ||
33 | #define AK4641_STATUS 0x0f | ||
34 | #define AK4641_EQLO 0x10 | ||
35 | #define AK4641_EQMID 0x11 | ||
36 | #define AK4641_EQHI 0x12 | ||
37 | #define AK4641_BTIF 0x13 | ||
38 | |||
39 | #define AK4641_CACHEREGNUM 0x14 | ||
40 | |||
41 | |||
42 | |||
43 | #define AK4641_DAI_HIFI 0 | ||
44 | #define AK4641_DAI_VOICE 1 | ||
45 | |||
46 | |||
47 | #endif | ||
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 57e9dac88d38..f9a87737ec16 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c | |||
@@ -39,7 +39,31 @@ static struct snd_soc_dai_driver dmic_dai = { | |||
39 | }, | 39 | }, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct snd_soc_codec_driver soc_dmic = {}; | 42 | static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = { |
43 | SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0, | ||
44 | SND_SOC_NOPM, 0, 0), | ||
45 | SND_SOC_DAPM_INPUT("DMic"), | ||
46 | }; | ||
47 | |||
48 | static const struct snd_soc_dapm_route intercon[] = { | ||
49 | {"DMIC AIF", NULL, "DMic"}, | ||
50 | }; | ||
51 | |||
52 | static int dmic_probe(struct snd_soc_codec *codec) | ||
53 | { | ||
54 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
55 | |||
56 | snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets, | ||
57 | ARRAY_SIZE(dmic_dapm_widgets)); | ||
58 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | ||
59 | snd_soc_dapm_new_widgets(dapm); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static struct snd_soc_codec_driver soc_dmic = { | ||
65 | .probe = dmic_probe, | ||
66 | }; | ||
43 | 67 | ||
44 | static int __devinit dmic_dev_probe(struct platform_device *pdev) | 68 | static int __devinit dmic_dev_probe(struct platform_device *pdev) |
45 | { | 69 | { |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 93255ff48b4f..ac65a2d36408 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -656,8 +656,6 @@ static const struct soc_enum max98088_exmode_enum = | |||
656 | ARRAY_SIZE(max98088_exmode_texts), | 656 | ARRAY_SIZE(max98088_exmode_texts), |
657 | max98088_exmode_texts, | 657 | max98088_exmode_texts, |
658 | max98088_exmode_values); | 658 | max98088_exmode_values); |
659 | static const struct snd_kcontrol_new max98088_exmode_controls = | ||
660 | SOC_DAPM_VALUE_ENUM("Route", max98088_exmode_enum); | ||
661 | 659 | ||
662 | static const char *max98088_ex_thresh[] = { /* volts PP */ | 660 | static const char *max98088_ex_thresh[] = { /* volts PP */ |
663 | "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; | 661 | "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; |
@@ -783,6 +781,7 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = { | |||
783 | SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0), | 781 | SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0), |
784 | SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0), | 782 | SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0), |
785 | 783 | ||
784 | SOC_ENUM("EX Limiter Mode", max98088_exmode_enum), | ||
786 | SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum), | 785 | SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum), |
787 | 786 | ||
788 | SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum), | 787 | SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum), |
@@ -808,10 +807,10 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = { | |||
808 | 807 | ||
809 | /* Left speaker mixer switch */ | 808 | /* Left speaker mixer switch */ |
810 | static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = { | 809 | static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = { |
811 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), | 810 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), |
812 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), | 811 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), |
813 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), | 812 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), |
814 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), | 813 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), |
815 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0), | 814 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0), |
816 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0), | 815 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0), |
817 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0), | 816 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0), |
@@ -836,10 +835,10 @@ static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = { | |||
836 | 835 | ||
837 | /* Left headphone mixer switch */ | 836 | /* Left headphone mixer switch */ |
838 | static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = { | 837 | static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = { |
839 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), | 838 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), |
840 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), | 839 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), |
841 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), | 840 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), |
842 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), | 841 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), |
843 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0), | 842 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0), |
844 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0), | 843 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0), |
845 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0), | 844 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0), |
@@ -864,10 +863,10 @@ static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = { | |||
864 | 863 | ||
865 | /* Left earpiece/receiver mixer switch */ | 864 | /* Left earpiece/receiver mixer switch */ |
866 | static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = { | 865 | static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = { |
867 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), | 866 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), |
868 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), | 867 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), |
869 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), | 868 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), |
870 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), | 869 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), |
871 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0), | 870 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0), |
872 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0), | 871 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0), |
873 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0), | 872 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0), |
@@ -1094,9 +1093,6 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = { | |||
1094 | 1093 | ||
1095 | SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0), | 1094 | SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0), |
1096 | 1095 | ||
1097 | SND_SOC_DAPM_MUX("EX Limiter Mode", SND_SOC_NOPM, 0, 0, | ||
1098 | &max98088_exmode_controls), | ||
1099 | |||
1100 | SND_SOC_DAPM_OUTPUT("HPL"), | 1096 | SND_SOC_DAPM_OUTPUT("HPL"), |
1101 | SND_SOC_DAPM_OUTPUT("HPR"), | 1097 | SND_SOC_DAPM_OUTPUT("HPR"), |
1102 | SND_SOC_DAPM_OUTPUT("SPKL"), | 1098 | SND_SOC_DAPM_OUTPUT("SPKL"), |
@@ -1568,6 +1564,36 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, | |||
1568 | return 0; | 1564 | return 0; |
1569 | } | 1565 | } |
1570 | 1566 | ||
1567 | static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute) | ||
1568 | { | ||
1569 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1570 | int reg; | ||
1571 | |||
1572 | if (mute) | ||
1573 | reg = M98088_DAI_MUTE; | ||
1574 | else | ||
1575 | reg = 0; | ||
1576 | |||
1577 | snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY, | ||
1578 | M98088_DAI_MUTE_MASK, reg); | ||
1579 | return 0; | ||
1580 | } | ||
1581 | |||
1582 | static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute) | ||
1583 | { | ||
1584 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1585 | int reg; | ||
1586 | |||
1587 | if (mute) | ||
1588 | reg = M98088_DAI_MUTE; | ||
1589 | else | ||
1590 | reg = 0; | ||
1591 | |||
1592 | snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY, | ||
1593 | M98088_DAI_MUTE_MASK, reg); | ||
1594 | return 0; | ||
1595 | } | ||
1596 | |||
1571 | static void max98088_sync_cache(struct snd_soc_codec *codec) | 1597 | static void max98088_sync_cache(struct snd_soc_codec *codec) |
1572 | { | 1598 | { |
1573 | u16 *reg_cache = codec->reg_cache; | 1599 | u16 *reg_cache = codec->reg_cache; |
@@ -1629,12 +1655,14 @@ static struct snd_soc_dai_ops max98088_dai1_ops = { | |||
1629 | .set_sysclk = max98088_dai_set_sysclk, | 1655 | .set_sysclk = max98088_dai_set_sysclk, |
1630 | .set_fmt = max98088_dai1_set_fmt, | 1656 | .set_fmt = max98088_dai1_set_fmt, |
1631 | .hw_params = max98088_dai1_hw_params, | 1657 | .hw_params = max98088_dai1_hw_params, |
1658 | .digital_mute = max98088_dai1_digital_mute, | ||
1632 | }; | 1659 | }; |
1633 | 1660 | ||
1634 | static struct snd_soc_dai_ops max98088_dai2_ops = { | 1661 | static struct snd_soc_dai_ops max98088_dai2_ops = { |
1635 | .set_sysclk = max98088_dai_set_sysclk, | 1662 | .set_sysclk = max98088_dai_set_sysclk, |
1636 | .set_fmt = max98088_dai2_set_fmt, | 1663 | .set_fmt = max98088_dai2_set_fmt, |
1637 | .hw_params = max98088_dai2_hw_params, | 1664 | .hw_params = max98088_dai2_hw_params, |
1665 | .digital_mute = max98088_dai2_digital_mute, | ||
1638 | }; | 1666 | }; |
1639 | 1667 | ||
1640 | static struct snd_soc_dai_driver max98088_dai[] = { | 1668 | static struct snd_soc_dai_driver max98088_dai[] = { |
diff --git a/sound/soc/codecs/max98088.h b/sound/soc/codecs/max98088.h index 56554c797fef..be89a4f4aab8 100644 --- a/sound/soc/codecs/max98088.h +++ b/sound/soc/codecs/max98088.h | |||
@@ -133,6 +133,19 @@ | |||
133 | #define M98088_REC_LINEMODE (1<<7) | 133 | #define M98088_REC_LINEMODE (1<<7) |
134 | #define M98088_REC_LINEMODE_MASK (1<<7) | 134 | #define M98088_REC_LINEMODE_MASK (1<<7) |
135 | 135 | ||
136 | /* M98088_REG_2D_MIX_SPK_CNTL */ | ||
137 | #define M98088_MIX_SPKR_GAIN_MASK (3<<2) | ||
138 | #define M98088_MIX_SPKR_GAIN_SHIFT 2 | ||
139 | #define M98088_MIX_SPKL_GAIN_MASK (3<<0) | ||
140 | #define M98088_MIX_SPKL_GAIN_SHIFT 0 | ||
141 | |||
142 | /* M98088_REG_2F_LVL_DAI1_PLAY, M98088_REG_31_LVL_DAI2_PLAY */ | ||
143 | #define M98088_DAI_MUTE (1<<7) | ||
144 | #define M98088_DAI_MUTE_MASK (1<<7) | ||
145 | #define M98088_DAI_VOICE_GAIN_MASK (3<<4) | ||
146 | #define M98088_DAI_ATTENUATION_MASK (0xF<<0) | ||
147 | #define M98088_DAI_ATTENUATION_SHIFT 0 | ||
148 | |||
136 | /* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */ | 149 | /* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */ |
137 | #define M98088_MICPRE_MASK (3<<5) | 150 | #define M98088_MICPRE_MASK (3<<5) |
138 | #define M98088_MICPRE_SHIFT 5 | 151 | #define M98088_MICPRE_SHIFT 5 |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index fe19677bf4b5..872a5fa4bf1f 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -1870,16 +1870,14 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, | |||
1870 | 1870 | ||
1871 | BUG_ON(channel > 1); | 1871 | BUG_ON(channel > 1); |
1872 | 1872 | ||
1873 | cdata = &max98095->dai[channel]; | 1873 | if (!pdata || !max98095->eq_textcnt) |
1874 | return 0; | ||
1874 | 1875 | ||
1875 | if (sel >= pdata->eq_cfgcnt) | 1876 | if (sel >= pdata->eq_cfgcnt) |
1876 | return -EINVAL; | 1877 | return -EINVAL; |
1877 | 1878 | ||
1879 | cdata = &max98095->dai[channel]; | ||
1878 | cdata->eq_sel = sel; | 1880 | cdata->eq_sel = sel; |
1879 | |||
1880 | if (!pdata || !max98095->eq_textcnt) | ||
1881 | return 0; | ||
1882 | |||
1883 | fs = cdata->rate; | 1881 | fs = cdata->rate; |
1884 | 1882 | ||
1885 | /* Find the selected configuration with nearest sample rate */ | 1883 | /* Find the selected configuration with nearest sample rate */ |
@@ -2018,16 +2016,14 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, | |||
2018 | 2016 | ||
2019 | BUG_ON(channel > 1); | 2017 | BUG_ON(channel > 1); |
2020 | 2018 | ||
2021 | cdata = &max98095->dai[channel]; | 2019 | if (!pdata || !max98095->bq_textcnt) |
2020 | return 0; | ||
2022 | 2021 | ||
2023 | if (sel >= pdata->bq_cfgcnt) | 2022 | if (sel >= pdata->bq_cfgcnt) |
2024 | return -EINVAL; | 2023 | return -EINVAL; |
2025 | 2024 | ||
2025 | cdata = &max98095->dai[channel]; | ||
2026 | cdata->bq_sel = sel; | 2026 | cdata->bq_sel = sel; |
2027 | |||
2028 | if (!pdata || !max98095->bq_textcnt) | ||
2029 | return 0; | ||
2030 | |||
2031 | fs = cdata->rate; | 2027 | fs = cdata->rate; |
2032 | 2028 | ||
2033 | /* Find the selected configuration with nearest sample rate */ | 2029 | /* Find the selected configuration with nearest sample rate */ |
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c index 4c32b54913ad..6a1a7e705cd7 100644 --- a/sound/soc/codecs/spdif_transciever.c +++ b/sound/soc/codecs/spdif_transciever.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <sound/pcm.h> | 21 | #include <sound/pcm.h> |
22 | #include <sound/initval.h> | 22 | #include <sound/initval.h> |
23 | 23 | ||
24 | MODULE_LICENSE("GPL"); | 24 | #define DRV_NAME "spdif-dit" |
25 | 25 | ||
26 | #define STUB_RATES SNDRV_PCM_RATE_8000_96000 | 26 | #define STUB_RATES SNDRV_PCM_RATE_8000_96000 |
27 | #define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE | 27 | #define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE |
@@ -56,7 +56,7 @@ static struct platform_driver spdif_dit_driver = { | |||
56 | .probe = spdif_dit_probe, | 56 | .probe = spdif_dit_probe, |
57 | .remove = spdif_dit_remove, | 57 | .remove = spdif_dit_remove, |
58 | .driver = { | 58 | .driver = { |
59 | .name = "spdif-dit", | 59 | .name = DRV_NAME, |
60 | .owner = THIS_MODULE, | 60 | .owner = THIS_MODULE, |
61 | }, | 61 | }, |
62 | }; | 62 | }; |
@@ -74,3 +74,7 @@ static void __exit dit_exit(void) | |||
74 | module_init(dit_modinit); | 74 | module_init(dit_modinit); |
75 | module_exit(dit_exit); | 75 | module_exit(dit_exit); |
76 | 76 | ||
77 | MODULE_AUTHOR("Steve Chen <schen@mvista.com>"); | ||
78 | MODULE_DESCRIPTION("SPDIF dummy codec driver"); | ||
79 | MODULE_LICENSE("GPL"); | ||
80 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 70099c9d63c7..84f4ad568556 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -137,7 +137,7 @@ SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1), | |||
137 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), | 137 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), |
138 | SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0), | 138 | SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0), |
139 | 139 | ||
140 | SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, 0, 0), | 140 | SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, NULL, 0), |
141 | 141 | ||
142 | SND_SOC_DAPM_OUTPUT("LOUT"), | 142 | SND_SOC_DAPM_OUTPUT("LOUT"), |
143 | SND_SOC_DAPM_OUTPUT("ROUT"), | 143 | SND_SOC_DAPM_OUTPUT("ROUT"), |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 6c43c13f0430..c3d96fc8c267 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -157,7 +157,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg, | |||
157 | static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, | 157 | static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, |
158 | struct snd_ctl_elem_value *ucontrol) | 158 | struct snd_ctl_elem_value *ucontrol) |
159 | { | 159 | { |
160 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); | 160 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
161 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; | ||
161 | struct soc_mixer_control *mc = | 162 | struct soc_mixer_control *mc = |
162 | (struct soc_mixer_control *)kcontrol->private_value; | 163 | (struct soc_mixer_control *)kcontrol->private_value; |
163 | unsigned int reg = mc->reg; | 164 | unsigned int reg = mc->reg; |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 90c361ef598f..faa5e9fb1471 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ALSA SoC Texas Instruments TLV320DAC33 codec driver | 2 | * ALSA SoC Texas Instruments TLV320DAC33 codec driver |
3 | * | 3 | * |
4 | * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> | 4 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> |
5 | * | 5 | * |
6 | * Copyright: (C) 2009 Nokia Corporation | 6 | * Copyright: (C) 2009 Nokia Corporation |
7 | * | 7 | * |
@@ -1658,5 +1658,5 @@ module_exit(dac33_module_exit); | |||
1658 | 1658 | ||
1659 | 1659 | ||
1660 | MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); | 1660 | MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); |
1661 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>"); | 1661 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
1662 | MODULE_LICENSE("GPL"); | 1662 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h index 7c318b5da437..ed69670747bf 100644 --- a/sound/soc/codecs/tlv320dac33.h +++ b/sound/soc/codecs/tlv320dac33.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ALSA SoC Texas Instruments TLV320DAC33 codec driver | 2 | * ALSA SoC Texas Instruments TLV320DAC33 codec driver |
3 | * | 3 | * |
4 | * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> | 4 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> |
5 | * | 5 | * |
6 | * Copyright: (C) 2009 Nokia Corporation | 6 | * Copyright: (C) 2009 Nokia Corporation |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 1f1ac8110bef..239e0c461068 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) Nokia Corporation | 4 | * Copyright (C) Nokia Corporation |
5 | * | 5 | * |
6 | * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> | 6 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | 9 | * modify it under the terms of the GNU General Public License |
@@ -495,7 +495,7 @@ static void __exit tpa6130a2_exit(void) | |||
495 | i2c_del_driver(&tpa6130a2_i2c_driver); | 495 | i2c_del_driver(&tpa6130a2_i2c_driver); |
496 | } | 496 | } |
497 | 497 | ||
498 | MODULE_AUTHOR("Peter Ujfalusi"); | 498 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
499 | MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); | 499 | MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); |
500 | MODULE_LICENSE("GPL"); | 500 | MODULE_LICENSE("GPL"); |
501 | 501 | ||
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h index 5df49c8756b2..417444020ba6 100644 --- a/sound/soc/codecs/tpa6130a2.h +++ b/sound/soc/codecs/tpa6130a2.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) Nokia Corporation | 4 | * Copyright (C) Nokia Corporation |
5 | * | 5 | * |
6 | * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> | 6 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | 9 | * modify it under the terms of the GNU General Public License |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 255901c4460d..4c336636d4f5 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -960,9 +960,9 @@ static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0); | |||
960 | 960 | ||
961 | /* | 961 | /* |
962 | * AFMGAIN volume control: | 962 | * AFMGAIN volume control: |
963 | * from 18 to 24 dB in 6 dB steps | 963 | * from -18 to 24 dB in 6 dB steps |
964 | */ | 964 | */ |
965 | static DECLARE_TLV_DB_SCALE(afm_amp_tlv, 1800, 600, 0); | 965 | static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0); |
966 | 966 | ||
967 | /* | 967 | /* |
968 | * HSGAIN volume control: | 968 | * HSGAIN volume control: |
@@ -1049,7 +1049,7 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { | |||
1049 | 1049 | ||
1050 | /* AFM gains */ | 1050 | /* AFM gains */ |
1051 | SOC_DOUBLE_TLV("Aux FM Volume", | 1051 | SOC_DOUBLE_TLV("Aux FM Volume", |
1052 | TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv), | 1052 | TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), |
1053 | 1053 | ||
1054 | /* Playback gains */ | 1054 | /* Playback gains */ |
1055 | SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", | 1055 | SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", |
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index 14d0716bf009..bcc208967917 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c | |||
@@ -22,7 +22,7 @@ SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), | |||
22 | SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0), | 22 | SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0), |
23 | 23 | ||
24 | SND_SOC_DAPM_INPUT("WM1250 Input"), | 24 | SND_SOC_DAPM_INPUT("WM1250 Input"), |
25 | SND_SOC_DAPM_INPUT("WM1250 Output"), | 25 | SND_SOC_DAPM_OUTPUT("WM1250 Output"), |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = { | 28 | static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = { |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 6dec7cee2cb4..2dc964b55e4f 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -198,7 +198,7 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source, | |||
198 | { | 198 | { |
199 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec); | 199 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec); |
200 | 200 | ||
201 | return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; | 201 | return wm8731->sysclk_type == WM8731_SYSCLK_XTAL; |
202 | } | 202 | } |
203 | 203 | ||
204 | static const struct snd_soc_dapm_route wm8731_intercon[] = { | 204 | static const struct snd_soc_dapm_route wm8731_intercon[] = { |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 957cd66177d6..43e3d760766f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -382,7 +382,8 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm, | |||
382 | static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, | 382 | static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, |
383 | struct snd_ctl_elem_value *ucontrol) | 383 | struct snd_ctl_elem_value *ucontrol) |
384 | { | 384 | { |
385 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); | 385 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
386 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; | ||
386 | struct snd_soc_codec *codec = widget->codec; | 387 | struct snd_soc_codec *codec = widget->codec; |
387 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 388 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
388 | u16 reg; | 389 | u16 reg; |
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c index ccc9bd832794..a0b1a7278284 100644 --- a/sound/soc/codecs/wm8915.c +++ b/sound/soc/codecs/wm8915.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/gcd.h> | 19 | #include <linux/gcd.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
24 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
25 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 74983ee2b87f..0293763debe5 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -99,7 +99,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
99 | len = fw->size - len; | 99 | len = fw->size - len; |
100 | while (len) { | 100 | while (len) { |
101 | if (len < 12) { | 101 | if (len < 12) { |
102 | dev_err(codec->dev, "%s short data block of %d\n", | 102 | dev_err(codec->dev, "%s short data block of %zd\n", |
103 | name, len); | 103 | name, len); |
104 | goto err; | 104 | goto err; |
105 | } | 105 | } |
@@ -107,7 +107,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
107 | memcpy(&data32, data + 4, sizeof(data32)); | 107 | memcpy(&data32, data + 4, sizeof(data32)); |
108 | block_len = be32_to_cpu(data32); | 108 | block_len = be32_to_cpu(data32); |
109 | if (block_len + 8 > len) { | 109 | if (block_len + 8 > len) { |
110 | dev_err(codec->dev, "%d byte block longer than file\n", | 110 | dev_err(codec->dev, "%zd byte block longer than file\n", |
111 | block_len); | 111 | block_len); |
112 | goto err; | 112 | goto err; |
113 | } | 113 | } |
@@ -141,7 +141,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
141 | case WM_FW_BLOCK_I: | 141 | case WM_FW_BLOCK_I: |
142 | case WM_FW_BLOCK_A: | 142 | case WM_FW_BLOCK_A: |
143 | case WM_FW_BLOCK_C: | 143 | case WM_FW_BLOCK_C: |
144 | dev_dbg(codec->dev, "%s: %d bytes of %x@%x\n", name, | 144 | dev_dbg(codec->dev, "%s: %zd bytes of %x@%x\n", name, |
145 | block_len, (data32 >> 24) & 0xff, | 145 | block_len, (data32 >> 24) & 0xff, |
146 | data32 & 0xffffff); | 146 | data32 & 0xffffff); |
147 | 147 | ||
@@ -362,6 +362,10 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) | |||
362 | path, wm8994->dsp_active, start, pwr_reg, reg); | 362 | path, wm8994->dsp_active, start, pwr_reg, reg); |
363 | 363 | ||
364 | if (start && ena) { | 364 | if (start && ena) { |
365 | /* If the DSP is already running then noop */ | ||
366 | if (reg & WM8958_DSP2_ENA) | ||
367 | return; | ||
368 | |||
365 | /* If either AIFnCLK is not yet enabled postpone */ | 369 | /* If either AIFnCLK is not yet enabled postpone */ |
366 | if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) | 370 | if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) |
367 | & WM8994_AIF1CLK_ENA_MASK) && | 371 | & WM8994_AIF1CLK_ENA_MASK) && |
@@ -508,6 +512,9 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, | |||
508 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 512 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
509 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 513 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
510 | 514 | ||
515 | if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0]) | ||
516 | return 0; | ||
517 | |||
511 | if (ucontrol->value.integer.value[0] > 1) | 518 | if (ucontrol->value.integer.value[0] > 1) |
512 | return -EINVAL; | 519 | return -EINVAL; |
513 | 520 | ||
@@ -628,6 +635,9 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol, | |||
628 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 635 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
629 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 636 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
630 | 637 | ||
638 | if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0]) | ||
639 | return 0; | ||
640 | |||
631 | if (ucontrol->value.integer.value[0] > 1) | 641 | if (ucontrol->value.integer.value[0] > 1) |
632 | return -EINVAL; | 642 | return -EINVAL; |
633 | 643 | ||
@@ -689,6 +699,16 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, | |||
689 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 699 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
690 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 700 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
691 | 701 | ||
702 | if (hpf < 3) { | ||
703 | if (wm8994->hpf1_ena[hpf % 3] == | ||
704 | ucontrol->value.integer.value[0]) | ||
705 | return 0; | ||
706 | } else { | ||
707 | if (wm8994->hpf2_ena[hpf % 3] == | ||
708 | ucontrol->value.integer.value[0]) | ||
709 | return 0; | ||
710 | } | ||
711 | |||
692 | if (ucontrol->value.integer.value[0] > 1) | 712 | if (ucontrol->value.integer.value[0] > 1) |
693 | return -EINVAL; | 713 | return -EINVAL; |
694 | 714 | ||
@@ -782,6 +802,9 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, | |||
782 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 802 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
783 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 803 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
784 | 804 | ||
805 | if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0]) | ||
806 | return 0; | ||
807 | |||
785 | if (ucontrol->value.integer.value[0] > 1) | 808 | if (ucontrol->value.integer.value[0] > 1) |
786 | return -EINVAL; | 809 | return -EINVAL; |
787 | 810 | ||
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 056aef904347..9e5ff789b805 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -718,7 +718,8 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w, | |||
718 | static int class_w_put(struct snd_kcontrol *kcontrol, | 718 | static int class_w_put(struct snd_kcontrol *kcontrol, |
719 | struct snd_ctl_elem_value *ucontrol) | 719 | struct snd_ctl_elem_value *ucontrol) |
720 | { | 720 | { |
721 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); | 721 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
722 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; | ||
722 | struct snd_soc_codec *codec = widget->codec; | 723 | struct snd_soc_codec *codec = widget->codec; |
723 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 724 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
724 | int ret; | 725 | int ret; |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b6d47e771519..970a95c5360b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -877,7 +877,8 @@ static const char *hp_mux_text[] = { | |||
877 | static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, | 877 | static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, |
878 | struct snd_ctl_elem_value *ucontrol) | 878 | struct snd_ctl_elem_value *ucontrol) |
879 | { | 879 | { |
880 | struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); | 880 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
881 | struct snd_soc_dapm_widget *w = wlist->widgets[0]; | ||
881 | struct snd_soc_codec *codec = w->codec; | 882 | struct snd_soc_codec *codec = w->codec; |
882 | int ret; | 883 | int ret; |
883 | 884 | ||
@@ -1004,7 +1005,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, | |||
1004 | static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, | 1005 | static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, |
1005 | struct snd_ctl_elem_value *ucontrol) | 1006 | struct snd_ctl_elem_value *ucontrol) |
1006 | { | 1007 | { |
1007 | struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); | 1008 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
1009 | struct snd_soc_dapm_widget *w = wlist->widgets[0]; | ||
1008 | struct snd_soc_codec *codec = w->codec; | 1010 | struct snd_soc_codec *codec = w->codec; |
1009 | int ret; | 1011 | int ret; |
1010 | 1012 | ||
@@ -2416,8 +2418,19 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2416 | static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) | 2418 | static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) |
2417 | { | 2419 | { |
2418 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2420 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2421 | struct wm8994 *control = codec->control_data; | ||
2419 | int i, ret; | 2422 | int i, ret; |
2420 | 2423 | ||
2424 | switch (control->type) { | ||
2425 | case WM8994: | ||
2426 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); | ||
2427 | break; | ||
2428 | case WM8958: | ||
2429 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
2430 | WM8958_MICD_ENA, 0); | ||
2431 | break; | ||
2432 | } | ||
2433 | |||
2421 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { | 2434 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { |
2422 | memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], | 2435 | memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], |
2423 | sizeof(struct wm8994_fll_config)); | 2436 | sizeof(struct wm8994_fll_config)); |
@@ -2435,6 +2448,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
2435 | static int wm8994_resume(struct snd_soc_codec *codec) | 2448 | static int wm8994_resume(struct snd_soc_codec *codec) |
2436 | { | 2449 | { |
2437 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2450 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2451 | struct wm8994 *control = codec->control_data; | ||
2438 | int i, ret; | 2452 | int i, ret; |
2439 | unsigned int val, mask; | 2453 | unsigned int val, mask; |
2440 | 2454 | ||
@@ -2473,6 +2487,19 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2473 | i + 1, ret); | 2487 | i + 1, ret); |
2474 | } | 2488 | } |
2475 | 2489 | ||
2490 | switch (control->type) { | ||
2491 | case WM8994: | ||
2492 | if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) | ||
2493 | snd_soc_update_bits(codec, WM8994_MICBIAS, | ||
2494 | WM8994_MICD_ENA, WM8994_MICD_ENA); | ||
2495 | break; | ||
2496 | case WM8958: | ||
2497 | if (wm8994->jack_cb) | ||
2498 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
2499 | WM8958_MICD_ENA, WM8958_MICD_ENA); | ||
2500 | break; | ||
2501 | } | ||
2502 | |||
2476 | return 0; | 2503 | return 0; |
2477 | } | 2504 | } |
2478 | #else | 2505 | #else |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 67eaaecbb42e..5ad873fda814 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -305,11 +305,11 @@ static int check_clk_sys(struct snd_soc_dapm_widget *source, | |||
305 | static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, | 305 | static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, |
306 | struct snd_ctl_elem_value *ucontrol) | 306 | struct snd_ctl_elem_value *ucontrol) |
307 | { | 307 | { |
308 | struct snd_soc_dapm_widget *w; | 308 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
309 | struct snd_soc_dapm_widget *w = wlist->widgets[0]; | ||
309 | struct snd_soc_codec *codec; | 310 | struct snd_soc_codec *codec; |
310 | int ret; | 311 | int ret; |
311 | 312 | ||
312 | w = snd_kcontrol_chip(kcontrol); | ||
313 | codec = w->codec; | 313 | codec = w->codec; |
314 | ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); | 314 | ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); |
315 | wm8995_update_class_w(codec); | 315 | wm8995_update_class_w(codec); |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 4005e9af5d61..9e370d14ad88 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -215,23 +215,23 @@ static const struct snd_kcontrol_new analogue_snd_controls[] = { | |||
215 | SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, | 215 | SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, |
216 | inpga_tlv), | 216 | inpga_tlv), |
217 | SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), | 217 | SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), |
218 | SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 0), | 218 | SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 6, 1, 0), |
219 | 219 | ||
220 | SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, | 220 | SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, |
221 | inpga_tlv), | 221 | inpga_tlv), |
222 | SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), | 222 | SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), |
223 | SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 0), | 223 | SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 6, 1, 0), |
224 | 224 | ||
225 | 225 | ||
226 | SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, | 226 | SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, |
227 | inpga_tlv), | 227 | inpga_tlv), |
228 | SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), | 228 | SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), |
229 | SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 0), | 229 | SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 6, 1, 0), |
230 | 230 | ||
231 | SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, | 231 | SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, |
232 | inpga_tlv), | 232 | inpga_tlv), |
233 | SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), | 233 | SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), |
234 | SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 0), | 234 | SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 6, 1, 0), |
235 | 235 | ||
236 | SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0, | 236 | SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0, |
237 | inmix_sw_tlv), | 237 | inmix_sw_tlv), |
@@ -787,17 +787,17 @@ static const struct snd_soc_dapm_route analogue_routes[] = { | |||
787 | static const struct snd_soc_dapm_route lineout1_diff_routes[] = { | 787 | static const struct snd_soc_dapm_route lineout1_diff_routes[] = { |
788 | { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, | 788 | { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, |
789 | { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, | 789 | { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, |
790 | { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" }, | 790 | { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" }, |
791 | 791 | ||
792 | { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, | 792 | { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, |
793 | { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, | 793 | { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, |
794 | }; | 794 | }; |
795 | 795 | ||
796 | static const struct snd_soc_dapm_route lineout1_se_routes[] = { | 796 | static const struct snd_soc_dapm_route lineout1_se_routes[] = { |
797 | { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" }, | 797 | { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, |
798 | { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" }, | 798 | { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, |
799 | 799 | ||
800 | { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" }, | 800 | { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, |
801 | 801 | ||
802 | { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, | 802 | { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, |
803 | { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, | 803 | { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, |
@@ -806,17 +806,17 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { | |||
806 | static const struct snd_soc_dapm_route lineout2_diff_routes[] = { | 806 | static const struct snd_soc_dapm_route lineout2_diff_routes[] = { |
807 | { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, | 807 | { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, |
808 | { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, | 808 | { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, |
809 | { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" }, | 809 | { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, |
810 | 810 | ||
811 | { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, | 811 | { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, |
812 | { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, | 812 | { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, |
813 | }; | 813 | }; |
814 | 814 | ||
815 | static const struct snd_soc_dapm_route lineout2_se_routes[] = { | 815 | static const struct snd_soc_dapm_route lineout2_se_routes[] = { |
816 | { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" }, | 816 | { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, |
817 | { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" }, | 817 | { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, |
818 | 818 | ||
819 | { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" }, | 819 | { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, |
820 | 820 | ||
821 | { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, | 821 | { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, |
822 | { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, | 822 | { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, |
@@ -836,17 +836,21 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) | |||
836 | snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, | 836 | snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, |
837 | WM8993_IN2_VU, WM8993_IN2_VU); | 837 | WM8993_IN2_VU, WM8993_IN2_VU); |
838 | 838 | ||
839 | snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT, | ||
840 | WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); | ||
839 | snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, | 841 | snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, |
840 | WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); | 842 | WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); |
841 | 843 | ||
842 | snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, | 844 | snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, |
843 | WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC); | 845 | WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC, |
846 | WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC); | ||
844 | snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, | 847 | snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, |
845 | WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, | 848 | WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, |
846 | WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); | 849 | WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); |
847 | 850 | ||
848 | snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, | 851 | snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, |
849 | WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC); | 852 | WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU, |
853 | WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU); | ||
850 | snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, | 854 | snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, |
851 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, | 855 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, |
852 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); | 856 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 4ddc6d3b6678..8566238db2a5 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -909,6 +909,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
909 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; | 909 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; |
910 | dma_data->asp_chan_q = pdata->asp_chan_q; | 910 | dma_data->asp_chan_q = pdata->asp_chan_q; |
911 | dma_data->ram_chan_q = pdata->ram_chan_q; | 911 | dma_data->ram_chan_q = pdata->ram_chan_q; |
912 | dma_data->sram_size = pdata->sram_size_playback; | ||
912 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + | 913 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + |
913 | mem->start); | 914 | mem->start); |
914 | 915 | ||
@@ -925,6 +926,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
925 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; | 926 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; |
926 | dma_data->asp_chan_q = pdata->asp_chan_q; | 927 | dma_data->asp_chan_q = pdata->asp_chan_q; |
927 | dma_data->ram_chan_q = pdata->ram_chan_q; | 928 | dma_data->ram_chan_q = pdata->ram_chan_q; |
929 | dma_data->sram_size = pdata->sram_size_capture; | ||
928 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + | 930 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + |
929 | mem->start); | 931 | mem->start); |
930 | 932 | ||
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 2175f09e57b6..07b772357244 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2008 Nokia Corporation | 4 | * Copyright (C) 2008 Nokia Corporation |
5 | * | 5 | * |
6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> | 6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> |
7 | * Peter Ujfalusi <peter.ujfalusi@nokia.com> | 7 | * Peter Ujfalusi <peter.ujfalusi@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
@@ -146,7 +146,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | |||
146 | * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) | 146 | * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) |
147 | * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) | 147 | * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) |
148 | */ | 148 | */ |
149 | if (cpu_is_omap343x() || cpu_is_omap44xx()) { | 149 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { |
150 | /* | 150 | /* |
151 | * Rule for the buffer size. We should not allow | 151 | * Rule for the buffer size. We should not allow |
152 | * smaller buffer than the FIFO size to avoid underruns | 152 | * smaller buffer than the FIFO size to avoid underruns |
@@ -258,7 +258,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
258 | default: | 258 | default: |
259 | return -EINVAL; | 259 | return -EINVAL; |
260 | } | 260 | } |
261 | if (cpu_is_omap343x()) { | 261 | if (cpu_is_omap34xx()) { |
262 | dma_data->set_threshold = omap_mcbsp_set_threshold; | 262 | dma_data->set_threshold = omap_mcbsp_set_threshold; |
263 | /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ | 263 | /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ |
264 | if (omap_mcbsp_get_dma_op_mode(bus_id) == | 264 | if (omap_mcbsp_get_dma_op_mode(bus_id) == |
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index 37dc7211ed3f..9a7dedd6f5a9 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2008 Nokia Corporation | 4 | * Copyright (C) 2008 Nokia Corporation |
5 | * | 5 | * |
6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> | 6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> |
7 | * Peter Ujfalusi <peter.ujfalusi@nokia.com> | 7 | * Peter Ujfalusi <peter.ujfalusi@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 8caeb8d305c3..e6a6b991d05f 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2008 Nokia Corporation | 4 | * Copyright (C) 2008 Nokia Corporation |
5 | * | 5 | * |
6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> | 6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> |
7 | * Peter Ujfalusi <peter.ujfalusi@nokia.com> | 7 | * Peter Ujfalusi <peter.ujfalusi@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
@@ -37,7 +37,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { | |||
37 | SNDRV_PCM_INFO_MMAP_VALID | | 37 | SNDRV_PCM_INFO_MMAP_VALID | |
38 | SNDRV_PCM_INFO_INTERLEAVED | | 38 | SNDRV_PCM_INFO_INTERLEAVED | |
39 | SNDRV_PCM_INFO_PAUSE | | 39 | SNDRV_PCM_INFO_PAUSE | |
40 | SNDRV_PCM_INFO_RESUME, | 40 | SNDRV_PCM_INFO_RESUME | |
41 | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, | ||
41 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 42 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
42 | SNDRV_PCM_FMTBIT_S32_LE, | 43 | SNDRV_PCM_FMTBIT_S32_LE, |
43 | .period_bytes_min = 32, | 44 | .period_bytes_min = 32, |
@@ -195,7 +196,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
195 | if ((cpu_is_omap1510())) | 196 | if ((cpu_is_omap1510())) |
196 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | | 197 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | |
197 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); | 198 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); |
198 | else | 199 | else if (!substream->runtime->no_period_wakeup) |
199 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); | 200 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); |
200 | 201 | ||
201 | if (!(cpu_class_is_omap1())) { | 202 | if (!(cpu_class_is_omap1())) { |
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index fea0515331fb..a0ed1dbb52d6 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2008 Nokia Corporation | 4 | * Copyright (C) 2008 Nokia Corporation |
5 | * | 5 | * |
6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> | 6 | * Contact: Jarkko Nikula <jhnikula@gmail.com> |
7 | * Peter Ujfalusi <peter.ujfalusi@nokia.com> | 7 | * Peter Ujfalusi <peter.ujfalusi@ti.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index d0986220eff9..0aae998b6540 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2008 - 2009 Nokia Corporation | 4 | * Copyright (C) 2008 - 2009 Nokia Corporation |
5 | * | 5 | * |
6 | * Contact: Peter Ujfalusi <peter.ujfalusi@nokia.com> | 6 | * Contact: Peter Ujfalusi <peter.ujfalusi@ti.com> |
7 | * Eduardo Valentin <eduardo.valentin@nokia.com> | 7 | * Eduardo Valentin <eduardo.valentin@nokia.com> |
8 | * Jarkko Nikula <jhnikula@gmail.com> | 8 | * Jarkko Nikula <jhnikula@gmail.com> |
9 | * | 9 | * |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 580f48571303..33ebc46b45b5 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -155,6 +155,15 @@ config SND_SOC_RAUMFELD | |||
155 | help | 155 | help |
156 | Say Y if you want to add support for SoC audio on Raumfeld devices | 156 | Say Y if you want to add support for SoC audio on Raumfeld devices |
157 | 157 | ||
158 | config SND_PXA2XX_SOC_HX4700 | ||
159 | tristate "SoC Audio support for HP iPAQ hx4700" | ||
160 | depends on SND_PXA2XX_SOC && MACH_H4700 | ||
161 | select SND_PXA2XX_SOC_I2S | ||
162 | select SND_SOC_AK4641 | ||
163 | help | ||
164 | Say Y if you want to add support for SoC audio on the | ||
165 | HP iPAQ hx4700. | ||
166 | |||
158 | config SND_PXA2XX_SOC_MAGICIAN | 167 | config SND_PXA2XX_SOC_MAGICIAN |
159 | tristate "SoC Audio support for HTC Magician" | 168 | tristate "SoC Audio support for HTC Magician" |
160 | depends on SND_PXA2XX_SOC && MACH_MAGICIAN | 169 | depends on SND_PXA2XX_SOC && MACH_MAGICIAN |
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index 07660165ec8d..af357623be9d 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile | |||
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o | |||
22 | snd-soc-saarb-objs := saarb.o | 22 | snd-soc-saarb-objs := saarb.o |
23 | snd-soc-tavorevb3-objs := tavorevb3.o | 23 | snd-soc-tavorevb3-objs := tavorevb3.o |
24 | snd-soc-zylonite-objs := zylonite.o | 24 | snd-soc-zylonite-objs := zylonite.o |
25 | snd-soc-hx4700-objs := hx4700.o | ||
25 | snd-soc-magician-objs := magician.o | 26 | snd-soc-magician-objs := magician.o |
26 | snd-soc-mioa701-objs := mioa701_wm9713.o | 27 | snd-soc-mioa701-objs := mioa701_wm9713.o |
27 | snd-soc-z2-objs := z2.o | 28 | snd-soc-z2-objs := z2.o |
@@ -37,6 +38,7 @@ obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o | |||
37 | obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o | 38 | obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o |
38 | obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o | 39 | obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o |
39 | obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o | 40 | obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o |
41 | obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o | ||
40 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o | 42 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o |
41 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o | 43 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o |
42 | obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o | 44 | obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o |
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c new file mode 100644 index 000000000000..65c124831a00 --- /dev/null +++ b/sound/soc/pxa/hx4700.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * SoC audio for HP iPAQ hx4700 | ||
3 | * | ||
4 | * Copyright (c) 2009 Philipp Zabel | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/timer.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/gpio.h> | ||
19 | |||
20 | #include <sound/core.h> | ||
21 | #include <sound/jack.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/pcm_params.h> | ||
24 | #include <sound/soc.h> | ||
25 | |||
26 | #include <mach/hx4700.h> | ||
27 | #include <asm/mach-types.h> | ||
28 | #include "pxa2xx-i2s.h" | ||
29 | |||
30 | #include "../codecs/ak4641.h" | ||
31 | |||
32 | static struct snd_soc_jack hs_jack; | ||
33 | |||
34 | /* Headphones jack detection DAPM pin */ | ||
35 | static struct snd_soc_jack_pin hs_jack_pin[] = { | ||
36 | { | ||
37 | .pin = "Headphone Jack", | ||
38 | .mask = SND_JACK_HEADPHONE, | ||
39 | }, | ||
40 | { | ||
41 | .pin = "Speaker", | ||
42 | /* disable speaker when hp jack is inserted */ | ||
43 | .mask = SND_JACK_HEADPHONE, | ||
44 | .invert = 1, | ||
45 | }, | ||
46 | }; | ||
47 | |||
48 | /* Headphones jack detection GPIO */ | ||
49 | static struct snd_soc_jack_gpio hs_jack_gpio = { | ||
50 | .gpio = GPIO75_HX4700_EARPHONE_nDET, | ||
51 | .invert = true, | ||
52 | .name = "hp-gpio", | ||
53 | .report = SND_JACK_HEADPHONE, | ||
54 | .debounce_time = 200, | ||
55 | }; | ||
56 | |||
57 | /* | ||
58 | * iPAQ hx4700 uses I2S for capture and playback. | ||
59 | */ | ||
60 | static int hx4700_hw_params(struct snd_pcm_substream *substream, | ||
61 | struct snd_pcm_hw_params *params) | ||
62 | { | ||
63 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
64 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
65 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
66 | int ret = 0; | ||
67 | |||
68 | /* set codec DAI configuration */ | ||
69 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
70 | SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | | ||
71 | SND_SOC_DAIFMT_CBS_CFS); | ||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | |||
75 | /* set cpu DAI configuration */ | ||
76 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
77 | SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | | ||
78 | SND_SOC_DAIFMT_CBS_CFS); | ||
79 | if (ret < 0) | ||
80 | return ret; | ||
81 | |||
82 | /* set the I2S system clock as output */ | ||
83 | ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, | ||
84 | SND_SOC_CLOCK_OUT); | ||
85 | if (ret < 0) | ||
86 | return ret; | ||
87 | |||
88 | /* inform codec driver about clock freq * | ||
89 | * (PXA I2S always uses divider 256) */ | ||
90 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params), | ||
91 | SND_SOC_CLOCK_IN); | ||
92 | if (ret < 0) | ||
93 | return ret; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static struct snd_soc_ops hx4700_ops = { | ||
99 | .hw_params = hx4700_hw_params, | ||
100 | }; | ||
101 | |||
102 | static int hx4700_spk_power(struct snd_soc_dapm_widget *w, | ||
103 | struct snd_kcontrol *k, int event) | ||
104 | { | ||
105 | gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event)); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int hx4700_hp_power(struct snd_soc_dapm_widget *w, | ||
110 | struct snd_kcontrol *k, int event) | ||
111 | { | ||
112 | gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event)); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* hx4700 machine dapm widgets */ | ||
117 | static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = { | ||
118 | SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power), | ||
119 | SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power), | ||
120 | SND_SOC_DAPM_MIC("Built-in Microphone", NULL), | ||
121 | }; | ||
122 | |||
123 | /* hx4700 machine audio_map */ | ||
124 | static const struct snd_soc_dapm_route hx4700_audio_map[] = { | ||
125 | |||
126 | /* Headphone connected to LOUT, ROUT */ | ||
127 | {"Headphone Jack", NULL, "LOUT"}, | ||
128 | {"Headphone Jack", NULL, "ROUT"}, | ||
129 | |||
130 | /* Speaker connected to MOUT2 */ | ||
131 | {"Speaker", NULL, "MOUT2"}, | ||
132 | |||
133 | /* Microphone connected to MICIN */ | ||
134 | {"MICIN", NULL, "Built-in Microphone"}, | ||
135 | {"AIN", NULL, "MICOUT"}, | ||
136 | }; | ||
137 | |||
138 | /* | ||
139 | * Logic for a ak4641 as connected on a HP iPAQ hx4700 | ||
140 | */ | ||
141 | static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) | ||
142 | { | ||
143 | struct snd_soc_codec *codec = rtd->codec; | ||
144 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
145 | int err; | ||
146 | |||
147 | /* NC codec pins */ | ||
148 | /* FIXME: is anything connected here? */ | ||
149 | snd_soc_dapm_nc_pin(dapm, "MOUT1"); | ||
150 | snd_soc_dapm_nc_pin(dapm, "MICEXT"); | ||
151 | snd_soc_dapm_nc_pin(dapm, "AUX"); | ||
152 | |||
153 | /* Jack detection API stuff */ | ||
154 | err = snd_soc_jack_new(codec, "Headphone Jack", | ||
155 | SND_JACK_HEADPHONE, &hs_jack); | ||
156 | if (err) | ||
157 | return err; | ||
158 | |||
159 | err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin), | ||
160 | hs_jack_pin); | ||
161 | if (err) | ||
162 | return err; | ||
163 | |||
164 | err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio); | ||
165 | |||
166 | return err; | ||
167 | } | ||
168 | |||
169 | /* hx4700 digital audio interface glue - connects codec <--> CPU */ | ||
170 | static struct snd_soc_dai_link hx4700_dai = { | ||
171 | .name = "ak4641", | ||
172 | .stream_name = "AK4641", | ||
173 | .cpu_dai_name = "pxa2xx-i2s", | ||
174 | .codec_dai_name = "ak4641-hifi", | ||
175 | .platform_name = "pxa-pcm-audio", | ||
176 | .codec_name = "ak4641.0-0012", | ||
177 | .init = hx4700_ak4641_init, | ||
178 | .ops = &hx4700_ops, | ||
179 | }; | ||
180 | |||
181 | /* hx4700 audio machine driver */ | ||
182 | static struct snd_soc_card snd_soc_card_hx4700 = { | ||
183 | .name = "iPAQ hx4700", | ||
184 | .dai_link = &hx4700_dai, | ||
185 | .num_links = 1, | ||
186 | .dapm_widgets = hx4700_dapm_widgets, | ||
187 | .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets), | ||
188 | .dapm_routes = hx4700_audio_map, | ||
189 | .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map), | ||
190 | }; | ||
191 | |||
192 | static struct gpio hx4700_audio_gpios[] = { | ||
193 | { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" }, | ||
194 | { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" }, | ||
195 | }; | ||
196 | |||
197 | static int __devinit hx4700_audio_probe(struct platform_device *pdev) | ||
198 | { | ||
199 | int ret; | ||
200 | |||
201 | if (!machine_is_h4700()) | ||
202 | return -ENODEV; | ||
203 | |||
204 | ret = gpio_request_array(hx4700_audio_gpios, | ||
205 | ARRAY_SIZE(hx4700_audio_gpios)); | ||
206 | if (ret) | ||
207 | return ret; | ||
208 | |||
209 | snd_soc_card_hx4700.dev = &pdev->dev; | ||
210 | ret = snd_soc_register_card(&snd_soc_card_hx4700); | ||
211 | if (ret) | ||
212 | return ret; | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static int __devexit hx4700_audio_remove(struct platform_device *pdev) | ||
218 | { | ||
219 | snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio); | ||
220 | snd_soc_unregister_card(&snd_soc_card_hx4700); | ||
221 | |||
222 | gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0); | ||
223 | gpio_set_value(GPIO107_HX4700_SPK_nSD, 0); | ||
224 | |||
225 | gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios)); | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static struct platform_driver hx4700_audio_driver = { | ||
230 | .driver = { | ||
231 | .name = "hx4700-audio", | ||
232 | .owner = THIS_MODULE, | ||
233 | .pm = &snd_soc_pm_ops, | ||
234 | }, | ||
235 | .probe = hx4700_audio_probe, | ||
236 | .remove = __devexit_p(hx4700_audio_remove), | ||
237 | }; | ||
238 | |||
239 | static int __init hx4700_modinit(void) | ||
240 | { | ||
241 | return platform_driver_register(&hx4700_audio_driver); | ||
242 | } | ||
243 | module_init(hx4700_modinit); | ||
244 | |||
245 | static void __exit hx4700_modexit(void) | ||
246 | { | ||
247 | platform_driver_unregister(&hx4700_audio_driver); | ||
248 | } | ||
249 | |||
250 | module_exit(hx4700_modexit); | ||
251 | |||
252 | MODULE_AUTHOR("Philipp Zabel"); | ||
253 | MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700"); | ||
254 | MODULE_LICENSE("GPL"); | ||
255 | MODULE_ALIAS("platform:hx4700-audio"); | ||
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index 2afabaf59491..1a591f1ebfbd 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c | |||
@@ -151,13 +151,13 @@ static struct snd_soc_ops raumfeld_cs4270_ops = { | |||
151 | .hw_params = raumfeld_cs4270_hw_params, | 151 | .hw_params = raumfeld_cs4270_hw_params, |
152 | }; | 152 | }; |
153 | 153 | ||
154 | static int raumfeld_line_suspend(struct snd_soc_card *card) | 154 | static int raumfeld_analog_suspend(struct snd_soc_card *card) |
155 | { | 155 | { |
156 | raumfeld_enable_audio(false); | 156 | raumfeld_enable_audio(false); |
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
159 | 159 | ||
160 | static int raumfeld_line_resume(struct snd_soc_card *card) | 160 | static int raumfeld_analog_resume(struct snd_soc_card *card) |
161 | { | 161 | { |
162 | raumfeld_enable_audio(true); | 162 | raumfeld_enable_audio(true); |
163 | return 0; | 163 | return 0; |
@@ -225,32 +225,53 @@ static struct snd_soc_ops raumfeld_ak4104_ops = { | |||
225 | .hw_params = raumfeld_ak4104_hw_params, | 225 | .hw_params = raumfeld_ak4104_hw_params, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | static struct snd_soc_dai_link raumfeld_dai[] = { | 228 | #define DAI_LINK_CS4270 \ |
229 | { \ | ||
230 | .name = "CS4270", \ | ||
231 | .stream_name = "CS4270", \ | ||
232 | .cpu_dai_name = "pxa-ssp-dai.0", \ | ||
233 | .platform_name = "pxa-pcm-audio", \ | ||
234 | .codec_dai_name = "cs4270-hifi", \ | ||
235 | .codec_name = "cs4270-codec.0-0048", \ | ||
236 | .ops = &raumfeld_cs4270_ops, \ | ||
237 | } | ||
238 | |||
239 | #define DAI_LINK_AK4104 \ | ||
240 | { \ | ||
241 | .name = "ak4104", \ | ||
242 | .stream_name = "Playback", \ | ||
243 | .cpu_dai_name = "pxa-ssp-dai.1", \ | ||
244 | .codec_dai_name = "ak4104-hifi", \ | ||
245 | .platform_name = "pxa-pcm-audio", \ | ||
246 | .ops = &raumfeld_ak4104_ops, \ | ||
247 | .codec_name = "spi0.0", \ | ||
248 | } | ||
249 | |||
250 | static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = | ||
229 | { | 251 | { |
230 | .name = "ak4104", | 252 | DAI_LINK_CS4270, |
231 | .stream_name = "Playback", | 253 | DAI_LINK_AK4104, |
232 | .cpu_dai_name = "pxa-ssp-dai.1", | 254 | }; |
233 | .codec_dai_name = "ak4104-hifi", | 255 | |
234 | .platform_name = "pxa-pcm-audio", | 256 | static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = |
235 | .ops = &raumfeld_ak4104_ops, | ||
236 | .codec_name = "ak4104-codec.0", | ||
237 | }, | ||
238 | { | 257 | { |
239 | .name = "CS4270", | 258 | DAI_LINK_CS4270, |
240 | .stream_name = "CS4270", | 259 | }; |
241 | .cpu_dai_name = "pxa-ssp-dai.0", | 260 | |
242 | .platform_name = "pxa-pcm-audio", | 261 | static struct snd_soc_card snd_soc_raumfeld_connector = { |
243 | .codec_dai_name = "cs4270-hifi", | 262 | .name = "Raumfeld Connector", |
244 | .codec_name = "cs4270-codec.0-0048", | 263 | .dai_link = snd_soc_raumfeld_connector_dai, |
245 | .ops = &raumfeld_cs4270_ops, | 264 | .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai), |
246 | },}; | 265 | .suspend_post = raumfeld_analog_suspend, |
247 | 266 | .resume_pre = raumfeld_analog_resume, | |
248 | static struct snd_soc_card snd_soc_raumfeld = { | 267 | }; |
249 | .name = "Raumfeld", | 268 | |
250 | .dai_link = raumfeld_dai, | 269 | static struct snd_soc_card snd_soc_raumfeld_speaker = { |
251 | .suspend_post = raumfeld_line_suspend, | 270 | .name = "Raumfeld Speaker", |
252 | .resume_pre = raumfeld_line_resume, | 271 | .dai_link = snd_soc_raumfeld_speaker_dai, |
253 | .num_links = ARRAY_SIZE(raumfeld_dai), | 272 | .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai), |
273 | .suspend_post = raumfeld_analog_suspend, | ||
274 | .resume_pre = raumfeld_analog_resume, | ||
254 | }; | 275 | }; |
255 | 276 | ||
256 | static struct platform_device *raumfeld_audio_device; | 277 | static struct platform_device *raumfeld_audio_device; |
@@ -271,22 +292,25 @@ static int __init raumfeld_audio_init(void) | |||
271 | 292 | ||
272 | set_max9485_clk(MAX9485_MCLK_FREQ_122880); | 293 | set_max9485_clk(MAX9485_MCLK_FREQ_122880); |
273 | 294 | ||
274 | /* Register LINE and SPDIF */ | 295 | /* Register analog device */ |
275 | raumfeld_audio_device = platform_device_alloc("soc-audio", 0); | 296 | raumfeld_audio_device = platform_device_alloc("soc-audio", 0); |
276 | if (!raumfeld_audio_device) | 297 | if (!raumfeld_audio_device) |
277 | return -ENOMEM; | 298 | return -ENOMEM; |
278 | 299 | ||
279 | platform_set_drvdata(raumfeld_audio_device, | ||
280 | &snd_soc_raumfeld); | ||
281 | ret = platform_device_add(raumfeld_audio_device); | ||
282 | |||
283 | /* no S/PDIF on Speakers */ | ||
284 | if (machine_is_raumfeld_speaker()) | 300 | if (machine_is_raumfeld_speaker()) |
301 | platform_set_drvdata(raumfeld_audio_device, | ||
302 | &snd_soc_raumfeld_speaker); | ||
303 | |||
304 | if (machine_is_raumfeld_connector()) | ||
305 | platform_set_drvdata(raumfeld_audio_device, | ||
306 | &snd_soc_raumfeld_connector); | ||
307 | |||
308 | ret = platform_device_add(raumfeld_audio_device); | ||
309 | if (ret < 0) | ||
285 | return ret; | 310 | return ret; |
286 | 311 | ||
287 | raumfeld_enable_audio(true); | 312 | raumfeld_enable_audio(true); |
288 | 313 | return 0; | |
289 | return ret; | ||
290 | } | 314 | } |
291 | 315 | ||
292 | static void __exit raumfeld_audio_exit(void) | 316 | static void __exit raumfeld_audio_exit(void) |
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index d1d4059be04e..d8ce34c83d8b 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -20,25 +20,15 @@ | |||
20 | 20 | ||
21 | #include <trace/events/asoc.h> | 21 | #include <trace/events/asoc.h> |
22 | 22 | ||
23 | #if defined(CONFIG_SPI_MASTER) | 23 | #ifdef CONFIG_SPI_MASTER |
24 | static int do_spi_write(void *control_data, const void *msg, | 24 | static int do_spi_write(void *control, const char *data, int len) |
25 | int len) | ||
26 | { | 25 | { |
27 | struct spi_device *spi = control_data; | 26 | struct spi_device *spi = control; |
28 | struct spi_transfer t; | 27 | int ret; |
29 | struct spi_message m; | ||
30 | |||
31 | if (len <= 0) | ||
32 | return 0; | ||
33 | |||
34 | spi_message_init(&m); | ||
35 | memset(&t, 0, sizeof t); | ||
36 | |||
37 | t.tx_buf = msg; | ||
38 | t.len = len; | ||
39 | 28 | ||
40 | spi_message_add_tail(&t, &m); | 29 | ret = spi_write(spi, data, len); |
41 | spi_sync(spi, &m); | 30 | if (ret < 0) |
31 | return ret; | ||
42 | 32 | ||
43 | return len; | 33 | return len; |
44 | } | 34 | } |
@@ -101,28 +91,12 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, | |||
101 | static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | 91 | static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, |
102 | unsigned int value) | 92 | unsigned int value) |
103 | { | 93 | { |
104 | u8 data[2]; | 94 | u16 data; |
105 | |||
106 | data[0] = (reg << 4) | ((value >> 8) & 0x000f); | ||
107 | data[1] = value & 0x00ff; | ||
108 | |||
109 | return do_hw_write(codec, reg, value, data, 2); | ||
110 | } | ||
111 | |||
112 | #if defined(CONFIG_SPI_MASTER) | ||
113 | static int snd_soc_4_12_spi_write(void *control_data, const char *data, | ||
114 | int len) | ||
115 | { | ||
116 | u8 msg[2]; | ||
117 | 95 | ||
118 | msg[0] = data[1]; | 96 | data = cpu_to_be16((reg << 12) | (value & 0xffffff)); |
119 | msg[1] = data[0]; | ||
120 | 97 | ||
121 | return do_spi_write(control_data, msg, len); | 98 | return do_hw_write(codec, reg, value, &data, 2); |
122 | } | 99 | } |
123 | #else | ||
124 | #define snd_soc_4_12_spi_write NULL | ||
125 | #endif | ||
126 | 100 | ||
127 | static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, | 101 | static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, |
128 | unsigned int reg) | 102 | unsigned int reg) |
@@ -140,21 +114,6 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, | |||
140 | return do_hw_write(codec, reg, value, &data, 2); | 114 | return do_hw_write(codec, reg, value, &data, 2); |
141 | } | 115 | } |
142 | 116 | ||
143 | #if defined(CONFIG_SPI_MASTER) | ||
144 | static int snd_soc_7_9_spi_write(void *control_data, const char *data, | ||
145 | int len) | ||
146 | { | ||
147 | u8 msg[2]; | ||
148 | |||
149 | msg[0] = data[0]; | ||
150 | msg[1] = data[1]; | ||
151 | |||
152 | return do_spi_write(control_data, msg, len); | ||
153 | } | ||
154 | #else | ||
155 | #define snd_soc_7_9_spi_write NULL | ||
156 | #endif | ||
157 | |||
158 | static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, | 117 | static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, |
159 | unsigned int value) | 118 | unsigned int value) |
160 | { | 119 | { |
@@ -173,21 +132,6 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, | |||
173 | return do_hw_read(codec, reg); | 132 | return do_hw_read(codec, reg); |
174 | } | 133 | } |
175 | 134 | ||
176 | #if defined(CONFIG_SPI_MASTER) | ||
177 | static int snd_soc_8_8_spi_write(void *control_data, const char *data, | ||
178 | int len) | ||
179 | { | ||
180 | u8 msg[2]; | ||
181 | |||
182 | msg[0] = data[0]; | ||
183 | msg[1] = data[1]; | ||
184 | |||
185 | return do_spi_write(control_data, msg, len); | ||
186 | } | ||
187 | #else | ||
188 | #define snd_soc_8_8_spi_write NULL | ||
189 | #endif | ||
190 | |||
191 | static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, | 135 | static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, |
192 | unsigned int value) | 136 | unsigned int value) |
193 | { | 137 | { |
@@ -206,22 +150,6 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, | |||
206 | return do_hw_read(codec, reg); | 150 | return do_hw_read(codec, reg); |
207 | } | 151 | } |
208 | 152 | ||
209 | #if defined(CONFIG_SPI_MASTER) | ||
210 | static int snd_soc_8_16_spi_write(void *control_data, const char *data, | ||
211 | int len) | ||
212 | { | ||
213 | u8 msg[3]; | ||
214 | |||
215 | msg[0] = data[0]; | ||
216 | msg[1] = data[1]; | ||
217 | msg[2] = data[2]; | ||
218 | |||
219 | return do_spi_write(control_data, msg, len); | ||
220 | } | ||
221 | #else | ||
222 | #define snd_soc_8_16_spi_write NULL | ||
223 | #endif | ||
224 | |||
225 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 153 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
226 | static unsigned int do_i2c_read(struct snd_soc_codec *codec, | 154 | static unsigned int do_i2c_read(struct snd_soc_codec *codec, |
227 | void *reg, int reglen, | 155 | void *reg, int reglen, |
@@ -318,27 +246,10 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, | |||
318 | 246 | ||
319 | memcpy(data, &rval, sizeof(rval)); | 247 | memcpy(data, &rval, sizeof(rval)); |
320 | data[2] = value; | 248 | data[2] = value; |
321 | reg &= 0xff; | ||
322 | 249 | ||
323 | return do_hw_write(codec, reg, value, data, 3); | 250 | return do_hw_write(codec, reg, value, data, 3); |
324 | } | 251 | } |
325 | 252 | ||
326 | #if defined(CONFIG_SPI_MASTER) | ||
327 | static int snd_soc_16_8_spi_write(void *control_data, const char *data, | ||
328 | int len) | ||
329 | { | ||
330 | u8 msg[3]; | ||
331 | |||
332 | msg[0] = data[0]; | ||
333 | msg[1] = data[1]; | ||
334 | msg[2] = data[2]; | ||
335 | |||
336 | return do_spi_write(control_data, msg, len); | ||
337 | } | ||
338 | #else | ||
339 | #define snd_soc_16_8_spi_write NULL | ||
340 | #endif | ||
341 | |||
342 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 253 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) |
343 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, | 254 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, |
344 | unsigned int r) | 255 | unsigned int r) |
@@ -373,23 +284,6 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, | |||
373 | return do_hw_write(codec, reg, value, data, sizeof(data)); | 284 | return do_hw_write(codec, reg, value, data, sizeof(data)); |
374 | } | 285 | } |
375 | 286 | ||
376 | #if defined(CONFIG_SPI_MASTER) | ||
377 | static int snd_soc_16_16_spi_write(void *control_data, const char *data, | ||
378 | int len) | ||
379 | { | ||
380 | u8 msg[4]; | ||
381 | |||
382 | msg[0] = data[0]; | ||
383 | msg[1] = data[1]; | ||
384 | msg[2] = data[2]; | ||
385 | msg[3] = data[3]; | ||
386 | |||
387 | return do_spi_write(control_data, msg, len); | ||
388 | } | ||
389 | #else | ||
390 | #define snd_soc_16_16_spi_write NULL | ||
391 | #endif | ||
392 | |||
393 | /* Primitive bulk write support for soc-cache. The data pointed to by | 287 | /* Primitive bulk write support for soc-cache. The data pointed to by |
394 | * `data' needs to already be in the form the hardware expects | 288 | * `data' needs to already be in the form the hardware expects |
395 | * including any leading register specific data. Any data written | 289 | * including any leading register specific data. Any data written |
@@ -419,7 +313,7 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r | |||
419 | #endif | 313 | #endif |
420 | #if defined(CONFIG_SPI_MASTER) | 314 | #if defined(CONFIG_SPI_MASTER) |
421 | case SND_SOC_SPI: | 315 | case SND_SOC_SPI: |
422 | ret = do_spi_write(codec->control_data, data, len); | 316 | ret = spi_write(codec->control_data, data, len); |
423 | break; | 317 | break; |
424 | #endif | 318 | #endif |
425 | default: | 319 | default: |
@@ -438,43 +332,36 @@ static struct { | |||
438 | int addr_bits; | 332 | int addr_bits; |
439 | int data_bits; | 333 | int data_bits; |
440 | int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); | 334 | int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); |
441 | int (*spi_write)(void *, const char *, int); | ||
442 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); | 335 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); |
443 | unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); | 336 | unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); |
444 | } io_types[] = { | 337 | } io_types[] = { |
445 | { | 338 | { |
446 | .addr_bits = 4, .data_bits = 12, | 339 | .addr_bits = 4, .data_bits = 12, |
447 | .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, | 340 | .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, |
448 | .spi_write = snd_soc_4_12_spi_write, | ||
449 | }, | 341 | }, |
450 | { | 342 | { |
451 | .addr_bits = 7, .data_bits = 9, | 343 | .addr_bits = 7, .data_bits = 9, |
452 | .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, | 344 | .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, |
453 | .spi_write = snd_soc_7_9_spi_write, | ||
454 | }, | 345 | }, |
455 | { | 346 | { |
456 | .addr_bits = 8, .data_bits = 8, | 347 | .addr_bits = 8, .data_bits = 8, |
457 | .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, | 348 | .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, |
458 | .i2c_read = snd_soc_8_8_read_i2c, | 349 | .i2c_read = snd_soc_8_8_read_i2c, |
459 | .spi_write = snd_soc_8_8_spi_write, | ||
460 | }, | 350 | }, |
461 | { | 351 | { |
462 | .addr_bits = 8, .data_bits = 16, | 352 | .addr_bits = 8, .data_bits = 16, |
463 | .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, | 353 | .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, |
464 | .i2c_read = snd_soc_8_16_read_i2c, | 354 | .i2c_read = snd_soc_8_16_read_i2c, |
465 | .spi_write = snd_soc_8_16_spi_write, | ||
466 | }, | 355 | }, |
467 | { | 356 | { |
468 | .addr_bits = 16, .data_bits = 8, | 357 | .addr_bits = 16, .data_bits = 8, |
469 | .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, | 358 | .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, |
470 | .i2c_read = snd_soc_16_8_read_i2c, | 359 | .i2c_read = snd_soc_16_8_read_i2c, |
471 | .spi_write = snd_soc_16_8_spi_write, | ||
472 | }, | 360 | }, |
473 | { | 361 | { |
474 | .addr_bits = 16, .data_bits = 16, | 362 | .addr_bits = 16, .data_bits = 16, |
475 | .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, | 363 | .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, |
476 | .i2c_read = snd_soc_16_16_read_i2c, | 364 | .i2c_read = snd_soc_16_16_read_i2c, |
477 | .spi_write = snd_soc_16_16_spi_write, | ||
478 | }, | 365 | }, |
479 | }; | 366 | }; |
480 | 367 | ||
@@ -535,8 +422,9 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
535 | break; | 422 | break; |
536 | 423 | ||
537 | case SND_SOC_SPI: | 424 | case SND_SOC_SPI: |
538 | if (io_types[i].spi_write) | 425 | #ifdef CONFIG_SPI_MASTER |
539 | codec->hw_write = io_types[i].spi_write; | 426 | codec->hw_write = do_spi_write; |
427 | #endif | ||
540 | 428 | ||
541 | codec->control_data = container_of(codec->dev, | 429 | codec->control_data = container_of(codec->dev, |
542 | struct spi_device, | 430 | struct spi_device, |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c261eeb835b4..13a40fc78d32 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -242,7 +242,7 @@ static ssize_t codec_reg_write_file(struct file *file, | |||
242 | const char __user *user_buf, size_t count, loff_t *ppos) | 242 | const char __user *user_buf, size_t count, loff_t *ppos) |
243 | { | 243 | { |
244 | char buf[32]; | 244 | char buf[32]; |
245 | int buf_size; | 245 | size_t buf_size; |
246 | char *start = buf; | 246 | char *start = buf; |
247 | unsigned long reg, value; | 247 | unsigned long reg, value; |
248 | int step = 1; | 248 | int step = 1; |
@@ -1307,10 +1307,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
1307 | /* no, then find CPU DAI from registered DAIs*/ | 1307 | /* no, then find CPU DAI from registered DAIs*/ |
1308 | list_for_each_entry(cpu_dai, &dai_list, list) { | 1308 | list_for_each_entry(cpu_dai, &dai_list, list) { |
1309 | if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) { | 1309 | if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) { |
1310 | |||
1311 | if (!try_module_get(cpu_dai->dev->driver->owner)) | ||
1312 | return -ENODEV; | ||
1313 | |||
1314 | rtd->cpu_dai = cpu_dai; | 1310 | rtd->cpu_dai = cpu_dai; |
1315 | goto find_codec; | 1311 | goto find_codec; |
1316 | } | 1312 | } |
@@ -1623,11 +1619,15 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) | |||
1623 | 1619 | ||
1624 | /* probe the cpu_dai */ | 1620 | /* probe the cpu_dai */ |
1625 | if (!cpu_dai->probed) { | 1621 | if (!cpu_dai->probed) { |
1622 | if (!try_module_get(cpu_dai->dev->driver->owner)) | ||
1623 | return -ENODEV; | ||
1624 | |||
1626 | if (cpu_dai->driver->probe) { | 1625 | if (cpu_dai->driver->probe) { |
1627 | ret = cpu_dai->driver->probe(cpu_dai); | 1626 | ret = cpu_dai->driver->probe(cpu_dai); |
1628 | if (ret < 0) { | 1627 | if (ret < 0) { |
1629 | printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", | 1628 | printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", |
1630 | cpu_dai->name); | 1629 | cpu_dai->name); |
1630 | module_put(cpu_dai->dev->driver->owner); | ||
1631 | return ret; | 1631 | return ret; |
1632 | } | 1632 | } |
1633 | } | 1633 | } |
@@ -1927,9 +1927,11 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1927 | card->num_dapm_routes); | 1927 | card->num_dapm_routes); |
1928 | 1928 | ||
1929 | snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), | 1929 | snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), |
1930 | "%s", card->name); | ||
1931 | snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), | ||
1932 | "%s", card->name); | 1930 | "%s", card->name); |
1931 | snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), | ||
1932 | "%s", card->long_name ? card->long_name : card->name); | ||
1933 | snprintf(card->snd_card->driver, sizeof(card->snd_card->driver), | ||
1934 | "%s", card->driver_name ? card->driver_name : card->name); | ||
1933 | 1935 | ||
1934 | if (card->late_probe) { | 1936 | if (card->late_probe) { |
1935 | ret = card->late_probe(card); | 1937 | ret = card->late_probe(card); |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 456617e63789..776e6f418306 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -325,6 +325,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, | |||
325 | } | 325 | } |
326 | 326 | ||
327 | static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, | 327 | static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, |
328 | struct snd_soc_dapm_widget *kcontrolw, | ||
328 | const struct snd_kcontrol_new *kcontrol_new, | 329 | const struct snd_kcontrol_new *kcontrol_new, |
329 | struct snd_kcontrol **kcontrol) | 330 | struct snd_kcontrol **kcontrol) |
330 | { | 331 | { |
@@ -334,6 +335,8 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, | |||
334 | *kcontrol = NULL; | 335 | *kcontrol = NULL; |
335 | 336 | ||
336 | list_for_each_entry(w, &dapm->card->widgets, list) { | 337 | list_for_each_entry(w, &dapm->card->widgets, list) { |
338 | if (w == kcontrolw || w->dapm != kcontrolw->dapm) | ||
339 | continue; | ||
337 | for (i = 0; i < w->num_kcontrols; i++) { | 340 | for (i = 0; i < w->num_kcontrols; i++) { |
338 | if (&w->kcontrol_news[i] == kcontrol_new) { | 341 | if (&w->kcontrol_news[i] == kcontrol_new) { |
339 | if (w->kcontrols) | 342 | if (w->kcontrols) |
@@ -468,7 +471,7 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm, | |||
468 | return -EINVAL; | 471 | return -EINVAL; |
469 | } | 472 | } |
470 | 473 | ||
471 | shared = dapm_is_shared_kcontrol(dapm, &w->kcontrol_news[0], | 474 | shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0], |
472 | &kcontrol); | 475 | &kcontrol); |
473 | if (kcontrol) { | 476 | if (kcontrol) { |
474 | wlist = kcontrol->private_data; | 477 | wlist = kcontrol->private_data; |
@@ -1110,7 +1113,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
1110 | trace_snd_soc_dapm_start(card); | 1113 | trace_snd_soc_dapm_start(card); |
1111 | 1114 | ||
1112 | list_for_each_entry(d, &card->dapm_list, list) | 1115 | list_for_each_entry(d, &card->dapm_list, list) |
1113 | if (d->n_widgets) | 1116 | if (d->n_widgets || d->codec == NULL) |
1114 | d->dev_power = 0; | 1117 | d->dev_power = 0; |
1115 | 1118 | ||
1116 | /* Check which widgets we need to power and store them in | 1119 | /* Check which widgets we need to power and store them in |
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 4f5e2c90b020..6b817e20548c 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c | |||
@@ -114,7 +114,7 @@ static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) | |||
114 | debugfs_remove(i2s->debug); | 114 | debugfs_remove(i2s->debug); |
115 | } | 115 | } |
116 | #else | 116 | #else |
117 | static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s) | 117 | static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) |
118 | { | 118 | { |
119 | } | 119 | } |
120 | 120 | ||