Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci/hdaudio Implement and enable headphone sensing. ...



details:   https://anonhg.NetBSD.org/src/rev/19677cef541c
branches:  trunk
changeset: 747653:19677cef541c
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Sep 26 11:51:29 2009 +0000

description:
Implement and enable headphone sensing. Slightly different from the FreeBSD
implementation in that this code does not care if the headphones are seq=15.
Instead, for each association, find any HP pins with jack sense capabilities
and if at least one has the Presense Detect bit set, enable output on all
PWCs of type HP_OUT and disable output on all PWCs of type LINE_OUT, SPEAKER,
or AUX. Do the reverse if no HP pins have the Presense Detect bit set.

diffstat:

 sys/dev/pci/hdaudio/hdaudio_afg.c |  140 +++++++++++++------------------------
 1 files changed, 50 insertions(+), 90 deletions(-)

diffs (183 lines):

diff -r 703d983820bb -r 19677cef541c sys/dev/pci/hdaudio/hdaudio_afg.c
--- a/sys/dev/pci/hdaudio/hdaudio_afg.c Sat Sep 26 11:45:41 2009 +0000
+++ b/sys/dev/pci/hdaudio/hdaudio_afg.c Sat Sep 26 11:51:29 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio_afg.c,v 1.12 2009/09/25 19:49:31 sborrill Exp $ */
+/* $NetBSD: hdaudio_afg.c,v 1.13 2009/09/26 11:51:29 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2009 Precedence Technologies Ltd <support%precedence.co.uk@localhost>
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.12 2009/09/25 19:49:31 sborrill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.13 2009/09/26 11:51:29 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -106,6 +106,8 @@
 
 #define        HDAUDIO_UNSOLTAG_EVENT_HP       0x00
 
+#define        HDAUDIO_HP_SENSE_PERIOD         (hz / 2)
+
 static const char *hdaudio_afg_mixer_names[] = HDAUDIO_DEVICE_NAMES;
 
 static const char *hdaudio_afg_port_connectivity[] = {
@@ -2932,96 +2934,56 @@
        struct hdaudio_afg_softc *sc = opaque;
        struct hdaudio_assoc *as = sc->sc_assocs;
        struct hdaudio_widget *w;
-       struct hdaudio_control *ctl;
-       uint32_t res, v;
+       uint32_t res = 0;
        int i, j;
 
-       for (i = 0; i < sc->sc_nassocs; i++) {
-               if (as[i].as_hpredir < 0)
-                       continue;
-               w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[15]);
-               if (w == NULL || w->w_enable == false)
-                       continue;
-               if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
-                       continue;
-
-               res = hdaudio_command(sc->sc_codec, as[i].as_pins[15],
-                   CORB_GET_PIN_SENSE, 0);
-               res = (res & COP_GET_PIN_SENSE_PRESENSE_DETECT) >> 31;
-
-               /* mute/unmute headphone pin */
-               ctl = hdaudio_afg_control_amp_get(sc, as[i].as_pins[15],
-                   HDAUDIO_PINDIR_IN, -1, 1);
-               if (ctl && ctl->ctl_mute) {
-                       /* pin has muter, so use it */
-                       v = (res != 0) ? 0 : 1;
-                       if (v != ctl->ctl_forcemute) {
-                               ctl->ctl_forcemute = v;
-                               hdaudio_afg_control_amp_set(ctl,
-                                   HDAUDIO_AMP_MUTE_DEFAULT,
-                                   HDAUDIO_AMP_VOL_DEFAULT,
-                                   HDAUDIO_AMP_VOL_DEFAULT);
-                       }
-               } else {
-                       /* no muter, so disable pin output */
-                       w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[15]);
-                       if (w && w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX) {
-                               if (res)
-                                       v = w->w_pin.ctrl | COP_PWC_OUT_ENABLE;
+       for (i = 0; i < sc->sc_nassocs; i++)
+               for (j = 0; j < HDAUDIO_MAXPINS; j++) {
+                       w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[j]);
+                       if (w == NULL || w->w_enable == false)
+                               continue;
+                       if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
+                               continue;
+                       if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) !=
+                           COP_DEVICE_HP_OUT)
+                               continue;
+                       res |= hdaudio_command(sc->sc_codec, as[i].as_pins[j],
+                           CORB_GET_PIN_SENSE, 0) &
+                           COP_GET_PIN_SENSE_PRESENSE_DETECT;
+               }
+
+       for (i = 0; i < sc->sc_nassocs; i++)
+               for (j = 0; j < HDAUDIO_MAXPINS; j++) {
+                       w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[j]);
+                       if (w == NULL || w->w_enable == false)
+                               continue;
+                       if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
+                               continue;
+                       switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
+                       case COP_DEVICE_HP_OUT:
+                               if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
+                                       w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
                                else
-                                       v = w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
-                               if (v != w->w_pin.ctrl) {
-                                       w->w_pin.ctrl = v;
-                                       hdaudio_command(sc->sc_codec, w->w_nid,
-                                           CORB_SET_PIN_WIDGET_CONTROL, v);
-                               }
+                                       w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
+                               hdaudio_command(sc->sc_codec, w->w_nid,
+                                   CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
+                               break;
+                       case COP_DEVICE_LINE_OUT:
+                       case COP_DEVICE_SPEAKER:
+                       case COP_DEVICE_AUX:
+                               if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
+                                       w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
+                               else
+                                       w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
+                               hdaudio_command(sc->sc_codec, w->w_nid,
+                                   CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
+                               break;
+                       default:
+                               break;
                        }
                }
-               /* mute/unmute other pins */
-               for (j = 0; j < HDAUDIO_MAXPINS - 1; j++) {
-                       int type = -1;
-                       if (as[i].as_pins[j] <= 0)
-                               continue;
-                       w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[j]);
-                       if (w && w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
-                               type = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
-#if notyet
-                       ctl = hdaudio_afg_control_amp_get(sc,
-                           as[i].as_pins[j], HDAUDIO_PINDIR_IN, -1, 1);
-                       if (ctl && ctl->ctl_mute) {
-                               /* pin has muter, so use it */
-                               if (type == COP_DEVICE_HP_OUT)
-                                       v = (res != 0) ? 0 : 1;
-                               else
-                                       v = (res != 0) ? 1 : 0;
-                               if (v == ctl->ctl_forcemute)
-                                       continue;
-                               ctl->ctl_forcemute = v;
-                               hdaudio_afg_control_amp_set(ctl,
-                                   HDAUDIO_AMP_MUTE_DEFAULT,
-                                   HDAUDIO_AMP_VOL_DEFAULT,
-                                   HDAUDIO_AMP_VOL_DEFAULT);
-                               continue;
-                       }
-#endif
-                       /* no muter, so disable pin output */
-                       w = hdaudio_afg_widget_lookup(sc, as[i].as_pins[j]);
-                       if (w && w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX) {
-                               int rres = res;
-                               if (type == COP_DEVICE_HP_OUT)
-                                       rres = !rres;
-                               if (rres)
-                                       v = w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
-                               else
-                                       v = w->w_pin.ctrl | COP_PWC_OUT_ENABLE;
-                               if (v != w->w_pin.ctrl) {
-                                       w->w_pin.ctrl = v;
-                                       hdaudio_command(sc->sc_codec, w->w_nid,
-                                           CORB_SET_PIN_WIDGET_CONTROL, v);
-                               }
-                       }
-               }
-       }
+
+       callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD);
 }
 
 static void
@@ -3060,12 +3022,10 @@
                    (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) ?
                    "unsol" : "poll");
        }
-#if notyet
        if (enable) {
                hdaudio_afg_hp_switch_handler(sc);
-               callout_schedule(&sc->sc_jack_callout, hz);
+               callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD);
        } else
-#endif
                hda_trace(sc, "jack detect not enabled\n");
 }
 



Home | Main Index | Thread Index | Old Index