diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 151 |
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] = { | |||
568 | 0x0f, 0x10, 0x11, 0x1f, 0x20, | 568 | 0x0f, 0x10, 0x11, 0x1f, 0x20, |
569 | }; | 569 | }; |
570 | 570 | ||
571 | static hda_nid_t stac92hd88xxx_pin_nids[10] = { | ||
572 | 0x0a, 0x0b, 0x0c, 0x0d, | ||
573 | 0x0f, 0x11, 0x1f, 0x20, | ||
574 | }; | ||
575 | |||
571 | #define STAC92HD71BXX_NUM_PINS 13 | 576 | #define STAC92HD71BXX_NUM_PINS 13 |
572 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | 577 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { |
573 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | 578 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, |
@@ -2873,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
2873 | 2878 | ||
2874 | conn_len = snd_hda_get_connections(codec, nid, conn, | 2879 | conn_len = snd_hda_get_connections(codec, nid, conn, |
2875 | HDA_MAX_CONNECTIONS); | 2880 | HDA_MAX_CONNECTIONS); |
2881 | /* 92HD88: trace back up the link of nids to find the DAC */ | ||
2882 | while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0])) | ||
2883 | != AC_WID_AUD_OUT)) { | ||
2884 | nid = conn[0]; | ||
2885 | conn_len = snd_hda_get_connections(codec, nid, conn, | ||
2886 | HDA_MAX_CONNECTIONS); | ||
2887 | } | ||
2876 | for (j = 0; j < conn_len; j++) { | 2888 | for (j = 0; j < conn_len; j++) { |
2877 | wcaps = get_wcaps(codec, conn[j]); | 2889 | wcaps = get_wcaps(codec, conn[j]); |
2878 | wtype = get_wcaps_type(wcaps); | 2890 | wtype = get_wcaps_type(wcaps); |
@@ -4351,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4351 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) | 4363 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) |
4352 | stac_issue_unsol_event(codec, nid); | 4364 | stac_issue_unsol_event(codec, nid); |
4353 | } | 4365 | } |
4366 | |||
4367 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4368 | /* sync mute LED */ | ||
4369 | if (spec->gpio_led && codec->patch_ops.check_power_status) | ||
4370 | codec->patch_ops.check_power_status(codec, 0x01); | ||
4371 | #endif | ||
4354 | if (spec->dac_list) | 4372 | if (spec->dac_list) |
4355 | stac92xx_power_down(codec); | 4373 | stac92xx_power_down(codec); |
4356 | return 0; | 4374 | return 0; |
@@ -4742,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id); | |||
4742 | static void set_hp_led_gpio(struct hda_codec *codec) | 4760 | static void set_hp_led_gpio(struct hda_codec *codec) |
4743 | { | 4761 | { |
4744 | struct sigmatel_spec *spec = codec->spec; | 4762 | struct sigmatel_spec *spec = codec->spec; |
4745 | switch (codec->vendor_id) { | 4763 | unsigned int gpio; |
4746 | case 0x111d7608: | 4764 | |
4747 | /* GPIO 0 */ | 4765 | gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); |
4748 | spec->gpio_led = 0x01; | 4766 | gpio &= AC_GPIO_IO_COUNT; |
4749 | break; | 4767 | if (gpio > 3) |
4750 | case 0x111d7600: | 4768 | spec->gpio_led = 0x08; /* GPIO 3 */ |
4751 | case 0x111d7601: | 4769 | else |
4752 | case 0x111d7602: | 4770 | spec->gpio_led = 0x01; /* GPIO 0 */ |
4753 | case 0x111d7603: | ||
4754 | /* GPIO 3 */ | ||
4755 | spec->gpio_led = 0x08; | ||
4756 | break; | ||
4757 | } | ||
4758 | } | 4771 | } |
4759 | 4772 | ||
4760 | /* | 4773 | /* |
@@ -4777,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec) | |||
4777 | * Need more information on whether it is true across the entire series. | 4790 | * Need more information on whether it is true across the entire series. |
4778 | * -- kunal | 4791 | * -- kunal |
4779 | */ | 4792 | */ |
4780 | static int find_mute_led_gpio(struct hda_codec *codec) | 4793 | static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) |
4781 | { | 4794 | { |
4782 | struct sigmatel_spec *spec = codec->spec; | 4795 | struct sigmatel_spec *spec = codec->spec; |
4783 | const struct dmi_device *dev = NULL; | 4796 | const struct dmi_device *dev = NULL; |
@@ -4804,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec) | |||
4804 | */ | 4817 | */ |
4805 | if (!hp_blike_system(codec->subsystem_id)) { | 4818 | if (!hp_blike_system(codec->subsystem_id)) { |
4806 | set_hp_led_gpio(codec); | 4819 | set_hp_led_gpio(codec); |
4807 | spec->gpio_led_polarity = 1; | 4820 | spec->gpio_led_polarity = default_polarity; |
4808 | return 1; | 4821 | return 1; |
4809 | } | 4822 | } |
4810 | } | 4823 | } |
@@ -4902,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4902 | stac_issue_unsol_event(codec, | 4915 | stac_issue_unsol_event(codec, |
4903 | spec->autocfg.line_out_pins[0]); | 4916 | spec->autocfg.line_out_pins[0]); |
4904 | } | 4917 | } |
4918 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4919 | /* sync mute LED */ | ||
4920 | if (spec->gpio_led && codec->patch_ops.check_power_status) | ||
4921 | codec->patch_ops.check_power_status(codec, 0x01); | ||
4922 | #endif | ||
4905 | return 0; | 4923 | return 0; |
4906 | } | 4924 | } |
4907 | 4925 | ||
@@ -4921,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, | |||
4921 | hda_nid_t nid) | 4939 | hda_nid_t nid) |
4922 | { | 4940 | { |
4923 | struct sigmatel_spec *spec = codec->spec; | 4941 | struct sigmatel_spec *spec = codec->spec; |
4942 | int i, muted = 1; | ||
4924 | 4943 | ||
4925 | if (nid == 0x10) { | 4944 | for (i = 0; i < spec->multiout.num_dacs; i++) { |
4926 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | 4945 | nid = spec->multiout.dac_nids[i]; |
4927 | HDA_AMP_MUTE) | 4946 | if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & |
4928 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | 4947 | HDA_AMP_MUTE)) { |
4929 | else | 4948 | muted = 0; /* something heard */ |
4930 | spec->gpio_data |= spec->gpio_led; /* white */ | 4949 | break; |
4931 | |||
4932 | if (!spec->gpio_led_polarity) { | ||
4933 | /* LED state is inverted on these systems */ | ||
4934 | spec->gpio_data ^= spec->gpio_led; | ||
4935 | } | 4950 | } |
4936 | |||
4937 | stac_gpio_set(codec, spec->gpio_mask, | ||
4938 | spec->gpio_dir, | ||
4939 | spec->gpio_data); | ||
4940 | } | 4951 | } |
4952 | if (muted) | ||
4953 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | ||
4954 | else | ||
4955 | spec->gpio_data |= spec->gpio_led; /* white */ | ||
4941 | 4956 | ||
4942 | return 0; | 4957 | if (!spec->gpio_led_polarity) { |
4943 | } | 4958 | /* LED state is inverted on these systems */ |
4944 | 4959 | spec->gpio_data ^= spec->gpio_led; | |
4945 | static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec, | 4960 | } |
4946 | hda_nid_t nid) | ||
4947 | { | ||
4948 | struct sigmatel_spec *spec = codec->spec; | ||
4949 | 4961 | ||
4950 | if (nid != 0x13) | ||
4951 | return 0; | ||
4952 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE) | ||
4953 | spec->gpio_data |= spec->gpio_led; /* mute LED on */ | ||
4954 | else | ||
4955 | spec->gpio_data &= ~spec->gpio_led; /* mute LED off */ | ||
4956 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); | 4962 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); |
4957 | |||
4958 | return 0; | 4963 | return 0; |
4959 | } | 4964 | } |
4960 | |||
4961 | #endif | 4965 | #endif |
4962 | 4966 | ||
4963 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4967 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) |
@@ -5279,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5279 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; | 5283 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; |
5280 | int err; | 5284 | int err; |
5281 | int num_dacs; | 5285 | int num_dacs; |
5282 | hda_nid_t nid; | ||
5283 | 5286 | ||
5284 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5287 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5285 | if (spec == NULL) | 5288 | if (spec == NULL) |
@@ -5318,7 +5321,18 @@ again: | |||
5318 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5321 | stac92hd83xxx_brd_tbl[spec->board_config]); |
5319 | 5322 | ||
5320 | switch (codec->vendor_id) { | 5323 | switch (codec->vendor_id) { |
5324 | case 0x111d7666: | ||
5325 | case 0x111d7667: | ||
5326 | case 0x111d7668: | ||
5327 | case 0x111d7669: | ||
5328 | spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); | ||
5329 | spec->pin_nids = stac92hd88xxx_pin_nids; | ||
5330 | spec->mono_nid = 0; | ||
5331 | spec->digbeep_nid = 0; | ||
5332 | spec->num_pwrs = 0; | ||
5333 | break; | ||
5321 | case 0x111d7604: | 5334 | case 0x111d7604: |
5335 | case 0x111d76d4: | ||
5322 | case 0x111d7605: | 5336 | case 0x111d7605: |
5323 | case 0x111d76d5: | 5337 | case 0x111d76d5: |
5324 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | 5338 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) |
@@ -5329,8 +5343,10 @@ again: | |||
5329 | 5343 | ||
5330 | codec->patch_ops = stac92xx_patch_ops; | 5344 | codec->patch_ops = stac92xx_patch_ops; |
5331 | 5345 | ||
5332 | if (spec->board_config == STAC_92HD83XXX_HP) | 5346 | if (find_mute_led_gpio(codec, 0)) |
5333 | spec->gpio_led = 0x01; | 5347 | snd_printd("mute LED gpio %d polarity %d\n", |
5348 | spec->gpio_led, | ||
5349 | spec->gpio_led_polarity); | ||
5334 | 5350 | ||
5335 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5351 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5336 | if (spec->gpio_led) { | 5352 | if (spec->gpio_led) { |
@@ -5339,7 +5355,7 @@ again: | |||
5339 | spec->gpio_data |= spec->gpio_led; | 5355 | spec->gpio_data |= spec->gpio_led; |
5340 | /* register check_power_status callback. */ | 5356 | /* register check_power_status callback. */ |
5341 | codec->patch_ops.check_power_status = | 5357 | codec->patch_ops.check_power_status = |
5342 | idt92hd83xxx_hp_check_power_status; | 5358 | stac92xx_hp_check_power_status; |
5343 | } | 5359 | } |
5344 | #endif | 5360 | #endif |
5345 | 5361 | ||
@@ -5359,24 +5375,21 @@ again: | |||
5359 | return err; | 5375 | return err; |
5360 | } | 5376 | } |
5361 | 5377 | ||
5362 | switch (spec->board_config) { | 5378 | /* docking output support */ |
5363 | case STAC_DELL_S14: | 5379 | num_dacs = snd_hda_get_connections(codec, 0xF, |
5364 | nid = 0xf; | ||
5365 | break; | ||
5366 | default: | ||
5367 | nid = 0xe; | ||
5368 | break; | ||
5369 | } | ||
5370 | |||
5371 | num_dacs = snd_hda_get_connections(codec, nid, | ||
5372 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | 5380 | conn, STAC92HD83_DAC_COUNT + 1) - 1; |
5373 | if (num_dacs < 0) | 5381 | /* skip non-DAC connections */ |
5374 | num_dacs = STAC92HD83_DAC_COUNT; | 5382 | while (num_dacs >= 0 && |
5375 | 5383 | (get_wcaps_type(get_wcaps(codec, conn[num_dacs])) | |
5376 | /* set port X to select the last DAC | 5384 | != AC_WID_AUD_OUT)) |
5377 | */ | 5385 | num_dacs--; |
5378 | snd_hda_codec_write_cache(codec, nid, 0, | 5386 | /* set port E and F to select the last DAC */ |
5387 | if (num_dacs >= 0) { | ||
5388 | snd_hda_codec_write_cache(codec, 0xE, 0, | ||
5389 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
5390 | snd_hda_codec_write_cache(codec, 0xF, 0, | ||
5379 | AC_VERB_SET_CONNECT_SEL, num_dacs); | 5391 | AC_VERB_SET_CONNECT_SEL, num_dacs); |
5392 | } | ||
5380 | 5393 | ||
5381 | codec->proc_widget_hook = stac92hd_proc_hook; | 5394 | codec->proc_widget_hook = stac92hd_proc_hook; |
5382 | 5395 | ||
@@ -5657,7 +5670,6 @@ again: | |||
5657 | */ | 5670 | */ |
5658 | spec->num_smuxes = 1; | 5671 | spec->num_smuxes = 1; |
5659 | spec->num_dmuxes = 1; | 5672 | spec->num_dmuxes = 1; |
5660 | spec->gpio_led = 0x01; | ||
5661 | /* fallthrough */ | 5673 | /* fallthrough */ |
5662 | case STAC_HP_DV5: | 5674 | case STAC_HP_DV5: |
5663 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | 5675 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); |
@@ -5672,8 +5684,6 @@ again: | |||
5672 | spec->num_dmics = 1; | 5684 | spec->num_dmics = 1; |
5673 | spec->num_dmuxes = 1; | 5685 | spec->num_dmuxes = 1; |
5674 | spec->num_smuxes = 1; | 5686 | spec->num_smuxes = 1; |
5675 | /* orange/white mute led on GPIO3, orange=0, white=1 */ | ||
5676 | spec->gpio_led = 0x08; | ||
5677 | break; | 5687 | break; |
5678 | } | 5688 | } |
5679 | 5689 | ||
@@ -5695,7 +5705,7 @@ again: | |||
5695 | } | 5705 | } |
5696 | } | 5706 | } |
5697 | 5707 | ||
5698 | if (find_mute_led_gpio(codec)) | 5708 | if (find_mute_led_gpio(codec, 1)) |
5699 | snd_printd("mute LED gpio %d polarity %d\n", | 5709 | snd_printd("mute LED gpio %d polarity %d\n", |
5700 | spec->gpio_led, | 5710 | spec->gpio_led, |
5701 | spec->gpio_led_polarity); | 5711 | spec->gpio_led_polarity); |
@@ -6236,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
6236 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, | 6246 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, |
6237 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | 6247 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, |
6238 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, | 6248 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, |
6249 | { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx}, | ||
6239 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, | 6250 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, |
6240 | { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, | 6251 | { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, |
6252 | { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx}, | ||
6253 | { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx}, | ||
6254 | { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx}, | ||
6255 | { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx}, | ||
6241 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | 6256 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, |
6242 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 6257 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
6243 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 6258 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |