diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 271 |
1 files changed, 175 insertions, 96 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 799ba2570902..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, |
@@ -2688,7 +2693,7 @@ static struct snd_kcontrol_new * | |||
2688 | stac_control_new(struct sigmatel_spec *spec, | 2693 | stac_control_new(struct sigmatel_spec *spec, |
2689 | struct snd_kcontrol_new *ktemp, | 2694 | struct snd_kcontrol_new *ktemp, |
2690 | const char *name, | 2695 | const char *name, |
2691 | hda_nid_t nid) | 2696 | unsigned int subdev) |
2692 | { | 2697 | { |
2693 | struct snd_kcontrol_new *knew; | 2698 | struct snd_kcontrol_new *knew; |
2694 | 2699 | ||
@@ -2704,8 +2709,7 @@ stac_control_new(struct sigmatel_spec *spec, | |||
2704 | spec->kctls.alloced--; | 2709 | spec->kctls.alloced--; |
2705 | return NULL; | 2710 | return NULL; |
2706 | } | 2711 | } |
2707 | if (nid) | 2712 | knew->subdevice = subdev; |
2708 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | ||
2709 | return knew; | 2713 | return knew; |
2710 | } | 2714 | } |
2711 | 2715 | ||
@@ -2715,7 +2719,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | |||
2715 | unsigned long val) | 2719 | unsigned long val) |
2716 | { | 2720 | { |
2717 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, | 2721 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, |
2718 | get_amp_nid_(val)); | 2722 | HDA_SUBDEV_AMP_FLAG); |
2719 | if (!knew) | 2723 | if (!knew) |
2720 | return -ENOMEM; | 2724 | return -ENOMEM; |
2721 | knew->index = idx; | 2725 | knew->index = idx; |
@@ -2874,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
2874 | 2878 | ||
2875 | conn_len = snd_hda_get_connections(codec, nid, conn, | 2879 | conn_len = snd_hda_get_connections(codec, nid, conn, |
2876 | 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 | } | ||
2877 | for (j = 0; j < conn_len; j++) { | 2888 | for (j = 0; j < conn_len; j++) { |
2878 | wcaps = get_wcaps(codec, conn[j]); | 2889 | wcaps = get_wcaps(codec, conn[j]); |
2879 | wtype = get_wcaps_type(wcaps); | 2890 | wtype = get_wcaps_type(wcaps); |
@@ -4160,34 +4171,52 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
4160 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | 4171 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, |
4161 | int enable); | 4172 | int enable); |
4162 | 4173 | ||
4174 | static inline int get_int_hint(struct hda_codec *codec, const char *key, | ||
4175 | int *valp) | ||
4176 | { | ||
4177 | const char *p; | ||
4178 | p = snd_hda_get_hint(codec, key); | ||
4179 | if (p) { | ||
4180 | unsigned long val; | ||
4181 | if (!strict_strtoul(p, 0, &val)) { | ||
4182 | *valp = val; | ||
4183 | return 1; | ||
4184 | } | ||
4185 | } | ||
4186 | return 0; | ||
4187 | } | ||
4188 | |||
4163 | /* override some hints from the hwdep entry */ | 4189 | /* override some hints from the hwdep entry */ |
4164 | static void stac_store_hints(struct hda_codec *codec) | 4190 | static void stac_store_hints(struct hda_codec *codec) |
4165 | { | 4191 | { |
4166 | struct sigmatel_spec *spec = codec->spec; | 4192 | struct sigmatel_spec *spec = codec->spec; |
4167 | const char *p; | ||
4168 | int val; | 4193 | int val; |
4169 | 4194 | ||
4170 | val = snd_hda_get_bool_hint(codec, "hp_detect"); | 4195 | val = snd_hda_get_bool_hint(codec, "hp_detect"); |
4171 | if (val >= 0) | 4196 | if (val >= 0) |
4172 | spec->hp_detect = val; | 4197 | spec->hp_detect = val; |
4173 | p = snd_hda_get_hint(codec, "gpio_mask"); | 4198 | if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) { |
4174 | if (p) { | ||
4175 | spec->gpio_mask = simple_strtoul(p, NULL, 0); | ||
4176 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = | 4199 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = |
4177 | spec->gpio_mask; | 4200 | spec->gpio_mask; |
4178 | } | 4201 | } |
4179 | p = snd_hda_get_hint(codec, "gpio_dir"); | 4202 | if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) |
4180 | if (p) | 4203 | spec->gpio_mask &= spec->gpio_mask; |
4181 | spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | 4204 | if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) |
4182 | p = snd_hda_get_hint(codec, "gpio_data"); | 4205 | spec->gpio_dir &= spec->gpio_mask; |
4183 | if (p) | 4206 | if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) |
4184 | spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | 4207 | spec->eapd_mask &= spec->gpio_mask; |
4185 | p = snd_hda_get_hint(codec, "eapd_mask"); | 4208 | if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) |
4186 | if (p) | 4209 | spec->gpio_mute &= spec->gpio_mask; |
4187 | spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
4188 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); | 4210 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); |
4189 | if (val >= 0) | 4211 | if (val >= 0) |
4190 | spec->eapd_switch = val; | 4212 | spec->eapd_switch = val; |
4213 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); | ||
4214 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { | ||
4215 | spec->gpio_mask |= spec->gpio_led; | ||
4216 | spec->gpio_dir |= spec->gpio_led; | ||
4217 | if (spec->gpio_led_polarity) | ||
4218 | spec->gpio_data |= spec->gpio_led; | ||
4219 | } | ||
4191 | } | 4220 | } |
4192 | 4221 | ||
4193 | static int stac92xx_init(struct hda_codec *codec) | 4222 | static int stac92xx_init(struct hda_codec *codec) |
@@ -4334,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4334 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) | 4363 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) |
4335 | stac_issue_unsol_event(codec, nid); | 4364 | stac_issue_unsol_event(codec, nid); |
4336 | } | 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 | ||
4337 | if (spec->dac_list) | 4372 | if (spec->dac_list) |
4338 | stac92xx_power_down(codec); | 4373 | stac92xx_power_down(codec); |
4339 | return 0; | 4374 | return 0; |
@@ -4372,18 +4407,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec) | |||
4372 | static void stac92xx_shutup(struct hda_codec *codec) | 4407 | static void stac92xx_shutup(struct hda_codec *codec) |
4373 | { | 4408 | { |
4374 | struct sigmatel_spec *spec = codec->spec; | 4409 | struct sigmatel_spec *spec = codec->spec; |
4375 | int i; | ||
4376 | hda_nid_t nid; | ||
4377 | 4410 | ||
4378 | /* reset each pin before powering down DAC/ADC to avoid click noise */ | 4411 | snd_hda_shutup_pins(codec); |
4379 | nid = codec->start_nid; | ||
4380 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
4381 | unsigned int wcaps = get_wcaps(codec, nid); | ||
4382 | unsigned int wid_type = get_wcaps_type(wcaps); | ||
4383 | if (wid_type == AC_WID_PIN) | ||
4384 | snd_hda_codec_read(codec, nid, 0, | ||
4385 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4386 | } | ||
4387 | 4412 | ||
4388 | if (spec->eapd_mask) | 4413 | if (spec->eapd_mask) |
4389 | stac_gpio_set(codec, spec->gpio_mask, | 4414 | stac_gpio_set(codec, spec->gpio_mask, |
@@ -4735,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id); | |||
4735 | static void set_hp_led_gpio(struct hda_codec *codec) | 4760 | static void set_hp_led_gpio(struct hda_codec *codec) |
4736 | { | 4761 | { |
4737 | struct sigmatel_spec *spec = codec->spec; | 4762 | struct sigmatel_spec *spec = codec->spec; |
4738 | switch (codec->vendor_id) { | 4763 | unsigned int gpio; |
4739 | case 0x111d7608: | 4764 | |
4740 | /* GPIO 0 */ | 4765 | gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); |
4741 | spec->gpio_led = 0x01; | 4766 | gpio &= AC_GPIO_IO_COUNT; |
4742 | break; | 4767 | if (gpio > 3) |
4743 | case 0x111d7600: | 4768 | spec->gpio_led = 0x08; /* GPIO 3 */ |
4744 | case 0x111d7601: | 4769 | else |
4745 | case 0x111d7602: | 4770 | spec->gpio_led = 0x01; /* GPIO 0 */ |
4746 | case 0x111d7603: | ||
4747 | /* GPIO 3 */ | ||
4748 | spec->gpio_led = 0x08; | ||
4749 | break; | ||
4750 | } | ||
4751 | } | 4771 | } |
4752 | 4772 | ||
4753 | /* | 4773 | /* |
@@ -4770,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec) | |||
4770 | * 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. |
4771 | * -- kunal | 4791 | * -- kunal |
4772 | */ | 4792 | */ |
4773 | static int find_mute_led_gpio(struct hda_codec *codec) | 4793 | static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) |
4774 | { | 4794 | { |
4775 | struct sigmatel_spec *spec = codec->spec; | 4795 | struct sigmatel_spec *spec = codec->spec; |
4776 | const struct dmi_device *dev = NULL; | 4796 | const struct dmi_device *dev = NULL; |
@@ -4797,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec) | |||
4797 | */ | 4817 | */ |
4798 | if (!hp_blike_system(codec->subsystem_id)) { | 4818 | if (!hp_blike_system(codec->subsystem_id)) { |
4799 | set_hp_led_gpio(codec); | 4819 | set_hp_led_gpio(codec); |
4800 | spec->gpio_led_polarity = 1; | 4820 | spec->gpio_led_polarity = default_polarity; |
4801 | return 1; | 4821 | return 1; |
4802 | } | 4822 | } |
4803 | } | 4823 | } |
@@ -4895,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4895 | stac_issue_unsol_event(codec, | 4915 | stac_issue_unsol_event(codec, |
4896 | spec->autocfg.line_out_pins[0]); | 4916 | spec->autocfg.line_out_pins[0]); |
4897 | } | 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 | ||
4898 | return 0; | 4923 | return 0; |
4899 | } | 4924 | } |
4900 | 4925 | ||
@@ -4914,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, | |||
4914 | hda_nid_t nid) | 4939 | hda_nid_t nid) |
4915 | { | 4940 | { |
4916 | struct sigmatel_spec *spec = codec->spec; | 4941 | struct sigmatel_spec *spec = codec->spec; |
4942 | int i, muted = 1; | ||
4917 | 4943 | ||
4918 | if (nid == 0x10) { | 4944 | for (i = 0; i < spec->multiout.num_dacs; i++) { |
4919 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | 4945 | nid = spec->multiout.dac_nids[i]; |
4920 | HDA_AMP_MUTE) | 4946 | if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & |
4921 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | 4947 | HDA_AMP_MUTE)) { |
4922 | else | 4948 | muted = 0; /* something heard */ |
4923 | spec->gpio_data |= spec->gpio_led; /* white */ | 4949 | break; |
4924 | |||
4925 | if (!spec->gpio_led_polarity) { | ||
4926 | /* LED state is inverted on these systems */ | ||
4927 | spec->gpio_data ^= spec->gpio_led; | ||
4928 | } | 4950 | } |
4929 | |||
4930 | stac_gpio_set(codec, spec->gpio_mask, | ||
4931 | spec->gpio_dir, | ||
4932 | spec->gpio_data); | ||
4933 | } | 4951 | } |
4952 | if (muted) | ||
4953 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | ||
4954 | else | ||
4955 | spec->gpio_data |= spec->gpio_led; /* white */ | ||
4934 | 4956 | ||
4935 | return 0; | 4957 | if (!spec->gpio_led_polarity) { |
4936 | } | 4958 | /* LED state is inverted on these systems */ |
4937 | 4959 | spec->gpio_data ^= spec->gpio_led; | |
4938 | static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec, | 4960 | } |
4939 | hda_nid_t nid) | ||
4940 | { | ||
4941 | struct sigmatel_spec *spec = codec->spec; | ||
4942 | 4961 | ||
4943 | if (nid != 0x13) | ||
4944 | return 0; | ||
4945 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE) | ||
4946 | spec->gpio_data |= spec->gpio_led; /* mute LED on */ | ||
4947 | else | ||
4948 | spec->gpio_data &= ~spec->gpio_led; /* mute LED off */ | ||
4949 | 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); |
4950 | |||
4951 | return 0; | 4963 | return 0; |
4952 | } | 4964 | } |
4953 | |||
4954 | #endif | 4965 | #endif |
4955 | 4966 | ||
4956 | 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) |
@@ -5272,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5272 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; | 5283 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; |
5273 | int err; | 5284 | int err; |
5274 | int num_dacs; | 5285 | int num_dacs; |
5275 | hda_nid_t nid; | ||
5276 | 5286 | ||
5277 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5287 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5278 | if (spec == NULL) | 5288 | if (spec == NULL) |
@@ -5311,7 +5321,18 @@ again: | |||
5311 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5321 | stac92hd83xxx_brd_tbl[spec->board_config]); |
5312 | 5322 | ||
5313 | 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; | ||
5314 | case 0x111d7604: | 5334 | case 0x111d7604: |
5335 | case 0x111d76d4: | ||
5315 | case 0x111d7605: | 5336 | case 0x111d7605: |
5316 | case 0x111d76d5: | 5337 | case 0x111d76d5: |
5317 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | 5338 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) |
@@ -5322,8 +5343,10 @@ again: | |||
5322 | 5343 | ||
5323 | codec->patch_ops = stac92xx_patch_ops; | 5344 | codec->patch_ops = stac92xx_patch_ops; |
5324 | 5345 | ||
5325 | if (spec->board_config == STAC_92HD83XXX_HP) | 5346 | if (find_mute_led_gpio(codec, 0)) |
5326 | spec->gpio_led = 0x01; | 5347 | snd_printd("mute LED gpio %d polarity %d\n", |
5348 | spec->gpio_led, | ||
5349 | spec->gpio_led_polarity); | ||
5327 | 5350 | ||
5328 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5351 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5329 | if (spec->gpio_led) { | 5352 | if (spec->gpio_led) { |
@@ -5332,7 +5355,7 @@ again: | |||
5332 | spec->gpio_data |= spec->gpio_led; | 5355 | spec->gpio_data |= spec->gpio_led; |
5333 | /* register check_power_status callback. */ | 5356 | /* register check_power_status callback. */ |
5334 | codec->patch_ops.check_power_status = | 5357 | codec->patch_ops.check_power_status = |
5335 | idt92hd83xxx_hp_check_power_status; | 5358 | stac92xx_hp_check_power_status; |
5336 | } | 5359 | } |
5337 | #endif | 5360 | #endif |
5338 | 5361 | ||
@@ -5352,24 +5375,21 @@ again: | |||
5352 | return err; | 5375 | return err; |
5353 | } | 5376 | } |
5354 | 5377 | ||
5355 | switch (spec->board_config) { | 5378 | /* docking output support */ |
5356 | case STAC_DELL_S14: | 5379 | num_dacs = snd_hda_get_connections(codec, 0xF, |
5357 | nid = 0xf; | ||
5358 | break; | ||
5359 | default: | ||
5360 | nid = 0xe; | ||
5361 | break; | ||
5362 | } | ||
5363 | |||
5364 | num_dacs = snd_hda_get_connections(codec, nid, | ||
5365 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | 5380 | conn, STAC92HD83_DAC_COUNT + 1) - 1; |
5366 | if (num_dacs < 0) | 5381 | /* skip non-DAC connections */ |
5367 | num_dacs = STAC92HD83_DAC_COUNT; | 5382 | while (num_dacs >= 0 && |
5368 | 5383 | (get_wcaps_type(get_wcaps(codec, conn[num_dacs])) | |
5369 | /* set port X to select the last DAC | 5384 | != AC_WID_AUD_OUT)) |
5370 | */ | 5385 | num_dacs--; |
5371 | 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, | ||
5372 | AC_VERB_SET_CONNECT_SEL, num_dacs); | 5391 | AC_VERB_SET_CONNECT_SEL, num_dacs); |
5392 | } | ||
5373 | 5393 | ||
5374 | codec->proc_widget_hook = stac92hd_proc_hook; | 5394 | codec->proc_widget_hook = stac92hd_proc_hook; |
5375 | 5395 | ||
@@ -5431,6 +5451,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | |||
5431 | return 0; | 5451 | return 0; |
5432 | } | 5452 | } |
5433 | 5453 | ||
5454 | /* HP dv7 bass switch - GPIO5 */ | ||
5455 | #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info | ||
5456 | static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol, | ||
5457 | struct snd_ctl_elem_value *ucontrol) | ||
5458 | { | ||
5459 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
5460 | struct sigmatel_spec *spec = codec->spec; | ||
5461 | ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20); | ||
5462 | return 0; | ||
5463 | } | ||
5464 | |||
5465 | static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, | ||
5466 | struct snd_ctl_elem_value *ucontrol) | ||
5467 | { | ||
5468 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
5469 | struct sigmatel_spec *spec = codec->spec; | ||
5470 | unsigned int gpio_data; | ||
5471 | |||
5472 | gpio_data = (spec->gpio_data & ~0x20) | | ||
5473 | (ucontrol->value.integer.value[0] ? 0x20 : 0); | ||
5474 | if (gpio_data == spec->gpio_data) | ||
5475 | return 0; | ||
5476 | spec->gpio_data = gpio_data; | ||
5477 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); | ||
5478 | return 1; | ||
5479 | } | ||
5480 | |||
5481 | static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { | ||
5482 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5483 | .info = stac_hp_bass_gpio_info, | ||
5484 | .get = stac_hp_bass_gpio_get, | ||
5485 | .put = stac_hp_bass_gpio_put, | ||
5486 | }; | ||
5487 | |||
5488 | static int stac_add_hp_bass_switch(struct hda_codec *codec) | ||
5489 | { | ||
5490 | struct sigmatel_spec *spec = codec->spec; | ||
5491 | |||
5492 | if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl, | ||
5493 | "Bass Speaker Playback Switch", 0)) | ||
5494 | return -ENOMEM; | ||
5495 | |||
5496 | spec->gpio_mask |= 0x20; | ||
5497 | spec->gpio_dir |= 0x20; | ||
5498 | spec->gpio_data |= 0x20; | ||
5499 | return 0; | ||
5500 | } | ||
5501 | |||
5434 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 5502 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
5435 | { | 5503 | { |
5436 | struct sigmatel_spec *spec; | 5504 | struct sigmatel_spec *spec; |
@@ -5602,7 +5670,6 @@ again: | |||
5602 | */ | 5670 | */ |
5603 | spec->num_smuxes = 1; | 5671 | spec->num_smuxes = 1; |
5604 | spec->num_dmuxes = 1; | 5672 | spec->num_dmuxes = 1; |
5605 | spec->gpio_led = 0x01; | ||
5606 | /* fallthrough */ | 5673 | /* fallthrough */ |
5607 | case STAC_HP_DV5: | 5674 | case STAC_HP_DV5: |
5608 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | 5675 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); |
@@ -5617,8 +5684,6 @@ again: | |||
5617 | spec->num_dmics = 1; | 5684 | spec->num_dmics = 1; |
5618 | spec->num_dmuxes = 1; | 5685 | spec->num_dmuxes = 1; |
5619 | spec->num_smuxes = 1; | 5686 | spec->num_smuxes = 1; |
5620 | /* orange/white mute led on GPIO3, orange=0, white=1 */ | ||
5621 | spec->gpio_led = 0x08; | ||
5622 | break; | 5687 | break; |
5623 | } | 5688 | } |
5624 | 5689 | ||
@@ -5640,7 +5705,7 @@ again: | |||
5640 | } | 5705 | } |
5641 | } | 5706 | } |
5642 | 5707 | ||
5643 | if (find_mute_led_gpio(codec)) | 5708 | if (find_mute_led_gpio(codec, 1)) |
5644 | snd_printd("mute LED gpio %d polarity %d\n", | 5709 | snd_printd("mute LED gpio %d polarity %d\n", |
5645 | spec->gpio_led, | 5710 | spec->gpio_led, |
5646 | spec->gpio_led_polarity); | 5711 | spec->gpio_led_polarity); |
@@ -5674,6 +5739,15 @@ again: | |||
5674 | return err; | 5739 | return err; |
5675 | } | 5740 | } |
5676 | 5741 | ||
5742 | /* enable bass on HP dv7 */ | ||
5743 | if (spec->board_config == STAC_HP_DV5) { | ||
5744 | unsigned int cap; | ||
5745 | cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); | ||
5746 | cap &= AC_GPIO_IO_COUNT; | ||
5747 | if (cap >= 6) | ||
5748 | stac_add_hp_bass_switch(codec); | ||
5749 | } | ||
5750 | |||
5677 | codec->proc_widget_hook = stac92hd7x_proc_hook; | 5751 | codec->proc_widget_hook = stac92hd7x_proc_hook; |
5678 | 5752 | ||
5679 | return 0; | 5753 | return 0; |
@@ -6172,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
6172 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, | 6246 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, |
6173 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | 6247 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, |
6174 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, | 6248 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, |
6249 | { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx}, | ||
6175 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, | 6250 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, |
6176 | { .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}, | ||
6177 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | 6256 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, |
6178 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 6257 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
6179 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 6258 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |