diff options
Diffstat (limited to 'sound/pci/hda/patch_senarytech.c')
-rw-r--r-- | sound/pci/hda/patch_senarytech.c | 244 |
1 files changed, 0 insertions, 244 deletions
diff --git a/sound/pci/hda/patch_senarytech.c b/sound/pci/hda/patch_senarytech.c deleted file mode 100644 index 0691996fa971..000000000000 --- a/sound/pci/hda/patch_senarytech.c +++ /dev/null @@ -1,244 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * HD audio interface patch for Senary HDA audio codec - * - * Initially based on sound/pci/hda/patch_conexant.c - */ - -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <sound/core.h> -#include <sound/jack.h> - -#include <sound/hda_codec.h> -#include "hda_local.h" -#include "hda_auto_parser.h" -#include "hda_beep.h" -#include "hda_jack.h" -#include "hda_generic.h" - -struct senary_spec { - struct hda_gen_spec gen; - - /* extra EAPD pins */ - unsigned int num_eapds; - hda_nid_t eapds[4]; - hda_nid_t mute_led_eapd; - - unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ - - int mute_led_polarity; - unsigned int gpio_led; - unsigned int gpio_mute_led_mask; - unsigned int gpio_mic_led_mask; -}; - -#ifdef CONFIG_SND_HDA_INPUT_BEEP -/* additional beep mixers; private_value will be overwritten */ -static const struct snd_kcontrol_new senary_beep_mixer[] = { - HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), - HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), -}; - -static int set_beep_amp(struct senary_spec *spec, hda_nid_t nid, - int idx, int dir) -{ - struct snd_kcontrol_new *knew; - unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); - int i; - - spec->gen.beep_nid = nid; - for (i = 0; i < ARRAY_SIZE(senary_beep_mixer); i++) { - knew = snd_hda_gen_add_kctl(&spec->gen, NULL, - &senary_beep_mixer[i]); - if (!knew) - return -ENOMEM; - knew->private_value = beep_amp; - } - return 0; -} - -static int senary_auto_parse_beep(struct hda_codec *codec) -{ - struct senary_spec *spec = codec->spec; - hda_nid_t nid; - - for_each_hda_codec_node(nid, codec) - if ((get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) && - (get_wcaps(codec, nid) & (AC_WCAP_OUT_AMP | AC_WCAP_AMP_OVRD))) - return set_beep_amp(spec, nid, 0, HDA_OUTPUT); - return 0; -} -#else -#define senary_auto_parse_beep(codec) 0 -#endif - -/* parse EAPDs */ -static void senary_auto_parse_eapd(struct hda_codec *codec) -{ - struct senary_spec *spec = codec->spec; - hda_nid_t nid; - - for_each_hda_codec_node(nid, codec) { - if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) - continue; - if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) - continue; - spec->eapds[spec->num_eapds++] = nid; - if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) - break; - } -} - -static void senary_auto_turn_eapd(struct hda_codec *codec, int num_pins, - const hda_nid_t *pins, bool on) -{ - int i; - - for (i = 0; i < num_pins; i++) { - if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) - snd_hda_codec_write(codec, pins[i], 0, - AC_VERB_SET_EAPD_BTLENABLE, - on ? 0x02 : 0); - } -} - -/* turn on/off EAPD according to Master switch */ -static void senary_auto_vmaster_hook(void *private_data, int enabled) -{ - struct hda_codec *codec = private_data; - struct senary_spec *spec = codec->spec; - - senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); -} - -static void senary_init_gpio_led(struct hda_codec *codec) -{ - struct senary_spec *spec = codec->spec; - unsigned int mask = spec->gpio_mute_led_mask | spec->gpio_mic_led_mask; - - if (mask) { - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, - mask); - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, - mask); - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - spec->gpio_led); - } -} - -static int senary_auto_init(struct hda_codec *codec) -{ - snd_hda_gen_init(codec); - senary_init_gpio_led(codec); - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); - - return 0; -} - -static void senary_auto_shutdown(struct hda_codec *codec) -{ - struct senary_spec *spec = codec->spec; - - /* Turn the problematic codec into D3 to avoid spurious noises - * from the internal speaker during (and after) reboot - */ - senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, false); -} - -static void senary_auto_free(struct hda_codec *codec) -{ - senary_auto_shutdown(codec); - snd_hda_gen_free(codec); -} - -static int senary_auto_suspend(struct hda_codec *codec) -{ - senary_auto_shutdown(codec); - return 0; -} - -static const struct hda_codec_ops senary_auto_patch_ops = { - .build_controls = snd_hda_gen_build_controls, - .build_pcms = snd_hda_gen_build_pcms, - .init = senary_auto_init, - .free = senary_auto_free, - .unsol_event = snd_hda_jack_unsol_event, - .suspend = senary_auto_suspend, - .check_power_status = snd_hda_gen_check_power_status, -}; - -static int patch_senary_auto(struct hda_codec *codec) -{ - struct senary_spec *spec; - int err; - - codec_info(codec, "%s: BIOS auto-probing.\n", codec->core.chip_name); - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - snd_hda_gen_spec_init(&spec->gen); - codec->spec = spec; - codec->patch_ops = senary_auto_patch_ops; - - senary_auto_parse_eapd(codec); - spec->gen.own_eapd_ctl = 1; - - if (!spec->gen.vmaster_mute.hook) - spec->gen.vmaster_mute.hook = senary_auto_vmaster_hook; - - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - - err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, - spec->parse_flags); - if (err < 0) - goto error; - - err = senary_auto_parse_beep(codec); - if (err < 0) - goto error; - - err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); - if (err < 0) - goto error; - - /* Some laptops with Senary chips show stalls in S3 resume, - * which falls into the single-cmd mode. - * Better to make reset, then. - */ - if (!codec->bus->core.sync_write) { - codec_info(codec, - "Enable sync_write for stable communication\n"); - codec->bus->core.sync_write = 1; - codec->bus->allow_bus_reset = 1; - } - - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); - - return 0; - - error: - senary_auto_free(codec); - return err; -} - -/* - */ - -static const struct hda_device_id snd_hda_id_senary[] = { - HDA_CODEC_ENTRY(0x1fa86186, "SN6186", patch_senary_auto), - {} /* terminator */ -}; -MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_senary); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Senarytech HD-audio codec"); - -static struct hda_codec_driver senary_driver = { - .id = snd_hda_id_senary, -}; - -module_hda_codec_driver(senary_driver); |