Jacob Meuser writes:

> that (AC97_HOST_SWAPPED_CHANNELS) just tells the ac97 layer to
> swap the gains (change the left gain when the request was to
> change the right gain), not the channels.

HD Audio can actually do it in the driver; I just don't think
it's worth adding more mixer items.  The most I've seen so far
is 99, can anyone beat that?

If anyone's feeling too lazy to move and has azalia...

(from NetBSD)

Index: azalia.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/azalia.h,v
retrieving revision 1.14
diff -u -p -r1.14 azalia.h
--- azalia.h    10 Oct 2007 03:39:21 -0000      1.14
+++ azalia.h    21 Jan 2008 01:49:29 -0000
@@ -554,6 +554,7 @@ typedef struct {
 #define MI_TARGET_ADC          0x105
 #define MI_TARGET_VOLUME       0x106
 #define MI_TARGET_EAPD         0x107
+#define MI_TARGET_LRSWAP       0x108
 } mixer_item_t;
 
 #define VALID_WIDGET_NID(nid, codec)   (nid == (codec)->audiofunc || \
Index: azalia_codec.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/azalia_codec.c,v
retrieving revision 1.46
diff -u -p -r1.46 azalia_codec.c
--- azalia_codec.c      16 Dec 2007 18:48:19 -0000      1.46
+++ azalia_codec.c      21 Jan 2008 02:09:23 -0000
@@ -679,6 +679,29 @@ azalia_generic_mixer_init(codec_t *this)
                        this->nmixers++;
                }
 
+               if (w->widgetcap & COP_AWCAP_LRSWAP) {
+                       MIXER_REG_PROLOG;
+                       DPRINTF(("%s: lrswap %s\n", __func__, w->name));
+                       snprintf(d->label.name, sizeof(d->label.name),
+                           "%s.lrswap", w->name);
+                       d->type = AUDIO_MIXER_ENUM;
+                       if (w->type == COP_AWTYPE_PIN_COMPLEX)
+                               d->mixer_class = AZ_CLASS_OUTPUT;
+                       else if (w->type == COP_AWTYPE_AUDIO_INPUT)
+                               d->mixer_class = AZ_CLASS_RECORD;
+                       else
+                               d->mixer_class = AZ_CLASS_INPUT;
+                       m->target = MI_TARGET_LRSWAP;
+                       d->un.e.num_mem = 2;
+                       d->un.e.member[0].ord = 0;
+                       strlcpy(d->un.e.member[0].label.name, AudioNoff,
+                           MAX_AUDIO_DEV_LEN);
+                       d->un.e.member[1].ord = 1;
+                       strlcpy(d->un.e.member[1].label.name, AudioNon,
+                           MAX_AUDIO_DEV_LEN);
+                       this->nmixers++;
+               }
+
                /* volume knob */
                if (w->type == COP_AWTYPE_VOLUME_KNOB &&
                    w->d.volume.cap & COP_VKCAP_DELTA) {
@@ -1004,6 +1027,15 @@ azalia_generic_mixer_get(const codec_t *
                mc->un.ord = result & CORB_EAPD_EAPD ? 1 : 0;
        }
 
+       /* LR-Swap */
+       else if (target == MI_TARGET_LRSWAP) {
+               err = this->comresp(this, nid,
+                   CORB_GET_EAPD_BTL_ENABLE, 0, &result);
+               if (err)
+                       return err;
+               mc->un.ord = result & CORB_EAPD_LRSWAP ? 1 : 0;
+       }
+
        else {
                printf("%s: internal error in %s: target=%x\n",
                    XNAME(this), __func__, target);
@@ -1278,6 +1310,26 @@ azalia_generic_mixer_set(codec_t *this, 
                if (err)
                        return err;
        } 
+
+       /* LR-Swap */
+       else if (target == MI_TARGET_LRSWAP) {
+               if (mc->un.ord >= 2)
+                       return EINVAL;
+               err = this->comresp(this, nid,
+                   CORB_GET_EAPD_BTL_ENABLE, 0, &result);
+               if (err)
+                       return err;
+               result &= 0xff;
+               if (mc->un.ord == 0) {
+                       result &= ~CORB_EAPD_LRSWAP;
+               } else {
+                       result |= CORB_EAPD_LRSWAP;
+               }
+               err = this->comresp(this, nid,
+                   CORB_SET_EAPD_BTL_ENABLE, result, &result);
+               if (err)
+                       return err;
+       }
 
        else {
                printf("%s: internal error in %s: target=%x\n",

Reply via email to