diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.h')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 113 |
1 files changed, 88 insertions, 25 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 56c26e7ccdf1..2bce925d84ef 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -24,6 +24,11 @@ | |||
24 | #include <sound/info.h> | 24 | #include <sound/info.h> |
25 | #include <sound/control.h> | 25 | #include <sound/control.h> |
26 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
27 | #include <sound/hwdep.h> | ||
28 | |||
29 | #if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE) | ||
30 | #define SND_HDA_NEEDS_RESUME /* resume control code is required */ | ||
31 | #endif | ||
27 | 32 | ||
28 | /* | 33 | /* |
29 | * nodes | 34 | * nodes |
@@ -199,7 +204,9 @@ enum { | |||
199 | #define AC_AMPCAP_OFFSET_SHIFT 0 | 204 | #define AC_AMPCAP_OFFSET_SHIFT 0 |
200 | #define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */ | 205 | #define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */ |
201 | #define AC_AMPCAP_NUM_STEPS_SHIFT 8 | 206 | #define AC_AMPCAP_NUM_STEPS_SHIFT 8 |
202 | #define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB in 0.25dB */ | 207 | #define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB |
208 | * in 0.25dB | ||
209 | */ | ||
203 | #define AC_AMPCAP_STEP_SIZE_SHIFT 16 | 210 | #define AC_AMPCAP_STEP_SIZE_SHIFT 16 |
204 | #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ | 211 | #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ |
205 | #define AC_AMPCAP_MUTE_SHIFT 31 | 212 | #define AC_AMPCAP_MUTE_SHIFT 31 |
@@ -409,6 +416,10 @@ struct hda_bus_ops { | |||
409 | unsigned int (*get_response)(struct hda_codec *codec); | 416 | unsigned int (*get_response)(struct hda_codec *codec); |
410 | /* free the private data */ | 417 | /* free the private data */ |
411 | void (*private_free)(struct hda_bus *); | 418 | void (*private_free)(struct hda_bus *); |
419 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
420 | /* notify power-up/down from codec to contoller */ | ||
421 | void (*pm_notify)(struct hda_codec *codec); | ||
422 | #endif | ||
412 | }; | 423 | }; |
413 | 424 | ||
414 | /* template to pass to the bus constructor */ | 425 | /* template to pass to the bus constructor */ |
@@ -436,7 +447,8 @@ struct hda_bus { | |||
436 | 447 | ||
437 | /* codec linked list */ | 448 | /* codec linked list */ |
438 | struct list_head codec_list; | 449 | struct list_head codec_list; |
439 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ | 450 | /* link caddr -> codec */ |
451 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; | ||
440 | 452 | ||
441 | struct mutex cmd_mutex; | 453 | struct mutex cmd_mutex; |
442 | 454 | ||
@@ -469,19 +481,34 @@ struct hda_codec_ops { | |||
469 | int (*init)(struct hda_codec *codec); | 481 | int (*init)(struct hda_codec *codec); |
470 | void (*free)(struct hda_codec *codec); | 482 | void (*free)(struct hda_codec *codec); |
471 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); | 483 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); |
472 | #ifdef CONFIG_PM | 484 | #ifdef SND_HDA_NEEDS_RESUME |
473 | int (*suspend)(struct hda_codec *codec, pm_message_t state); | 485 | int (*suspend)(struct hda_codec *codec, pm_message_t state); |
474 | int (*resume)(struct hda_codec *codec); | 486 | int (*resume)(struct hda_codec *codec); |
475 | #endif | 487 | #endif |
488 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
489 | int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); | ||
490 | #endif | ||
476 | }; | 491 | }; |
477 | 492 | ||
478 | /* record for amp information cache */ | 493 | /* record for amp information cache */ |
479 | struct hda_amp_info { | 494 | struct hda_cache_head { |
480 | u32 key; /* hash key */ | 495 | u32 key; /* hash key */ |
496 | u16 val; /* assigned value */ | ||
497 | u16 next; /* next link; -1 = terminal */ | ||
498 | }; | ||
499 | |||
500 | struct hda_amp_info { | ||
501 | struct hda_cache_head head; | ||
481 | u32 amp_caps; /* amp capabilities */ | 502 | u32 amp_caps; /* amp capabilities */ |
482 | u16 vol[2]; /* current volume & mute */ | 503 | u16 vol[2]; /* current volume & mute */ |
483 | u16 status; /* update flag */ | 504 | }; |
484 | u16 next; /* next link */ | 505 | |
506 | struct hda_cache_rec { | ||
507 | u16 hash[64]; /* hash table for index */ | ||
508 | unsigned int num_entries; /* number of assigned entries */ | ||
509 | unsigned int size; /* allocated size */ | ||
510 | unsigned int record_size; /* record size (including header) */ | ||
511 | void *buffer; /* hash table entries */ | ||
485 | }; | 512 | }; |
486 | 513 | ||
487 | /* PCM callbacks */ | 514 | /* PCM callbacks */ |
@@ -499,7 +526,7 @@ struct hda_pcm_ops { | |||
499 | 526 | ||
500 | /* PCM information for each substream */ | 527 | /* PCM information for each substream */ |
501 | struct hda_pcm_stream { | 528 | struct hda_pcm_stream { |
502 | unsigned int substreams; /* number of substreams, 0 = not exist */ | 529 | unsigned int substreams; /* number of substreams, 0 = not exist*/ |
503 | unsigned int channels_min; /* min. number of channels */ | 530 | unsigned int channels_min; /* min. number of channels */ |
504 | unsigned int channels_max; /* max. number of channels */ | 531 | unsigned int channels_max; /* max. number of channels */ |
505 | hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */ | 532 | hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */ |
@@ -536,11 +563,6 @@ struct hda_codec { | |||
536 | /* set by patch */ | 563 | /* set by patch */ |
537 | struct hda_codec_ops patch_ops; | 564 | struct hda_codec_ops patch_ops; |
538 | 565 | ||
539 | /* resume phase - all controls should update even if | ||
540 | * the values are not changed | ||
541 | */ | ||
542 | unsigned int in_resume; | ||
543 | |||
544 | /* PCM to create, set by patch_ops.build_pcms callback */ | 566 | /* PCM to create, set by patch_ops.build_pcms callback */ |
545 | unsigned int num_pcms; | 567 | unsigned int num_pcms; |
546 | struct hda_pcm *pcm_info; | 568 | struct hda_pcm *pcm_info; |
@@ -553,16 +575,22 @@ struct hda_codec { | |||
553 | hda_nid_t start_nid; | 575 | hda_nid_t start_nid; |
554 | u32 *wcaps; | 576 | u32 *wcaps; |
555 | 577 | ||
556 | /* hash for amp access */ | 578 | struct hda_cache_rec amp_cache; /* cache for amp access */ |
557 | u16 amp_hash[32]; | 579 | struct hda_cache_rec cmd_cache; /* cache for other commands */ |
558 | int num_amp_entries; | ||
559 | int amp_info_size; | ||
560 | struct hda_amp_info *amp_info; | ||
561 | 580 | ||
562 | struct mutex spdif_mutex; | 581 | struct mutex spdif_mutex; |
563 | unsigned int spdif_status; /* IEC958 status bits */ | 582 | unsigned int spdif_status; /* IEC958 status bits */ |
564 | unsigned short spdif_ctls; /* SPDIF control bits */ | 583 | unsigned short spdif_ctls; /* SPDIF control bits */ |
565 | unsigned int spdif_in_enable; /* SPDIF input enable? */ | 584 | unsigned int spdif_in_enable; /* SPDIF input enable? */ |
585 | |||
586 | struct snd_hwdep *hwdep; /* assigned hwdep device */ | ||
587 | |||
588 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
589 | unsigned int power_on :1; /* current (global) power-state */ | ||
590 | unsigned int power_transition :1; /* power-state in transition */ | ||
591 | int power_count; /* current (global) power refcount */ | ||
592 | struct delayed_work power_work; /* delayed task for powerdown */ | ||
593 | #endif | ||
566 | }; | 594 | }; |
567 | 595 | ||
568 | /* direction */ | 596 | /* direction */ |
@@ -582,13 +610,17 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
582 | /* | 610 | /* |
583 | * low level functions | 611 | * low level functions |
584 | */ | 612 | */ |
585 | unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, | 613 | unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, |
614 | int direct, | ||
586 | unsigned int verb, unsigned int parm); | 615 | unsigned int verb, unsigned int parm); |
587 | int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, | 616 | int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, |
588 | unsigned int verb, unsigned int parm); | 617 | unsigned int verb, unsigned int parm); |
589 | #define snd_hda_param_read(codec, nid, param) snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) | 618 | #define snd_hda_param_read(codec, nid, param) \ |
590 | int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); | 619 | snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) |
591 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); | 620 | int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, |
621 | hda_nid_t *start_id); | ||
622 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | ||
623 | hda_nid_t *conn_list, int max_conns); | ||
592 | 624 | ||
593 | struct hda_verb { | 625 | struct hda_verb { |
594 | hda_nid_t nid; | 626 | hda_nid_t nid; |
@@ -596,11 +628,24 @@ struct hda_verb { | |||
596 | u32 param; | 628 | u32 param; |
597 | }; | 629 | }; |
598 | 630 | ||
599 | void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq); | 631 | void snd_hda_sequence_write(struct hda_codec *codec, |
632 | const struct hda_verb *seq); | ||
600 | 633 | ||
601 | /* unsolicited event */ | 634 | /* unsolicited event */ |
602 | int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); | 635 | int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); |
603 | 636 | ||
637 | /* cached write */ | ||
638 | #ifdef SND_HDA_NEEDS_RESUME | ||
639 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | ||
640 | int direct, unsigned int verb, unsigned int parm); | ||
641 | void snd_hda_sequence_write_cache(struct hda_codec *codec, | ||
642 | const struct hda_verb *seq); | ||
643 | void snd_hda_codec_resume_cache(struct hda_codec *codec); | ||
644 | #else | ||
645 | #define snd_hda_codec_write_cache snd_hda_codec_write | ||
646 | #define snd_hda_sequence_write_cache snd_hda_sequence_write | ||
647 | #endif | ||
648 | |||
604 | /* | 649 | /* |
605 | * Mixer | 650 | * Mixer |
606 | */ | 651 | */ |
@@ -610,10 +655,13 @@ int snd_hda_build_controls(struct hda_bus *bus); | |||
610 | * PCM | 655 | * PCM |
611 | */ | 656 | */ |
612 | int snd_hda_build_pcms(struct hda_bus *bus); | 657 | int snd_hda_build_pcms(struct hda_bus *bus); |
613 | void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, | 658 | void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, |
659 | u32 stream_tag, | ||
614 | int channel_id, int format); | 660 | int channel_id, int format); |
615 | unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, | 661 | unsigned int snd_hda_calc_stream_format(unsigned int rate, |
616 | unsigned int format, unsigned int maxbps); | 662 | unsigned int channels, |
663 | unsigned int format, | ||
664 | unsigned int maxbps); | ||
617 | int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | 665 | int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, |
618 | u32 *ratesp, u64 *formatsp, unsigned int *bpsp); | 666 | u32 *ratesp, u64 *formatsp, unsigned int *bpsp); |
619 | int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | 667 | int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, |
@@ -632,4 +680,19 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state); | |||
632 | int snd_hda_resume(struct hda_bus *bus); | 680 | int snd_hda_resume(struct hda_bus *bus); |
633 | #endif | 681 | #endif |
634 | 682 | ||
683 | /* | ||
684 | * power saving | ||
685 | */ | ||
686 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
687 | void snd_hda_power_up(struct hda_codec *codec); | ||
688 | void snd_hda_power_down(struct hda_codec *codec); | ||
689 | #define snd_hda_codec_needs_resume(codec) codec->power_count | ||
690 | int snd_hda_codecs_inuse(struct hda_bus *bus); | ||
691 | #else | ||
692 | static inline void snd_hda_power_up(struct hda_codec *codec) {} | ||
693 | static inline void snd_hda_power_down(struct hda_codec *codec) {} | ||
694 | #define snd_hda_codec_needs_resume(codec) 1 | ||
695 | #define snd_hda_codecs_inuse(bus) 1 | ||
696 | #endif | ||
697 | |||
635 | #endif /* __SOUND_HDA_CODEC_H */ | 698 | #endif /* __SOUND_HDA_CODEC_H */ |