Skip to content

Commit

Permalink
[ALSA] hda: Add GPIO mute support to STAC9205
Browse files Browse the repository at this point in the history
Support added for detecting HP jack presence via GPIO on several laptop docks.

Signed-off-by: Matthew Ranostay <mranostay@embeddedalley.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
Matthew Ranostay authored and Jaroslav Kysela committed Jan 31, 2008
1 parent 0aaa22e commit 4fe5195
Showing 1 changed file with 45 additions and 17 deletions.
62 changes: 45 additions & 17 deletions sound/pci/hda/patch_sigmatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,13 @@ struct sigmatel_spec {
unsigned int alt_switch: 1;
unsigned int hp_detect: 1;

unsigned int gpio_mask, gpio_data;
/* gpio lines */
unsigned int gpio_mask;
unsigned int gpio_dir;
unsigned int gpio_data;
unsigned int gpio_mute;

/* analog loopback */
unsigned char aloopback_mask;
unsigned char aloopback_shift;

Expand Down Expand Up @@ -2803,21 +2809,21 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
*/

static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
unsigned int data)
unsigned int dir_mask, unsigned int data)
{
unsigned int gpiostate, gpiomask, gpiodir;

gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
AC_VERB_GET_GPIO_DATA, 0);
gpiostate = (gpiostate & ~mask) | (data & mask);
gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);

gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
AC_VERB_GET_GPIO_MASK, 0);
gpiomask |= mask;

gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
AC_VERB_GET_GPIO_DIRECTION, 0);
gpiodir |= mask;
gpiodir |= dir_mask;

/* Configure GPIOx as CMOS */
snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
Expand Down Expand Up @@ -2912,7 +2918,8 @@ static int stac92xx_init(struct hda_codec *codec)
stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
AC_PINCTL_IN_EN);

stac_gpio_set(codec, spec->gpio_mask, spec->gpio_data);
stac_gpio_set(codec, spec->gpio_mask,
spec->gpio_dir, spec->gpio_data);

return 0;
}
Expand Down Expand Up @@ -3002,10 +3009,14 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
int i, presence;

presence = 0;
if (spec->gpio_mute)
presence = !(snd_hda_codec_read(codec, codec->afg, 0,
AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);

for (i = 0; i < cfg->hp_outs; i++) {
presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
if (presence)
break;
presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
}

if (presence) {
Expand Down Expand Up @@ -3068,7 +3079,8 @@ static int stac92xx_resume(struct hda_codec *codec)

stac92xx_set_config_regs(codec);
snd_hda_sequence_write(codec, spec->init);
stac_gpio_set(codec, spec->gpio_mask, spec->gpio_data);
stac_gpio_set(codec, spec->gpio_mask,
spec->gpio_dir, spec->gpio_data);
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
/* invoke unsolicited event to reset the HP state */
Expand Down Expand Up @@ -3302,7 +3314,8 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
spec->dinput_mux = &stac92hd73xx_dmux;
/* GPIO0 High = Enable EAPD */
spec->gpio_mask = spec->gpio_data = 0x000001;
spec->gpio_mask = spec->gpio_dir = 0x1;
spec->gpio_data = 0x01;

spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
spec->pwr_nids = stac92hd73xx_pwr_nids;
Expand Down Expand Up @@ -3376,7 +3389,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
spec->aloopback_mask = 0x20;
spec->aloopback_shift = 0;

spec->gpio_mask = spec->gpio_data = 0x00000001; /* GPIO0 High = EAPD */
/* GPIO0 High = EAPD */
spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0x1;

spec->mux_nids = stac92hd71bxx_mux_nids;
spec->adc_nids = stac92hd71bxx_adc_nids;
Expand Down Expand Up @@ -3432,7 +3446,8 @@ static int patch_stac922x(struct hda_codec *codec)
stac922x_models,
stac922x_cfg_tbl);
if (spec->board_config == STAC_INTEL_MAC_V3) {
spec->gpio_mask = spec->gpio_data = 0x03;
spec->gpio_mask = spec->gpio_dir = 0x03;
spec->gpio_data = 0x03;
/* Intel Macs have all same PCI SSID, so we need to check
* codec SSID to distinguish the exact models
*/
Expand Down Expand Up @@ -3560,7 +3575,8 @@ static int patch_stac927x(struct hda_codec *codec)
case STAC_D965_3ST:
case STAC_D965_5ST:
/* GPIO0 High = Enable EAPD */
spec->gpio_mask = spec->gpio_data = 0x00000001;
spec->gpio_mask = spec->gpio_dir = 0x01;
spec->gpio_data = 0x01;
spec->num_dmics = 0;

spec->init = d965_core_init;
Expand All @@ -3574,7 +3590,8 @@ static int patch_stac927x(struct hda_codec *codec)
/* fallthru */
case STAC_DELL_3ST:
/* GPIO2 High = Enable EAPD */
spec->gpio_mask = spec->gpio_data = 0x00000004;
spec->gpio_mask = spec->gpio_dir = 0x04;
spec->gpio_data = 0x04;
spec->dmic_nids = stac927x_dmic_nids;
spec->num_dmics = STAC927X_NUM_DMICS;

Expand All @@ -3585,7 +3602,8 @@ static int patch_stac927x(struct hda_codec *codec)
break;
default:
/* GPIO0 High = Enable EAPD */
spec->gpio_mask = spec->gpio_data = 0x00000001;
spec->gpio_mask = spec->gpio_dir = 0x1;
spec->gpio_data = 0x01;
spec->num_dmics = 0;

spec->init = stac927x_core_init;
Expand Down Expand Up @@ -3680,15 +3698,25 @@ static int patch_stac9205(struct hda_codec *codec)
stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
stac92xx_set_config_reg(codec, 0x20, 0x1c410030);

spec->gpio_mask = 0x0000000b;
/* Enable unsol response for GPIO4/Dock HP connection */
snd_hda_codec_write(codec, codec->afg, 0,
AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
snd_hda_codec_write_cache(codec, codec->afg, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
(AC_USRSP_EN | STAC_HP_EVENT));

spec->gpio_dir = 0x0b;
spec->gpio_mask = 0x1b;
spec->gpio_mute = 0x10;
/* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
* GPIO3 High = DRM
* GPIO3 Low = DRM
*/
spec->gpio_data = 0x00000009;
spec->gpio_data = 0x01;
break;
default:
/* GPIO0 High = EAPD */
spec->gpio_mask = spec->gpio_data = 0x00000001;
spec->gpio_mask = spec->gpio_dir = 0x1;
spec->gpio_data = 0x01;
break;
}

Expand Down

0 comments on commit 4fe5195

Please sign in to comment.