diff options
author | Ian Minett <ian_minett@creativelabs.com> | 2012-12-20 21:53:34 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-15 10:57:56 -0500 |
commit | 5aaca44d8d05d144eec891498ff529c6ad4f5794 (patch) | |
tree | b5a0d535d63ed89c2e19fb130080c21ad319a77b /sound/pci/hda | |
parent | ef6b2eada3b8c1b21f6479d7480ea7030183fe1d (diff) |
ALSA: hda/ca0132: Init chip, DSP effects and mixer settings
This patch adds the framework to set effect parameters: ca0132_effects_set()
and ca0132_setup_defaults() are general functions for parameter setting and
initializing to default values. dspio_set_param() and dspio_set_uint_param()
are lower-level fns to simplify setting individual DSP parameters via an
SCP buffer transfer to the firmware.
The CA0132 chip parameter init code is added in ca0132_init_params().
In chipio_[write,read]_data(), the current chip address is auto-incremented
if no error has occurred.
ca0132_select_out() selects the current output. If autodetect is enabled,
use headphones (if jack detected) or speakers (if no jack).
ca0132_select_mic() selects the current mic in. If autodetect is enabled,
use exterior mic (if jack detected) or built-in mic (if no jack).
Init digital mic and switch between dmic and amic with ca0132_init_dmic(),
ca0132_set_dmic(). amic2 is initialized in ca0132_init_analog_mic2().
Finally, add verb tables for configuring DSP firmware.
Signed-off-by: Ian Minett <ian_minett@creativelabs.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 732 |
1 files changed, 700 insertions, 32 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 38ac07b8a4ec..e4e1684ace6f 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "hda_codec.h" | 32 | #include "hda_codec.h" |
33 | #include "hda_local.h" | 33 | #include "hda_local.h" |
34 | #include "hda_auto_parser.h" | 34 | #include "hda_auto_parser.h" |
35 | #include "hda_jack.h" | ||
35 | 36 | ||
36 | #include "ca0132_regs.h" | 37 | #include "ca0132_regs.h" |
37 | 38 | ||
@@ -672,22 +673,11 @@ enum ca0132_sample_rate { | |||
672 | SR_RATE_UNKNOWN = 0x1F | 673 | SR_RATE_UNKNOWN = 0x1F |
673 | }; | 674 | }; |
674 | 675 | ||
675 | /* | ||
676 | * Scp Helper function | ||
677 | */ | ||
678 | enum get_set { | ||
679 | IS_SET = 0, | ||
680 | IS_GET = 1, | ||
681 | }; | ||
682 | |||
683 | /* | ||
684 | * Duplicated from ca0110 codec | ||
685 | */ | ||
686 | |||
687 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | 676 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) |
688 | { | 677 | { |
689 | if (pin) { | 678 | if (pin) { |
690 | snd_hda_set_pin_ctl(codec, pin, PIN_HP); | 679 | snd_hda_codec_write(codec, pin, 0, |
680 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | ||
691 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | 681 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) |
692 | snd_hda_codec_write(codec, pin, 0, | 682 | snd_hda_codec_write(codec, pin, 0, |
693 | AC_VERB_SET_AMP_GAIN_MUTE, | 683 | AC_VERB_SET_AMP_GAIN_MUTE, |
@@ -701,16 +691,23 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | |||
701 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | 691 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) |
702 | { | 692 | { |
703 | if (pin) { | 693 | if (pin) { |
704 | snd_hda_set_pin_ctl(codec, pin, PIN_IN | | 694 | snd_hda_codec_write(codec, pin, 0, |
705 | snd_hda_get_default_vref(codec, pin)); | 695 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); |
706 | if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) | 696 | if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) |
707 | snd_hda_codec_write(codec, pin, 0, | 697 | snd_hda_codec_write(codec, pin, 0, |
708 | AC_VERB_SET_AMP_GAIN_MUTE, | 698 | AC_VERB_SET_AMP_GAIN_MUTE, |
709 | AMP_IN_UNMUTE(0)); | 699 | AMP_IN_UNMUTE(0)); |
710 | } | 700 | } |
711 | if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP)) | 701 | if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP)) { |
712 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 702 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
713 | AMP_IN_UNMUTE(0)); | 703 | AMP_IN_UNMUTE(0)); |
704 | |||
705 | /* init to 0 dB and unmute. */ | ||
706 | snd_hda_codec_amp_stereo(codec, adc, HDA_INPUT, 0, | ||
707 | HDA_AMP_VOLMASK, 0x5a); | ||
708 | snd_hda_codec_amp_stereo(codec, adc, HDA_INPUT, 0, | ||
709 | HDA_AMP_MUTE, 0); | ||
710 | } | ||
714 | } | 711 | } |
715 | 712 | ||
716 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | 713 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, |
@@ -774,11 +771,18 @@ enum dsp_download_state { | |||
774 | */ | 771 | */ |
775 | 772 | ||
776 | struct ca0132_spec { | 773 | struct ca0132_spec { |
774 | const struct hda_verb *base_init_verbs; | ||
775 | const struct hda_verb *base_exit_verbs; | ||
776 | const struct hda_verb *init_verbs[5]; | ||
777 | unsigned int num_init_verbs; /* exclude base init verbs */ | ||
777 | struct auto_pin_cfg autocfg; | 778 | struct auto_pin_cfg autocfg; |
779 | |||
780 | /* Nodes configurations */ | ||
778 | struct hda_multi_out multiout; | 781 | struct hda_multi_out multiout; |
779 | hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; | 782 | hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; |
780 | hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; | 783 | hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; |
781 | hda_nid_t hp_dac; | 784 | hda_nid_t hp_dac; |
785 | unsigned int num_outputs; | ||
782 | hda_nid_t input_pins[AUTO_PIN_LAST]; | 786 | hda_nid_t input_pins[AUTO_PIN_LAST]; |
783 | hda_nid_t adcs[AUTO_PIN_LAST]; | 787 | hda_nid_t adcs[AUTO_PIN_LAST]; |
784 | hda_nid_t dig_out; | 788 | hda_nid_t dig_out; |
@@ -788,7 +792,7 @@ struct ca0132_spec { | |||
788 | long curr_hp_volume[2]; | 792 | long curr_hp_volume[2]; |
789 | long curr_speaker_switch; | 793 | long curr_speaker_switch; |
790 | const char *input_labels[AUTO_PIN_LAST]; | 794 | const char *input_labels[AUTO_PIN_LAST]; |
791 | struct hda_pcm pcm_rec[2]; /* PCM information */ | 795 | struct hda_pcm pcm_rec[5]; /* PCM information */ |
792 | 796 | ||
793 | /* chip access */ | 797 | /* chip access */ |
794 | struct mutex chipio_mutex; /* chip access mutex */ | 798 | struct mutex chipio_mutex; /* chip access mutex */ |
@@ -803,6 +807,18 @@ struct ca0132_spec { | |||
803 | unsigned int scp_resp_header; | 807 | unsigned int scp_resp_header; |
804 | unsigned int scp_resp_data[4]; | 808 | unsigned int scp_resp_data[4]; |
805 | unsigned int scp_resp_count; | 809 | unsigned int scp_resp_count; |
810 | |||
811 | /* mixer and effects related */ | ||
812 | unsigned char dmic_ctl; | ||
813 | int cur_out_type; | ||
814 | int cur_mic_type; | ||
815 | long vnode_lvol[VNODES_COUNT]; | ||
816 | long vnode_rvol[VNODES_COUNT]; | ||
817 | long vnode_lswitch[VNODES_COUNT]; | ||
818 | long vnode_rswitch[VNODES_COUNT]; | ||
819 | long effects_switch[EFFECTS_COUNT]; | ||
820 | long voicefx_val; | ||
821 | long cur_mic_boost; | ||
806 | }; | 822 | }; |
807 | 823 | ||
808 | /* | 824 | /* |
@@ -886,6 +902,7 @@ static int chipio_write_address(struct hda_codec *codec, | |||
886 | */ | 902 | */ |
887 | static int chipio_write_data(struct hda_codec *codec, unsigned int data) | 903 | static int chipio_write_data(struct hda_codec *codec, unsigned int data) |
888 | { | 904 | { |
905 | struct ca0132_spec *spec = codec->spec; | ||
889 | int res; | 906 | int res; |
890 | 907 | ||
891 | /* send low 16 bits of the data */ | 908 | /* send low 16 bits of the data */ |
@@ -897,6 +914,10 @@ static int chipio_write_data(struct hda_codec *codec, unsigned int data) | |||
897 | data >> 16); | 914 | data >> 16); |
898 | } | 915 | } |
899 | 916 | ||
917 | /*If no error encountered, automatically increment the address | ||
918 | as per chip behaviour*/ | ||
919 | spec->curr_chip_addx = (res != -EIO) ? | ||
920 | (spec->curr_chip_addx + 4) : ~0UL; | ||
900 | return res; | 921 | return res; |
901 | } | 922 | } |
902 | 923 | ||
@@ -926,6 +947,7 @@ static int chipio_write_data_multiple(struct hda_codec *codec, | |||
926 | */ | 947 | */ |
927 | static int chipio_read_data(struct hda_codec *codec, unsigned int *data) | 948 | static int chipio_read_data(struct hda_codec *codec, unsigned int *data) |
928 | { | 949 | { |
950 | struct ca0132_spec *spec = codec->spec; | ||
929 | int res; | 951 | int res; |
930 | 952 | ||
931 | /* post read */ | 953 | /* post read */ |
@@ -943,6 +965,10 @@ static int chipio_read_data(struct hda_codec *codec, unsigned int *data) | |||
943 | 0); | 965 | 0); |
944 | } | 966 | } |
945 | 967 | ||
968 | /*If no error encountered, automatically increment the address | ||
969 | as per chip behaviour*/ | ||
970 | spec->curr_chip_addx = (res != -EIO) ? | ||
971 | (spec->curr_chip_addx + 4) : ~0UL; | ||
946 | return res; | 972 | return res; |
947 | } | 973 | } |
948 | 974 | ||
@@ -1419,6 +1445,21 @@ static int dspio_scp(struct hda_codec *codec, | |||
1419 | } | 1445 | } |
1420 | 1446 | ||
1421 | /* | 1447 | /* |
1448 | * Set DSP parameters | ||
1449 | */ | ||
1450 | static int dspio_set_param(struct hda_codec *codec, int mod_id, | ||
1451 | int req, void *data, unsigned int len) | ||
1452 | { | ||
1453 | return dspio_scp(codec, mod_id, req, SCP_SET, data, len, NULL, NULL); | ||
1454 | } | ||
1455 | |||
1456 | static int dspio_set_uint_param(struct hda_codec *codec, int mod_id, | ||
1457 | int req, unsigned int data) | ||
1458 | { | ||
1459 | return dspio_set_param(codec, mod_id, req, &data, sizeof(unsigned int)); | ||
1460 | } | ||
1461 | |||
1462 | /* | ||
1422 | * Allocate a DSP DMA channel via an SCP message | 1463 | * Allocate a DSP DMA channel via an SCP message |
1423 | */ | 1464 | */ |
1424 | static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan) | 1465 | static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan) |
@@ -2597,6 +2638,9 @@ static bool dspload_wait_loaded(struct hda_codec *codec) | |||
2597 | return false; | 2638 | return false; |
2598 | } | 2639 | } |
2599 | 2640 | ||
2641 | /* | ||
2642 | * Controls stuffs. | ||
2643 | */ | ||
2600 | 2644 | ||
2601 | /* | 2645 | /* |
2602 | * Mixer controls helpers. | 2646 | * Mixer controls helpers. |
@@ -2699,6 +2743,300 @@ static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
2699 | } | 2743 | } |
2700 | 2744 | ||
2701 | /* | 2745 | /* |
2746 | * Select the active output. | ||
2747 | * If autodetect is enabled, output will be selected based on jack detection. | ||
2748 | * If jack inserted, headphone will be selected, else built-in speakers | ||
2749 | * If autodetect is disabled, output will be selected based on selection. | ||
2750 | */ | ||
2751 | static int ca0132_select_out(struct hda_codec *codec) | ||
2752 | { | ||
2753 | struct ca0132_spec *spec = codec->spec; | ||
2754 | unsigned int pin_ctl; | ||
2755 | int jack_present; | ||
2756 | int auto_jack; | ||
2757 | unsigned int tmp; | ||
2758 | int err; | ||
2759 | |||
2760 | snd_printdd(KERN_INFO "ca0132_select_out\n"); | ||
2761 | |||
2762 | snd_hda_power_up(codec); | ||
2763 | |||
2764 | auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID]; | ||
2765 | |||
2766 | if (auto_jack) | ||
2767 | jack_present = snd_hda_jack_detect(codec, spec->out_pins[1]); | ||
2768 | else | ||
2769 | jack_present = | ||
2770 | spec->vnode_lswitch[VNID_HP_SEL - VNODE_START_NID]; | ||
2771 | |||
2772 | if (jack_present) | ||
2773 | spec->cur_out_type = HEADPHONE_OUT; | ||
2774 | else | ||
2775 | spec->cur_out_type = SPEAKER_OUT; | ||
2776 | |||
2777 | if (spec->cur_out_type == SPEAKER_OUT) { | ||
2778 | snd_printdd(KERN_INFO "ca0132_select_out speaker\n"); | ||
2779 | /*speaker out config*/ | ||
2780 | tmp = FLOAT_ONE; | ||
2781 | err = dspio_set_uint_param(codec, 0x80, 0x04, tmp); | ||
2782 | if (err < 0) | ||
2783 | goto exit; | ||
2784 | /*enable speaker EQ*/ | ||
2785 | tmp = FLOAT_ONE; | ||
2786 | err = dspio_set_uint_param(codec, 0x8f, 0x00, tmp); | ||
2787 | if (err < 0) | ||
2788 | goto exit; | ||
2789 | |||
2790 | /* Setup EAPD */ | ||
2791 | snd_hda_codec_write(codec, spec->out_pins[1], 0, | ||
2792 | VENDOR_CHIPIO_EAPD_SEL_SET, 0x02); | ||
2793 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2794 | AC_VERB_SET_EAPD_BTLENABLE, 0x00); | ||
2795 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2796 | VENDOR_CHIPIO_EAPD_SEL_SET, 0x00); | ||
2797 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2798 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
2799 | |||
2800 | /* disable headphone node */ | ||
2801 | pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0, | ||
2802 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
2803 | snd_hda_codec_write(codec, spec->out_pins[1], 0, | ||
2804 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2805 | pin_ctl & 0xBF); | ||
2806 | /* enable speaker node */ | ||
2807 | pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, | ||
2808 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
2809 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2810 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2811 | pin_ctl | 0x40); | ||
2812 | } else { | ||
2813 | snd_printdd(KERN_INFO "ca0132_select_out hp\n"); | ||
2814 | /*headphone out config*/ | ||
2815 | tmp = FLOAT_ZERO; | ||
2816 | err = dspio_set_uint_param(codec, 0x80, 0x04, tmp); | ||
2817 | if (err < 0) | ||
2818 | goto exit; | ||
2819 | /*disable speaker EQ*/ | ||
2820 | tmp = FLOAT_ZERO; | ||
2821 | err = dspio_set_uint_param(codec, 0x8f, 0x00, tmp); | ||
2822 | if (err < 0) | ||
2823 | goto exit; | ||
2824 | |||
2825 | /* Setup EAPD */ | ||
2826 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2827 | VENDOR_CHIPIO_EAPD_SEL_SET, 0x00); | ||
2828 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2829 | AC_VERB_SET_EAPD_BTLENABLE, 0x00); | ||
2830 | snd_hda_codec_write(codec, spec->out_pins[1], 0, | ||
2831 | VENDOR_CHIPIO_EAPD_SEL_SET, 0x02); | ||
2832 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2833 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
2834 | |||
2835 | /* disable speaker*/ | ||
2836 | pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, | ||
2837 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
2838 | snd_hda_codec_write(codec, spec->out_pins[0], 0, | ||
2839 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2840 | pin_ctl & 0xBF); | ||
2841 | /* enable headphone*/ | ||
2842 | pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0, | ||
2843 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
2844 | snd_hda_codec_write(codec, spec->out_pins[1], 0, | ||
2845 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2846 | pin_ctl | 0x40); | ||
2847 | } | ||
2848 | |||
2849 | exit: | ||
2850 | snd_hda_power_down(codec); | ||
2851 | |||
2852 | return err < 0 ? err : 0; | ||
2853 | } | ||
2854 | |||
2855 | static void ca0132_set_dmic(struct hda_codec *codec, int enable); | ||
2856 | static int ca0132_mic_boost_set(struct hda_codec *codec, long val); | ||
2857 | static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val); | ||
2858 | |||
2859 | /* | ||
2860 | * Select the active VIP source | ||
2861 | */ | ||
2862 | static int ca0132_set_vipsource(struct hda_codec *codec, int val) | ||
2863 | { | ||
2864 | struct ca0132_spec *spec = codec->spec; | ||
2865 | unsigned int tmp; | ||
2866 | |||
2867 | if (!dspload_is_loaded(codec)) | ||
2868 | return 0; | ||
2869 | |||
2870 | /* if CrystalVoice if off, vipsource should be 0 */ | ||
2871 | if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] || | ||
2872 | (val == 0)) { | ||
2873 | chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); | ||
2874 | chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); | ||
2875 | chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); | ||
2876 | if (spec->cur_mic_type == DIGITAL_MIC) | ||
2877 | tmp = FLOAT_TWO; | ||
2878 | else | ||
2879 | tmp = FLOAT_ONE; | ||
2880 | dspio_set_uint_param(codec, 0x80, 0x00, tmp); | ||
2881 | tmp = FLOAT_ZERO; | ||
2882 | dspio_set_uint_param(codec, 0x80, 0x05, tmp); | ||
2883 | } else { | ||
2884 | chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000); | ||
2885 | chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000); | ||
2886 | if (spec->cur_mic_type == DIGITAL_MIC) | ||
2887 | tmp = FLOAT_TWO; | ||
2888 | else | ||
2889 | tmp = FLOAT_ONE; | ||
2890 | dspio_set_uint_param(codec, 0x80, 0x00, tmp); | ||
2891 | tmp = FLOAT_ONE; | ||
2892 | dspio_set_uint_param(codec, 0x80, 0x05, tmp); | ||
2893 | msleep(20); | ||
2894 | chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val); | ||
2895 | } | ||
2896 | |||
2897 | return 1; | ||
2898 | } | ||
2899 | |||
2900 | /* | ||
2901 | * Select the active microphone. | ||
2902 | * If autodetect is enabled, mic will be selected based on jack detection. | ||
2903 | * If jack inserted, ext.mic will be selected, else built-in mic | ||
2904 | * If autodetect is disabled, mic will be selected based on selection. | ||
2905 | */ | ||
2906 | static int ca0132_select_mic(struct hda_codec *codec) | ||
2907 | { | ||
2908 | struct ca0132_spec *spec = codec->spec; | ||
2909 | int jack_present; | ||
2910 | int auto_jack; | ||
2911 | |||
2912 | snd_printdd(KERN_INFO "ca0132_select_mic\n"); | ||
2913 | |||
2914 | snd_hda_power_up(codec); | ||
2915 | |||
2916 | auto_jack = spec->vnode_lswitch[VNID_AMIC1_ASEL - VNODE_START_NID]; | ||
2917 | |||
2918 | if (auto_jack) | ||
2919 | jack_present = snd_hda_jack_detect(codec, spec->input_pins[0]); | ||
2920 | else | ||
2921 | jack_present = | ||
2922 | spec->vnode_lswitch[VNID_AMIC1_SEL - VNODE_START_NID]; | ||
2923 | |||
2924 | if (jack_present) | ||
2925 | spec->cur_mic_type = LINE_MIC_IN; | ||
2926 | else | ||
2927 | spec->cur_mic_type = DIGITAL_MIC; | ||
2928 | |||
2929 | if (spec->cur_mic_type == DIGITAL_MIC) { | ||
2930 | /* enable digital Mic */ | ||
2931 | chipio_set_conn_rate(codec, MEM_CONNID_DMIC, SR_32_000); | ||
2932 | ca0132_set_dmic(codec, 1); | ||
2933 | ca0132_mic_boost_set(codec, 0); | ||
2934 | /* set voice focus */ | ||
2935 | ca0132_effects_set(codec, VOICE_FOCUS, | ||
2936 | spec->effects_switch | ||
2937 | [VOICE_FOCUS - EFFECT_START_NID]); | ||
2938 | } else { | ||
2939 | /* disable digital Mic */ | ||
2940 | chipio_set_conn_rate(codec, MEM_CONNID_DMIC, SR_96_000); | ||
2941 | ca0132_set_dmic(codec, 0); | ||
2942 | ca0132_mic_boost_set(codec, spec->cur_mic_boost); | ||
2943 | /* disable voice focus */ | ||
2944 | ca0132_effects_set(codec, VOICE_FOCUS, 0); | ||
2945 | } | ||
2946 | |||
2947 | snd_hda_power_down(codec); | ||
2948 | |||
2949 | return 0; | ||
2950 | } | ||
2951 | |||
2952 | /* | ||
2953 | * Set the effects parameters | ||
2954 | */ | ||
2955 | static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val) | ||
2956 | { | ||
2957 | struct ca0132_spec *spec = codec->spec; | ||
2958 | unsigned int on; | ||
2959 | int num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT; | ||
2960 | int err = 0; | ||
2961 | int idx = nid - EFFECT_START_NID; | ||
2962 | |||
2963 | if ((idx < 0) || (idx >= num_fx)) | ||
2964 | return 0; /* no changed */ | ||
2965 | |||
2966 | /* for out effect, qualify with PE */ | ||
2967 | if ((nid >= OUT_EFFECT_START_NID) && (nid < OUT_EFFECT_END_NID)) { | ||
2968 | /* if PE if off, turn off out effects. */ | ||
2969 | if (!spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) | ||
2970 | val = 0; | ||
2971 | } | ||
2972 | |||
2973 | /* for in effect, qualify with CrystalVoice */ | ||
2974 | if ((nid >= IN_EFFECT_START_NID) && (nid < IN_EFFECT_END_NID)) { | ||
2975 | /* if CrystalVoice if off, turn off in effects. */ | ||
2976 | if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID]) | ||
2977 | val = 0; | ||
2978 | |||
2979 | /* Voice Focus applies to 2-ch Mic, Digital Mic */ | ||
2980 | if ((nid == VOICE_FOCUS) && (spec->cur_mic_type != DIGITAL_MIC)) | ||
2981 | val = 0; | ||
2982 | } | ||
2983 | |||
2984 | snd_printdd(KERN_INFO, "ca0132_effect_set: nid=0x%x, val=%ld\n", | ||
2985 | nid, val); | ||
2986 | |||
2987 | on = (val == 0) ? FLOAT_ZERO : FLOAT_ONE; | ||
2988 | err = dspio_set_uint_param(codec, ca0132_effects[idx].mid, | ||
2989 | ca0132_effects[idx].reqs[0], on); | ||
2990 | |||
2991 | if (err < 0) | ||
2992 | return 0; /* no changed */ | ||
2993 | |||
2994 | return 1; | ||
2995 | } | ||
2996 | |||
2997 | /* Check if Mic1 is streaming, if so, stop streaming */ | ||
2998 | static int stop_mic1(struct hda_codec *codec) | ||
2999 | { | ||
3000 | struct ca0132_spec *spec = codec->spec; | ||
3001 | unsigned int oldval = snd_hda_codec_read(codec, spec->adcs[0], 0, | ||
3002 | AC_VERB_GET_CONV, 0); | ||
3003 | if (oldval != 0) | ||
3004 | snd_hda_codec_write(codec, spec->adcs[0], 0, | ||
3005 | AC_VERB_SET_CHANNEL_STREAMID, | ||
3006 | 0); | ||
3007 | return oldval; | ||
3008 | } | ||
3009 | |||
3010 | /* Resume Mic1 streaming if it was stopped. */ | ||
3011 | static void resume_mic1(struct hda_codec *codec, unsigned int oldval) | ||
3012 | { | ||
3013 | struct ca0132_spec *spec = codec->spec; | ||
3014 | /* Restore the previous stream and channel */ | ||
3015 | if (oldval != 0) | ||
3016 | snd_hda_codec_write(codec, spec->adcs[0], 0, | ||
3017 | AC_VERB_SET_CHANNEL_STREAMID, | ||
3018 | oldval); | ||
3019 | } | ||
3020 | |||
3021 | /* | ||
3022 | * Set Mic Boost | ||
3023 | */ | ||
3024 | static int ca0132_mic_boost_set(struct hda_codec *codec, long val) | ||
3025 | { | ||
3026 | struct ca0132_spec *spec = codec->spec; | ||
3027 | int ret = 0; | ||
3028 | |||
3029 | if (val) /* on */ | ||
3030 | ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0, | ||
3031 | HDA_INPUT, 0, HDA_AMP_VOLMASK, 3); | ||
3032 | else /* off */ | ||
3033 | ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0, | ||
3034 | HDA_INPUT, 0, HDA_AMP_VOLMASK, 0); | ||
3035 | |||
3036 | return ret; | ||
3037 | } | ||
3038 | |||
3039 | /* | ||
2702 | */ | 3040 | */ |
2703 | static struct hda_pcm_stream ca0132_pcm_analog_playback = { | 3041 | static struct hda_pcm_stream ca0132_pcm_analog_playback = { |
2704 | .substreams = 1, | 3042 | .substreams = 1, |
@@ -2892,7 +3230,7 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol, | |||
2892 | 3230 | ||
2893 | /* any change? */ | 3231 | /* any change? */ |
2894 | if ((spec->curr_hp_volume[0] == left_vol) && | 3232 | if ((spec->curr_hp_volume[0] == left_vol) && |
2895 | (spec->curr_hp_volume[1] == right_vol)) | 3233 | (spec->curr_hp_volume[1] == right_vol)) |
2896 | return 0; | 3234 | return 0; |
2897 | 3235 | ||
2898 | snd_hda_power_up(codec); | 3236 | snd_hda_power_up(codec); |
@@ -2925,7 +3263,7 @@ static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) | |||
2925 | { | 3263 | { |
2926 | struct snd_kcontrol_new knew = | 3264 | struct snd_kcontrol_new knew = |
2927 | HDA_CODEC_MUTE_MONO("Headphone Playback Switch", | 3265 | HDA_CODEC_MUTE_MONO("Headphone Playback Switch", |
2928 | nid, 1, 0, HDA_OUTPUT); | 3266 | nid, 1, 0, HDA_OUTPUT); |
2929 | knew.get = ca0132_hp_switch_get; | 3267 | knew.get = ca0132_hp_switch_get; |
2930 | knew.put = ca0132_hp_switch_put; | 3268 | knew.put = ca0132_hp_switch_put; |
2931 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 3269 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
@@ -2935,7 +3273,7 @@ static int add_hp_volume(struct hda_codec *codec, hda_nid_t nid) | |||
2935 | { | 3273 | { |
2936 | struct snd_kcontrol_new knew = | 3274 | struct snd_kcontrol_new knew = |
2937 | HDA_CODEC_VOLUME_MONO("Headphone Playback Volume", | 3275 | HDA_CODEC_VOLUME_MONO("Headphone Playback Volume", |
2938 | nid, 3, 0, HDA_OUTPUT); | 3276 | nid, 3, 0, HDA_OUTPUT); |
2939 | knew.get = ca0132_hp_volume_get; | 3277 | knew.get = ca0132_hp_volume_get; |
2940 | knew.put = ca0132_hp_volume_put; | 3278 | knew.put = ca0132_hp_volume_put; |
2941 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 3279 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
@@ -2945,7 +3283,7 @@ static int add_speaker_switch(struct hda_codec *codec, hda_nid_t nid) | |||
2945 | { | 3283 | { |
2946 | struct snd_kcontrol_new knew = | 3284 | struct snd_kcontrol_new knew = |
2947 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", | 3285 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", |
2948 | nid, 1, 0, HDA_OUTPUT); | 3286 | nid, 1, 0, HDA_OUTPUT); |
2949 | knew.get = ca0132_speaker_switch_get; | 3287 | knew.get = ca0132_speaker_switch_get; |
2950 | knew.put = ca0132_speaker_switch_put; | 3288 | knew.put = ca0132_speaker_switch_put; |
2951 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 3289 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
@@ -3021,6 +3359,215 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
3021 | return 0; | 3359 | return 0; |
3022 | } | 3360 | } |
3023 | 3361 | ||
3362 | static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir) | ||
3363 | { | ||
3364 | unsigned int caps; | ||
3365 | |||
3366 | caps = snd_hda_param_read(codec, nid, dir == HDA_OUTPUT ? | ||
3367 | AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); | ||
3368 | snd_hda_override_amp_caps(codec, nid, dir, caps); | ||
3369 | } | ||
3370 | |||
3371 | /* | ||
3372 | * Switch between Digital built-in mic and analog mic. | ||
3373 | */ | ||
3374 | static void ca0132_set_dmic(struct hda_codec *codec, int enable) | ||
3375 | { | ||
3376 | struct ca0132_spec *spec = codec->spec; | ||
3377 | unsigned int tmp; | ||
3378 | u8 val; | ||
3379 | unsigned int oldval; | ||
3380 | |||
3381 | snd_printdd(KERN_INFO "ca0132_set_dmic: enable=%d\n", enable); | ||
3382 | |||
3383 | oldval = stop_mic1(codec); | ||
3384 | ca0132_set_vipsource(codec, 0); | ||
3385 | if (enable) { | ||
3386 | /* set DMic input as 2-ch */ | ||
3387 | tmp = FLOAT_TWO; | ||
3388 | dspio_set_uint_param(codec, 0x80, 0x00, tmp); | ||
3389 | |||
3390 | val = spec->dmic_ctl; | ||
3391 | val |= 0x80; | ||
3392 | snd_hda_codec_write(codec, spec->input_pins[0], 0, | ||
3393 | VENDOR_CHIPIO_DMIC_CTL_SET, val); | ||
3394 | |||
3395 | if (!(spec->dmic_ctl & 0x20)) | ||
3396 | chipio_set_control_flag(codec, CONTROL_FLAG_DMIC, 1); | ||
3397 | } else { | ||
3398 | /* set AMic input as mono */ | ||
3399 | tmp = FLOAT_ONE; | ||
3400 | dspio_set_uint_param(codec, 0x80, 0x00, tmp); | ||
3401 | |||
3402 | val = spec->dmic_ctl; | ||
3403 | /* clear bit7 and bit5 to disable dmic */ | ||
3404 | val &= 0x5f; | ||
3405 | snd_hda_codec_write(codec, spec->input_pins[0], 0, | ||
3406 | VENDOR_CHIPIO_DMIC_CTL_SET, val); | ||
3407 | |||
3408 | if (!(spec->dmic_ctl & 0x20)) | ||
3409 | chipio_set_control_flag(codec, CONTROL_FLAG_DMIC, 0); | ||
3410 | } | ||
3411 | ca0132_set_vipsource(codec, 1); | ||
3412 | resume_mic1(codec, oldval); | ||
3413 | } | ||
3414 | |||
3415 | /* | ||
3416 | * Initialization for Digital Mic. | ||
3417 | */ | ||
3418 | static void ca0132_init_dmic(struct hda_codec *codec) | ||
3419 | { | ||
3420 | struct ca0132_spec *spec = codec->spec; | ||
3421 | u8 val; | ||
3422 | |||
3423 | /* Setup Digital Mic here, but don't enable. | ||
3424 | * Enable based on jack detect. | ||
3425 | */ | ||
3426 | |||
3427 | /* MCLK uses MPIO1, set to enable. | ||
3428 | * Bit 2-0: MPIO select | ||
3429 | * Bit 3: set to disable | ||
3430 | * Bit 7-4: reserved | ||
3431 | */ | ||
3432 | val = 0x01; | ||
3433 | snd_hda_codec_write(codec, spec->input_pins[0], 0, | ||
3434 | VENDOR_CHIPIO_DMIC_MCLK_SET, val); | ||
3435 | |||
3436 | /* Data1 uses MPIO3. Data2 not use | ||
3437 | * Bit 2-0: Data1 MPIO select | ||
3438 | * Bit 3: set disable Data1 | ||
3439 | * Bit 6-4: Data2 MPIO select | ||
3440 | * Bit 7: set disable Data2 | ||
3441 | */ | ||
3442 | val = 0x83; | ||
3443 | snd_hda_codec_write(codec, spec->input_pins[0], 0, | ||
3444 | VENDOR_CHIPIO_DMIC_PIN_SET, val); | ||
3445 | |||
3446 | /* Use Ch-0 and Ch-1. Rate is 48K, mode 1. Disable DMic first. | ||
3447 | * Bit 3-0: Channel mask | ||
3448 | * Bit 4: set for 48KHz, clear for 32KHz | ||
3449 | * Bit 5: mode | ||
3450 | * Bit 6: set to select Data2, clear for Data1 | ||
3451 | * Bit 7: set to enable DMic, clear for AMic | ||
3452 | */ | ||
3453 | val = 0x23; | ||
3454 | /* keep a copy of dmic ctl val for enable/disable dmic purpuse */ | ||
3455 | spec->dmic_ctl = val; | ||
3456 | snd_hda_codec_write(codec, spec->input_pins[0], 0, | ||
3457 | VENDOR_CHIPIO_DMIC_CTL_SET, val); | ||
3458 | } | ||
3459 | |||
3460 | /* | ||
3461 | * Initialization for Analog Mic 2 | ||
3462 | */ | ||
3463 | static void ca0132_init_analog_mic2(struct hda_codec *codec) | ||
3464 | { | ||
3465 | struct ca0132_spec *spec = codec->spec; | ||
3466 | |||
3467 | mutex_lock(&spec->chipio_mutex); | ||
3468 | snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, | ||
3469 | VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20); | ||
3470 | snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, | ||
3471 | VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19); | ||
3472 | snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, | ||
3473 | VENDOR_CHIPIO_8051_DATA_WRITE, 0x00); | ||
3474 | snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, | ||
3475 | VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x2D); | ||
3476 | snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, | ||
3477 | VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19); | ||
3478 | snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, | ||
3479 | VENDOR_CHIPIO_8051_DATA_WRITE, 0x00); | ||
3480 | mutex_unlock(&spec->chipio_mutex); | ||
3481 | } | ||
3482 | |||
3483 | static void ca0132_refresh_widget_caps(struct hda_codec *codec) | ||
3484 | { | ||
3485 | struct ca0132_spec *spec = codec->spec; | ||
3486 | int i; | ||
3487 | hda_nid_t nid; | ||
3488 | |||
3489 | snd_printdd(KERN_INFO "ca0132_refresh_widget_caps.\n"); | ||
3490 | nid = codec->start_nid; | ||
3491 | for (i = 0; i < codec->num_nodes; i++, nid++) | ||
3492 | codec->wcaps[i] = snd_hda_param_read(codec, nid, | ||
3493 | AC_PAR_AUDIO_WIDGET_CAP); | ||
3494 | |||
3495 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
3496 | refresh_amp_caps(codec, spec->dacs[i], HDA_OUTPUT); | ||
3497 | |||
3498 | for (i = 0; i < spec->num_outputs; i++) | ||
3499 | refresh_amp_caps(codec, spec->out_pins[i], HDA_OUTPUT); | ||
3500 | |||
3501 | for (i = 0; i < spec->num_inputs; i++) { | ||
3502 | refresh_amp_caps(codec, spec->adcs[i], HDA_INPUT); | ||
3503 | refresh_amp_caps(codec, spec->input_pins[i], HDA_INPUT); | ||
3504 | } | ||
3505 | } | ||
3506 | |||
3507 | /* | ||
3508 | * Setup default parameters for DSP | ||
3509 | */ | ||
3510 | static void ca0132_setup_defaults(struct hda_codec *codec) | ||
3511 | { | ||
3512 | unsigned int tmp; | ||
3513 | int num_fx; | ||
3514 | int idx, i; | ||
3515 | |||
3516 | if (!dspload_is_loaded(codec)) | ||
3517 | return; | ||
3518 | |||
3519 | /* out, in effects + voicefx */ | ||
3520 | num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1; | ||
3521 | for (idx = 0; idx < num_fx; idx++) { | ||
3522 | for (i = 0; i <= ca0132_effects[idx].params; i++) { | ||
3523 | dspio_set_uint_param(codec, ca0132_effects[idx].mid, | ||
3524 | ca0132_effects[idx].reqs[i], | ||
3525 | ca0132_effects[idx].def_vals[i]); | ||
3526 | } | ||
3527 | } | ||
3528 | |||
3529 | /*remove DSP headroom*/ | ||
3530 | tmp = FLOAT_ZERO; | ||
3531 | dspio_set_uint_param(codec, 0x96, 0x3C, tmp); | ||
3532 | |||
3533 | /*set speaker EQ bypass attenuation*/ | ||
3534 | dspio_set_uint_param(codec, 0x8f, 0x01, tmp); | ||
3535 | |||
3536 | /* set AMic1 and AMic2 as mono mic */ | ||
3537 | tmp = FLOAT_ONE; | ||
3538 | dspio_set_uint_param(codec, 0x80, 0x00, tmp); | ||
3539 | dspio_set_uint_param(codec, 0x80, 0x01, tmp); | ||
3540 | |||
3541 | /* set AMic1 as CrystalVoice input */ | ||
3542 | tmp = FLOAT_ONE; | ||
3543 | dspio_set_uint_param(codec, 0x80, 0x05, tmp); | ||
3544 | |||
3545 | /* set WUH source */ | ||
3546 | tmp = FLOAT_TWO; | ||
3547 | dspio_set_uint_param(codec, 0x31, 0x00, tmp); | ||
3548 | } | ||
3549 | |||
3550 | /* | ||
3551 | * Initialization of flags in chip | ||
3552 | */ | ||
3553 | static void ca0132_init_flags(struct hda_codec *codec) | ||
3554 | { | ||
3555 | chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); | ||
3556 | chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_COMMON_MODE, 0); | ||
3557 | chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_COMMON_MODE, 0); | ||
3558 | chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0); | ||
3559 | chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); | ||
3560 | chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1); | ||
3561 | } | ||
3562 | |||
3563 | /* | ||
3564 | * Initialization of parameters in chip | ||
3565 | */ | ||
3566 | static void ca0132_init_params(struct hda_codec *codec) | ||
3567 | { | ||
3568 | chipio_set_control_param(codec, CONTROL_PARAM_PORTA_160OHM_GAIN, 6); | ||
3569 | chipio_set_control_param(codec, CONTROL_PARAM_PORTD_160OHM_GAIN, 6); | ||
3570 | } | ||
3024 | 3571 | ||
3025 | static void ca0132_set_ct_ext(struct hda_codec *codec, int enable) | 3572 | static void ca0132_set_ct_ext(struct hda_codec *codec, int enable) |
3026 | { | 3573 | { |
@@ -3038,7 +3585,6 @@ static void ca0132_config(struct hda_codec *codec) | |||
3038 | struct ca0132_spec *spec = codec->spec; | 3585 | struct ca0132_spec *spec = codec->spec; |
3039 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3586 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3040 | 3587 | ||
3041 | codec->pcm_format_first = 1; | ||
3042 | codec->no_sticky_stream = 1; | 3588 | codec->no_sticky_stream = 1; |
3043 | 3589 | ||
3044 | /* line-outs */ | 3590 | /* line-outs */ |
@@ -3088,16 +3634,115 @@ static void ca0132_config(struct hda_codec *codec) | |||
3088 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | 3634 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; |
3089 | } | 3635 | } |
3090 | 3636 | ||
3637 | /* | ||
3638 | * Verbs tables. | ||
3639 | */ | ||
3640 | |||
3641 | /* Sends before DSP download. */ | ||
3642 | static struct hda_verb ca0132_base_init_verbs[] = { | ||
3643 | /*enable ct extension*/ | ||
3644 | {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1}, | ||
3645 | /*enable DSP node unsol, needed for DSP download*/ | ||
3646 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_DSP}, | ||
3647 | {} | ||
3648 | }; | ||
3649 | |||
3650 | /* Send at exit. */ | ||
3651 | static struct hda_verb ca0132_base_exit_verbs[] = { | ||
3652 | /*set afg to D3*/ | ||
3653 | {0x01, AC_VERB_SET_POWER_STATE, 0x03}, | ||
3654 | /*disable ct extension*/ | ||
3655 | {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0}, | ||
3656 | {} | ||
3657 | }; | ||
3658 | |||
3659 | /* Other verbs tables. Sends after DSP download. */ | ||
3660 | static struct hda_verb ca0132_init_verbs0[] = { | ||
3661 | /* chip init verbs */ | ||
3662 | {0x15, 0x70D, 0xF0}, | ||
3663 | {0x15, 0x70E, 0xFE}, | ||
3664 | {0x15, 0x707, 0x75}, | ||
3665 | {0x15, 0x707, 0xD3}, | ||
3666 | {0x15, 0x707, 0x09}, | ||
3667 | {0x15, 0x707, 0x53}, | ||
3668 | {0x15, 0x707, 0xD4}, | ||
3669 | {0x15, 0x707, 0xEF}, | ||
3670 | {0x15, 0x707, 0x75}, | ||
3671 | {0x15, 0x707, 0xD3}, | ||
3672 | {0x15, 0x707, 0x09}, | ||
3673 | {0x15, 0x707, 0x02}, | ||
3674 | {0x15, 0x707, 0x37}, | ||
3675 | {0x15, 0x707, 0x78}, | ||
3676 | {0x15, 0x53C, 0xCE}, | ||
3677 | {0x15, 0x575, 0xC9}, | ||
3678 | {0x15, 0x53D, 0xCE}, | ||
3679 | {0x15, 0x5B7, 0xC9}, | ||
3680 | {0x15, 0x70D, 0xE8}, | ||
3681 | {0x15, 0x70E, 0xFE}, | ||
3682 | {0x15, 0x707, 0x02}, | ||
3683 | {0x15, 0x707, 0x68}, | ||
3684 | {0x15, 0x707, 0x62}, | ||
3685 | {0x15, 0x53A, 0xCE}, | ||
3686 | {0x15, 0x546, 0xC9}, | ||
3687 | {0x15, 0x53B, 0xCE}, | ||
3688 | {0x15, 0x5E8, 0xC9}, | ||
3689 | {0x15, 0x717, 0x0D}, | ||
3690 | {0x15, 0x718, 0x20}, | ||
3691 | {} | ||
3692 | }; | ||
3693 | |||
3694 | static struct hda_verb ca0132_init_verbs1[] = { | ||
3695 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_HP}, | ||
3696 | {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_AMIC1}, | ||
3697 | /* config EAPD */ | ||
3698 | {0x0b, 0x78D, 0x00}, | ||
3699 | /*{0x0b, AC_VERB_SET_EAPD_BTLENABLE, 0x02},*/ | ||
3700 | /*{0x10, 0x78D, 0x02},*/ | ||
3701 | /*{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x02},*/ | ||
3702 | {} | ||
3703 | }; | ||
3704 | |||
3091 | static void ca0132_init_chip(struct hda_codec *codec) | 3705 | static void ca0132_init_chip(struct hda_codec *codec) |
3092 | { | 3706 | { |
3093 | struct ca0132_spec *spec = codec->spec; | 3707 | struct ca0132_spec *spec = codec->spec; |
3708 | int num_fx; | ||
3709 | int i; | ||
3710 | unsigned int on; | ||
3094 | 3711 | ||
3095 | mutex_init(&spec->chipio_mutex); | 3712 | mutex_init(&spec->chipio_mutex); |
3713 | |||
3714 | spec->cur_out_type = SPEAKER_OUT; | ||
3715 | spec->cur_mic_type = DIGITAL_MIC; | ||
3716 | spec->cur_mic_boost = 0; | ||
3717 | |||
3718 | for (i = 0; i < VNODES_COUNT; i++) { | ||
3719 | spec->vnode_lvol[i] = 0x5a; | ||
3720 | spec->vnode_rvol[i] = 0x5a; | ||
3721 | spec->vnode_lswitch[i] = 0; | ||
3722 | spec->vnode_rswitch[i] = 0; | ||
3723 | } | ||
3724 | |||
3725 | /* | ||
3726 | * Default states for effects are in ca0132_effects[]. | ||
3727 | */ | ||
3728 | num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT; | ||
3729 | for (i = 0; i < num_fx; i++) { | ||
3730 | on = (unsigned int)ca0132_effects[i].reqs[0]; | ||
3731 | spec->effects_switch[i] = on ? 1 : 0; | ||
3732 | } | ||
3733 | |||
3734 | spec->voicefx_val = 0; | ||
3735 | spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID] = 1; | ||
3736 | spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] = 0; | ||
3737 | |||
3096 | } | 3738 | } |
3097 | 3739 | ||
3098 | static void ca0132_exit_chip(struct hda_codec *codec) | 3740 | static void ca0132_exit_chip(struct hda_codec *codec) |
3099 | { | 3741 | { |
3100 | /* put any chip cleanup stuffs here. */ | 3742 | /* put any chip cleanup stuffs here. */ |
3743 | |||
3744 | if (dspload_is_loaded(codec)) | ||
3745 | dsp_reset(codec); | ||
3101 | } | 3746 | } |
3102 | 3747 | ||
3103 | static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k) | 3748 | static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k) |
@@ -3155,15 +3800,25 @@ static int ca0132_init(struct hda_codec *codec) | |||
3155 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3800 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3156 | int i; | 3801 | int i; |
3157 | 3802 | ||
3803 | spec->dsp_state = DSP_DOWNLOAD_INIT; | ||
3804 | spec->curr_chip_addx = (unsigned int)INVALID_CHIP_ADDRESS; | ||
3805 | |||
3806 | snd_hda_power_up(codec); | ||
3807 | |||
3808 | ca0132_init_params(codec); | ||
3809 | ca0132_init_flags(codec); | ||
3810 | snd_hda_sequence_write(codec, spec->base_init_verbs); | ||
3158 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 3811 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
3159 | ca0132_download_dsp(codec); | 3812 | ca0132_download_dsp(codec); |
3160 | #endif | 3813 | #endif |
3814 | ca0132_refresh_widget_caps(codec); | ||
3815 | ca0132_setup_defaults(codec); | ||
3816 | ca0132_init_analog_mic2(codec); | ||
3817 | ca0132_init_dmic(codec); | ||
3818 | |||
3819 | for (i = 0; i < spec->num_outputs; i++) | ||
3820 | init_output(codec, spec->out_pins[i], spec->dacs[0]); | ||
3161 | 3821 | ||
3162 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
3163 | init_output(codec, spec->out_pins[i], | ||
3164 | spec->multiout.dac_nids[i]); | ||
3165 | } | ||
3166 | init_output(codec, cfg->hp_pins[0], spec->hp_dac); | ||
3167 | init_output(codec, cfg->dig_out_pins[0], spec->dig_out); | 3822 | init_output(codec, cfg->dig_out_pins[0], spec->dig_out); |
3168 | 3823 | ||
3169 | for (i = 0; i < spec->num_inputs; i++) | 3824 | for (i = 0; i < spec->num_inputs; i++) |
@@ -3171,16 +3826,25 @@ static int ca0132_init(struct hda_codec *codec) | |||
3171 | 3826 | ||
3172 | init_input(codec, cfg->dig_in_pin, spec->dig_in); | 3827 | init_input(codec, cfg->dig_in_pin, spec->dig_in); |
3173 | 3828 | ||
3174 | ca0132_set_ct_ext(codec, 1); | 3829 | for (i = 0; i < spec->num_init_verbs; i++) |
3830 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | ||
3831 | |||
3832 | ca0132_select_out(codec); | ||
3833 | ca0132_select_mic(codec); | ||
3834 | |||
3835 | snd_hda_power_down(codec); | ||
3175 | 3836 | ||
3176 | return 0; | 3837 | return 0; |
3177 | } | 3838 | } |
3178 | 3839 | ||
3179 | |||
3180 | static void ca0132_free(struct hda_codec *codec) | 3840 | static void ca0132_free(struct hda_codec *codec) |
3181 | { | 3841 | { |
3182 | ca0132_set_ct_ext(codec, 0); | 3842 | struct ca0132_spec *spec = codec->spec; |
3843 | |||
3844 | snd_hda_power_up(codec); | ||
3845 | snd_hda_sequence_write(codec, spec->base_exit_verbs); | ||
3183 | ca0132_exit_chip(codec); | 3846 | ca0132_exit_chip(codec); |
3847 | snd_hda_power_down(codec); | ||
3184 | kfree(codec->spec); | 3848 | kfree(codec->spec); |
3185 | } | 3849 | } |
3186 | 3850 | ||
@@ -3191,8 +3855,6 @@ static struct hda_codec_ops ca0132_patch_ops = { | |||
3191 | .free = ca0132_free, | 3855 | .free = ca0132_free, |
3192 | }; | 3856 | }; |
3193 | 3857 | ||
3194 | |||
3195 | |||
3196 | static int patch_ca0132(struct hda_codec *codec) | 3858 | static int patch_ca0132(struct hda_codec *codec) |
3197 | { | 3859 | { |
3198 | struct ca0132_spec *spec; | 3860 | struct ca0132_spec *spec; |
@@ -3204,6 +3866,12 @@ static int patch_ca0132(struct hda_codec *codec) | |||
3204 | return -ENOMEM; | 3866 | return -ENOMEM; |
3205 | codec->spec = spec; | 3867 | codec->spec = spec; |
3206 | 3868 | ||
3869 | spec->base_init_verbs = ca0132_base_init_verbs; | ||
3870 | spec->base_exit_verbs = ca0132_base_exit_verbs; | ||
3871 | spec->init_verbs[0] = ca0132_init_verbs0; | ||
3872 | spec->init_verbs[1] = ca0132_init_verbs1; | ||
3873 | spec->num_init_verbs = 2; | ||
3874 | |||
3207 | ca0132_init_chip(codec); | 3875 | ca0132_init_chip(codec); |
3208 | 3876 | ||
3209 | ca0132_config(codec); | 3877 | ca0132_config(codec); |