Subject: Re: kern/34071: azalia device driver doesn't support pin sensing
To: None <gnats-bugs@netbsd.org>
From: Berndt Josef Wulf <wulf@ping.net.au>
List: netbsd-bugs
Date: 02/07/2007 12:57:45
On Tuesday 06 February 2007 01:10, TAMURA Kent wrote:
> The following reply was made to PR kern/34071; it has been noted by GNATS.
>
> From: "TAMURA Kent" <kent@NetBSD.org>
> To: "Berndt Josef Wulf" <wulf@ping.net.au>
> Cc: gnats-bugs@netbsd.org
> Subject: Re: kern/34071: azalia device driver doesn't support pin sensing
> Date: Mon, 5 Feb 2007 23:35:51 +0900
>
> Could you test the following patch and tell me the name of
> the machine or mainboard?
>
> ----------------------------------------------------------------
> Index: azalia_codec.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/pci/azalia_codec.c,v
> retrieving revision 1.28
> diff -u -r1.28 azalia_codec.c
> --- azalia_codec.c 6 Jan 2007 18:35:35 -0000 1.28
> +++ azalia_codec.c 5 Feb 2007 14:32:42 -0000
> @@ -123,6 +123,9 @@
> static int stac9221_init_dacgroup(codec_t *);
> static int stac9221_mixer_init(codec_t *);
> static int stac9220_mixer_init(codec_t *);
> +static int stac9220_set_port(codec_t *, mixer_ctrl_t *);
> +static int stac9220_get_port(codec_t *, mixer_ctrl_t *);
> +static int stac9220_unsol_event(codec_t *, int);
>
>
> int
> @@ -190,6 +193,9 @@
> case 0x83847690:
> this->name = "Sigmatel STAC9220";
> this->mixer_init = stac9220_mixer_init;
> + this->set_port = stac9220_set_port;
> + this->unsol_event = stac9220_unsol_event;
> + extra_size = 1;
> break;
> }
> if (extra_size > 0) {
> @@ -2606,6 +2612,7 @@
> stac9220_mixer_init(codec_t *this)
> {
> mixer_ctrl_t mc;
> + uint32_t value;
>
> this->nmixers = sizeof(stac9220_mixer_items) / sizeof(mixer_item_t);
> this->mixers = malloc(sizeof(mixer_item_t) * this->nmixers,
> @@ -2633,7 +2640,104 @@
> mc.un.value.level[1] = mc.un.value.level[0];
> generic_mixer_set(this, 0x0c, MI_TARGET_OUTAMP, &mc);
>
> +#define STAC9220_XXX_ID 0x01cd1028
> +#define STAC9220_EVENT_HP 0
> +#define STAC9220_EXTRA_MASTER 0
> +#define STAC9220_NID_MASTER 0x0b
> +#define STAC9220_NID_HP 0x0d
> + if (this->subid == STAC9220_XXX_ID) {
> + /* setup a unsolicited event for the headphones */
> + this->comresp(this, STAC9220_NID_HP, CORB_SET_UNSOLICITED_RESPONSE,
> + CORB_UNSOL_ENABLE | STAC9220_EVENT_HP, NULL);
> + this->extra[STAC9220_EXTRA_MASTER] = 0; /* unmute */
> + /* If the headphone presents, mute the internal speaker */
> + this->comresp(this, STAC9220_NID_HP, CORB_GET_PIN_SENSE, 0, &value);
> + mc.un.ord = value & CORB_PS_PRESENSE ? 1 : 0;
> + generic_mixer_set(this, STAC9220_NID_MASTER, MI_TARGET_OUTAMP, &mc);
> + this->get_port = stac9220_get_port;
> + }
> + return 0;
> +}
> +
> +static int
> +stac9220_set_port(codec_t *this, mixer_ctrl_t *mc)
> +{
> + const mixer_item_t *m;
> + uint32_t value;
> + int err;
> +
> + if (mc->dev >= this->nmixers)
> + return ENXIO;
> + m = &this->mixers[mc->dev];
> + if (mc->type != m->devinfo.type)
> + return EINVAL;
> + if (mc->type == AUDIO_MIXER_CLASS)
> + return 0;
> + if (this->subid == STAC9220_XXX_ID && m->nid == STAC9220_NID_MASTER &&
> + m->target == MI_TARGET_OUTAMP && mc->type == AUDIO_MIXER_ENUM) {
> + if (mc->un.ord != 0 && mc->un.ord != 1)
> + return EINVAL;
> + this->extra[STAC9220_EXTRA_MASTER] = mc->un.ord;
> + err = this->comresp(this, STAC9220_NID_HP,
> + CORB_GET_PIN_SENSE, 0, &value);
> + if (err)
> + return err;
> + if (!(value & CORB_PS_PRESENSE)) {
> + return generic_mixer_set(this, m->nid, m->target, mc);
> + }
> + return 0;
> + }
> + return generic_mixer_set(this, m->nid, m->target, mc);
> +}
> +
> +static int
> +stac9220_get_port(codec_t *this, mixer_ctrl_t *mc)
> +{
> + const mixer_item_t *m;
> +
> + if (mc->dev >= this->nmixers)
> + return ENXIO;
> + m = &this->mixers[mc->dev];
> + mc->type = m->devinfo.type;
> + if (mc->type == AUDIO_MIXER_CLASS)
> + return 0;
> + if (this->subid == STAC9220_XXX_ID && m->nid == STAC9220_NID_MASTER &&
> + m->target == MI_TARGET_OUTAMP && mc->type == AUDIO_MIXER_ENUM) {
> + mc->un.ord = this->extra[STAC9220_EXTRA_MASTER];
> + return 0;
> + }
> + return generic_mixer_get(this, m->nid, m->target, mc);
> +}
> +
> +static int
> +stac9220_unsol_event(codec_t *this, int tag)
> +{
> + int err;
> + uint32_t value;
> + mixer_ctrl_t mc;
> +
> + switch (tag) {
> + case STAC9220_EVENT_HP:
> + err = this->comresp(this, STAC9220_NID_HP,
> + CORB_GET_PIN_SENSE, 0, &value);
> + if (err)
> + break;
> + mc.dev = -1;
> + mc.type = AUDIO_MIXER_ENUM;
> + if (value & CORB_PS_PRESENSE) {
> + DPRINTF(("%s: headphone has been inserted.\n", __func__));
> + mc.un.ord = 1; /* mute */
> + generic_mixer_set(this, STAC9220_NID_MASTER,
> + MI_TARGET_OUTAMP, &mc);
> + } else {
> + DPRINTF(("%s: headphone has been pulled out.\n", __func__));
> + mc.un.ord = this->extra[ALC260_EXTRA_MASTER];
> + generic_mixer_set(this, STAC9220_NID_MASTER,
> + MI_TARGET_OUTAMP, &mc);
> + }
> + break;
> + default:
> + printf("%s: unknown tag: %d\n", __func__, tag);
> + }
> return 0;
> }
> ----------------------------------------------------------------
> --
> TAMURA Kent <kent_2007 at hauN.org> <kent at NetBSD.org>
G'day,
Thanks for this patch. I've applied it and installed new kernel.
Unfortunately, it appears that no event is registered when plugging in the
headphone set into line socket.
System information:
Hardware - Dell Inspiron 9400
Kernel -
NetBSD barossa 4.99.9 NetBSD 4.99.9 (BAROSSA) #2: Tue Feb 6 08:19:47 CST 2007
wulf@barossa:/sys/arch/i386/compile/BAROSSA i386
The azalia device is detected as:
azalia0 at pci0 dev 27 function 0: Generic High Definition Audio Controller
azalia0: interrupting at ioapic0 pin 21 (irq 11)
azalia0: host: Intel 82801GB/GR High Definition Audio Controller (rev. 1)
azalia0: host: High Definition Audio rev. 1.0
[...]
azalia0: codec[0]: Sigmatel STAC9220 (rev. 34.1)
azalia0: codec[0]: High Definition Audio rev. 1.0
azalia0: playback: max channels=2, encodings=1<PCM>
azalia0: playback: PCM
formats=e07e0<24bit,20bit,16bit,192kHz,176.4kHz,96kHz,88.
2kHz,48kHz,44.1kHz>
azalia0: recording: max channels=2, encodings=1<PCM>
azalia0: recording: PCM
formats=e07e0<24bit,20bit,16bit,192kHz,176.4kHz,96kHz,88
.2kHz,48kHz,44.1kHz>
azalia0: codec[1]: 0x14f1/0x2bfa (rev. 0.0)
azalia0: codec[1]: High Definition Audio rev. 0.9
azalia0: codec[1]: No support for modem function groups
azalia0: codec[1] has no audio function groups
audio0 at azalia0: full duplex, independent
cheerio Berndt