summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c151
1 files changed, 83 insertions, 68 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index dbffb5b5c69d..8c416bb18a57 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -568,6 +568,11 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = {
0x0f, 0x10, 0x11, 0x1f, 0x20,
};
+static hda_nid_t stac92hd88xxx_pin_nids[10] = {
+ 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0f, 0x11, 0x1f, 0x20,
+};
+
#define STAC92HD71BXX_NUM_PINS 13
static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -2873,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
conn_len = snd_hda_get_connections(codec, nid, conn,
HDA_MAX_CONNECTIONS);
+ /* 92HD88: trace back up the link of nids to find the DAC */
+ while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
+ != AC_WID_AUD_OUT)) {
+ nid = conn[0];
+ conn_len = snd_hda_get_connections(codec, nid, conn,
+ HDA_MAX_CONNECTIONS);
+ }
for (j = 0; j < conn_len; j++) {
wcaps = get_wcaps(codec, conn[j]);
wtype = get_wcaps_type(wcaps);
@@ -4351,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec)
if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
stac_issue_unsol_event(codec, nid);
}
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ /* sync mute LED */
+ if (spec->gpio_led && codec->patch_ops.check_power_status)
+ codec->patch_ops.check_power_status(codec, 0x01);
+#endif
if (spec->dac_list)
stac92xx_power_down(codec);
return 0;
@@ -4742,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id);
static void set_hp_led_gpio(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
- switch (codec->vendor_id) {
- case 0x111d7608:
- /* GPIO 0 */
- spec->gpio_led = 0x01;
- break;
- case 0x111d7600:
- case 0x111d7601:
- case 0x111d7602:
- case 0x111d7603:
- /* GPIO 3 */
- spec->gpio_led = 0x08;
- break;
- }
+ unsigned int gpio;
+
+ gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
+ gpio &= AC_GPIO_IO_COUNT;
+ if (gpio > 3)
+ spec->gpio_led = 0x08; /* GPIO 3 */
+ else
+ spec->gpio_led = 0x01; /* GPIO 0 */
}
/*
@@ -4777,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec)
* Need more information on whether it is true across the entire series.
* -- kunal
*/
-static int find_mute_led_gpio(struct hda_codec *codec)
+static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
{
struct sigmatel_spec *spec = codec->spec;
const struct dmi_device *dev = NULL;
@@ -4804,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec)
*/
if (!hp_blike_system(codec->subsystem_id)) {
set_hp_led_gpio(codec);
- spec->gpio_led_polarity = 1;
+ spec->gpio_led_polarity = default_polarity;
return 1;
}
}
@@ -4902,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec)
stac_issue_unsol_event(codec,
spec->autocfg.line_out_pins[0]);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ /* sync mute LED */
+ if (spec->gpio_led && codec->patch_ops.check_power_status)
+ codec->patch_ops.check_power_status(codec, 0x01);
+#endif
return 0;
}
@@ -4921,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
hda_nid_t nid)
{
struct sigmatel_spec *spec = codec->spec;
+ int i, muted = 1;
- if (nid == 0x10) {
- if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
- HDA_AMP_MUTE)
- spec->gpio_data &= ~spec->gpio_led; /* orange */
- else
- spec->gpio_data |= spec->gpio_led; /* white */
-
- if (!spec->gpio_led_polarity) {
- /* LED state is inverted on these systems */
- spec->gpio_data ^= spec->gpio_led;
+ for (i = 0; i < spec->multiout.num_dacs; i++) {
+ nid = spec->multiout.dac_nids[i];
+ if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
+ HDA_AMP_MUTE)) {
+ muted = 0; /* something heard */
+ break;
}
-
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir,
- spec->gpio_data);
}
+ if (muted)
+ spec->gpio_data &= ~spec->gpio_led; /* orange */
+ else
+ spec->gpio_data |= spec->gpio_led; /* white */
- return 0;
-}
-
-static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec,
- hda_nid_t nid)
-{
- struct sigmatel_spec *spec = codec->spec;
+ if (!spec->gpio_led_polarity) {
+ /* LED state is inverted on these systems */
+ spec->gpio_data ^= spec->gpio_led;
+ }
- if (nid != 0x13)
- return 0;
- if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE)
- spec->gpio_data |= spec->gpio_led; /* mute LED on */
- else
- spec->gpio_data &= ~spec->gpio_led; /* mute LED off */
stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
-
return 0;
}
-
#endif
static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
@@ -5279,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
int err;
int num_dacs;
- hda_nid_t nid;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
@@ -5318,7 +5321,18 @@ again:
stac92hd83xxx_brd_tbl[spec->board_config]);
switch (codec->vendor_id) {
+ case 0x111d7666:
+ case 0x111d7667:
+ case 0x111d7668:
+ case 0x111d7669:
+ spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
+ spec->pin_nids = stac92hd88xxx_pin_nids;
+ spec->mono_nid = 0;
+ spec->digbeep_nid = 0;
+ spec->num_pwrs = 0;
+ break;
case 0x111d7604:
+ case 0x111d76d4:
case 0x111d7605:
case 0x111d76d5:
if (spec->board_config == STAC_92HD83XXX_PWR_REF)
@@ -5329,8 +5343,10 @@ again:
codec->patch_ops = stac92xx_patch_ops;
- if (spec->board_config == STAC_92HD83XXX_HP)
- spec->gpio_led = 0x01;
+ if (find_mute_led_gpio(codec, 0))
+ snd_printd("mute LED gpio %d polarity %d\n",
+ spec->gpio_led,
+ spec->gpio_led_polarity);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
@@ -5339,7 +5355,7 @@ again:
spec->gpio_data |= spec->gpio_led;
/* register check_power_status callback. */
codec->patch_ops.check_power_status =
- idt92hd83xxx_hp_check_power_status;
+ stac92xx_hp_check_power_status;
}
#endif
@@ -5359,24 +5375,21 @@ again:
return err;
}
- switch (spec->board_config) {
- case STAC_DELL_S14:
- nid = 0xf;
- break;
- default:
- nid = 0xe;
- break;
- }
-
- num_dacs = snd_hda_get_connections(codec, nid,
+ /* docking output support */
+ num_dacs = snd_hda_get_connections(codec, 0xF,
conn, STAC92HD83_DAC_COUNT + 1) - 1;
- if (num_dacs < 0)
- num_dacs = STAC92HD83_DAC_COUNT;
-
- /* set port X to select the last DAC
- */
- snd_hda_codec_write_cache(codec, nid, 0,
+ /* skip non-DAC connections */
+ while (num_dacs >= 0 &&
+ (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
+ != AC_WID_AUD_OUT))
+ num_dacs--;
+ /* set port E and F to select the last DAC */
+ if (num_dacs >= 0) {
+ snd_hda_codec_write_cache(codec, 0xE, 0,
+ AC_VERB_SET_CONNECT_SEL, num_dacs);
+ snd_hda_codec_write_cache(codec, 0xF, 0,
AC_VERB_SET_CONNECT_SEL, num_dacs);
+ }
codec->proc_widget_hook = stac92hd_proc_hook;
@@ -5657,7 +5670,6 @@ again:
*/
spec->num_smuxes = 1;
spec->num_dmuxes = 1;
- spec->gpio_led = 0x01;
/* fallthrough */
case STAC_HP_DV5:
snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
@@ -5672,8 +5684,6 @@ again:
spec->num_dmics = 1;
spec->num_dmuxes = 1;
spec->num_smuxes = 1;
- /* orange/white mute led on GPIO3, orange=0, white=1 */
- spec->gpio_led = 0x08;
break;
}
@@ -5695,7 +5705,7 @@ again:
}
}
- if (find_mute_led_gpio(codec))
+ if (find_mute_led_gpio(codec, 1))
snd_printd("mute LED gpio %d polarity %d\n",
spec->gpio_led,
spec->gpio_led_polarity);
@@ -6236,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
{ .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
{ .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
{ .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
{ .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
{ .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
{ .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },