| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: hdaudio_afg.c,v 1.14.2.2 2009/09/26 19:52:10 snj Exp $ */ | | 1 | /* $NetBSD: hdaudio_afg.c,v 1.14.2.3 2009/09/28 00:40:21 snj Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk> | | 4 | * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk> |
5 | * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca> | | 5 | * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca> |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation | | 8 | * This code is derived from software contributed to The NetBSD Foundation |
9 | * by Precedence Technologies Ltd | | 9 | * by Precedence Technologies Ltd |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -50,27 +50,27 @@ | | | @@ -50,27 +50,27 @@ |
50 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 50 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
51 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 51 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
52 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 52 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
53 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 53 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
54 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 54 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
55 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 55 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
56 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 56 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
57 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 57 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
59 | * SUCH DAMAGE. | | 59 | * SUCH DAMAGE. |
60 | */ | | 60 | */ |
61 | | | 61 | |
62 | #include <sys/cdefs.h> | | 62 | #include <sys/cdefs.h> |
63 | __KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.14.2.2 2009/09/26 19:52:10 snj Exp $"); | | 63 | __KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.14.2.3 2009/09/28 00:40:21 snj Exp $"); |
64 | | | 64 | |
65 | #include <sys/types.h> | | 65 | #include <sys/types.h> |
66 | #include <sys/param.h> | | 66 | #include <sys/param.h> |
67 | #include <sys/systm.h> | | 67 | #include <sys/systm.h> |
68 | #include <sys/kernel.h> | | 68 | #include <sys/kernel.h> |
69 | #include <sys/device.h> | | 69 | #include <sys/device.h> |
70 | #include <sys/conf.h> | | 70 | #include <sys/conf.h> |
71 | #include <sys/bus.h> | | 71 | #include <sys/bus.h> |
72 | #include <sys/kmem.h> | | 72 | #include <sys/kmem.h> |
73 | | | 73 | |
74 | #include <sys/audioio.h> | | 74 | #include <sys/audioio.h> |
75 | #include <dev/audio_if.h> | | 75 | #include <dev/audio_if.h> |
76 | #include <dev/auconv.h> | | 76 | #include <dev/auconv.h> |
| @@ -96,27 +96,27 @@ static int hdaudio_afg_debug = 0; | | | @@ -96,27 +96,27 @@ static int hdaudio_afg_debug = 0; |
96 | if (hdaudio_afg_debug) hda_print(sc, __VA_ARGS__) | | 96 | if (hdaudio_afg_debug) hda_print(sc, __VA_ARGS__) |
97 | | | 97 | |
98 | #define HDAUDIO_MIXER_CLASS_OUTPUTS 0 | | 98 | #define HDAUDIO_MIXER_CLASS_OUTPUTS 0 |
99 | #define HDAUDIO_MIXER_CLASS_INPUTS 1 | | 99 | #define HDAUDIO_MIXER_CLASS_INPUTS 1 |
100 | #define HDAUDIO_MIXER_CLASS_RECORD 2 | | 100 | #define HDAUDIO_MIXER_CLASS_RECORD 2 |
101 | #define HDAUDIO_MIXER_CLASS_LAST HDAUDIO_MIXER_CLASS_RECORD | | 101 | #define HDAUDIO_MIXER_CLASS_LAST HDAUDIO_MIXER_CLASS_RECORD |
102 | | | 102 | |
103 | #define HDAUDIO_GPIO_MASK 0 | | 103 | #define HDAUDIO_GPIO_MASK 0 |
104 | #define HDAUDIO_GPIO_DIR 1 | | 104 | #define HDAUDIO_GPIO_DIR 1 |
105 | #define HDAUDIO_GPIO_DATA 2 | | 105 | #define HDAUDIO_GPIO_DATA 2 |
106 | | | 106 | |
107 | #define HDAUDIO_UNSOLTAG_EVENT_HP 0x00 | | 107 | #define HDAUDIO_UNSOLTAG_EVENT_HP 0x00 |
108 | | | 108 | |
109 | #define HDAUDIO_HP_SENSE_PERIOD (hz / 2) | | 109 | #define HDAUDIO_HP_SENSE_PERIOD hz |
110 | | | 110 | |
111 | static const char *hdaudio_afg_mixer_names[] = HDAUDIO_DEVICE_NAMES; | | 111 | static const char *hdaudio_afg_mixer_names[] = HDAUDIO_DEVICE_NAMES; |
112 | | | 112 | |
113 | static const char *hdaudio_afg_port_connectivity[] = { | | 113 | static const char *hdaudio_afg_port_connectivity[] = { |
114 | "Jack", | | 114 | "Jack", |
115 | "Unconnected", | | 115 | "Unconnected", |
116 | "Fixed Function", | | 116 | "Fixed Function", |
117 | "Jack & Fixed Function" | | 117 | "Jack & Fixed Function" |
118 | }; | | 118 | }; |
119 | static const char *hdaudio_afg_default_device[] = { | | 119 | static const char *hdaudio_afg_default_device[] = { |
120 | "Line Out", | | 120 | "Line Out", |
121 | "Speaker", | | 121 | "Speaker", |
122 | "HP Out", | | 122 | "HP Out", |
| @@ -280,44 +280,46 @@ struct hdaudio_afg_softc { | | | @@ -280,44 +280,46 @@ struct hdaudio_afg_softc { |
280 | int sc_nwidgets; | | 280 | int sc_nwidgets; |
281 | struct hdaudio_widget *sc_widgets; | | 281 | struct hdaudio_widget *sc_widgets; |
282 | int sc_nassocs; | | 282 | int sc_nassocs; |
283 | struct hdaudio_assoc *sc_assocs; | | 283 | struct hdaudio_assoc *sc_assocs; |
284 | int sc_nctls; | | 284 | int sc_nctls; |
285 | struct hdaudio_control *sc_ctls; | | 285 | struct hdaudio_control *sc_ctls; |
286 | int sc_nmixers; | | 286 | int sc_nmixers; |
287 | struct hdaudio_mixer *sc_mixers; | | 287 | struct hdaudio_mixer *sc_mixers; |
288 | | | 288 | |
289 | int sc_pchan, sc_rchan; | | 289 | int sc_pchan, sc_rchan; |
290 | audio_params_t sc_pparam, sc_rparam; | | 290 | audio_params_t sc_pparam, sc_rparam; |
291 | | | 291 | |
292 | struct callout sc_jack_callout; | | 292 | struct callout sc_jack_callout; |
| | | 293 | bool sc_jack_polling; |
293 | | | 294 | |
294 | struct { | | 295 | struct { |
295 | uint32_t afg_cap; | | 296 | uint32_t afg_cap; |
296 | uint32_t pcm_size_rate; | | 297 | uint32_t pcm_size_rate; |
297 | uint32_t stream_format; | | 298 | uint32_t stream_format; |
298 | uint32_t outamp_cap; | | 299 | uint32_t outamp_cap; |
299 | uint32_t inamp_cap; | | 300 | uint32_t inamp_cap; |
300 | uint32_t power_states; | | 301 | uint32_t power_states; |
301 | uint32_t gpio_cnt; | | 302 | uint32_t gpio_cnt; |
302 | } sc_p; | | 303 | } sc_p; |
303 | | | 304 | |
304 | struct hdaudio_audiodev sc_audiodev; | | 305 | struct hdaudio_audiodev sc_audiodev; |
305 | }; | | 306 | }; |
306 | | | 307 | |
307 | static int hdaudio_afg_match(device_t, cfdata_t, void *); | | 308 | static int hdaudio_afg_match(device_t, cfdata_t, void *); |
308 | static void hdaudio_afg_attach(device_t, device_t, void *); | | 309 | static void hdaudio_afg_attach(device_t, device_t, void *); |
309 | static int hdaudio_afg_detach(device_t, int); | | 310 | static int hdaudio_afg_detach(device_t, int); |
310 | static void hdaudio_afg_childdet(device_t, device_t); | | 311 | static void hdaudio_afg_childdet(device_t, device_t); |
| | | 312 | static bool hdaudio_afg_suspend(device_t PMF_FN_PROTO); |
311 | static bool hdaudio_afg_resume(device_t PMF_FN_PROTO); | | 313 | static bool hdaudio_afg_resume(device_t PMF_FN_PROTO); |
312 | | | 314 | |
313 | CFATTACH_DECL2_NEW( | | 315 | CFATTACH_DECL2_NEW( |
314 | hdafg, | | 316 | hdafg, |
315 | sizeof(struct hdaudio_afg_softc), | | 317 | sizeof(struct hdaudio_afg_softc), |
316 | hdaudio_afg_match, | | 318 | hdaudio_afg_match, |
317 | hdaudio_afg_attach, | | 319 | hdaudio_afg_attach, |
318 | hdaudio_afg_detach, | | 320 | hdaudio_afg_detach, |
319 | NULL, | | 321 | NULL, |
320 | NULL, | | 322 | NULL, |
321 | hdaudio_afg_childdet | | 323 | hdaudio_afg_childdet |
322 | ); | | 324 | ); |
323 | | | 325 | |
| @@ -2974,26 +2976,29 @@ hdaudio_afg_configure_encodings(struct h | | | @@ -2974,26 +2976,29 @@ hdaudio_afg_configure_encodings(struct h |
2974 | | | 2976 | |
2975 | hda_print1(sc, "\n"); | | 2977 | hda_print1(sc, "\n"); |
2976 | } | | 2978 | } |
2977 | | | 2979 | |
2978 | static void | | 2980 | static void |
2979 | hdaudio_afg_hp_switch_handler(void *opaque) | | 2981 | hdaudio_afg_hp_switch_handler(void *opaque) |
2980 | { | | 2982 | { |
2981 | struct hdaudio_afg_softc *sc = opaque; | | 2983 | struct hdaudio_afg_softc *sc = opaque; |
2982 | struct hdaudio_assoc *as = sc->sc_assocs; | | 2984 | struct hdaudio_assoc *as = sc->sc_assocs; |
2983 | struct hdaudio_widget *w; | | 2985 | struct hdaudio_widget *w; |
2984 | uint32_t res = 0; | | 2986 | uint32_t res = 0; |
2985 | int i, j; | | 2987 | int i, j; |
2986 | | | 2988 | |
| | | 2989 | if (!device_is_active(sc->sc_dev)) |
| | | 2990 | goto resched; |
| | | 2991 | |
2987 | for (i = 0; i < sc->sc_nassocs; i++) | | 2992 | for (i = 0; i < sc->sc_nassocs; i++) |
2988 | for (j = 0; j < HDAUDIO_MAXPINS; j++) { | | 2993 | for (j = 0; j < HDAUDIO_MAXPINS; j++) { |
2989 | w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[j]); | | 2994 | w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[j]); |
2990 | if (w == NULL || w->w_enable == false) | | 2995 | if (w == NULL || w->w_enable == false) |
2991 | continue; | | 2996 | continue; |
2992 | if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX) | | 2997 | if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX) |
2993 | continue; | | 2998 | continue; |
2994 | if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) != | | 2999 | if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) != |
2995 | COP_DEVICE_HP_OUT) | | 3000 | COP_DEVICE_HP_OUT) |
2996 | continue; | | 3001 | continue; |
2997 | res |= hdaudio_command(sc->sc_codec, as[i].as_pins[j], | | 3002 | res |= hdaudio_command(sc->sc_codec, as[i].as_pins[j], |
2998 | CORB_GET_PIN_SENSE, 0) & | | 3003 | CORB_GET_PIN_SENSE, 0) & |
2999 | COP_GET_PIN_SENSE_PRESENSE_DETECT; | | 3004 | COP_GET_PIN_SENSE_PRESENSE_DETECT; |
| @@ -3020,26 +3025,27 @@ hdaudio_afg_hp_switch_handler(void *opaq | | | @@ -3020,26 +3025,27 @@ hdaudio_afg_hp_switch_handler(void *opaq |
3020 | case COP_DEVICE_AUX: | | 3025 | case COP_DEVICE_AUX: |
3021 | if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT) | | 3026 | if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT) |
3022 | w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE; | | 3027 | w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE; |
3023 | else | | 3028 | else |
3024 | w->w_pin.ctrl |= COP_PWC_OUT_ENABLE; | | 3029 | w->w_pin.ctrl |= COP_PWC_OUT_ENABLE; |
3025 | hdaudio_command(sc->sc_codec, w->w_nid, | | 3030 | hdaudio_command(sc->sc_codec, w->w_nid, |
3026 | CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl); | | 3031 | CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl); |
3027 | break; | | 3032 | break; |
3028 | default: | | 3033 | default: |
3029 | break; | | 3034 | break; |
3030 | } | | 3035 | } |
3031 | } | | 3036 | } |
3032 | | | 3037 | |
| | | 3038 | resched: |
3033 | callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD); | | 3039 | callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD); |
3034 | } | | 3040 | } |
3035 | | | 3041 | |
3036 | static void | | 3042 | static void |
3037 | hdaudio_afg_hp_switch_init(struct hdaudio_afg_softc *sc) | | 3043 | hdaudio_afg_hp_switch_init(struct hdaudio_afg_softc *sc) |
3038 | { | | 3044 | { |
3039 | struct hdaudio_assoc *as = sc->sc_assocs; | | 3045 | struct hdaudio_assoc *as = sc->sc_assocs; |
3040 | struct hdaudio_widget *w; | | 3046 | struct hdaudio_widget *w; |
3041 | bool enable = false; | | 3047 | bool enable = false; |
3042 | int i; | | 3048 | int i; |
3043 | | | 3049 | |
3044 | for (i = 0; i < sc->sc_nassocs; i++) { | | 3050 | for (i = 0; i < sc->sc_nassocs; i++) { |
3045 | if (as[i].as_hpredir < 0) | | 3051 | if (as[i].as_hpredir < 0) |
| @@ -3060,50 +3066,50 @@ hdaudio_afg_hp_switch_init(struct hdaudi | | | @@ -3060,50 +3066,50 @@ hdaudio_afg_hp_switch_init(struct hdaudi |
3060 | | | 3066 | |
3061 | if (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) | | 3067 | if (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) |
3062 | hdaudio_command(sc->sc_codec, w->w_nid, | | 3068 | hdaudio_command(sc->sc_codec, w->w_nid, |
3063 | CORB_SET_UNSOLICITED_RESPONSE, | | 3069 | CORB_SET_UNSOLICITED_RESPONSE, |
3064 | COP_SET_UNSOLICITED_RESPONSE_ENABLE | | | 3070 | COP_SET_UNSOLICITED_RESPONSE_ENABLE | |
3065 | HDAUDIO_UNSOLTAG_EVENT_HP); | | 3071 | HDAUDIO_UNSOLTAG_EVENT_HP); |
3066 | | | 3072 | |
3067 | hda_trace(sc, "jack detect supported on pin %02X [%s]\n", | | 3073 | hda_trace(sc, "jack detect supported on pin %02X [%s]\n", |
3068 | as[i].as_pins[15], | | 3074 | as[i].as_pins[15], |
3069 | (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) ? | | 3075 | (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) ? |
3070 | "unsol" : "poll"); | | 3076 | "unsol" : "poll"); |
3071 | } | | 3077 | } |
3072 | if (enable) { | | 3078 | if (enable) { |
| | | 3079 | sc->sc_jack_polling = true; |
3073 | hdaudio_afg_hp_switch_handler(sc); | | 3080 | hdaudio_afg_hp_switch_handler(sc); |
3074 | callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD); | | | |
3075 | } else | | 3081 | } else |
3076 | hda_trace(sc, "jack detect not enabled\n"); | | 3082 | hda_trace(sc, "jack detect not enabled\n"); |
3077 | } | | 3083 | } |
3078 | | | 3084 | |
3079 | static void | | 3085 | static void |
3080 | hdaudio_afg_attach(device_t parent, device_t self, void *opaque) | | 3086 | hdaudio_afg_attach(device_t parent, device_t self, void *opaque) |
3081 | { | | 3087 | { |
3082 | struct hdaudio_afg_softc *sc = device_private(self); | | 3088 | struct hdaudio_afg_softc *sc = device_private(self); |
3083 | audio_params_t defparams; | | 3089 | audio_params_t defparams; |
3084 | prop_dictionary_t args = opaque; | | 3090 | prop_dictionary_t args = opaque; |
3085 | uint64_t fgptr = 0; | | 3091 | uint64_t fgptr = 0; |
3086 | uint8_t nid = 0; | | 3092 | uint8_t nid = 0; |
3087 | int err; | | 3093 | int err; |
3088 | bool rv; | | 3094 | bool rv; |
3089 | | | 3095 | |
3090 | sc->sc_dev = self; | | 3096 | sc->sc_dev = self; |
3091 | | | 3097 | |
3092 | callout_init(&sc->sc_jack_callout, 0); | | 3098 | callout_init(&sc->sc_jack_callout, 0); |
3093 | callout_setfunc(&sc->sc_jack_callout, | | 3099 | callout_setfunc(&sc->sc_jack_callout, |
3094 | hdaudio_afg_hp_switch_handler, sc); | | 3100 | hdaudio_afg_hp_switch_handler, sc); |
3095 | | | 3101 | |
3096 | if (!pmf_device_register(self, NULL, hdaudio_afg_resume)) | | 3102 | if (!pmf_device_register(self, hdaudio_afg_suspend, hdaudio_afg_resume)) |
3097 | aprint_error_dev(self, "couldn't establish power handler\n"); | | 3103 | aprint_error_dev(self, "couldn't establish power handler\n"); |
3098 | | | 3104 | |
3099 | sc->sc_config = prop_dictionary_get(args, "pin-config"); | | 3105 | sc->sc_config = prop_dictionary_get(args, "pin-config"); |
3100 | if (sc->sc_config && prop_object_type(sc->sc_config) != PROP_TYPE_ARRAY) | | 3106 | if (sc->sc_config && prop_object_type(sc->sc_config) != PROP_TYPE_ARRAY) |
3101 | sc->sc_config = NULL; | | 3107 | sc->sc_config = NULL; |
3102 | hda_print1(sc, " (%s configuration)\n", sc->sc_config ? | | 3108 | hda_print1(sc, " (%s configuration)\n", sc->sc_config ? |
3103 | "custom" : "firmware"); | | 3109 | "custom" : "firmware"); |
3104 | | | 3110 | |
3105 | rv = prop_dictionary_get_uint64(args, "function-group", &fgptr); | | 3111 | rv = prop_dictionary_get_uint64(args, "function-group", &fgptr); |
3106 | if (rv == false || fgptr == 0) { | | 3112 | if (rv == false || fgptr == 0) { |
3107 | hda_error(sc, "missing function-group property\n"); | | 3113 | hda_error(sc, "missing function-group property\n"); |
3108 | return; | | 3114 | return; |
3109 | } | | 3115 | } |
| @@ -3231,43 +3237,56 @@ hdaudio_afg_detach(device_t self, int fl | | | @@ -3231,43 +3237,56 @@ hdaudio_afg_detach(device_t self, int fl |
3231 | return 0; | | 3237 | return 0; |
3232 | } | | 3238 | } |
3233 | | | 3239 | |
3234 | static void | | 3240 | static void |
3235 | hdaudio_afg_childdet(device_t self, device_t child) | | 3241 | hdaudio_afg_childdet(device_t self, device_t child) |
3236 | { | | 3242 | { |
3237 | struct hdaudio_afg_softc *sc = device_private(self); | | 3243 | struct hdaudio_afg_softc *sc = device_private(self); |
3238 | | | 3244 | |
3239 | if (child == sc->sc_audiodev.ad_audiodev) | | 3245 | if (child == sc->sc_audiodev.ad_audiodev) |
3240 | sc->sc_audiodev.ad_audiodev = NULL; | | 3246 | sc->sc_audiodev.ad_audiodev = NULL; |
3241 | } | | 3247 | } |
3242 | | | 3248 | |
3243 | static bool | | 3249 | static bool |
| | | 3250 | hdaudio_afg_suspend(device_t self PMF_FN_ARGS) |
| | | 3251 | { |
| | | 3252 | struct hdaudio_afg_softc *sc = device_private(self); |
| | | 3253 | |
| | | 3254 | callout_halt(&sc->sc_jack_callout, NULL); |
| | | 3255 | |
| | | 3256 | return true; |
| | | 3257 | } |
| | | 3258 | |
| | | 3259 | static bool |
3244 | hdaudio_afg_resume(device_t self PMF_FN_ARGS) | | 3260 | hdaudio_afg_resume(device_t self PMF_FN_ARGS) |
3245 | { | | 3261 | { |
3246 | struct hdaudio_afg_softc *sc = device_private(self); | | 3262 | struct hdaudio_afg_softc *sc = device_private(self); |
3247 | int nid; | | 3263 | int nid; |
3248 | | | 3264 | |
3249 | hdaudio_command(sc->sc_codec, sc->sc_nid, | | 3265 | hdaudio_command(sc->sc_codec, sc->sc_nid, |
3250 | CORB_SET_POWER_STATE, COP_POWER_STATE_D0); | | 3266 | CORB_SET_POWER_STATE, COP_POWER_STATE_D0); |
3251 | hda_delay(100); | | 3267 | hda_delay(100); |
3252 | for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) | | 3268 | for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) |
3253 | hdaudio_command(sc->sc_codec, nid, | | 3269 | hdaudio_command(sc->sc_codec, nid, |
3254 | CORB_SET_POWER_STATE, COP_POWER_STATE_D0); | | 3270 | CORB_SET_POWER_STATE, COP_POWER_STATE_D0); |
3255 | hda_delay(1000); | | 3271 | hda_delay(1000); |
3256 | | | 3272 | |
3257 | hdaudio_afg_commit(sc); | | 3273 | hdaudio_afg_commit(sc); |
3258 | hdaudio_afg_stream_connect(sc, AUMODE_PLAY); | | 3274 | hdaudio_afg_stream_connect(sc, AUMODE_PLAY); |
3259 | hdaudio_afg_stream_connect(sc, AUMODE_RECORD); | | 3275 | hdaudio_afg_stream_connect(sc, AUMODE_RECORD); |
3260 | | | 3276 | |
| | | 3277 | if (sc->sc_jack_polling) |
| | | 3278 | hdaudio_afg_hp_switch_handler(sc); |
| | | 3279 | |
3261 | return true; | | 3280 | return true; |
3262 | } | | 3281 | } |
3263 | | | 3282 | |
3264 | static int | | 3283 | static int |
3265 | hdaudio_afg_query_encoding(void *opaque, struct audio_encoding *ae) | | 3284 | hdaudio_afg_query_encoding(void *opaque, struct audio_encoding *ae) |
3266 | { | | 3285 | { |
3267 | struct hdaudio_audiodev *ad = opaque; | | 3286 | struct hdaudio_audiodev *ad = opaque; |
3268 | return auconv_query_encoding(ad->ad_encodings, ae); | | 3287 | return auconv_query_encoding(ad->ad_encodings, ae); |
3269 | } | | 3288 | } |
3270 | | | 3289 | |
3271 | static int | | 3290 | static int |
3272 | hdaudio_afg_set_params(void *opaque, int setmode, int usemode, | | 3291 | hdaudio_afg_set_params(void *opaque, int setmode, int usemode, |
3273 | audio_params_t *play, audio_params_t *rec, | | 3292 | audio_params_t *play, audio_params_t *rec, |