diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.h')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 162 |
1 files changed, 62 insertions, 100 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 9c8820f21f94..ccf355d4a8fa 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #ifndef __SOUND_HDA_CODEC_H | 21 | #ifndef __SOUND_HDA_CODEC_H |
22 | #define __SOUND_HDA_CODEC_H | 22 | #define __SOUND_HDA_CODEC_H |
23 | 23 | ||
24 | #include <linux/kref.h> | ||
24 | #include <sound/info.h> | 25 | #include <sound/info.h> |
25 | #include <sound/control.h> | 26 | #include <sound/control.h> |
26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
@@ -66,7 +67,6 @@ struct hda_beep; | |||
66 | struct hda_codec; | 67 | struct hda_codec; |
67 | struct hda_pcm; | 68 | struct hda_pcm; |
68 | struct hda_pcm_stream; | 69 | struct hda_pcm_stream; |
69 | struct hda_bus_unsolicited; | ||
70 | 70 | ||
71 | /* NID type */ | 71 | /* NID type */ |
72 | typedef u16 hda_nid_t; | 72 | typedef u16 hda_nid_t; |
@@ -84,10 +84,6 @@ struct hda_bus_ops { | |||
84 | struct hda_pcm *pcm); | 84 | struct hda_pcm *pcm); |
85 | /* reset bus for retry verb */ | 85 | /* reset bus for retry verb */ |
86 | void (*bus_reset)(struct hda_bus *bus); | 86 | void (*bus_reset)(struct hda_bus *bus); |
87 | #ifdef CONFIG_PM | ||
88 | /* notify power-up/down from codec to controller */ | ||
89 | void (*pm_notify)(struct hda_bus *bus, bool power_up); | ||
90 | #endif | ||
91 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 87 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
92 | /* prepare DSP transfer */ | 88 | /* prepare DSP transfer */ |
93 | int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format, | 89 | int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format, |
@@ -101,13 +97,14 @@ struct hda_bus_ops { | |||
101 | #endif | 97 | #endif |
102 | }; | 98 | }; |
103 | 99 | ||
104 | /* template to pass to the bus constructor */ | 100 | /* unsolicited event handler */ |
105 | struct hda_bus_template { | 101 | #define HDA_UNSOL_QUEUE_SIZE 64 |
106 | void *private_data; | 102 | struct hda_bus_unsolicited { |
107 | struct pci_dev *pci; | 103 | /* ring buffer */ |
108 | const char *modelname; | 104 | u32 queue[HDA_UNSOL_QUEUE_SIZE * 2]; |
109 | int *power_save; | 105 | unsigned int rp, wp; |
110 | struct hda_bus_ops ops; | 106 | /* workqueue */ |
107 | struct work_struct work; | ||
111 | }; | 108 | }; |
112 | 109 | ||
113 | /* | 110 | /* |
@@ -119,11 +116,9 @@ struct hda_bus_template { | |||
119 | struct hda_bus { | 116 | struct hda_bus { |
120 | struct snd_card *card; | 117 | struct snd_card *card; |
121 | 118 | ||
122 | /* copied from template */ | ||
123 | void *private_data; | 119 | void *private_data; |
124 | struct pci_dev *pci; | 120 | struct pci_dev *pci; |
125 | const char *modelname; | 121 | const char *modelname; |
126 | int *power_save; | ||
127 | struct hda_bus_ops ops; | 122 | struct hda_bus_ops ops; |
128 | 123 | ||
129 | /* codec linked list */ | 124 | /* codec linked list */ |
@@ -136,9 +131,7 @@ struct hda_bus { | |||
136 | struct mutex prepare_mutex; | 131 | struct mutex prepare_mutex; |
137 | 132 | ||
138 | /* unsolicited event queue */ | 133 | /* unsolicited event queue */ |
139 | struct hda_bus_unsolicited *unsol; | 134 | struct hda_bus_unsolicited unsol; |
140 | char workq_name[16]; | ||
141 | struct workqueue_struct *workq; /* common workqueue for codecs */ | ||
142 | 135 | ||
143 | /* assigned PCMs */ | 136 | /* assigned PCMs */ |
144 | DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); | 137 | DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); |
@@ -152,10 +145,10 @@ struct hda_bus { | |||
152 | unsigned int rirb_error:1; /* error in codec communication */ | 145 | unsigned int rirb_error:1; /* error in codec communication */ |
153 | unsigned int response_reset:1; /* controller was reset */ | 146 | unsigned int response_reset:1; /* controller was reset */ |
154 | unsigned int in_reset:1; /* during reset operation */ | 147 | unsigned int in_reset:1; /* during reset operation */ |
155 | unsigned int power_keep_link_on:1; /* don't power off HDA link */ | ||
156 | unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ | 148 | unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ |
157 | 149 | ||
158 | int primary_dig_out_type; /* primary digital out PCM type */ | 150 | int primary_dig_out_type; /* primary digital out PCM type */ |
151 | unsigned long codec_powered; /* bit flags of powered codecs */ | ||
159 | }; | 152 | }; |
160 | 153 | ||
161 | /* | 154 | /* |
@@ -175,15 +168,22 @@ struct hda_codec_preset { | |||
175 | int (*patch)(struct hda_codec *codec); | 168 | int (*patch)(struct hda_codec *codec); |
176 | }; | 169 | }; |
177 | 170 | ||
178 | struct hda_codec_preset_list { | 171 | #define HDA_CODEC_ID_GENERIC_HDMI 0x00000101 |
172 | #define HDA_CODEC_ID_GENERIC 0x00000201 | ||
173 | |||
174 | struct hda_codec_driver { | ||
175 | struct device_driver driver; | ||
179 | const struct hda_codec_preset *preset; | 176 | const struct hda_codec_preset *preset; |
180 | struct module *owner; | ||
181 | struct list_head list; | ||
182 | }; | 177 | }; |
183 | 178 | ||
184 | /* initial hook */ | 179 | int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, |
185 | int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset); | 180 | struct module *owner); |
186 | int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset); | 181 | #define hda_codec_driver_register(drv) \ |
182 | __hda_codec_driver_register(drv, KBUILD_MODNAME, THIS_MODULE) | ||
183 | void hda_codec_driver_unregister(struct hda_codec_driver *drv); | ||
184 | #define module_hda_codec_driver(drv) \ | ||
185 | module_driver(drv, hda_codec_driver_register, \ | ||
186 | hda_codec_driver_unregister) | ||
187 | 187 | ||
188 | /* ops set by the preset patch */ | 188 | /* ops set by the preset patch */ |
189 | struct hda_codec_ops { | 189 | struct hda_codec_ops { |
@@ -200,6 +200,7 @@ struct hda_codec_ops { | |||
200 | int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); | 200 | int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); |
201 | #endif | 201 | #endif |
202 | void (*reboot_notify)(struct hda_codec *codec); | 202 | void (*reboot_notify)(struct hda_codec *codec); |
203 | void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on); | ||
203 | }; | 204 | }; |
204 | 205 | ||
205 | /* record for amp information cache */ | 206 | /* record for amp information cache */ |
@@ -267,12 +268,17 @@ struct hda_pcm { | |||
267 | int device; /* device number to assign */ | 268 | int device; /* device number to assign */ |
268 | struct snd_pcm *pcm; /* assigned PCM instance */ | 269 | struct snd_pcm *pcm; /* assigned PCM instance */ |
269 | bool own_chmap; /* codec driver provides own channel maps */ | 270 | bool own_chmap; /* codec driver provides own channel maps */ |
271 | /* private: */ | ||
272 | struct hda_codec *codec; | ||
273 | struct kref kref; | ||
274 | struct list_head list; | ||
270 | }; | 275 | }; |
271 | 276 | ||
272 | /* codec information */ | 277 | /* codec information */ |
273 | struct hda_codec { | 278 | struct hda_codec { |
274 | struct device dev; | 279 | struct device dev; |
275 | struct hda_bus *bus; | 280 | struct hda_bus *bus; |
281 | struct snd_card *card; | ||
276 | unsigned int addr; /* codec addr*/ | 282 | unsigned int addr; /* codec addr*/ |
277 | struct list_head list; /* list point */ | 283 | struct list_head list; /* list point */ |
278 | 284 | ||
@@ -287,11 +293,10 @@ struct hda_codec { | |||
287 | u32 vendor_id; | 293 | u32 vendor_id; |
288 | u32 subsystem_id; | 294 | u32 subsystem_id; |
289 | u32 revision_id; | 295 | u32 revision_id; |
296 | u32 probe_id; /* overridden id for probing */ | ||
290 | 297 | ||
291 | /* detected preset */ | 298 | /* detected preset */ |
292 | const struct hda_codec_preset *preset; | 299 | const struct hda_codec_preset *preset; |
293 | struct module *owner; | ||
294 | int (*parser)(struct hda_codec *codec); | ||
295 | const char *vendor_name; /* codec vendor name */ | 300 | const char *vendor_name; /* codec vendor name */ |
296 | const char *chip_name; /* codec chip name */ | 301 | const char *chip_name; /* codec chip name */ |
297 | const char *modelname; /* model name for preset */ | 302 | const char *modelname; /* model name for preset */ |
@@ -300,8 +305,7 @@ struct hda_codec { | |||
300 | struct hda_codec_ops patch_ops; | 305 | struct hda_codec_ops patch_ops; |
301 | 306 | ||
302 | /* PCM to create, set by patch_ops.build_pcms callback */ | 307 | /* PCM to create, set by patch_ops.build_pcms callback */ |
303 | unsigned int num_pcms; | 308 | struct list_head pcm_list_head; |
304 | struct hda_pcm *pcm_info; | ||
305 | 309 | ||
306 | /* codec specific info */ | 310 | /* codec specific info */ |
307 | void *spec; | 311 | void *spec; |
@@ -345,6 +349,7 @@ struct hda_codec { | |||
345 | #endif | 349 | #endif |
346 | 350 | ||
347 | /* misc flags */ | 351 | /* misc flags */ |
352 | unsigned int in_freeing:1; /* being released */ | ||
348 | unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each | 353 | unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each |
349 | * status change | 354 | * status change |
350 | * (e.g. Realtek codecs) | 355 | * (e.g. Realtek codecs) |
@@ -366,18 +371,13 @@ struct hda_codec { | |||
366 | unsigned int cached_write:1; /* write only to caches */ | 371 | unsigned int cached_write:1; /* write only to caches */ |
367 | unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */ | 372 | unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */ |
368 | unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ | 373 | unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ |
374 | unsigned int power_save_node:1; /* advanced PM for each widget */ | ||
369 | #ifdef CONFIG_PM | 375 | #ifdef CONFIG_PM |
370 | unsigned int power_on :1; /* current (global) power-state */ | ||
371 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ | 376 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ |
372 | unsigned int pm_up_notified:1; /* PM notified to controller */ | 377 | atomic_t in_pm; /* suspend/resume being performed */ |
373 | unsigned int in_pm:1; /* suspend/resume being performed */ | ||
374 | int power_transition; /* power-state in transition */ | ||
375 | int power_count; /* current (global) power refcount */ | ||
376 | struct delayed_work power_work; /* delayed task for powerdown */ | ||
377 | unsigned long power_on_acct; | 378 | unsigned long power_on_acct; |
378 | unsigned long power_off_acct; | 379 | unsigned long power_off_acct; |
379 | unsigned long power_jiffies; | 380 | unsigned long power_jiffies; |
380 | spinlock_t power_lock; | ||
381 | #endif | 381 | #endif |
382 | 382 | ||
383 | /* filter the requested power state per nid */ | 383 | /* filter the requested power state per nid */ |
@@ -409,6 +409,11 @@ struct hda_codec { | |||
409 | struct snd_array verbs; | 409 | struct snd_array verbs; |
410 | }; | 410 | }; |
411 | 411 | ||
412 | #define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, dev) | ||
413 | #define hda_codec_dev(_dev) (&(_dev)->dev) | ||
414 | |||
415 | extern struct bus_type snd_hda_bus_type; | ||
416 | |||
412 | /* direction */ | 417 | /* direction */ |
413 | enum { | 418 | enum { |
414 | HDA_INPUT, HDA_OUTPUT | 419 | HDA_INPUT, HDA_OUTPUT |
@@ -420,10 +425,9 @@ enum { | |||
420 | /* | 425 | /* |
421 | * constructors | 426 | * constructors |
422 | */ | 427 | */ |
423 | int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, | 428 | int snd_hda_bus_new(struct snd_card *card, struct hda_bus **busp); |
424 | struct hda_bus **busp); | 429 | int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, |
425 | int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | 430 | unsigned int codec_addr, struct hda_codec **codecp); |
426 | struct hda_codec **codecp); | ||
427 | int snd_hda_codec_configure(struct hda_codec *codec); | 431 | int snd_hda_codec_configure(struct hda_codec *codec); |
428 | int snd_hda_codec_update_widgets(struct hda_codec *codec); | 432 | int snd_hda_codec_update_widgets(struct hda_codec *codec); |
429 | 433 | ||
@@ -512,15 +516,24 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid); | |||
512 | /* | 516 | /* |
513 | * Mixer | 517 | * Mixer |
514 | */ | 518 | */ |
515 | int snd_hda_build_controls(struct hda_bus *bus); | ||
516 | int snd_hda_codec_build_controls(struct hda_codec *codec); | 519 | int snd_hda_codec_build_controls(struct hda_codec *codec); |
517 | 520 | ||
518 | /* | 521 | /* |
519 | * PCM | 522 | * PCM |
520 | */ | 523 | */ |
521 | int snd_hda_build_pcms(struct hda_bus *bus); | 524 | int snd_hda_codec_parse_pcms(struct hda_codec *codec); |
522 | int snd_hda_codec_build_pcms(struct hda_codec *codec); | 525 | int snd_hda_codec_build_pcms(struct hda_codec *codec); |
523 | 526 | ||
527 | __printf(2, 3) | ||
528 | struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, | ||
529 | const char *fmt, ...); | ||
530 | |||
531 | static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm) | ||
532 | { | ||
533 | kref_get(&pcm->kref); | ||
534 | } | ||
535 | void snd_hda_codec_pcm_put(struct hda_pcm *pcm); | ||
536 | |||
524 | int snd_hda_codec_prepare(struct hda_codec *codec, | 537 | int snd_hda_codec_prepare(struct hda_codec *codec, |
525 | struct hda_pcm_stream *hinfo, | 538 | struct hda_pcm_stream *hinfo, |
526 | unsigned int stream, | 539 | unsigned int stream, |
@@ -552,20 +565,17 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[]; | |||
552 | * Misc | 565 | * Misc |
553 | */ | 566 | */ |
554 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); | 567 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); |
555 | void snd_hda_bus_reboot_notify(struct hda_bus *bus); | ||
556 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | 568 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, |
557 | unsigned int power_state); | 569 | unsigned int power_state); |
558 | 570 | ||
559 | int snd_hda_lock_devices(struct hda_bus *bus); | 571 | int snd_hda_lock_devices(struct hda_bus *bus); |
560 | void snd_hda_unlock_devices(struct hda_bus *bus); | 572 | void snd_hda_unlock_devices(struct hda_bus *bus); |
573 | void snd_hda_bus_reset(struct hda_bus *bus); | ||
561 | 574 | ||
562 | /* | 575 | /* |
563 | * power management | 576 | * power management |
564 | */ | 577 | */ |
565 | #ifdef CONFIG_PM | 578 | extern const struct dev_pm_ops hda_codec_driver_pm; |
566 | int snd_hda_suspend(struct hda_bus *bus); | ||
567 | int snd_hda_resume(struct hda_bus *bus); | ||
568 | #endif | ||
569 | 579 | ||
570 | static inline | 580 | static inline |
571 | int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 581 | int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
@@ -588,64 +598,16 @@ const char *snd_hda_get_jack_location(u32 cfg); | |||
588 | * power saving | 598 | * power saving |
589 | */ | 599 | */ |
590 | #ifdef CONFIG_PM | 600 | #ifdef CONFIG_PM |
591 | void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait); | 601 | void snd_hda_power_up(struct hda_codec *codec); |
602 | void snd_hda_power_down(struct hda_codec *codec); | ||
603 | void snd_hda_set_power_save(struct hda_bus *bus, int delay); | ||
592 | void snd_hda_update_power_acct(struct hda_codec *codec); | 604 | void snd_hda_update_power_acct(struct hda_codec *codec); |
593 | #else | 605 | #else |
594 | static inline void snd_hda_power_save(struct hda_codec *codec, int delta, | 606 | static inline void snd_hda_power_up(struct hda_codec *codec) {} |
595 | bool d3wait) {} | 607 | static inline void snd_hda_power_down(struct hda_codec *codec) {} |
608 | static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {} | ||
596 | #endif | 609 | #endif |
597 | 610 | ||
598 | /** | ||
599 | * snd_hda_power_up - Power-up the codec | ||
600 | * @codec: HD-audio codec | ||
601 | * | ||
602 | * Increment the power-up counter and power up the hardware really when | ||
603 | * not turned on yet. | ||
604 | */ | ||
605 | static inline void snd_hda_power_up(struct hda_codec *codec) | ||
606 | { | ||
607 | snd_hda_power_save(codec, 1, false); | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending | ||
612 | * D3 transition to complete. This differs from snd_hda_power_up() when | ||
613 | * power_transition == -1. snd_hda_power_up sees this case as a nop, | ||
614 | * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers | ||
615 | * back up. | ||
616 | * @codec: HD-audio codec | ||
617 | * | ||
618 | * Cancel any power down operation hapenning on the work queue, then power up. | ||
619 | */ | ||
620 | static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) | ||
621 | { | ||
622 | snd_hda_power_save(codec, 1, true); | ||
623 | } | ||
624 | |||
625 | /** | ||
626 | * snd_hda_power_down - Power-down the codec | ||
627 | * @codec: HD-audio codec | ||
628 | * | ||
629 | * Decrement the power-up counter and schedules the power-off work if | ||
630 | * the counter rearches to zero. | ||
631 | */ | ||
632 | static inline void snd_hda_power_down(struct hda_codec *codec) | ||
633 | { | ||
634 | snd_hda_power_save(codec, -1, false); | ||
635 | } | ||
636 | |||
637 | /** | ||
638 | * snd_hda_power_sync - Synchronize the power-save status | ||
639 | * @codec: HD-audio codec | ||
640 | * | ||
641 | * Synchronize the actual power state with the power account; | ||
642 | * called when power_save parameter is changed | ||
643 | */ | ||
644 | static inline void snd_hda_power_sync(struct hda_codec *codec) | ||
645 | { | ||
646 | snd_hda_power_save(codec, 0, false); | ||
647 | } | ||
648 | |||
649 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 611 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
650 | /* | 612 | /* |
651 | * patch firmware | 613 | * patch firmware |