diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-03-16 09:48:16 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-16 09:48:16 -0400 |
commit | 8f88f0256f2e8afd83177b3554992009acb98996 (patch) | |
tree | 2cfbc07c64edda0db4afa67b5ed2d6c9a6c78537 | |
parent | 34e72afe73c40d9974c1f230c3b62fc43f5c5b28 (diff) | |
parent | 820cc6cf2c552155ea919e596a85e1f4e5dfa2b5 (diff) |
Merge branch 'topic/hda-bus' into for-next
-rw-r--r-- | sound/pci/hda/Makefile | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_bind.c | 321 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 731 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 108 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.c | 62 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.h | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 33 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 41 | ||||
-rw-r--r-- | sound/pci/hda/hda_tegra.c | 23 | ||||
-rw-r--r-- | sound/pci/hda/hda_trace.h | 24 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 27 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 20 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 16 |
24 files changed, 572 insertions, 991 deletions
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 194f30935e77..96caaebfc19d 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
@@ -4,7 +4,7 @@ snd-hda-tegra-objs := hda_tegra.o | |||
4 | # for haswell power well | 4 | # for haswell power well |
5 | snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o | 5 | snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o |
6 | 6 | ||
7 | snd-hda-codec-y := hda_codec.o hda_jack.o hda_auto_parser.o hda_sysfs.o | 7 | snd-hda-codec-y := hda_bind.o hda_codec.o hda_jack.o hda_auto_parser.o hda_sysfs.o |
8 | snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o | 8 | snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o |
9 | snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o | 9 | snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o |
10 | snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o | 10 | snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 1e7de08e77cb..e98438e95e79 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -160,6 +160,7 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
160 | input_dev->name = "HDA Digital PCBeep"; | 160 | input_dev->name = "HDA Digital PCBeep"; |
161 | input_dev->phys = beep->phys; | 161 | input_dev->phys = beep->phys; |
162 | input_dev->id.bustype = BUS_PCI; | 162 | input_dev->id.bustype = BUS_PCI; |
163 | input_dev->dev.parent = &codec->bus->card->card_dev; | ||
163 | 164 | ||
164 | input_dev->id.vendor = codec->vendor_id >> 16; | 165 | input_dev->id.vendor = codec->vendor_id >> 16; |
165 | input_dev->id.product = codec->vendor_id & 0xffff; | 166 | input_dev->id.product = codec->vendor_id & 0xffff; |
@@ -168,7 +169,6 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
168 | input_dev->evbit[0] = BIT_MASK(EV_SND); | 169 | input_dev->evbit[0] = BIT_MASK(EV_SND); |
169 | input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); | 170 | input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); |
170 | input_dev->event = snd_hda_beep_event; | 171 | input_dev->event = snd_hda_beep_event; |
171 | input_dev->dev.parent = &codec->dev; | ||
172 | input_set_drvdata(input_dev, beep); | 172 | input_set_drvdata(input_dev, beep); |
173 | 173 | ||
174 | beep->dev = input_dev; | 174 | beep->dev = input_dev; |
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c new file mode 100644 index 000000000000..ce2dd7b0dc07 --- /dev/null +++ b/sound/pci/hda/hda_bind.c | |||
@@ -0,0 +1,321 @@ | |||
1 | /* | ||
2 | * HD-audio codec driver binding | ||
3 | * Copyright (c) Takashi Iwai <tiwai@suse.de> | ||
4 | */ | ||
5 | |||
6 | #include <linux/init.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/mutex.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/pm.h> | ||
12 | #include <sound/core.h> | ||
13 | #include "hda_codec.h" | ||
14 | #include "hda_local.h" | ||
15 | |||
16 | /* codec vendor labels */ | ||
17 | struct hda_vendor_id { | ||
18 | unsigned int id; | ||
19 | const char *name; | ||
20 | }; | ||
21 | |||
22 | static struct hda_vendor_id hda_vendor_ids[] = { | ||
23 | { 0x1002, "ATI" }, | ||
24 | { 0x1013, "Cirrus Logic" }, | ||
25 | { 0x1057, "Motorola" }, | ||
26 | { 0x1095, "Silicon Image" }, | ||
27 | { 0x10de, "Nvidia" }, | ||
28 | { 0x10ec, "Realtek" }, | ||
29 | { 0x1102, "Creative" }, | ||
30 | { 0x1106, "VIA" }, | ||
31 | { 0x111d, "IDT" }, | ||
32 | { 0x11c1, "LSI" }, | ||
33 | { 0x11d4, "Analog Devices" }, | ||
34 | { 0x13f6, "C-Media" }, | ||
35 | { 0x14f1, "Conexant" }, | ||
36 | { 0x17e8, "Chrontel" }, | ||
37 | { 0x1854, "LG" }, | ||
38 | { 0x1aec, "Wolfson Microelectronics" }, | ||
39 | { 0x1af4, "QEMU" }, | ||
40 | { 0x434d, "C-Media" }, | ||
41 | { 0x8086, "Intel" }, | ||
42 | { 0x8384, "SigmaTel" }, | ||
43 | {} /* terminator */ | ||
44 | }; | ||
45 | |||
46 | /* | ||
47 | * find a matching codec preset | ||
48 | */ | ||
49 | static int hda_bus_match(struct device *dev, struct device_driver *drv) | ||
50 | { | ||
51 | struct hda_codec *codec = container_of(dev, struct hda_codec, dev); | ||
52 | struct hda_codec_driver *driver = | ||
53 | container_of(drv, struct hda_codec_driver, driver); | ||
54 | const struct hda_codec_preset *preset; | ||
55 | /* check probe_id instead of vendor_id if set */ | ||
56 | u32 id = codec->probe_id ? codec->probe_id : codec->vendor_id; | ||
57 | |||
58 | for (preset = driver->preset; preset->id; preset++) { | ||
59 | u32 mask = preset->mask; | ||
60 | |||
61 | if (preset->afg && preset->afg != codec->afg) | ||
62 | continue; | ||
63 | if (preset->mfg && preset->mfg != codec->mfg) | ||
64 | continue; | ||
65 | if (!mask) | ||
66 | mask = ~0; | ||
67 | if (preset->id == (id & mask) && | ||
68 | (!preset->rev || preset->rev == codec->revision_id)) { | ||
69 | codec->preset = preset; | ||
70 | return 1; | ||
71 | } | ||
72 | } | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /* reset the codec name from the preset */ | ||
77 | static int codec_refresh_name(struct hda_codec *codec, const char *name) | ||
78 | { | ||
79 | char tmp[16]; | ||
80 | |||
81 | kfree(codec->chip_name); | ||
82 | if (!name) { | ||
83 | sprintf(tmp, "ID %x", codec->vendor_id & 0xffff); | ||
84 | name = tmp; | ||
85 | } | ||
86 | codec->chip_name = kstrdup(name, GFP_KERNEL); | ||
87 | return codec->chip_name ? 0 : -ENOMEM; | ||
88 | } | ||
89 | |||
90 | static int hda_codec_driver_probe(struct device *dev) | ||
91 | { | ||
92 | struct hda_codec *codec = dev_to_hda_codec(dev); | ||
93 | struct module *owner = dev->driver->owner; | ||
94 | int err; | ||
95 | |||
96 | if (WARN_ON(!codec->preset)) | ||
97 | return -EINVAL; | ||
98 | |||
99 | err = codec_refresh_name(codec, codec->preset->name); | ||
100 | if (err < 0) | ||
101 | goto error; | ||
102 | |||
103 | if (!try_module_get(owner)) { | ||
104 | err = -EINVAL; | ||
105 | goto error; | ||
106 | } | ||
107 | |||
108 | err = codec->preset->patch(codec); | ||
109 | if (err < 0) { | ||
110 | module_put(owner); | ||
111 | goto error; | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | |||
116 | error: | ||
117 | codec->preset = NULL; | ||
118 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | ||
119 | return err; | ||
120 | } | ||
121 | |||
122 | static int hda_codec_driver_remove(struct device *dev) | ||
123 | { | ||
124 | struct hda_codec *codec = dev_to_hda_codec(dev); | ||
125 | |||
126 | if (codec->patch_ops.free) | ||
127 | codec->patch_ops.free(codec); | ||
128 | codec->preset = NULL; | ||
129 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | ||
130 | module_put(dev->driver->owner); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, | ||
135 | struct module *owner) | ||
136 | { | ||
137 | drv->driver.name = name; | ||
138 | drv->driver.owner = owner; | ||
139 | drv->driver.bus = &snd_hda_bus_type; | ||
140 | drv->driver.probe = hda_codec_driver_probe; | ||
141 | drv->driver.remove = hda_codec_driver_remove; | ||
142 | drv->driver.pm = &hda_codec_driver_pm; | ||
143 | return driver_register(&drv->driver); | ||
144 | } | ||
145 | EXPORT_SYMBOL_GPL(__hda_codec_driver_register); | ||
146 | |||
147 | void hda_codec_driver_unregister(struct hda_codec_driver *drv) | ||
148 | { | ||
149 | driver_unregister(&drv->driver); | ||
150 | } | ||
151 | EXPORT_SYMBOL_GPL(hda_codec_driver_unregister); | ||
152 | |||
153 | static inline bool codec_probed(struct hda_codec *codec) | ||
154 | { | ||
155 | return device_attach(hda_codec_dev(codec)) > 0 && codec->preset; | ||
156 | } | ||
157 | |||
158 | /* try to auto-load and bind the codec module */ | ||
159 | static void codec_bind_module(struct hda_codec *codec) | ||
160 | { | ||
161 | #ifdef MODULE | ||
162 | request_module("snd-hda-codec-id:%08x", codec->vendor_id); | ||
163 | if (codec_probed(codec)) | ||
164 | return; | ||
165 | request_module("snd-hda-codec-id:%04x*", | ||
166 | (codec->vendor_id >> 16) & 0xffff); | ||
167 | if (codec_probed(codec)) | ||
168 | return; | ||
169 | #endif | ||
170 | } | ||
171 | |||
172 | /* store the codec vendor name */ | ||
173 | static int get_codec_vendor_name(struct hda_codec *codec) | ||
174 | { | ||
175 | const struct hda_vendor_id *c; | ||
176 | const char *vendor = NULL; | ||
177 | u16 vendor_id = codec->vendor_id >> 16; | ||
178 | char tmp[16]; | ||
179 | |||
180 | for (c = hda_vendor_ids; c->id; c++) { | ||
181 | if (c->id == vendor_id) { | ||
182 | vendor = c->name; | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | if (!vendor) { | ||
187 | sprintf(tmp, "Generic %04x", vendor_id); | ||
188 | vendor = tmp; | ||
189 | } | ||
190 | codec->vendor_name = kstrdup(vendor, GFP_KERNEL); | ||
191 | if (!codec->vendor_name) | ||
192 | return -ENOMEM; | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) | ||
197 | /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ | ||
198 | static bool is_likely_hdmi_codec(struct hda_codec *codec) | ||
199 | { | ||
200 | hda_nid_t nid = codec->start_nid; | ||
201 | int i; | ||
202 | |||
203 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
204 | unsigned int wcaps = get_wcaps(codec, nid); | ||
205 | switch (get_wcaps_type(wcaps)) { | ||
206 | case AC_WID_AUD_IN: | ||
207 | return false; /* HDMI parser supports only HDMI out */ | ||
208 | case AC_WID_AUD_OUT: | ||
209 | if (!(wcaps & AC_WCAP_DIGITAL)) | ||
210 | return false; | ||
211 | break; | ||
212 | } | ||
213 | } | ||
214 | return true; | ||
215 | } | ||
216 | #else | ||
217 | /* no HDMI codec parser support */ | ||
218 | #define is_likely_hdmi_codec(codec) false | ||
219 | #endif /* CONFIG_SND_HDA_CODEC_HDMI */ | ||
220 | |||
221 | static int codec_bind_generic(struct hda_codec *codec) | ||
222 | { | ||
223 | if (codec->probe_id) | ||
224 | return -ENODEV; | ||
225 | |||
226 | if (is_likely_hdmi_codec(codec)) { | ||
227 | codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI; | ||
228 | #if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI) | ||
229 | request_module("snd-hda-codec-hdmi"); | ||
230 | #endif | ||
231 | if (codec_probed(codec)) | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | codec->probe_id = HDA_CODEC_ID_GENERIC; | ||
236 | #if IS_MODULE(CONFIG_SND_HDA_GENERIC) | ||
237 | request_module("snd-hda-codec-generic"); | ||
238 | #endif | ||
239 | if (codec_probed(codec)) | ||
240 | return 0; | ||
241 | return -ENODEV; | ||
242 | } | ||
243 | |||
244 | #if IS_ENABLED(CONFIG_SND_HDA_GENERIC) | ||
245 | #define is_generic_config(codec) \ | ||
246 | (codec->modelname && !strcmp(codec->modelname, "generic")) | ||
247 | #else | ||
248 | #define is_generic_config(codec) 0 | ||
249 | #endif | ||
250 | |||
251 | /** | ||
252 | * snd_hda_codec_configure - (Re-)configure the HD-audio codec | ||
253 | * @codec: the HDA codec | ||
254 | * | ||
255 | * Start parsing of the given codec tree and (re-)initialize the whole | ||
256 | * patch instance. | ||
257 | * | ||
258 | * Returns 0 if successful or a negative error code. | ||
259 | */ | ||
260 | int snd_hda_codec_configure(struct hda_codec *codec) | ||
261 | { | ||
262 | int err; | ||
263 | |||
264 | if (!codec->vendor_name) { | ||
265 | err = get_codec_vendor_name(codec); | ||
266 | if (err < 0) | ||
267 | return err; | ||
268 | } | ||
269 | |||
270 | if (is_generic_config(codec)) | ||
271 | codec->probe_id = HDA_CODEC_ID_GENERIC; | ||
272 | else | ||
273 | codec->probe_id = 0; | ||
274 | |||
275 | err = device_add(hda_codec_dev(codec)); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | |||
279 | if (!codec->preset) | ||
280 | codec_bind_module(codec); | ||
281 | if (!codec->preset) { | ||
282 | err = codec_bind_generic(codec); | ||
283 | if (err < 0) { | ||
284 | codec_err(codec, "Unable to bind the codec\n"); | ||
285 | goto error; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* audio codec should override the mixer name */ | ||
290 | if (codec->afg || !*codec->bus->card->mixername) | ||
291 | snprintf(codec->bus->card->mixername, | ||
292 | sizeof(codec->bus->card->mixername), | ||
293 | "%s %s", codec->vendor_name, codec->chip_name); | ||
294 | return 0; | ||
295 | |||
296 | error: | ||
297 | device_del(hda_codec_dev(codec)); | ||
298 | return err; | ||
299 | } | ||
300 | EXPORT_SYMBOL_GPL(snd_hda_codec_configure); | ||
301 | |||
302 | /* | ||
303 | * bus registration | ||
304 | */ | ||
305 | struct bus_type snd_hda_bus_type = { | ||
306 | .name = "hdaudio", | ||
307 | .match = hda_bus_match, | ||
308 | }; | ||
309 | |||
310 | static int __init hda_codec_init(void) | ||
311 | { | ||
312 | return bus_register(&snd_hda_bus_type); | ||
313 | } | ||
314 | |||
315 | static void __exit hda_codec_exit(void) | ||
316 | { | ||
317 | bus_unregister(&snd_hda_bus_type); | ||
318 | } | ||
319 | |||
320 | module_init(hda_codec_init); | ||
321 | module_exit(hda_codec_exit); | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 5e755eb6f19a..db86b446743c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/async.h> | 28 | #include <linux/async.h> |
29 | #include <linux/pm.h> | ||
30 | #include <linux/pm_runtime.h> | ||
29 | #include <sound/core.h> | 31 | #include <sound/core.h> |
30 | #include "hda_codec.h" | 32 | #include "hda_codec.h" |
31 | #include <sound/asoundef.h> | 33 | #include <sound/asoundef.h> |
@@ -40,92 +42,13 @@ | |||
40 | #define CREATE_TRACE_POINTS | 42 | #define CREATE_TRACE_POINTS |
41 | #include "hda_trace.h" | 43 | #include "hda_trace.h" |
42 | 44 | ||
43 | /* | ||
44 | * vendor / preset table | ||
45 | */ | ||
46 | |||
47 | struct hda_vendor_id { | ||
48 | unsigned int id; | ||
49 | const char *name; | ||
50 | }; | ||
51 | |||
52 | /* codec vendor labels */ | ||
53 | static struct hda_vendor_id hda_vendor_ids[] = { | ||
54 | { 0x1002, "ATI" }, | ||
55 | { 0x1013, "Cirrus Logic" }, | ||
56 | { 0x1057, "Motorola" }, | ||
57 | { 0x1095, "Silicon Image" }, | ||
58 | { 0x10de, "Nvidia" }, | ||
59 | { 0x10ec, "Realtek" }, | ||
60 | { 0x1102, "Creative" }, | ||
61 | { 0x1106, "VIA" }, | ||
62 | { 0x111d, "IDT" }, | ||
63 | { 0x11c1, "LSI" }, | ||
64 | { 0x11d4, "Analog Devices" }, | ||
65 | { 0x13f6, "C-Media" }, | ||
66 | { 0x14f1, "Conexant" }, | ||
67 | { 0x17e8, "Chrontel" }, | ||
68 | { 0x1854, "LG" }, | ||
69 | { 0x1aec, "Wolfson Microelectronics" }, | ||
70 | { 0x1af4, "QEMU" }, | ||
71 | { 0x434d, "C-Media" }, | ||
72 | { 0x8086, "Intel" }, | ||
73 | { 0x8384, "SigmaTel" }, | ||
74 | {} /* terminator */ | ||
75 | }; | ||
76 | |||
77 | static DEFINE_MUTEX(preset_mutex); | ||
78 | static LIST_HEAD(hda_preset_tables); | ||
79 | |||
80 | /** | ||
81 | * snd_hda_add_codec_preset - Add a codec preset to the chain | ||
82 | * @preset: codec preset table to add | ||
83 | */ | ||
84 | int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) | ||
85 | { | ||
86 | mutex_lock(&preset_mutex); | ||
87 | list_add_tail(&preset->list, &hda_preset_tables); | ||
88 | mutex_unlock(&preset_mutex); | ||
89 | return 0; | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(snd_hda_add_codec_preset); | ||
92 | |||
93 | /** | ||
94 | * snd_hda_delete_codec_preset - Delete a codec preset from the chain | ||
95 | * @preset: codec preset table to delete | ||
96 | */ | ||
97 | int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) | ||
98 | { | ||
99 | mutex_lock(&preset_mutex); | ||
100 | list_del(&preset->list); | ||
101 | mutex_unlock(&preset_mutex); | ||
102 | return 0; | ||
103 | } | ||
104 | EXPORT_SYMBOL_GPL(snd_hda_delete_codec_preset); | ||
105 | |||
106 | #ifdef CONFIG_PM | 45 | #ifdef CONFIG_PM |
107 | #define codec_in_pm(codec) ((codec)->in_pm) | 46 | #define codec_in_pm(codec) atomic_read(&(codec)->in_pm) |
108 | static void hda_power_work(struct work_struct *work); | 47 | #define hda_codec_is_power_on(codec) \ |
109 | static void hda_keep_power_on(struct hda_codec *codec); | 48 | (!pm_runtime_suspended(hda_codec_dev(codec))) |
110 | #define hda_codec_is_power_on(codec) ((codec)->power_on) | ||
111 | |||
112 | static void hda_call_pm_notify(struct hda_codec *codec, bool power_up) | ||
113 | { | ||
114 | struct hda_bus *bus = codec->bus; | ||
115 | |||
116 | if ((power_up && codec->pm_up_notified) || | ||
117 | (!power_up && !codec->pm_up_notified)) | ||
118 | return; | ||
119 | if (bus->ops.pm_notify) | ||
120 | bus->ops.pm_notify(bus, power_up); | ||
121 | codec->pm_up_notified = power_up; | ||
122 | } | ||
123 | |||
124 | #else | 49 | #else |
125 | #define codec_in_pm(codec) 0 | 50 | #define codec_in_pm(codec) 0 |
126 | static inline void hda_keep_power_on(struct hda_codec *codec) {} | ||
127 | #define hda_codec_is_power_on(codec) 1 | 51 | #define hda_codec_is_power_on(codec) 1 |
128 | #define hda_call_pm_notify(codec, state) {} | ||
129 | #endif | 52 | #endif |
130 | 53 | ||
131 | /** | 54 | /** |
@@ -885,111 +808,6 @@ int snd_hda_bus_new(struct snd_card *card, | |||
885 | } | 808 | } |
886 | EXPORT_SYMBOL_GPL(snd_hda_bus_new); | 809 | EXPORT_SYMBOL_GPL(snd_hda_bus_new); |
887 | 810 | ||
888 | #if IS_ENABLED(CONFIG_SND_HDA_GENERIC) | ||
889 | #define is_generic_config(codec) \ | ||
890 | (codec->modelname && !strcmp(codec->modelname, "generic")) | ||
891 | #else | ||
892 | #define is_generic_config(codec) 0 | ||
893 | #endif | ||
894 | |||
895 | #ifdef MODULE | ||
896 | #define HDA_MODREQ_MAX_COUNT 2 /* two request_modules()'s */ | ||
897 | #else | ||
898 | #define HDA_MODREQ_MAX_COUNT 0 /* all presets are statically linked */ | ||
899 | #endif | ||
900 | |||
901 | /* | ||
902 | * find a matching codec preset | ||
903 | */ | ||
904 | static const struct hda_codec_preset * | ||
905 | find_codec_preset(struct hda_codec *codec) | ||
906 | { | ||
907 | struct hda_codec_preset_list *tbl; | ||
908 | const struct hda_codec_preset *preset; | ||
909 | unsigned int mod_requested = 0; | ||
910 | |||
911 | again: | ||
912 | mutex_lock(&preset_mutex); | ||
913 | list_for_each_entry(tbl, &hda_preset_tables, list) { | ||
914 | if (!try_module_get(tbl->owner)) { | ||
915 | codec_err(codec, "cannot module_get\n"); | ||
916 | continue; | ||
917 | } | ||
918 | for (preset = tbl->preset; preset->id; preset++) { | ||
919 | u32 mask = preset->mask; | ||
920 | if (preset->afg && preset->afg != codec->afg) | ||
921 | continue; | ||
922 | if (preset->mfg && preset->mfg != codec->mfg) | ||
923 | continue; | ||
924 | if (!mask) | ||
925 | mask = ~0; | ||
926 | if (preset->id == (codec->vendor_id & mask) && | ||
927 | (!preset->rev || | ||
928 | preset->rev == codec->revision_id)) { | ||
929 | mutex_unlock(&preset_mutex); | ||
930 | codec->owner = tbl->owner; | ||
931 | return preset; | ||
932 | } | ||
933 | } | ||
934 | module_put(tbl->owner); | ||
935 | } | ||
936 | mutex_unlock(&preset_mutex); | ||
937 | |||
938 | if (mod_requested < HDA_MODREQ_MAX_COUNT) { | ||
939 | if (!mod_requested) | ||
940 | request_module("snd-hda-codec-id:%08x", | ||
941 | codec->vendor_id); | ||
942 | else | ||
943 | request_module("snd-hda-codec-id:%04x*", | ||
944 | (codec->vendor_id >> 16) & 0xffff); | ||
945 | mod_requested++; | ||
946 | goto again; | ||
947 | } | ||
948 | return NULL; | ||
949 | } | ||
950 | |||
951 | /* | ||
952 | * get_codec_name - store the codec name | ||
953 | */ | ||
954 | static int get_codec_name(struct hda_codec *codec) | ||
955 | { | ||
956 | const struct hda_vendor_id *c; | ||
957 | const char *vendor = NULL; | ||
958 | u16 vendor_id = codec->vendor_id >> 16; | ||
959 | char tmp[16]; | ||
960 | |||
961 | if (codec->vendor_name) | ||
962 | goto get_chip_name; | ||
963 | |||
964 | for (c = hda_vendor_ids; c->id; c++) { | ||
965 | if (c->id == vendor_id) { | ||
966 | vendor = c->name; | ||
967 | break; | ||
968 | } | ||
969 | } | ||
970 | if (!vendor) { | ||
971 | sprintf(tmp, "Generic %04x", vendor_id); | ||
972 | vendor = tmp; | ||
973 | } | ||
974 | codec->vendor_name = kstrdup(vendor, GFP_KERNEL); | ||
975 | if (!codec->vendor_name) | ||
976 | return -ENOMEM; | ||
977 | |||
978 | get_chip_name: | ||
979 | if (codec->chip_name) | ||
980 | return 0; | ||
981 | |||
982 | if (codec->preset && codec->preset->name) | ||
983 | codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL); | ||
984 | else { | ||
985 | sprintf(tmp, "ID %x", codec->vendor_id & 0xffff); | ||
986 | codec->chip_name = kstrdup(tmp, GFP_KERNEL); | ||
987 | } | ||
988 | if (!codec->chip_name) | ||
989 | return -ENOMEM; | ||
990 | return 0; | ||
991 | } | ||
992 | |||
993 | /* | 811 | /* |
994 | * look for an AFG and MFG nodes | 812 | * look for an AFG and MFG nodes |
995 | */ | 813 | */ |
@@ -1301,20 +1119,6 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) | |||
1301 | } | 1119 | } |
1302 | 1120 | ||
1303 | /* | 1121 | /* |
1304 | * Dynamic symbol binding for the codec parsers | ||
1305 | */ | ||
1306 | |||
1307 | #define load_parser(codec, sym) \ | ||
1308 | ((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym)) | ||
1309 | |||
1310 | static void unload_parser(struct hda_codec *codec) | ||
1311 | { | ||
1312 | if (codec->parser) | ||
1313 | symbol_put_addr(codec->parser); | ||
1314 | codec->parser = NULL; | ||
1315 | } | ||
1316 | |||
1317 | /* | ||
1318 | * codec destructor | 1122 | * codec destructor |
1319 | */ | 1123 | */ |
1320 | static void snd_hda_codec_free(struct hda_codec *codec) | 1124 | static void snd_hda_codec_free(struct hda_codec *codec) |
@@ -1322,12 +1126,11 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1322 | if (!codec) | 1126 | if (!codec) |
1323 | return; | 1127 | return; |
1324 | cancel_delayed_work_sync(&codec->jackpoll_work); | 1128 | cancel_delayed_work_sync(&codec->jackpoll_work); |
1129 | if (device_is_registered(hda_codec_dev(codec))) | ||
1130 | device_del(hda_codec_dev(codec)); | ||
1325 | snd_hda_jack_tbl_clear(codec); | 1131 | snd_hda_jack_tbl_clear(codec); |
1326 | free_init_pincfgs(codec); | 1132 | free_init_pincfgs(codec); |
1327 | #ifdef CONFIG_PM | ||
1328 | cancel_delayed_work(&codec->power_work); | ||
1329 | flush_workqueue(codec->bus->workq); | 1133 | flush_workqueue(codec->bus->workq); |
1330 | #endif | ||
1331 | list_del(&codec->list); | 1134 | list_del(&codec->list); |
1332 | snd_array_free(&codec->mixers); | 1135 | snd_array_free(&codec->mixers); |
1333 | snd_array_free(&codec->nids); | 1136 | snd_array_free(&codec->nids); |
@@ -1335,12 +1138,8 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1335 | snd_array_free(&codec->spdif_out); | 1138 | snd_array_free(&codec->spdif_out); |
1336 | remove_conn_list(codec); | 1139 | remove_conn_list(codec); |
1337 | codec->bus->caddr_tbl[codec->addr] = NULL; | 1140 | codec->bus->caddr_tbl[codec->addr] = NULL; |
1338 | if (codec->patch_ops.free) | 1141 | clear_bit(codec->addr, &codec->bus->codec_powered); |
1339 | codec->patch_ops.free(codec); | ||
1340 | hda_call_pm_notify(codec, false); /* cancel leftover refcounts */ | ||
1341 | snd_hda_sysfs_clear(codec); | 1142 | snd_hda_sysfs_clear(codec); |
1342 | unload_parser(codec); | ||
1343 | module_put(codec->owner); | ||
1344 | free_hda_cache(&codec->amp_cache); | 1143 | free_hda_cache(&codec->amp_cache); |
1345 | free_hda_cache(&codec->cmd_cache); | 1144 | free_hda_cache(&codec->cmd_cache); |
1346 | kfree(codec->vendor_name); | 1145 | kfree(codec->vendor_name); |
@@ -1348,7 +1147,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1348 | kfree(codec->modelname); | 1147 | kfree(codec->modelname); |
1349 | kfree(codec->wcaps); | 1148 | kfree(codec->wcaps); |
1350 | codec->bus->num_codecs--; | 1149 | codec->bus->num_codecs--; |
1351 | put_device(&codec->dev); | 1150 | put_device(hda_codec_dev(codec)); |
1352 | } | 1151 | } |
1353 | 1152 | ||
1354 | static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, | 1153 | static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, |
@@ -1360,11 +1159,12 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, | |||
1360 | static int snd_hda_codec_dev_register(struct snd_device *device) | 1159 | static int snd_hda_codec_dev_register(struct snd_device *device) |
1361 | { | 1160 | { |
1362 | struct hda_codec *codec = device->device_data; | 1161 | struct hda_codec *codec = device->device_data; |
1363 | int err = device_add(&codec->dev); | ||
1364 | 1162 | ||
1365 | if (err < 0) | ||
1366 | return err; | ||
1367 | snd_hda_register_beep_device(codec); | 1163 | snd_hda_register_beep_device(codec); |
1164 | if (device_is_registered(hda_codec_dev(codec))) | ||
1165 | pm_runtime_enable(hda_codec_dev(codec)); | ||
1166 | /* it was powered up in snd_hda_codec_new(), now all done */ | ||
1167 | snd_hda_power_down(codec); | ||
1368 | return 0; | 1168 | return 0; |
1369 | } | 1169 | } |
1370 | 1170 | ||
@@ -1373,7 +1173,6 @@ static int snd_hda_codec_dev_disconnect(struct snd_device *device) | |||
1373 | struct hda_codec *codec = device->device_data; | 1173 | struct hda_codec *codec = device->device_data; |
1374 | 1174 | ||
1375 | snd_hda_detach_beep_device(codec); | 1175 | snd_hda_detach_beep_device(codec); |
1376 | device_del(&codec->dev); | ||
1377 | return 0; | 1176 | return 0; |
1378 | } | 1177 | } |
1379 | 1178 | ||
@@ -1386,7 +1185,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device) | |||
1386 | /* just free the container */ | 1185 | /* just free the container */ |
1387 | static void snd_hda_codec_dev_release(struct device *dev) | 1186 | static void snd_hda_codec_dev_release(struct device *dev) |
1388 | { | 1187 | { |
1389 | kfree(container_of(dev, struct hda_codec, dev)); | 1188 | kfree(dev_to_hda_codec(dev)); |
1390 | } | 1189 | } |
1391 | 1190 | ||
1392 | /** | 1191 | /** |
@@ -1402,6 +1201,7 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1402 | struct hda_codec **codecp) | 1201 | struct hda_codec **codecp) |
1403 | { | 1202 | { |
1404 | struct hda_codec *codec; | 1203 | struct hda_codec *codec; |
1204 | struct device *dev; | ||
1405 | char component[31]; | 1205 | char component[31]; |
1406 | hda_nid_t fg; | 1206 | hda_nid_t fg; |
1407 | int err; | 1207 | int err; |
@@ -1429,14 +1229,15 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1429 | return -ENOMEM; | 1229 | return -ENOMEM; |
1430 | } | 1230 | } |
1431 | 1231 | ||
1432 | device_initialize(&codec->dev); | 1232 | dev = hda_codec_dev(codec); |
1433 | codec->dev.parent = &bus->card->card_dev; | 1233 | device_initialize(dev); |
1434 | codec->dev.class = sound_class; | 1234 | dev->parent = bus->card->dev; |
1435 | codec->dev.release = snd_hda_codec_dev_release; | 1235 | dev->bus = &snd_hda_bus_type; |
1436 | codec->dev.groups = snd_hda_dev_attr_groups; | 1236 | dev->release = snd_hda_codec_dev_release; |
1437 | dev_set_name(&codec->dev, "hdaudioC%dD%d", bus->card->number, | 1237 | dev->groups = snd_hda_dev_attr_groups; |
1438 | codec_addr); | 1238 | dev_set_name(dev, "hdaudioC%dD%d", bus->card->number, codec_addr); |
1439 | dev_set_drvdata(&codec->dev, codec); /* for sysfs */ | 1239 | dev_set_drvdata(dev, codec); /* for sysfs */ |
1240 | device_enable_async_suspend(dev); | ||
1440 | 1241 | ||
1441 | codec->bus = bus; | 1242 | codec->bus = bus; |
1442 | codec->addr = codec_addr; | 1243 | codec->addr = codec_addr; |
@@ -1460,13 +1261,13 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1460 | codec->fixup_id = HDA_FIXUP_ID_NOT_SET; | 1261 | codec->fixup_id = HDA_FIXUP_ID_NOT_SET; |
1461 | 1262 | ||
1462 | #ifdef CONFIG_PM | 1263 | #ifdef CONFIG_PM |
1463 | spin_lock_init(&codec->power_lock); | ||
1464 | INIT_DELAYED_WORK(&codec->power_work, hda_power_work); | ||
1465 | /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. | 1264 | /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. |
1466 | * the caller has to power down appropriatley after initialization | 1265 | * it's powered down later in snd_hda_codec_dev_register(). |
1467 | * phase. | ||
1468 | */ | 1266 | */ |
1469 | hda_keep_power_on(codec); | 1267 | set_bit(codec->addr, &bus->codec_powered); |
1268 | pm_runtime_set_active(hda_codec_dev(codec)); | ||
1269 | pm_runtime_get_noresume(hda_codec_dev(codec)); | ||
1270 | codec->power_jiffies = jiffies; | ||
1470 | #endif | 1271 | #endif |
1471 | 1272 | ||
1472 | snd_hda_sysfs_init(codec); | 1273 | snd_hda_sysfs_init(codec); |
@@ -1526,11 +1327,6 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1526 | #endif | 1327 | #endif |
1527 | codec->epss = snd_hda_codec_get_supported_ps(codec, fg, | 1328 | codec->epss = snd_hda_codec_get_supported_ps(codec, fg, |
1528 | AC_PWRST_EPSS); | 1329 | AC_PWRST_EPSS); |
1529 | #ifdef CONFIG_PM | ||
1530 | if (!codec->d3_stop_clk || !codec->epss) | ||
1531 | bus->power_keep_link_on = 1; | ||
1532 | #endif | ||
1533 | |||
1534 | 1330 | ||
1535 | /* power-up all before initialization */ | 1331 | /* power-up all before initialization */ |
1536 | hda_set_power_state(codec, AC_PWRST_D0); | 1332 | hda_set_power_state(codec, AC_PWRST_D0); |
@@ -1587,92 +1383,6 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec) | |||
1587 | } | 1383 | } |
1588 | EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); | 1384 | EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); |
1589 | 1385 | ||
1590 | |||
1591 | #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) | ||
1592 | /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ | ||
1593 | static bool is_likely_hdmi_codec(struct hda_codec *codec) | ||
1594 | { | ||
1595 | hda_nid_t nid = codec->start_nid; | ||
1596 | int i; | ||
1597 | |||
1598 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
1599 | unsigned int wcaps = get_wcaps(codec, nid); | ||
1600 | switch (get_wcaps_type(wcaps)) { | ||
1601 | case AC_WID_AUD_IN: | ||
1602 | return false; /* HDMI parser supports only HDMI out */ | ||
1603 | case AC_WID_AUD_OUT: | ||
1604 | if (!(wcaps & AC_WCAP_DIGITAL)) | ||
1605 | return false; | ||
1606 | break; | ||
1607 | } | ||
1608 | } | ||
1609 | return true; | ||
1610 | } | ||
1611 | #else | ||
1612 | /* no HDMI codec parser support */ | ||
1613 | #define is_likely_hdmi_codec(codec) false | ||
1614 | #endif /* CONFIG_SND_HDA_CODEC_HDMI */ | ||
1615 | |||
1616 | /** | ||
1617 | * snd_hda_codec_configure - (Re-)configure the HD-audio codec | ||
1618 | * @codec: the HDA codec | ||
1619 | * | ||
1620 | * Start parsing of the given codec tree and (re-)initialize the whole | ||
1621 | * patch instance. | ||
1622 | * | ||
1623 | * Returns 0 if successful or a negative error code. | ||
1624 | */ | ||
1625 | int snd_hda_codec_configure(struct hda_codec *codec) | ||
1626 | { | ||
1627 | int (*patch)(struct hda_codec *) = NULL; | ||
1628 | int err; | ||
1629 | |||
1630 | codec->preset = find_codec_preset(codec); | ||
1631 | if (!codec->vendor_name || !codec->chip_name) { | ||
1632 | err = get_codec_name(codec); | ||
1633 | if (err < 0) | ||
1634 | return err; | ||
1635 | } | ||
1636 | |||
1637 | if (!is_generic_config(codec) && codec->preset) | ||
1638 | patch = codec->preset->patch; | ||
1639 | if (!patch) { | ||
1640 | unload_parser(codec); /* to be sure */ | ||
1641 | if (is_likely_hdmi_codec(codec)) { | ||
1642 | #if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI) | ||
1643 | patch = load_parser(codec, snd_hda_parse_hdmi_codec); | ||
1644 | #elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI) | ||
1645 | patch = snd_hda_parse_hdmi_codec; | ||
1646 | #endif | ||
1647 | } | ||
1648 | if (!patch) { | ||
1649 | #if IS_MODULE(CONFIG_SND_HDA_GENERIC) | ||
1650 | patch = load_parser(codec, snd_hda_parse_generic_codec); | ||
1651 | #elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC) | ||
1652 | patch = snd_hda_parse_generic_codec; | ||
1653 | #endif | ||
1654 | } | ||
1655 | if (!patch) { | ||
1656 | codec_err(codec, "No codec parser is available\n"); | ||
1657 | return -ENODEV; | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | err = patch(codec); | ||
1662 | if (err < 0) { | ||
1663 | unload_parser(codec); | ||
1664 | return err; | ||
1665 | } | ||
1666 | |||
1667 | /* audio codec should override the mixer name */ | ||
1668 | if (codec->afg || !*codec->bus->card->mixername) | ||
1669 | snprintf(codec->bus->card->mixername, | ||
1670 | sizeof(codec->bus->card->mixername), | ||
1671 | "%s %s", codec->vendor_name, codec->chip_name); | ||
1672 | return 0; | ||
1673 | } | ||
1674 | EXPORT_SYMBOL_GPL(snd_hda_codec_configure); | ||
1675 | |||
1676 | /* update the stream-id if changed */ | 1386 | /* update the stream-id if changed */ |
1677 | static void update_pcm_stream_id(struct hda_codec *codec, | 1387 | static void update_pcm_stream_id(struct hda_codec *codec, |
1678 | struct hda_cvt_setup *p, hda_nid_t nid, | 1388 | struct hda_cvt_setup *p, hda_nid_t nid, |
@@ -2725,10 +2435,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2725 | 2435 | ||
2726 | /* OK, let it free */ | 2436 | /* OK, let it free */ |
2727 | cancel_delayed_work_sync(&codec->jackpoll_work); | 2437 | cancel_delayed_work_sync(&codec->jackpoll_work); |
2728 | #ifdef CONFIG_PM | ||
2729 | cancel_delayed_work_sync(&codec->power_work); | ||
2730 | flush_workqueue(bus->workq); | 2438 | flush_workqueue(bus->workq); |
2731 | #endif | ||
2732 | snd_hda_ctls_clear(codec); | 2439 | snd_hda_ctls_clear(codec); |
2733 | /* release PCMs */ | 2440 | /* release PCMs */ |
2734 | for (i = 0; i < codec->num_pcms; i++) { | 2441 | for (i = 0; i < codec->num_pcms; i++) { |
@@ -2739,8 +2446,9 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2739 | } | 2446 | } |
2740 | } | 2447 | } |
2741 | snd_hda_detach_beep_device(codec); | 2448 | snd_hda_detach_beep_device(codec); |
2742 | if (codec->patch_ops.free) | 2449 | if (device_is_registered(hda_codec_dev(codec))) |
2743 | codec->patch_ops.free(codec); | 2450 | device_del(hda_codec_dev(codec)); |
2451 | |||
2744 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); | 2452 | memset(&codec->patch_ops, 0, sizeof(codec->patch_ops)); |
2745 | snd_hda_jack_tbl_clear(codec); | 2453 | snd_hda_jack_tbl_clear(codec); |
2746 | codec->proc_widget_hook = NULL; | 2454 | codec->proc_widget_hook = NULL; |
@@ -2759,9 +2467,6 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2759 | codec->preset = NULL; | 2467 | codec->preset = NULL; |
2760 | codec->slave_dig_outs = NULL; | 2468 | codec->slave_dig_outs = NULL; |
2761 | codec->spdif_status_reset = 0; | 2469 | codec->spdif_status_reset = 0; |
2762 | unload_parser(codec); | ||
2763 | module_put(codec->owner); | ||
2764 | codec->owner = NULL; | ||
2765 | 2470 | ||
2766 | /* allow device access again */ | 2471 | /* allow device access again */ |
2767 | snd_hda_unlock_devices(bus); | 2472 | snd_hda_unlock_devices(bus); |
@@ -4167,31 +3872,40 @@ static inline void hda_exec_init_verbs(struct hda_codec *codec) {} | |||
4167 | #endif | 3872 | #endif |
4168 | 3873 | ||
4169 | #ifdef CONFIG_PM | 3874 | #ifdef CONFIG_PM |
3875 | /* update the power on/off account with the current jiffies */ | ||
3876 | static void update_power_acct(struct hda_codec *codec, bool on) | ||
3877 | { | ||
3878 | unsigned long delta = jiffies - codec->power_jiffies; | ||
3879 | |||
3880 | if (on) | ||
3881 | codec->power_on_acct += delta; | ||
3882 | else | ||
3883 | codec->power_off_acct += delta; | ||
3884 | codec->power_jiffies += delta; | ||
3885 | } | ||
3886 | |||
3887 | void snd_hda_update_power_acct(struct hda_codec *codec) | ||
3888 | { | ||
3889 | update_power_acct(codec, hda_codec_is_power_on(codec)); | ||
3890 | } | ||
3891 | |||
4170 | /* | 3892 | /* |
4171 | * call suspend and power-down; used both from PM and power-save | 3893 | * call suspend and power-down; used both from PM and power-save |
4172 | * this function returns the power state in the end | 3894 | * this function returns the power state in the end |
4173 | */ | 3895 | */ |
4174 | static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) | 3896 | static unsigned int hda_call_codec_suspend(struct hda_codec *codec) |
4175 | { | 3897 | { |
4176 | unsigned int state; | 3898 | unsigned int state; |
4177 | 3899 | ||
4178 | codec->in_pm = 1; | 3900 | atomic_inc(&codec->in_pm); |
4179 | 3901 | ||
4180 | if (codec->patch_ops.suspend) | 3902 | if (codec->patch_ops.suspend) |
4181 | codec->patch_ops.suspend(codec); | 3903 | codec->patch_ops.suspend(codec); |
4182 | hda_cleanup_all_streams(codec); | 3904 | hda_cleanup_all_streams(codec); |
4183 | state = hda_set_power_state(codec, AC_PWRST_D3); | 3905 | state = hda_set_power_state(codec, AC_PWRST_D3); |
4184 | /* Cancel delayed work if we aren't currently running from it. */ | ||
4185 | if (!in_wq) | ||
4186 | cancel_delayed_work_sync(&codec->power_work); | ||
4187 | spin_lock(&codec->power_lock); | ||
4188 | snd_hda_update_power_acct(codec); | ||
4189 | trace_hda_power_down(codec); | 3906 | trace_hda_power_down(codec); |
4190 | codec->power_on = 0; | 3907 | update_power_acct(codec, true); |
4191 | codec->power_transition = 0; | 3908 | atomic_dec(&codec->in_pm); |
4192 | codec->power_jiffies = jiffies; | ||
4193 | spin_unlock(&codec->power_lock); | ||
4194 | codec->in_pm = 0; | ||
4195 | return state; | 3909 | return state; |
4196 | } | 3910 | } |
4197 | 3911 | ||
@@ -4216,14 +3930,13 @@ static void hda_mark_cmd_cache_dirty(struct hda_codec *codec) | |||
4216 | */ | 3930 | */ |
4217 | static void hda_call_codec_resume(struct hda_codec *codec) | 3931 | static void hda_call_codec_resume(struct hda_codec *codec) |
4218 | { | 3932 | { |
4219 | codec->in_pm = 1; | 3933 | atomic_inc(&codec->in_pm); |
4220 | 3934 | ||
3935 | trace_hda_power_up(codec); | ||
4221 | hda_mark_cmd_cache_dirty(codec); | 3936 | hda_mark_cmd_cache_dirty(codec); |
4222 | 3937 | ||
4223 | /* set as if powered on for avoiding re-entering the resume | 3938 | codec->power_jiffies = jiffies; |
4224 | * in the resume / power-save sequence | 3939 | |
4225 | */ | ||
4226 | hda_keep_power_on(codec); | ||
4227 | hda_set_power_state(codec, AC_PWRST_D0); | 3940 | hda_set_power_state(codec, AC_PWRST_D0); |
4228 | restore_shutup_pins(codec); | 3941 | restore_shutup_pins(codec); |
4229 | hda_exec_init_verbs(codec); | 3942 | hda_exec_init_verbs(codec); |
@@ -4241,12 +3954,42 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
4241 | hda_jackpoll_work(&codec->jackpoll_work.work); | 3954 | hda_jackpoll_work(&codec->jackpoll_work.work); |
4242 | else | 3955 | else |
4243 | snd_hda_jack_report_sync(codec); | 3956 | snd_hda_jack_report_sync(codec); |
3957 | atomic_dec(&codec->in_pm); | ||
3958 | } | ||
3959 | |||
3960 | static int hda_codec_runtime_suspend(struct device *dev) | ||
3961 | { | ||
3962 | struct hda_codec *codec = dev_to_hda_codec(dev); | ||
3963 | unsigned int state; | ||
3964 | int i; | ||
3965 | |||
3966 | cancel_delayed_work_sync(&codec->jackpoll_work); | ||
3967 | for (i = 0; i < codec->num_pcms; i++) | ||
3968 | snd_pcm_suspend_all(codec->pcm_info[i].pcm); | ||
3969 | state = hda_call_codec_suspend(codec); | ||
3970 | if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) | ||
3971 | clear_bit(codec->addr, &codec->bus->codec_powered); | ||
3972 | return 0; | ||
3973 | } | ||
3974 | |||
3975 | static int hda_codec_runtime_resume(struct device *dev) | ||
3976 | { | ||
3977 | struct hda_codec *codec = dev_to_hda_codec(dev); | ||
4244 | 3978 | ||
4245 | codec->in_pm = 0; | 3979 | set_bit(codec->addr, &codec->bus->codec_powered); |
4246 | snd_hda_power_down(codec); /* flag down before returning */ | 3980 | hda_call_codec_resume(codec); |
3981 | pm_runtime_mark_last_busy(dev); | ||
3982 | return 0; | ||
4247 | } | 3983 | } |
4248 | #endif /* CONFIG_PM */ | 3984 | #endif /* CONFIG_PM */ |
4249 | 3985 | ||
3986 | /* referred in hda_bind.c */ | ||
3987 | const struct dev_pm_ops hda_codec_driver_pm = { | ||
3988 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | ||
3989 | pm_runtime_force_resume) | ||
3990 | SET_RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume, | ||
3991 | NULL) | ||
3992 | }; | ||
4250 | 3993 | ||
4251 | /** | 3994 | /** |
4252 | * snd_hda_build_controls - build mixer controls | 3995 | * snd_hda_build_controls - build mixer controls |
@@ -4984,127 +4727,70 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, | |||
4984 | EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls); | 4727 | EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls); |
4985 | 4728 | ||
4986 | #ifdef CONFIG_PM | 4729 | #ifdef CONFIG_PM |
4987 | static void hda_power_work(struct work_struct *work) | 4730 | /** |
4731 | * snd_hda_power_up - Power-up the codec | ||
4732 | * @codec: HD-audio codec | ||
4733 | * | ||
4734 | * Increment the usage counter and resume the device if not done yet. | ||
4735 | */ | ||
4736 | void snd_hda_power_up(struct hda_codec *codec) | ||
4988 | { | 4737 | { |
4989 | struct hda_codec *codec = | 4738 | struct device *dev = hda_codec_dev(codec); |
4990 | container_of(work, struct hda_codec, power_work.work); | ||
4991 | struct hda_bus *bus = codec->bus; | ||
4992 | unsigned int state; | ||
4993 | 4739 | ||
4994 | spin_lock(&codec->power_lock); | 4740 | if (codec_in_pm(codec)) |
4995 | if (codec->power_transition > 0) { /* during power-up sequence? */ | ||
4996 | spin_unlock(&codec->power_lock); | ||
4997 | return; | ||
4998 | } | ||
4999 | if (!codec->power_on || codec->power_count) { | ||
5000 | codec->power_transition = 0; | ||
5001 | spin_unlock(&codec->power_lock); | ||
5002 | return; | 4741 | return; |
5003 | } | 4742 | pm_runtime_get_sync(dev); |
5004 | spin_unlock(&codec->power_lock); | ||
5005 | |||
5006 | state = hda_call_codec_suspend(codec, true); | ||
5007 | if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) | ||
5008 | hda_call_pm_notify(codec, false); | ||
5009 | } | ||
5010 | |||
5011 | static void hda_keep_power_on(struct hda_codec *codec) | ||
5012 | { | ||
5013 | spin_lock(&codec->power_lock); | ||
5014 | codec->power_count++; | ||
5015 | codec->power_on = 1; | ||
5016 | codec->power_jiffies = jiffies; | ||
5017 | spin_unlock(&codec->power_lock); | ||
5018 | hda_call_pm_notify(codec, true); | ||
5019 | } | 4743 | } |
4744 | EXPORT_SYMBOL_GPL(snd_hda_power_up); | ||
5020 | 4745 | ||
5021 | /* update the power on/off account with the current jiffies */ | 4746 | /** |
5022 | void snd_hda_update_power_acct(struct hda_codec *codec) | 4747 | * snd_hda_power_down - Power-down the codec |
5023 | { | 4748 | * @codec: HD-audio codec |
5024 | unsigned long delta = jiffies - codec->power_jiffies; | 4749 | * |
5025 | if (codec->power_on) | 4750 | * Decrement the usage counter and schedules the autosuspend if none used. |
5026 | codec->power_on_acct += delta; | 4751 | */ |
5027 | else | 4752 | void snd_hda_power_down(struct hda_codec *codec) |
5028 | codec->power_off_acct += delta; | ||
5029 | codec->power_jiffies += delta; | ||
5030 | } | ||
5031 | |||
5032 | /* Transition to powered up, if wait_power_down then wait for a pending | ||
5033 | * transition to D3 to complete. A pending D3 transition is indicated | ||
5034 | * with power_transition == -1. */ | ||
5035 | /* call this with codec->power_lock held! */ | ||
5036 | static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) | ||
5037 | { | 4753 | { |
5038 | /* Return if power_on or transitioning to power_on, unless currently | 4754 | struct device *dev = hda_codec_dev(codec); |
5039 | * powering down. */ | ||
5040 | if ((codec->power_on || codec->power_transition > 0) && | ||
5041 | !(wait_power_down && codec->power_transition < 0)) | ||
5042 | return; | ||
5043 | spin_unlock(&codec->power_lock); | ||
5044 | |||
5045 | cancel_delayed_work_sync(&codec->power_work); | ||
5046 | 4755 | ||
5047 | spin_lock(&codec->power_lock); | 4756 | if (codec_in_pm(codec)) |
5048 | /* If the power down delayed work was cancelled above before starting, | ||
5049 | * then there is no need to go through power up here. | ||
5050 | */ | ||
5051 | if (codec->power_on) { | ||
5052 | if (codec->power_transition < 0) | ||
5053 | codec->power_transition = 0; | ||
5054 | return; | 4757 | return; |
5055 | } | 4758 | pm_runtime_mark_last_busy(dev); |
5056 | 4759 | pm_runtime_put_autosuspend(dev); | |
5057 | trace_hda_power_up(codec); | ||
5058 | snd_hda_update_power_acct(codec); | ||
5059 | codec->power_on = 1; | ||
5060 | codec->power_jiffies = jiffies; | ||
5061 | codec->power_transition = 1; /* avoid reentrance */ | ||
5062 | spin_unlock(&codec->power_lock); | ||
5063 | |||
5064 | hda_call_codec_resume(codec); | ||
5065 | |||
5066 | spin_lock(&codec->power_lock); | ||
5067 | codec->power_transition = 0; | ||
5068 | } | 4760 | } |
4761 | EXPORT_SYMBOL_GPL(snd_hda_power_down); | ||
5069 | 4762 | ||
5070 | #define power_save(codec) \ | 4763 | static void codec_set_power_save(struct hda_codec *codec, int delay) |
5071 | ((codec)->bus->power_save ? *(codec)->bus->power_save : 0) | ||
5072 | |||
5073 | /* Transition to powered down */ | ||
5074 | static void __snd_hda_power_down(struct hda_codec *codec) | ||
5075 | { | 4764 | { |
5076 | if (!codec->power_on || codec->power_count || codec->power_transition) | 4765 | struct device *dev = hda_codec_dev(codec); |
5077 | return; | ||
5078 | 4766 | ||
5079 | if (power_save(codec)) { | 4767 | if (delay > 0) { |
5080 | codec->power_transition = -1; /* avoid reentrance */ | 4768 | pm_runtime_set_autosuspend_delay(dev, delay); |
5081 | queue_delayed_work(codec->bus->workq, &codec->power_work, | 4769 | pm_runtime_use_autosuspend(dev); |
5082 | msecs_to_jiffies(power_save(codec) * 1000)); | 4770 | pm_runtime_allow(dev); |
4771 | if (!pm_runtime_suspended(dev)) | ||
4772 | pm_runtime_mark_last_busy(dev); | ||
4773 | } else { | ||
4774 | pm_runtime_dont_use_autosuspend(dev); | ||
4775 | pm_runtime_forbid(dev); | ||
5083 | } | 4776 | } |
5084 | } | 4777 | } |
5085 | 4778 | ||
5086 | /** | 4779 | /** |
5087 | * snd_hda_power_save - Power-up/down/sync the codec | 4780 | * snd_hda_set_power_save - reprogram autosuspend for the given delay |
5088 | * @codec: HD-audio codec | 4781 | * @bus: HD-audio bus |
5089 | * @delta: the counter delta to change | 4782 | * @delay: autosuspend delay in msec, 0 = off |
5090 | * @d3wait: sync for D3 transition complete | ||
5091 | * | 4783 | * |
5092 | * Change the power-up counter via @delta, and power up or down the hardware | 4784 | * Synchronize the runtime PM autosuspend state from the power_save option. |
5093 | * appropriately. For the power-down, queue to the delayed action. | ||
5094 | * Passing zero to @delta means to synchronize the power state. | ||
5095 | */ | 4785 | */ |
5096 | void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait) | 4786 | void snd_hda_set_power_save(struct hda_bus *bus, int delay) |
5097 | { | 4787 | { |
5098 | spin_lock(&codec->power_lock); | 4788 | struct hda_codec *c; |
5099 | codec->power_count += delta; | 4789 | |
5100 | trace_hda_power_count(codec); | 4790 | list_for_each_entry(c, &bus->codec_list, list) |
5101 | if (delta > 0) | 4791 | codec_set_power_save(c, delay); |
5102 | __snd_hda_power_up(codec, d3wait); | ||
5103 | else | ||
5104 | __snd_hda_power_down(codec); | ||
5105 | spin_unlock(&codec->power_lock); | ||
5106 | } | 4792 | } |
5107 | EXPORT_SYMBOL_GPL(snd_hda_power_save); | 4793 | EXPORT_SYMBOL_GPL(snd_hda_set_power_save); |
5108 | 4794 | ||
5109 | /** | 4795 | /** |
5110 | * snd_hda_check_amp_list_power - Check the amp list and update the power | 4796 | * snd_hda_check_amp_list_power - Check the amp list and update the power |
@@ -5158,88 +4844,6 @@ EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power); | |||
5158 | #endif | 4844 | #endif |
5159 | 4845 | ||
5160 | /* | 4846 | /* |
5161 | * Channel mode helper | ||
5162 | */ | ||
5163 | |||
5164 | /** | ||
5165 | * snd_hda_ch_mode_info - Info callback helper for the channel mode enum | ||
5166 | * @codec: the HDA codec | ||
5167 | * @uinfo: pointer to get/store the data | ||
5168 | * @chmode: channel mode array | ||
5169 | * @num_chmodes: channel mode array size | ||
5170 | */ | ||
5171 | int snd_hda_ch_mode_info(struct hda_codec *codec, | ||
5172 | struct snd_ctl_elem_info *uinfo, | ||
5173 | const struct hda_channel_mode *chmode, | ||
5174 | int num_chmodes) | ||
5175 | { | ||
5176 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
5177 | uinfo->count = 1; | ||
5178 | uinfo->value.enumerated.items = num_chmodes; | ||
5179 | if (uinfo->value.enumerated.item >= num_chmodes) | ||
5180 | uinfo->value.enumerated.item = num_chmodes - 1; | ||
5181 | sprintf(uinfo->value.enumerated.name, "%dch", | ||
5182 | chmode[uinfo->value.enumerated.item].channels); | ||
5183 | return 0; | ||
5184 | } | ||
5185 | EXPORT_SYMBOL_GPL(snd_hda_ch_mode_info); | ||
5186 | |||
5187 | /** | ||
5188 | * snd_hda_ch_mode_get - Get callback helper for the channel mode enum | ||
5189 | * @codec: the HDA codec | ||
5190 | * @ucontrol: pointer to get/store the data | ||
5191 | * @chmode: channel mode array | ||
5192 | * @num_chmodes: channel mode array size | ||
5193 | * @max_channels: max number of channels | ||
5194 | */ | ||
5195 | int snd_hda_ch_mode_get(struct hda_codec *codec, | ||
5196 | struct snd_ctl_elem_value *ucontrol, | ||
5197 | const struct hda_channel_mode *chmode, | ||
5198 | int num_chmodes, | ||
5199 | int max_channels) | ||
5200 | { | ||
5201 | int i; | ||
5202 | |||
5203 | for (i = 0; i < num_chmodes; i++) { | ||
5204 | if (max_channels == chmode[i].channels) { | ||
5205 | ucontrol->value.enumerated.item[0] = i; | ||
5206 | break; | ||
5207 | } | ||
5208 | } | ||
5209 | return 0; | ||
5210 | } | ||
5211 | EXPORT_SYMBOL_GPL(snd_hda_ch_mode_get); | ||
5212 | |||
5213 | /** | ||
5214 | * snd_hda_ch_mode_put - Put callback helper for the channel mode enum | ||
5215 | * @codec: the HDA codec | ||
5216 | * @ucontrol: pointer to get/store the data | ||
5217 | * @chmode: channel mode array | ||
5218 | * @num_chmodes: channel mode array size | ||
5219 | * @max_channelsp: pointer to store the max channels | ||
5220 | */ | ||
5221 | int snd_hda_ch_mode_put(struct hda_codec *codec, | ||
5222 | struct snd_ctl_elem_value *ucontrol, | ||
5223 | const struct hda_channel_mode *chmode, | ||
5224 | int num_chmodes, | ||
5225 | int *max_channelsp) | ||
5226 | { | ||
5227 | unsigned int mode; | ||
5228 | |||
5229 | mode = ucontrol->value.enumerated.item[0]; | ||
5230 | if (mode >= num_chmodes) | ||
5231 | return -EINVAL; | ||
5232 | if (*max_channelsp == chmode[mode].channels) | ||
5233 | return 0; | ||
5234 | /* change the current channel setting */ | ||
5235 | *max_channelsp = chmode[mode].channels; | ||
5236 | if (chmode[mode].sequence) | ||
5237 | snd_hda_sequence_write_cache(codec, chmode[mode].sequence); | ||
5238 | return 1; | ||
5239 | } | ||
5240 | EXPORT_SYMBOL_GPL(snd_hda_ch_mode_put); | ||
5241 | |||
5242 | /* | ||
5243 | * input MUX helper | 4847 | * input MUX helper |
5244 | */ | 4848 | */ |
5245 | 4849 | ||
@@ -5780,77 +5384,26 @@ int snd_hda_add_imux_item(struct hda_codec *codec, | |||
5780 | } | 5384 | } |
5781 | EXPORT_SYMBOL_GPL(snd_hda_add_imux_item); | 5385 | EXPORT_SYMBOL_GPL(snd_hda_add_imux_item); |
5782 | 5386 | ||
5783 | |||
5784 | #ifdef CONFIG_PM | ||
5785 | /* | ||
5786 | * power management | ||
5787 | */ | ||
5788 | |||
5789 | |||
5790 | static void hda_async_suspend(void *data, async_cookie_t cookie) | ||
5791 | { | ||
5792 | hda_call_codec_suspend(data, false); | ||
5793 | } | ||
5794 | |||
5795 | static void hda_async_resume(void *data, async_cookie_t cookie) | ||
5796 | { | ||
5797 | hda_call_codec_resume(data); | ||
5798 | } | ||
5799 | |||
5800 | /** | 5387 | /** |
5801 | * snd_hda_suspend - suspend the codecs | 5388 | * snd_hda_bus_reset - Reset the bus |
5802 | * @bus: the HDA bus | 5389 | * @bus: HD-audio bus |
5803 | * | ||
5804 | * Returns 0 if successful. | ||
5805 | */ | 5390 | */ |
5806 | int snd_hda_suspend(struct hda_bus *bus) | 5391 | void snd_hda_bus_reset(struct hda_bus *bus) |
5807 | { | 5392 | { |
5808 | struct hda_codec *codec; | 5393 | struct hda_codec *codec; |
5809 | ASYNC_DOMAIN_EXCLUSIVE(domain); | ||
5810 | 5394 | ||
5811 | list_for_each_entry(codec, &bus->codec_list, list) { | 5395 | list_for_each_entry(codec, &bus->codec_list, list) { |
5396 | /* FIXME: maybe a better way needed for forced reset */ | ||
5812 | cancel_delayed_work_sync(&codec->jackpoll_work); | 5397 | cancel_delayed_work_sync(&codec->jackpoll_work); |
5398 | #ifdef CONFIG_PM | ||
5813 | if (hda_codec_is_power_on(codec)) { | 5399 | if (hda_codec_is_power_on(codec)) { |
5814 | if (bus->num_codecs > 1) | 5400 | hda_call_codec_suspend(codec); |
5815 | async_schedule_domain(hda_async_suspend, codec, | ||
5816 | &domain); | ||
5817 | else | ||
5818 | hda_call_codec_suspend(codec, false); | ||
5819 | } | ||
5820 | } | ||
5821 | |||
5822 | if (bus->num_codecs > 1) | ||
5823 | async_synchronize_full_domain(&domain); | ||
5824 | |||
5825 | return 0; | ||
5826 | } | ||
5827 | EXPORT_SYMBOL_GPL(snd_hda_suspend); | ||
5828 | |||
5829 | /** | ||
5830 | * snd_hda_resume - resume the codecs | ||
5831 | * @bus: the HDA bus | ||
5832 | * | ||
5833 | * Returns 0 if successful. | ||
5834 | */ | ||
5835 | int snd_hda_resume(struct hda_bus *bus) | ||
5836 | { | ||
5837 | struct hda_codec *codec; | ||
5838 | ASYNC_DOMAIN_EXCLUSIVE(domain); | ||
5839 | |||
5840 | list_for_each_entry(codec, &bus->codec_list, list) { | ||
5841 | if (bus->num_codecs > 1) | ||
5842 | async_schedule_domain(hda_async_resume, codec, &domain); | ||
5843 | else | ||
5844 | hda_call_codec_resume(codec); | 5401 | hda_call_codec_resume(codec); |
5402 | } | ||
5403 | #endif | ||
5845 | } | 5404 | } |
5846 | |||
5847 | if (bus->num_codecs > 1) | ||
5848 | async_synchronize_full_domain(&domain); | ||
5849 | |||
5850 | return 0; | ||
5851 | } | 5405 | } |
5852 | EXPORT_SYMBOL_GPL(snd_hda_resume); | 5406 | EXPORT_SYMBOL_GPL(snd_hda_bus_reset); |
5853 | #endif /* CONFIG_PM */ | ||
5854 | 5407 | ||
5855 | /* | 5408 | /* |
5856 | * generic arrays | 5409 | * generic arrays |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 96421a3b32cd..457fc589eb46 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -83,10 +83,6 @@ struct hda_bus_ops { | |||
83 | struct hda_pcm *pcm); | 83 | struct hda_pcm *pcm); |
84 | /* reset bus for retry verb */ | 84 | /* reset bus for retry verb */ |
85 | void (*bus_reset)(struct hda_bus *bus); | 85 | void (*bus_reset)(struct hda_bus *bus); |
86 | #ifdef CONFIG_PM | ||
87 | /* notify power-up/down from codec to controller */ | ||
88 | void (*pm_notify)(struct hda_bus *bus, bool power_up); | ||
89 | #endif | ||
90 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 86 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
91 | /* prepare DSP transfer */ | 87 | /* prepare DSP transfer */ |
92 | int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format, | 88 | int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format, |
@@ -122,7 +118,6 @@ struct hda_bus { | |||
122 | void *private_data; | 118 | void *private_data; |
123 | struct pci_dev *pci; | 119 | struct pci_dev *pci; |
124 | const char *modelname; | 120 | const char *modelname; |
125 | int *power_save; | ||
126 | struct hda_bus_ops ops; | 121 | struct hda_bus_ops ops; |
127 | 122 | ||
128 | /* codec linked list */ | 123 | /* codec linked list */ |
@@ -151,10 +146,10 @@ struct hda_bus { | |||
151 | unsigned int rirb_error:1; /* error in codec communication */ | 146 | unsigned int rirb_error:1; /* error in codec communication */ |
152 | unsigned int response_reset:1; /* controller was reset */ | 147 | unsigned int response_reset:1; /* controller was reset */ |
153 | unsigned int in_reset:1; /* during reset operation */ | 148 | unsigned int in_reset:1; /* during reset operation */ |
154 | unsigned int power_keep_link_on:1; /* don't power off HDA link */ | ||
155 | unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ | 149 | unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ |
156 | 150 | ||
157 | int primary_dig_out_type; /* primary digital out PCM type */ | 151 | int primary_dig_out_type; /* primary digital out PCM type */ |
152 | unsigned long codec_powered; /* bit flags of powered codecs */ | ||
158 | }; | 153 | }; |
159 | 154 | ||
160 | /* | 155 | /* |
@@ -174,15 +169,22 @@ struct hda_codec_preset { | |||
174 | int (*patch)(struct hda_codec *codec); | 169 | int (*patch)(struct hda_codec *codec); |
175 | }; | 170 | }; |
176 | 171 | ||
177 | struct hda_codec_preset_list { | 172 | #define HDA_CODEC_ID_GENERIC_HDMI 0x00000101 |
173 | #define HDA_CODEC_ID_GENERIC 0x00000201 | ||
174 | |||
175 | struct hda_codec_driver { | ||
176 | struct device_driver driver; | ||
178 | const struct hda_codec_preset *preset; | 177 | const struct hda_codec_preset *preset; |
179 | struct module *owner; | ||
180 | struct list_head list; | ||
181 | }; | 178 | }; |
182 | 179 | ||
183 | /* initial hook */ | 180 | int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, |
184 | int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset); | 181 | struct module *owner); |
185 | int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset); | 182 | #define hda_codec_driver_register(drv) \ |
183 | __hda_codec_driver_register(drv, KBUILD_MODNAME, THIS_MODULE) | ||
184 | void hda_codec_driver_unregister(struct hda_codec_driver *drv); | ||
185 | #define module_hda_codec_driver(drv) \ | ||
186 | module_driver(drv, hda_codec_driver_register, \ | ||
187 | hda_codec_driver_unregister) | ||
186 | 188 | ||
187 | /* ops set by the preset patch */ | 189 | /* ops set by the preset patch */ |
188 | struct hda_codec_ops { | 190 | struct hda_codec_ops { |
@@ -286,11 +288,10 @@ struct hda_codec { | |||
286 | u32 vendor_id; | 288 | u32 vendor_id; |
287 | u32 subsystem_id; | 289 | u32 subsystem_id; |
288 | u32 revision_id; | 290 | u32 revision_id; |
291 | u32 probe_id; /* overridden id for probing */ | ||
289 | 292 | ||
290 | /* detected preset */ | 293 | /* detected preset */ |
291 | const struct hda_codec_preset *preset; | 294 | const struct hda_codec_preset *preset; |
292 | struct module *owner; | ||
293 | int (*parser)(struct hda_codec *codec); | ||
294 | const char *vendor_name; /* codec vendor name */ | 295 | const char *vendor_name; /* codec vendor name */ |
295 | const char *chip_name; /* codec chip name */ | 296 | const char *chip_name; /* codec chip name */ |
296 | const char *modelname; /* model name for preset */ | 297 | const char *modelname; /* model name for preset */ |
@@ -366,17 +367,11 @@ struct hda_codec { | |||
366 | unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */ | 367 | unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */ |
367 | unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ | 368 | unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ |
368 | #ifdef CONFIG_PM | 369 | #ifdef CONFIG_PM |
369 | unsigned int power_on :1; /* current (global) power-state */ | ||
370 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ | 370 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ |
371 | unsigned int pm_up_notified:1; /* PM notified to controller */ | 371 | atomic_t in_pm; /* suspend/resume being performed */ |
372 | unsigned int in_pm:1; /* suspend/resume being performed */ | ||
373 | int power_transition; /* power-state in transition */ | ||
374 | int power_count; /* current (global) power refcount */ | ||
375 | struct delayed_work power_work; /* delayed task for powerdown */ | ||
376 | unsigned long power_on_acct; | 372 | unsigned long power_on_acct; |
377 | unsigned long power_off_acct; | 373 | unsigned long power_off_acct; |
378 | unsigned long power_jiffies; | 374 | unsigned long power_jiffies; |
379 | spinlock_t power_lock; | ||
380 | #endif | 375 | #endif |
381 | 376 | ||
382 | /* filter the requested power state per nid */ | 377 | /* filter the requested power state per nid */ |
@@ -408,6 +403,11 @@ struct hda_codec { | |||
408 | struct snd_array verbs; | 403 | struct snd_array verbs; |
409 | }; | 404 | }; |
410 | 405 | ||
406 | #define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, dev) | ||
407 | #define hda_codec_dev(_dev) (&(_dev)->dev) | ||
408 | |||
409 | extern struct bus_type snd_hda_bus_type; | ||
410 | |||
411 | /* direction */ | 411 | /* direction */ |
412 | enum { | 412 | enum { |
413 | HDA_INPUT, HDA_OUTPUT | 413 | HDA_INPUT, HDA_OUTPUT |
@@ -556,14 +556,12 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | |||
556 | 556 | ||
557 | int snd_hda_lock_devices(struct hda_bus *bus); | 557 | int snd_hda_lock_devices(struct hda_bus *bus); |
558 | void snd_hda_unlock_devices(struct hda_bus *bus); | 558 | void snd_hda_unlock_devices(struct hda_bus *bus); |
559 | void snd_hda_bus_reset(struct hda_bus *bus); | ||
559 | 560 | ||
560 | /* | 561 | /* |
561 | * power management | 562 | * power management |
562 | */ | 563 | */ |
563 | #ifdef CONFIG_PM | 564 | extern const struct dev_pm_ops hda_codec_driver_pm; |
564 | int snd_hda_suspend(struct hda_bus *bus); | ||
565 | int snd_hda_resume(struct hda_bus *bus); | ||
566 | #endif | ||
567 | 565 | ||
568 | static inline | 566 | static inline |
569 | int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 567 | int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
@@ -586,64 +584,16 @@ const char *snd_hda_get_jack_location(u32 cfg); | |||
586 | * power saving | 584 | * power saving |
587 | */ | 585 | */ |
588 | #ifdef CONFIG_PM | 586 | #ifdef CONFIG_PM |
589 | void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait); | 587 | void snd_hda_power_up(struct hda_codec *codec); |
588 | void snd_hda_power_down(struct hda_codec *codec); | ||
589 | void snd_hda_set_power_save(struct hda_bus *bus, int delay); | ||
590 | void snd_hda_update_power_acct(struct hda_codec *codec); | 590 | void snd_hda_update_power_acct(struct hda_codec *codec); |
591 | #else | 591 | #else |
592 | static inline void snd_hda_power_save(struct hda_codec *codec, int delta, | 592 | static inline void snd_hda_power_up(struct hda_codec *codec) {} |
593 | bool d3wait) {} | 593 | static inline void snd_hda_power_down(struct hda_codec *codec) {} |
594 | static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {} | ||
594 | #endif | 595 | #endif |
595 | 596 | ||
596 | /** | ||
597 | * snd_hda_power_up - Power-up the codec | ||
598 | * @codec: HD-audio codec | ||
599 | * | ||
600 | * Increment the power-up counter and power up the hardware really when | ||
601 | * not turned on yet. | ||
602 | */ | ||
603 | static inline void snd_hda_power_up(struct hda_codec *codec) | ||
604 | { | ||
605 | snd_hda_power_save(codec, 1, false); | ||
606 | } | ||
607 | |||
608 | /** | ||
609 | * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending | ||
610 | * D3 transition to complete. This differs from snd_hda_power_up() when | ||
611 | * power_transition == -1. snd_hda_power_up sees this case as a nop, | ||
612 | * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers | ||
613 | * back up. | ||
614 | * @codec: HD-audio codec | ||
615 | * | ||
616 | * Cancel any power down operation hapenning on the work queue, then power up. | ||
617 | */ | ||
618 | static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) | ||
619 | { | ||
620 | snd_hda_power_save(codec, 1, true); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * snd_hda_power_down - Power-down the codec | ||
625 | * @codec: HD-audio codec | ||
626 | * | ||
627 | * Decrement the power-up counter and schedules the power-off work if | ||
628 | * the counter rearches to zero. | ||
629 | */ | ||
630 | static inline void snd_hda_power_down(struct hda_codec *codec) | ||
631 | { | ||
632 | snd_hda_power_save(codec, -1, false); | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * snd_hda_power_sync - Synchronize the power-save status | ||
637 | * @codec: HD-audio codec | ||
638 | * | ||
639 | * Synchronize the actual power state with the power account; | ||
640 | * called when power_save parameter is changed | ||
641 | */ | ||
642 | static inline void snd_hda_power_sync(struct hda_codec *codec) | ||
643 | { | ||
644 | snd_hda_power_save(codec, 0, false); | ||
645 | } | ||
646 | |||
647 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 597 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
648 | /* | 598 | /* |
649 | * patch firmware | 599 | * patch firmware |
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 2e73a59f3f71..a438e8540763 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -258,11 +258,18 @@ static void azx_timecounter_init(struct snd_pcm_substream *substream, | |||
258 | tc->cycle_last = last; | 258 | tc->cycle_last = last; |
259 | } | 259 | } |
260 | 260 | ||
261 | static inline struct hda_pcm_stream * | ||
262 | to_hda_pcm_stream(struct snd_pcm_substream *substream) | ||
263 | { | ||
264 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
265 | return &apcm->info->stream[substream->stream]; | ||
266 | } | ||
267 | |||
261 | static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream, | 268 | static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream, |
262 | u64 nsec) | 269 | u64 nsec) |
263 | { | 270 | { |
264 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 271 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
265 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 272 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
266 | u64 codec_frames, codec_nsecs; | 273 | u64 codec_frames, codec_nsecs; |
267 | 274 | ||
268 | if (!hinfo->ops.get_delay) | 275 | if (!hinfo->ops.get_delay) |
@@ -398,7 +405,7 @@ static int azx_setup_periods(struct azx *chip, | |||
398 | static int azx_pcm_close(struct snd_pcm_substream *substream) | 405 | static int azx_pcm_close(struct snd_pcm_substream *substream) |
399 | { | 406 | { |
400 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 407 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
401 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 408 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
402 | struct azx *chip = apcm->chip; | 409 | struct azx *chip = apcm->chip; |
403 | struct azx_dev *azx_dev = get_azx_dev(substream); | 410 | struct azx_dev *azx_dev = get_azx_dev(substream); |
404 | unsigned long flags; | 411 | unsigned long flags; |
@@ -440,7 +447,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
440 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 447 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
441 | struct azx_dev *azx_dev = get_azx_dev(substream); | 448 | struct azx_dev *azx_dev = get_azx_dev(substream); |
442 | struct azx *chip = apcm->chip; | 449 | struct azx *chip = apcm->chip; |
443 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 450 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
444 | int err; | 451 | int err; |
445 | 452 | ||
446 | /* reset BDL address */ | 453 | /* reset BDL address */ |
@@ -467,7 +474,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
467 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 474 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
468 | struct azx *chip = apcm->chip; | 475 | struct azx *chip = apcm->chip; |
469 | struct azx_dev *azx_dev = get_azx_dev(substream); | 476 | struct azx_dev *azx_dev = get_azx_dev(substream); |
470 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 477 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
471 | struct snd_pcm_runtime *runtime = substream->runtime; | 478 | struct snd_pcm_runtime *runtime = substream->runtime; |
472 | unsigned int bufsize, period_bytes, format_val, stream_tag; | 479 | unsigned int bufsize, period_bytes, format_val, stream_tag; |
473 | int err; | 480 | int err; |
@@ -707,7 +714,7 @@ unsigned int azx_get_position(struct azx *chip, | |||
707 | 714 | ||
708 | if (substream->runtime) { | 715 | if (substream->runtime) { |
709 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 716 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
710 | struct hda_pcm_stream *hinfo = apcm->hinfo[stream]; | 717 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
711 | 718 | ||
712 | if (chip->get_delay[stream]) | 719 | if (chip->get_delay[stream]) |
713 | delay += chip->get_delay[stream](chip, azx_dev, pos); | 720 | delay += chip->get_delay[stream](chip, azx_dev, pos); |
@@ -790,7 +797,7 @@ static struct snd_pcm_hardware azx_pcm_hw = { | |||
790 | static int azx_pcm_open(struct snd_pcm_substream *substream) | 797 | static int azx_pcm_open(struct snd_pcm_substream *substream) |
791 | { | 798 | { |
792 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 799 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
793 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 800 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
794 | struct azx *chip = apcm->chip; | 801 | struct azx *chip = apcm->chip; |
795 | struct azx_dev *azx_dev; | 802 | struct azx_dev *azx_dev; |
796 | struct snd_pcm_runtime *runtime = substream->runtime; | 803 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -836,7 +843,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
836 | buff_step); | 843 | buff_step); |
837 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 844 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
838 | buff_step); | 845 | buff_step); |
839 | snd_hda_power_up_d3wait(apcm->codec); | 846 | snd_hda_power_up(apcm->codec); |
840 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | 847 | err = hinfo->ops.open(hinfo, apcm->codec, substream); |
841 | if (err < 0) { | 848 | if (err < 0) { |
842 | azx_release_device(azx_dev); | 849 | azx_release_device(azx_dev); |
@@ -904,6 +911,7 @@ static void azx_pcm_free(struct snd_pcm *pcm) | |||
904 | struct azx_pcm *apcm = pcm->private_data; | 911 | struct azx_pcm *apcm = pcm->private_data; |
905 | if (apcm) { | 912 | if (apcm) { |
906 | list_del(&apcm->list); | 913 | list_del(&apcm->list); |
914 | apcm->info->pcm = NULL; | ||
907 | kfree(apcm); | 915 | kfree(apcm); |
908 | } | 916 | } |
909 | } | 917 | } |
@@ -940,6 +948,7 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
940 | apcm->chip = chip; | 948 | apcm->chip = chip; |
941 | apcm->pcm = pcm; | 949 | apcm->pcm = pcm; |
942 | apcm->codec = codec; | 950 | apcm->codec = codec; |
951 | apcm->info = cpcm; | ||
943 | pcm->private_data = apcm; | 952 | pcm->private_data = apcm; |
944 | pcm->private_free = azx_pcm_free; | 953 | pcm->private_free = azx_pcm_free; |
945 | if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) | 954 | if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) |
@@ -947,7 +956,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
947 | list_add_tail(&apcm->list, &chip->pcm_list); | 956 | list_add_tail(&apcm->list, &chip->pcm_list); |
948 | cpcm->pcm = pcm; | 957 | cpcm->pcm = pcm; |
949 | for (s = 0; s < 2; s++) { | 958 | for (s = 0; s < 2; s++) { |
950 | apcm->hinfo[s] = &cpcm->stream[s]; | ||
951 | if (cpcm->stream[s].substreams) | 959 | if (cpcm->stream[s].substreams) |
952 | snd_pcm_set_ops(pcm, s, &azx_pcm_ops); | 960 | snd_pcm_set_ops(pcm, s, &azx_pcm_ops); |
953 | } | 961 | } |
@@ -958,9 +966,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
958 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, | 966 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, |
959 | chip->card->dev, | 967 | chip->card->dev, |
960 | size, MAX_PREALLOC_SIZE); | 968 | size, MAX_PREALLOC_SIZE); |
961 | /* link to codec */ | ||
962 | for (s = 0; s < 2; s++) | ||
963 | pcm->streams[s].dev.parent = &codec->dev; | ||
964 | return 0; | 969 | return 0; |
965 | } | 970 | } |
966 | 971 | ||
@@ -1778,34 +1783,11 @@ static void azx_bus_reset(struct hda_bus *bus) | |||
1778 | bus->in_reset = 1; | 1783 | bus->in_reset = 1; |
1779 | azx_stop_chip(chip); | 1784 | azx_stop_chip(chip); |
1780 | azx_init_chip(chip, true); | 1785 | azx_init_chip(chip, true); |
1781 | #ifdef CONFIG_PM | 1786 | if (chip->initialized) |
1782 | if (chip->initialized) { | 1787 | snd_hda_bus_reset(chip->bus); |
1783 | struct azx_pcm *p; | ||
1784 | list_for_each_entry(p, &chip->pcm_list, list) | ||
1785 | snd_pcm_suspend_all(p->pcm); | ||
1786 | snd_hda_suspend(chip->bus); | ||
1787 | snd_hda_resume(chip->bus); | ||
1788 | } | ||
1789 | #endif | ||
1790 | bus->in_reset = 0; | 1788 | bus->in_reset = 0; |
1791 | } | 1789 | } |
1792 | 1790 | ||
1793 | #ifdef CONFIG_PM | ||
1794 | /* power-up/down the controller */ | ||
1795 | static void azx_power_notify(struct hda_bus *bus, bool power_up) | ||
1796 | { | ||
1797 | struct azx *chip = bus->private_data; | ||
1798 | |||
1799 | if (!azx_has_pm_runtime(chip)) | ||
1800 | return; | ||
1801 | |||
1802 | if (power_up) | ||
1803 | pm_runtime_get_sync(chip->card->dev); | ||
1804 | else | ||
1805 | pm_runtime_put_sync(chip->card->dev); | ||
1806 | } | ||
1807 | #endif | ||
1808 | |||
1809 | static int get_jackpoll_interval(struct azx *chip) | 1791 | static int get_jackpoll_interval(struct azx *chip) |
1810 | { | 1792 | { |
1811 | int i; | 1793 | int i; |
@@ -1832,9 +1814,6 @@ static struct hda_bus_ops bus_ops = { | |||
1832 | .get_response = azx_get_response, | 1814 | .get_response = azx_get_response, |
1833 | .attach_pcm = azx_attach_pcm_stream, | 1815 | .attach_pcm = azx_attach_pcm_stream, |
1834 | .bus_reset = azx_bus_reset, | 1816 | .bus_reset = azx_bus_reset, |
1835 | #ifdef CONFIG_PM | ||
1836 | .pm_notify = azx_power_notify, | ||
1837 | #endif | ||
1838 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 1817 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
1839 | .load_dsp_prepare = azx_load_dsp_prepare, | 1818 | .load_dsp_prepare = azx_load_dsp_prepare, |
1840 | .load_dsp_trigger = azx_load_dsp_trigger, | 1819 | .load_dsp_trigger = azx_load_dsp_trigger, |
@@ -1843,7 +1822,7 @@ static struct hda_bus_ops bus_ops = { | |||
1843 | }; | 1822 | }; |
1844 | 1823 | ||
1845 | /* HD-audio bus initialization */ | 1824 | /* HD-audio bus initialization */ |
1846 | int azx_bus_create(struct azx *chip, const char *model, int *power_save_to) | 1825 | int azx_bus_create(struct azx *chip, const char *model) |
1847 | { | 1826 | { |
1848 | struct hda_bus *bus; | 1827 | struct hda_bus *bus; |
1849 | int err; | 1828 | int err; |
@@ -1857,9 +1836,6 @@ int azx_bus_create(struct azx *chip, const char *model, int *power_save_to) | |||
1857 | bus->pci = chip->pci; | 1836 | bus->pci = chip->pci; |
1858 | bus->modelname = model; | 1837 | bus->modelname = model; |
1859 | bus->ops = bus_ops; | 1838 | bus->ops = bus_ops; |
1860 | #ifdef CONFIG_PM | ||
1861 | bus->power_save = power_save_to; | ||
1862 | #endif | ||
1863 | 1839 | ||
1864 | if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { | 1840 | if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { |
1865 | dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); | 1841 | dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); |
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 0d09aa6b49ac..94c1a4719f7f 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h | |||
@@ -283,7 +283,7 @@ struct azx_pcm { | |||
283 | struct azx *chip; | 283 | struct azx *chip; |
284 | struct snd_pcm *pcm; | 284 | struct snd_pcm *pcm; |
285 | struct hda_codec *codec; | 285 | struct hda_codec *codec; |
286 | struct hda_pcm_stream *hinfo[2]; | 286 | struct hda_pcm *info; |
287 | struct list_head list; | 287 | struct list_head list; |
288 | }; | 288 | }; |
289 | 289 | ||
@@ -432,7 +432,7 @@ void azx_enter_link_reset(struct azx *chip); | |||
432 | irqreturn_t azx_interrupt(int irq, void *dev_id); | 432 | irqreturn_t azx_interrupt(int irq, void *dev_id); |
433 | 433 | ||
434 | /* Codec interface */ | 434 | /* Codec interface */ |
435 | int azx_bus_create(struct azx *chip, const char *model, int *power_save_to); | 435 | int azx_bus_create(struct azx *chip, const char *model); |
436 | int azx_probe_codecs(struct azx *chip, unsigned int max_slots); | 436 | int azx_probe_codecs(struct azx *chip, unsigned int max_slots); |
437 | int azx_codec_configure(struct azx *chip); | 437 | int azx_codec_configure(struct azx *chip); |
438 | int azx_init_stream(struct azx *chip); | 438 | int azx_init_stream(struct azx *chip); |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 8ec5289f8e05..43ad51c672d6 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -5524,13 +5524,11 @@ static const struct hda_codec_ops generic_patch_ops = { | |||
5524 | #endif | 5524 | #endif |
5525 | }; | 5525 | }; |
5526 | 5526 | ||
5527 | /** | 5527 | /* |
5528 | * snd_hda_parse_generic_codec - Generic codec parser | 5528 | * snd_hda_parse_generic_codec - Generic codec parser |
5529 | * @codec: the HDA codec | 5529 | * @codec: the HDA codec |
5530 | * | ||
5531 | * This should be called from the HDA codec core. | ||
5532 | */ | 5530 | */ |
5533 | int snd_hda_parse_generic_codec(struct hda_codec *codec) | 5531 | static int snd_hda_parse_generic_codec(struct hda_codec *codec) |
5534 | { | 5532 | { |
5535 | struct hda_gen_spec *spec; | 5533 | struct hda_gen_spec *spec; |
5536 | int err; | 5534 | int err; |
@@ -5556,7 +5554,17 @@ error: | |||
5556 | snd_hda_gen_free(codec); | 5554 | snd_hda_gen_free(codec); |
5557 | return err; | 5555 | return err; |
5558 | } | 5556 | } |
5559 | EXPORT_SYMBOL_GPL(snd_hda_parse_generic_codec); | 5557 | |
5558 | static const struct hda_codec_preset snd_hda_preset_generic[] = { | ||
5559 | { .id = HDA_CODEC_ID_GENERIC, .patch = snd_hda_parse_generic_codec }, | ||
5560 | {} /* terminator */ | ||
5561 | }; | ||
5562 | |||
5563 | static struct hda_codec_driver generic_driver = { | ||
5564 | .preset = snd_hda_preset_generic, | ||
5565 | }; | ||
5566 | |||
5567 | module_hda_codec_driver(generic_driver); | ||
5560 | 5568 | ||
5561 | MODULE_LICENSE("GPL"); | 5569 | MODULE_LICENSE("GPL"); |
5562 | MODULE_DESCRIPTION("Generic HD-audio codec parser"); | 5570 | MODULE_DESCRIPTION("Generic HD-audio codec parser"); |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 11b5a42b4ec8..125f3420fa6a 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -116,9 +116,6 @@ int snd_hda_create_hwdep(struct hda_codec *codec) | |||
116 | hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; | 116 | hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; |
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | /* link to codec */ | ||
120 | hwdep->dev.parent = &codec->dev; | ||
121 | |||
122 | /* for sysfs */ | 119 | /* for sysfs */ |
123 | hwdep->dev.groups = snd_hda_dev_attr_groups; | 120 | hwdep->dev.groups = snd_hda_dev_attr_groups; |
124 | dev_set_drvdata(&hwdep->dev, codec); | 121 | dev_set_drvdata(&hwdep->dev, codec); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4614cb1f9582..13529715bc55 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -173,7 +173,6 @@ static struct kernel_param_ops param_ops_xint = { | |||
173 | #define param_check_xint param_check_int | 173 | #define param_check_xint param_check_int |
174 | 174 | ||
175 | static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; | 175 | static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; |
176 | static int *power_save_addr = &power_save; | ||
177 | module_param(power_save, xint, 0644); | 176 | module_param(power_save, xint, 0644); |
178 | MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " | 177 | MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " |
179 | "(in second, 0 = disable)."); | 178 | "(in second, 0 = disable)."); |
@@ -186,7 +185,7 @@ static bool power_save_controller = 1; | |||
186 | module_param(power_save_controller, bool, 0644); | 185 | module_param(power_save_controller, bool, 0644); |
187 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 186 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
188 | #else | 187 | #else |
189 | static int *power_save_addr; | 188 | #define power_save 0 |
190 | #endif /* CONFIG_PM */ | 189 | #endif /* CONFIG_PM */ |
191 | 190 | ||
192 | static int align_buffer_size = -1; | 191 | static int align_buffer_size = -1; |
@@ -740,7 +739,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) | |||
740 | { | 739 | { |
741 | struct hda_intel *hda; | 740 | struct hda_intel *hda; |
742 | struct azx *chip; | 741 | struct azx *chip; |
743 | struct hda_codec *c; | ||
744 | int prev = power_save; | 742 | int prev = power_save; |
745 | int ret = param_set_int(val, kp); | 743 | int ret = param_set_int(val, kp); |
746 | 744 | ||
@@ -752,8 +750,7 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) | |||
752 | chip = &hda->chip; | 750 | chip = &hda->chip; |
753 | if (!chip->bus || chip->disabled) | 751 | if (!chip->bus || chip->disabled) |
754 | continue; | 752 | continue; |
755 | list_for_each_entry(c, &chip->bus->codec_list, list) | 753 | snd_hda_set_power_save(chip->bus, power_save * 1000); |
756 | snd_hda_power_sync(c); | ||
757 | } | 754 | } |
758 | mutex_unlock(&card_list_lock); | 755 | mutex_unlock(&card_list_lock); |
759 | return 0; | 756 | return 0; |
@@ -772,7 +769,6 @@ static int azx_suspend(struct device *dev) | |||
772 | struct snd_card *card = dev_get_drvdata(dev); | 769 | struct snd_card *card = dev_get_drvdata(dev); |
773 | struct azx *chip; | 770 | struct azx *chip; |
774 | struct hda_intel *hda; | 771 | struct hda_intel *hda; |
775 | struct azx_pcm *p; | ||
776 | 772 | ||
777 | if (!card) | 773 | if (!card) |
778 | return 0; | 774 | return 0; |
@@ -784,10 +780,6 @@ static int azx_suspend(struct device *dev) | |||
784 | 780 | ||
785 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 781 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
786 | azx_clear_irq_pending(chip); | 782 | azx_clear_irq_pending(chip); |
787 | list_for_each_entry(p, &chip->pcm_list, list) | ||
788 | snd_pcm_suspend_all(p->pcm); | ||
789 | if (chip->initialized) | ||
790 | snd_hda_suspend(chip->bus); | ||
791 | azx_stop_chip(chip); | 783 | azx_stop_chip(chip); |
792 | azx_enter_link_reset(chip); | 784 | azx_enter_link_reset(chip); |
793 | if (chip->irq >= 0) { | 785 | if (chip->irq >= 0) { |
@@ -830,7 +822,6 @@ static int azx_resume(struct device *dev) | |||
830 | 822 | ||
831 | azx_init_chip(chip, true); | 823 | azx_init_chip(chip, true); |
832 | 824 | ||
833 | snd_hda_resume(chip->bus); | ||
834 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 825 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
835 | return 0; | 826 | return 0; |
836 | } | 827 | } |
@@ -927,7 +918,8 @@ static int azx_runtime_idle(struct device *dev) | |||
927 | if (chip->disabled || hda->init_failed) | 918 | if (chip->disabled || hda->init_failed) |
928 | return 0; | 919 | return 0; |
929 | 920 | ||
930 | if (!power_save_controller || !azx_has_pm_runtime(chip)) | 921 | if (!power_save_controller || !azx_has_pm_runtime(chip) || |
922 | chip->bus->codec_powered) | ||
931 | return -EBUSY; | 923 | return -EBUSY; |
932 | 924 | ||
933 | return 0; | 925 | return 0; |
@@ -1612,19 +1604,6 @@ static int azx_first_init(struct azx *chip) | |||
1612 | return 0; | 1604 | return 0; |
1613 | } | 1605 | } |
1614 | 1606 | ||
1615 | static void power_down_all_codecs(struct azx *chip) | ||
1616 | { | ||
1617 | #ifdef CONFIG_PM | ||
1618 | /* The codecs were powered up in snd_hda_codec_new(). | ||
1619 | * Now all initialization done, so turn them down if possible | ||
1620 | */ | ||
1621 | struct hda_codec *codec; | ||
1622 | list_for_each_entry(codec, &chip->bus->codec_list, list) { | ||
1623 | snd_hda_power_down(codec); | ||
1624 | } | ||
1625 | #endif | ||
1626 | } | ||
1627 | |||
1628 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 1607 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
1629 | /* callback from request_firmware_nowait() */ | 1608 | /* callback from request_firmware_nowait() */ |
1630 | static void azx_firmware_cb(const struct firmware *fw, void *context) | 1609 | static void azx_firmware_cb(const struct firmware *fw, void *context) |
@@ -1893,7 +1872,7 @@ static int azx_probe_continue(struct azx *chip) | |||
1893 | #endif | 1872 | #endif |
1894 | 1873 | ||
1895 | /* create codec instances */ | 1874 | /* create codec instances */ |
1896 | err = azx_bus_create(chip, model[dev], power_save_addr); | 1875 | err = azx_bus_create(chip, model[dev]); |
1897 | if (err < 0) | 1876 | if (err < 0) |
1898 | goto out_free; | 1877 | goto out_free; |
1899 | 1878 | ||
@@ -1934,9 +1913,9 @@ static int azx_probe_continue(struct azx *chip) | |||
1934 | goto out_free; | 1913 | goto out_free; |
1935 | 1914 | ||
1936 | chip->running = 1; | 1915 | chip->running = 1; |
1937 | power_down_all_codecs(chip); | ||
1938 | azx_notifier_register(chip); | 1916 | azx_notifier_register(chip); |
1939 | azx_add_card_list(chip); | 1917 | azx_add_card_list(chip); |
1918 | snd_hda_set_power_save(chip->bus, power_save * 1000); | ||
1940 | if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) | 1919 | if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) |
1941 | pm_runtime_put_noidle(&pci->dev); | 1920 | pm_runtime_put_noidle(&pci->dev); |
1942 | 1921 | ||
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 49c08a7278c4..8588813163e3 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -273,29 +273,6 @@ int snd_hda_add_imux_item(struct hda_codec *codec, | |||
273 | int index, int *type_index_ret); | 273 | int index, int *type_index_ret); |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * Channel mode helper | ||
277 | */ | ||
278 | struct hda_channel_mode { | ||
279 | int channels; | ||
280 | const struct hda_verb *sequence; | ||
281 | }; | ||
282 | |||
283 | int snd_hda_ch_mode_info(struct hda_codec *codec, | ||
284 | struct snd_ctl_elem_info *uinfo, | ||
285 | const struct hda_channel_mode *chmode, | ||
286 | int num_chmodes); | ||
287 | int snd_hda_ch_mode_get(struct hda_codec *codec, | ||
288 | struct snd_ctl_elem_value *ucontrol, | ||
289 | const struct hda_channel_mode *chmode, | ||
290 | int num_chmodes, | ||
291 | int max_channels); | ||
292 | int snd_hda_ch_mode_put(struct hda_codec *codec, | ||
293 | struct snd_ctl_elem_value *ucontrol, | ||
294 | const struct hda_channel_mode *chmode, | ||
295 | int num_chmodes, | ||
296 | int *max_channelsp); | ||
297 | |||
298 | /* | ||
299 | * Multi-channel / digital-out PCM helper | 276 | * Multi-channel / digital-out PCM helper |
300 | */ | 277 | */ |
301 | 278 | ||
@@ -351,12 +328,6 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | |||
351 | struct hda_multi_out *mout); | 328 | struct hda_multi_out *mout); |
352 | 329 | ||
353 | /* | 330 | /* |
354 | * generic codec parser | ||
355 | */ | ||
356 | int snd_hda_parse_generic_codec(struct hda_codec *codec); | ||
357 | int snd_hda_parse_hdmi_codec(struct hda_codec *codec); | ||
358 | |||
359 | /* | ||
360 | * generic proc interface | 331 | * generic proc interface |
361 | */ | 332 | */ |
362 | #ifdef CONFIG_PROC_FS | 333 | #ifdef CONFIG_PROC_FS |
@@ -783,9 +754,13 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); | |||
783 | 754 | ||
784 | /* | 755 | /* |
785 | */ | 756 | */ |
786 | #define codec_err(codec, fmt, args...) dev_err(&(codec)->dev, fmt, ##args) | 757 | #define codec_err(codec, fmt, args...) \ |
787 | #define codec_warn(codec, fmt, args...) dev_warn(&(codec)->dev, fmt, ##args) | 758 | dev_err(hda_codec_dev(codec), fmt, ##args) |
788 | #define codec_info(codec, fmt, args...) dev_info(&(codec)->dev, fmt, ##args) | 759 | #define codec_warn(codec, fmt, args...) \ |
789 | #define codec_dbg(codec, fmt, args...) dev_dbg(&(codec)->dev, fmt, ##args) | 760 | dev_warn(hda_codec_dev(codec), fmt, ##args) |
761 | #define codec_info(codec, fmt, args...) \ | ||
762 | dev_info(hda_codec_dev(codec), fmt, ##args) | ||
763 | #define codec_dbg(codec, fmt, args...) \ | ||
764 | dev_dbg(hda_codec_dev(codec), fmt, ##args) | ||
790 | 765 | ||
791 | #endif /* __SOUND_HDA_LOCAL_H */ | 766 | #endif /* __SOUND_HDA_LOCAL_H */ |
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 1bd7a9e04046..1359fdd20f02 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c | |||
@@ -81,7 +81,7 @@ module_param(power_save, bint, 0644); | |||
81 | MODULE_PARM_DESC(power_save, | 81 | MODULE_PARM_DESC(power_save, |
82 | "Automatic power-saving timeout (in seconds, 0 = disable)."); | 82 | "Automatic power-saving timeout (in seconds, 0 = disable)."); |
83 | #else | 83 | #else |
84 | static int power_save = 0; | 84 | #define power_save 0 |
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | /* | 87 | /* |
@@ -249,14 +249,9 @@ static int hda_tegra_suspend(struct device *dev) | |||
249 | { | 249 | { |
250 | struct snd_card *card = dev_get_drvdata(dev); | 250 | struct snd_card *card = dev_get_drvdata(dev); |
251 | struct azx *chip = card->private_data; | 251 | struct azx *chip = card->private_data; |
252 | struct azx_pcm *p; | ||
253 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); | 252 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); |
254 | 253 | ||
255 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 254 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
256 | list_for_each_entry(p, &chip->pcm_list, list) | ||
257 | snd_pcm_suspend_all(p->pcm); | ||
258 | if (chip->initialized) | ||
259 | snd_hda_suspend(chip->bus); | ||
260 | 255 | ||
261 | azx_stop_chip(chip); | 256 | azx_stop_chip(chip); |
262 | azx_enter_link_reset(chip); | 257 | azx_enter_link_reset(chip); |
@@ -277,7 +272,6 @@ static int hda_tegra_resume(struct device *dev) | |||
277 | 272 | ||
278 | azx_init_chip(chip, 1); | 273 | azx_init_chip(chip, 1); |
279 | 274 | ||
280 | snd_hda_resume(chip->bus); | ||
281 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 275 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
282 | 276 | ||
283 | return 0; | 277 | return 0; |
@@ -343,17 +337,6 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) | |||
343 | return 0; | 337 | return 0; |
344 | } | 338 | } |
345 | 339 | ||
346 | /* | ||
347 | * The codecs were powered up in snd_hda_codec_new(). | ||
348 | * Now all initialization done, so turn them down if possible | ||
349 | */ | ||
350 | static void power_down_all_codecs(struct azx *chip) | ||
351 | { | ||
352 | struct hda_codec *codec; | ||
353 | list_for_each_entry(codec, &chip->bus->codec_list, list) | ||
354 | snd_hda_power_down(codec); | ||
355 | } | ||
356 | |||
357 | static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) | 340 | static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) |
358 | { | 341 | { |
359 | struct snd_card *card = chip->card; | 342 | struct snd_card *card = chip->card; |
@@ -502,7 +485,7 @@ static int hda_tegra_probe(struct platform_device *pdev) | |||
502 | goto out_free; | 485 | goto out_free; |
503 | 486 | ||
504 | /* create codec instances */ | 487 | /* create codec instances */ |
505 | err = azx_bus_create(chip, NULL, &power_save); | 488 | err = azx_bus_create(chip, NULL); |
506 | if (err < 0) | 489 | if (err < 0) |
507 | goto out_free; | 490 | goto out_free; |
508 | 491 | ||
@@ -529,8 +512,8 @@ static int hda_tegra_probe(struct platform_device *pdev) | |||
529 | goto out_free; | 512 | goto out_free; |
530 | 513 | ||
531 | chip->running = 1; | 514 | chip->running = 1; |
532 | power_down_all_codecs(chip); | ||
533 | azx_notifier_register(chip); | 515 | azx_notifier_register(chip); |
516 | snd_hda_set_power_save(chip->bus, power_save * 1000); | ||
534 | 517 | ||
535 | return 0; | 518 | return 0; |
536 | 519 | ||
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h index 3a1c63161eb1..c0e1c7d24dbe 100644 --- a/sound/pci/hda/hda_trace.h +++ b/sound/pci/hda/hda_trace.h | |||
@@ -87,30 +87,6 @@ DEFINE_EVENT(hda_power, hda_power_up, | |||
87 | TP_PROTO(struct hda_codec *codec), | 87 | TP_PROTO(struct hda_codec *codec), |
88 | TP_ARGS(codec) | 88 | TP_ARGS(codec) |
89 | ); | 89 | ); |
90 | |||
91 | TRACE_EVENT(hda_power_count, | ||
92 | TP_PROTO(struct hda_codec *codec), | ||
93 | TP_ARGS(codec), | ||
94 | TP_STRUCT__entry( | ||
95 | __field( unsigned int, card ) | ||
96 | __field( unsigned int, addr ) | ||
97 | __field( int, power_count ) | ||
98 | __field( int, power_on ) | ||
99 | __field( int, power_transition ) | ||
100 | ), | ||
101 | |||
102 | TP_fast_assign( | ||
103 | __entry->card = (codec)->bus->card->number; | ||
104 | __entry->addr = (codec)->addr; | ||
105 | __entry->power_count = (codec)->power_count; | ||
106 | __entry->power_on = (codec)->power_on; | ||
107 | __entry->power_transition = (codec)->power_transition; | ||
108 | ), | ||
109 | |||
110 | TP_printk("[%d:%d] power_count=%d, power_on=%d, power_transition=%d", | ||
111 | __entry->card, __entry->addr, __entry->power_count, | ||
112 | __entry->power_on, __entry->power_transition) | ||
113 | ); | ||
114 | #endif /* CONFIG_PM */ | 90 | #endif /* CONFIG_PM */ |
115 | 91 | ||
116 | TRACE_EVENT(hda_unsol_event, | 92 | TRACE_EVENT(hda_unsol_event, |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index d285904cdb64..af4c7be86c27 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1194,20 +1194,8 @@ MODULE_ALIAS("snd-hda-codec-id:11d4*"); | |||
1194 | MODULE_LICENSE("GPL"); | 1194 | MODULE_LICENSE("GPL"); |
1195 | MODULE_DESCRIPTION("Analog Devices HD-audio codec"); | 1195 | MODULE_DESCRIPTION("Analog Devices HD-audio codec"); |
1196 | 1196 | ||
1197 | static struct hda_codec_preset_list analog_list = { | 1197 | static struct hda_codec_driver analog_driver = { |
1198 | .preset = snd_hda_preset_analog, | 1198 | .preset = snd_hda_preset_analog, |
1199 | .owner = THIS_MODULE, | ||
1200 | }; | 1199 | }; |
1201 | 1200 | ||
1202 | static int __init patch_analog_init(void) | 1201 | module_hda_codec_driver(analog_driver); |
1203 | { | ||
1204 | return snd_hda_add_codec_preset(&analog_list); | ||
1205 | } | ||
1206 | |||
1207 | static void __exit patch_analog_exit(void) | ||
1208 | { | ||
1209 | snd_hda_delete_codec_preset(&analog_list); | ||
1210 | } | ||
1211 | |||
1212 | module_init(patch_analog_init) | ||
1213 | module_exit(patch_analog_exit) | ||
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 5e65999e0d8e..447302695195 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -98,20 +98,8 @@ MODULE_ALIAS("snd-hda-codec-id:1102000d"); | |||
98 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
99 | MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); | 99 | MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); |
100 | 100 | ||
101 | static struct hda_codec_preset_list ca0110_list = { | 101 | static struct hda_codec_driver ca0110_driver = { |
102 | .preset = snd_hda_preset_ca0110, | 102 | .preset = snd_hda_preset_ca0110, |
103 | .owner = THIS_MODULE, | ||
104 | }; | 103 | }; |
105 | 104 | ||
106 | static int __init patch_ca0110_init(void) | 105 | module_hda_codec_driver(ca0110_driver); |
107 | { | ||
108 | return snd_hda_add_codec_preset(&ca0110_list); | ||
109 | } | ||
110 | |||
111 | static void __exit patch_ca0110_exit(void) | ||
112 | { | ||
113 | snd_hda_delete_codec_preset(&ca0110_list); | ||
114 | } | ||
115 | |||
116 | module_init(patch_ca0110_init) | ||
117 | module_exit(patch_ca0110_exit) | ||
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index e0383eea9880..81991b4134cd 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -4702,20 +4702,8 @@ MODULE_ALIAS("snd-hda-codec-id:11020011"); | |||
4702 | MODULE_LICENSE("GPL"); | 4702 | MODULE_LICENSE("GPL"); |
4703 | MODULE_DESCRIPTION("Creative Sound Core3D codec"); | 4703 | MODULE_DESCRIPTION("Creative Sound Core3D codec"); |
4704 | 4704 | ||
4705 | static struct hda_codec_preset_list ca0132_list = { | 4705 | static struct hda_codec_driver ca0132_driver = { |
4706 | .preset = snd_hda_preset_ca0132, | 4706 | .preset = snd_hda_preset_ca0132, |
4707 | .owner = THIS_MODULE, | ||
4708 | }; | 4707 | }; |
4709 | 4708 | ||
4710 | static int __init patch_ca0132_init(void) | 4709 | module_hda_codec_driver(ca0132_driver); |
4711 | { | ||
4712 | return snd_hda_add_codec_preset(&ca0132_list); | ||
4713 | } | ||
4714 | |||
4715 | static void __exit patch_ca0132_exit(void) | ||
4716 | { | ||
4717 | snd_hda_delete_codec_preset(&ca0132_list); | ||
4718 | } | ||
4719 | |||
4720 | module_init(patch_ca0132_init) | ||
4721 | module_exit(patch_ca0132_exit) | ||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index dd2b3d92071f..50e9dd675579 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -1221,20 +1221,8 @@ MODULE_ALIAS("snd-hda-codec-id:10134213"); | |||
1221 | MODULE_LICENSE("GPL"); | 1221 | MODULE_LICENSE("GPL"); |
1222 | MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); | 1222 | MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); |
1223 | 1223 | ||
1224 | static struct hda_codec_preset_list cirrus_list = { | 1224 | static struct hda_codec_driver cirrus_driver = { |
1225 | .preset = snd_hda_preset_cirrus, | 1225 | .preset = snd_hda_preset_cirrus, |
1226 | .owner = THIS_MODULE, | ||
1227 | }; | 1226 | }; |
1228 | 1227 | ||
1229 | static int __init patch_cirrus_init(void) | 1228 | module_hda_codec_driver(cirrus_driver); |
1230 | { | ||
1231 | return snd_hda_add_codec_preset(&cirrus_list); | ||
1232 | } | ||
1233 | |||
1234 | static void __exit patch_cirrus_exit(void) | ||
1235 | { | ||
1236 | snd_hda_delete_codec_preset(&cirrus_list); | ||
1237 | } | ||
1238 | |||
1239 | module_init(patch_cirrus_init) | ||
1240 | module_exit(patch_cirrus_exit) | ||
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index c895a8f21192..617d9012e78a 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -137,20 +137,8 @@ MODULE_ALIAS("snd-hda-codec-id:434d4980"); | |||
137 | MODULE_LICENSE("GPL"); | 137 | MODULE_LICENSE("GPL"); |
138 | MODULE_DESCRIPTION("C-Media HD-audio codec"); | 138 | MODULE_DESCRIPTION("C-Media HD-audio codec"); |
139 | 139 | ||
140 | static struct hda_codec_preset_list cmedia_list = { | 140 | static struct hda_codec_driver cmedia_driver = { |
141 | .preset = snd_hda_preset_cmedia, | 141 | .preset = snd_hda_preset_cmedia, |
142 | .owner = THIS_MODULE, | ||
143 | }; | 142 | }; |
144 | 143 | ||
145 | static int __init patch_cmedia_init(void) | 144 | module_hda_codec_driver(cmedia_driver); |
146 | { | ||
147 | return snd_hda_add_codec_preset(&cmedia_list); | ||
148 | } | ||
149 | |||
150 | static void __exit patch_cmedia_exit(void) | ||
151 | { | ||
152 | snd_hda_delete_codec_preset(&cmedia_list); | ||
153 | } | ||
154 | |||
155 | module_init(patch_cmedia_init) | ||
156 | module_exit(patch_cmedia_exit) | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index da67ea8645a6..5aa466a13e43 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -1018,20 +1018,8 @@ MODULE_ALIAS("snd-hda-codec-id:14f151d7"); | |||
1018 | MODULE_LICENSE("GPL"); | 1018 | MODULE_LICENSE("GPL"); |
1019 | MODULE_DESCRIPTION("Conexant HD-audio codec"); | 1019 | MODULE_DESCRIPTION("Conexant HD-audio codec"); |
1020 | 1020 | ||
1021 | static struct hda_codec_preset_list conexant_list = { | 1021 | static struct hda_codec_driver conexant_driver = { |
1022 | .preset = snd_hda_preset_conexant, | 1022 | .preset = snd_hda_preset_conexant, |
1023 | .owner = THIS_MODULE, | ||
1024 | }; | 1023 | }; |
1025 | 1024 | ||
1026 | static int __init patch_conexant_init(void) | 1025 | module_hda_codec_driver(conexant_driver); |
1027 | { | ||
1028 | return snd_hda_add_codec_preset(&conexant_list); | ||
1029 | } | ||
1030 | |||
1031 | static void __exit patch_conexant_exit(void) | ||
1032 | { | ||
1033 | snd_hda_delete_codec_preset(&conexant_list); | ||
1034 | } | ||
1035 | |||
1036 | module_init(patch_conexant_init) | ||
1037 | module_exit(patch_conexant_exit) | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index b422e406a9cb..f1812aabd63e 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -3301,15 +3301,6 @@ static int patch_via_hdmi(struct hda_codec *codec) | |||
3301 | } | 3301 | } |
3302 | 3302 | ||
3303 | /* | 3303 | /* |
3304 | * called from hda_codec.c for generic HDMI support | ||
3305 | */ | ||
3306 | int snd_hda_parse_hdmi_codec(struct hda_codec *codec) | ||
3307 | { | ||
3308 | return patch_generic_hdmi(codec); | ||
3309 | } | ||
3310 | EXPORT_SYMBOL_GPL(snd_hda_parse_hdmi_codec); | ||
3311 | |||
3312 | /* | ||
3313 | * patch entries | 3304 | * patch entries |
3314 | */ | 3305 | */ |
3315 | static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | 3306 | static const struct hda_codec_preset snd_hda_preset_hdmi[] = { |
@@ -3373,6 +3364,8 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
3373 | { .id = 0x80862882, .name = "Valleyview2 HDMI", .patch = patch_generic_hdmi }, | 3364 | { .id = 0x80862882, .name = "Valleyview2 HDMI", .patch = patch_generic_hdmi }, |
3374 | { .id = 0x80862883, .name = "Braswell HDMI", .patch = patch_generic_hdmi }, | 3365 | { .id = 0x80862883, .name = "Braswell HDMI", .patch = patch_generic_hdmi }, |
3375 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, | 3366 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, |
3367 | /* special ID for generic HDMI */ | ||
3368 | { .id = HDA_CODEC_ID_GENERIC_HDMI, .patch = patch_generic_hdmi }, | ||
3376 | {} /* terminator */ | 3369 | {} /* terminator */ |
3377 | }; | 3370 | }; |
3378 | 3371 | ||
@@ -3442,20 +3435,8 @@ MODULE_ALIAS("snd-hda-codec-intelhdmi"); | |||
3442 | MODULE_ALIAS("snd-hda-codec-nvhdmi"); | 3435 | MODULE_ALIAS("snd-hda-codec-nvhdmi"); |
3443 | MODULE_ALIAS("snd-hda-codec-atihdmi"); | 3436 | MODULE_ALIAS("snd-hda-codec-atihdmi"); |
3444 | 3437 | ||
3445 | static struct hda_codec_preset_list intel_list = { | 3438 | static struct hda_codec_driver hdmi_driver = { |
3446 | .preset = snd_hda_preset_hdmi, | 3439 | .preset = snd_hda_preset_hdmi, |
3447 | .owner = THIS_MODULE, | ||
3448 | }; | 3440 | }; |
3449 | 3441 | ||
3450 | static int __init patch_hdmi_init(void) | 3442 | module_hda_codec_driver(hdmi_driver); |
3451 | { | ||
3452 | return snd_hda_add_codec_preset(&intel_list); | ||
3453 | } | ||
3454 | |||
3455 | static void __exit patch_hdmi_exit(void) | ||
3456 | { | ||
3457 | snd_hda_delete_codec_preset(&intel_list); | ||
3458 | } | ||
3459 | |||
3460 | module_init(patch_hdmi_init) | ||
3461 | module_exit(patch_hdmi_exit) | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 526398a4a442..0ae1f5b7639b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -6521,20 +6521,8 @@ MODULE_ALIAS("snd-hda-codec-id:10ec*"); | |||
6521 | MODULE_LICENSE("GPL"); | 6521 | MODULE_LICENSE("GPL"); |
6522 | MODULE_DESCRIPTION("Realtek HD-audio codec"); | 6522 | MODULE_DESCRIPTION("Realtek HD-audio codec"); |
6523 | 6523 | ||
6524 | static struct hda_codec_preset_list realtek_list = { | 6524 | static struct hda_codec_driver realtek_driver = { |
6525 | .preset = snd_hda_preset_realtek, | 6525 | .preset = snd_hda_preset_realtek, |
6526 | .owner = THIS_MODULE, | ||
6527 | }; | 6526 | }; |
6528 | 6527 | ||
6529 | static int __init patch_realtek_init(void) | 6528 | module_hda_codec_driver(realtek_driver); |
6530 | { | ||
6531 | return snd_hda_add_codec_preset(&realtek_list); | ||
6532 | } | ||
6533 | |||
6534 | static void __exit patch_realtek_exit(void) | ||
6535 | { | ||
6536 | snd_hda_delete_codec_preset(&realtek_list); | ||
6537 | } | ||
6538 | |||
6539 | module_init(patch_realtek_init) | ||
6540 | module_exit(patch_realtek_exit) | ||
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 3208ad69583e..38a477333321 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -319,20 +319,8 @@ MODULE_ALIAS("snd-hda-codec-id:18540018"); | |||
319 | MODULE_LICENSE("GPL"); | 319 | MODULE_LICENSE("GPL"); |
320 | MODULE_DESCRIPTION("Si3054 HD-audio modem codec"); | 320 | MODULE_DESCRIPTION("Si3054 HD-audio modem codec"); |
321 | 321 | ||
322 | static struct hda_codec_preset_list si3054_list = { | 322 | static struct hda_codec_driver si3054_driver = { |
323 | .preset = snd_hda_preset_si3054, | 323 | .preset = snd_hda_preset_si3054, |
324 | .owner = THIS_MODULE, | ||
325 | }; | 324 | }; |
326 | 325 | ||
327 | static int __init patch_si3054_init(void) | 326 | module_hda_codec_driver(si3054_driver); |
328 | { | ||
329 | return snd_hda_add_codec_preset(&si3054_list); | ||
330 | } | ||
331 | |||
332 | static void __exit patch_si3054_exit(void) | ||
333 | { | ||
334 | snd_hda_delete_codec_preset(&si3054_list); | ||
335 | } | ||
336 | |||
337 | module_init(patch_si3054_init) | ||
338 | module_exit(patch_si3054_exit) | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 87eff3173ce9..2956a6ba6bf0 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -2132,8 +2132,10 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec, | |||
2132 | 2132 | ||
2133 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 2133 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
2134 | spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ | 2134 | spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ |
2135 | #ifdef CONFIG_PM | ||
2135 | /* resetting controller clears GPIO, so we need to keep on */ | 2136 | /* resetting controller clears GPIO, so we need to keep on */ |
2136 | codec->bus->power_keep_link_on = 1; | 2137 | codec->d3_stop_clk = 0; |
2138 | #endif | ||
2137 | } | 2139 | } |
2138 | } | 2140 | } |
2139 | 2141 | ||
@@ -5091,20 +5093,8 @@ MODULE_ALIAS("snd-hda-codec-id:111d*"); | |||
5091 | MODULE_LICENSE("GPL"); | 5093 | MODULE_LICENSE("GPL"); |
5092 | MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec"); | 5094 | MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec"); |
5093 | 5095 | ||
5094 | static struct hda_codec_preset_list sigmatel_list = { | 5096 | static struct hda_codec_driver sigmatel_driver = { |
5095 | .preset = snd_hda_preset_sigmatel, | 5097 | .preset = snd_hda_preset_sigmatel, |
5096 | .owner = THIS_MODULE, | ||
5097 | }; | 5098 | }; |
5098 | 5099 | ||
5099 | static int __init patch_sigmatel_init(void) | 5100 | module_hda_codec_driver(sigmatel_driver); |
5100 | { | ||
5101 | return snd_hda_add_codec_preset(&sigmatel_list); | ||
5102 | } | ||
5103 | |||
5104 | static void __exit patch_sigmatel_exit(void) | ||
5105 | { | ||
5106 | snd_hda_delete_codec_preset(&sigmatel_list); | ||
5107 | } | ||
5108 | |||
5109 | module_init(patch_sigmatel_init) | ||
5110 | module_exit(patch_sigmatel_exit) | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 3de6d3d779c9..2045f33b1ace 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -1884,23 +1884,11 @@ static const struct hda_codec_preset snd_hda_preset_via[] = { | |||
1884 | 1884 | ||
1885 | MODULE_ALIAS("snd-hda-codec-id:1106*"); | 1885 | MODULE_ALIAS("snd-hda-codec-id:1106*"); |
1886 | 1886 | ||
1887 | static struct hda_codec_preset_list via_list = { | 1887 | static struct hda_codec_driver via_driver = { |
1888 | .preset = snd_hda_preset_via, | 1888 | .preset = snd_hda_preset_via, |
1889 | .owner = THIS_MODULE, | ||
1890 | }; | 1889 | }; |
1891 | 1890 | ||
1892 | MODULE_LICENSE("GPL"); | 1891 | MODULE_LICENSE("GPL"); |
1893 | MODULE_DESCRIPTION("VIA HD-audio codec"); | 1892 | MODULE_DESCRIPTION("VIA HD-audio codec"); |
1894 | 1893 | ||
1895 | static int __init patch_via_init(void) | 1894 | module_hda_codec_driver(via_driver); |
1896 | { | ||
1897 | return snd_hda_add_codec_preset(&via_list); | ||
1898 | } | ||
1899 | |||
1900 | static void __exit patch_via_exit(void) | ||
1901 | { | ||
1902 | snd_hda_delete_codec_preset(&via_list); | ||
1903 | } | ||
1904 | |||
1905 | module_init(patch_via_init) | ||
1906 | module_exit(patch_via_exit) | ||