support for EAPD, Balanced I/O, and LR-Swap
This commit is contained in:
parent
9d93195858
commit
21623cc733
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: azalia.h,v 1.13 2006/06/25 13:41:58 kent Exp $ */
|
||||
/* $NetBSD: azalia.h,v 1.14 2006/07/21 14:40:12 kent Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||
|
@ -356,6 +356,9 @@
|
|||
#define CORB_PS_RIGHT 0x1
|
||||
#define CORB_GET_EAPD_BTL_ENABLE 0xf0c
|
||||
#define CORB_SET_EAPD_BTL_ENABLE 0x70c
|
||||
#define CORB_EAPD_BTL 0x01
|
||||
#define CORB_EAPD_EAPD 0x02
|
||||
#define CORB_EAPD_LRSWAP 0x04
|
||||
#define CORB_GET_GPI_DATA 0xf10
|
||||
#define CORB_SET_GPI_DATA 0x710
|
||||
#define CORB_GET_GPI_WAKE_ENABLE_MASK 0xf11
|
||||
|
@ -523,6 +526,9 @@ typedef struct {
|
|||
#define MI_TARGET_VOLUME 0x106
|
||||
#define MI_TARGET_SPDIF 0x107
|
||||
#define MI_TARGET_SPDIF_CC 0x108
|
||||
#define MI_TARGET_EAPD 0x109
|
||||
#define MI_TARGET_BALANCE 0x10a
|
||||
#define MI_TARGET_LRSWAP 0x10b
|
||||
} mixer_item_t;
|
||||
|
||||
#define VALID_WIDGET_NID(nid, codec) (nid == (codec)->audiofunc || \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: azalia_codec.c,v 1.22 2006/07/19 02:40:18 kent Exp $ */
|
||||
/* $NetBSD: azalia_codec.c,v 1.23 2006/07/21 14:40:12 kent Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: azalia_codec.c,v 1.22 2006/07/19 02:40:18 kent Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: azalia_codec.c,v 1.23 2006/07/21 14:40:12 kent Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
@ -694,6 +694,72 @@ generic_mixer_init(codec_t *this)
|
|||
this->nmixers++;
|
||||
}
|
||||
|
||||
if (w->type == COP_AWTYPE_PIN_COMPLEX &&
|
||||
w->d.pin.cap & COP_PINCAP_EAPD) {
|
||||
MIXER_REG_PROLOG;
|
||||
DPRINTF(("%s: eapd %s\n", __func__, w->name));
|
||||
snprintf(d->label.name, sizeof(d->label.name),
|
||||
"%s.eapd", w->name);
|
||||
d->type = AUDIO_MIXER_ENUM;
|
||||
d->mixer_class = AZ_CLASS_OUTPUT;
|
||||
m->target = MI_TARGET_EAPD;
|
||||
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++;
|
||||
}
|
||||
|
||||
if (w->type == COP_AWTYPE_PIN_COMPLEX &&
|
||||
w->d.pin.cap & COP_PINCAP_BALANCE) {
|
||||
MIXER_REG_PROLOG;
|
||||
DPRINTF(("%s: balance %s\n", __func__, w->name));
|
||||
snprintf(d->label.name, sizeof(d->label.name),
|
||||
"%s.balance", 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_BALANCE;
|
||||
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++;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -1048,6 +1114,33 @@ generic_mixer_get(const codec_t *this, nid_t nid, int target, mixer_ctrl_t *mc)
|
|||
mc->un.value.level[0] = CORB_DCC_CC(result);
|
||||
}
|
||||
|
||||
/* EAPD */
|
||||
else if (target == MI_TARGET_EAPD) {
|
||||
err = this->comresp(this, nid,
|
||||
CORB_GET_EAPD_BTL_ENABLE, 0, &result);
|
||||
if (err)
|
||||
return err;
|
||||
mc->un.ord = result & CORB_EAPD_EAPD ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Balanced I/O */
|
||||
else if (target == MI_TARGET_BALANCE) {
|
||||
err = this->comresp(this, nid,
|
||||
CORB_GET_EAPD_BTL_ENABLE, 0, &result);
|
||||
if (err)
|
||||
return err;
|
||||
mc->un.ord = result & CORB_EAPD_BTL ? 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 {
|
||||
aprint_error("%s: internal error in %s: target=%x\n",
|
||||
XNAME(this), __func__, target);
|
||||
|
@ -1324,6 +1417,66 @@ generic_mixer_set(codec_t *this, nid_t nid, int target, const mixer_ctrl_t *mc)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* EAPD */
|
||||
else if (target == MI_TARGET_EAPD) {
|
||||
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_EAPD;
|
||||
} else {
|
||||
result |= CORB_EAPD_EAPD;
|
||||
}
|
||||
err = this->comresp(this, nid,
|
||||
CORB_SET_EAPD_BTL_ENABLE, result, &result);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Balanced I/O */
|
||||
else if (target == MI_TARGET_BALANCE) {
|
||||
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_BTL;
|
||||
} else {
|
||||
result |= CORB_EAPD_BTL;
|
||||
}
|
||||
err = this->comresp(this, nid,
|
||||
CORB_SET_EAPD_BTL_ENABLE, result, &result);
|
||||
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 {
|
||||
aprint_error("%s: internal error in %s: target=%x\n",
|
||||
XNAME(this), __func__, target);
|
||||
|
|
Loading…
Reference in New Issue